feat: Themes
This commit is contained in:
parent
139f61faa6
commit
cbc7ae8465
41 changed files with 374 additions and 163 deletions
|
|
@ -10,6 +10,7 @@ import '@fontsource/poppins/600.css';
|
|||
import 'virtual:uno.css';
|
||||
import '@unocss/reset/tailwind.css';
|
||||
import 'overlayscrollbars/overlayscrollbars.css';
|
||||
import '~styles/themes.scss';
|
||||
import '~styles/globals.css';
|
||||
import '~styles/highlightjs.css';
|
||||
|
||||
|
|
@ -23,11 +24,9 @@ import { render } from 'solid-js/web';
|
|||
import RootLayout from './RootLayout';
|
||||
import HomePage from './ui/pages/Home';
|
||||
import UpdatesPage from './ui/pages/Updates';
|
||||
import { getProgramInfo, initProgramInfo } from '@onelauncher/client';
|
||||
import { initProgramInfo } from '@onelauncher/client';
|
||||
|
||||
initProgramInfo().finally(() => {
|
||||
document.body.setAttribute('data-platform', getProgramInfo().platform);
|
||||
|
||||
render(() => (
|
||||
<Router root={RootLayout}>
|
||||
<Route component={App}>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,18 @@ body {
|
|||
@apply font-sans text-fg-primary text-md;
|
||||
}
|
||||
|
||||
body.theme-transition * {
|
||||
transition-delay: 0ms !important;
|
||||
transition-duration: 400ms !important;
|
||||
transition-property: color, border, background-color !important;
|
||||
}
|
||||
|
||||
body[data-platform="linux"].theme-transition * {
|
||||
transition-delay: 0ms !important;
|
||||
transition-duration: 400ms !important;
|
||||
transition-property: background-color !important;
|
||||
}
|
||||
|
||||
/* start lynith's native experience (tm) */
|
||||
* {
|
||||
-webkit-user-select: none;
|
||||
|
|
@ -24,13 +36,13 @@ img {
|
|||
}
|
||||
/* end lynith's native experience (tm) */
|
||||
|
||||
/* lynith's epic webkit gtk <=2.44 fixer */
|
||||
body[data-platform="linux"] img {
|
||||
/* Forces webkit gtk to use the GPU for image rendering, should speed up loading of some pages. Temporary until Tauri updates to at least 2.45
|
||||
2.45 is the first version to use Skia for rendering, which prioritises the GPU over the CPU unlike Cairo */
|
||||
/* lynith's epic webkit gtk <=2.45 fixer */
|
||||
body[data-platform="linux"][data-skia-renderer="false"] img {
|
||||
/* Forces webkit gtk to use the GPU for image rendering, should speed up loading of some pages. Temporary until Tauri updates to at least 2.46
|
||||
2.46 is the first version to use Skia for rendering, which prioritises the GPU over the CPU unlike Cairo */
|
||||
@apply transform-gpu;
|
||||
}
|
||||
/* end lynith's epic webkit gtk <=2.44 fixer */
|
||||
/* end lynith's epic webkit gtk <=2.45 fixer */
|
||||
|
||||
h1 { @apply text-2xl font-semibold; line-height: 1.5 !important; }
|
||||
h2 { @apply text-xxl font-semibold; line-height: 1.25 !important; }
|
||||
|
|
|
|||
126
apps/frontend/src/styles/themes.scss
Normal file
126
apps/frontend/src/styles/themes.scss
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
@mixin define-theme($name, $selectors: "") {
|
||||
$selector: "#{$selectors} [data-theme="#{$name}"], .theme-#{$name}";
|
||||
|
||||
#{$selector} {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@include define-theme("dark", ":root,") {
|
||||
--clr-white: 255, 255, 255;
|
||||
--clr-black: 0, 0, 0;
|
||||
|
||||
--clr-border: 255, 255, 255;
|
||||
|
||||
--clr-fg-primary: 213, 219, 255;
|
||||
--clr-fg-primary-hover: 218, 224, 255;
|
||||
--clr-fg-primary-pressed: 225, 229, 255;
|
||||
--clr-fg-primary-disabled: 225, 229, 255, 0.5;
|
||||
|
||||
--clr-fg-secondary: 120, 129, 141;
|
||||
--clr-fg-secondary-hover: 95, 104, 116;
|
||||
--clr-fg-secondary-pressed: 130, 141, 155;
|
||||
--clr-fg-secondary-disabled: 120, 129, 141, 0.5;
|
||||
|
||||
--clr-brand: 43, 75, 255;
|
||||
--clr-brand-hover: 40, 67, 221;
|
||||
--clr-brand-pressed: 57, 87, 255;
|
||||
--clr-brand-disabled: 57, 87, 255, 0.5;
|
||||
|
||||
--clr-onbrand: 213, 219, 255;
|
||||
--clr-onbrand-hover: 218, 224, 255;
|
||||
--clr-onbrand-pressed: 225, 229, 255;
|
||||
--clr-onbrand-disabled: 225, 229, 255, 0.5;
|
||||
|
||||
--clr-danger: 255, 68, 68;
|
||||
--clr-danger-hover: 214, 52, 52;
|
||||
--clr-danger-pressed: 255, 86, 86;
|
||||
--clr-danger-disabled: 255, 68, 68, 0.5;
|
||||
|
||||
--clr-success: 35, 154, 96;
|
||||
--clr-success-hover: 26, 135, 82;
|
||||
--clr-success-pressed: 44, 172, 110;
|
||||
--clr-success-disabled: 35, 154, 96, 0.5;
|
||||
|
||||
--clr-component-bg: 26, 34, 41;
|
||||
--clr-component-bg-hover: 23, 31, 37;
|
||||
--clr-component-bg-pressed: 34, 44, 53;
|
||||
--clr-component-bg-disabled: 26, 34, 41, 0.5;
|
||||
|
||||
--clr-code-info: 97, 175, 239;
|
||||
--clr-code-warn: 229, 192, 123;
|
||||
--clr-code-error: 190, 80, 70;
|
||||
--clr-code-debug: 43, 75, 255;
|
||||
--clr-code-trace: 253, 253, 253;
|
||||
|
||||
--clr-link: 97, 175, 239;
|
||||
--clr-link-hover: 95, 135, 255;
|
||||
--clr-link-pressed: 114, 175, 255;
|
||||
--clr-link-disabled: 97, 175, 239, 0.5;
|
||||
|
||||
--clr-page: 17, 23, 28;
|
||||
--clr-page-elevated: 21, 28, 34;
|
||||
--clr-page-pressed: 14, 19, 23;
|
||||
|
||||
--clr-secondary: 25, 32, 38;
|
||||
}
|
||||
|
||||
@include define-theme("light") {
|
||||
--clr-white: 255, 255, 255;
|
||||
--clr-black: 0, 0, 0;
|
||||
|
||||
--clr-border: 40, 40, 40;
|
||||
|
||||
--clr-fg-primary: 40, 40, 40;
|
||||
--clr-fg-primary-hover: 30, 30, 30;
|
||||
--clr-fg-primary-pressed: 20, 20, 20;
|
||||
--clr-fg-primary-disabled: 40, 40, 40, 0.5;
|
||||
|
||||
--clr-fg-secondary: 80, 80, 80;
|
||||
--clr-fg-secondary-hover: 60, 60, 60;
|
||||
--clr-fg-secondary-pressed: 100, 100, 100;
|
||||
--clr-fg-secondary-disabled: 80, 80, 80, 0.5;
|
||||
|
||||
--clr-brand: 43, 75, 255;
|
||||
--clr-brand-hover: 35, 60, 200;
|
||||
--clr-brand-pressed: 30, 50, 170;
|
||||
--clr-brand-disabled: 43, 75, 255, 0.5;
|
||||
|
||||
--clr-onbrand: 255, 255, 255;
|
||||
--clr-onbrand-hover: 245, 245, 245;
|
||||
--clr-onbrand-pressed: 230, 230, 230;
|
||||
--clr-onbrand-disabled: 230, 230, 230, 0.5;
|
||||
|
||||
--clr-danger: 200, 50, 50;
|
||||
--clr-danger-hover: 180, 40, 40;
|
||||
--clr-danger-pressed: 220, 60, 60;
|
||||
--clr-danger-disabled: 200, 50, 50, 0.5;
|
||||
|
||||
--clr-success: 50, 160, 100;
|
||||
--clr-success-hover: 40, 140, 90;
|
||||
--clr-success-pressed: 60, 180, 110;
|
||||
--clr-success-disabled: 50, 160, 100, 0.5;
|
||||
|
||||
--clr-component-bg: 240, 240, 240;
|
||||
--clr-component-bg-hover: 230, 230, 230;
|
||||
--clr-component-bg-pressed: 220, 220, 220;
|
||||
--clr-component-bg-disabled: 240, 240, 240, 0.5;
|
||||
|
||||
--clr-code-info: 40, 120, 200;
|
||||
--clr-code-warn: 200, 150, 90;
|
||||
--clr-code-error: 180, 70, 60;
|
||||
--clr-code-debug: 40, 70, 200;
|
||||
--clr-code-trace: 40, 40, 40;
|
||||
|
||||
--clr-link: 40, 120, 200;
|
||||
--clr-link-hover: 30, 100, 180;
|
||||
--clr-link-pressed: 20, 80, 160;
|
||||
--clr-link-disabled: 40, 120, 200, 0.5;
|
||||
|
||||
--clr-page: 255, 255, 255;
|
||||
--clr-page-elevated: 245, 245, 245;
|
||||
--clr-page-pressed: 230, 230, 230;
|
||||
|
||||
--clr-secondary: 220, 220, 220;
|
||||
|
||||
}
|
||||
|
|
@ -41,8 +41,8 @@ function Navbar() {
|
|||
|
||||
return (
|
||||
<div class="h-15 min-h-[60px] flex flex-row items-center *:flex-1">
|
||||
<div>
|
||||
<div class="w-min flex items-center justify-center transition-transform active:scale-90" onClick={() => open(WEBSITE)}>
|
||||
<div class="h-full flex items-center justify-start">
|
||||
<div class="h-full flex items-start justify-start transition-transform active:scale-90" onClick={() => open(WEBSITE)}>
|
||||
<PolyfrostFull />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ function Sidebar(props: SidebarProps) {
|
|||
return (
|
||||
<a
|
||||
class={
|
||||
`px-3 py-1 rounded-md text-md border hover:bg-component-bg-hover active:bg-component-bg-pressed ${isActive(link[2], link[3]) ? 'bg-component-bg border-gray-05' : 'border-transparent'}`
|
||||
`px-3 py-1 rounded-md text-md border hover:bg-component-bg-hover active:bg-component-bg-pressed ${isActive(link[2], link[3]) ? 'bg-component-bg border-border/05' : 'border-transparent'}`
|
||||
}
|
||||
onClick={() => goto(link[2], link[3])}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
}
|
||||
|
||||
&__secondary, &__iconSecondary {
|
||||
@apply border box-border border-gray-05;
|
||||
@apply border box-border border-border/05;
|
||||
@apply text-fg-primary hover:text-fg-primary-hover active:text-fg-primary-pressed disabled:text-fg-primary-disabled;
|
||||
@apply bg-component-bg hover:bg-component-bg-hover active:bg-component-bg-pressed disabled:bg-component-bg-disabled;
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
}
|
||||
|
||||
&__ghost {
|
||||
@apply hover:bg-gray-05 [&[aria-checked="true"]]:bg-gray-10 active:bg-gray-10;
|
||||
@apply hover:bg-border/05 [&[aria-checked="true"]]:(bg-border/10) active:bg-border/10;
|
||||
}
|
||||
|
||||
&__icon, &__iconPrimary, &__iconSecondary, &__iconDanger {
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
}
|
||||
|
||||
&__icon, &__iconSecondary {
|
||||
@apply hover:bg-gray-05 [&[aria-checked="true"]]:bg-gray-10 active:bg-gray-10;
|
||||
@apply hover:bg-border/05 [&[aria-checked="true"]]:bg-border/10 active:bg-border/10;
|
||||
|
||||
&:hover > * {
|
||||
@apply stroke-fg-primary-hover;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
@apply flex flex-row gap-x-1 items-center;
|
||||
|
||||
.box {
|
||||
@apply w-[18px] h-[18px] flex flex-col justify-center items-center rounded-md bg-component-bg hover:bg-component-bg-hover active:bg-component-bg-pressed border border-gray-05 transition-all;
|
||||
@apply w-[18px] h-[18px] flex flex-col justify-center items-center rounded-md bg-component-bg hover:bg-component-bg-hover active:bg-component-bg-pressed border border-border/05 transition-all;
|
||||
|
||||
> svg {
|
||||
@apply w-[18px] h-[18px] mt-px opacity-0 transition-opacity;
|
||||
|
|
@ -10,11 +10,11 @@
|
|||
|
||||
&.checked {
|
||||
@apply bg-brand hover:bg-brand-hover active:bg-brand-pressed border-transparent;
|
||||
|
||||
|
||||
> svg {
|
||||
@apply opacity-100;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
}
|
||||
|
||||
.dropdown_element {
|
||||
@apply bg-page-elevated rounded-lg border border-gray-05 p-1 shadow-md shadow-black/30 h-full;
|
||||
@apply bg-page-elevated rounded-lg border border-border/05 p-1 shadow-md shadow-black/30 h-full;
|
||||
}
|
||||
|
||||
.list {
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ function Dropdown(props: DropdownProps) {
|
|||
<Index each={items()}>
|
||||
{(item, index) => (
|
||||
<div onClick={() => select(index)}>
|
||||
<div class="flex flex-row items-center justify-between gap-2 rounded-lg p-2 hover:bg-gray-05">
|
||||
<div class="flex flex-row items-center justify-between gap-2 rounded-lg p-2 hover:bg-border/05">
|
||||
{item()}
|
||||
<div class={styles.selected! + (selected() === index ? ` ${styles.visible}` : '')} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
.select_list {
|
||||
@apply bg-component-bg rounded-lg overflow-hidden border border-gray-05;
|
||||
@apply bg-component-bg rounded-lg overflow-hidden border border-border/05;
|
||||
|
||||
.row {
|
||||
@apply min-h-4 py-1 px-2 text-left;
|
||||
|
|
@ -9,4 +9,4 @@
|
|||
@apply bg-white/10;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
.tag {
|
||||
@apply flex flex-row justify-center items-center gap-x-2;
|
||||
@apply bg-component-bg/60 border border-gray-05 text-fg-secondary text-sm font-medium backdrop-blur-md rounded-lg px-2.5 py-0.5;
|
||||
@apply bg-component-bg/60 border border-border/05 text-fg-secondary text-sm font-medium backdrop-blur-md rounded-lg px-2.5 py-0.5;
|
||||
}
|
||||
|
||||
.icon > * {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
.textfield {
|
||||
@apply bg-component-bg [&:not(:focus-within)]:hover:bg-component-bg-hover focus-within:bg-component-bg-pressed disabled:bg-component-bg-disabled;
|
||||
@apply border border-gray-05 text-fg-primary fill-fg-primary;
|
||||
@apply border border-border/05 text-fg-primary fill-fg-primary;
|
||||
@apply rounded-lg px-2.5 py-1.5 min-h-8;
|
||||
@apply flex flex-row items-center justify-start gap-x-1.5;
|
||||
@apply text-sm;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ function Toggle(props: ToggleProps) {
|
|||
|
||||
return (
|
||||
<div
|
||||
class={`w-[40px] h-[22px] p-3 flex flex-row relative rounded-full transition-colors overflow-hidden ${checked() ? 'bg-brand' : 'bg-gray-10'}${` ${split.class}` || ''}`}
|
||||
class={`w-[40px] h-[22px] p-3 flex flex-row relative rounded-full transition-colors overflow-hidden ${checked() ? 'bg-brand' : 'bg-border/10'}${` ${split.class}` || ''}`}
|
||||
onClick={() => toggle()}
|
||||
{...rest}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ function FormattedLog(props: FormattedLogProps) {
|
|||
return (
|
||||
<div class="relative h-full flex flex-1 flex-col overflow-hidden rounded-md bg-component-bg">
|
||||
<Show when={props.enableAutoScroll === true}>
|
||||
<div class="absolute right-0 top-0 z-1 h-6 w-full flex flex-row justify-end border border-gray-05 rounded-t-md bg-page p-px">
|
||||
<div class="absolute right-0 top-0 z-1 h-6 w-full flex flex-row justify-end border border-border/05 rounded-t-md bg-page p-px">
|
||||
<Button.Toggle
|
||||
buttonStyle="icon"
|
||||
checked={shouldScroll}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ function LauncherIcon(props: LauncherIconProps) {
|
|||
<Show
|
||||
children={getLauncherLogoElement(split.launcher!)({ ...rest, ...(split.class ? { class: split.class } : {}) })}
|
||||
fallback={(
|
||||
<div class={`bg-gray-05 ${split.class || ''}`} {...rest as JSX.HTMLAttributes<HTMLDivElement>} />
|
||||
<div class={`bg-border/05 ${split.class || ''}`} {...rest as JSX.HTMLAttributes<HTMLDivElement>} />
|
||||
)}
|
||||
when={split.launcher !== undefined}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ function ProviderIcon(props: ProviderIconProps) {
|
|||
<Element />
|
||||
)}
|
||||
fallback={(
|
||||
<div class={`bg-gray-05 ${split.class || ''}`} {...rest as JSX.HTMLAttributes<HTMLDivElement>} />
|
||||
<div class={`bg-border/05 ${split.class || ''}`} {...rest as JSX.HTMLAttributes<HTMLDivElement>} />
|
||||
)}
|
||||
when={split.provider !== undefined}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ function PackageItem(props: SearchResult & { provider: Providers; row?: boolean
|
|||
<Show
|
||||
fallback={(
|
||||
<div
|
||||
class="aspect-ratio-square rounded-md bg-gray-05"
|
||||
class="aspect-ratio-square rounded-md bg-border/05"
|
||||
classList={{
|
||||
'w-2/5': !props.row,
|
||||
'w-3/4': props.row,
|
||||
|
|
|
|||
|
|
@ -11,5 +11,5 @@
|
|||
-webkit-mask: linear-gradient(var(--degrees), transparent, black 50%);
|
||||
mask: linear-gradient(var(--degrees), transparent, black 50%);
|
||||
|
||||
background: linear-gradient(var(--degrees), transparent, rgba(0, 0, 0, 0.4) 50%);
|
||||
background: linear-gradient(var(--degrees), transparent, rgba(0, 0, 0, 0.85) 80%);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
function PolyfrostFull() {
|
||||
return (
|
||||
<svg fill="none" height="30" viewBox="0 0 174 30" width="174" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg class="h-full w-full" fill="none" height="30" viewBox="0 0 174 30" width="174" xmlns="http://www.w3.org/2000/svg">
|
||||
<path clip-rule="evenodd" d="M22.86 16.6283L13.8843 1.08171C13.0516 -0.36057 11.689 -0.36057 10.8564 1.08171L0.947095 18.2464C-1.74381 22.9075 1.61965 28.7332 7.00145 28.7332H15.8719L22.8601 16.629L29.8482 28.7331H34.7491C38.7858 28.7331 41.3082 24.3637 39.2898 20.8681L31.3646 7.14161C30.532 5.70003 29.1701 5.70003 28.3374 7.14161L22.86 16.6283Z" fill="#0A5BE8" fill-rule="evenodd" />
|
||||
<path d="M117.79 11.03H120.95V14.6499H117.92V24.3499H113.26V14.6499H111.32V11.03H113.26V10.6699C113.26 9 113.74 7.66992 114.69 6.67993C115.65 5.67993 117.02 5.17993 118.8 5.17993C119.37 5.17993 119.93 5.23999 120.49 5.35986C121.04 5.47998 121.51 5.65991 121.89 5.8999L120.73 9.31982C120.54 9.19995 120.32 9.09985 120.07 9.02002C119.83 8.94995 119.58 8.90991 119.34 8.90991C118.85 8.90991 118.47 9.05981 118.2 9.35986C117.93 9.6499 117.79 10.1099 117.79 10.72V11.03Z" fill="#0A5BE8" />
|
||||
<path d="M131.74 10.29V14.6501L131.626 14.6343C131.457 14.6104 131.313 14.5901 131.19 14.5901C131.03 14.5801 130.86 14.5701 130.68 14.5701C129.74 14.5701 128.97 14.8401 128.38 15.3801C127.79 15.9102 127.5 16.79 127.5 17.99V24.3501H122.84V10.52H127.28V12.1799C127.61 11.72 128.03 11.3501 128.53 11.0601C129.41 10.55 130.48 10.29 131.74 10.29Z" fill="#0A5BE8" />
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ function ContextMenu(props: ContextMenuProps) {
|
|||
setVisible={props.setVisible}
|
||||
visible={props.visible}
|
||||
>
|
||||
<div class="border border-gray-05 rounded-xl bg-page-elevated p-1 shadow-black/30 shadow-md" ref={setRef}>
|
||||
<div class="border border-border/05 rounded-xl bg-page-elevated p-1 shadow-black/30 shadow-md" ref={setRef}>
|
||||
<div class="flex flex-col gap-y-1 text-fg-primary">
|
||||
{props.children}
|
||||
</div>
|
||||
|
|
@ -46,7 +46,7 @@ function ContextMenu(props: ContextMenuProps) {
|
|||
}
|
||||
|
||||
ContextMenu.Seperator = function () {
|
||||
return <div class="mx-1 border-b border-gray-05" />;
|
||||
return <div class="mx-1 border-b border-border/05" />;
|
||||
};
|
||||
|
||||
interface ContextMenuRowProps {
|
||||
|
|
@ -58,7 +58,7 @@ interface ContextMenuRowProps {
|
|||
ContextMenu.Row = function (props: ContextMenuRowProps) {
|
||||
return (
|
||||
<div
|
||||
class="m-px flex items-center gap-x-2 rounded-lg px-1.5 py-0.5 [&>svg]:w-[18px] active:bg-gray-10 hover:bg-gray-05"
|
||||
class="m-px flex items-center gap-x-2 rounded-lg px-1.5 py-0.5 [&>svg]:w-[18px] active:bg-border/10 hover:bg-border/05"
|
||||
onClick={e => props.onClick?.(e)}
|
||||
>
|
||||
{props.icon}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ function FullscreenOverlay(props: FullscreenOverlayProps) {
|
|||
return (
|
||||
<Portal {...(props.mount ? { mount: props.mount } : {})}>
|
||||
<div
|
||||
class={`fixed top-0 left-0 w-screen h-screen bg-black/60 backdrop-blur-sm backdrop-grayscale transition-opacity ${props.visible() ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'}`}
|
||||
class={`fixed top-0 left-0 w-screen h-screen bg-black/60 backdrop-blur-sm backdrop-borderscale transition-opacity ${props.visible() ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'}`}
|
||||
style={{ 'z-index': props.zIndex || 1000 }}
|
||||
>
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ function AccountComponent(props: AccountComponentProps) {
|
|||
return (
|
||||
<Show when={props.account}>
|
||||
<div
|
||||
class={`flex flex-row justify-between p-2 rounded-lg ${props.loggedIn !== true && 'hover:bg-gray-05 active:bg-gray-10 hover:text-fg-primary-hover'}`}
|
||||
class={`flex flex-row justify-between p-2 rounded-lg ${props.loggedIn !== true && 'hover:bg-border/05 active:bg-border/10 hover:text-fg-primary-hover'}`}
|
||||
onClick={login}
|
||||
>
|
||||
<div class="flex flex-1 flex-row justify-start gap-x-3">
|
||||
|
|
@ -60,7 +60,7 @@ function AccountPopup(props: PopupProps) {
|
|||
|
||||
return (
|
||||
<Popup {...props}>
|
||||
<div class="w-72 border border-gray-10 rounded-xl bg-page-elevated p-2 shadow-black/30 shadow-md">
|
||||
<div class="w-72 border border-border/10 rounded-xl bg-page-elevated p-2 shadow-black/30 shadow-md">
|
||||
<div class="flex flex-col gap-y-2 text-fg-primary">
|
||||
<Show when={controller.defaultAccount() !== null || controller.defaultAccount() !== undefined}>
|
||||
<AccountComponent
|
||||
|
|
@ -76,7 +76,7 @@ function AccountPopup(props: PopupProps) {
|
|||
)}
|
||||
</For>
|
||||
</Show>
|
||||
<div class="h-px w-full rounded-md bg-gray-05" />
|
||||
<div class="h-px w-full rounded-md bg-border/05" />
|
||||
|
||||
<div class="flex flex-row justify-between">
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ function VersionSelector(props: { setVersion: (version: string) => void }) {
|
|||
</Show>
|
||||
</SelectList>
|
||||
|
||||
<div class="flex flex-1 flex-col gap-y-2 overflow-hidden border border-gray-05 rounded-lg bg-component-bg p-2">
|
||||
<div class="flex flex-1 flex-col gap-y-2 overflow-hidden border border-border/05 rounded-lg bg-component-bg p-2">
|
||||
<For each={Object.keys(filters())}>
|
||||
{name => (
|
||||
<Checkbox
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ function NotificationPopup(props: PopupProps) {
|
|||
|
||||
return (
|
||||
<Popup {...props}>
|
||||
<div class="w-96 border border-gray-10 rounded-xl bg-page-elevated p-2 shadow-black/30 shadow-md">
|
||||
<div class="w-96 border border-border/10 rounded-xl bg-page-elevated p-2 shadow-black/30 shadow-md">
|
||||
<div class="overflow-hidden transition-height" ref={parent}>
|
||||
<div class="flex flex-col items-stretch justify-start gap-2 text-start" ref={inner}>
|
||||
<p class="px-2 pt-1 text-2lg">Notifications</p>
|
||||
|
|
@ -39,7 +39,7 @@ function NotificationPopup(props: PopupProps) {
|
|||
{noti => (
|
||||
<div class="w-full flex flex-col">
|
||||
<NotificationComponent {...noti} overlay={false} />
|
||||
<span class="h-px w-full bg-gray-05" />
|
||||
<span class="h-px w-full bg-border/05" />
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
|
|
@ -48,7 +48,7 @@ function NotificationPopup(props: PopupProps) {
|
|||
</Match>
|
||||
<Match when>
|
||||
<span class="px-2">You have no notifications</span>
|
||||
<span class="h-px bg-gray-05" />
|
||||
<span class="h-px bg-border/05" />
|
||||
</Match>
|
||||
</Switch>
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import useCommand from './useCommand';
|
|||
*/
|
||||
export function syncSettings(settings: Settings) {
|
||||
document.body.classList.toggle('reduce-motion', settings.disable_animations);
|
||||
document.body.setAttribute('data-theme', settings.theme ?? 'dark');
|
||||
}
|
||||
|
||||
interface SettingsControllerType {
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ function HomePage() {
|
|||
<Button
|
||||
buttonStyle="primary"
|
||||
children="New Cluster"
|
||||
iconLeft={<PlusIcon class="stroke-[2.2] !w-5" />}
|
||||
iconLeft={<PlusIcon class="stroke-width-[2.2] !w-5" />}
|
||||
onClick={newCluster}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -108,7 +108,7 @@ function Banner() {
|
|||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<div class="relative h-52 min-h-52 w-full overflow-hidden rounded-xl">
|
||||
<div class="theme-dark relative h-52 min-h-52 w-full overflow-hidden rounded-xl">
|
||||
<ClusterCover
|
||||
class="absolute h-52 w-full rounded-xl object-cover"
|
||||
cluster={cluster()}
|
||||
|
|
@ -180,7 +180,7 @@ function ClusterCard(props: Cluster) {
|
|||
return (
|
||||
<>
|
||||
<div
|
||||
class="group relative h-[152px] flex flex-col border border-gray-05 rounded-xl bg-component-bg active:bg-component-bg-pressed hover:bg-component-bg-hover"
|
||||
class="group border-border/05 relative h-[152px] flex flex-col border rounded-xl bg-component-bg active:bg-component-bg-pressed hover:bg-component-bg-hover"
|
||||
onClick={e => openClusterPage(e)}
|
||||
>
|
||||
<div class="relative flex-1 overflow-hidden rounded-t-xl">
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ function Featured(props: FeaturedProps) {
|
|||
<div class="max-w-84 min-w-52 flex flex-col gap-y-1 p-4">
|
||||
<h2>{props.package.title}</h2>
|
||||
|
||||
<div class="w-fit flex flex-row items-center gap-x-1 rounded-lg bg-gray-10 px-1.5 py-1 text-fg-primary transition hover:opacity-80">
|
||||
<div class="w-fit flex flex-row items-center gap-x-1 rounded-lg bg-border/10 px-1.5 py-1 text-fg-primary transition hover:opacity-80">
|
||||
<OneConfigLogo class="h-3.5 w-3.5" />
|
||||
<span class="text-sm font-medium">OneConfig Integrated</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ function BrowserSidebar(props: { package: ManagedPackage }) {
|
|||
<LinkExternal01Icon class="h-4 w-4" />
|
||||
</div>
|
||||
<Show when={author.is_organization_user === true && ((authors()?.length || 0) > 1)}>
|
||||
<div class="h-px w-full bg-gray-05" />
|
||||
<div class="h-px w-full bg-border/05" />
|
||||
</Show>
|
||||
</>
|
||||
)}
|
||||
|
|
@ -481,7 +481,7 @@ function colorForType(type: string) {
|
|||
case 'alpha':
|
||||
return 'bg-code-error';
|
||||
default:
|
||||
return 'bg-gray-05';
|
||||
return 'bg-border/05';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ function ModEntry(props: ModEntryProps) {
|
|||
<div>
|
||||
<Show
|
||||
children={<img alt={name()} class="aspect-ratio-square h-10 rounded-lg" src={icon()!} />}
|
||||
fallback={<div class="aspect-ratio-square h-10 rounded-lg bg-gray-05" />}
|
||||
fallback={<div class="aspect-ratio-square h-10 rounded-lg bg-border/05" />}
|
||||
when={icon()}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -215,7 +215,7 @@ function ModEntry(props: ModEntryProps) {
|
|||
<span
|
||||
class="rounded-xl px-1.5 py-1 text-xs"
|
||||
classList={{
|
||||
'bg-gray-05 text-white/60': status === 'normal',
|
||||
'bg-border/05 text-white/60': status === 'normal',
|
||||
'bg-amber/10 text-amber': status === 'warning',
|
||||
'bg-danger/15 text-danger': status === 'danger',
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ function Banner(props: BannerProps) {
|
|||
|
||||
return (
|
||||
<div class="h-37 flex flex-row gap-x-2.5 rounded-xl bg-page-elevated p-2.5">
|
||||
<div class="relative aspect-ratio-video h-full min-w-57 w-57 overflow-hidden border border-gray-10 rounded-lg">
|
||||
<div class="relative aspect-ratio-video h-full min-w-57 w-57 overflow-hidden border border-border/10 rounded-lg">
|
||||
<Show when={props.editMode()}>
|
||||
<div
|
||||
class="absolute z-1 h-full w-full flex items-center justify-center bg-black/50 opacity-50 hover:opacity-100"
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ function ClusterScreenshots() {
|
|||
<h1>Screenshots</h1>
|
||||
<ScrollableContainer>
|
||||
<Show
|
||||
fallback={<div class="text-gray-400">No screenshots found. Press F2 in game to take a screenshot!</div>}
|
||||
fallback={<div class="text-border/400">No screenshots found. Press F2 in game to take a screenshot!</div>}
|
||||
when={list() !== undefined && list()!.length > 0}
|
||||
>
|
||||
<div class="grid grid-cols-[repeat(auto-fill,minmax(350px,1fr))] w-full transform-gpu gap-2">
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ function ClusterWorlds() {
|
|||
<h1>Worlds</h1>
|
||||
<ScrollableContainer>
|
||||
<Show
|
||||
fallback={<div class="text-gray-400">No worlds found.</div>}
|
||||
fallback={<div class="text-border/400">No worlds found.</div>}
|
||||
when={list() !== undefined && list()!.length > 0}
|
||||
>
|
||||
<div class="flex flex-col gap-2">
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ function OnboardingImport() {
|
|||
<For each={LAUNCHER_IMPORT_TYPES}>
|
||||
{type => (
|
||||
<button
|
||||
class={`flex flex-col items-center justify-center gap-y-4 rounded-md p-4 active:bg-gray-10 hover:bg-gray-05 ${(ctx.importInstances(type)?.instances.length || 0) > 0 ? 'bg-success hover:bg-success/70' : ''}`}
|
||||
class={`flex flex-col items-center justify-center gap-y-4 rounded-md p-4 active:bg-border/10 hover:bg-border/05 ${(ctx.importInstances(type)?.instances.length || 0) > 0 ? 'bg-success hover:bg-success/70' : ''}`}
|
||||
onClick={() => displayImport(type)}
|
||||
>
|
||||
<LauncherIcon class="h-16 max-w-22 min-w-16" launcher={type} />
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ function OnboardingLanguage() {
|
|||
class="flex flex-row items-center rounded-lg px-6 py-5"
|
||||
classList={{
|
||||
'bg-brand': language === getSelectedLanguage(),
|
||||
'hover:bg-gray-05 active:bg-gray-10': language !== getSelectedLanguage(),
|
||||
'hover:bg-border/05 active:bg-border/10': language !== getSelectedLanguage(),
|
||||
}}
|
||||
onClick={() => setSelected(code as Language)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -9,12 +9,20 @@ import Sidebar from '~ui/components/Sidebar';
|
|||
import useSettings from '~ui/hooks/useSettings';
|
||||
import { upperFirst } from '~utils';
|
||||
import { BROWSER_VIEWS } from '~utils/browser';
|
||||
import { createSignal, For } from 'solid-js';
|
||||
import { THEMES } from '~utils/theming';
|
||||
import { createEffect, createSignal, For } from 'solid-js';
|
||||
import SettingsRow from '../../../components/SettingsRow';
|
||||
|
||||
function SettingsAppearance() {
|
||||
const { settings, saveOnLeave } = useSettings();
|
||||
const [shouldReload, setShouldReload] = createSignal(false);
|
||||
const [theme, setTheme] = createSignal(settings().theme);
|
||||
|
||||
createEffect(() => {
|
||||
document.body.classList.add('theme-transition');
|
||||
document.body.setAttribute('data-theme', theme() ?? 'dark');
|
||||
setTimeout(() => document.body.classList.remove('theme-transition'), 300);
|
||||
});
|
||||
|
||||
useBeforeLeave((e) => {
|
||||
if (shouldReload()) {
|
||||
|
|
@ -27,18 +35,27 @@ function SettingsAppearance() {
|
|||
bridge.commands.setWindowStyle(settings().custom_frame!);
|
||||
});
|
||||
|
||||
// eslint-disable-next-line solid/reactivity -- This is a side effect
|
||||
saveOnLeave(() => ({
|
||||
disable_animations: settings().disable_animations!,
|
||||
custom_frame: settings().custom_frame!,
|
||||
theme: theme() ?? 'dark',
|
||||
}));
|
||||
|
||||
return (
|
||||
<Sidebar.Page>
|
||||
<h1>Appearance</h1>
|
||||
<ScrollableContainer>
|
||||
{/* <div class="flex flex-row items-center">
|
||||
<p>theme placeholder</p>
|
||||
</div> */}
|
||||
<div class="flex flex-row items-center gap-4">
|
||||
<PrimaryThemeCard theme={theme()} />
|
||||
<div class="grid grid-cols-3 h-full gap-4">
|
||||
<For each={THEMES}>
|
||||
{theme => (
|
||||
<ThemeCard setTheme={setTheme} theme={theme} />
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* <SettingsRow
|
||||
description="The main color used across the launcher. This doesn't edit your theme."
|
||||
|
|
@ -99,3 +116,49 @@ function SettingsAppearance() {
|
|||
}
|
||||
|
||||
export default SettingsAppearance;
|
||||
|
||||
interface ThemeCardProps {
|
||||
theme: string;
|
||||
setTheme: (theme: string) => void;
|
||||
};
|
||||
|
||||
function ThemeCard(props: ThemeCardProps) {
|
||||
return (
|
||||
<div class={`theme-${props.theme}`} onClick={() => props.setTheme(props.theme)}>
|
||||
<svg fill="none" height="78" viewBox="0 0 126 78" width="126" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect fill="rgb(var(--clr-page))" height="78" rx="8" width="126" />
|
||||
<rect height="77" rx="7.5" stroke="rgb(var(--clr-border))" stroke-opacity="0.1" width="125" x="0.5" y="0.5" />
|
||||
<path d="M8 16H116" stroke="rgb(var(--clr-fg-primary))" stroke-linecap="round" stroke-width="5" />
|
||||
<path d="M8 26H56" stroke="rgb(var(--clr-fg-secondary))" stroke-linecap="round" stroke-width="3" />
|
||||
<rect fill="rgb(var(--clr-brand))" fill-opacity="0.5" height="16" rx="4" width="64" x="54" y="54" />
|
||||
<path d="M54 58C54 55.7909 55.7909 54 58 54H86V70H58C55.7909 70 54 68.2091 54 66V58Z" fill="rgb(var(--clr-brand))" />
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface PrimaryThemeCardProps {
|
||||
theme: string | undefined;
|
||||
}
|
||||
|
||||
function PrimaryThemeCard(props: PrimaryThemeCardProps) {
|
||||
return (
|
||||
<div class={`theme-${props.theme ?? 'dark'}`}>
|
||||
<svg fill="none" height="183" viewBox="0 0 296 183" width="296" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect fill="rgb(var(--clr-page))" height="183" rx="16" width="296" />
|
||||
<rect height="180" rx="14.5" stroke="rgb(var(--clr-border))" stroke-opacity="0.1" stroke-width="1.5" width="293" x="1.5" y="1.5" />
|
||||
<rect fill="rgb(var(--clr-page-elevated))" height="123" rx="8" width="168" x="112" y="44" />
|
||||
<rect height="122" rx="7.5" stroke="rgb(var(--clr-border))" stroke-opacity="0.05" width="167" x="112.5" y="44.5" />
|
||||
<rect fill="rgb(var(--clr-brand))" fill-opacity="0.5" height="16" rx="4" width="64" x="208" y="143" />
|
||||
<path d="M132 64H240" stroke="rgb(var(--clr-fg-primary))" stroke-linecap="round" stroke-width="5" />
|
||||
<path d="M132 74H180" stroke="rgb(var(--clr-fg-secondary))" stroke-linecap="round" stroke-width="3" />
|
||||
<path d="M132 94H216" stroke="rgb(var(--clr-code-error))" stroke-linecap="round" stroke-width="4" />
|
||||
<path d="M132 104H192" stroke="rgb(var(--clr-code-warn))" stroke-linecap="round" stroke-width="4" />
|
||||
<path d="M132 114H210" stroke="rgb(var(--clr-code-info))" stroke-linecap="round" stroke-width="4" />
|
||||
<path d="M208 147C208 144.791 209.791 143 212 143H240V159H212C209.791 159 208 157.209 208 155V147Z" fill="rgb(var(--clr-brand))" />
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
48
apps/frontend/src/utils/theming.ts
Normal file
48
apps/frontend/src/utils/theming.ts
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
// When adding a theme, make sure to add the theme here and define the colors in the CSS file!
|
||||
export const THEMES = ['dark', 'light'] as const;
|
||||
|
||||
export const THEMABLE_PROPERTIES = [
|
||||
'clr-white',
|
||||
'clr-black',
|
||||
'clr-fg-primary',
|
||||
'clr-fg-primary-hover',
|
||||
'clr-fg-primary-pressed',
|
||||
'clr-fg-primary-disabled',
|
||||
'clr-fg-secondary',
|
||||
'clr-fg-secondary-hover',
|
||||
'clr-fg-secondary-pressed',
|
||||
'clr-fg-secondary-disabled',
|
||||
'clr-brand',
|
||||
'clr-brand-hover',
|
||||
'clr-brand-pressed',
|
||||
'clr-brand-disabled',
|
||||
'clr-onbrand',
|
||||
'clr-onbrand-hover',
|
||||
'clr-onbrand-pressed',
|
||||
'clr-onbrand-disabled',
|
||||
'clr-danger',
|
||||
'clr-danger-hover',
|
||||
'clr-danger-pressed',
|
||||
'clr-danger-disabled',
|
||||
'clr-success',
|
||||
'clr-success-hover',
|
||||
'clr-success-pressed',
|
||||
'clr-success-disabled',
|
||||
'clr-component-bg',
|
||||
'clr-component-bg-hover',
|
||||
'clr-component-bg-pressed',
|
||||
'clr-component-bg-disabled',
|
||||
'clr-code-info',
|
||||
'clr-code-warn',
|
||||
'clr-code-error',
|
||||
'clr-code-debug',
|
||||
'clr-code-trace',
|
||||
'clr-link',
|
||||
'clr-link-hover',
|
||||
'clr-link-pressed',
|
||||
'clr-link-disabled',
|
||||
'clr-page',
|
||||
'clr-page-elevated',
|
||||
'clr-page-pressed',
|
||||
'clr-secondary',
|
||||
] as const;
|
||||
|
|
@ -12,7 +12,6 @@ export default defineConfig({
|
|||
shortcuts: {},
|
||||
presets: [
|
||||
presetUno(),
|
||||
presetAttributify(),
|
||||
presetIcons(),
|
||||
],
|
||||
transformers: [
|
||||
|
|
@ -43,88 +42,85 @@ export default defineConfig({
|
|||
},
|
||||
|
||||
colors: {
|
||||
white: '#ffffff',
|
||||
black: '#000000',
|
||||
white: 'rgba(var(--clr-white), <alpha-value>)',
|
||||
black: 'rgba(var(--clr-black), <alpha-value>)',
|
||||
|
||||
gray: {
|
||||
'05': '#FFFFFF0D',
|
||||
'10': '#FFFFFF1A',
|
||||
},
|
||||
border: 'rgba(var(--clr-border), <alpha-value>)',
|
||||
|
||||
fg: {
|
||||
primary: {
|
||||
DEFAULT: '#D5DBFF',
|
||||
hover: '#D5DBFFD9',
|
||||
pressed: '#E1E5FF',
|
||||
disabled: '#E1E5FF80',
|
||||
DEFAULT: 'rgba(var(--clr-fg-primary), <alpha-value>)',
|
||||
hover: 'rgba(var(--clr-fg-primary-hover), <alpha-value>)',
|
||||
pressed: 'rgba(var(--clr-fg-primary-pressed), <alpha-value>)',
|
||||
disabled: 'rgba(var(--clr-fg-primary-disabled))',
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: '#78818D',
|
||||
hover: '#5F6874',
|
||||
pressed: '#828D9B',
|
||||
disabled: '#78818D80',
|
||||
DEFAULT: 'rgba(var(--clr-fg-secondary), <alpha-value>)',
|
||||
hover: 'rgba(var(--clr-fg-secondary-hover), <alpha-value>)',
|
||||
pressed: 'rgba(var(--clr-fg-secondary-pressed), <alpha-value>)',
|
||||
disabled: 'rgba(var(--clr-fg-secondary-disabled))',
|
||||
},
|
||||
},
|
||||
|
||||
brand: {
|
||||
DEFAULT: '#2B4BFF',
|
||||
hover: '#2843DD',
|
||||
pressed: '#3957FF',
|
||||
disabled: '#3957FF80',
|
||||
DEFAULT: 'rgba(var(--clr-brand), <alpha-value>)',
|
||||
hover: 'rgba(var(--clr-brand-hover), <alpha-value>)',
|
||||
pressed: 'rgba(var(--clr-brand-pressed), <alpha-value>)',
|
||||
disabled: 'rgba(var(--clr-brand-disabled))',
|
||||
},
|
||||
|
||||
onbrand: {
|
||||
DEFAULT: '#D5DBFF',
|
||||
hover: '#D5DBFFD9',
|
||||
pressed: '#E1E5FF',
|
||||
disabled: '#E1E5FF80',
|
||||
DEFAULT: 'rgba(var(--clr-onbrand), <alpha-value>)',
|
||||
hover: 'rgba(var(--clr-onbrand-hover), <alpha-value>)',
|
||||
pressed: 'rgba(var(--clr-onbrand-pressed), <alpha-value>)',
|
||||
disabled: 'rgba(var(--clr-onbrand-disabled))',
|
||||
},
|
||||
|
||||
danger: {
|
||||
DEFAULT: '#FF4444',
|
||||
hover: '#D63434',
|
||||
pressed: '#FF5656',
|
||||
disabled: '#FF444480',
|
||||
DEFAULT: 'rgba(var(--clr-danger), <alpha-value>)',
|
||||
hover: 'rgba(var(--clr-danger-hover), <alpha-value>)',
|
||||
pressed: 'rgba(var(--clr-danger-pressed), <alpha-value>)',
|
||||
disabled: 'rgba(var(--clr-danger-disabled))',
|
||||
},
|
||||
|
||||
success: {
|
||||
DEFAULT: '#239A60',
|
||||
hover: '#1A8752',
|
||||
pressed: '#2CAC6E',
|
||||
disabled: '#239A6080',
|
||||
DEFAULT: 'rgba(var(--clr-success), <alpha-value>)',
|
||||
hover: 'rgba(var(--clr-success-hover), <alpha-value>)',
|
||||
pressed: 'rgba(var(--clr-success-pressed), <alpha-value>)',
|
||||
disabled: 'rgba(var(--clr-success-disabled))',
|
||||
},
|
||||
|
||||
component: {
|
||||
bg: {
|
||||
DEFAULT: '#1A2229',
|
||||
hover: '#171F25',
|
||||
pressed: '#222C35',
|
||||
disabled: '#1A222980',
|
||||
DEFAULT: 'rgba(var(--clr-component-bg), <alpha-value>)',
|
||||
hover: 'rgba(var(--clr-component-bg-hover), <alpha-value>)',
|
||||
pressed: 'rgba(var(--clr-component-bg-pressed), <alpha-value>)',
|
||||
disabled: 'rgba(var(--clr-component-bg-disabled))',
|
||||
},
|
||||
},
|
||||
|
||||
code: {
|
||||
info: '#61AFEF',
|
||||
warn: '#E5C07B',
|
||||
error: '#BE5046',
|
||||
debug: '#2B4BFF',
|
||||
trace: '#FDFDFD',
|
||||
info: 'rgba(var(--clr-code-info), <alpha-value>)',
|
||||
warn: 'rgba(var(--clr-code-warn), <alpha-value>)',
|
||||
error: 'rgba(var(--clr-code-error), <alpha-value>)',
|
||||
debug: 'rgba(var(--clr-code-debug), <alpha-value>)',
|
||||
trace: 'rgba(var(--clr-code-trace), <alpha-value>)',
|
||||
},
|
||||
|
||||
link: {
|
||||
DEFAULT: '#61AFEF',
|
||||
hover: '#5F87FF',
|
||||
pressed: '#72AFFF',
|
||||
disabled: '#61AFEF80',
|
||||
DEFAULT: 'rgba(var(--clr-link), <alpha-value>)',
|
||||
hover: 'rgba(var(--clr-link-hover), <alpha-value>)',
|
||||
pressed: 'rgba(var(--clr-link-pressed), <alpha-value>)',
|
||||
disabled: 'rgba(var(--clr-link-disabled))',
|
||||
},
|
||||
|
||||
page: {
|
||||
DEFAULT: '#11171c',
|
||||
elevated: '#151c22',
|
||||
pressed: '#0e1317',
|
||||
DEFAULT: 'rgba(var(--clr-page), <alpha-value>)',
|
||||
elevated: 'rgba(var(--clr-page-elevated), <alpha-value>)',
|
||||
pressed: 'rgba(var(--clr-page-pressed), <alpha-value>)',
|
||||
},
|
||||
|
||||
secondary: '#192026',
|
||||
secondary: 'rgba(var(--clr-secondary), <alpha-value>)',
|
||||
},
|
||||
extend: {
|
||||
height: {
|
||||
|
|
@ -138,22 +134,6 @@ export default defineConfig({
|
|||
backgroundColor: {
|
||||
transparent: 'transparent',
|
||||
},
|
||||
|
||||
// animation: {
|
||||
// 'fade-in': 'fadeIn 150ms easeOutExpo forwards',
|
||||
// 'fade-out': 'fadeOut 150ms easeOutExpo forwards',
|
||||
// },
|
||||
|
||||
// keyframes: {
|
||||
// fadeIn: {
|
||||
// '0%': { opacity: '0' },
|
||||
// '100%': { opacity: '1' },
|
||||
// },
|
||||
// fadeOut: {
|
||||
// '0%': { opacity: '1' },
|
||||
// '100%': { opacity: '0' },
|
||||
// },
|
||||
// },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
24
packages/client/src/bindings.ts
generated
24
packages/client/src/bindings.ts
generated
|
|
@ -968,9 +968,9 @@ export interface SearchResult { slug: string; title: string; description: string
|
|||
*/
|
||||
export interface Settings {
|
||||
/**
|
||||
* A `OneLauncher` [`Theme`] managed by the core GUI.
|
||||
* A `OneLauncher` theme managed by the `OneLauncher` GUI.
|
||||
*/
|
||||
theme: Theme;
|
||||
theme?: string;
|
||||
/**
|
||||
* A global browser list view for the `OneLauncher` GUI.
|
||||
*/
|
||||
|
|
@ -1060,26 +1060,6 @@ export interface Settings {
|
|||
*/
|
||||
onboarding_completed?: boolean;
|
||||
};
|
||||
/**
|
||||
* A `OneLauncher` theme managed by the GUI.
|
||||
*/
|
||||
export type Theme =
|
||||
/**
|
||||
* A default Dark theme.
|
||||
*/
|
||||
'dark' |
|
||||
/**
|
||||
* A default Light theme.
|
||||
*/
|
||||
'light' |
|
||||
/**
|
||||
* OLED Dark Theme.
|
||||
*/
|
||||
'oled' |
|
||||
/**
|
||||
* Cute and colorful theme.
|
||||
*/
|
||||
'cat';
|
||||
export interface Update { version: string };
|
||||
/**
|
||||
* A game version of Minecraft
|
||||
|
|
|
|||
|
|
@ -13,6 +13,18 @@ export async function initProgramInfo() {
|
|||
const result = await commands.getProgramInfo();
|
||||
if (result.status === 'ok')
|
||||
_programInfo = result.data;
|
||||
|
||||
setBodyAttributes();
|
||||
}
|
||||
|
||||
export const getProgramInfo = () => _programInfo;
|
||||
|
||||
function setBodyAttributes() {
|
||||
document.body.setAttribute('data-platform', _programInfo.platform);
|
||||
if (_programInfo.platform === 'linux') {
|
||||
const minorVersion = Number.parseInt(_programInfo.webview_version.split('.')[1] || 'NaN');
|
||||
|
||||
// Check if WebKitGTK version is 2.46 or higher (Skia renderer implemented which fixes some issues)
|
||||
document.body.setAttribute('data-skia-renderer', (!Number.isNaN(minorVersion) && minorVersion >= 46).toString());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ pub mod data {
|
|||
pub use crate::store::{
|
||||
ClusterMeta, Credentials, Directories, InitHooks, JavaOptions, Loader, ManagedDependency,
|
||||
ManagedPackage, ManagedUser, ManagedVersion, Memory, MinecraftCredentials, PackageData,
|
||||
PackageType, Resolution, Settings, Theme,
|
||||
PackageType, Resolution, Settings,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,9 @@ use std::path::{Path, PathBuf};
|
|||
#[cfg_attr(feature = "specta", derive(specta::Type))]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Settings {
|
||||
/// A `OneLauncher` [`Theme`] managed by the core GUI.
|
||||
pub theme: Theme,
|
||||
/// A `OneLauncher` theme managed by the `OneLauncher` GUI.
|
||||
#[serde(default = "theme_default")]
|
||||
pub theme: String,
|
||||
/// A global browser list view for the `OneLauncher` GUI.
|
||||
#[serde(default)]
|
||||
pub browser_list_view: BrowserListView,
|
||||
|
|
@ -71,6 +72,10 @@ pub struct Settings {
|
|||
pub onboarding_completed: bool,
|
||||
}
|
||||
|
||||
fn theme_default() -> String {
|
||||
"dark".to_string()
|
||||
}
|
||||
|
||||
impl Settings {
|
||||
/// Initializes the global settings state.
|
||||
#[tracing::instrument]
|
||||
|
|
@ -103,7 +108,7 @@ impl Settings {
|
|||
Ok(settings)
|
||||
} else {
|
||||
let settings = Self {
|
||||
theme: Theme::Dark,
|
||||
theme: "dark".to_string(),
|
||||
browser_list_view: BrowserListView::Grid,
|
||||
hide_close_prompt: true,
|
||||
disable_animations: false,
|
||||
|
|
@ -157,21 +162,6 @@ pub enum BrowserListView {
|
|||
List,
|
||||
}
|
||||
|
||||
/// A `OneLauncher` theme managed by the GUI.
|
||||
#[cfg_attr(feature = "specta", derive(specta::Type))]
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Theme {
|
||||
/// A default Dark theme.
|
||||
Dark,
|
||||
/// A default Light theme.
|
||||
Light,
|
||||
/// OLED Dark Theme.
|
||||
Oled,
|
||||
/// Cute and colorful theme.
|
||||
Cat,
|
||||
}
|
||||
|
||||
/// Global memory settings across all clusters.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
|
||||
#[cfg_attr(feature = "specta", derive(specta::Type))]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue