@adea-ai/ui 0.123.0 → 0.124.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 (90) hide show
  1. package/dist/NOTICE +18 -0
  2. package/dist/components/layout/split-layout/resize-controller-core-retry.d.ts +13 -0
  3. package/dist/components/layout/split-layout/resize-controller-core-retry.d.ts.map +1 -0
  4. package/dist/components/layout/split-layout/resize-controller-core-retry.js +63 -0
  5. package/dist/components/layout/split-layout/resize-controller-core-retry.js.map +1 -0
  6. package/dist/components/layout/split-layout/resize-controller-core.d.ts +13 -0
  7. package/dist/components/layout/split-layout/resize-controller-core.d.ts.map +1 -0
  8. package/dist/components/layout/split-layout/resize-controller-core.js +63 -0
  9. package/dist/components/layout/split-layout/resize-controller-core.js.map +1 -0
  10. package/dist/components/layout/split-layout/resize-controller-retry-2.d.ts +3 -0
  11. package/dist/components/layout/split-layout/resize-controller-retry-2.d.ts.map +1 -0
  12. package/dist/components/layout/split-layout/resize-controller-retry-2.js +2 -0
  13. package/dist/components/layout/split-layout/resize-controller-retry.d.ts +2 -0
  14. package/dist/components/layout/split-layout/resize-controller-retry.d.ts.map +1 -0
  15. package/dist/components/layout/split-layout/resize-controller-retry.js +2 -0
  16. package/dist/components/layout/split-layout/resize-controller.d.ts +2 -0
  17. package/dist/components/layout/split-layout/resize-controller.d.ts.map +1 -0
  18. package/dist/components/layout/split-layout/resize-controller.js +2 -0
  19. package/dist/components/layout/split-layout/split-layout.d.ts.map +1 -1
  20. package/dist/components/layout/split-layout/split-layout.js +171 -60
  21. package/dist/components/layout/split-layout/split-layout.js.map +1 -1
  22. package/dist/components/theme/appearance-panel.js +1 -1
  23. package/dist/components/theme/index.d.ts +1 -1
  24. package/dist/components/theme/index.d.ts.map +1 -1
  25. package/dist/components/theme/index.js +5 -2
  26. package/dist/components/theme/theme-context.d.ts +13 -0
  27. package/dist/components/theme/theme-context.d.ts.map +1 -0
  28. package/dist/components/theme/theme-context.js +41 -0
  29. package/dist/components/theme/theme-context.js.map +1 -0
  30. package/dist/components/theme/theme-document.d.ts +76 -0
  31. package/dist/components/theme/theme-document.d.ts.map +1 -0
  32. package/dist/components/theme/theme-document.js +93 -0
  33. package/dist/components/theme/theme-document.js.map +1 -0
  34. package/dist/components/theme/theme-persistence.d.ts +50 -0
  35. package/dist/components/theme/theme-persistence.d.ts.map +1 -0
  36. package/dist/components/theme/theme-persistence.js +86 -0
  37. package/dist/components/theme/theme-persistence.js.map +1 -0
  38. package/dist/components/theme/theme-provider.d.ts +43 -75
  39. package/dist/components/theme/theme-provider.d.ts.map +1 -1
  40. package/dist/components/theme/theme-provider.js +50 -116
  41. package/dist/components/theme/theme-provider.js.map +1 -1
  42. package/dist/components/theme/theme-state.d.ts +142 -0
  43. package/dist/components/theme/theme-state.d.ts.map +1 -0
  44. package/dist/components/theme/theme-state.js +104 -0
  45. package/dist/components/theme/theme-state.js.map +1 -0
  46. package/dist/components/theme/theme-toggle.js +1 -1
  47. package/dist/index.d.ts +1 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +6 -3
  50. package/dist/lib/appearance-font-settings.d.ts +1 -1
  51. package/dist/lib/appearance-font-settings.d.ts.map +1 -1
  52. package/dist/lib/appearance-font-settings.js.map +1 -1
  53. package/dist/lib/themes.d.ts +48 -0
  54. package/dist/lib/themes.d.ts.map +1 -1
  55. package/dist/lib/themes.js +150 -36
  56. package/dist/lib/themes.js.map +1 -1
  57. package/dist/r/registry.json +46 -0
  58. package/dist/r/split-layout.json +26 -0
  59. package/dist/r/src/components/layout/split-layout/resize-controller-core-retry.tsx +66 -0
  60. package/dist/r/src/components/layout/split-layout/resize-controller-core.tsx +66 -0
  61. package/dist/r/src/components/layout/split-layout/resize-controller-retry-2.tsx +2 -0
  62. package/dist/r/src/components/layout/split-layout/resize-controller-retry.tsx +1 -0
  63. package/dist/r/src/components/layout/split-layout/resize-controller.tsx +1 -0
  64. package/dist/r/src/components/layout/split-layout/split-layout.tsx +197 -49
  65. package/dist/r/src/components/theme/index.ts +3 -0
  66. package/dist/r/src/components/theme/theme-context.ts +43 -0
  67. package/dist/r/src/components/theme/theme-document.ts +168 -0
  68. package/dist/r/src/components/theme/theme-persistence.ts +140 -0
  69. package/dist/r/src/components/theme/theme-provider.tsx +126 -253
  70. package/dist/r/src/components/theme/theme-state.ts +225 -0
  71. package/dist/r/src/lib/appearance-font-settings.ts +1 -1
  72. package/dist/r/src/lib/themes.ts +181 -40
  73. package/dist/r/theming.json +20 -0
  74. package/package.json +1 -1
  75. package/registry.json +46 -0
  76. package/src/components/layout/split-layout/resize-controller-core-retry.tsx +66 -0
  77. package/src/components/layout/split-layout/resize-controller-core.tsx +66 -0
  78. package/src/components/layout/split-layout/resize-controller-retry-2.tsx +2 -0
  79. package/src/components/layout/split-layout/resize-controller-retry.tsx +1 -0
  80. package/src/components/layout/split-layout/resize-controller.tsx +1 -0
  81. package/src/components/layout/split-layout/split-layout.tsx +197 -49
  82. package/src/components/theme/index.ts +3 -0
  83. package/src/components/theme/theme-context.ts +43 -0
  84. package/src/components/theme/theme-document.ts +168 -0
  85. package/src/components/theme/theme-persistence.ts +140 -0
  86. package/src/components/theme/theme-provider.tsx +126 -253
  87. package/src/components/theme/theme-state.ts +225 -0
  88. package/src/index.ts +3 -0
  89. package/src/lib/appearance-font-settings.ts +1 -1
  90. package/src/lib/themes.ts +181 -40
@@ -0,0 +1,142 @@
1
+ import { type AppearanceEditorFontSettings } from '#lib/appearance-font-settings';
2
+ import type { AccentPreset } from '@adea-ai/themes';
3
+ import { type ThemeAppearance, type ThemeVariant } from '#lib/themes';
4
+ /**
5
+ * The pure half of the theme provider: what a selection is, how two selections
6
+ * merge, and what a selection resolves to.
7
+ *
8
+ * Nothing here touches the document, storage or a signal, so each rule can be
9
+ * tested by calling it. `ThemeProvider` owns the reactivity and wires these to it;
10
+ * `theme-document.ts` owns the writes; `theme-persistence.ts` owns the store.
11
+ */
12
+ /**
13
+ * Four independent choices, and keeping them independent is the point:
14
+ *
15
+ * - **appearance** — light, dark, or follow the system.
16
+ * - **a theme per appearance** — so a user can run Catppuccin Mocha by night and
17
+ * Solarized Light by day without re-choosing when the system flips.
18
+ * - **an accent** — adea's six presets, or one of the accents the selected theme
19
+ * pair carries itself (`ansi-blue`…), which re-colour the interactive roles on
20
+ * top of whichever theme is active.
21
+ * - **fonts** — separate family and size choices for UI, content and code.
22
+ */
23
+ export type ThemeSelection = {
24
+ /** `system` follows `prefers-color-scheme` and updates when it changes. */
25
+ appearance: ThemeAppearance | 'system';
26
+ /** The variant to use when the resolved appearance is light. */
27
+ lightThemeId: string;
28
+ /** The variant to use when the resolved appearance is dark. */
29
+ darkThemeId: string;
30
+ /**
31
+ * An `accentPresets` id, a theme accent id from `themeAccents()` (`ansi-blue`…),
32
+ * or `theme` for the variant's own primary. A theme accent the current pair does
33
+ * not offer falls back to the variant's own primary.
34
+ */
35
+ accent: string;
36
+ /** UI-family alias for consumers of the original single-font preference. */
37
+ font: string;
38
+ /** UI, content and code font settings. Omitted legacy records are migrated from `font`. */
39
+ fonts?: AppearanceEditorFontSettings;
40
+ /**
41
+ * `comfortable` is the system's default geometry; `compact` moves the control
42
+ * ladder down one rung.
43
+ *
44
+ * Optional, and defaulted on read, so a preference stored before density existed
45
+ * keeps working and `ThemeSelection` stays assignable without it.
46
+ */
47
+ density?: ThemeDensity;
48
+ };
49
+ /**
50
+ * The two density rungs.
51
+ *
52
+ * `comfortable` is the geometry in `theme.css`, so it is the absence of an
53
+ * attribute rather than a value: a document that ships no `data-density` at all
54
+ * renders correctly, which is what keeps this additive.
55
+ */
56
+ export type ThemeDensity = 'comfortable' | 'compact';
57
+ /**
58
+ * Deliberately lists only the fields every consumer has always had. A field added
59
+ * to {@link ThemeSelection} later gets no default here: `JSON.stringify` drops an
60
+ * `undefined`, so a store written by a consumer that never sets the field stays
61
+ * byte-identical to what it was before the field existed.
62
+ */
63
+ export declare const defaultThemeSelection: ThemeSelection;
64
+ /**
65
+ * A stored selection's density, defaulted.
66
+ *
67
+ * The stored value is read through here rather than trusted, because a preference
68
+ * written before density existed has no `density` key and a hand-edited store may
69
+ * hold anything.
70
+ */
71
+ export declare function resolvedDensity(selection: ThemeSelection): ThemeDensity;
72
+ export type ThemeContextValue = {
73
+ /** The preference as stored. A {@link ThemeContextValue.preview} does not change it. */
74
+ selection: () => ThemeSelection;
75
+ /** What the preference resolves to right now, after `system`. */
76
+ resolvedAppearance: () => ThemeAppearance;
77
+ /** The variant in use. */
78
+ variant: () => ThemeVariant;
79
+ /** Update part of the preference. */
80
+ setSelection: (patch: Partial<ThemeSelection>) => void;
81
+ /**
82
+ * The built-in catalogue, so a picker does not import it separately. A plain
83
+ * array: {@link ThemeContextValue.allThemes} is the one that follows a host's
84
+ * extra themes.
85
+ */
86
+ themes: readonly ThemeVariant[];
87
+ /**
88
+ * The accents the selected light/dark pair carries, offered beside the presets.
89
+ * Follows the selection: a different theme pair may offer different slots.
90
+ */
91
+ themeAccents: () => readonly AccentPreset[];
92
+ /**
93
+ * The built-in catalogue followed by the provider's `themes` prop. Reactive when
94
+ * that prop is a function that reads signals.
95
+ */
96
+ allThemes: () => readonly ThemeVariant[];
97
+ /**
98
+ * Paint the document from `draft` laid over the stored selection, without
99
+ * persisting it or changing what {@link ThemeContextValue.selection} returns.
100
+ * `undefined` ends the preview. A {@link ThemeContextValue.setSelection} ends it
101
+ * too, because the committed selection is then what should be showing.
102
+ */
103
+ preview: (draft: Partial<ThemeSelection> | undefined) => void;
104
+ /** True while a {@link ThemeContextValue.preview} draft is on the document. */
105
+ previewing: () => boolean;
106
+ };
107
+ /** Keep the deprecated single-font view synchronized with the UI axis. */
108
+ export declare function mergeThemeSelection(base: ThemeSelection, patch: Partial<ThemeSelection>): ThemeSelection;
109
+ /**
110
+ * The selection a provider starts from: the defaults, then whatever the store
111
+ * returned, then `initial`.
112
+ *
113
+ * `initial` wins over the store on every mount. That precedence is part of the
114
+ * contract Cortana relies on (its `initial` pins `appearance` and `font`), and it
115
+ * is why the store's answer is only the middle layer. A store that returned
116
+ * nothing, or threw, or answered with explicit `undefined`s, leaves the defaults
117
+ * standing for those fields.
118
+ */
119
+ export declare function initialThemeSelection(stored: Partial<ThemeSelection> | undefined, initial: Partial<ThemeSelection> | undefined): ThemeSelection;
120
+ /** `system` resolved against what the operating system reports. */
121
+ export declare function resolveAppearance(preference: ThemeSelection['appearance'], system: ThemeAppearance): ThemeAppearance;
122
+ /** The theme id the selection names for a resolved appearance. */
123
+ export declare function selectedThemeId(selection: ThemeSelection, appearance: ThemeAppearance): string;
124
+ /**
125
+ * What a selection paints: the resolved appearance and the variant for it.
126
+ *
127
+ * An id the registry does not hold resolves to the appearance's default rather than
128
+ * being rewritten (see `resolveVariant`), so the selection a host stores is never
129
+ * changed by being unresolvable.
130
+ */
131
+ export declare function resolveThemeState(selection: ThemeSelection, system: ThemeAppearance, registry: readonly ThemeVariant[]): {
132
+ appearance: ThemeAppearance;
133
+ variant: ThemeVariant;
134
+ };
135
+ /**
136
+ * The registry a provider resolves against: the catalogue, then the host's extras.
137
+ *
138
+ * The catalogue wins an id collision, because it is listed first and `resolveVariant`
139
+ * takes the first match: a host's variant can add a theme but cannot shadow one.
140
+ */
141
+ export declare function mergeRegistry(builtin: readonly ThemeVariant[], extra: readonly ThemeVariant[] | undefined): readonly ThemeVariant[];
142
+ //# sourceMappingURL=theme-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-state.d.ts","sourceRoot":"","sources":["../../../src/components/theme/theme-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,4BAA4B,EAClC,MAAM,+BAA+B,CAAA;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAIL,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,MAAM,aAAa,CAAA;AAEpB;;;;;;;GAOG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,2EAA2E;IAC3E,UAAU,EAAE,eAAe,GAAG,QAAQ,CAAA;IACtC,gEAAgE;IAChE,YAAY,EAAE,MAAM,CAAA;IACpB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAA;IACZ,2FAA2F;IAC3F,KAAK,CAAC,EAAE,4BAA4B,CAAA;IACpC;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,YAAY,CAAA;CACvB,CAAA;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,SAAS,CAAA;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,cAQnC,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,cAAc,GAAG,YAAY,CAEvE;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,wFAAwF;IACxF,SAAS,EAAE,MAAM,cAAc,CAAA;IAC/B,iEAAiE;IACjE,kBAAkB,EAAE,MAAM,eAAe,CAAA;IACzC,0BAA0B;IAC1B,OAAO,EAAE,MAAM,YAAY,CAAA;IAC3B,qCAAqC;IACrC,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,KAAK,IAAI,CAAA;IACtD;;;;OAIG;IACH,MAAM,EAAE,SAAS,YAAY,EAAE,CAAA;IAC/B;;;OAGG;IACH,YAAY,EAAE,MAAM,SAAS,YAAY,EAAE,CAAA;IAC3C;;;OAGG;IACH,SAAS,EAAE,MAAM,SAAS,YAAY,EAAE,CAAA;IACxC;;;;;OAKG;IACH,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,SAAS,KAAK,IAAI,CAAA;IAC7D,+EAA+E;IAC/E,UAAU,EAAE,MAAM,OAAO,CAAA;CAC1B,CAAA;AASD,0EAA0E;AAC1E,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,GAC7B,cAAc,CAiBhB;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,SAAS,EAC3C,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,SAAS,GAC3C,cAAc,CAGhB;AAED,mEAAmE;AACnE,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,cAAc,CAAC,YAAY,CAAC,EACxC,MAAM,EAAE,eAAe,GACtB,eAAe,CAEjB;AAED,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,GAAG,MAAM,CAE9F;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,cAAc,EACzB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,SAAS,YAAY,EAAE,GAChC;IAAE,UAAU,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAMxD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,KAAK,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,GACzC,SAAS,YAAY,EAAE,CAEzB"}
@@ -0,0 +1,104 @@
1
+ import { defaultDarkThemeId, defaultLightThemeId, resolveVariant } from "../../lib/themes.js";
2
+ import { DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS, normalizeAppearanceEditorFontSettings } from "../../lib/appearance-font-settings.js";
3
+ //#region src/components/theme/theme-state.ts
4
+ /**
5
+ * Deliberately lists only the fields every consumer has always had. A field added
6
+ * to {@link ThemeSelection} later gets no default here: `JSON.stringify` drops an
7
+ * `undefined`, so a store written by a consumer that never sets the field stays
8
+ * byte-identical to what it was before the field existed.
9
+ */
10
+ var defaultThemeSelection = {
11
+ appearance: "system",
12
+ lightThemeId: defaultLightThemeId,
13
+ darkThemeId: defaultDarkThemeId,
14
+ accent: "theme",
15
+ font: "system",
16
+ fonts: DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS,
17
+ density: "comfortable"
18
+ };
19
+ /**
20
+ * A stored selection's density, defaulted.
21
+ *
22
+ * The stored value is read through here rather than trusted, because a preference
23
+ * written before density existed has no `density` key and a hand-edited store may
24
+ * hold anything.
25
+ */
26
+ function resolvedDensity(selection) {
27
+ return selection.density === "compact" ? "compact" : "comfortable";
28
+ }
29
+ /** A selection with the `undefined` keys of a patch left out. */
30
+ function definedOnly(value) {
31
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
32
+ }
33
+ /** Keep the deprecated single-font view synchronized with the UI axis. */
34
+ function mergeThemeSelection(base, patch) {
35
+ const merged = {
36
+ ...base,
37
+ ...patch
38
+ };
39
+ let fonts;
40
+ if (patch.fonts !== void 0) fonts = normalizeAppearanceEditorFontSettings(patch.fonts).settings;
41
+ else if (patch.font !== void 0) {
42
+ const currentFonts = normalizeAppearanceEditorFontSettings(base.fonts, base.font).settings;
43
+ fonts = normalizeAppearanceEditorFontSettings({
44
+ ...currentFonts,
45
+ ui: {
46
+ ...currentFonts.ui,
47
+ family: patch.font
48
+ }
49
+ }).settings;
50
+ } else fonts = normalizeAppearanceEditorFontSettings(merged.fonts, merged.font).settings;
51
+ return {
52
+ ...merged,
53
+ fonts,
54
+ font: fonts.ui.family
55
+ };
56
+ }
57
+ /**
58
+ * The selection a provider starts from: the defaults, then whatever the store
59
+ * returned, then `initial`.
60
+ *
61
+ * `initial` wins over the store on every mount. That precedence is part of the
62
+ * contract Cortana relies on (its `initial` pins `appearance` and `font`), and it
63
+ * is why the store's answer is only the middle layer. A store that returned
64
+ * nothing, or threw, or answered with explicit `undefined`s, leaves the defaults
65
+ * standing for those fields.
66
+ */
67
+ function initialThemeSelection(stored, initial) {
68
+ return mergeThemeSelection(mergeThemeSelection(defaultThemeSelection, definedOnly(stored ?? {})), initial ?? {});
69
+ }
70
+ /** `system` resolved against what the operating system reports. */
71
+ function resolveAppearance(preference, system) {
72
+ return preference === "system" ? system : preference;
73
+ }
74
+ /** The theme id the selection names for a resolved appearance. */
75
+ function selectedThemeId(selection, appearance) {
76
+ return appearance === "dark" ? selection.darkThemeId : selection.lightThemeId;
77
+ }
78
+ /**
79
+ * What a selection paints: the resolved appearance and the variant for it.
80
+ *
81
+ * An id the registry does not hold resolves to the appearance's default rather than
82
+ * being rewritten (see `resolveVariant`), so the selection a host stores is never
83
+ * changed by being unresolvable.
84
+ */
85
+ function resolveThemeState(selection, system, registry) {
86
+ const appearance = resolveAppearance(selection.appearance, system);
87
+ return {
88
+ appearance,
89
+ variant: resolveVariant(registry, selectedThemeId(selection, appearance), appearance)
90
+ };
91
+ }
92
+ /**
93
+ * The registry a provider resolves against: the catalogue, then the host's extras.
94
+ *
95
+ * The catalogue wins an id collision, because it is listed first and `resolveVariant`
96
+ * takes the first match: a host's variant can add a theme but cannot shadow one.
97
+ */
98
+ function mergeRegistry(builtin, extra) {
99
+ return extra && extra.length > 0 ? [...builtin, ...extra] : builtin;
100
+ }
101
+ //#endregion
102
+ export { defaultThemeSelection, initialThemeSelection, mergeRegistry, mergeThemeSelection, resolveAppearance, resolveThemeState, resolvedDensity, selectedThemeId };
103
+
104
+ //# sourceMappingURL=theme-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-state.js","names":[],"sources":["../../../src/components/theme/theme-state.ts"],"sourcesContent":["import {\n DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS,\n normalizeAppearanceEditorFontSettings,\n type AppearanceEditorFontSettings,\n} from '#lib/appearance-font-settings'\nimport type { AccentPreset } from '@adea-ai/themes'\nimport {\n defaultDarkThemeId,\n defaultLightThemeId,\n resolveVariant,\n type ThemeAppearance,\n type ThemeVariant,\n} from '#lib/themes'\n\n/**\n * The pure half of the theme provider: what a selection is, how two selections\n * merge, and what a selection resolves to.\n *\n * Nothing here touches the document, storage or a signal, so each rule can be\n * tested by calling it. `ThemeProvider` owns the reactivity and wires these to it;\n * `theme-document.ts` owns the writes; `theme-persistence.ts` owns the store.\n */\n\n/**\n * Four independent choices, and keeping them independent is the point:\n *\n * - **appearance** — light, dark, or follow the system.\n * - **a theme per appearance** — so a user can run Catppuccin Mocha by night and\n * Solarized Light by day without re-choosing when the system flips.\n * - **an accent** — adea's six presets, or one of the accents the selected theme\n * pair carries itself (`ansi-blue`…), which re-colour the interactive roles on\n * top of whichever theme is active.\n * - **fonts** — separate family and size choices for UI, content and code.\n */\nexport type ThemeSelection = {\n /** `system` follows `prefers-color-scheme` and updates when it changes. */\n appearance: ThemeAppearance | 'system'\n /** The variant to use when the resolved appearance is light. */\n lightThemeId: string\n /** The variant to use when the resolved appearance is dark. */\n darkThemeId: string\n /**\n * An `accentPresets` id, a theme accent id from `themeAccents()` (`ansi-blue`…),\n * or `theme` for the variant's own primary. A theme accent the current pair does\n * not offer falls back to the variant's own primary.\n */\n accent: string\n /** UI-family alias for consumers of the original single-font preference. */\n font: string\n /** UI, content and code font settings. Omitted legacy records are migrated from `font`. */\n fonts?: AppearanceEditorFontSettings\n /**\n * `comfortable` is the system's default geometry; `compact` moves the control\n * ladder down one rung.\n *\n * Optional, and defaulted on read, so a preference stored before density existed\n * keeps working and `ThemeSelection` stays assignable without it.\n */\n density?: ThemeDensity\n}\n\n/**\n * The two density rungs.\n *\n * `comfortable` is the geometry in `theme.css`, so it is the absence of an\n * attribute rather than a value: a document that ships no `data-density` at all\n * renders correctly, which is what keeps this additive.\n */\nexport type ThemeDensity = 'comfortable' | 'compact'\n\n/**\n * Deliberately lists only the fields every consumer has always had. A field added\n * to {@link ThemeSelection} later gets no default here: `JSON.stringify` drops an\n * `undefined`, so a store written by a consumer that never sets the field stays\n * byte-identical to what it was before the field existed.\n */\nexport const defaultThemeSelection: ThemeSelection = {\n appearance: 'system',\n lightThemeId: defaultLightThemeId,\n darkThemeId: defaultDarkThemeId,\n accent: 'theme',\n font: 'system',\n fonts: DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS,\n density: 'comfortable',\n}\n\n/**\n * A stored selection's density, defaulted.\n *\n * The stored value is read through here rather than trusted, because a preference\n * written before density existed has no `density` key and a hand-edited store may\n * hold anything.\n */\nexport function resolvedDensity(selection: ThemeSelection): ThemeDensity {\n return selection.density === 'compact' ? 'compact' : 'comfortable'\n}\n\nexport type ThemeContextValue = {\n /** The preference as stored. A {@link ThemeContextValue.preview} does not change it. */\n selection: () => ThemeSelection\n /** What the preference resolves to right now, after `system`. */\n resolvedAppearance: () => ThemeAppearance\n /** The variant in use. */\n variant: () => ThemeVariant\n /** Update part of the preference. */\n setSelection: (patch: Partial<ThemeSelection>) => void\n /**\n * The built-in catalogue, so a picker does not import it separately. A plain\n * array: {@link ThemeContextValue.allThemes} is the one that follows a host's\n * extra themes.\n */\n themes: readonly ThemeVariant[]\n /**\n * The accents the selected light/dark pair carries, offered beside the presets.\n * Follows the selection: a different theme pair may offer different slots.\n */\n themeAccents: () => readonly AccentPreset[]\n /**\n * The built-in catalogue followed by the provider's `themes` prop. Reactive when\n * that prop is a function that reads signals.\n */\n allThemes: () => readonly ThemeVariant[]\n /**\n * Paint the document from `draft` laid over the stored selection, without\n * persisting it or changing what {@link ThemeContextValue.selection} returns.\n * `undefined` ends the preview. A {@link ThemeContextValue.setSelection} ends it\n * too, because the committed selection is then what should be showing.\n */\n preview: (draft: Partial<ThemeSelection> | undefined) => void\n /** True while a {@link ThemeContextValue.preview} draft is on the document. */\n previewing: () => boolean\n}\n\n/** A selection with the `undefined` keys of a patch left out. */\nfunction definedOnly<T extends object>(value: T): Partial<T> {\n return Object.fromEntries(\n Object.entries(value).filter(([, entry]) => entry !== undefined)\n ) as Partial<T>\n}\n\n/** Keep the deprecated single-font view synchronized with the UI axis. */\nexport function mergeThemeSelection(\n base: ThemeSelection,\n patch: Partial<ThemeSelection>\n): ThemeSelection {\n const merged = { ...base, ...patch }\n let fonts: AppearanceEditorFontSettings\n\n if (patch.fonts !== undefined) {\n fonts = normalizeAppearanceEditorFontSettings(patch.fonts).settings\n } else if (patch.font !== undefined) {\n const currentFonts = normalizeAppearanceEditorFontSettings(base.fonts, base.font).settings\n fonts = normalizeAppearanceEditorFontSettings({\n ...currentFonts,\n ui: { ...currentFonts.ui, family: patch.font },\n }).settings\n } else {\n fonts = normalizeAppearanceEditorFontSettings(merged.fonts, merged.font).settings\n }\n\n return { ...merged, fonts, font: fonts.ui.family }\n}\n\n/**\n * The selection a provider starts from: the defaults, then whatever the store\n * returned, then `initial`.\n *\n * `initial` wins over the store on every mount. That precedence is part of the\n * contract Cortana relies on (its `initial` pins `appearance` and `font`), and it\n * is why the store's answer is only the middle layer. A store that returned\n * nothing, or threw, or answered with explicit `undefined`s, leaves the defaults\n * standing for those fields.\n */\nexport function initialThemeSelection(\n stored: Partial<ThemeSelection> | undefined,\n initial: Partial<ThemeSelection> | undefined\n): ThemeSelection {\n const base = mergeThemeSelection(defaultThemeSelection, definedOnly(stored ?? {}))\n return mergeThemeSelection(base, initial ?? {})\n}\n\n/** `system` resolved against what the operating system reports. */\nexport function resolveAppearance(\n preference: ThemeSelection['appearance'],\n system: ThemeAppearance\n): ThemeAppearance {\n return preference === 'system' ? system : preference\n}\n\n/** The theme id the selection names for a resolved appearance. */\nexport function selectedThemeId(selection: ThemeSelection, appearance: ThemeAppearance): string {\n return appearance === 'dark' ? selection.darkThemeId : selection.lightThemeId\n}\n\n/**\n * What a selection paints: the resolved appearance and the variant for it.\n *\n * An id the registry does not hold resolves to the appearance's default rather than\n * being rewritten (see `resolveVariant`), so the selection a host stores is never\n * changed by being unresolvable.\n */\nexport function resolveThemeState(\n selection: ThemeSelection,\n system: ThemeAppearance,\n registry: readonly ThemeVariant[]\n): { appearance: ThemeAppearance; variant: ThemeVariant } {\n const appearance = resolveAppearance(selection.appearance, system)\n return {\n appearance,\n variant: resolveVariant(registry, selectedThemeId(selection, appearance), appearance),\n }\n}\n\n/**\n * The registry a provider resolves against: the catalogue, then the host's extras.\n *\n * The catalogue wins an id collision, because it is listed first and `resolveVariant`\n * takes the first match: a host's variant can add a theme but cannot shadow one.\n */\nexport function mergeRegistry(\n builtin: readonly ThemeVariant[],\n extra: readonly ThemeVariant[] | undefined\n): readonly ThemeVariant[] {\n return extra && extra.length > 0 ? [...builtin, ...extra] : builtin\n}\n"],"mappings":";;;;;;;;;AA4EA,IAAa,wBAAwC;CACnD,YAAY;CACZ,cAAc;CACd,aAAa;CACb,QAAQ;CACR,MAAM;CACN,OAAO;CACP,SAAS;AACX;;;;;;;;AASA,SAAgB,gBAAgB,WAAyC;CACvE,OAAO,UAAU,YAAY,YAAY,YAAY;AACvD;;AAuCA,SAAS,YAA8B,OAAsB;CAC3D,OAAO,OAAO,YACZ,OAAO,QAAQ,KAAK,CAAC,CAAC,QAAQ,GAAG,WAAW,UAAU,KAAA,CAAS,CACjE;AACF;;AAGA,SAAgB,oBACd,MACA,OACgB;CAChB,MAAM,SAAS;EAAE,GAAG;EAAM,GAAG;CAAM;CACnC,IAAI;CAEJ,IAAI,MAAM,UAAU,KAAA,GAClB,QAAQ,sCAAsC,MAAM,KAAK,CAAC,CAAC;MACtD,IAAI,MAAM,SAAS,KAAA,GAAW;EACnC,MAAM,eAAe,sCAAsC,KAAK,OAAO,KAAK,IAAI,CAAC,CAAC;EAClF,QAAQ,sCAAsC;GAC5C,GAAG;GACH,IAAI;IAAE,GAAG,aAAa;IAAI,QAAQ,MAAM;GAAK;EAC/C,CAAC,CAAC,CAAC;CACL,OACE,QAAQ,sCAAsC,OAAO,OAAO,OAAO,IAAI,CAAC,CAAC;CAG3E,OAAO;EAAE,GAAG;EAAQ;EAAO,MAAM,MAAM,GAAG;CAAO;AACnD;;;;;;;;;;;AAYA,SAAgB,sBACd,QACA,SACgB;CAEhB,OAAO,oBADM,oBAAoB,uBAAuB,YAAY,UAAU,CAAC,CAAC,CACrD,GAAM,WAAW,CAAC,CAAC;AAChD;;AAGA,SAAgB,kBACd,YACA,QACiB;CACjB,OAAO,eAAe,WAAW,SAAS;AAC5C;;AAGA,SAAgB,gBAAgB,WAA2B,YAAqC;CAC9F,OAAO,eAAe,SAAS,UAAU,cAAc,UAAU;AACnE;;;;;;;;AASA,SAAgB,kBACd,WACA,QACA,UACwD;CACxD,MAAM,aAAa,kBAAkB,UAAU,YAAY,MAAM;CACjE,OAAO;EACL;EACA,SAAS,eAAe,UAAU,gBAAgB,WAAW,UAAU,GAAG,UAAU;CACtF;AACF;;;;;;;AAQA,SAAgB,cACd,SACA,OACyB;CACzB,OAAO,SAAS,MAAM,SAAS,IAAI,CAAC,GAAG,SAAS,GAAG,KAAK,IAAI;AAC9D"}
@@ -1,6 +1,6 @@
1
1
  import { cn } from "../../lib/utils.js";
2
2
  import { ToggleGroup, ToggleGroupItem } from "../ui/toggle-group/toggle-group.js";
3
- import { useTheme } from "./theme-provider.js";
3
+ import { useTheme } from "./theme-context.js";
4
4
  import { createComponent, insert, memo, mergeProps, template } from "solid-js/web";
5
5
  import { Monitor, Moon, Sun } from "lucide-solid";
6
6
  import { For, splitProps } from "solid-js";
package/dist/index.d.ts CHANGED
@@ -104,7 +104,7 @@ export * from './components/composites/help-center';
104
104
  export * from './components/composites/workspace-mark';
105
105
  export { cn } from './lib/utils';
106
106
  export { controlInteractive, controlSize, controlSizeIcon, controlSizes, cva, surfaceInteractive, type ControlSize, type VariantProps, } from './lib/variants';
107
- export { appearancePreviewThemes, builtinThemes, contrastRatio, defaultDarkThemeId, defaultLightThemeId, isThemeAccentId, resolveAccentPreset, themeAccentsFor, themeById, themeCssVariables, themeFamilies, themeRecordById, themeRecords, themesForAppearance, validateTheme, validateThemeRegistry, withAccent, type ThemeAppearance, type ThemeColors, type ThemeEditorPalette, type ThemeFinding, type ThemeProvenance, type ThemeTerminalPalette, type ThemeVariant, } from './lib/themes';
107
+ export { appearancePreviewThemes, builtinThemes, contrastRatio, defaultDarkThemeId, defaultLightThemeId, isThemeAccentId, resolveAccentPreset, resolveVariant, themeAccentsFor, themeById, themeCssVariables, themeFamilies, themeRecordById, themeRecords, themesForAppearance, tokensAsHex, validateTheme, validateThemeRegistry, variantFromRecord, withAccent, type ThemeAppearance, type ThemeColors, type ThemeEditorPalette, type ThemeFinding, type ThemeProvenance, type ThemeTerminalPalette, type ThemeVariant, } from './lib/themes';
108
108
  export { keyedRows, type KeyedRow } from './lib/keyed-rows';
109
109
  export { writeClipboardText } from './lib/clipboard';
110
110
  export { formatBytes, formatReleaseDate, plainTextFromMarkdown } from './lib/version-notes';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -104,11 +104,14 @@ import { PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, countL
104
104
  import { fontOptions } from "./lib/font-catalog.js";
105
105
  import { accentPresets, allTokens, colorTokens, densityTokens, designTokens, elevationTokens, motionTokens, radiusTokens, typographyTokens, undocumentedTokenAliases, zIndexTokens } from "./lib/tokens.js";
106
106
  import { isThemeAccentId } from "./lib/theme-accents.js";
107
- import { appearancePreviewThemes, builtinThemes, contrastRatio, defaultDarkThemeId, defaultLightThemeId, resolveAccentPreset, themeAccentsFor, themeById, themeCssVariables, themeFamilies, themeRecordById, themeRecords, themesForAppearance, validateTheme, validateThemeRegistry, withAccent } from "./lib/themes.js";
107
+ import { appearancePreviewThemes, builtinThemes, contrastRatio, defaultDarkThemeId, defaultLightThemeId, resolveAccentPreset, resolveVariant, themeAccentsFor, themeById, themeCssVariables, themeFamilies, themeRecordById, themeRecords, themesForAppearance, tokensAsHex, validateTheme, validateThemeRegistry, variantFromRecord, withAccent } from "./lib/themes.js";
108
108
  import { APPEARANCE_EDITOR_FONT_AXES, APPEARANCE_EDITOR_FONT_SIZE_MAX, APPEARANCE_EDITOR_FONT_SIZE_MIN, DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS, applyAppearanceFontSettings, fontSettingsBootstrapScript, normalizeAppearanceEditorFontSettings, normalizeAppearanceEditorFontSize } from "./lib/appearance-font-settings.js";
109
109
  import { AppearanceFontSettingsGroup } from "./components/composites/appearance-editor/font-settings-group.js";
110
110
  import { ThemePicker, ThemePreview, ThemeSwatch } from "./components/theme/theme-picker.js";
111
- import { ThemeProvider, defaultThemeSelection, inlineScriptLiteral, resolvedDensity, themeScript, useTheme } from "./components/theme/theme-provider.js";
111
+ import { useOptionalTheme, useTheme } from "./components/theme/theme-context.js";
112
+ import { defaultThemeSelection, resolvedDensity } from "./components/theme/theme-state.js";
113
+ import { localStoragePersistence } from "./components/theme/theme-persistence.js";
114
+ import { ThemeProvider, inlineScriptLiteral, themeScript } from "./components/theme/theme-provider.js";
112
115
  import { AppearancePanel } from "./components/theme/appearance-panel.js";
113
116
  import { ThemeToggle } from "./components/theme/theme-toggle.js";
114
117
  import { ThemeModeToggle } from "./components/theme/theme-mode-toggle.js";
@@ -133,4 +136,4 @@ import { AboutDialog } from "./components/composites/about-dialog/about-dialog.j
133
136
  import { HelpCenter } from "./components/composites/help-center/help-center.js";
134
137
  import { WorkspaceMark } from "./components/composites/workspace-mark/workspace-mark.js";
135
138
  import { writeClipboardText } from "./lib/clipboard.js";
136
- export { APPEARANCE_EDITOR_FONT_AXES, APPEARANCE_EDITOR_FONT_SIZE_MAX, APPEARANCE_EDITOR_FONT_SIZE_MIN, AboutDialog, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AccountMenu, ActionButton, Alert, AlertAction, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AnnotationSurface, AppShell, AppShellBody, AppShellContent, AppShellMain, AppearanceEditor, AppearanceEditorActions, AppearanceFontSettingsGroup, AppearancePanel, AppearancePopover, AspectRatio, AttachmentCard, Avatar, AvatarFallback, AvatarImage, Badge, Board, BoardCardBody, BoardCardTitle, BoardCardTrigger, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, BusySendButton, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CalendarSurface, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CatalogBrowser, CatalogDetail, CatalogDetailSection, ChatComposer, Checkbox, CheckboxDescription, CheckboxLabel, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxClear, ComboboxContent, ComboboxControl, ComboboxInput, ComboboxItem, ComboboxSection, ComboboxTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandHint, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut, CommandStatus, ComposerAttachmentButton, ComposerHint, ComposerMenu, ComposerMenuItem, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ContextualSidebar, ConversationAvatar, ConversationPane, ConversationSurface, DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS, DatePicker, DetailPanel, DetailPanelBody, DetailPanelField, DetailPanelHeader, DetailPanelSection, Dialog, DialogClose, DialogCloseButton, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffBlock, DiffSummary, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyState, EmptyTitle, EntityIcon, FLOATING_PREVIEW_CORNER_RADIUS, FLOATING_PREVIEW_EDGE_GAP, Field, FieldDescription, FieldError, FieldGroup, FieldInput, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTextArea, FloatingPreview, FormField, Heading, HelpCenter, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputControl, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputOtp, InputOtpCaret, Item, ItemDescription, ItemEmpty, ItemGroup, ItemGroupEntry, ItemTitle, Kbd, KbdChord, KbdGroup, Label, ListGroup, ListRow, ListRowControl, MAX_LAYOUT_DEPTH, MAX_LAYOUT_LEAVES, MAX_SPLIT_RATIO, MIN_SPLIT_RATIO, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, ModalDialog, Motion, NO_FLOATING_PREVIEW_OBSTACLES, NO_PREVIEW_MINI_PLAYER_OBSTACLES, NativeSelect, NavigationMenu, NavigationMenuContent, NavigationMenuGroup, NavigationMenuGroupLabel, NavigationMenuItem, NavigationMenuMenu, NavigationMenuSeparator, NavigationMenuTrigger, NavigationMenuViewport, NumberField, OrbitItem, OrbitLayout, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, PREVIEW_MINI_PLAYER_CORNER_RADIUS, PREVIEW_MINI_PLAYER_EDGE_GAP, Page, PageHeader, PageHeaderActions, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, PageSection, Pagination, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPrevious, PalettePreview, Panel, PanelActions, PanelBody, PanelCard, PanelDescription, PanelFooter, PanelHeader, PanelPlaceholder, PanelTitle, PanelToolbar, PixelResizeHandle, Popover, PopoverAnchor, PopoverCloseButton, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger, Presence, Progress, PropertyList, PropertyRow, PropertyTerm, PropertyValue, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, SceneControls, ScrollArea, SecretInputGroup, Select, SelectChevronsUpDown, SelectContent, SelectItem, SelectLabel, SelectSection, SelectTrigger, SelectValue, Separator, SettingsField, SettingsLayout, SettingsNavigation, SettingsPage, SettingsRow, SettingsSection, Sheet, SheetBody, SheetCloseButton, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, SideRail, SideRailButton, SideRailContent, SideRailFooter, SideRailHeader, SideRailItem, SideRailSection, SidebarNav, SidebarNavButton, SidebarNavContent, SidebarNavFooter, SidebarNavHeader, SidebarNavItem, SidebarNavLabel, SidebarNavResizeHandle, SidebarNavRow, SidebarNavSection, SidebarNavTitle, Skeleton, SkipLink, Slider, Spinner, SplitLayout, Stat, StatGroup, StatusBar, StatusBarItem, StatusBarSpacer, StatusChip, StatusList, Switch, SwitchDescription, SwitchLabel, TALL_CODE_BLOCK_PX, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableNumericCell, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Text, TextLink, Textarea, ThemeMiniature, ThemeMiniatureSplit, ThemeModeToggle, ThemePicker, ThemePreview, ThemeProvider, ThemeSwatch, ThemeToggle, ThreadPanel, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, TopBarBreadcrumb, TopBarPill, TopBarSearch, TopBarSection, TopBarTitle, TranscriptComposition, Tree, TreeRow, TreeRowActions, UpdateChannelControl, UpdateDialog, ValueCombobox, VirtualWindow, WorkspaceMark, accentPresets, alertVariants, allTokens, appearancePreviewThemes, applyAppearanceFontSettings, badgeVariants, boardCardTitleVariants, builtinThemes, buttonVariants, cardVariants, clampFloatingPreviewPosition, clampPreviewMiniPlayerPosition, closePane, cn, colorTokens, computeLayoutFrames, contrastRatio, controlInteractive, controlSize, controlSizeIcon, controlSizes, countLeaves, countLines, createAppMenuItems, createLayoutState, cva, defaultDarkThemeId, defaultLightThemeId, defaultThemeSelection, densityTokens, designTokens, diffLineVariants, diffStats, diffTargetPath, elevationTokens, entityIconVariants, expandAll, findTokenRanges, focusPane, fontOptions, fontSettingsBootstrapScript, formatBytes, formatReleaseDate, formatToken, headingElement, headingVariants, initialsFrom, inlineScriptLiteral, isPasteBlock, isThemeAccentId, itemVariants, kbdChordKeys, kbdGroupVariants, kbdVariants, keyedRows, layoutDepth, listLeaves, monogram, motionTokens, movePane, neighborLeaf, nextSeq, normalizeAppearanceEditorFontSettings, normalizeAppearanceEditorFontSize, normalizeLayout, parseDiff, plainTextFromMarkdown, platformModifierKey, pruneBlocks, radiusTokens, recollapsePastes, remapCarriedBlocks, resizeFloatingPreview, resizePreviewMiniPlayer, resizeSplit, resolveAccentPreset, resolveFloatingPreviewFrame, resolvePreviewMiniPlayerFrame, resolvedDensity, searchShortcutKeyshortcuts, searchShortcutLabel, sheetVariants, shouldCollapse, sidebarNavItemClass, sidebarNavItemStateClass, splitPane, splitPaneBalanced, statusDotVariants, stripTrailingBlankLines, surfaceInteractive, swapPanes, textElement, textVariants, textareaVariants, themeAccentsFor, themeById, themeCssVariables, themeFamilies, themeRecordById, themeRecords, themeScript, themesForAppearance, toast, toaster, toggleVariants, tokenRangeAt, transcriptDisclosureKey, typographyTokens, undoClosePane, undocumentedTokenAliases, useSideRail, useTheme, validateTheme, validateThemeRegistry, withAccent, writeClipboardText, zIndexTokens };
139
+ export { APPEARANCE_EDITOR_FONT_AXES, APPEARANCE_EDITOR_FONT_SIZE_MAX, APPEARANCE_EDITOR_FONT_SIZE_MIN, AboutDialog, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AccountMenu, ActionButton, Alert, AlertAction, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AnnotationSurface, AppShell, AppShellBody, AppShellContent, AppShellMain, AppearanceEditor, AppearanceEditorActions, AppearanceFontSettingsGroup, AppearancePanel, AppearancePopover, AspectRatio, AttachmentCard, Avatar, AvatarFallback, AvatarImage, Badge, Board, BoardCardBody, BoardCardTitle, BoardCardTrigger, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, BusySendButton, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CalendarSurface, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CatalogBrowser, CatalogDetail, CatalogDetailSection, ChatComposer, Checkbox, CheckboxDescription, CheckboxLabel, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxClear, ComboboxContent, ComboboxControl, ComboboxInput, ComboboxItem, ComboboxSection, ComboboxTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandHint, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut, CommandStatus, ComposerAttachmentButton, ComposerHint, ComposerMenu, ComposerMenuItem, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ContextualSidebar, ConversationAvatar, ConversationPane, ConversationSurface, DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS, DatePicker, DetailPanel, DetailPanelBody, DetailPanelField, DetailPanelHeader, DetailPanelSection, Dialog, DialogClose, DialogCloseButton, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffBlock, DiffSummary, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyState, EmptyTitle, EntityIcon, FLOATING_PREVIEW_CORNER_RADIUS, FLOATING_PREVIEW_EDGE_GAP, Field, FieldDescription, FieldError, FieldGroup, FieldInput, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTextArea, FloatingPreview, FormField, Heading, HelpCenter, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputControl, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputOtp, InputOtpCaret, Item, ItemDescription, ItemEmpty, ItemGroup, ItemGroupEntry, ItemTitle, Kbd, KbdChord, KbdGroup, Label, ListGroup, ListRow, ListRowControl, MAX_LAYOUT_DEPTH, MAX_LAYOUT_LEAVES, MAX_SPLIT_RATIO, MIN_SPLIT_RATIO, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, ModalDialog, Motion, NO_FLOATING_PREVIEW_OBSTACLES, NO_PREVIEW_MINI_PLAYER_OBSTACLES, NativeSelect, NavigationMenu, NavigationMenuContent, NavigationMenuGroup, NavigationMenuGroupLabel, NavigationMenuItem, NavigationMenuMenu, NavigationMenuSeparator, NavigationMenuTrigger, NavigationMenuViewport, NumberField, OrbitItem, OrbitLayout, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, PREVIEW_MINI_PLAYER_CORNER_RADIUS, PREVIEW_MINI_PLAYER_EDGE_GAP, Page, PageHeader, PageHeaderActions, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, PageSection, Pagination, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPrevious, PalettePreview, Panel, PanelActions, PanelBody, PanelCard, PanelDescription, PanelFooter, PanelHeader, PanelPlaceholder, PanelTitle, PanelToolbar, PixelResizeHandle, Popover, PopoverAnchor, PopoverCloseButton, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger, Presence, Progress, PropertyList, PropertyRow, PropertyTerm, PropertyValue, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, SceneControls, ScrollArea, SecretInputGroup, Select, SelectChevronsUpDown, SelectContent, SelectItem, SelectLabel, SelectSection, SelectTrigger, SelectValue, Separator, SettingsField, SettingsLayout, SettingsNavigation, SettingsPage, SettingsRow, SettingsSection, Sheet, SheetBody, SheetCloseButton, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, SideRail, SideRailButton, SideRailContent, SideRailFooter, SideRailHeader, SideRailItem, SideRailSection, SidebarNav, SidebarNavButton, SidebarNavContent, SidebarNavFooter, SidebarNavHeader, SidebarNavItem, SidebarNavLabel, SidebarNavResizeHandle, SidebarNavRow, SidebarNavSection, SidebarNavTitle, Skeleton, SkipLink, Slider, Spinner, SplitLayout, Stat, StatGroup, StatusBar, StatusBarItem, StatusBarSpacer, StatusChip, StatusList, Switch, SwitchDescription, SwitchLabel, TALL_CODE_BLOCK_PX, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableNumericCell, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Text, TextLink, Textarea, ThemeMiniature, ThemeMiniatureSplit, ThemeModeToggle, ThemePicker, ThemePreview, ThemeProvider, ThemeSwatch, ThemeToggle, ThreadPanel, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, TopBarBreadcrumb, TopBarPill, TopBarSearch, TopBarSection, TopBarTitle, TranscriptComposition, Tree, TreeRow, TreeRowActions, UpdateChannelControl, UpdateDialog, ValueCombobox, VirtualWindow, WorkspaceMark, accentPresets, alertVariants, allTokens, appearancePreviewThemes, applyAppearanceFontSettings, badgeVariants, boardCardTitleVariants, builtinThemes, buttonVariants, cardVariants, clampFloatingPreviewPosition, clampPreviewMiniPlayerPosition, closePane, cn, colorTokens, computeLayoutFrames, contrastRatio, controlInteractive, controlSize, controlSizeIcon, controlSizes, countLeaves, countLines, createAppMenuItems, createLayoutState, cva, defaultDarkThemeId, defaultLightThemeId, defaultThemeSelection, densityTokens, designTokens, diffLineVariants, diffStats, diffTargetPath, elevationTokens, entityIconVariants, expandAll, findTokenRanges, focusPane, fontOptions, fontSettingsBootstrapScript, formatBytes, formatReleaseDate, formatToken, headingElement, headingVariants, initialsFrom, inlineScriptLiteral, isPasteBlock, isThemeAccentId, itemVariants, kbdChordKeys, kbdGroupVariants, kbdVariants, keyedRows, layoutDepth, listLeaves, localStoragePersistence, monogram, motionTokens, movePane, neighborLeaf, nextSeq, normalizeAppearanceEditorFontSettings, normalizeAppearanceEditorFontSize, normalizeLayout, parseDiff, plainTextFromMarkdown, platformModifierKey, pruneBlocks, radiusTokens, recollapsePastes, remapCarriedBlocks, resizeFloatingPreview, resizePreviewMiniPlayer, resizeSplit, resolveAccentPreset, resolveFloatingPreviewFrame, resolvePreviewMiniPlayerFrame, resolveVariant, resolvedDensity, searchShortcutKeyshortcuts, searchShortcutLabel, sheetVariants, shouldCollapse, sidebarNavItemClass, sidebarNavItemStateClass, splitPane, splitPaneBalanced, statusDotVariants, stripTrailingBlankLines, surfaceInteractive, swapPanes, textElement, textVariants, textareaVariants, themeAccentsFor, themeById, themeCssVariables, themeFamilies, themeRecordById, themeRecords, themeScript, themesForAppearance, toast, toaster, toggleVariants, tokenRangeAt, tokensAsHex, transcriptDisclosureKey, typographyTokens, undoClosePane, undocumentedTokenAliases, useOptionalTheme, useSideRail, useTheme, validateTheme, validateThemeRegistry, variantFromRecord, withAccent, writeClipboardText, zIndexTokens };
@@ -38,7 +38,7 @@ export declare function normalizeAppearanceEditorFontSettings(value: unknown, le
38
38
  * sizes, and projected CSS variables. The marker activates the optional role
39
39
  * stylesheet and survives CSS import reordering.
40
40
  */
41
- export declare function applyAppearanceFontSettings(root: HTMLElement, value: unknown): NormalizedAppearanceEditorFontSettings;
41
+ export declare function applyAppearanceFontSettings(root: Pick<HTMLElement, 'removeAttribute' | 'setAttribute' | 'style'>, value: unknown): NormalizedAppearanceEditorFontSettings;
42
42
  /**
43
43
  * Generate a safe inline prepaint script for a host-owned appearance record.
44
44
  *
@@ -1 +1 @@
1
- {"version":3,"file":"appearance-font-settings.d.ts","sourceRoot":"","sources":["../../src/lib/appearance-font-settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAGhE,eAAO,MAAM,2BAA2B,oCAAqC,CAAA;AAE7E,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAA;AACnF,MAAM,MAAM,4BAA4B,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;AAE3D,MAAM,MAAM,2BAA2B,GAAG,QAAQ,CAAC;IACjD,6EAA6E;IAC7E,MAAM,EAAE,4BAA4B,CAAA;IACpC,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAA;CACb,CAAC,CAAA;AAEF,0EAA0E;AAC1E,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CACjD,MAAM,CAAC,wBAAwB,EAAE,2BAA2B,CAAC,CAC9D,CAAA;AAED,eAAO,MAAM,+BAA+B,KAAK,CAAA;AACjD,eAAO,MAAM,+BAA+B,KAAK,CAAA;AAEjD,+DAA+D;AAC/D,eAAO,MAAM,uCAAuC,EAAE,4BAIpD,CAAA;AAEF,MAAM,MAAM,sCAAsC,GAAG,QAAQ,CAAC;IAC5D,QAAQ,EAAE,4BAA4B,CAAA;IACtC,iFAAiF;IACjF,aAAa,EAAE,SAAS,wBAAwB,EAAE,CAAA;CACnD,CAAC,CAAA;AAqEF,oFAAoF;AACpF,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ1F;AAED;;;;;;;GAOG;AACH,wBAAgB,qCAAqC,CACnD,KAAK,EAAE,OAAO,EACd,cAAc,CAAC,EAAE,OAAO,GACvB,sCAAsC,CA+CxC;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,OAAO,GACb,sCAAsC,CAsBxC;AAED;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAajG"}
1
+ {"version":3,"file":"appearance-font-settings.d.ts","sourceRoot":"","sources":["../../src/lib/appearance-font-settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAGhE,eAAO,MAAM,2BAA2B,oCAAqC,CAAA;AAE7E,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAA;AACnF,MAAM,MAAM,4BAA4B,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;AAE3D,MAAM,MAAM,2BAA2B,GAAG,QAAQ,CAAC;IACjD,6EAA6E;IAC7E,MAAM,EAAE,4BAA4B,CAAA;IACpC,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAA;CACb,CAAC,CAAA;AAEF,0EAA0E;AAC1E,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CACjD,MAAM,CAAC,wBAAwB,EAAE,2BAA2B,CAAC,CAC9D,CAAA;AAED,eAAO,MAAM,+BAA+B,KAAK,CAAA;AACjD,eAAO,MAAM,+BAA+B,KAAK,CAAA;AAEjD,+DAA+D;AAC/D,eAAO,MAAM,uCAAuC,EAAE,4BAIpD,CAAA;AAEF,MAAM,MAAM,sCAAsC,GAAG,QAAQ,CAAC;IAC5D,QAAQ,EAAE,4BAA4B,CAAA;IACtC,iFAAiF;IACjF,aAAa,EAAE,SAAS,wBAAwB,EAAE,CAAA;CACnD,CAAC,CAAA;AAqEF,oFAAoF;AACpF,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ1F;AAED;;;;;;;GAOG;AACH,wBAAgB,qCAAqC,CACnD,KAAK,EAAE,OAAO,EACd,cAAc,CAAC,EAAE,OAAO,GACvB,sCAAsC,CA+CxC;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,iBAAiB,GAAG,cAAc,GAAG,OAAO,CAAC,EACrE,KAAK,EAAE,OAAO,GACb,sCAAsC,CAsBxC;AAED;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAajG"}
@@ -1 +1 @@
1
- {"version":3,"file":"appearance-font-settings.js","names":[],"sources":["../../src/lib/appearance-font-settings.ts"],"sourcesContent":["import { fontOptions, type FontOption } from '#lib/font-catalog'\nimport { safeScriptStringLiteral } from '#lib/safe-script'\n\nexport const APPEARANCE_EDITOR_FONT_AXES = ['ui', 'content', 'code'] as const\n\nexport type AppearanceEditorFontAxis = (typeof APPEARANCE_EDITOR_FONT_AXES)[number]\nexport type AppearanceEditorFontFamilyId = FontOption['id']\n\nexport type AppearanceEditorFontSetting = Readonly<{\n /** A stable id from the shared font catalogue, never a CSS family string. */\n family: AppearanceEditorFontFamilyId\n /** A pixel size, normalized to the supported range. */\n size: number\n}>\n\n/** The host-owned choices edited by the shared appearance composition. */\nexport type AppearanceEditorFontSettings = Readonly<\n Record<AppearanceEditorFontAxis, AppearanceEditorFontSetting>\n>\n\nexport const APPEARANCE_EDITOR_FONT_SIZE_MIN = 10\nexport const APPEARANCE_EDITOR_FONT_SIZE_MAX = 32\n\n/** New preferences use the platform face in each text role. */\nexport const DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS: AppearanceEditorFontSettings = Object.freeze({\n ui: Object.freeze({ family: 'system', size: 14 }),\n content: Object.freeze({ family: 'system', size: 14 }),\n code: Object.freeze({ family: 'system', size: 12 }),\n})\n\nexport type NormalizedAppearanceEditorFontSettings = Readonly<{\n settings: AppearanceEditorFontSettings\n /** Axes whose persisted family or size was unavailable or outside its limits. */\n recoveredAxes: readonly AppearanceEditorFontAxis[]\n}>\n\nconst fontFamilyIds: ReadonlySet<string> = new Set(fontOptions.map((option) => option.id))\nconst fontOptionsById = Object.freeze(\n Object.fromEntries(fontOptions.map((option) => [option.id, option])) as Record<\n AppearanceEditorFontFamilyId,\n FontOption\n >\n)\nconst fontProjectionById = Object.freeze(\n Object.fromEntries(\n fontOptions.map((option) => [\n option.id,\n {\n familyVariables: option.familyVariables,\n uiTracking: option.uiTracking,\n uiWordSpacing: option.uiWordSpacing,\n },\n ])\n ) as Record<\n AppearanceEditorFontFamilyId,\n Pick<FontOption, 'familyVariables' | 'uiTracking' | 'uiWordSpacing'>\n >\n)\nconst fontAxisProjection = Object.freeze({\n ui: Object.freeze({\n familyAttribute: 'data-ui-font',\n familyProperty: '--font-ui',\n sizeProperty: '--font-ui-size',\n scaleProperty: '--font-ui-scale',\n defaultSize: DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS.ui.size,\n }),\n content: Object.freeze({\n familyAttribute: 'data-content-font',\n familyProperty: '--font-content',\n sizeProperty: '--font-content-size',\n scaleProperty: '--font-content-scale',\n defaultSize: DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS.content.size,\n }),\n code: Object.freeze({\n familyAttribute: 'data-code-font',\n familyProperty: '--font-code',\n sizeProperty: '--font-code-size',\n scaleProperty: '--font-code-scale',\n defaultSize: DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS.code.size,\n }),\n})\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction hasOwn(value: Record<string, unknown>, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(value, key)\n}\n\nfunction normalizeFamily(value: unknown): AppearanceEditorFontFamilyId | undefined {\n return typeof value === 'string' && fontFamilyIds.has(value)\n ? (value as AppearanceEditorFontFamilyId)\n : undefined\n}\n\nfunction clampFontSize(value: number): number {\n return Math.min(\n APPEARANCE_EDITOR_FONT_SIZE_MAX,\n Math.max(APPEARANCE_EDITOR_FONT_SIZE_MIN, Math.round(value))\n )\n}\n\n/** Normalize a single number-input value; invalid edits return the current size. */\nexport function normalizeAppearanceEditorFontSize(value: unknown, fallback: number): number {\n const parsed =\n typeof value === 'number'\n ? value\n : typeof value === 'string' && value.trim() !== ''\n ? Number(value)\n : Number.NaN\n return Number.isFinite(parsed) ? clampFontSize(parsed) : clampFontSize(fallback)\n}\n\n/**\n * Recover persisted font choices against the shared font catalogue.\n *\n * `legacyUiFamily` lets a host migrate its previous single font field into the\n * UI axis. Content and code remain on the new System defaults during that\n * migration. Missing settings are ordinary defaults; an unknown saved id or an\n * invalid size is reported through `recoveredAxes` for the host's notice.\n */\nexport function normalizeAppearanceEditorFontSettings(\n value: unknown,\n legacyUiFamily?: unknown\n): NormalizedAppearanceEditorFontSettings {\n const source = isRecord(value) ? value : undefined\n const malformedRoot = value !== undefined && value !== null && source === undefined\n const recovered = new Set<AppearanceEditorFontAxis>()\n const settings = {} as Record<AppearanceEditorFontAxis, AppearanceEditorFontSetting>\n\n for (const axis of APPEARANCE_EDITOR_FONT_AXES) {\n const axisPresent = source ? hasOwn(source, axis) : false\n const axisValue = source?.[axis]\n const axisSource = isRecord(axisValue) ? axisValue : undefined\n const fallback = DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS[axis]\n\n if (malformedRoot || (axisPresent && axisSource === undefined)) recovered.add(axis)\n\n const hasFamily = axisSource ? hasOwn(axisSource, 'family') : false\n const familyInput = hasFamily\n ? axisSource?.['family']\n : axis === 'ui' && legacyUiFamily !== undefined\n ? legacyUiFamily\n : undefined\n const family = normalizeFamily(familyInput) ?? fallback.family\n if (\n (hasFamily || (axis === 'ui' && legacyUiFamily !== undefined)) &&\n !normalizeFamily(familyInput)\n ) {\n recovered.add(axis)\n }\n\n const hasSize = axisSource ? hasOwn(axisSource, 'size') : false\n const sizeInput = axisSource?.['size']\n const size = hasSize\n ? normalizeAppearanceEditorFontSize(sizeInput, fallback.size)\n : fallback.size\n if (\n hasSize &&\n (typeof sizeInput !== 'number' || !Number.isFinite(sizeInput) || sizeInput !== size)\n ) {\n recovered.add(axis)\n }\n\n settings[axis] = Object.freeze({ family, size })\n }\n\n return Object.freeze({\n settings: Object.freeze(settings),\n recoveredAxes: Object.freeze(APPEARANCE_EDITOR_FONT_AXES.filter((axis) => recovered.has(axis))),\n })\n}\n\n/**\n * Project normalized font preferences onto a document root.\n *\n * This is shared by `ThemeProvider` and hosts that own their own appearance\n * persistence, so UI/content/code use the same catalogue ids, theme tokens,\n * sizes, and projected CSS variables. The marker activates the optional role\n * stylesheet and survives CSS import reordering.\n */\nexport function applyAppearanceFontSettings(\n root: HTMLElement,\n value: unknown\n): NormalizedAppearanceEditorFontSettings {\n const normalized = normalizeAppearanceEditorFontSettings(value)\n const { settings } = normalized\n\n root.removeAttribute('data-font')\n root.setAttribute('data-font-settings', '')\n for (const axis of APPEARANCE_EDITOR_FONT_AXES) {\n const projection = fontAxisProjection[axis]\n const setting = settings[axis]\n const option = fontOptionsById[setting.family]\n if (setting.family === 'system') root.removeAttribute(projection.familyAttribute)\n else root.setAttribute(projection.familyAttribute, setting.family)\n root.style.setProperty(projection.familyProperty, `var(${option.familyVariables[axis]})`)\n root.style.setProperty(projection.sizeProperty, String(setting.size) + 'px')\n root.style.setProperty(projection.scaleProperty, String(setting.size / projection.defaultSize))\n if (axis === 'ui') {\n root.style.setProperty('--ui-tracking', option.uiTracking)\n root.style.setProperty('--ui-word-spacing', option.uiWordSpacing)\n }\n }\n\n return normalized\n}\n\n/**\n * Generate a safe inline prepaint script for a host-owned appearance record.\n *\n * The stored object is read from `localStorage[storageKey].fonts`. A legacy\n * top-level `font` family migrates into UI only; content/code use the shared\n * defaults. The script applies the same catalogue whitelist, limits, attributes,\n * and CSS properties as `applyAppearanceFontSettings` before styles paint. When\n * `persistedVersion` is supplied, only a record with that exact top-level version\n * is used; absent or mismatched records receive the System defaults.\n */\nexport function fontSettingsBootstrapScript(storageKey: string, persistedVersion?: number): string {\n if (persistedVersion !== undefined && !Number.isSafeInteger(persistedVersion)) {\n throw new RangeError('persistedVersion must be a safe integer')\n }\n const axisConfig = JSON.stringify(fontAxisProjection)\n const fontProjection = JSON.stringify(fontProjectionById)\n const fontIds = `[${fontOptions.map((option) => safeScriptStringLiteral(option.id)).join(',')}]`\n const persistedVersionGuard =\n persistedVersion === undefined\n ? ''\n : `&&parsed.version===Number(${safeScriptStringLiteral(String(persistedVersion))})`\n\n return `(function(){var r=document.documentElement;var axes=JSON.parse(${safeScriptStringLiteral(axisConfig)});var projection=JSON.parse(${safeScriptStringLiteral(fontProjection)});var ids=${fontIds};var has=function(v,k){return Object.prototype.hasOwnProperty.call(v,k)};var record=function(v){return typeof v==='object'&&v!==null&&!Array.isArray(v)};var p={};try{var raw=localStorage.getItem(${safeScriptStringLiteral(storageKey)});var parsed=raw?JSON.parse(raw):{};if(record(parsed)${persistedVersionGuard})p=parsed;}catch(e){}var saved=record(p.fonts)?p.fonts:{};var valid=function(v,d){return ids.indexOf(v)!==-1?v:d};var size=function(v,d){var n=typeof v==='number'?v:typeof v==='string'&&v.trim()!==''?Number(v):NaN;return Number.isFinite(n)?Math.min(${APPEARANCE_EDITOR_FONT_SIZE_MAX},Math.max(${APPEARANCE_EDITOR_FONT_SIZE_MIN},Math.round(n))):d};r.setAttribute('data-font-settings','');for(var axis in axes){if(!has(axes,axis))continue;var spec=axes[axis];var candidate=saved[axis];var value=record(candidate)?candidate:{};var legacyUi=axis==='ui'&&!has(value,'family');var family=legacyUi?valid(p.font,'system'):valid(value.family,'system');var font=projection[family];if(family==='system')r.removeAttribute(spec.familyAttribute);else r.setAttribute(spec.familyAttribute,family);r.style.setProperty(spec.familyProperty,'var('+font.familyVariables[axis]+')');var px=size(value.size,spec.defaultSize);r.style.setProperty(spec.sizeProperty,px+'px');r.style.setProperty(spec.scaleProperty,String(px/spec.defaultSize));if(axis==='ui'){r.style.setProperty('--ui-tracking',font.uiTracking);r.style.setProperty('--ui-word-spacing',font.uiWordSpacing);}}r.removeAttribute('data-font');})();`\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"appearance-font-settings.js","names":[],"sources":["../../src/lib/appearance-font-settings.ts"],"sourcesContent":["import { fontOptions, type FontOption } from '#lib/font-catalog'\nimport { safeScriptStringLiteral } from '#lib/safe-script'\n\nexport const APPEARANCE_EDITOR_FONT_AXES = ['ui', 'content', 'code'] as const\n\nexport type AppearanceEditorFontAxis = (typeof APPEARANCE_EDITOR_FONT_AXES)[number]\nexport type AppearanceEditorFontFamilyId = FontOption['id']\n\nexport type AppearanceEditorFontSetting = Readonly<{\n /** A stable id from the shared font catalogue, never a CSS family string. */\n family: AppearanceEditorFontFamilyId\n /** A pixel size, normalized to the supported range. */\n size: number\n}>\n\n/** The host-owned choices edited by the shared appearance composition. */\nexport type AppearanceEditorFontSettings = Readonly<\n Record<AppearanceEditorFontAxis, AppearanceEditorFontSetting>\n>\n\nexport const APPEARANCE_EDITOR_FONT_SIZE_MIN = 10\nexport const APPEARANCE_EDITOR_FONT_SIZE_MAX = 32\n\n/** New preferences use the platform face in each text role. */\nexport const DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS: AppearanceEditorFontSettings = Object.freeze({\n ui: Object.freeze({ family: 'system', size: 14 }),\n content: Object.freeze({ family: 'system', size: 14 }),\n code: Object.freeze({ family: 'system', size: 12 }),\n})\n\nexport type NormalizedAppearanceEditorFontSettings = Readonly<{\n settings: AppearanceEditorFontSettings\n /** Axes whose persisted family or size was unavailable or outside its limits. */\n recoveredAxes: readonly AppearanceEditorFontAxis[]\n}>\n\nconst fontFamilyIds: ReadonlySet<string> = new Set(fontOptions.map((option) => option.id))\nconst fontOptionsById = Object.freeze(\n Object.fromEntries(fontOptions.map((option) => [option.id, option])) as Record<\n AppearanceEditorFontFamilyId,\n FontOption\n >\n)\nconst fontProjectionById = Object.freeze(\n Object.fromEntries(\n fontOptions.map((option) => [\n option.id,\n {\n familyVariables: option.familyVariables,\n uiTracking: option.uiTracking,\n uiWordSpacing: option.uiWordSpacing,\n },\n ])\n ) as Record<\n AppearanceEditorFontFamilyId,\n Pick<FontOption, 'familyVariables' | 'uiTracking' | 'uiWordSpacing'>\n >\n)\nconst fontAxisProjection = Object.freeze({\n ui: Object.freeze({\n familyAttribute: 'data-ui-font',\n familyProperty: '--font-ui',\n sizeProperty: '--font-ui-size',\n scaleProperty: '--font-ui-scale',\n defaultSize: DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS.ui.size,\n }),\n content: Object.freeze({\n familyAttribute: 'data-content-font',\n familyProperty: '--font-content',\n sizeProperty: '--font-content-size',\n scaleProperty: '--font-content-scale',\n defaultSize: DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS.content.size,\n }),\n code: Object.freeze({\n familyAttribute: 'data-code-font',\n familyProperty: '--font-code',\n sizeProperty: '--font-code-size',\n scaleProperty: '--font-code-scale',\n defaultSize: DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS.code.size,\n }),\n})\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction hasOwn(value: Record<string, unknown>, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(value, key)\n}\n\nfunction normalizeFamily(value: unknown): AppearanceEditorFontFamilyId | undefined {\n return typeof value === 'string' && fontFamilyIds.has(value)\n ? (value as AppearanceEditorFontFamilyId)\n : undefined\n}\n\nfunction clampFontSize(value: number): number {\n return Math.min(\n APPEARANCE_EDITOR_FONT_SIZE_MAX,\n Math.max(APPEARANCE_EDITOR_FONT_SIZE_MIN, Math.round(value))\n )\n}\n\n/** Normalize a single number-input value; invalid edits return the current size. */\nexport function normalizeAppearanceEditorFontSize(value: unknown, fallback: number): number {\n const parsed =\n typeof value === 'number'\n ? value\n : typeof value === 'string' && value.trim() !== ''\n ? Number(value)\n : Number.NaN\n return Number.isFinite(parsed) ? clampFontSize(parsed) : clampFontSize(fallback)\n}\n\n/**\n * Recover persisted font choices against the shared font catalogue.\n *\n * `legacyUiFamily` lets a host migrate its previous single font field into the\n * UI axis. Content and code remain on the new System defaults during that\n * migration. Missing settings are ordinary defaults; an unknown saved id or an\n * invalid size is reported through `recoveredAxes` for the host's notice.\n */\nexport function normalizeAppearanceEditorFontSettings(\n value: unknown,\n legacyUiFamily?: unknown\n): NormalizedAppearanceEditorFontSettings {\n const source = isRecord(value) ? value : undefined\n const malformedRoot = value !== undefined && value !== null && source === undefined\n const recovered = new Set<AppearanceEditorFontAxis>()\n const settings = {} as Record<AppearanceEditorFontAxis, AppearanceEditorFontSetting>\n\n for (const axis of APPEARANCE_EDITOR_FONT_AXES) {\n const axisPresent = source ? hasOwn(source, axis) : false\n const axisValue = source?.[axis]\n const axisSource = isRecord(axisValue) ? axisValue : undefined\n const fallback = DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS[axis]\n\n if (malformedRoot || (axisPresent && axisSource === undefined)) recovered.add(axis)\n\n const hasFamily = axisSource ? hasOwn(axisSource, 'family') : false\n const familyInput = hasFamily\n ? axisSource?.['family']\n : axis === 'ui' && legacyUiFamily !== undefined\n ? legacyUiFamily\n : undefined\n const family = normalizeFamily(familyInput) ?? fallback.family\n if (\n (hasFamily || (axis === 'ui' && legacyUiFamily !== undefined)) &&\n !normalizeFamily(familyInput)\n ) {\n recovered.add(axis)\n }\n\n const hasSize = axisSource ? hasOwn(axisSource, 'size') : false\n const sizeInput = axisSource?.['size']\n const size = hasSize\n ? normalizeAppearanceEditorFontSize(sizeInput, fallback.size)\n : fallback.size\n if (\n hasSize &&\n (typeof sizeInput !== 'number' || !Number.isFinite(sizeInput) || sizeInput !== size)\n ) {\n recovered.add(axis)\n }\n\n settings[axis] = Object.freeze({ family, size })\n }\n\n return Object.freeze({\n settings: Object.freeze(settings),\n recoveredAxes: Object.freeze(APPEARANCE_EDITOR_FONT_AXES.filter((axis) => recovered.has(axis))),\n })\n}\n\n/**\n * Project normalized font preferences onto a document root.\n *\n * This is shared by `ThemeProvider` and hosts that own their own appearance\n * persistence, so UI/content/code use the same catalogue ids, theme tokens,\n * sizes, and projected CSS variables. The marker activates the optional role\n * stylesheet and survives CSS import reordering.\n */\nexport function applyAppearanceFontSettings(\n root: Pick<HTMLElement, 'removeAttribute' | 'setAttribute' | 'style'>,\n value: unknown\n): NormalizedAppearanceEditorFontSettings {\n const normalized = normalizeAppearanceEditorFontSettings(value)\n const { settings } = normalized\n\n root.removeAttribute('data-font')\n root.setAttribute('data-font-settings', '')\n for (const axis of APPEARANCE_EDITOR_FONT_AXES) {\n const projection = fontAxisProjection[axis]\n const setting = settings[axis]\n const option = fontOptionsById[setting.family]\n if (setting.family === 'system') root.removeAttribute(projection.familyAttribute)\n else root.setAttribute(projection.familyAttribute, setting.family)\n root.style.setProperty(projection.familyProperty, `var(${option.familyVariables[axis]})`)\n root.style.setProperty(projection.sizeProperty, String(setting.size) + 'px')\n root.style.setProperty(projection.scaleProperty, String(setting.size / projection.defaultSize))\n if (axis === 'ui') {\n root.style.setProperty('--ui-tracking', option.uiTracking)\n root.style.setProperty('--ui-word-spacing', option.uiWordSpacing)\n }\n }\n\n return normalized\n}\n\n/**\n * Generate a safe inline prepaint script for a host-owned appearance record.\n *\n * The stored object is read from `localStorage[storageKey].fonts`. A legacy\n * top-level `font` family migrates into UI only; content/code use the shared\n * defaults. The script applies the same catalogue whitelist, limits, attributes,\n * and CSS properties as `applyAppearanceFontSettings` before styles paint. When\n * `persistedVersion` is supplied, only a record with that exact top-level version\n * is used; absent or mismatched records receive the System defaults.\n */\nexport function fontSettingsBootstrapScript(storageKey: string, persistedVersion?: number): string {\n if (persistedVersion !== undefined && !Number.isSafeInteger(persistedVersion)) {\n throw new RangeError('persistedVersion must be a safe integer')\n }\n const axisConfig = JSON.stringify(fontAxisProjection)\n const fontProjection = JSON.stringify(fontProjectionById)\n const fontIds = `[${fontOptions.map((option) => safeScriptStringLiteral(option.id)).join(',')}]`\n const persistedVersionGuard =\n persistedVersion === undefined\n ? ''\n : `&&parsed.version===Number(${safeScriptStringLiteral(String(persistedVersion))})`\n\n return `(function(){var r=document.documentElement;var axes=JSON.parse(${safeScriptStringLiteral(axisConfig)});var projection=JSON.parse(${safeScriptStringLiteral(fontProjection)});var ids=${fontIds};var has=function(v,k){return Object.prototype.hasOwnProperty.call(v,k)};var record=function(v){return typeof v==='object'&&v!==null&&!Array.isArray(v)};var p={};try{var raw=localStorage.getItem(${safeScriptStringLiteral(storageKey)});var parsed=raw?JSON.parse(raw):{};if(record(parsed)${persistedVersionGuard})p=parsed;}catch(e){}var saved=record(p.fonts)?p.fonts:{};var valid=function(v,d){return ids.indexOf(v)!==-1?v:d};var size=function(v,d){var n=typeof v==='number'?v:typeof v==='string'&&v.trim()!==''?Number(v):NaN;return Number.isFinite(n)?Math.min(${APPEARANCE_EDITOR_FONT_SIZE_MAX},Math.max(${APPEARANCE_EDITOR_FONT_SIZE_MIN},Math.round(n))):d};r.setAttribute('data-font-settings','');for(var axis in axes){if(!has(axes,axis))continue;var spec=axes[axis];var candidate=saved[axis];var value=record(candidate)?candidate:{};var legacyUi=axis==='ui'&&!has(value,'family');var family=legacyUi?valid(p.font,'system'):valid(value.family,'system');var font=projection[family];if(family==='system')r.removeAttribute(spec.familyAttribute);else r.setAttribute(spec.familyAttribute,family);r.style.setProperty(spec.familyProperty,'var('+font.familyVariables[axis]+')');var px=size(value.size,spec.defaultSize);r.style.setProperty(spec.sizeProperty,px+'px');r.style.setProperty(spec.scaleProperty,String(px/spec.defaultSize));if(axis==='ui'){r.style.setProperty('--ui-tracking',font.uiTracking);r.style.setProperty('--ui-word-spacing',font.uiWordSpacing);}}r.removeAttribute('data-font');})();`\n}\n"],"mappings":"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"}
@@ -147,7 +147,26 @@ export type ThemeVariant = {
147
147
  /** The categorical series, in order. */
148
148
  chart: readonly string[];
149
149
  provenance: ThemeProvenance;
150
+ /**
151
+ * Custom properties written verbatim over {@link themeCssVariables}, last.
152
+ *
153
+ * For a variant a host built from data it does not control the derivation of —
154
+ * an imported theme whose painted colours must stay exactly what the user
155
+ * imported. The catalogue's own variants never carry it, so the derived roles
156
+ * stay the only source of truth for them.
157
+ */
158
+ tokens?: Readonly<Record<string, string>>;
150
159
  };
160
+ /**
161
+ * The design system's view of one catalogue record, built in full and at once.
162
+ *
163
+ * For a host that holds a record the catalogue does not — an imported theme, a
164
+ * reconstruction from stored data — and wants a variant it can hand to
165
+ * `ThemeProvider`'s `themes`. It throws for a record the shadcn projection cannot
166
+ * map, here and now, rather than on first paint. The catalogue itself goes through
167
+ * {@link lazyVariant} instead.
168
+ */
169
+ export declare function variantFromRecord(theme: AdeaThemeRecord): ThemeVariant;
151
170
  /**
152
171
  * A variant's `--primary-subtle`: the tint over `var(--primary)` at the strength its
153
172
  * catalogue record measures (`primarySubtleAlpha`). A variant that is not in the
@@ -157,6 +176,24 @@ export declare function primarySubtleFor(theme: Pick<ThemeVariant, 'id' | 'appea
157
176
  /** The catalogue, in catalogue order. */
158
177
  export declare const builtinThemes: readonly ThemeVariant[];
159
178
  export declare function themeById(id: string): ThemeVariant | undefined;
179
+ /**
180
+ * The variant a stored id means, or the default of the same appearance.
181
+ *
182
+ * An id the registry does not hold — an imported theme that was deleted, a
183
+ * catalogue entry that was renamed — must still paint *something of the appearance
184
+ * being shown*. Falling back to whichever variant happens to be first in the
185
+ * registry painted a dark palette under a light `color-scheme` for a light id, so
186
+ * the fallback is the appearance's own default, then any variant of that
187
+ * appearance, then the registry's first entry only when it holds nothing else.
188
+ *
189
+ * `registry` is the builtin catalogue plus whatever extras the host supplies; the
190
+ * stored id is never rewritten, only resolved, so a host that keeps an unknown id
191
+ * keeps resolving it if the theme comes back.
192
+ *
193
+ * The fallback order is translated from Zeron's `ThemeRegistry::resolve` (MIT,
194
+ * Copyright (c) 2026 Wing); see NOTICE.
195
+ */
196
+ export declare function resolveVariant(registry: readonly ThemeVariant[], id: string, appearance: ThemeAppearance): ThemeVariant;
160
197
  /** The variants of one appearance, which is what a picker for that mode shows. */
161
198
  export declare function themesForAppearance(appearance: ThemeAppearance): readonly ThemeVariant[];
162
199
  /** The families in the catalogue, in catalogue order. */
@@ -262,6 +299,17 @@ export declare function accentVariables(accentId: string, appearance: ThemeAppea
262
299
  * than separate roles, which is why they are built here and not in the catalogue.
263
300
  */
264
301
  export declare function themeCssVariables(theme: ThemeVariant): Record<string, string>;
302
+ /**
303
+ * Token values with every `oklch()` colour written as `#rrggbb`.
304
+ *
305
+ * For a host whose stylesheet, tests or native shell speak hex: the catalogue's
306
+ * roles are `oklch()` strings, and this is the one conversion, gamut-mapped by the
307
+ * catalogue's own `oklchToHex`. A value that is already hex, carries alpha
308
+ * (`rgba()`), or is not a plain colour (`color-mix()`, `var()`) is left byte for
309
+ * byte, because converting would either lose the alpha or be a guess. Suitable as
310
+ * `ThemeProvider`'s `transformTokens`.
311
+ */
312
+ export declare function tokensAsHex(tokens: Readonly<Record<string, string>>): Record<string, string>;
265
313
  export type ThemeFinding = {
266
314
  themeId: string;
267
315
  role: string;
@@ -1 +1 @@
1
- {"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../src/lib/themes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAkBL,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,eAAe,EAErB,MAAM,iBAAiB,CAAA;AAIxB,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,MAAM,CAAA;AAE9C;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,cAAc,EAAE,MAAM,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,iBAAiB,EAAE,MAAM,CAAA;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,iBAAiB,EAAE,MAAM,CAAA;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,EAAE,MAAM,CAAA;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB,EAAE,MAAM,CAAA;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,iBAAiB,EAAE,MAAM,CAAA;IACzB,sFAAsF;IACtF,iBAAiB,EAAE,MAAM,CAAA;IACzB,2BAA2B,EAAE,MAAM,CAAA;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,iBAAiB,EAAE,MAAM,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,iBAAiB,EAAE,MAAM,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,iBAAiB,EAAE,MAAM,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,sBAAsB,EAAE,MAAM,CAAA;CAC/B,CAAA;AAED,gFAAgF;AAChF,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,0CAA0C;AAC1C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,iEAAiE;AACjE,MAAM,MAAM,eAAe,GAAG;IAC5B,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAA;IACV,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,eAAe,CAAA;IAC3B,mCAAmC;IACnC,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,WAAW,CAAA;IACnB,QAAQ,EAAE,oBAAoB,CAAA;IAC9B,MAAM,EAAE,kBAAkB,CAAA;IAC1B,wCAAwC;IACxC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,UAAU,EAAE,eAAe,CAAA;CAC5B,CAAA;AAoGD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,YAAY,CAAC,GAAG,MAAM,CAGvF;AAED,yCAAyC;AACzC,eAAO,MAAM,aAAa,EAAE,SAAS,YAAY,EAA4C,CAAA;AAE7F,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAG9D;AAED,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,eAAe,GAAG,SAAS,YAAY,EAAE,CAGxF;AAED,yDAAyD;AACzD,wBAAgB,aAAa,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,EAAE,CAAA;CAAE,EAAE,CAY3F;AAED,kEAAkE;AAClE,eAAO,MAAM,OAAO,yBAAU,CAAA;AAE9B;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,eAAe,EAAc,CAAA;AAEjE,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAEvE;AASD;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,SAAS,YAAY,EAAE,CAGzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE,SAAS,GACd,YAAY,GAAG,SAAS,CAM1B;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,CAAC,CAO7F;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE;IACjD,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACf,GAAG;IAAE,UAAU,EAAE,eAAe,CAAC;IAAC,SAAS,EAAE,eAAe,CAAA;CAAE,CAI9D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,eAAe,EAC3B,IAAI,GAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAGhD,GACA,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAmBpC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA6G7E;AAUD,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAMD,+FAA+F;AAC/F,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,EAAE,CAMjE;AAED,8EAA8E;AAC9E,wBAAgB,qBAAqB,CACnC,MAAM,GAAE,SAAS,YAAY,EAAkB,GAC9C,YAAY,EAAE,CAchB;AAED,eAAO,MAAM,mBAAmB,eAAe,CAAA;AAC/C,eAAO,MAAM,kBAAkB,cAAc,CAAA;AAE7C,kFAAkF;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../src/lib/themes.ts"],"names":[],"mappings":"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"}