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/pnpm-lock.yaml b/pnpm-lock.yaml
index 25f06d9..bae4fd5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -103,7 +103,7 @@ importers:
version: 4.16.2(typescript@7.0.2)
shiki:
specifier: ^4.4.2
- version: 4.4.2
+ version: 4.4.3
sonner:
specifier: ^2.0.8
version: 2.0.8(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
@@ -904,34 +904,42 @@ packages:
'@sec-ant/readable-stream@0.4.1':
resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==}
- '@shikijs/core@4.4.2':
- resolution: {integrity: sha512-StyzbAyxg2/tBGf78gwbBkGyeQ73lf8UiJArFaQhTQIDqQOCKPCQFanvrs4/Yv3Yfyc+ONInJM6K+FMIf+P+kA==}
+ '@shikijs/core@4.4.3':
+ resolution: {integrity: sha512-QCR4q2ZO/ILJEuwiBMel4wdcTDb1JGwfjKTxPDF6x8ixOaluPrVqIn06C99AcRPhmYlBR56d/Fb+GN58GzExpg==}
engines: {node: '>=20'}
- '@shikijs/engine-javascript@4.4.2':
- resolution: {integrity: sha512-MnIkeqWdVPUWsxlx8gKLVCJFTsqrQJgpTPBPpQwaFeJ56lOnJxj5aN2LUFnfxUEcvOQuNocmbaMnVrCEln6rkw==}
+ '@shikijs/engine-javascript@4.4.3':
+ resolution: {integrity: sha512-FbOjFJp9VLdo1Wevs10BBtVxiTWwNLqZh5Gkhjgda/ioL15YOgeSl9n+6XMa3qRlPQzfhFNe641SrynFHYG0nQ==}
engines: {node: '>=20'}
- '@shikijs/engine-oniguruma@4.4.2':
- resolution: {integrity: sha512-GLhowz1+jixjz+wiZ3wMnOn1jTxiFCGl2PkXufivbnwPHKuyw1AYqu5/hbWhZZ2oAb0NP05WUJhYeigY14drnw==}
+ '@shikijs/engine-oniguruma@4.4.3':
+ resolution: {integrity: sha512-EcOQkxdxGQrc1Row/cC2c96/v1dbZqGnEVu1qTuT/MJmp6+cXCvQussowVmCv5Tqr3KuY3c7IbM6HTW3LJ1k9w==}
engines: {node: '>=20'}
'@shikijs/langs@4.4.2':
resolution: {integrity: sha512-8DfeusD+Zdv/eYIDdXyJTUnSMHt+aAWjAOCXV20HNGAHRlInXpG8wh421v6B91WOm9TFwRLN+b/LG5F2NAIojg==}
engines: {node: '>=20'}
- '@shikijs/primitive@4.4.2':
- resolution: {integrity: sha512-l6fQQKsOMlz72n38fztmSgZ76MO6KSWuw8o+GJ+FhmqrpC9pIOJNQNXGgbb5yX2AwpzlEHwsaLPnk/8o4Fm+rA==}
+ '@shikijs/langs@4.4.3':
+ resolution: {integrity: sha512-ePic0yfAJGOF83D5wBHK/00EjK65oahBYxFk5epgq33WRv7X9UuxLEV8PtR0szC0z8dl7INIpIodB99JRFlR+A==}
engines: {node: '>=20'}
- '@shikijs/themes@4.4.2':
- resolution: {integrity: sha512-H0CFoL07ddDC2Dd6EdrPYNkRhUR6YCkJlnuYFceYYUJJA5TIm2b5B33qqiDYryBExgbKMndFJPb2u1gTuqO37g==}
+ '@shikijs/primitive@4.4.3':
+ resolution: {integrity: sha512-m0wBeLDQDeIxRdUmrCPdQqfuUamDwRL5isCfYbguKD6NiaKpVbsv+3J81DyIKgNW5h4WAIIr8T4EkgQrBBxvaQ==}
+ engines: {node: '>=20'}
+
+ '@shikijs/themes@4.4.3':
+ resolution: {integrity: sha512-w8UHjeUnIR965KMWJHUPXOc2mNJUnK3vpVLYLvw5IYU2mnTTJ89E24OrJDBNiJDQ0qzb0tc4l7mrIXx5cFeIyw==}
engines: {node: '>=20'}
'@shikijs/types@4.4.2':
resolution: {integrity: sha512-PFYitV4vpDr/iPCIhnHp+Q4ftic5N5VeNJ3KQ1O8gn3h2ar8qgwMAXF7tq4m1CWaMS60fV4VqF6vfnWH4F7vqQ==}
engines: {node: '>=20'}
+ '@shikijs/types@4.4.3':
+ resolution: {integrity: sha512-UEJxmRR++MAGR6hugn0vgVS2W/6lWAts84FFSrnlH9sP0LNol7E5+NQ792pH8liWUhyMyjhTgSUH3k7iD7tc5g==}
+ engines: {node: '>=20'}
+
'@shikijs/vscode-textmate@10.0.2':
resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
@@ -3082,8 +3090,8 @@ packages:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
- shiki@4.4.2:
- resolution: {integrity: sha512-P8F/dFhRevaw2uSdeIYlq/5SXZNY85DPtmXQ947gD1Zj2JqO5AkNvVVBar0Me9JkFx3uzVud/qOtP5ek9NEQGA==}
+ shiki@4.4.3:
+ resolution: {integrity: sha512-Mb/GvXPHBAXdgGIcnfU5L3ldpn1XcxrGkPHwqgRx17/I2XRfqlFKk2vGkHWINn1kdXvzJZeuO3is6I9KLPFm0g==}
engines: {node: '>=20'}
side-channel-list@1.0.1:
@@ -4203,44 +4211,53 @@ snapshots:
'@sec-ant/readable-stream@0.4.1': {}
- '@shikijs/core@4.4.2':
+ '@shikijs/core@4.4.3':
dependencies:
- '@shikijs/primitive': 4.4.2
- '@shikijs/types': 4.4.2
+ '@shikijs/primitive': 4.4.3
+ '@shikijs/types': 4.4.3
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.5
hast-util-to-html: 9.0.5
- '@shikijs/engine-javascript@4.4.2':
+ '@shikijs/engine-javascript@4.4.3':
dependencies:
- '@shikijs/types': 4.4.2
+ '@shikijs/types': 4.4.3
'@shikijs/vscode-textmate': 10.0.2
oniguruma-to-es: 4.3.6
- '@shikijs/engine-oniguruma@4.4.2':
+ '@shikijs/engine-oniguruma@4.4.3':
dependencies:
- '@shikijs/types': 4.4.2
+ '@shikijs/types': 4.4.3
'@shikijs/vscode-textmate': 10.0.2
'@shikijs/langs@4.4.2':
dependencies:
'@shikijs/types': 4.4.2
- '@shikijs/primitive@4.4.2':
+ '@shikijs/langs@4.4.3':
dependencies:
- '@shikijs/types': 4.4.2
+ '@shikijs/types': 4.4.3
+
+ '@shikijs/primitive@4.4.3':
+ dependencies:
+ '@shikijs/types': 4.4.3
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.5
- '@shikijs/themes@4.4.2':
+ '@shikijs/themes@4.4.3':
dependencies:
- '@shikijs/types': 4.4.2
+ '@shikijs/types': 4.4.3
'@shikijs/types@4.4.2':
dependencies:
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.5
+ '@shikijs/types@4.4.3':
+ dependencies:
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.5
+
'@shikijs/vscode-textmate@10.0.2': {}
'@sindresorhus/merge-streams@4.0.0': {}
@@ -6572,14 +6589,14 @@ snapshots:
shebang-regex@3.0.0: {}
- shiki@4.4.2:
+ shiki@4.4.3:
dependencies:
- '@shikijs/core': 4.4.2
- '@shikijs/engine-javascript': 4.4.2
- '@shikijs/engine-oniguruma': 4.4.2
- '@shikijs/langs': 4.4.2
- '@shikijs/themes': 4.4.2
- '@shikijs/types': 4.4.2
+ '@shikijs/core': 4.4.3
+ '@shikijs/engine-javascript': 4.4.3
+ '@shikijs/engine-oniguruma': 4.4.3
+ '@shikijs/langs': 4.4.3
+ '@shikijs/themes': 4.4.3
+ '@shikijs/types': 4.4.3
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.5
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),