@reopt-ai/opt-ui 1.5.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPONENT_CATALOG.md +178 -50
- package/README.md +28 -7
- package/dist/app.css +170 -0
- package/dist/core/index.cjs +164 -324
- package/dist/core/index.d.cts +3 -6
- package/dist/core/index.d.ts +3 -6
- package/dist/core/index.js +3 -323
- package/dist/docs/01-getting-started.md +25 -5
- package/dist/docs/02-components/01-core.md +36 -28
- package/dist/docs/02-components/02-visuals.md +1 -1
- package/dist/docs/02-components/03-shells.md +144 -23
- package/dist/docs/02-components/04-surfaces.md +1 -1
- package/dist/docs/02-components/index.md +4 -4
- package/dist/docs/03-recipes/03-layouts.md +16 -12
- package/dist/docs/05-migration/01-breaking-changes.md +46 -1
- package/dist/field-sidebar-BTZCBviA.d.cts +1031 -0
- package/dist/field-sidebar-BTZCBviA.d.cts.map +1 -0
- package/dist/field-sidebar-CB8vjvUM.d.ts +1031 -0
- package/dist/field-sidebar-CB8vjvUM.d.ts.map +1 -0
- package/dist/field-sidebar-Cs-J-5VE.js +4233 -0
- package/dist/field-sidebar-Cs-J-5VE.js.map +1 -0
- package/dist/field-sidebar-CzIQX70-.cjs +4561 -0
- package/dist/id-registry.cjs +1939 -1872
- package/dist/id-registry.d.cts +14 -11
- package/dist/id-registry.d.cts.map +1 -0
- package/dist/id-registry.d.ts +14 -11
- package/dist/id-registry.d.ts.map +1 -0
- package/dist/id-registry.js +1937 -1871
- package/dist/id-registry.js.map +1 -0
- package/dist/id-registry.json +113 -28
- package/dist/index.cjs +8380 -9790
- package/dist/index.d.cts +1555 -1442
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +1555 -1442
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7996 -9778
- package/dist/index.js.map +1 -0
- package/dist/meta.cjs +7753 -6875
- package/dist/meta.d.cts.map +1 -0
- package/dist/meta.d.ts.map +1 -0
- package/dist/meta.js +7752 -6846
- package/dist/meta.js.map +1 -0
- package/dist/pagination-DWbvACuN.js +3850 -0
- package/dist/pagination-DWbvACuN.js.map +1 -0
- package/dist/pagination-DjfxBcjX.cjs +4739 -0
- package/dist/query.cjs +386 -0
- package/dist/query.d.cts +141 -0
- package/dist/query.d.cts.map +1 -0
- package/dist/query.d.ts +141 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +371 -0
- package/dist/query.js.map +1 -0
- package/dist/shader-surface-BUPZ0P-n.js +3654 -0
- package/dist/shader-surface-BUPZ0P-n.js.map +1 -0
- package/dist/shader-surface-BfTP9c1Q.d.ts +1788 -0
- package/dist/shader-surface-BfTP9c1Q.d.ts.map +1 -0
- package/dist/shader-surface-DRrcLrWf.d.cts +1788 -0
- package/dist/shader-surface-DRrcLrWf.d.cts.map +1 -0
- package/dist/shader-surface-Fav5K9UC.cjs +4041 -0
- package/dist/shells/index.cjs +58 -65
- package/dist/shells/index.d.cts +4 -5
- package/dist/shells/index.d.ts +4 -5
- package/dist/shells/index.js +4 -64
- package/dist/tailwind.css +49 -0
- package/dist/theme/presets/default.css +2 -2
- package/dist/theme/presets/minimal.css +2 -2
- package/dist/theme/presets/mono-dark.css +2 -2
- package/dist/theme/presets/natural.css +1 -1
- package/dist/theme/presets/pro.css +2 -2
- package/dist/theme/server.cjs +257 -228
- package/dist/theme/server.d.cts +48 -60
- package/dist/theme/server.d.cts.map +1 -0
- package/dist/theme/server.d.ts +48 -60
- package/dist/theme/server.d.ts.map +1 -0
- package/dist/theme/server.js +234 -189
- package/dist/theme/server.js.map +1 -0
- package/dist/types-D0FlcYnM.d.cts +301 -0
- package/dist/types-D0FlcYnM.d.cts.map +1 -0
- package/dist/types-D0FlcYnM.d.ts +301 -0
- package/dist/types-D0FlcYnM.d.ts.map +1 -0
- package/dist/visuals/index.cjs +10 -4
- package/dist/visuals/index.d.cts +2 -1
- package/dist/visuals/index.d.ts +2 -1
- package/dist/visuals/index.js +1 -2
- package/package.json +27 -11
- package/dist/chunk-3GWWZKX7.js +0 -38
- package/dist/chunk-3QFYBBL6.cjs +0 -4759
- package/dist/chunk-3XD4HIFL.js +0 -3241
- package/dist/chunk-AFF2HPE5.cjs +0 -5008
- package/dist/chunk-NXZJIHEZ.cjs +0 -3241
- package/dist/chunk-ONE3C5RV.cjs +0 -38
- package/dist/chunk-RBM2RNC2.js +0 -5008
- package/dist/chunk-VBGPEW45.js +0 -4759
- package/dist/index-BZ_lBlO1.d.ts +0 -474
- package/dist/index-BuvxoWHf.d.cts +0 -474
- package/dist/index-DWyqDIkH.d.cts +0 -1689
- package/dist/index-Uyijm14M.d.ts +0 -1689
- package/dist/types-D4-0lwaE.d.cts +0 -298
- package/dist/types-D4-0lwaE.d.ts +0 -298
package/dist/theme/server.d.ts
CHANGED
|
@@ -1,53 +1,40 @@
|
|
|
1
|
-
import { PaletteConfig } from
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* presets/index.ts
|
|
5
|
-
*
|
|
6
|
-
* Single registry of theme preset metadata. Each entry pairs a stable id
|
|
7
|
-
* (used in `<html data-theme>` and localStorage) with display metadata and an
|
|
8
|
-
* optional `PaletteConfig` that approximates the preset's seed for the
|
|
9
|
-
* ThemeSwitcher swatch row and "clone to custom" workflow.
|
|
10
|
-
*
|
|
11
|
-
* Token values themselves currently live in the sibling `*.css` files. A
|
|
12
|
-
* follow-up sub-phase will migrate the full token tables into this file and
|
|
13
|
-
* have a codegen step emit the CSS, but the metadata layer is enough to
|
|
14
|
-
* unblock dynamic ThemeSwitcher rendering and type-safe preset id unions.
|
|
15
|
-
*/
|
|
16
|
-
|
|
1
|
+
import { PaletteConfig } from "@reopt-ai/opt-palette";
|
|
2
|
+
//#region src/lib/theme/presets/index.d.ts
|
|
17
3
|
interface ThemeDescriptor {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
4
|
+
/** Stable id used in `<html data-theme="...">` and localStorage. */
|
|
5
|
+
readonly id: string;
|
|
6
|
+
/** Human-readable label shown in ThemeSwitcher. */
|
|
7
|
+
readonly label: string;
|
|
8
|
+
/** Short description shown under the label. */
|
|
9
|
+
readonly description: string;
|
|
10
|
+
/**
|
|
11
|
+
* Optional engine input that approximates this preset. Used by
|
|
12
|
+
* ThemeSwitcher to derive swatches when `switcherSwatches` is omitted, and
|
|
13
|
+
* as the starting point when a user clones a preset into a custom palette.
|
|
14
|
+
* Codegen does NOT consume this in the current phase — the static `*.css`
|
|
15
|
+
* file remains the source of token values.
|
|
16
|
+
*/
|
|
17
|
+
readonly palette?: PaletteConfig;
|
|
18
|
+
/**
|
|
19
|
+
* Three CSS color strings for the ThemeSwitcher swatch row. Falls back to
|
|
20
|
+
* the live `--opt-accent` / `--opt-surface` / `--opt-text` tokens when
|
|
21
|
+
* omitted.
|
|
22
|
+
*/
|
|
23
|
+
readonly switcherSwatches?: readonly [string, string, string];
|
|
24
|
+
/** Disable dark variant generation entirely. */
|
|
25
|
+
readonly forceLightOnly?: boolean;
|
|
40
26
|
}
|
|
41
27
|
declare const THEME_REGISTRY: {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
28
|
+
readonly default: ThemeDescriptor;
|
|
29
|
+
readonly minimal: ThemeDescriptor;
|
|
30
|
+
readonly natural: ThemeDescriptor;
|
|
31
|
+
readonly pro: ThemeDescriptor;
|
|
32
|
+
readonly "mono-dark": ThemeDescriptor;
|
|
47
33
|
};
|
|
48
34
|
/** Compile-time-derived union of registered preset ids. */
|
|
49
35
|
type ThemePresetId = keyof typeof THEME_REGISTRY;
|
|
50
|
-
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/lib/theme/theme-resolution.d.ts
|
|
51
38
|
/**
|
|
52
39
|
* Registered preset id list. Preferred for runtime iteration.
|
|
53
40
|
* @deprecated Prefer `THEME_PRESET_IDS` from `./presets`.
|
|
@@ -60,17 +47,17 @@ declare const THEME_MODE_VALUES: readonly ["light", "dark", "system"];
|
|
|
60
47
|
type ThemeMode = (typeof THEME_MODE_VALUES)[number];
|
|
61
48
|
/** Runtime constraints for apps that expose only a subset of opt-ui theming. */
|
|
62
49
|
interface ThemeRuntimeOptions {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Force the root theme to one preset regardless of stored preset/generated
|
|
52
|
+
* theme state. Mode is still resolved normally unless constrained.
|
|
53
|
+
*/
|
|
54
|
+
lockedPreset?: ThemePreset;
|
|
55
|
+
/**
|
|
56
|
+
* Restrict mode reads/writes to a smaller set, e.g. `["light", "dark"]`.
|
|
57
|
+
* The first value becomes the fallback when the stored/default mode is not
|
|
58
|
+
* allowed.
|
|
59
|
+
*/
|
|
60
|
+
allowedModes?: readonly ThemeMode[];
|
|
74
61
|
}
|
|
75
62
|
/**
|
|
76
63
|
* Compound theme value applied to `<html data-theme>`. Derived from the
|
|
@@ -91,7 +78,7 @@ declare const FORCE_LIGHT_PRESETS: ReadonlySet<ThemePreset>;
|
|
|
91
78
|
/** All valid compound theme names. Useful for static enumeration. */
|
|
92
79
|
declare const ALL_COMPOUND_THEMES: CompoundTheme[];
|
|
93
80
|
interface ThemeStorageReader {
|
|
94
|
-
|
|
81
|
+
getItem(key: string): string | null;
|
|
95
82
|
}
|
|
96
83
|
/** Handles is theme preset. */
|
|
97
84
|
declare function isThemePreset(value: string | null): value is ThemePreset;
|
|
@@ -103,10 +90,10 @@ declare function getCompoundTheme(preset: ThemePreset, resolvedMode: "light" | "
|
|
|
103
90
|
declare function resolveThemeMode(preset: ThemePreset, mode: ThemeMode, systemDark: boolean): "light" | "dark";
|
|
104
91
|
/** Handles read stored theme. */
|
|
105
92
|
declare function readStoredTheme(storage: ThemeStorageReader, defaultPreset: ThemePreset, defaultMode: ThemeMode, options?: {
|
|
106
|
-
|
|
93
|
+
migrateLegacy?: boolean;
|
|
107
94
|
}): {
|
|
108
|
-
|
|
109
|
-
|
|
95
|
+
preset: ThemePreset;
|
|
96
|
+
mode: ThemeMode;
|
|
110
97
|
};
|
|
111
98
|
/** Normalize a mode against an optional allowed-mode list. */
|
|
112
99
|
declare function coerceThemeMode(mode: ThemeMode, allowedModes: readonly ThemeMode[] | undefined, fallback?: ThemeMode): ThemeMode;
|
|
@@ -125,5 +112,6 @@ declare function coerceThemeMode(mode: ThemeMode, allowedModes: readonly ThemeMo
|
|
|
125
112
|
* Returned as a single minified line; intended for `dangerouslySetInnerHTML`.
|
|
126
113
|
*/
|
|
127
114
|
declare function createThemeBootScript(defaultPreset?: ThemePreset, defaultMode?: ThemeMode, options?: ThemeRuntimeOptions): string;
|
|
128
|
-
|
|
115
|
+
//#endregion
|
|
129
116
|
export { ALL_COMPOUND_THEMES, type CompoundTheme, DARK_MQ, FORCE_LIGHT_PRESETS, LEGACY_THEME_STORAGE_KEY, THEME_MODE_STORAGE_KEY, THEME_MODE_VALUES, THEME_PRESET_STORAGE_KEY, THEME_PRESET_VALUES, type ThemeMode, type ThemePreset, type ThemeRuntimeOptions, coerceThemeMode, createThemeBootScript, getCompoundTheme, isThemeMode, isThemePreset, readStoredTheme, resolveThemeMode };
|
|
117
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","names":[],"sources":["../../src/lib/theme/presets/index.ts","../../src/lib/theme/theme-resolution.ts"],"mappings":";;UAgBiB;;WAEN;;WAEA;;WAEA;;;;;;;;WAQA,UAAU;;;;;;WAMV;;WAEA;;cA8EE;;;;;;;;KASD,6BAA6B;;;;;;;cC5G5B,8BAA8B;;KAG/B,cAAc;cAEb;;KAED,oBAAoB;;UAGf;;;;;EAKf,eAAe;;;;;;EAMf,wBAAwB;;;;;;;KAQd,mBAAmB,mBAAmB;cAErC;cACA;cACA;cACA;;;;;;cAOA,qBAAqB,YAAY;;cAIjC,qBAAqB;UAOxB;EACR,QAAQ;;;iBAkBM,cAAc,uBAAuB,SAAS;;iBAQ9C,YAAY,uBAAuB,SAAS;;iBAO5C,iBACd,QAAQ,aACR,iCACC;;iBAMa,iBACd,QAAQ,aACR,MAAM,WACN;;iBAQc,gBACd,SAAS,oBACT,eAAe,aACf,aAAa,WACb;EAAW;;EACR,QAAQ;EAAa,MAAM;;;iBAqChB,gBACd,MAAM,WACN,uBAAuB,yBACvB,WAAU,YACT;;;;;;;;;;;;;;;iBAqBa,sBACd,gBAAe,aACf,cAAa,WACb,UAAS"}
|
package/dist/theme/server.js
CHANGED
|
@@ -1,194 +1,253 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
import "@reopt-ai/opt-palette";
|
|
2
|
+
const THEME_REGISTRY = {
|
|
3
|
+
default: {
|
|
4
|
+
id: "default",
|
|
5
|
+
label: "Default",
|
|
6
|
+
description: "Blue accent, balanced radius & shadow",
|
|
7
|
+
palette: {
|
|
8
|
+
seed: "#2563eb",
|
|
9
|
+
harmony: "split-complementary",
|
|
10
|
+
radiusScale: "medium",
|
|
11
|
+
shadowIntensity: "subtle",
|
|
12
|
+
neutralTemperature: "cool"
|
|
13
|
+
},
|
|
14
|
+
switcherSwatches: [
|
|
15
|
+
"hsl(221 83% 53%)",
|
|
16
|
+
"hsl(142 71% 45%)",
|
|
17
|
+
"hsl(38 92% 50%)"
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
minimal: {
|
|
21
|
+
id: "minimal",
|
|
22
|
+
label: "Minimal",
|
|
23
|
+
description: "Monochrome, no shadow, sharp edges",
|
|
24
|
+
palette: {
|
|
25
|
+
seed: "#333333",
|
|
26
|
+
harmony: "analogous",
|
|
27
|
+
radiusScale: "sharp",
|
|
28
|
+
shadowIntensity: "none",
|
|
29
|
+
neutralTemperature: "cool"
|
|
30
|
+
},
|
|
31
|
+
switcherSwatches: [
|
|
32
|
+
"hsl(0 0% 20%)",
|
|
33
|
+
"hsl(0 0% 45%)",
|
|
34
|
+
"hsl(0 0% 70%)"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
natural: {
|
|
38
|
+
id: "natural",
|
|
39
|
+
label: "Natural",
|
|
40
|
+
description: "Always light — sage accent, warm cream",
|
|
41
|
+
forceLightOnly: true,
|
|
42
|
+
palette: {
|
|
43
|
+
seed: "#5a9376",
|
|
44
|
+
harmony: "complementary",
|
|
45
|
+
radiusScale: "medium",
|
|
46
|
+
shadowIntensity: "subtle",
|
|
47
|
+
neutralTemperature: "warm"
|
|
48
|
+
},
|
|
49
|
+
switcherSwatches: [
|
|
50
|
+
"hsl(155 38% 45%)",
|
|
51
|
+
"hsl(25 65% 55%)",
|
|
52
|
+
"hsl(45 75% 50%)"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
pro: {
|
|
56
|
+
id: "pro",
|
|
57
|
+
label: "Pro",
|
|
58
|
+
description: "Neon blue accent, mono headings, ultra-dense",
|
|
59
|
+
palette: {
|
|
60
|
+
seed: "#0080ff",
|
|
61
|
+
harmony: "tetradic",
|
|
62
|
+
radiusScale: "sharp",
|
|
63
|
+
shadowIntensity: "subtle",
|
|
64
|
+
neutralTemperature: "cool"
|
|
65
|
+
},
|
|
66
|
+
switcherSwatches: [
|
|
67
|
+
"hsl(210 100% 55%)",
|
|
68
|
+
"hsl(170 90% 48%)",
|
|
69
|
+
"hsl(290 85% 60%)"
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
"mono-dark": {
|
|
73
|
+
id: "mono-dark",
|
|
74
|
+
label: "Mono Dark",
|
|
75
|
+
description: "OLED-friendly black, neon cyan accent, mono headings",
|
|
76
|
+
palette: {
|
|
77
|
+
seed: "#00d4ff",
|
|
78
|
+
harmony: "tetradic",
|
|
79
|
+
radiusScale: "sharp",
|
|
80
|
+
shadowIntensity: "subtle",
|
|
81
|
+
neutralTemperature: "cool"
|
|
82
|
+
},
|
|
83
|
+
switcherSwatches: [
|
|
84
|
+
"hsl(190 100% 50%)",
|
|
85
|
+
"hsl(0 0% 8%)",
|
|
86
|
+
"hsl(280 90% 65%)"
|
|
87
|
+
]
|
|
88
|
+
}
|
|
14
89
|
};
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
description: "Monochrome, no shadow, sharp edges",
|
|
19
|
-
palette: {
|
|
20
|
-
seed: "#333333",
|
|
21
|
-
harmony: "analogous",
|
|
22
|
-
radiusScale: "sharp",
|
|
23
|
-
shadowIntensity: "none",
|
|
24
|
-
neutralTemperature: "cool"
|
|
25
|
-
},
|
|
26
|
-
switcherSwatches: ["hsl(0 0% 20%)", "hsl(0 0% 45%)", "hsl(0 0% 70%)"]
|
|
27
|
-
};
|
|
28
|
-
var NATURAL_DESCRIPTOR = {
|
|
29
|
-
id: "natural",
|
|
30
|
-
label: "Natural",
|
|
31
|
-
description: "Always light \u2014 sage accent, warm cream",
|
|
32
|
-
forceLightOnly: true,
|
|
33
|
-
palette: {
|
|
34
|
-
seed: "#5a9376",
|
|
35
|
-
harmony: "complementary",
|
|
36
|
-
radiusScale: "medium",
|
|
37
|
-
shadowIntensity: "subtle",
|
|
38
|
-
neutralTemperature: "warm"
|
|
39
|
-
},
|
|
40
|
-
switcherSwatches: ["hsl(155 38% 45%)", "hsl(25 65% 55%)", "hsl(45 75% 50%)"]
|
|
41
|
-
};
|
|
42
|
-
var PRO_DESCRIPTOR = {
|
|
43
|
-
id: "pro",
|
|
44
|
-
label: "Pro",
|
|
45
|
-
description: "Neon blue accent, mono headings, ultra-dense",
|
|
46
|
-
palette: {
|
|
47
|
-
seed: "#0080ff",
|
|
48
|
-
harmony: "tetradic",
|
|
49
|
-
radiusScale: "sharp",
|
|
50
|
-
shadowIntensity: "subtle",
|
|
51
|
-
neutralTemperature: "cool"
|
|
52
|
-
},
|
|
53
|
-
switcherSwatches: [
|
|
54
|
-
"hsl(210 100% 55%)",
|
|
55
|
-
"hsl(170 90% 48%)",
|
|
56
|
-
"hsl(290 85% 60%)"
|
|
57
|
-
]
|
|
58
|
-
};
|
|
59
|
-
var MONO_DARK_DESCRIPTOR = {
|
|
60
|
-
id: "mono-dark",
|
|
61
|
-
label: "Mono Dark",
|
|
62
|
-
description: "OLED-friendly black, neon cyan accent, mono headings",
|
|
63
|
-
palette: {
|
|
64
|
-
seed: "#00d4ff",
|
|
65
|
-
harmony: "tetradic",
|
|
66
|
-
radiusScale: "sharp",
|
|
67
|
-
shadowIntensity: "subtle",
|
|
68
|
-
neutralTemperature: "cool"
|
|
69
|
-
},
|
|
70
|
-
switcherSwatches: ["hsl(190 100% 50%)", "hsl(0 0% 8%)", "hsl(280 90% 65%)"]
|
|
71
|
-
};
|
|
72
|
-
var THEME_REGISTRY = {
|
|
73
|
-
default: DEFAULT_DESCRIPTOR,
|
|
74
|
-
minimal: MINIMAL_DESCRIPTOR,
|
|
75
|
-
natural: NATURAL_DESCRIPTOR,
|
|
76
|
-
pro: PRO_DESCRIPTOR,
|
|
77
|
-
"mono-dark": MONO_DARK_DESCRIPTOR
|
|
78
|
-
};
|
|
79
|
-
var THEME_PRESET_IDS = Object.keys(THEME_REGISTRY);
|
|
90
|
+
/** All registered preset ids in declaration order. */
|
|
91
|
+
const THEME_PRESET_IDS = Object.keys(THEME_REGISTRY);
|
|
92
|
+
/** Type guard for a known preset id. */
|
|
80
93
|
function isThemePresetId(id) {
|
|
81
|
-
|
|
94
|
+
return id in THEME_REGISTRY;
|
|
82
95
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
96
|
+
/** Preset ids that suppress dark mode generation. */
|
|
97
|
+
const FORCE_LIGHT_PRESET_IDS = new Set(THEME_PRESET_IDS.filter((id) => THEME_REGISTRY[id].forceLightOnly));
|
|
98
|
+
/**
|
|
99
|
+
* Map from removed preset ids to the closest surviving preset. Boot script and
|
|
100
|
+
* `readStoredTheme` consult this so users with persisted `corporate`/`playful`
|
|
101
|
+
* values silently land on a working preset on next page load instead of
|
|
102
|
+
* showing the global default fallback for an unknown id.
|
|
103
|
+
*
|
|
104
|
+
* Keep this around indefinitely — localStorage values are forever and the
|
|
105
|
+
* cost of two extra entries is negligible.
|
|
106
|
+
*/
|
|
107
|
+
const DEPRECATED_PRESET_MIGRATIONS = Object.freeze({
|
|
108
|
+
corporate: "default",
|
|
109
|
+
playful: "default"
|
|
89
110
|
});
|
|
111
|
+
/**
|
|
112
|
+
* Resolve a possibly-deprecated preset id to a registered one. Returns the
|
|
113
|
+
* input unchanged when it is already valid; returns the migration target when
|
|
114
|
+
* it is a known deprecated id; returns `null` when the id is unknown
|
|
115
|
+
* altogether (caller should fall back to its default).
|
|
116
|
+
*/
|
|
90
117
|
function migrateDeprecatedPresetId(id) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
return null;
|
|
118
|
+
if (!id) return null;
|
|
119
|
+
if (isThemePresetId(id)) return id;
|
|
120
|
+
if (id in DEPRECATED_PRESET_MIGRATIONS) return DEPRECATED_PRESET_MIGRATIONS[id];
|
|
121
|
+
return null;
|
|
97
122
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
123
|
+
//#endregion
|
|
124
|
+
//#region src/lib/theme/theme-serialize.ts
|
|
125
|
+
/** Element id used for the global generated theme style tag. */
|
|
126
|
+
const GLOBAL_THEME_STYLE_ID = "opt-global-theme";
|
|
127
|
+
/** localStorage key for the persisted ThemeSpec (generated mode). */
|
|
128
|
+
const THEME_SPEC_STORAGE_KEY = "opt-theme-spec";
|
|
129
|
+
/**
|
|
130
|
+
* localStorage key for the cached, pre-serialized token maps that match the
|
|
131
|
+
* spec under `THEME_SPEC_STORAGE_KEY`. The boot script reads this directly so
|
|
132
|
+
* it can inline tokens without invoking opt-palette at startup.
|
|
133
|
+
*/
|
|
134
|
+
const THEME_TOKENS_STORAGE_KEY = "opt-theme-tokens";
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region src/lib/theme/theme-resolution.ts
|
|
137
|
+
/**
|
|
138
|
+
* Registered preset id list. Preferred for runtime iteration.
|
|
139
|
+
* @deprecated Prefer `THEME_PRESET_IDS` from `./presets`.
|
|
140
|
+
*/
|
|
141
|
+
const THEME_PRESET_VALUES = THEME_PRESET_IDS;
|
|
142
|
+
const THEME_MODE_VALUES = [
|
|
143
|
+
"light",
|
|
144
|
+
"dark",
|
|
145
|
+
"system"
|
|
146
|
+
];
|
|
147
|
+
const LEGACY_THEME_STORAGE_KEY = "opt-theme";
|
|
148
|
+
const THEME_PRESET_STORAGE_KEY = "opt-preset";
|
|
149
|
+
const THEME_MODE_STORAGE_KEY = "opt-mode";
|
|
150
|
+
const DARK_MQ = "(prefers-color-scheme: dark)";
|
|
151
|
+
/**
|
|
152
|
+
* Presets that force light mode regardless of system dark/light preference.
|
|
153
|
+
* Mirrors `FORCE_LIGHT_PRESET_IDS` from `./presets` — kept as alias for
|
|
154
|
+
* existing imports.
|
|
155
|
+
*/
|
|
156
|
+
const FORCE_LIGHT_PRESETS = FORCE_LIGHT_PRESET_IDS;
|
|
157
|
+
/** All valid compound theme names. Useful for static enumeration. */
|
|
158
|
+
const ALL_COMPOUND_THEMES = THEME_PRESET_IDS.flatMap((id) => FORCE_LIGHT_PRESET_IDS.has(id) ? [id] : [id, `${id}-dark`]);
|
|
118
159
|
function hasStorageMutation(storage) {
|
|
119
|
-
|
|
160
|
+
return typeof storage.setItem === "function" && typeof storage.removeItem === "function";
|
|
120
161
|
}
|
|
162
|
+
/** Handles is theme preset. */
|
|
121
163
|
function isThemePreset(value) {
|
|
122
|
-
|
|
164
|
+
return typeof value === "string" && THEME_PRESET_VALUES.includes(value);
|
|
123
165
|
}
|
|
166
|
+
/** Handles is theme mode. */
|
|
124
167
|
function isThemeMode(value) {
|
|
125
|
-
|
|
168
|
+
return typeof value === "string" && THEME_MODE_VALUES.includes(value);
|
|
126
169
|
}
|
|
170
|
+
/** Compute compound theme name from preset + resolved mode. */
|
|
127
171
|
function getCompoundTheme(preset, resolvedMode) {
|
|
128
|
-
|
|
129
|
-
|
|
172
|
+
if (FORCE_LIGHT_PRESETS.has(preset)) return preset;
|
|
173
|
+
return resolvedMode === "dark" ? `${preset}-dark` : preset;
|
|
130
174
|
}
|
|
175
|
+
/** Handles resolve theme mode. */
|
|
131
176
|
function resolveThemeMode(preset, mode, systemDark) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
177
|
+
if (FORCE_LIGHT_PRESETS.has(preset)) return "light";
|
|
178
|
+
if (mode === "system") return systemDark ? "dark" : "light";
|
|
179
|
+
return mode;
|
|
135
180
|
}
|
|
181
|
+
/** Handles read stored theme. */
|
|
136
182
|
function readStoredTheme(storage, defaultPreset, defaultMode, options = {}) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
183
|
+
const legacy = storage.getItem(LEGACY_THEME_STORAGE_KEY);
|
|
184
|
+
const storedPreset = storage.getItem(THEME_PRESET_STORAGE_KEY);
|
|
185
|
+
const storedMode = storage.getItem(THEME_MODE_STORAGE_KEY);
|
|
186
|
+
let preset = defaultPreset;
|
|
187
|
+
if (typeof legacy === "string") {
|
|
188
|
+
const migratedLegacy = migrateDeprecatedPresetId(legacy);
|
|
189
|
+
if (migratedLegacy) {
|
|
190
|
+
if (options.migrateLegacy && hasStorageMutation(storage)) {
|
|
191
|
+
storage.setItem(THEME_PRESET_STORAGE_KEY, migratedLegacy);
|
|
192
|
+
storage.removeItem(LEGACY_THEME_STORAGE_KEY);
|
|
193
|
+
}
|
|
194
|
+
preset = migratedLegacy;
|
|
195
|
+
}
|
|
196
|
+
} else if (typeof storedPreset === "string") {
|
|
197
|
+
const migrated = migrateDeprecatedPresetId(storedPreset);
|
|
198
|
+
if (migrated) {
|
|
199
|
+
preset = migrated;
|
|
200
|
+
if (hasStorageMutation(storage) && migrated !== storedPreset && storedPreset in DEPRECATED_PRESET_MIGRATIONS) storage.setItem(THEME_PRESET_STORAGE_KEY, migrated);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const mode = isThemeMode(storedMode) ? storedMode : defaultMode;
|
|
204
|
+
return {
|
|
205
|
+
preset,
|
|
206
|
+
mode
|
|
207
|
+
};
|
|
161
208
|
}
|
|
209
|
+
/** Normalize a mode against an optional allowed-mode list. */
|
|
162
210
|
function coerceThemeMode(mode, allowedModes, fallback = "system") {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
211
|
+
var _allowedModes$;
|
|
212
|
+
if (!allowedModes || allowedModes.length === 0) return mode;
|
|
213
|
+
if (allowedModes.includes(mode)) return mode;
|
|
214
|
+
if (allowedModes.includes(fallback)) return fallback;
|
|
215
|
+
return (_allowedModes$ = allowedModes[0]) !== null && _allowedModes$ !== void 0 ? _allowedModes$ : fallback;
|
|
168
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* Build the inline `<head>` boot script that paints the correct theme before
|
|
219
|
+
* React mounts. Two paths:
|
|
220
|
+
*
|
|
221
|
+
* 1. **Generated** — when both `opt-theme-spec` (kind: "generated") and
|
|
222
|
+
* `opt-theme-tokens` are present and well-formed, a `<style id="…">` tag
|
|
223
|
+
* is inserted with the cached tokens and `<html data-theme>` is set to the
|
|
224
|
+
* generated id (with optional `-dark` suffix). This bypasses opt-palette
|
|
225
|
+
* at startup so first paint is instant.
|
|
226
|
+
* 2. **Preset (legacy)** — falls through to the existing preset selector,
|
|
227
|
+
* including legacy `opt-theme` → `opt-preset` migration.
|
|
228
|
+
*
|
|
229
|
+
* Returned as a single minified line; intended for `dangerouslySetInnerHTML`.
|
|
230
|
+
*/
|
|
169
231
|
function createThemeBootScript(defaultPreset = "default", defaultMode = "system", options = {}) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const legacyKey = JSON.stringify(LEGACY_THEME_STORAGE_KEY);
|
|
190
|
-
const darkMq = JSON.stringify(DARK_MQ);
|
|
191
|
-
const source = `
|
|
232
|
+
var _options$allowedModes, _allowedModes$2;
|
|
233
|
+
const presetValues = JSON.stringify(THEME_PRESET_VALUES);
|
|
234
|
+
const modeValues = JSON.stringify(THEME_MODE_VALUES);
|
|
235
|
+
const allowedModes = ((_options$allowedModes = options.allowedModes) === null || _options$allowedModes === void 0 ? void 0 : _options$allowedModes.length) ? options.allowedModes : THEME_MODE_VALUES;
|
|
236
|
+
const allowedModeValues = JSON.stringify(allowedModes);
|
|
237
|
+
const forceLightPresets = JSON.stringify(Array.from(FORCE_LIGHT_PRESETS));
|
|
238
|
+
const deprecatedMap = JSON.stringify(DEPRECATED_PRESET_MIGRATIONS);
|
|
239
|
+
const lockedPreset = options.lockedPreset;
|
|
240
|
+
const defaultPresetLiteral = JSON.stringify(lockedPreset !== null && lockedPreset !== void 0 ? lockedPreset : defaultPreset);
|
|
241
|
+
const defaultModeLiteral = JSON.stringify(coerceThemeMode(defaultMode, allowedModes, (_allowedModes$2 = allowedModes[0]) !== null && _allowedModes$2 !== void 0 ? _allowedModes$2 : "system"));
|
|
242
|
+
const lockedPresetLiteral = JSON.stringify(lockedPreset !== null && lockedPreset !== void 0 ? lockedPreset : null);
|
|
243
|
+
const styleId = JSON.stringify(GLOBAL_THEME_STYLE_ID);
|
|
244
|
+
const specKey = JSON.stringify(THEME_SPEC_STORAGE_KEY);
|
|
245
|
+
const tokensKey = JSON.stringify(THEME_TOKENS_STORAGE_KEY);
|
|
246
|
+
const presetKey = JSON.stringify(THEME_PRESET_STORAGE_KEY);
|
|
247
|
+
const modeKey = JSON.stringify(THEME_MODE_STORAGE_KEY);
|
|
248
|
+
const legacyKey = JSON.stringify(LEGACY_THEME_STORAGE_KEY);
|
|
249
|
+
const darkMq = JSON.stringify(DARK_MQ);
|
|
250
|
+
return `
|
|
192
251
|
try {
|
|
193
252
|
var pv=${presetValues},mv=${modeValues},am=${allowedModeValues},fp=${forceLightPresets},dm=${deprecatedMap},lk=${lockedPresetLiteral};
|
|
194
253
|
function mp(v){if(typeof v!=="string")return null;if(pv.indexOf(v)>=0)return v;return Object.prototype.hasOwnProperty.call(dm,v)?dm[v]:null;}
|
|
@@ -220,23 +279,9 @@ try {
|
|
|
220
279
|
var d=fp.indexOf(p)<0&&(m==="dark"||(m==="system"&&matchMedia(${darkMq}).matches));
|
|
221
280
|
document.documentElement.setAttribute("data-theme",d?p+"-dark":p);
|
|
222
281
|
}
|
|
223
|
-
} catch(e){}
|
|
224
|
-
return source.replace(/\n\s*/g, "");
|
|
282
|
+
} catch(e){}`.replace(/\n\s*/g, "");
|
|
225
283
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
LEGACY_THEME_STORAGE_KEY,
|
|
231
|
-
THEME_MODE_STORAGE_KEY,
|
|
232
|
-
THEME_MODE_VALUES,
|
|
233
|
-
THEME_PRESET_STORAGE_KEY,
|
|
234
|
-
THEME_PRESET_VALUES,
|
|
235
|
-
coerceThemeMode,
|
|
236
|
-
createThemeBootScript,
|
|
237
|
-
getCompoundTheme,
|
|
238
|
-
isThemeMode,
|
|
239
|
-
isThemePreset,
|
|
240
|
-
readStoredTheme,
|
|
241
|
-
resolveThemeMode
|
|
242
|
-
};
|
|
284
|
+
//#endregion
|
|
285
|
+
export { ALL_COMPOUND_THEMES, DARK_MQ, FORCE_LIGHT_PRESETS, LEGACY_THEME_STORAGE_KEY, THEME_MODE_STORAGE_KEY, THEME_MODE_VALUES, THEME_PRESET_STORAGE_KEY, THEME_PRESET_VALUES, coerceThemeMode, createThemeBootScript, getCompoundTheme, isThemeMode, isThemePreset, readStoredTheme, resolveThemeMode };
|
|
286
|
+
|
|
287
|
+
//# sourceMappingURL=server.js.map
|