@adea-ai/ui 0.102.0 → 0.103.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 (56) hide show
  1. package/README.md +27 -11
  2. package/dist/components/composites/appearance-editor/appearance-choices.d.ts +7 -0
  3. package/dist/components/composites/appearance-editor/appearance-choices.d.ts.map +1 -1
  4. package/dist/components/composites/appearance-editor/appearance-choices.js +44 -3
  5. package/dist/components/composites/appearance-editor/appearance-choices.js.map +1 -1
  6. package/dist/components/composites/appearance-editor/appearance-editor.d.ts.map +1 -1
  7. package/dist/components/composites/appearance-editor/appearance-editor.js +7 -3
  8. package/dist/components/composites/appearance-editor/appearance-editor.js.map +1 -1
  9. package/dist/components/composites/appearance-editor/appearance-types.d.ts +8 -0
  10. package/dist/components/composites/appearance-editor/appearance-types.d.ts.map +1 -1
  11. package/dist/components/composites/update-dialog/update-dialog.d.ts +15 -2
  12. package/dist/components/composites/update-dialog/update-dialog.d.ts.map +1 -1
  13. package/dist/components/composites/update-dialog/update-dialog.js +80 -16
  14. package/dist/components/composites/update-dialog/update-dialog.js.map +1 -1
  15. package/dist/components/theme/appearance-panel.d.ts +2 -1
  16. package/dist/components/theme/appearance-panel.d.ts.map +1 -1
  17. package/dist/components/theme/appearance-panel.js +62 -22
  18. package/dist/components/theme/appearance-panel.js.map +1 -1
  19. package/dist/components/theme/theme-provider.d.ts +13 -2
  20. package/dist/components/theme/theme-provider.d.ts.map +1 -1
  21. package/dist/components/theme/theme-provider.js +7 -4
  22. package/dist/components/theme/theme-provider.js.map +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +3 -2
  26. package/dist/lib/theme-accents.d.ts +9 -0
  27. package/dist/lib/theme-accents.d.ts.map +1 -0
  28. package/dist/lib/theme-accents.js +41 -0
  29. package/dist/lib/theme-accents.js.map +1 -0
  30. package/dist/lib/themes.d.ts +69 -5
  31. package/dist/lib/themes.d.ts.map +1 -1
  32. package/dist/lib/themes.js +100 -7
  33. package/dist/lib/themes.js.map +1 -1
  34. package/dist/r/appearance-editor.json +1 -1
  35. package/dist/r/lib.json +6 -1
  36. package/dist/r/registry.json +8 -2
  37. package/dist/r/src/components/composites/appearance-editor/appearance-choices.tsx +41 -4
  38. package/dist/r/src/components/composites/appearance-editor/appearance-editor.tsx +12 -6
  39. package/dist/r/src/components/composites/appearance-editor/appearance-types.ts +8 -0
  40. package/dist/r/src/components/composites/update-dialog/update-dialog.tsx +90 -10
  41. package/dist/r/src/components/theme/appearance-panel.tsx +60 -29
  42. package/dist/r/src/components/theme/theme-provider.tsx +31 -7
  43. package/dist/r/src/lib/theme-accents.ts +44 -0
  44. package/dist/r/src/lib/themes.ts +116 -5
  45. package/dist/r/theming.json +1 -0
  46. package/package.json +2 -2
  47. package/registry.json +8 -2
  48. package/src/components/composites/appearance-editor/appearance-choices.tsx +41 -4
  49. package/src/components/composites/appearance-editor/appearance-editor.tsx +12 -6
  50. package/src/components/composites/appearance-editor/appearance-types.ts +8 -0
  51. package/src/components/composites/update-dialog/update-dialog.tsx +90 -10
  52. package/src/components/theme/appearance-panel.tsx +60 -29
  53. package/src/components/theme/theme-provider.tsx +31 -7
  54. package/src/index.ts +7 -0
  55. package/src/lib/theme-accents.ts +44 -0
  56. package/src/lib/themes.ts +116 -5
@@ -1 +1 @@
1
- {"version":3,"file":"appearance-panel.js","names":["ComponentProps","For","Show","splitProps","accentPresets","fontOptions","themesForAppearance","cn","Button","RadioGroup","RadioGroupItem","ThemePicker","useTheme","Heading","AppearancePanelProps","LIGHT_THEMES","DARK_THEMES","AppearancePanel","props","local","rest","selection","setSelection","resolvedAppearance","_el$","_tmpl$","_el$2","firstChild","_el$3","_el$4","_el$5","nextSibling","_el$6","_el$7","_el$8","_el$9","_el$0","_el$1","_$spread","_$mergeProps","class","_$insert","_$createComponent","as","size","children","value","appearance","onChange","label","description","when","ThemeSection","title","themes","selectedId","lightThemeId","onThemeSelect","theme","id","darkThemeId","each","preset","type","variant","role","aria-checked","accent","aria-label","onClick","_el$10","_tmpl$2","_$effect","_$p","_$setStyleProperty","dark","_$memo","font","option","ReturnType","_el$11","_tmpl$3","_el$12","_el$13","_$mergeProps","_$createComponent","_$setStyleProperty","_$memo"],"sources":["../../../src/components/theme/appearance-panel.tsx"],"sourcesContent":["import type { ComponentProps } from 'solid-js'\nimport { For, Show, splitProps } from 'solid-js'\nimport { accentPresets, fontOptions } from '#lib/tokens'\nimport { themesForAppearance } from '#lib/themes'\nimport { cn } from '#lib/utils'\nimport { Button } from '../ui/button/button'\nimport { RadioGroup, RadioGroupItem } from '../ui/radio-group/radio-group'\nimport { ThemePicker } from './theme-picker'\nimport { useTheme } from './theme-provider'\nimport { Heading } from '../ui/typography'\n\n/**\n * AppearancePanel.\n *\n * The appearance page, as a component rather than as a screen each application\n * draws for itself. Two applications that both let a user choose a theme should\n * offer the *same* choices in the *same* arrangement — otherwise \"Adea\" and\n * \"Cortana\" are two products that happen to share a component library, which is\n * the opposite of what this system is for.\n *\n * Four axes, in the order a user thinks about them:\n *\n * 1. **Appearance** — light, dark, or follow the system.\n * 2. **Themes** — one for each appearance. Both are shown at once, because the\n * choice is per-appearance and hiding the other half makes it feel like one\n * setting that keeps changing.\n * 3. **Accent** — adea's presets, layered on whichever theme is active.\n * 4. **Font** — the interface face.\n *\n * The panel reads and writes the provider's preference and keeps no state of its\n * own, so it cannot disagree with what is applied.\n */\nexport type AppearancePanelProps = ComponentProps<'div'>\n\nconst LIGHT_THEMES = themesForAppearance('light')\nconst DARK_THEMES = themesForAppearance('dark')\n\nexport function AppearancePanel(props: AppearancePanelProps) {\n const [local, rest] = splitProps(props, ['class'])\n const { selection, setSelection, resolvedAppearance } = useTheme()\n\n return (\n <div data-slot=\"appearance-panel\" class={cn('flex flex-col gap-8', local.class)} {...rest}>\n {/* --- 1. Appearance ------------------------------------------------- */}\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <Heading as=\"h2\" size=\"card\">\n Appearance\n </Heading>\n <p class=\"max-w-prose text-sm text-muted-foreground\">\n Follow the system, or pin one. The theme below is chosen per appearance, so switching at\n sunset does not make you choose again.\n </p>\n </header>\n <RadioGroup\n value={selection().appearance}\n onChange={(value) => setSelection({ appearance: value as 'light' | 'dark' | 'system' })}\n aria-label=\"Appearance\"\n >\n <RadioGroupItem value=\"light\" label=\"Light\" description=\"Always the light theme.\" />\n <RadioGroupItem value=\"dark\" label=\"Dark\" description=\"Always the dark theme.\" />\n <RadioGroupItem\n value=\"system\"\n label=\"Match the system\"\n description={`Currently resolving to ${resolvedAppearance()}.`}\n />\n </RadioGroup>\n </section>\n\n {/* --- 2. Themes ------------------------------------------------------ */}\n <Show when={resolvedAppearance() === 'light'}>\n <ThemeSection\n title=\"Light theme\"\n description=\"Shown when the appearance resolves to light.\"\n themes={LIGHT_THEMES}\n selectedId={selection().lightThemeId}\n onThemeSelect={(theme) => setSelection({ lightThemeId: theme.id })}\n />\n </Show>\n <Show when={resolvedAppearance() === 'dark'}>\n <ThemeSection\n title=\"Dark theme\"\n description=\"Shown when the appearance resolves to dark.\"\n themes={DARK_THEMES}\n selectedId={selection().darkThemeId}\n onThemeSelect={(theme) => setSelection({ darkThemeId: theme.id })}\n />\n </Show>\n\n {/* --- 3. Accent ------------------------------------------------------ */}\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <Heading as=\"h2\" size=\"card\">\n Accent\n </Heading>\n <p class=\"max-w-prose text-sm text-muted-foreground\">\n Colours the interactive roles — the primary button, the focus ring, a selected row — on\n top of the theme above. Every preset is measured against the surface it lands on, so\n none of them can make a label unreadable.\n </p>\n </header>\n <div role=\"radiogroup\" aria-label=\"Accent\" class=\"flex flex-wrap gap-2\">\n <For each={accentPresets}>\n {(preset) => (\n <Button\n as=\"button\"\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n role=\"radio\"\n aria-checked={selection().accent === preset.id}\n aria-label={preset.label}\n class={cn({\n 'border-ring ring-3 ring-primary-subtle': selection().accent === preset.id,\n })}\n onClick={() => setSelection({ accent: preset.id })}\n >\n <span\n aria-hidden=\"true\"\n class=\"size-3 rounded-full border border-border\"\n style={{\n 'background-color':\n preset.id === 'theme'\n ? 'var(--primary)'\n : `var(--accent-${preset.id}, ${preset.dark})`,\n }}\n />\n {preset.label}\n </Button>\n )}\n </For>\n </div>\n </section>\n\n {/* --- 4. Font -------------------------------------------------------- */}\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <Heading as=\"h2\" size=\"card\">\n Typeface\n </Heading>\n <p class=\"max-w-prose text-sm text-muted-foreground\">\n The interface face. Every option is self-hosted, so nothing is fetched at runtime and\n the choice survives going offline.\n </p>\n </header>\n <RadioGroup\n value={selection().font}\n onChange={(value) => setSelection({ font: value as string })}\n aria-label=\"Typeface\"\n >\n <For each={fontOptions}>\n {(option) => (\n <RadioGroupItem\n value={option.id}\n label={option.label}\n description={option.description}\n />\n )}\n </For>\n </RadioGroup>\n </section>\n </div>\n )\n}\n\nfunction ThemeSection(props: {\n title: string\n description: string\n themes: ReturnType<typeof themesForAppearance>\n selectedId: string\n onThemeSelect: (theme: ReturnType<typeof themesForAppearance>[number]) => void\n}) {\n return (\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <Heading as=\"h2\" size=\"card\">\n {props.title}\n </Heading>\n <p class=\"max-w-prose text-sm text-muted-foreground\">{props.description}</p>\n </header>\n <ThemePicker\n themes={props.themes}\n selectedId={props.selectedId}\n onThemeSelect={props.onThemeSelect}\n />\n </section>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"appearance-panel.js","names":["ComponentProps","For","Show","splitProps","accentPresets","fontOptions","themesForAppearance","cn","Button","RadioGroup","RadioGroupItem","ThemePicker","useTheme","Heading","AppearancePanelProps","LIGHT_THEMES","DARK_THEMES","AppearancePanel","props","local","rest","selection","setSelection","resolvedAppearance","themeAccents","_el$","_tmpl$","_el$2","firstChild","_el$3","_el$4","_el$5","nextSibling","_el$6","_el$7","_el$8","_el$9","_el$0","_el$1","_$spread","_$mergeProps","class","_$insert","_$createComponent","as","size","children","value","appearance","onChange","label","description","when","ThemeSection","title","themes","selectedId","lightThemeId","onThemeSelect","theme","id","darkThemeId","each","preset","AccentOption","checked","accent","swatch","_$memo","dark","onSelect","toLowerCase","light","font","option","type","variant","role","data-accent-option","aria-checked","aria-label","onClick","_el$10","_tmpl$2","_$effect","_$p","_$setStyleProperty","ReturnType","_el$11","_tmpl$3","_el$12","_el$13","_$mergeProps","_$createComponent","_$memo","_$setStyleProperty"],"sources":["../../../src/components/theme/appearance-panel.tsx"],"sourcesContent":["import type { ComponentProps } from 'solid-js'\nimport { For, Show, splitProps } from 'solid-js'\nimport { accentPresets, fontOptions } from '#lib/tokens'\nimport { themesForAppearance } from '#lib/themes'\nimport { cn } from '#lib/utils'\nimport { Button } from '../ui/button/button'\nimport { RadioGroup, RadioGroupItem } from '../ui/radio-group/radio-group'\nimport { ThemePicker } from './theme-picker'\nimport { useTheme } from './theme-provider'\nimport { Heading } from '../ui/typography'\n\n/**\n * AppearancePanel.\n *\n * The appearance page, as a component rather than as a screen each application\n * draws for itself. Two applications that both let a user choose a theme should\n * offer the *same* choices in the *same* arrangement — otherwise \"Adea\" and\n * \"Cortana\" are two products that happen to share a component library, which is\n * the opposite of what this system is for.\n *\n * Four axes, in the order a user thinks about them:\n *\n * 1. **Appearance** — light, dark, or follow the system.\n * 2. **Themes** — one for each appearance. Both are shown at once, because the\n * choice is per-appearance and hiding the other half makes it feel like one\n * setting that keeps changing.\n * 3. **Accent** — adea's presets, then the accents the selected theme pair\n * carries itself, layered on whichever theme is active.\n * 4. **Font** — the interface face.\n *\n * The panel reads and writes the provider's preference and keeps no state of its\n * own, so it cannot disagree with what is applied.\n */\nexport type AppearancePanelProps = ComponentProps<'div'>\n\nconst LIGHT_THEMES = themesForAppearance('light')\nconst DARK_THEMES = themesForAppearance('dark')\n\nexport function AppearancePanel(props: AppearancePanelProps) {\n const [local, rest] = splitProps(props, ['class'])\n const { selection, setSelection, resolvedAppearance, themeAccents } = useTheme()\n\n return (\n <div data-slot=\"appearance-panel\" class={cn('flex flex-col gap-8', local.class)} {...rest}>\n {/* --- 1. Appearance ------------------------------------------------- */}\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <Heading as=\"h2\" size=\"card\">\n Appearance\n </Heading>\n <p class=\"max-w-prose text-sm text-muted-foreground\">\n Follow the system, or pin one. The theme below is chosen per appearance, so switching at\n sunset does not make you choose again.\n </p>\n </header>\n <RadioGroup\n value={selection().appearance}\n onChange={(value) => setSelection({ appearance: value as 'light' | 'dark' | 'system' })}\n aria-label=\"Appearance\"\n >\n <RadioGroupItem value=\"light\" label=\"Light\" description=\"Always the light theme.\" />\n <RadioGroupItem value=\"dark\" label=\"Dark\" description=\"Always the dark theme.\" />\n <RadioGroupItem\n value=\"system\"\n label=\"Match the system\"\n description={`Currently resolving to ${resolvedAppearance()}.`}\n />\n </RadioGroup>\n </section>\n\n {/* --- 2. Themes ------------------------------------------------------ */}\n <Show when={resolvedAppearance() === 'light'}>\n <ThemeSection\n title=\"Light theme\"\n description=\"Shown when the appearance resolves to light.\"\n themes={LIGHT_THEMES}\n selectedId={selection().lightThemeId}\n onThemeSelect={(theme) => setSelection({ lightThemeId: theme.id })}\n />\n </Show>\n <Show when={resolvedAppearance() === 'dark'}>\n <ThemeSection\n title=\"Dark theme\"\n description=\"Shown when the appearance resolves to dark.\"\n themes={DARK_THEMES}\n selectedId={selection().darkThemeId}\n onThemeSelect={(theme) => setSelection({ darkThemeId: theme.id })}\n />\n </Show>\n\n {/* --- 3. Accent ------------------------------------------------------ */}\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <Heading as=\"h2\" size=\"card\">\n Accent\n </Heading>\n <p class=\"max-w-prose text-sm text-muted-foreground\">\n Colours the interactive roles — the primary button, the focus ring, a selected row — on\n top of the theme above — one of the presets, or a colour the theme carries itself. Every\n option is measured against the surface it lands on, so none of them can make a label\n unreadable.\n </p>\n </header>\n <div role=\"radiogroup\" aria-label=\"Accent\" class=\"flex flex-wrap gap-2\">\n <For each={accentPresets}>\n {(preset) => (\n <AccentOption\n id={preset.id}\n label={preset.label}\n checked={selection().accent === preset.id}\n swatch={\n preset.id === 'theme'\n ? 'var(--primary)'\n : `var(--accent-${preset.id}, ${preset.dark})`\n }\n onSelect={() => setSelection({ accent: preset.id })}\n />\n )}\n </For>\n {/* The theme's own accents follow the presets. Their values are the\n theme pair's, so the swatch shows the side that is active now. */}\n <For each={themeAccents()}>\n {(accent) => (\n <AccentOption\n id={accent.id}\n label={`Theme ${accent.label.toLowerCase()}`}\n checked={selection().accent === accent.id}\n swatch={resolvedAppearance() === 'dark' ? accent.dark : accent.light}\n onSelect={() => setSelection({ accent: accent.id })}\n />\n )}\n </For>\n </div>\n </section>\n\n {/* --- 4. Font -------------------------------------------------------- */}\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <Heading as=\"h2\" size=\"card\">\n Typeface\n </Heading>\n <p class=\"max-w-prose text-sm text-muted-foreground\">\n The interface face. Every option is self-hosted, so nothing is fetched at runtime and\n the choice survives going offline.\n </p>\n </header>\n <RadioGroup\n value={selection().font}\n onChange={(value) => setSelection({ font: value as string })}\n aria-label=\"Typeface\"\n >\n <For each={fontOptions}>\n {(option) => (\n <RadioGroupItem\n value={option.id}\n label={option.label}\n description={option.description}\n />\n )}\n </For>\n </RadioGroup>\n </section>\n </div>\n )\n}\n\nfunction AccentOption(props: {\n id: string\n label: string\n checked: boolean\n swatch: string\n onSelect: () => void\n}) {\n return (\n <Button\n as=\"button\"\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n role=\"radio\"\n data-accent-option={props.id}\n aria-checked={props.checked}\n aria-label={props.label}\n class={cn({ 'border-ring ring-3 ring-primary-subtle': props.checked })}\n onClick={() => props.onSelect()}\n >\n <span\n aria-hidden=\"true\"\n class=\"size-3 rounded-full border border-border\"\n style={{ 'background-color': props.swatch }}\n />\n {props.label}\n </Button>\n )\n}\n\nfunction ThemeSection(props: {\n title: string\n description: string\n themes: ReturnType<typeof themesForAppearance>\n selectedId: string\n onThemeSelect: (theme: ReturnType<typeof themesForAppearance>[number]) => void\n}) {\n return (\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <Heading as=\"h2\" size=\"card\">\n {props.title}\n </Heading>\n <p class=\"max-w-prose text-sm text-muted-foreground\">{props.description}</p>\n </header>\n <ThemePicker\n themes={props.themes}\n selectedId={props.selectedId}\n onThemeSelect={props.onThemeSelect}\n />\n </section>\n )\n}\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { JSX } from 'solid-js';
2
+ import type { AccentPreset } from '@adea-ai/themes';
2
3
  import { type ThemeAppearance, type ThemeVariant } from '#lib/themes';
3
4
  /**
4
5
  * ThemeProvider.
@@ -13,7 +14,8 @@ import { type ThemeAppearance, type ThemeVariant } from '#lib/themes';
13
14
  * - **appearance** — light, dark, or follow the system.
14
15
  * - **a theme per appearance** — so a user can run Catppuccin Mocha by night and
15
16
  * Solarized Light by day without re-choosing when the system flips.
16
- * - **an accent** — adea's six presets, which re-colour the interactive roles on
17
+ * - **an accent** — adea's six presets, or one of the accents the selected theme
18
+ * pair carries itself (`ansi-blue`…), which re-colour the interactive roles on
17
19
  * top of whichever theme is active.
18
20
  * - **a font** — the interface face.
19
21
  *
@@ -37,7 +39,11 @@ export type ThemeSelection = {
37
39
  lightThemeId: string;
38
40
  /** The variant to use when the resolved appearance is dark. */
39
41
  darkThemeId: string;
40
- /** An `accentPresets` id, or `theme` for the variant's own primary. */
42
+ /**
43
+ * An `accentPresets` id, a theme accent id from `themeAccents()` (`ansi-blue`…),
44
+ * or `theme` for the variant's own primary. A theme accent the current pair does
45
+ * not offer falls back to the variant's own primary.
46
+ */
41
47
  accent: string;
42
48
  /** A `fontOptions` id, or `space-grotesk` for the default. */
43
49
  font: string;
@@ -78,6 +84,11 @@ export type ThemeContextValue = {
78
84
  setSelection: (patch: Partial<ThemeSelection>) => void;
79
85
  /** The catalogue, so a picker does not import it separately. */
80
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[];
81
92
  };
82
93
  export declare function useTheme(): ThemeContextValue;
83
94
  export type ThemeProviderProps = {
@@ -1 +1 @@
1
- {"version":3,"file":"theme-provider.d.ts","sourceRoot":"","sources":["../../../src/components/theme/theme-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAWnC,OAAO,EAOL,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,MAAM,aAAa,CAAA;AAEpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;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,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAA;IACd,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,YAAY,CAAA;CACvB,CAAA;AAED,eAAO,MAAM,qBAAqB,EAAE,cAOnC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,SAAS,CAAA;AAEpD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,cAAc,GAAG,YAAY,CAEvE;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,gCAAgC;IAChC,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,gEAAgE;IAChE,MAAM,EAAE,SAAS,YAAY,EAAE,CAAA;CAChC,CAAA;AAID,wBAAgB,QAAQ,IAAI,iBAAiB,CAI5C;AAkDD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACtB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wDAAwD;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IACjC;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;CACpC,CAAA;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,eAoGtD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,UAAU,SAAoB,GAAG,MAAM,CAElE"}
1
+ {"version":3,"file":"theme-provider.d.ts","sourceRoot":"","sources":["../../../src/components/theme/theme-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAWnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EASL,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,MAAM,aAAa,CAAA;AAEpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;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,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,YAAY,CAAA;CACvB,CAAA;AAED,eAAO,MAAM,qBAAqB,EAAE,cAOnC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,SAAS,CAAA;AAEpD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,cAAc,GAAG,YAAY,CAEvE;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,gCAAgC;IAChC,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,gEAAgE;IAChE,MAAM,EAAE,SAAS,YAAY,EAAE,CAAA;IAC/B;;;OAGG;IACH,YAAY,EAAE,MAAM,SAAS,YAAY,EAAE,CAAA;CAC5C,CAAA;AAID,wBAAgB,QAAQ,IAAI,iBAAiB,CAI5C;AAwDD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACtB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wDAAwD;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IACjC;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;CACpC,CAAA;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,eAyGtD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,UAAU,SAAoB,GAAG,MAAM,CAElE"}
@@ -1,5 +1,6 @@
1
1
  import { accentPresets, fontOptions } from "../../lib/tokens.js";
2
- import { accentVariables, builtinThemes, defaultDarkThemeId, defaultLightThemeId, themeById, themeCssVariables } from "../../lib/themes.js";
2
+ import { isThemeAccentId } from "../../lib/theme-accents.js";
3
+ import { accentVariables, builtinThemes, defaultDarkThemeId, defaultLightThemeId, themeAccentsFor, themeById, themeCssVariables } from "../../lib/themes.js";
3
4
  import { createComponent } from "solid-js/web";
4
5
  import { createContext, createEffect, createMemo, createSignal, onCleanup, splitProps, useContext } from "solid-js";
5
6
  //#region src/components/theme/theme-provider.tsx
@@ -49,7 +50,7 @@ function readSelection(storageKey) {
49
50
  appearance: parsed.appearance === "light" || parsed.appearance === "dark" || parsed.appearance === "system" ? parsed.appearance : defaultThemeSelection.appearance,
50
51
  lightThemeId: themeById(parsed.lightThemeId ?? "")?.appearance === "light" ? parsed.lightThemeId : defaultLightThemeId,
51
52
  darkThemeId: themeById(parsed.darkThemeId ?? "")?.appearance === "dark" ? parsed.darkThemeId : defaultDarkThemeId,
52
- accent: accentPresets.some((preset) => preset.id === parsed.accent) ? parsed.accent : defaultThemeSelection.accent,
53
+ accent: typeof parsed.accent === "string" && (accentPresets.some((preset) => preset.id === parsed.accent) || isThemeAccentId(parsed.accent)) ? parsed.accent : defaultThemeSelection.accent,
53
54
  font: fontOptions.some((option) => option.id === parsed.font) ? parsed.font : defaultThemeSelection.font
54
55
  };
55
56
  } catch {
@@ -97,25 +98,27 @@ function ThemeProvider(props) {
97
98
  const root = document.documentElement;
98
99
  const active = variant();
99
100
  const properties = { ...themeCssVariables(active) };
100
- const accent = accentVariables(selection().accent, resolvedAppearance());
101
+ const accent = accentVariables(selection().accent, resolvedAppearance(), selection());
101
102
  if (accent) Object.assign(properties, accent);
102
103
  for (const [name, value] of Object.entries(properties)) root.style.setProperty(name, value);
103
104
  root.classList.toggle("dark", resolvedAppearance() === "dark");
104
105
  root.dataset["theme"] = active.id;
105
106
  root.dataset["appearance"] = resolvedAppearance();
106
107
  root.style.colorScheme = resolvedAppearance();
107
- if (selection().accent === "theme") root.removeAttribute("data-accent");
108
+ if (!accent) root.removeAttribute("data-accent");
108
109
  else root.dataset["accent"] = selection().accent;
109
110
  if (selection().font === "space-grotesk") root.removeAttribute("data-font");
110
111
  else root.dataset["font"] = selection().font;
111
112
  if (resolvedDensity(selection()) === "comfortable") root.removeAttribute("data-density");
112
113
  else root.dataset["density"] = resolvedDensity(selection());
113
114
  });
115
+ const themeAccents = createMemo(() => themeAccentsFor(selection().lightThemeId, selection().darkThemeId));
114
116
  const value = {
115
117
  selection,
116
118
  resolvedAppearance,
117
119
  variant,
118
120
  themes: builtinThemes,
121
+ themeAccents,
119
122
  setSelection(patch) {
120
123
  const next = {
121
124
  ...selection(),
@@ -1 +1 @@
1
- {"version":3,"file":"theme-provider.js","names":["JSX","createContext","createEffect","createMemo","createSignal","onCleanup","splitProps","useContext","accentPresets","fontOptions","accentVariables","builtinThemes","defaultDarkThemeId","defaultLightThemeId","themeById","themeCssVariables","ThemeAppearance","ThemeVariant","ThemeSelection","appearance","lightThemeId","darkThemeId","accent","font","density","ThemeDensity","defaultThemeSelection","resolvedDensity","selection","ThemeContextValue","resolvedAppearance","variant","setSelection","patch","Partial","themes","ThemeContext","useTheme","value","Error","preferenceStore","Storage","localStorage","undefined","readSelection","storageKey","raw","getItem","parsed","JSON","parse","some","preset","id","option","ThemeProviderProps","children","Element","initial","ThemeProvider","props","local","setSelectionState","incoming","current","systemAppearance","setSystemAppearance","window","matchMedia","query","matches","onChange","event","MediaQueryListEvent","addEventListener","removeEventListener","preference","document","root","documentElement","active","properties","Object","assign","name","entries","style","setProperty","classList","toggle","dataset","colorScheme","removeAttribute","next","setItem","stringify","_$createComponent","Provider","inlineScriptLiteral","replace","character","charCodeAt","toString","padStart","themeScript","_$createComponent"],"sources":["../../../src/components/theme/theme-provider.tsx"],"sourcesContent":["import type { JSX } from 'solid-js'\nimport {\n createContext,\n createEffect,\n createMemo,\n createSignal,\n onCleanup,\n splitProps,\n useContext,\n} from 'solid-js'\nimport { accentPresets, fontOptions } from '#lib/tokens'\nimport {\n accentVariables,\n builtinThemes,\n defaultDarkThemeId,\n defaultLightThemeId,\n themeById,\n themeCssVariables,\n type ThemeAppearance,\n type ThemeVariant,\n} from '#lib/themes'\n\n/**\n * ThemeProvider.\n *\n * Owns the appearance preference and applies it to the document. One provider near\n * the root; everything below reads it.\n *\n * ## What a preference is\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, which re-colour the interactive roles on\n * top of whichever theme is active.\n * - **a font** — the interface face.\n *\n * Four axes rather than one list of presets, because they compose: a user who wants\n * Nord with a violet accent and the system font should not need someone to author\n * that combination.\n *\n * ## Why the variants are applied as inline properties\n *\n * The catalogue is data, and a theme is applied by writing its roles onto\n * `<html>` as custom properties. That is what makes an imported palette work\n * without a hand-written `[data-theme]` block per theme, and it is why a settings\n * UI can show a preview by reading the same object rather than by loading a\n * stylesheet. `theme.css` keeps the default theme's values so the first paint is\n * correct before any script runs.\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 /** An `accentPresets` id, or `theme` for the variant's own primary. */\n accent: string\n /** A `fontOptions` id, or `space-grotesk` for the default. */\n font: string\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\nexport const defaultThemeSelection: ThemeSelection = {\n appearance: 'system',\n lightThemeId: defaultLightThemeId,\n darkThemeId: defaultDarkThemeId,\n accent: 'theme',\n font: 'space-grotesk',\n density: 'comfortable',\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 * 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. */\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 /** The catalogue, so a picker does not import it separately. */\n themes: readonly ThemeVariant[]\n}\n\nconst ThemeContext = createContext<ThemeContextValue>()\n\nexport function useTheme(): ThemeContextValue {\n const value = useContext(ThemeContext)\n if (!value) throw new Error('useTheme must be called inside a <ThemeProvider>.')\n return value\n}\n\n/**\n * The preference store, or nothing.\n *\n * Only ever called inside a `try`: where storage is blocked — a sandboxed iframe, a\n * privacy mode, a denied site-data permission — merely *reading* the `localStorage`\n * global throws (\"Access is denied\", `SecurityError`), so even the `typeof` guard\n * has to sit inside the `try` rather than in front of it. Without a store the\n * preference lives only in the provider's signal for the session.\n */\nfunction preferenceStore(): Storage | undefined {\n return typeof localStorage === 'undefined' ? undefined : localStorage\n}\n\n/** The stored preference, validated against the catalogue. */\nfunction readSelection(storageKey: string): ThemeSelection {\n try {\n const raw = preferenceStore()?.getItem(storageKey)\n if (!raw) return defaultThemeSelection\n const parsed = JSON.parse(raw) as Partial<ThemeSelection>\n return {\n appearance:\n parsed.appearance === 'light' ||\n parsed.appearance === 'dark' ||\n parsed.appearance === 'system'\n ? parsed.appearance\n : defaultThemeSelection.appearance,\n // An unknown id would leave the document with no theme at all, so a stale\n // preference from an older catalogue falls back rather than applying nothing.\n lightThemeId:\n themeById(parsed.lightThemeId ?? '')?.appearance === 'light'\n ? (parsed.lightThemeId as string)\n : defaultLightThemeId,\n darkThemeId:\n themeById(parsed.darkThemeId ?? '')?.appearance === 'dark'\n ? (parsed.darkThemeId as string)\n : defaultDarkThemeId,\n accent: accentPresets.some((preset) => preset.id === parsed.accent)\n ? (parsed.accent as string)\n : defaultThemeSelection.accent,\n font: fontOptions.some((option) => option.id === parsed.font)\n ? (parsed.font as string)\n : defaultThemeSelection.font,\n }\n } catch {\n return defaultThemeSelection\n }\n}\n\nexport type ThemeProviderProps = {\n children?: JSX.Element\n /** Where the preference is persisted. Distinct per application. */\n storageKey?: string\n /** Start from this instead of the stored preference. */\n initial?: Partial<ThemeSelection>\n /**\n * The selection, owned by the caller.\n *\n * For a consumer that keeps the state itself — a settings store, or a workshop\n * whose selection lives in Storybook globals — rather than handing it to this\n * provider's signal. Each change lands here and the document follows; nothing is\n * written to the store, because the caller is the one who persists. A picker\n * below the provider still works, and its change is the caller's to read back.\n *\n * Absent, the provider is the whole owner: it reads `storageKey` on mount,\n * seeds from `initial`, and persists every `setSelection`.\n */\n selection?: Partial<ThemeSelection>\n}\n\nexport function ThemeProvider(props: ThemeProviderProps) {\n const [local] = splitProps(props, ['children', 'storageKey', 'initial', 'selection'])\n const storageKey = () => local.storageKey ?? 'adea-appearance'\n\n const [selection, setSelectionState] = createSignal<ThemeSelection>({\n ...readSelection(storageKey()),\n ...local.initial,\n })\n\n // The controlled half of the contract. A patch from the owner replaces the\n // matching axes; the stored preference is untouched, since the owner is the one\n // that persists. Reading `local.selection` — a prop getter, not a destructured\n // value — is what keeps this subscribed for the provider's lifetime.\n createEffect(() => {\n const incoming = local.selection\n if (incoming) setSelectionState((current) => ({ ...current, ...incoming }))\n })\n\n const [systemAppearance, setSystemAppearance] = createSignal<ThemeAppearance>('light')\n\n if (typeof window !== 'undefined' && typeof window.matchMedia === 'function') {\n const query = window.matchMedia('(prefers-color-scheme: dark)')\n setSystemAppearance(query.matches ? 'dark' : 'light')\n const onChange = (event: MediaQueryListEvent) =>\n setSystemAppearance(event.matches ? 'dark' : 'light')\n query.addEventListener('change', onChange)\n onCleanup(() => query.removeEventListener('change', onChange))\n }\n\n const resolvedAppearance = createMemo<ThemeAppearance>(() => {\n const preference = selection().appearance\n if (preference === 'system') return systemAppearance()\n return preference\n })\n\n const variant = createMemo<ThemeVariant>(() => {\n const id = resolvedAppearance() === 'dark' ? selection().darkThemeId : selection().lightThemeId\n return themeById(id) ?? builtinThemes[0]!\n })\n\n createEffect(() => {\n if (typeof document === 'undefined') return\n const root = document.documentElement\n const active = variant()\n\n // The variant's roles, as properties. `--primary` and `--ring` are written here\n // too, and an accent selection is layered over them below.\n //\n // The accent is applied *here* rather than left to the `[data-accent]` blocks in\n // `theme.css`, because this loop writes inline custom properties and an inline\n // declaration outranks every stylesheet selector however specific it is. The\n // blocks still exist and are still correct — they are what styles the window\n // before this runs — but they cannot win from here, so leaving the accent to\n // them meant the attribute was set, the rules were present, and nothing\n // changed on screen.\n const properties = { ...themeCssVariables(active) }\n const accent = accentVariables(selection().accent, resolvedAppearance())\n if (accent) Object.assign(properties, accent)\n\n for (const [name, value] of Object.entries(properties)) {\n root.style.setProperty(name, value)\n }\n\n root.classList.toggle('dark', resolvedAppearance() === 'dark')\n root.dataset['theme'] = active.id\n root.dataset['appearance'] = resolvedAppearance()\n root.style.colorScheme = resolvedAppearance()\n\n if (selection().accent === 'theme') root.removeAttribute('data-accent')\n else root.dataset['accent'] = selection().accent\n\n if (selection().font === 'space-grotesk') root.removeAttribute('data-font')\n else root.dataset['font'] = selection().font\n\n // Density is a pure token shift, so unlike the colour axes there is nothing to\n // compute: the attribute selects a block in `theme.css`. It is applied here for\n // the same reason as the others — this is the one place that knows what the\n // current selection is, and it is the only writer of these attributes.\n if (resolvedDensity(selection()) === 'comfortable') root.removeAttribute('data-density')\n else root.dataset['density'] = resolvedDensity(selection())\n })\n\n const value: ThemeContextValue = {\n selection,\n resolvedAppearance,\n variant,\n themes: builtinThemes,\n setSelection(patch) {\n const next = { ...selection(), ...patch }\n setSelectionState(next)\n try {\n preferenceStore()?.setItem(storageKey(), JSON.stringify(next))\n } catch {\n // A full, blocked or unavailable store must not break the switch: the\n // preference simply does not survive the reload.\n }\n },\n }\n\n return <ThemeContext.Provider value={value}>{local.children}</ThemeContext.Provider>\n}\n\n/**\n * A string as a JavaScript literal that is also safe inside an inline `<script>`.\n *\n * `JSON.stringify` produces a correct JavaScript literal, and it is **not** safe\n * here: it leaves `<` and `>` alone, so a value containing `</script>` ends the tag\n * early and everything after it is parsed as HTML. That is the classic inline-script\n * injection, and it is a real one even though the value is a developer-supplied prop\n * rather than user input — a prop can come from configuration, and a key that happens\n * to contain a closing tag should not be able to execute.\n *\n * The escape is also correct JavaScript: `\\u003c` is `<` to the parser, so the value\n * is byte-identical at runtime and inert to the HTML tokenizer. `\\u2028` and `\\u2029`\n * are escaped for the neighbouring reason — they are legal inside a JSON string and\n * were, before ES2019, line terminators to a JavaScript parser.\n *\n * CodeQL flags the unescaped form as `js/bad-code-sanitization`, which is how this\n * was found; `tests/theme-script.test.ts` pins it so it cannot come back.\n */\nexport function inlineScriptLiteral(value: string): string {\n return JSON.stringify(value).replace(\n /[<>\\u2028\\u2029]/g,\n (character) => `\\\\u${character.charCodeAt(0).toString(16).padStart(4, '0')}`\n )\n}\n\n/**\n * The no-flash script.\n *\n * Rendered inline in `<head>` before any stylesheet that matters. Without it a dark\n * preference paints the light theme first and then swaps, which is the flash every\n * themed application has to solve and the one thing a provider cannot do from\n * inside the body.\n *\n * Deliberately tiny and dependency-free: it reads the stored preference, resolves\n * `system`, and sets the class. It does not apply the variant's roles — the default\n * theme in `theme.css` covers the first paint, and the provider writes the rest on\n * mount.\n *\n * The script reads two values out of `localStorage` and writes them to `dataset`,\n * which is a *property* assignment rather than code: a stored accent or font id can\n * set an attribute and cannot execute. The one value that reaches the source as text\n * is `storageKey`, and it goes through {@link inlineScriptLiteral} for the reason\n * documented there.\n */\nexport function themeScript(storageKey = 'adea-appearance'): string {\n return `(function(){try{var s=localStorage.getItem(${inlineScriptLiteral(storageKey)});var p=s?JSON.parse(s):{};var a=p.appearance||'system';var d=a==='dark'||(a==='system'&&window.matchMedia('(prefers-color-scheme: dark)').matches);var r=document.documentElement;if(d)r.classList.add('dark');r.style.colorScheme=d?'dark':'light';if(p.accent&&p.accent!=='theme')r.dataset.accent=p.accent;if(p.font&&p.font!=='space-grotesk')r.dataset.font=p.font;if(p.density==='compact')r.dataset.density='compact';}catch(e){}})();`\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"theme-provider.js","names":["JSX","createContext","createEffect","createMemo","createSignal","onCleanup","splitProps","useContext","accentPresets","fontOptions","AccentPreset","accentVariables","builtinThemes","defaultDarkThemeId","defaultLightThemeId","isThemeAccentId","themeAccentsFor","themeById","themeCssVariables","ThemeAppearance","ThemeVariant","ThemeSelection","appearance","lightThemeId","darkThemeId","accent","font","density","ThemeDensity","defaultThemeSelection","resolvedDensity","selection","ThemeContextValue","resolvedAppearance","variant","setSelection","patch","Partial","themes","themeAccents","ThemeContext","useTheme","value","Error","preferenceStore","Storage","localStorage","undefined","readSelection","storageKey","raw","getItem","parsed","JSON","parse","some","preset","id","option","ThemeProviderProps","children","Element","initial","ThemeProvider","props","local","setSelectionState","incoming","current","systemAppearance","setSystemAppearance","window","matchMedia","query","matches","onChange","event","MediaQueryListEvent","addEventListener","removeEventListener","preference","document","root","documentElement","active","properties","Object","assign","name","entries","style","setProperty","classList","toggle","dataset","colorScheme","removeAttribute","next","setItem","stringify","_$createComponent","Provider","inlineScriptLiteral","replace","character","charCodeAt","toString","padStart","themeScript","_$createComponent"],"sources":["../../../src/components/theme/theme-provider.tsx"],"sourcesContent":["import type { JSX } from 'solid-js'\nimport {\n createContext,\n createEffect,\n createMemo,\n createSignal,\n onCleanup,\n splitProps,\n useContext,\n} from 'solid-js'\nimport { accentPresets, fontOptions } from '#lib/tokens'\nimport type { AccentPreset } from '@adea-ai/themes'\nimport {\n accentVariables,\n builtinThemes,\n defaultDarkThemeId,\n defaultLightThemeId,\n isThemeAccentId,\n themeAccentsFor,\n themeById,\n themeCssVariables,\n type ThemeAppearance,\n type ThemeVariant,\n} from '#lib/themes'\n\n/**\n * ThemeProvider.\n *\n * Owns the appearance preference and applies it to the document. One provider near\n * the root; everything below reads it.\n *\n * ## What a preference is\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 * - **a font** — the interface face.\n *\n * Four axes rather than one list of presets, because they compose: a user who wants\n * Nord with a violet accent and the system font should not need someone to author\n * that combination.\n *\n * ## Why the variants are applied as inline properties\n *\n * The catalogue is data, and a theme is applied by writing its roles onto\n * `<html>` as custom properties. That is what makes an imported palette work\n * without a hand-written `[data-theme]` block per theme, and it is why a settings\n * UI can show a preview by reading the same object rather than by loading a\n * stylesheet. `theme.css` keeps the default theme's values so the first paint is\n * correct before any script runs.\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 /** A `fontOptions` id, or `space-grotesk` for the default. */\n font: string\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\nexport const defaultThemeSelection: ThemeSelection = {\n appearance: 'system',\n lightThemeId: defaultLightThemeId,\n darkThemeId: defaultDarkThemeId,\n accent: 'theme',\n font: 'space-grotesk',\n density: 'comfortable',\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 * 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. */\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 /** The catalogue, so a picker does not import it separately. */\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\nconst ThemeContext = createContext<ThemeContextValue>()\n\nexport function useTheme(): ThemeContextValue {\n const value = useContext(ThemeContext)\n if (!value) throw new Error('useTheme must be called inside a <ThemeProvider>.')\n return value\n}\n\n/**\n * The preference store, or nothing.\n *\n * Only ever called inside a `try`: where storage is blocked — a sandboxed iframe, a\n * privacy mode, a denied site-data permission — merely *reading* the `localStorage`\n * global throws (\"Access is denied\", `SecurityError`), so even the `typeof` guard\n * has to sit inside the `try` rather than in front of it. Without a store the\n * preference lives only in the provider's signal for the session.\n */\nfunction preferenceStore(): Storage | undefined {\n return typeof localStorage === 'undefined' ? undefined : localStorage\n}\n\n/** The stored preference, validated against the catalogue. */\nfunction readSelection(storageKey: string): ThemeSelection {\n try {\n const raw = preferenceStore()?.getItem(storageKey)\n if (!raw) return defaultThemeSelection\n const parsed = JSON.parse(raw) as Partial<ThemeSelection>\n return {\n appearance:\n parsed.appearance === 'light' ||\n parsed.appearance === 'dark' ||\n parsed.appearance === 'system'\n ? parsed.appearance\n : defaultThemeSelection.appearance,\n // An unknown id would leave the document with no theme at all, so a stale\n // preference from an older catalogue falls back rather than applying nothing.\n lightThemeId:\n themeById(parsed.lightThemeId ?? '')?.appearance === 'light'\n ? (parsed.lightThemeId as string)\n : defaultLightThemeId,\n darkThemeId:\n themeById(parsed.darkThemeId ?? '')?.appearance === 'dark'\n ? (parsed.darkThemeId as string)\n : defaultDarkThemeId,\n // A theme accent is kept whenever it names a slot, even one the stored pair\n // cannot offer: the id is role-shaped so it survives a theme switch, and an\n // unoffered slot already resolves to the theme's own primary when applied.\n accent:\n typeof parsed.accent === 'string' &&\n (accentPresets.some((preset) => preset.id === parsed.accent) ||\n isThemeAccentId(parsed.accent))\n ? parsed.accent\n : defaultThemeSelection.accent,\n font: fontOptions.some((option) => option.id === parsed.font)\n ? (parsed.font as string)\n : defaultThemeSelection.font,\n }\n } catch {\n return defaultThemeSelection\n }\n}\n\nexport type ThemeProviderProps = {\n children?: JSX.Element\n /** Where the preference is persisted. Distinct per application. */\n storageKey?: string\n /** Start from this instead of the stored preference. */\n initial?: Partial<ThemeSelection>\n /**\n * The selection, owned by the caller.\n *\n * For a consumer that keeps the state itself — a settings store, or a workshop\n * whose selection lives in Storybook globals — rather than handing it to this\n * provider's signal. Each change lands here and the document follows; nothing is\n * written to the store, because the caller is the one who persists. A picker\n * below the provider still works, and its change is the caller's to read back.\n *\n * Absent, the provider is the whole owner: it reads `storageKey` on mount,\n * seeds from `initial`, and persists every `setSelection`.\n */\n selection?: Partial<ThemeSelection>\n}\n\nexport function ThemeProvider(props: ThemeProviderProps) {\n const [local] = splitProps(props, ['children', 'storageKey', 'initial', 'selection'])\n const storageKey = () => local.storageKey ?? 'adea-appearance'\n\n const [selection, setSelectionState] = createSignal<ThemeSelection>({\n ...readSelection(storageKey()),\n ...local.initial,\n })\n\n // The controlled half of the contract. A patch from the owner replaces the\n // matching axes; the stored preference is untouched, since the owner is the one\n // that persists. Reading `local.selection` — a prop getter, not a destructured\n // value — is what keeps this subscribed for the provider's lifetime.\n createEffect(() => {\n const incoming = local.selection\n if (incoming) setSelectionState((current) => ({ ...current, ...incoming }))\n })\n\n const [systemAppearance, setSystemAppearance] = createSignal<ThemeAppearance>('light')\n\n if (typeof window !== 'undefined' && typeof window.matchMedia === 'function') {\n const query = window.matchMedia('(prefers-color-scheme: dark)')\n setSystemAppearance(query.matches ? 'dark' : 'light')\n const onChange = (event: MediaQueryListEvent) =>\n setSystemAppearance(event.matches ? 'dark' : 'light')\n query.addEventListener('change', onChange)\n onCleanup(() => query.removeEventListener('change', onChange))\n }\n\n const resolvedAppearance = createMemo<ThemeAppearance>(() => {\n const preference = selection().appearance\n if (preference === 'system') return systemAppearance()\n return preference\n })\n\n const variant = createMemo<ThemeVariant>(() => {\n const id = resolvedAppearance() === 'dark' ? selection().darkThemeId : selection().lightThemeId\n return themeById(id) ?? builtinThemes[0]!\n })\n\n createEffect(() => {\n if (typeof document === 'undefined') return\n const root = document.documentElement\n const active = variant()\n\n // The variant's roles, as properties. `--primary` and `--ring` are written here\n // too, and an accent selection is layered over them below.\n //\n // The accent is applied *here* rather than left to the `[data-accent]` blocks in\n // `theme.css`, because this loop writes inline custom properties and an inline\n // declaration outranks every stylesheet selector however specific it is. The\n // blocks still exist and are still correct — they are what styles the window\n // before this runs — but they cannot win from here, so leaving the accent to\n // them meant the attribute was set, the rules were present, and nothing\n // changed on screen.\n const properties = { ...themeCssVariables(active) }\n const accent = accentVariables(selection().accent, resolvedAppearance(), selection())\n if (accent) Object.assign(properties, accent)\n\n for (const [name, value] of Object.entries(properties)) {\n root.style.setProperty(name, value)\n }\n\n root.classList.toggle('dark', resolvedAppearance() === 'dark')\n root.dataset['theme'] = active.id\n root.dataset['appearance'] = resolvedAppearance()\n root.style.colorScheme = resolvedAppearance()\n\n if (!accent) root.removeAttribute('data-accent')\n else root.dataset['accent'] = selection().accent\n\n if (selection().font === 'space-grotesk') root.removeAttribute('data-font')\n else root.dataset['font'] = selection().font\n\n // Density is a pure token shift, so unlike the colour axes there is nothing to\n // compute: the attribute selects a block in `theme.css`. It is applied here for\n // the same reason as the others — this is the one place that knows what the\n // current selection is, and it is the only writer of these attributes.\n if (resolvedDensity(selection()) === 'comfortable') root.removeAttribute('data-density')\n else root.dataset['density'] = resolvedDensity(selection())\n })\n\n const themeAccents = createMemo(() =>\n themeAccentsFor(selection().lightThemeId, selection().darkThemeId)\n )\n\n const value: ThemeContextValue = {\n selection,\n resolvedAppearance,\n variant,\n themes: builtinThemes,\n themeAccents,\n setSelection(patch) {\n const next = { ...selection(), ...patch }\n setSelectionState(next)\n try {\n preferenceStore()?.setItem(storageKey(), JSON.stringify(next))\n } catch {\n // A full, blocked or unavailable store must not break the switch: the\n // preference simply does not survive the reload.\n }\n },\n }\n\n return <ThemeContext.Provider value={value}>{local.children}</ThemeContext.Provider>\n}\n\n/**\n * A string as a JavaScript literal that is also safe inside an inline `<script>`.\n *\n * `JSON.stringify` produces a correct JavaScript literal, and it is **not** safe\n * here: it leaves `<` and `>` alone, so a value containing `</script>` ends the tag\n * early and everything after it is parsed as HTML. That is the classic inline-script\n * injection, and it is a real one even though the value is a developer-supplied prop\n * rather than user input — a prop can come from configuration, and a key that happens\n * to contain a closing tag should not be able to execute.\n *\n * The escape is also correct JavaScript: `\\u003c` is `<` to the parser, so the value\n * is byte-identical at runtime and inert to the HTML tokenizer. `\\u2028` and `\\u2029`\n * are escaped for the neighbouring reason — they are legal inside a JSON string and\n * were, before ES2019, line terminators to a JavaScript parser.\n *\n * CodeQL flags the unescaped form as `js/bad-code-sanitization`, which is how this\n * was found; `tests/theme-script.test.ts` pins it so it cannot come back.\n */\nexport function inlineScriptLiteral(value: string): string {\n return JSON.stringify(value).replace(\n /[<>\\u2028\\u2029]/g,\n (character) => `\\\\u${character.charCodeAt(0).toString(16).padStart(4, '0')}`\n )\n}\n\n/**\n * The no-flash script.\n *\n * Rendered inline in `<head>` before any stylesheet that matters. Without it a dark\n * preference paints the light theme first and then swaps, which is the flash every\n * themed application has to solve and the one thing a provider cannot do from\n * inside the body.\n *\n * Deliberately tiny and dependency-free: it reads the stored preference, resolves\n * `system`, and sets the class. It does not apply the variant's roles — the default\n * theme in `theme.css` covers the first paint, and the provider writes the rest on\n * mount.\n *\n * The script reads two values out of `localStorage` and writes them to `dataset`,\n * which is a *property* assignment rather than code: a stored accent or font id can\n * set an attribute and cannot execute. The one value that reaches the source as text\n * is `storageKey`, and it goes through {@link inlineScriptLiteral} for the reason\n * documented there.\n */\nexport function themeScript(storageKey = 'adea-appearance'): string {\n return `(function(){try{var s=localStorage.getItem(${inlineScriptLiteral(storageKey)});var p=s?JSON.parse(s):{};var a=p.appearance||'system';var d=a==='dark'||(a==='system'&&window.matchMedia('(prefers-color-scheme: dark)').matches);var r=document.documentElement;if(d)r.classList.add('dark');r.style.colorScheme=d?'dark':'light';if(p.accent&&p.accent!=='theme')r.dataset.accent=p.accent;if(p.font&&p.font!=='space-grotesk')r.dataset.font=p.font;if(p.density==='compact')r.dataset.density='compact';}catch(e){}})();`\n}\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -102,7 +102,7 @@ export * from './components/composites/help-center';
102
102
  export * from './components/composites/workspace-mark';
103
103
  export { cn } from './lib/utils';
104
104
  export { controlInteractive, controlSize, controlSizeIcon, controlSizes, cva, surfaceInteractive, type ControlSize, type VariantProps, } from './lib/variants';
105
- export { builtinThemes, contrastRatio, defaultDarkThemeId, defaultLightThemeId, themeById, themeCssVariables, themeFamilies, themesForAppearance, validateTheme, validateThemeRegistry, type ThemeAppearance, type ThemeColors, type ThemeEditorPalette, type ThemeFinding, type ThemeProvenance, type ThemeTerminalPalette, type ThemeVariant, } from './lib/themes';
105
+ 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';
106
106
  export { keyedRows, type KeyedRow } from './lib/keyed-rows';
107
107
  export { writeClipboardText } from './lib/clipboard';
108
108
  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
@@ -95,7 +95,8 @@ import { TranscriptComposition, transcriptDisclosureKey } from "./components/con
95
95
  import { AttachmentCard, ThreadPanel } from "./components/conversation/thread-panel.js";
96
96
  import { PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, countLines, expandAll, findTokenRanges, formatToken, isPasteBlock, nextSeq, pruneBlocks, recollapsePastes, remapCarriedBlocks, shouldCollapse, stripTrailingBlankLines, tokenRangeAt } from "./components/conversation/paste-tokens.js";
97
97
  import { accentPresets, allTokens, colorTokens, densityTokens, designTokens, elevationTokens, fontOptions, motionTokens, radiusTokens, typographyTokens, undocumentedTokenAliases, zIndexTokens } from "./lib/tokens.js";
98
- import { builtinThemes, contrastRatio, defaultDarkThemeId, defaultLightThemeId, themeById, themeCssVariables, themeFamilies, themesForAppearance, validateTheme, validateThemeRegistry } from "./lib/themes.js";
98
+ import { isThemeAccentId } from "./lib/theme-accents.js";
99
+ import { appearancePreviewThemes, builtinThemes, contrastRatio, defaultDarkThemeId, defaultLightThemeId, resolveAccentPreset, themeAccentsFor, themeById, themeCssVariables, themeFamilies, themeRecordById, themeRecords, themesForAppearance, validateTheme, validateThemeRegistry, withAccent } from "./lib/themes.js";
99
100
  import { ThemePicker, ThemePreview, ThemeSwatch } from "./components/theme/theme-picker.js";
100
101
  import { ThemeProvider, defaultThemeSelection, inlineScriptLiteral, resolvedDensity, themeScript, useTheme } from "./components/theme/theme-provider.js";
101
102
  import { AppearancePanel } from "./components/theme/appearance-panel.js";
@@ -121,4 +122,4 @@ import { AboutDialog } from "./components/composites/about-dialog/about-dialog.j
121
122
  import { HelpCenter } from "./components/composites/help-center/help-center.js";
122
123
  import { WorkspaceMark } from "./components/composites/workspace-mark/workspace-mark.js";
123
124
  import { writeClipboardText } from "./lib/clipboard.js";
124
- export { AboutDialog, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AccountMenu, ActionButton, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppShell, AppShellBody, AppShellContent, AppShellMain, AppearanceEditor, AppearancePanel, AppearancePopover, AspectRatio, AttachmentCard, Avatar, AvatarFallback, AvatarImage, Badge, Board, BoardCardBody, BoardCardTitle, BoardCardTrigger, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, 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, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut, ComposerAttachmentButton, ComposerHint, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ConversationAvatar, ConversationSurface, 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, 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, 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, UpdateDialog, ValueCombobox, VirtualWindow, WorkspaceMark, accentPresets, alertVariants, allTokens, badgeVariants, boardCardTitleVariants, builtinThemes, buttonVariants, 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, formatBytes, formatReleaseDate, formatToken, headingElement, headingVariants, initialsFrom, inlineScriptLiteral, isPasteBlock, itemVariants, keyedRows, layoutDepth, listLeaves, monogram, motionTokens, movePane, neighborLeaf, nextSeq, normalizeLayout, parseDiff, plainTextFromMarkdown, pruneBlocks, radiusTokens, recollapsePastes, remapCarriedBlocks, resizeFloatingPreview, resizePreviewMiniPlayer, resizeSplit, resolveFloatingPreviewFrame, resolvePreviewMiniPlayerFrame, resolvedDensity, sheetVariants, shouldCollapse, sidebarNavItemClass, sidebarNavItemStateClass, splitPane, statusDotVariants, stripTrailingBlankLines, surfaceInteractive, swapPanes, textElement, textVariants, textareaVariants, themeById, themeCssVariables, themeFamilies, themeScript, themesForAppearance, toast, toaster, toggleVariants, tokenRangeAt, transcriptDisclosureKey, typographyTokens, undoClosePane, undocumentedTokenAliases, useSideRail, useTheme, validateTheme, validateThemeRegistry, writeClipboardText, zIndexTokens };
125
+ export { AboutDialog, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AccountMenu, ActionButton, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppShell, AppShellBody, AppShellContent, AppShellMain, AppearanceEditor, AppearancePanel, AppearancePopover, AspectRatio, AttachmentCard, Avatar, AvatarFallback, AvatarImage, Badge, Board, BoardCardBody, BoardCardTitle, BoardCardTrigger, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, 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, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut, ComposerAttachmentButton, ComposerHint, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ConversationAvatar, ConversationSurface, 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, 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, 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, UpdateDialog, ValueCombobox, VirtualWindow, WorkspaceMark, accentPresets, alertVariants, allTokens, appearancePreviewThemes, badgeVariants, boardCardTitleVariants, builtinThemes, buttonVariants, 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, formatBytes, formatReleaseDate, formatToken, headingElement, headingVariants, initialsFrom, inlineScriptLiteral, isPasteBlock, isThemeAccentId, itemVariants, keyedRows, layoutDepth, listLeaves, monogram, motionTokens, movePane, neighborLeaf, nextSeq, normalizeLayout, parseDiff, plainTextFromMarkdown, pruneBlocks, radiusTokens, recollapsePastes, remapCarriedBlocks, resizeFloatingPreview, resizePreviewMiniPlayer, resizeSplit, resolveAccentPreset, resolveFloatingPreviewFrame, resolvePreviewMiniPlayerFrame, resolvedDensity, sheetVariants, shouldCollapse, sidebarNavItemClass, sidebarNavItemStateClass, splitPane, 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 };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Whether an id names a theme-derived accent slot.
3
+ *
4
+ * Deliberately wider than what any one pair offers: the id is valid to *store*
5
+ * whenever it names a slot, because the next theme may offer it even if this one
6
+ * does not. Whether it resolves is `resolveAccentPreset`'s question.
7
+ */
8
+ export declare function isThemeAccentId(id: string): boolean;
9
+ //# sourceMappingURL=theme-accents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-accents.d.ts","sourceRoot":"","sources":["../../src/lib/theme-accents.ts"],"names":[],"mappings":"AA4BA;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAQnD"}
@@ -0,0 +1,41 @@
1
+ import { ANSI_KEYS } from "@adea-ai/themes/schema";
2
+ //#region src/lib/theme-accents.ts
3
+ /**
4
+ * The accents a theme carries, beside the six presets.
5
+ *
6
+ * `@adea-ai/themes` offers two kinds of accent. The presets (`ACCENTS`) are brand
7
+ * colours, the same six on every theme. Since 0.9 the catalogue also offers the
8
+ * accent-shaped colours a theme carries itself — its ANSI blue, magenta, cyan and
9
+ * green, paired across a light and a dark theme and kept only when they clear the
10
+ * catalogue's accent floors — through `themeAccentPresets`. Those read as part of
11
+ * the palette rather than as visitors on it, which is why they are offered here.
12
+ *
13
+ * Their ids are role-shaped (`ansi-blue`), not value-shaped: a stored theme accent
14
+ * survives switching themes and resolves to the *new* theme's blue. That has one
15
+ * consequence a consumer must handle, and this module is where it is handled once:
16
+ * a stored theme accent may name a slot the current pair does not offer, and then
17
+ * it resolves to nothing and the theme's own primary applies — the same fallback a
18
+ * stale preset id gets.
19
+ *
20
+ * This module holds only the id test, and reads only the schema entry: the
21
+ * appearance editor uses it, and the editor's packed renderer gate forbids the
22
+ * catalogue and normalization modules that *computing* a theme accent needs
23
+ * (`themeAccentPresets` measures through `normalize.js`). Resolution lives in
24
+ * `lib/themes.ts`, beside the catalogue it reads.
25
+ */
26
+ /** The prefix the catalogue gives every theme-derived accent id. */
27
+ var THEME_ACCENT_PREFIX = "ansi-";
28
+ /**
29
+ * Whether an id names a theme-derived accent slot.
30
+ *
31
+ * Deliberately wider than what any one pair offers: the id is valid to *store*
32
+ * whenever it names a slot, because the next theme may offer it even if this one
33
+ * does not. Whether it resolves is `resolveAccentPreset`'s question.
34
+ */
35
+ function isThemeAccentId(id) {
36
+ return id.startsWith(THEME_ACCENT_PREFIX) && ANSI_KEYS.includes(id.slice(5));
37
+ }
38
+ //#endregion
39
+ export { isThemeAccentId };
40
+
41
+ //# sourceMappingURL=theme-accents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-accents.js","names":[],"sources":["../../src/lib/theme-accents.ts"],"sourcesContent":["/**\n * The accents a theme carries, beside the six presets.\n *\n * `@adea-ai/themes` offers two kinds of accent. The presets (`ACCENTS`) are brand\n * colours, the same six on every theme. Since 0.9 the catalogue also offers the\n * accent-shaped colours a theme carries itself — its ANSI blue, magenta, cyan and\n * green, paired across a light and a dark theme and kept only when they clear the\n * catalogue's accent floors — through `themeAccentPresets`. Those read as part of\n * the palette rather than as visitors on it, which is why they are offered here.\n *\n * Their ids are role-shaped (`ansi-blue`), not value-shaped: a stored theme accent\n * survives switching themes and resolves to the *new* theme's blue. That has one\n * consequence a consumer must handle, and this module is where it is handled once:\n * a stored theme accent may name a slot the current pair does not offer, and then\n * it resolves to nothing and the theme's own primary applies — the same fallback a\n * stale preset id gets.\n *\n * This module holds only the id test, and reads only the schema entry: the\n * appearance editor uses it, and the editor's packed renderer gate forbids the\n * catalogue and normalization modules that *computing* a theme accent needs\n * (`themeAccentPresets` measures through `normalize.js`). Resolution lives in\n * `lib/themes.ts`, beside the catalogue it reads.\n */\nimport { ANSI_KEYS } from '@adea-ai/themes/schema'\n\n/** The prefix the catalogue gives every theme-derived accent id. */\nconst THEME_ACCENT_PREFIX = 'ansi-'\n\n/**\n * Whether an id names a theme-derived accent slot.\n *\n * Deliberately wider than what any one pair offers: the id is valid to *store*\n * whenever it names a slot, because the next theme may offer it even if this one\n * does not. Whether it resolves is `resolveAccentPreset`'s question.\n */\nexport function isThemeAccentId(id: string): boolean {\n // Computed per call rather than held in a module-level set: a top-level\n // `new Set(...)` is a statement a bundler cannot prove pure, and it would keep\n // this module in every bundle that touches the root entry.\n return (\n id.startsWith(THEME_ACCENT_PREFIX) &&\n (ANSI_KEYS as readonly string[]).includes(id.slice(THEME_ACCENT_PREFIX.length))\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,IAAM,sBAAsB;;;;;;;;AAS5B,SAAgB,gBAAgB,IAAqB;CAInD,OACE,GAAG,WAAW,mBAAmB,KAChC,UAAgC,SAAS,GAAG,MAAM,CAA0B,CAAC;AAElF"}
@@ -32,6 +32,8 @@
32
32
  * `--primary`, and `--accent` is filled from `surfaceHover`, which is what shadcn
33
33
  * components actually use it for.
34
34
  */
35
+ import { type AccentPreset, type AdeaTheme, type AdeaThemeRecord } from '@adea-ai/themes';
36
+ export { isThemeAccentId } from './theme-accents';
35
37
  export type ThemeAppearance = 'light' | 'dark';
36
38
  /**
37
39
  * The surface and text roles, in shadcn's vocabulary.
@@ -157,7 +159,62 @@ export declare function themeFamilies(): {
157
159
  themes: ThemeVariant[];
158
160
  }[];
159
161
  /** The accent presets, in the order a picker should show them. */
160
- export declare const accents: readonly import("@adea-ai/themes").AccentPreset[];
162
+ export declare const accents: readonly AccentPreset[];
163
+ /**
164
+ * The canonical catalogue records, in catalogue order.
165
+ *
166
+ * {@link builtinThemes} is this system's projection of the catalogue onto the
167
+ * shadcn vocabulary, which is what a document is painted with. A *preview* of a
168
+ * theme — the miniatures `AppearanceEditor` and `ThemeMiniature` draw — reads the
169
+ * catalogue's own roles instead (`surfaceActive`, `borderMuted`, `textSubtle`…),
170
+ * several of which the projection folds together. These are those records, so a
171
+ * consumer hands the editor exactly what it takes rather than reconstructing it
172
+ * from the projection.
173
+ */
174
+ export declare const themeRecords: readonly AdeaThemeRecord[];
175
+ export declare function themeRecordById(id: string): AdeaThemeRecord | undefined;
176
+ /**
177
+ * The accents the selected light/dark pair carries — offered beside the presets.
178
+ *
179
+ * Computed per pair rather than per theme because a theme accent is a *pair* of
180
+ * values, like a preset: a slot is offered only when both themes can offer it.
181
+ */
182
+ export declare function themeAccentsFor(lightThemeId: string, darkThemeId: string): readonly AccentPreset[];
183
+ /**
184
+ * An accent id resolved against a theme pair: a preset, a theme accent the pair
185
+ * offers, or `undefined` for `theme`, an unknown id, or a slot this pair cannot
186
+ * offer — each of which means "use the theme's own primary".
187
+ *
188
+ * Theme accent ids are role-shaped (`ansi-blue`), so a stored one survives a theme
189
+ * switch and resolves to the new theme's blue; when the new pair cannot offer the
190
+ * slot it resolves to nothing, the same fallback a stale preset id gets.
191
+ */
192
+ export declare function resolveAccentPreset(accentId: string, light: AdeaTheme, dark: AdeaTheme): AccentPreset | undefined;
193
+ /**
194
+ * A theme with an accent laid over it, in the catalogue's own shape.
195
+ *
196
+ * The accent replaces `accent` and its measured label, which is all an accent
197
+ * changes about a theme; `undefined` returns the theme untouched. This is the
198
+ * overlay a host needs for `AppearanceEditor`'s `lightTheme`/`darkTheme`.
199
+ */
200
+ export declare function withAccent<T extends AdeaTheme>(theme: T, accent: AccentPreset | undefined): T;
201
+ /**
202
+ * The two preview themes an appearance selection resolves to, accent applied.
203
+ *
204
+ * The adapter between a stored selection and `AppearanceEditor`: it takes ids —
205
+ * what a preference holds — and returns the canonical records the editor's
206
+ * `lightTheme` and `darkTheme` props take, so a host does not map roles by hand.
207
+ * Unknown ids fall back to the defaults and an accent the pair cannot offer falls
208
+ * back to the theme's own, exactly as `ThemeProvider` resolves them.
209
+ */
210
+ export declare function appearancePreviewThemes(selection: {
211
+ lightThemeId: string;
212
+ darkThemeId: string;
213
+ accent: string;
214
+ }): {
215
+ lightTheme: AdeaThemeRecord;
216
+ darkTheme: AdeaThemeRecord;
217
+ };
161
218
  /**
162
219
  * The properties an accent selection overrides, as CSS custom properties.
163
220
  *
@@ -177,11 +234,18 @@ export declare const accents: readonly import("@adea-ai/themes").AccentPreset[];
177
234
  * provider and the CSS generator call `accentRoles` out of `@adea-ai/themes`, and
178
235
  * `tests/appearance-axes.test.ts` asserts the two agree value for value.
179
236
  *
180
- * Returns `undefined` for `theme` — the variant's own primary — and for an id the
181
- * catalogue does not have, so a stale stored preference falls back to the theme
182
- * rather than blanking the primary.
237
+ * A theme accent (`ansi-blue`) has no block: its value depends on the theme pair,
238
+ * so it is resolved against `pair` — the selection's light and dark theme ids —
239
+ * and only ever applied here. Without a pair it resolves against the defaults.
240
+ *
241
+ * Returns `undefined` for `theme` — the variant's own primary — for an id the
242
+ * catalogue does not have, and for a theme accent the pair does not offer, so a
243
+ * stale stored preference falls back to the theme rather than blanking the primary.
183
244
  */
184
- export declare function accentVariables(accentId: string, appearance: ThemeAppearance): Record<string, string> | undefined;
245
+ export declare function accentVariables(accentId: string, appearance: ThemeAppearance, pair?: {
246
+ lightThemeId: string;
247
+ darkThemeId: string;
248
+ }): Record<string, string> | undefined;
185
249
  /**
186
250
  * The roles a variant sets, as CSS custom properties.
187
251
  *
@@ -1 +1 @@
1
- {"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../src/lib/themes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../src/lib/themes.ts"],"names":[],"mappings":"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"}