@reopt-ai/opt-ui 1.5.0 → 1.6.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.
Files changed (87) hide show
  1. package/COMPONENT_CATALOG.md +83 -38
  2. package/README.md +28 -7
  3. package/dist/app.css +146 -0
  4. package/dist/core/index.cjs +164 -324
  5. package/dist/core/index.d.cts +3 -6
  6. package/dist/core/index.d.ts +3 -6
  7. package/dist/core/index.js +3 -323
  8. package/dist/docs/01-getting-started.md +25 -5
  9. package/dist/docs/02-components/01-core.md +36 -28
  10. package/dist/docs/02-components/02-visuals.md +1 -1
  11. package/dist/docs/02-components/03-shells.md +40 -12
  12. package/dist/docs/02-components/04-surfaces.md +1 -1
  13. package/dist/docs/02-components/index.md +1 -1
  14. package/dist/docs/03-recipes/03-layouts.md +16 -12
  15. package/dist/docs/05-migration/01-breaking-changes.md +28 -0
  16. package/dist/id-registry.cjs +1899 -1872
  17. package/dist/id-registry.d.cts +13 -10
  18. package/dist/id-registry.d.cts.map +1 -0
  19. package/dist/id-registry.d.ts +13 -10
  20. package/dist/id-registry.d.ts.map +1 -0
  21. package/dist/id-registry.js +1897 -1871
  22. package/dist/id-registry.js.map +1 -0
  23. package/dist/id-registry.json +28 -28
  24. package/dist/index.cjs +8294 -9790
  25. package/dist/index.d.cts +1486 -1442
  26. package/dist/index.d.cts.map +1 -0
  27. package/dist/index.d.ts +1486 -1442
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +7933 -9777
  30. package/dist/index.js.map +1 -0
  31. package/dist/meta.cjs +7461 -6875
  32. package/dist/meta.d.cts.map +1 -0
  33. package/dist/meta.d.ts.map +1 -0
  34. package/dist/meta.js +7460 -6846
  35. package/dist/meta.js.map +1 -0
  36. package/dist/pagination-By7Ozv3U.js +3788 -0
  37. package/dist/pagination-By7Ozv3U.js.map +1 -0
  38. package/dist/pagination-Uv3CnGJz.cjs +4677 -0
  39. package/dist/shader-surface-BK1GMt5_.d.cts +1788 -0
  40. package/dist/shader-surface-BK1GMt5_.d.cts.map +1 -0
  41. package/dist/shader-surface-BWhO2xkk.js +3715 -0
  42. package/dist/shader-surface-BWhO2xkk.js.map +1 -0
  43. package/dist/shader-surface-DIVWtpFl.d.ts +1788 -0
  44. package/dist/shader-surface-DIVWtpFl.d.ts.map +1 -0
  45. package/dist/shader-surface-DxLLfrE6.cjs +4108 -0
  46. package/dist/shells/index.cjs +51 -65
  47. package/dist/shells/index.d.cts +4 -5
  48. package/dist/shells/index.d.ts +4 -5
  49. package/dist/shells/index.js +3 -64
  50. package/dist/tailwind.css +49 -0
  51. package/dist/theme/server.cjs +257 -228
  52. package/dist/theme/server.d.cts +48 -60
  53. package/dist/theme/server.d.cts.map +1 -0
  54. package/dist/theme/server.d.ts +48 -60
  55. package/dist/theme/server.d.ts.map +1 -0
  56. package/dist/theme/server.js +234 -189
  57. package/dist/theme/server.js.map +1 -0
  58. package/dist/types-D0FlcYnM.d.cts +301 -0
  59. package/dist/types-D0FlcYnM.d.cts.map +1 -0
  60. package/dist/types-D0FlcYnM.d.ts +301 -0
  61. package/dist/types-D0FlcYnM.d.ts.map +1 -0
  62. package/dist/visuals/index.cjs +10 -4
  63. package/dist/visuals/index.d.cts +2 -1
  64. package/dist/visuals/index.d.ts +2 -1
  65. package/dist/visuals/index.js +1 -2
  66. package/dist/workflow-canvas-3Jeevkgy.cjs +2599 -0
  67. package/dist/workflow-canvas-BGBAcjf-.js +2403 -0
  68. package/dist/workflow-canvas-BGBAcjf-.js.map +1 -0
  69. package/dist/workflow-canvas-Bar_O2SQ.d.ts +494 -0
  70. package/dist/workflow-canvas-Bar_O2SQ.d.ts.map +1 -0
  71. package/dist/workflow-canvas-DghDRtHn.d.cts +494 -0
  72. package/dist/workflow-canvas-DghDRtHn.d.cts.map +1 -0
  73. package/package.json +11 -6
  74. package/dist/chunk-3GWWZKX7.js +0 -38
  75. package/dist/chunk-3QFYBBL6.cjs +0 -4759
  76. package/dist/chunk-3XD4HIFL.js +0 -3241
  77. package/dist/chunk-AFF2HPE5.cjs +0 -5008
  78. package/dist/chunk-NXZJIHEZ.cjs +0 -3241
  79. package/dist/chunk-ONE3C5RV.cjs +0 -38
  80. package/dist/chunk-RBM2RNC2.js +0 -5008
  81. package/dist/chunk-VBGPEW45.js +0 -4759
  82. package/dist/index-BZ_lBlO1.d.ts +0 -474
  83. package/dist/index-BuvxoWHf.d.cts +0 -474
  84. package/dist/index-DWyqDIkH.d.cts +0 -1689
  85. package/dist/index-Uyijm14M.d.ts +0 -1689
  86. package/dist/types-D4-0lwaE.d.cts +0 -298
  87. package/dist/types-D4-0lwaE.d.ts +0 -298
@@ -1,53 +1,40 @@
1
- import { PaletteConfig } from '@reopt-ai/opt-palette';
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
- /** Stable id used in `<html data-theme="...">` and localStorage. */
19
- readonly id: string;
20
- /** Human-readable label shown in ThemeSwitcher. */
21
- readonly label: string;
22
- /** Short description shown under the label. */
23
- readonly description: string;
24
- /**
25
- * Optional engine input that approximates this preset. Used by
26
- * ThemeSwitcher to derive swatches when `switcherSwatches` is omitted, and
27
- * as the starting point when a user clones a preset into a custom palette.
28
- * Codegen does NOT consume this in the current phase — the static `*.css`
29
- * file remains the source of token values.
30
- */
31
- readonly palette?: PaletteConfig;
32
- /**
33
- * Three CSS color strings for the ThemeSwitcher swatch row. Falls back to
34
- * the live `--opt-accent` / `--opt-surface` / `--opt-text` tokens when
35
- * omitted.
36
- */
37
- readonly switcherSwatches?: readonly [string, string, string];
38
- /** Disable dark variant generation entirely. */
39
- readonly forceLightOnly?: boolean;
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
- readonly default: ThemeDescriptor;
43
- readonly minimal: ThemeDescriptor;
44
- readonly natural: ThemeDescriptor;
45
- readonly pro: ThemeDescriptor;
46
- readonly "mono-dark": ThemeDescriptor;
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
- * Force the root theme to one preset regardless of stored preset/generated
65
- * theme state. Mode is still resolved normally unless constrained.
66
- */
67
- lockedPreset?: ThemePreset;
68
- /**
69
- * Restrict mode reads/writes to a smaller set, e.g. `["light", "dark"]`.
70
- * The first value becomes the fallback when the stored/default mode is not
71
- * allowed.
72
- */
73
- allowedModes?: readonly ThemeMode[];
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
- getItem(key: string): string | null;
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
- migrateLegacy?: boolean;
93
+ migrateLegacy?: boolean;
107
94
  }): {
108
- preset: ThemePreset;
109
- mode: ThemeMode;
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"}
@@ -1,194 +1,253 @@
1
- // src/lib/theme/presets/index.ts
2
- var DEFAULT_DESCRIPTOR = {
3
- id: "default",
4
- label: "Default",
5
- description: "Blue accent, balanced radius & shadow",
6
- palette: {
7
- seed: "#2563eb",
8
- harmony: "split-complementary",
9
- radiusScale: "medium",
10
- shadowIntensity: "subtle",
11
- neutralTemperature: "cool"
12
- },
13
- switcherSwatches: ["hsl(221 83% 53%)", "hsl(142 71% 45%)", "hsl(38 92% 50%)"]
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
- var MINIMAL_DESCRIPTOR = {
16
- id: "minimal",
17
- label: "Minimal",
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
- return id in THEME_REGISTRY;
94
+ return id in THEME_REGISTRY;
82
95
  }
83
- var FORCE_LIGHT_PRESET_IDS = new Set(
84
- THEME_PRESET_IDS.filter((id) => THEME_REGISTRY[id].forceLightOnly)
85
- );
86
- var DEPRECATED_PRESET_MIGRATIONS = Object.freeze({
87
- corporate: "default",
88
- playful: "default"
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
- if (!id) return null;
92
- if (isThemePresetId(id)) return id;
93
- if (id in DEPRECATED_PRESET_MIGRATIONS) {
94
- return DEPRECATED_PRESET_MIGRATIONS[id];
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
- // src/lib/theme/theme-serialize.ts
100
- import {
101
- generatePalette
102
- } from "@reopt-ai/opt-palette";
103
- var GLOBAL_THEME_STYLE_ID = "opt-global-theme";
104
- var THEME_SPEC_STORAGE_KEY = "opt-theme-spec";
105
- var THEME_TOKENS_STORAGE_KEY = "opt-theme-tokens";
106
-
107
- // src/lib/theme/theme-resolution.ts
108
- var THEME_PRESET_VALUES = THEME_PRESET_IDS;
109
- var THEME_MODE_VALUES = ["light", "dark", "system"];
110
- var LEGACY_THEME_STORAGE_KEY = "opt-theme";
111
- var THEME_PRESET_STORAGE_KEY = "opt-preset";
112
- var THEME_MODE_STORAGE_KEY = "opt-mode";
113
- var DARK_MQ = "(prefers-color-scheme: dark)";
114
- var FORCE_LIGHT_PRESETS = FORCE_LIGHT_PRESET_IDS;
115
- var ALL_COMPOUND_THEMES = THEME_PRESET_IDS.flatMap(
116
- (id) => FORCE_LIGHT_PRESET_IDS.has(id) ? [id] : [id, `${id}-dark`]
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
- return typeof storage.setItem === "function" && typeof storage.removeItem === "function";
160
+ return typeof storage.setItem === "function" && typeof storage.removeItem === "function";
120
161
  }
162
+ /** Handles is theme preset. */
121
163
  function isThemePreset(value) {
122
- return typeof value === "string" && THEME_PRESET_VALUES.includes(value);
164
+ return typeof value === "string" && THEME_PRESET_VALUES.includes(value);
123
165
  }
166
+ /** Handles is theme mode. */
124
167
  function isThemeMode(value) {
125
- return typeof value === "string" && THEME_MODE_VALUES.includes(value);
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
- if (FORCE_LIGHT_PRESETS.has(preset)) return preset;
129
- return resolvedMode === "dark" ? `${preset}-dark` : preset;
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
- if (FORCE_LIGHT_PRESETS.has(preset)) return "light";
133
- if (mode === "system") return systemDark ? "dark" : "light";
134
- return mode;
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
- const legacy = storage.getItem(LEGACY_THEME_STORAGE_KEY);
138
- const storedPreset = storage.getItem(THEME_PRESET_STORAGE_KEY);
139
- const storedMode = storage.getItem(THEME_MODE_STORAGE_KEY);
140
- let preset = defaultPreset;
141
- if (typeof legacy === "string") {
142
- const migratedLegacy = migrateDeprecatedPresetId(legacy);
143
- if (migratedLegacy) {
144
- if (options.migrateLegacy && hasStorageMutation(storage)) {
145
- storage.setItem(THEME_PRESET_STORAGE_KEY, migratedLegacy);
146
- storage.removeItem(LEGACY_THEME_STORAGE_KEY);
147
- }
148
- preset = migratedLegacy;
149
- }
150
- } else if (typeof storedPreset === "string") {
151
- const migrated = migrateDeprecatedPresetId(storedPreset);
152
- if (migrated) {
153
- preset = migrated;
154
- if (hasStorageMutation(storage) && migrated !== storedPreset && storedPreset in DEPRECATED_PRESET_MIGRATIONS) {
155
- storage.setItem(THEME_PRESET_STORAGE_KEY, migrated);
156
- }
157
- }
158
- }
159
- const mode = isThemeMode(storedMode) ? storedMode : defaultMode;
160
- return { preset, mode };
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
- var _a;
164
- if (!allowedModes || allowedModes.length === 0) return mode;
165
- if (allowedModes.includes(mode)) return mode;
166
- if (allowedModes.includes(fallback)) return fallback;
167
- return (_a = allowedModes[0]) != null ? _a : fallback;
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
- var _a, _b;
171
- const presetValues = JSON.stringify(THEME_PRESET_VALUES);
172
- const modeValues = JSON.stringify(THEME_MODE_VALUES);
173
- const allowedModes = ((_a = options.allowedModes) == null ? void 0 : _a.length) ? options.allowedModes : THEME_MODE_VALUES;
174
- const allowedModeValues = JSON.stringify(allowedModes);
175
- const forceLightPresets = JSON.stringify(Array.from(FORCE_LIGHT_PRESETS));
176
- const deprecatedMap = JSON.stringify(DEPRECATED_PRESET_MIGRATIONS);
177
- const lockedPreset = options.lockedPreset;
178
- const resolvedDefaultPreset = lockedPreset != null ? lockedPreset : defaultPreset;
179
- const defaultPresetLiteral = JSON.stringify(resolvedDefaultPreset);
180
- const defaultModeLiteral = JSON.stringify(
181
- coerceThemeMode(defaultMode, allowedModes, (_b = allowedModes[0]) != null ? _b : "system")
182
- );
183
- const lockedPresetLiteral = JSON.stringify(lockedPreset != null ? lockedPreset : null);
184
- const styleId = JSON.stringify(GLOBAL_THEME_STYLE_ID);
185
- const specKey = JSON.stringify(THEME_SPEC_STORAGE_KEY);
186
- const tokensKey = JSON.stringify(THEME_TOKENS_STORAGE_KEY);
187
- const presetKey = JSON.stringify(THEME_PRESET_STORAGE_KEY);
188
- const modeKey = JSON.stringify(THEME_MODE_STORAGE_KEY);
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
- export {
227
- ALL_COMPOUND_THEMES,
228
- DARK_MQ,
229
- FORCE_LIGHT_PRESETS,
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