diff --git a/package.json b/package.json index 1e336be..86ec34f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@methanium/ui", - "version": "0.0.29", + "version": "0.0.32", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/src/cmp/spinner.tsx b/src/cmp/spinner.tsx index 67168b4..ef8d12f 100644 --- a/src/cmp/spinner.tsx +++ b/src/cmp/spinner.tsx @@ -6,7 +6,7 @@ function Spinner({ className, ...props }: React.ComponentProps<"svg">) { ); diff --git a/src/markdown/code-block.tsx b/src/markdown/code-block.tsx index 3266dbc..a3ed488 100644 --- a/src/markdown/code-block.tsx +++ b/src/markdown/code-block.tsx @@ -71,7 +71,7 @@ function CodeBlock({ data-slot="code-block" data-line-numbers={showLineNumbers || undefined} data-language={language || undefined} - className="group/code-block overflow-hidden rounded-lg border-[length:var(--ui-border-width)] border-border bg-[var(--markdown-code-background)] my-2!" + className="group/code-block overflow-hidden rounded-lg border-[length:var(--ui-border-width)] border-border bg-[var(--markdown-code-background,var(--markdown-code-background-default))] my-2!" >
storedDesign(designStorageKey, initialDesign), ); + const [notCustomized, setNotCustomizedState] = useState(() => { + const stored = storageValue(notCustomizedStorageKey); + if (stored !== null) return stored === "true"; + return Boolean( + initialParent && + themeColor === "" && + themePalette === null && + themePrimaryColor === "" && + themeTint === "soft" && + themeBorderRadius === initialBorderRadius && + designsEqual(themeDesign, initialDesign) && + themeCustomCss === initialParent.css, + ); + }); const [systemPolarity, setSystemPolarity] = useState( () => getSystemTheme(), ); @@ -198,13 +213,22 @@ export function ThemeProvider({ const resolvedPolarity = themePolarity === "system" ? systemPolarity : themePolarity; + const setNotCustomized = useCallback( + (next: boolean) => { + saveStoredValue(notCustomizedStorageKey, String(next)); + setNotCustomizedState(next); + }, + [notCustomizedStorageKey], + ); + const setParentThemeId = useCallback( (id: string | null) => { const next = findTheme(themes, id)?.id ?? null; saveStoredValue(parentThemeStorageKey, next ?? ""); setParentThemeIdState(next); + setNotCustomized(false); }, - [parentThemeStorageKey, themes], + [parentThemeStorageKey, setNotCustomized, themes], ); const setThemePolarity = useCallback( @@ -219,30 +243,34 @@ export function ThemeProvider({ if (!isThemeColor(next)) return; saveStoredValue(colorStorageKey, next); setThemeColorState(next); + setNotCustomized(false); }, - [colorStorageKey], + [colorStorageKey, setNotCustomized], ); const setThemePalette = useCallback( (next: Base16Palette | null) => { saveStoredValue(paletteStorageKey, serializeBase16Palette(next)); setThemePaletteState(next); + setNotCustomized(false); }, - [paletteStorageKey], + [paletteStorageKey, setNotCustomized], ); const setThemePrimaryColor = useCallback( (next: string) => { if (!isThemeColor(next)) return; saveStoredValue(primaryColorStorageKey, next); setThemePrimaryColorState(next); + setNotCustomized(false); }, - [primaryColorStorageKey], + [primaryColorStorageKey, setNotCustomized], ); const setThemeTint = useCallback( (next: ThemeTint) => { saveStoredValue(tintStorageKey, next); setThemeTintState(next); + setNotCustomized(false); }, - [tintStorageKey], + [setNotCustomized, tintStorageKey], ); const setThemeBorderRadius = useCallback( (next: number) => { @@ -250,25 +278,28 @@ export function ThemeProvider({ if (radius === null) return; saveStoredValue(borderRadiusStorageKey, String(radius)); setThemeBorderRadiusState(radius); + setNotCustomized(false); }, - [borderRadiusStorageKey], + [borderRadiusStorageKey, setNotCustomized], ); const setThemeCustomCss = useCallback( (next: string) => { saveStoredValue(customCssStorageKey, next); setThemeCustomCssState(next); + setNotCustomized(false); }, - [customCssStorageKey], + [customCssStorageKey, setNotCustomized], ); const setThemeDesign = useCallback( (next: ThemeDesign | ((current: ThemeDesign) => ThemeDesign)) => { + setNotCustomized(false); setThemeDesignState((current) => { const value = typeof next === "function" ? next(current) : next; saveStoredValue(designStorageKey, JSON.stringify(value)); return value; }); }, - [designStorageKey], + [designStorageKey, setNotCustomized], ); const applyThemePreset = useCallback( @@ -283,6 +314,7 @@ export function ThemeProvider({ setThemeBorderRadius(presetBorderRadius(preset, defaultBorderRadius)); setThemeDesign(presetDesign(preset, defaultDesign)); setThemeCustomCss(preset.css); + setNotCustomized(true); }, [ defaultDesign, @@ -295,6 +327,7 @@ export function ThemeProvider({ setThemePalette, setThemePrimaryColor, setThemeTint, + setNotCustomized, themes, ], ); @@ -302,6 +335,13 @@ export function ThemeProvider({ if (parentTheme) applyThemePreset(parentTheme.id); }, [applyThemePreset, parentTheme]); + useEffect(() => { + if (typeof window === "undefined") return; + if (storageValue(notCustomizedStorageKey) === null) { + saveStoredValue(notCustomizedStorageKey, String(notCustomized)); + } + }, [notCustomized, notCustomizedStorageKey]); + useEffect(() => { if (typeof window === "undefined") return; const mediaQuery = window.matchMedia(COLOR_SCHEME_QUERY); @@ -310,6 +350,14 @@ export function ThemeProvider({ return () => mediaQuery.removeEventListener("change", handleChange); }, []); + useIsomorphicLayoutEffect(() => { + if (!notCustomized || !parentTheme || themeCustomCss === parentTheme.css) { + return; + } + saveStoredValue(customCssStorageKey, parentTheme.css); + setThemeCustomCssState(parentTheme.css); + }, [customCssStorageKey, notCustomized, parentTheme, themeCustomCss]); + useIsomorphicLayoutEffect(() => { if (typeof document === "undefined") return; const root = document.documentElement; @@ -422,6 +470,9 @@ export function ThemeProvider({ parseDesign(stored, presetDesign(parentTheme, defaultDesign)), ), ); + register(notCustomizedStorageKey, (stored) => + setNotCustomizedState(stored === "true"), + ); const handleStorageChange = (event: StorageEvent) => { if (event.storageArea !== localStorage) return; if (event.key) handlers.get(event.key)?.(event.newValue); @@ -440,6 +491,7 @@ export function ThemeProvider({ defaultTheme, defaultTint, designStorageKey, + notCustomizedStorageKey, paletteStorageKey, parentThemeStorageKey, parentTheme, @@ -449,22 +501,7 @@ export function ThemeProvider({ tintStorageKey, ]); - const parentDesign = presetDesign(parentTheme, defaultDesign); - const parentBorderRadius = presetBorderRadius( - parentTheme, - defaultBorderRadius, - ); - - const isThemeCustomized = Boolean( - parentTheme && - (themeCustomCss !== parentTheme.css || - themeColor !== "" || - themePalette !== null || - themePrimaryColor !== "" || - themeTint !== "soft" || - themeBorderRadius !== parentBorderRadius || - !designsEqual(themeDesign, parentDesign)), - ); + const isThemeCustomized = Boolean(parentTheme && !notCustomized); const value = useMemo( () => ({ @@ -492,12 +529,14 @@ export function ThemeProvider({ applyThemePreset, resetThemePreset, isThemeCustomized, + notCustomized, themeDesign, setThemeDesign, }), [ applyThemePreset, isThemeCustomized, + notCustomized, parentTheme, parentThemeId, resetThemePreset, diff --git a/src/theme/presets.ts b/src/theme/presets.ts index f110ab2..9601782 100644 --- a/src/theme/presets.ts +++ b/src/theme/presets.ts @@ -51,6 +51,7 @@ export const BUILT_IN_THEMES = defineThemes([ --ring: oklch(0.62 0.12 185); --sidebar: color-mix(in oklch, var(--background) 97%, black); --sidebar-primary: oklch(0.58 0.12 185); + --markdown-code-background: color-mix(in oklch, var(--muted) 72%, var(--background)); --tensamin-outline-background: #fff; --tensamin-outline-hover: #0000000a; --tensamin-outline-pressed: #00000014; @@ -73,6 +74,7 @@ export const BUILT_IN_THEMES = defineThemes([ --primary: oklch(0.69 0.12 184); --primary-foreground: oklch(0.16 0.025 190); --primary-foreground-alt: oklch(0.73 0.13 183); + --markdown-code-background: color-mix(in oklch, var(--card) 76%, black 24%); --tensamin-outline-background: #ffffff0f; --tensamin-outline-hover: #ffffff0f; --tensamin-outline-pressed: #ffffff1a; @@ -247,6 +249,7 @@ export const BUILT_IN_THEMES = defineThemes([ --chart-3: #aca1cf; --chart-4: #e29eca; --chart-5: #e5c890; + --markdown-code-background: color-mix(in srgb, var(--muted) 78%, var(--background)); } :root.dark[data-theme="og-tensamin"] { --background: #0f1014; @@ -281,6 +284,7 @@ export const BUILT_IN_THEMES = defineThemes([ --chart-3: #aca1cf; --chart-4: #e29eca; --chart-5: #e5c890; + --markdown-code-background: color-mix(in srgb, var(--muted) 72%, black 28%); } :root[data-theme="og-tensamin"] :where([data-slot="select-content"], [data-slot="dropdown-menu-content"], [data-slot="dropdown-menu-sub-content"], [data-slot="context-menu-content"], [data-slot="context-menu-sub-content"], [data-slot="menubar-content"], [data-slot="menubar-sub-content"], [data-slot="combobox-content"], [data-slot="popover-content"], [data-slot="hover-card-content"]) { background-color: var(--popover); @@ -323,7 +327,7 @@ export const BUILT_IN_THEMES = defineThemes([ --accent: #cf8fe633; --accent-foreground: #642f79; --destructive: #b91c1c; - --border: #242D38; + --border: #b7c2cc; --input: #b7c2cc; --ring: #9d53bc; --chart-1: #8c47ad; @@ -337,8 +341,9 @@ export const BUILT_IN_THEMES = defineThemes([ --sidebar-primary-foreground: #ffffff; --sidebar-accent: #cf8fe633; --sidebar-accent-foreground: #642f79; - --sidebar-border: #242D38; + --sidebar-border: #b7c2cc; --sidebar-ring: #9d53bc; + --markdown-code-background: color-mix(in srgb, var(--input) 55%, var(--background)); } :root.dark[data-theme="methanium"] { --background: #171E26; @@ -373,6 +378,7 @@ export const BUILT_IN_THEMES = defineThemes([ --sidebar-accent-foreground: #d2e0f0; --sidebar-border: #242D38; --sidebar-ring: #cf8fe6; + --markdown-code-background: color-mix(in srgb, var(--input) 55%, var(--background)); } :root[data-theme="methanium"] body { background-color: var(--background); @@ -435,8 +441,8 @@ export const BUILT_IN_THEMES = defineThemes([ } :root[data-theme="methanium"] [data-slot="card"] { padding-block: calc(1rem * var(--ui-density)); - border: none; - background-color: #242D38; + border: 1px solid var(--input); + background-color: color-mix(in srgb, var(--input) 55%, var(--background)); } :root[data-theme="methanium"] [data-slot="button"][data-variant="default"] { background-color: var(--primary); @@ -506,175 +512,464 @@ export const BUILT_IN_THEMES = defineThemes([ }, css: `:root[data-theme="secret"] { --secret-border: color-mix(in srgb, #2f1b13 22%, #fffaf2 78%); - --secret-control: #5e244e; + + --secret-purple: #d7a8c9; + --secret-control: var(--secret-purple); + --secret-gold: color-mix(in srgb, #f9b637 75%, #2f1b13 25%); --secret-gold-dark: color-mix(in srgb, var(--secret-gold) 60%, #2f1b13 40%); --secret-gold-light: color-mix(in srgb, var(--secret-gold) 45%, #ffe8b4 55%); + --background: oklch(0.98 0 0); --foreground: #2f1b13; + --card: var(--background); --card-foreground: var(--foreground); - --popover: #5e244e; - --popover-foreground: #fffaf2; + + --popover: var(--secret-purple); + --popover-foreground: #2f1b13; + --primary: var(--secret-gold); --primary-foreground: #24120c; - --primary-foreground-alt: #fb6c00; - --secondary: #5e244e; - --secondary-foreground: #fffaf2; - --muted: #24120c; - --muted-foreground: #6b7280; + --primary-foreground-alt: #c04b00; + + --secondary: var(--secret-purple); + --secondary-foreground: #2f1b13; + + --muted: #c89ab9; + --muted-foreground: #49333f; + --accent: #fb6c00; --accent-foreground: #24120c; - --destructive: #e73f1e; + + --destructive: #d93618; + --destructive-foreground: #fffaf2; + --border: var(--secret-border); --input: var(--secret-border); - --ring: #fb6c00; + --ring: #4a2110; + --sidebar: color-mix(in oklch, var(--background) 97%, black); --sidebar-foreground: #2f1b13; --sidebar-primary: var(--secret-gold); --sidebar-primary-foreground: #24120c; - --sidebar-accent: #aa1c41; - --sidebar-accent-foreground: #fffaf2; + --sidebar-accent: #d7a8c9; + --sidebar-accent-foreground: #2f1b13; --sidebar-border: var(--secret-border); + + --markdown-code-background: color-mix( + in srgb, + var(--secret-gold) 9%, + var(--background) + ); } + :root.dark[data-theme="secret"] { - --secret-border: color-mix(in srgb, #ffe8b4 15%, #24120c 85%); - --secret-control: #5e244e; - --background: #0A0A0A; + --secret-border: color-mix(in srgb, #ffe8b4 8%, #24120c 35%); + + --secret-purple: #5e244e; + --secret-control: var(--secret-purple); + + --background: #0a0a0a; --foreground: #ffe8b4; + --card: var(--background); --card-foreground: var(--foreground); + --popover: #2f1b13; --popover-foreground: #ffe8b4; + --primary: var(--secret-gold); --primary-foreground: #24120c; --primary-foreground-alt: #fb6c00; - --secondary: #5e244e; + + --secondary: var(--secret-purple); --secondary-foreground: #fffaf2; + --muted: #2f1b13; --muted-foreground: #e68457; - --accent: #e73f1e; + + --accent: #d93618; --accent-foreground: #fffaf2; - --destructive: #e73f1e; + + --destructive: #d93618; + --destructive-foreground: #fffaf2; + --border: var(--secret-border); --input: var(--secret-border); - --ring: #fb6c00; - --sidebar: #0F0F0F; + --ring: #f9b637; + + --sidebar: #0f0f0f; --sidebar-foreground: #ffe8b4; --sidebar-primary: var(--secret-gold); --sidebar-primary-foreground: #24120c; --sidebar-accent: #aa1c41; --sidebar-accent-foreground: #fffaf2; --sidebar-border: var(--secret-border); + + --markdown-code-background: color-mix( + in srgb, + var(--muted) 72%, + black 28% + ); } -:root[data-theme="secret"] :where([data-slot="button"], [data-slot="toggle"], [data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"], [data-slot="checkbox"], [data-slot="radio-group-item"], [data-slot="switch"]) { - background-image: linear-gradient(to top, rgb(255 255 255 / 12%), rgb(255 255 255 / 2%)); + +:root[data-theme="secret"] :where( + [data-slot="button"], + [data-slot="toggle"], + [data-slot="input"], + [data-slot="textarea"], + [data-slot="native-select"], + [data-slot="select-trigger"], + [data-slot="input-group"], + [data-slot="checkbox"], + [data-slot="radio-group-item"], + [data-slot="switch"] +) { + background-image: linear-gradient( + to top, + rgb(255 255 255 / 12%), + rgb(255 255 255 / 2%) + ); background-repeat: no-repeat; } + :root[data-theme="secret"] [data-slot="button"][data-variant="ghost"] { background-image: none; } + :root[data-theme="secret"] [data-slot="button"][data-variant="ghost"]:hover { - background-image: linear-gradient(to top, rgb(255 255 255 / 12%), rgb(255 255 255 / 2%)); + background-image: linear-gradient( + to top, + rgb(255 255 255 / 12%), + rgb(255 255 255 / 2%) + ); } + :root[data-theme="secret"] [data-slot="button"][data-variant="subtleDefault"] { - background-image: linear-gradient(to top, rgb(255 232 180 / 12%), rgb(255 232 180 / 2%)); + background-image: linear-gradient( + to top, + rgb(255 232 180 / 12%), + rgb(255 232 180 / 2%) + ); color: var(--foreground); } -:root:not(.dark)[data-theme="secret"] [data-slot="button"][data-variant="subtleDefault"] { - background-color: color-mix(in srgb, var(--primary-foreground-alt) 6%, transparent); - background-image: linear-gradient(to top, rgb(255 232 180 / 30%), rgb(255 232 180 / 80%)); + +:root:not(.dark)[data-theme="secret"] + [data-slot="button"][data-variant="subtleDefault"] { + background-color: color-mix( + in srgb, + var(--primary-foreground-alt) 6%, + transparent + ); + background-image: linear-gradient( + to top, + rgb(255 232 180 / 30%), + rgb(255 232 180 / 80%) + ); } -:root[data-theme="secret"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]) { + +:root[data-theme="secret"] :where( + [data-slot="input"], + [data-slot="textarea"], + [data-slot="native-select"], + [data-slot="select-trigger"], + [data-slot="input-group"] +) { background-color: var(--secret-control); border-color: transparent; - color: var(--foreground); } -:root:not(.dark)[data-theme="secret"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]) { - color: #fffaf2; + +:root:not(.dark)[data-theme="secret"] :where( + [data-slot="input"], + [data-slot="textarea"], + [data-slot="native-select"], + [data-slot="select-trigger"], + [data-slot="input-group"] +) { + color: #2f1b13; } -:root[data-theme="secret"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]):hover { - background-color: color-mix(in srgb, var(--secret-control) 84%, #24120c 16%); + +:root.dark[data-theme="secret"] :where( + [data-slot="input"], + [data-slot="textarea"], + [data-slot="native-select"], + [data-slot="select-trigger"], + [data-slot="input-group"] +) { + color: #ffe8b4; +} + +:root:not(.dark)[data-theme="secret"] :where( + [data-slot="input"], + [data-slot="textarea"] +)::placeholder { + color: #5f4558; + opacity: 1; +} + +:root.dark[data-theme="secret"] :where( + [data-slot="input"], + [data-slot="textarea"] +)::placeholder { + color: #d9b99c; + opacity: 1; +} + +:root:not(.dark)[data-theme="secret"] :where( + [data-slot="input"], + [data-slot="textarea"], + [data-slot="native-select"], + [data-slot="select-trigger"], + [data-slot="input-group"] +):hover { + background-color: color-mix( + in srgb, + var(--secret-control) 88%, + #622a53 12% + ); border-color: transparent; } -:root[data-theme="secret"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]):is(:focus-visible, :focus-within) { - background-color: color-mix(in srgb, var(--secret-control) 84%, #24120c 16%); + +:root.dark[data-theme="secret"] :where( + [data-slot="input"], + [data-slot="textarea"], + [data-slot="native-select"], + [data-slot="select-trigger"], + [data-slot="input-group"] +):hover { + background-color: color-mix( + in srgb, + var(--secret-control) 84%, + #24120c 16% + ); border-color: transparent; } -:root[data-theme="secret"] [data-slot="select-trigger"]:is([data-popup-open], [data-open], [aria-expanded="true"]) { - background-color: color-mix(in srgb, var(--secret-control) 84%, #24120c 16%); + +:root:not(.dark)[data-theme="secret"] :where( + [data-slot="input"], + [data-slot="textarea"], + [data-slot="native-select"], + [data-slot="select-trigger"], + [data-slot="input-group"] +):is(:focus-visible, :focus-within) { + background-color: color-mix( + in srgb, + var(--secret-control) 88%, + #622a53 12% + ); border-color: transparent; } + +:root.dark[data-theme="secret"] :where( + [data-slot="input"], + [data-slot="textarea"], + [data-slot="native-select"], + [data-slot="select-trigger"], + [data-slot="input-group"] +):is(:focus-visible, :focus-within) { + background-color: color-mix( + in srgb, + var(--secret-control) 84%, + #24120c 16% + ); + border-color: transparent; +} + +:root:not(.dark)[data-theme="secret"] + [data-slot="select-trigger"]:is( + [data-popup-open], + [data-open], + [aria-expanded="true"] + ) { + background-color: color-mix( + in srgb, + var(--secret-control) 88%, + #622a53 12% + ); + border-color: transparent; +} + +:root.dark[data-theme="secret"] + [data-slot="select-trigger"]:is( + [data-popup-open], + [data-open], + [aria-expanded="true"] + ) { + background-color: color-mix( + in srgb, + var(--secret-control) 84%, + #24120c 16% + ); + border-color: transparent; +} + :root[data-theme="secret"] [data-slot="select-content"] { background-color: var(--popover); border-color: var(--secret-border); color: var(--popover-foreground); } -:root.dark[data-theme="secret"] [data-slot="select-content"] { - border-color: var(--secret-border); + +:root:not(.dark)[data-theme="secret"] :where( + [data-slot="select-item"], + [data-slot="context-menu-item"], + [data-slot="context-menu-sub-trigger"] +):is( + :hover, + :focus, + [data-highlighted], + [data-selected], + [data-open] +) { + background-color: color-mix( + in srgb, + var(--popover) 82%, + #622a53 18% + ); + color: #2f1b13; } -:root[data-theme="secret"] :where([data-slot="select-item"], [data-slot="context-menu-item"], [data-slot="context-menu-sub-trigger"]):is(:hover, :focus, [data-highlighted], [data-selected], [data-open]) { - background-color: color-mix(in srgb, var(--popover) 72%, #0a0a0a 28%); + +:root.dark[data-theme="secret"] :where( + [data-slot="select-item"], + [data-slot="context-menu-item"], + [data-slot="context-menu-sub-trigger"] +):is( + :hover, + :focus, + [data-highlighted], + [data-selected], + [data-open] +) { + background-color: color-mix( + in srgb, + var(--popover) 72%, + #0a0a0a 28% + ); color: #ffe8b4; } + :root[data-theme="secret"] [data-slot="button"][data-variant="default"] { background-color: var(--primary); - background-image: linear-gradient(to top, rgb(255 255 255 / 12%), rgb(255 255 255 / 2%)), linear-gradient(115deg, var(--secret-gold-dark) 0%, var(--secret-gold) 30%, var(--secret-gold-light) 47%, var(--secret-gold) 62%, var(--secret-gold-dark) 100%); + background-image: + linear-gradient( + to top, + rgb(255 255 255 / 12%), + rgb(255 255 255 / 2%) + ), + linear-gradient( + 115deg, + var(--secret-gold-dark) 0%, + var(--secret-gold) 30%, + var(--secret-gold-light) 47%, + var(--secret-gold) 62%, + var(--secret-gold-dark) 100% + ); border-color: var(--secret-border); color: var(--primary-foreground); text-shadow: 0 1px rgb(255 255 255 / 35%); - box-shadow: inset 0 1px rgb(255 255 255 / 45%), 0 0.45rem 1.2rem rgb(36 18 12 / 28%); + box-shadow: + inset 0 1px rgb(255 255 255 / 45%), + 0 0.45rem 1.2rem rgb(36 18 12 / 28%); } -:root[data-theme="secret"] :where([data-slot="card"], [data-slot="dialog-content"], [data-slot="alert-dialog-content"]) { + +:root[data-theme="secret"] :where( + [data-slot="card"], + [data-slot="dialog-content"], + [data-slot="alert-dialog-content"] +) { border-color: var(--secret-border); - box-shadow: inset 0 1px color-mix(in oklch, white 8%, transparent), 0 1rem 3rem rgb(97 37 82 / 12%); + box-shadow: + inset 0 1px color-mix(in oklch, white 8%, transparent), + 0 1rem 3rem rgb(97 37 82 / 12%); } + :root[data-theme="secret"] [data-slot="card"] { background: var(--card); } -:root[data-theme="secret"] :where([data-slot="button"][data-variant="outline"], [data-slot="button"][data-variant="link"], [data-slot="badge"][data-variant="outline"], [data-slot="toggle"][data-variant="outline"]) { + +:root[data-theme="secret"] :where( + [data-slot="button"][data-variant="outline"], + [data-slot="button"][data-variant="link"], + [data-slot="badge"][data-variant="outline"], + [data-slot="toggle"][data-variant="outline"] +) { background-color: var(--secondary); border-color: transparent; color: var(--secondary-foreground); } + :root[data-theme="secret"] [data-slot="button"][data-variant="link"] { background-image: none; } + :root[data-theme="secret"] [data-slot="button"][data-variant="link"]:hover { background-color: var(--secondary); background-image: none; } -:root[data-theme="secret"] [data-slot="button"][data-variant="outline"]:hover { - background-color: color-mix(in srgb, #5e244e 82%, #24120c 18%); + +:root:not(.dark)[data-theme="secret"] :where( + [data-slot="button"], + [data-slot="badge"], + [data-slot="toggle"] +)[data-variant="outline"]:is( + :hover, + :focus-visible, + [aria-expanded="true"], + [data-popup-open], + [data-open] +) { + background-color: color-mix( + in srgb, + var(--secondary) 82%, + #622a53 18% + ); border-color: transparent; + color: var(--secondary-foreground); } -:root[data-theme="secret"] :where([data-slot="badge"], [data-slot="toggle"])[data-variant="outline"]:hover { - background-color: color-mix(in srgb, #5e244e 82%, #24120c 18%); + +:root.dark[data-theme="secret"] :where( + [data-slot="button"], + [data-slot="badge"], + [data-slot="toggle"] +)[data-variant="outline"]:is( + :hover, + :focus-visible, + [aria-expanded="true"], + [data-popup-open], + [data-open] +) { + background-color: color-mix( + in srgb, + var(--secondary) 82%, + #24120c 18% + ); border-color: transparent; + color: var(--secondary-foreground); } -:root[data-theme="secret"] :where([data-slot="button"], [data-slot="badge"], [data-slot="toggle"])[data-variant="outline"]:is(:focus-visible, [aria-expanded="true"], [data-popup-open], [data-open]) { - background-color: color-mix(in srgb, #5e244e 82%, #24120c 18%); - border-color: transparent; -} -:root:not(.dark)[data-theme="secret"] [data-slot="button"][data-variant="outline"]:hover, -:root:not(.dark)[data-theme="secret"] :where([data-slot="badge"], [data-slot="toggle"])[data-variant="outline"]:hover, -:root:not(.dark)[data-theme="secret"] :where([data-slot="button"], [data-slot="badge"], [data-slot="toggle"])[data-variant="outline"]:is(:focus-visible, [aria-expanded="true"], [data-popup-open], [data-open]) { - background-color: color-mix(in srgb, var(--secondary) 82%, #fffaf2 18%); - border-color: transparent; -} -:root.dark[data-theme="secret"] :where([data-slot="button"][data-variant="outline"], [data-slot="button"][data-variant="link"], [data-slot="badge"][data-variant="outline"], [data-slot="toggle"][data-variant="outline"]) { - background-color: #5e244e; - border-color: transparent; - color: #ffe8b4; -} -:root.dark[data-theme="secret"] [data-slot="button"][data-variant="outline"]:hover { - background-color: color-mix(in srgb, #5e244e 82%, #24120c 18%); -} -:root[data-theme="secret"] :where([data-slot="card-title"], [data-slot="item-media"][data-variant="icon"], [data-slot="badge"][data-variant="outline"]) svg { + +:root[data-theme="secret"] :where( + [data-slot="card-title"], + [data-slot="item-media"][data-variant="icon"], + [data-slot="badge"][data-variant="outline"] +) svg { color: var(--primary); } + +:root:not(.dark)[data-theme="secret"] :where( + [data-slot="card-title"], + [data-slot="item-media"][data-variant="icon"], + [data-slot="badge"][data-variant="outline"] +) svg { + color: var(--secret-gold-dark); +} + :root[data-theme="secret"] [data-slot="separator"] { - background: linear-gradient(90deg, transparent, color-mix(in oklch, var(--primary) 42%, var(--border)), transparent); + background: linear-gradient( + 90deg, + transparent, + color-mix(in oklch, var(--primary) 42%, var(--border)), + transparent + ); }`, }, ] as const); diff --git a/src/theme/types.ts b/src/theme/types.ts index d09fd11..1c488b9 100644 --- a/src/theme/types.ts +++ b/src/theme/types.ts @@ -74,6 +74,7 @@ export type ThemeProviderProps = { customCssStorageKey?: string | null; parentThemeStorageKey?: string | null; designStorageKey?: string | null; + notCustomizedStorageKey?: string | null; disableTransitionOnChange?: boolean; }; @@ -102,6 +103,7 @@ export type ThemeProviderState = { applyThemePreset: (id: string) => void; resetThemePreset: () => void; isThemeCustomized: boolean; + notCustomized: boolean; themeDesign: ThemeDesign; setThemeDesign: ( design: ThemeDesign | ((current: ThemeDesign) => ThemeDesign),