@adea-ai/ui 0.128.1 → 0.128.3

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 (141) hide show
  1. package/dist/components/theme/appearance-panel.js +1 -1
  2. package/dist/components/theme/index.js +1 -1
  3. package/dist/components/theme/lazy.d.ts +15 -0
  4. package/dist/components/theme/lazy.d.ts.map +1 -0
  5. package/dist/components/theme/lazy.js +9 -0
  6. package/dist/components/theme/theme-catalogue-source.d.ts +15 -0
  7. package/dist/components/theme/theme-catalogue-source.d.ts.map +1 -0
  8. package/dist/components/theme/theme-catalogue-source.js +51 -0
  9. package/dist/components/theme/theme-catalogue-source.js.map +1 -0
  10. package/dist/components/theme/theme-document-core.d.ts +123 -0
  11. package/dist/components/theme/theme-document-core.d.ts.map +1 -0
  12. package/dist/components/theme/{theme-document.js → theme-document-core.js} +12 -12
  13. package/dist/components/theme/theme-document-core.js.map +1 -0
  14. package/dist/components/theme/theme-document.d.ts +8 -107
  15. package/dist/components/theme/theme-document.d.ts.map +1 -1
  16. package/dist/components/theme/theme-persistence.d.ts +1 -1
  17. package/dist/components/theme/theme-persistence.d.ts.map +1 -1
  18. package/dist/components/theme/theme-persistence.js +9 -6
  19. package/dist/components/theme/theme-persistence.js.map +1 -1
  20. package/dist/components/theme/theme-provider-core.d.ts +19 -0
  21. package/dist/components/theme/theme-provider-core.d.ts.map +1 -0
  22. package/dist/components/theme/theme-provider-core.js +28 -0
  23. package/dist/components/theme/theme-provider-core.js.map +1 -0
  24. package/dist/components/theme/theme-provider-lazy.d.ts +28 -0
  25. package/dist/components/theme/theme-provider-lazy.d.ts.map +1 -0
  26. package/dist/components/theme/theme-provider-lazy.js +36 -0
  27. package/dist/components/theme/theme-provider-lazy.js.map +1 -0
  28. package/dist/components/theme/theme-provider-value.d.ts +175 -0
  29. package/dist/components/theme/theme-provider-value.d.ts.map +1 -0
  30. package/dist/components/theme/theme-provider-value.js +200 -0
  31. package/dist/components/theme/theme-provider-value.js.map +1 -0
  32. package/dist/components/theme/theme-provider.d.ts +11 -136
  33. package/dist/components/theme/theme-provider.d.ts.map +1 -1
  34. package/dist/components/theme/theme-provider.js +27 -149
  35. package/dist/components/theme/theme-provider.js.map +1 -1
  36. package/dist/components/theme/theme-script.js +4 -3
  37. package/dist/components/theme/theme-script.js.map +1 -1
  38. package/dist/components/theme/theme-state-core.d.ts +248 -0
  39. package/dist/components/theme/theme-state-core.d.ts.map +1 -0
  40. package/dist/components/theme/{theme-state.js → theme-state-core.js} +8 -7
  41. package/dist/components/theme/theme-state-core.js.map +1 -0
  42. package/dist/components/theme/theme-state.d.ts +8 -214
  43. package/dist/components/theme/theme-state.d.ts.map +1 -1
  44. package/dist/components/theme/theme-toggle.js.map +1 -1
  45. package/dist/index.js +7 -4
  46. package/dist/lib/accent-presets.d.ts +26 -0
  47. package/dist/lib/accent-presets.d.ts.map +1 -0
  48. package/dist/lib/accent-presets.js +11 -0
  49. package/dist/lib/accent-presets.js.map +1 -0
  50. package/dist/lib/accent-roles.js +94 -9
  51. package/dist/lib/accent-roles.js.map +1 -1
  52. package/dist/lib/font-zoom.js +4 -2
  53. package/dist/lib/font-zoom.js.map +1 -1
  54. package/dist/lib/overlay.js +3 -1
  55. package/dist/lib/overlay.js.map +1 -1
  56. package/dist/lib/theme-catalogue.d.ts +3 -0
  57. package/dist/lib/theme-catalogue.d.ts.map +1 -0
  58. package/dist/lib/theme-catalogue.js +22 -0
  59. package/dist/lib/theme-catalogue.js.map +1 -0
  60. package/dist/lib/theme-css.d.ts +43 -0
  61. package/dist/lib/theme-css.d.ts.map +1 -0
  62. package/dist/lib/theme-css.js +167 -0
  63. package/dist/lib/theme-css.js.map +1 -0
  64. package/dist/lib/theme-defaults.d.ts +46 -0
  65. package/dist/lib/theme-defaults.d.ts.map +1 -0
  66. package/dist/lib/theme-defaults.generated.d.ts +13 -0
  67. package/dist/lib/theme-defaults.generated.d.ts.map +1 -0
  68. package/dist/lib/theme-defaults.generated.js +318 -0
  69. package/dist/lib/theme-defaults.generated.js.map +1 -0
  70. package/dist/lib/theme-defaults.js +47 -0
  71. package/dist/lib/theme-defaults.js.map +1 -0
  72. package/dist/lib/theme-engine-light.d.ts +3 -0
  73. package/dist/lib/theme-engine-light.d.ts.map +1 -0
  74. package/dist/lib/theme-engine-light.js +75 -0
  75. package/dist/lib/theme-engine-light.js.map +1 -0
  76. package/dist/lib/theme-engine.d.ts +69 -0
  77. package/dist/lib/theme-engine.d.ts.map +1 -0
  78. package/dist/lib/theme-engine.js +33 -0
  79. package/dist/lib/theme-engine.js.map +1 -0
  80. package/dist/lib/themes.d.ts +14 -48
  81. package/dist/lib/themes.d.ts.map +1 -1
  82. package/dist/lib/themes.js +24 -164
  83. package/dist/lib/themes.js.map +1 -1
  84. package/dist/lib/tokens.d.ts +1 -25
  85. package/dist/lib/tokens.d.ts.map +1 -1
  86. package/dist/lib/tokens.js +1 -24
  87. package/dist/lib/tokens.js.map +1 -1
  88. package/dist/lib/tooltip-focus-gate.js +7 -1
  89. package/dist/lib/tooltip-focus-gate.js.map +1 -1
  90. package/dist/lib/variants.js +2 -2
  91. package/dist/r/lib.json +35 -0
  92. package/dist/r/registry.json +70 -0
  93. package/dist/r/src/components/theme/lazy.ts +35 -0
  94. package/dist/r/src/components/theme/theme-catalogue-source.ts +59 -0
  95. package/dist/r/src/components/theme/theme-document-core.ts +262 -0
  96. package/dist/r/src/components/theme/theme-document.ts +23 -240
  97. package/dist/r/src/components/theme/theme-persistence.ts +14 -6
  98. package/dist/r/src/components/theme/theme-provider-core.tsx +40 -0
  99. package/dist/r/src/components/theme/theme-provider-lazy.tsx +34 -0
  100. package/dist/r/src/components/theme/theme-provider-value.ts +445 -0
  101. package/dist/r/src/components/theme/theme-provider.tsx +23 -346
  102. package/dist/r/src/components/theme/theme-script.ts +3 -3
  103. package/dist/r/src/components/theme/theme-state-core.ts +364 -0
  104. package/dist/r/src/components/theme/theme-state.ts +10 -329
  105. package/dist/r/src/components/theme/theme-toggle.tsx +1 -1
  106. package/dist/r/src/lib/accent-presets.ts +43 -0
  107. package/dist/r/src/lib/theme-catalogue.ts +26 -0
  108. package/dist/r/src/lib/theme-css.ts +201 -0
  109. package/dist/r/src/lib/theme-defaults.generated.ts +319 -0
  110. package/dist/r/src/lib/theme-defaults.ts +79 -0
  111. package/dist/r/src/lib/theme-engine-light.ts +117 -0
  112. package/dist/r/src/lib/theme-engine.ts +111 -0
  113. package/dist/r/src/lib/themes.ts +27 -191
  114. package/dist/r/src/lib/tokens.ts +1 -35
  115. package/dist/r/theming.json +35 -0
  116. package/package.json +12 -3
  117. package/registry.json +70 -0
  118. package/src/components/theme/lazy.ts +35 -0
  119. package/src/components/theme/theme-catalogue-source.ts +59 -0
  120. package/src/components/theme/theme-document-core.ts +262 -0
  121. package/src/components/theme/theme-document.ts +23 -240
  122. package/src/components/theme/theme-persistence.ts +14 -6
  123. package/src/components/theme/theme-provider-core.tsx +40 -0
  124. package/src/components/theme/theme-provider-lazy.tsx +34 -0
  125. package/src/components/theme/theme-provider-value.ts +445 -0
  126. package/src/components/theme/theme-provider.tsx +23 -346
  127. package/src/components/theme/theme-script.ts +3 -3
  128. package/src/components/theme/theme-state-core.ts +364 -0
  129. package/src/components/theme/theme-state.ts +10 -329
  130. package/src/components/theme/theme-toggle.tsx +1 -1
  131. package/src/lib/accent-presets.ts +43 -0
  132. package/src/lib/theme-catalogue.ts +26 -0
  133. package/src/lib/theme-css.ts +201 -0
  134. package/src/lib/theme-defaults.generated.ts +319 -0
  135. package/src/lib/theme-defaults.ts +79 -0
  136. package/src/lib/theme-engine-light.ts +117 -0
  137. package/src/lib/theme-engine.ts +111 -0
  138. package/src/lib/themes.ts +27 -191
  139. package/src/lib/tokens.ts +1 -35
  140. package/dist/components/theme/theme-document.js.map +0 -1
  141. package/dist/components/theme/theme-state.js.map +0 -1
@@ -44,7 +44,6 @@ import {
44
44
  shadcnDestructiveProjection,
45
45
  statusForeground,
46
46
  tint,
47
- primaryHover,
48
47
  primarySubtleCss,
49
48
  syntaxRoles,
50
49
  themes as catalogue,
@@ -57,11 +56,14 @@ import {
57
56
  type ContrastFinding,
58
57
  } from '@adea-ai/themes'
59
58
  import { shadcnVariables } from '@adea-ai/themes/adapters/shadcn'
60
- import { oklchToHex, parseColor } from '@adea-ai/themes/oklch'
61
59
  import { accentOverrideVariables, resolveAccentRoles, type AccentRoles } from './accent-roles'
62
60
  import { isThemeAccentId } from './theme-accents'
61
+ import { themeCssVariablesWith } from './theme-css'
62
+ import { defaultDarkThemeId, defaultLightThemeId } from './theme-defaults'
63
63
 
64
64
  export { isThemeAccentId } from './theme-accents'
65
+ export { terminalCssVariables, tokensAsHex } from './theme-css'
66
+ export { defaultDarkThemeId, defaultLightThemeId, resolveVariant } from './theme-defaults'
65
67
 
66
68
  export type ThemeAppearance = 'light' | 'dark'
67
69
 
@@ -376,46 +378,22 @@ export function primarySubtleFor(theme: Pick<ThemeVariant, 'id' | 'appearance'>)
376
378
  return record ? primarySubtleCss(record) : primarySubtleCss(theme.appearance)
377
379
  }
378
380
 
379
- /** The catalogue, in catalogue order. */
380
- export const builtinThemes: readonly ThemeVariant[] = Object.freeze(catalogue.map(lazyVariant))
381
+ /**
382
+ * The catalogue, in catalogue order.
383
+ *
384
+ * The `@__PURE__` marks let a bundler drop the whole table, and with it the catalogue,
385
+ * from a consumer that imports only this module's catalogue-free helpers
386
+ * (`tokensAsHex`, `isThemeAccentId`, `resolveVariant`…) and never reads it.
387
+ */
388
+ export const builtinThemes: readonly ThemeVariant[] = /* @__PURE__ */ Object.freeze(
389
+ /* @__PURE__ */ catalogue.map(lazyVariant)
390
+ )
381
391
 
382
392
  export function themeById(id: string): ThemeVariant | undefined {
383
393
  if (!hasTheme(id)) return undefined
384
394
  return builtinThemes.find((theme) => theme.id === id)
385
395
  }
386
396
 
387
- /**
388
- * The variant a stored id means, or the default of the same appearance.
389
- *
390
- * An id the registry does not hold — an imported theme that was deleted, a
391
- * catalogue entry that was renamed — must still paint *something of the appearance
392
- * being shown*. Falling back to whichever variant happens to be first in the
393
- * registry painted a dark palette under a light `color-scheme` for a light id, so
394
- * the fallback is the appearance's own default, then any variant of that
395
- * appearance, then the registry's first entry only when it holds nothing else.
396
- *
397
- * `registry` is the builtin catalogue plus whatever extras the host supplies; the
398
- * stored id is never rewritten, only resolved, so a host that keeps an unknown id
399
- * keeps resolving it if the theme comes back.
400
- *
401
- * The fallback order is translated from Zeron's `ThemeRegistry::resolve` (MIT,
402
- * Copyright (c) 2026 Wing); see NOTICE.
403
- */
404
- export function resolveVariant(
405
- registry: readonly ThemeVariant[],
406
- id: string,
407
- appearance: ThemeAppearance
408
- ): ThemeVariant {
409
- const found = registry.find((variant) => variant.id === id)
410
- if (found) return found
411
- const defaultId = appearance === 'dark' ? defaultDarkThemeId : defaultLightThemeId
412
- return (
413
- registry.find((variant) => variant.id === defaultId) ??
414
- registry.find((variant) => variant.appearance === appearance) ??
415
- registry[0]!
416
- )
417
- }
418
-
419
397
  /** The variants of one appearance, which is what a picker for that mode shows. */
420
398
  export function themesForAppearance(appearance: ThemeAppearance): readonly ThemeVariant[] {
421
399
  const ids = new Set(themesByAppearance(appearance).map((theme) => theme.id))
@@ -708,166 +686,27 @@ export function editorPaletteFor(
708
686
  /**
709
687
  * The roles a variant sets, as CSS custom properties.
710
688
  *
711
- * The one place that knows the mapping from a theme's roles to this system's variable
712
- * names. A provider applies this; nothing else repeats it. The `--terminal-*` and
713
- * `--editor-*` ramps are presentations of the catalogue's ANSI and syntax data rather
714
- * than separate roles, which is why they are built here and not in the catalogue.
715
- *
716
- * `options.editor` picks the `--editor-*` projection ({@link EditorRolesMode}).
717
- * Absent it, the result is what it has always been; the generated `theme-variants.css`
718
- * and the design-system artifact are built without it.
689
+ * The mapping itself is `themeCssVariablesWith` in `theme-css.ts`; this binds it to
690
+ * the catalogue, which measures a theme's `--primary-subtle` strength
691
+ * ({@link primarySubtleFor}) and projects its floor editor ramp
692
+ * ({@link editorPaletteFor}). Absent `options`, the result is what it has always
693
+ * been; the generated `theme-variants.css` and the design-system artifact are built
694
+ * without it.
719
695
  */
720
696
  export function themeCssVariables(
721
697
  theme: ThemeVariant,
722
698
  options: ThemeCssVariableOptions = {}
723
699
  ): Record<string, string> {
724
- const c = theme.colors
725
- const t = theme.terminal
726
- const e = editorPaletteFor(theme, options.editor)
727
- const derived = {
728
- '--background': c.background,
729
- '--foreground': c.foreground,
730
- '--card': c.card,
731
- '--card-foreground': c.cardForeground,
732
- '--popover': c.popover,
733
- '--popover-foreground': c.popoverForeground,
734
- '--primary': c.primary,
735
- '--primary-foreground': c.primaryForeground,
736
- /*
737
- * The two tokens derived from the primary, and they are here rather than left to
738
- * `theme.css` because they must follow `--primary` — which this function writes
739
- * for *any* theme in the catalogue, not just the two defaults `theme.css` carries.
740
- *
741
- * `--primary-hover` is a resolved colour, not a `color-mix()`: a uniform hover
742
- * step cannot be expressed as a mix (see `primaryHover`). Left out, a theme switch
743
- * would keep the previous theme's hover on the new theme's primary.
744
- *
745
- * `--primary-subtle` is a mix over `--primary`, so it follows an accent on its
746
- * own, but its *strength* is per theme: `primarySubtleCss(record)` lowers the
747
- * appearance ceiling only as far as this theme needs for body text to clear 4.5:1
748
- * on the tint, over every surface, for every accent it offers. It has to be
749
- * written per theme for that reason — the appearance-wide value is not legible on
750
- * every palette.
751
- */
752
- '--primary-hover': primaryHover(c.primary, theme.appearance),
753
- '--primary-subtle': primarySubtleFor(theme),
754
- '--secondary': c.secondary,
755
- '--secondary-foreground': c.secondaryForeground,
756
- '--muted': c.muted,
757
- '--muted-foreground': c.mutedForeground,
758
- '--accent': c.accent,
759
- '--accent-foreground': c.accentForeground,
760
- '--destructive': c.destructive,
761
- '--destructive-foreground': c.destructiveForeground,
762
- '--destructive-subtle': c.destructiveSubtle,
763
- '--destructive-action': c.destructiveAction,
764
- '--destructive-action-foreground': c.destructiveActionForeground,
765
- '--success': c.success,
766
- '--success-foreground': c.successForeground,
767
- '--success-subtle': c.successSubtle,
768
- '--warning': c.warning,
769
- '--warning-foreground': c.warningForeground,
770
- '--warning-subtle': c.warningSubtle,
771
- '--info': c.info,
772
- '--info-foreground': c.infoForeground,
773
- '--info-subtle': c.infoSubtle,
774
- '--border': c.border,
775
- '--input': c.input,
776
- '--ring': c.ring,
777
- '--sidebar': c.sidebar,
778
- '--sidebar-foreground': c.sidebarForeground,
779
- '--sidebar-accent': c.sidebarAccent,
780
- '--sidebar-border': c.sidebarBorder,
781
- '--sidebar-primary': c.primary,
782
- '--sidebar-primary-foreground': c.primaryForeground,
783
- '--sidebar-ring': c.ring,
784
- '--sidebar-muted-foreground': c.sidebarMutedForeground,
785
- '--surface-sunken': c.muted,
786
- '--surface-hover': c.accent,
787
- '--surface-active': c.border,
788
- '--chrome': c.background,
789
- '--terminal-background': t.background,
790
- '--terminal-foreground': t.foreground,
791
- '--terminal-cursor': t.cursor,
792
- '--terminal-selection': t.selection,
793
- '--terminal-ansi-black': t.black,
794
- '--terminal-ansi-red': t.red,
795
- '--terminal-ansi-green': t.green,
796
- '--terminal-ansi-yellow': t.yellow,
797
- '--terminal-ansi-blue': t.blue,
798
- '--terminal-ansi-magenta': t.magenta,
799
- '--terminal-ansi-cyan': t.cyan,
800
- '--terminal-ansi-white': t.white,
801
- '--terminal-ansi-bright-black': t.brightBlack,
802
- '--terminal-ansi-bright-red': t.brightRed,
803
- '--terminal-ansi-bright-green': t.brightGreen,
804
- '--terminal-ansi-bright-yellow': t.brightYellow,
805
- '--terminal-ansi-bright-blue': t.brightBlue,
806
- '--terminal-ansi-bright-magenta': t.brightMagenta,
807
- '--terminal-ansi-bright-cyan': t.brightCyan,
808
- '--terminal-ansi-bright-white': t.brightWhite,
809
- '--editor-keyword': e.keyword,
810
- '--editor-string': e.string,
811
- '--editor-number': e.number,
812
- '--editor-comment': e.comment,
813
- '--editor-function': e.function,
814
- '--editor-variable': e.variable,
815
- '--editor-type': e.type,
816
- '--editor-tag': e.tag,
817
- '--editor-attribute': e.attribute,
818
- '--editor-operator': e.operator,
819
- '--editor-heading': e.heading,
820
- '--editor-link': e.link,
821
- '--editor-diff-add': e.diffAdd,
822
- '--editor-diff-delete': e.diffDelete,
823
- '--editor-diff-hunk': e.diffHunk,
824
- '--editor-search-match': e.searchMatch,
825
- '--chart-1': theme.chart[0] ?? c.primary,
826
- '--chart-2': theme.chart[1] ?? c.info,
827
- '--chart-3': theme.chart[2] ?? c.success,
828
- '--chart-4': theme.chart[3] ?? c.warning,
829
- '--chart-5': theme.chart[4] ?? c.destructive,
830
- '--chart-6': theme.chart[5] ?? c.mutedForeground,
831
- }
832
- return theme.tokens ? { ...derived, ...theme.tokens } : derived
833
- }
834
-
835
- /**
836
- * The `--terminal-*` properties of a variant: the palette a terminal paints.
837
- *
838
- * What a pinned terminal theme writes over the interface variant's own. Taken from
839
- * {@link themeCssVariables} rather than rebuilt, so the names, and a custom
840
- * variant's verbatim `tokens`, can never drift from what the interface variant
841
- * would have written for the same palette.
842
- */
843
- export function terminalCssVariables(theme: ThemeVariant): Record<string, string> {
844
- return Object.fromEntries(
845
- Object.entries(themeCssVariables(theme)).filter(([name]) => name.startsWith('--terminal-'))
700
+ return themeCssVariablesWith(
701
+ {
702
+ primarySubtle: primarySubtleFor,
703
+ editor: (variant, mode) => editorPaletteFor(variant, mode),
704
+ },
705
+ theme,
706
+ options
846
707
  )
847
708
  }
848
709
 
849
- /**
850
- * Token values with every `oklch()` colour written as `#rrggbb`.
851
- *
852
- * For a host whose stylesheet, tests or native shell speak hex: the catalogue's
853
- * roles are `oklch()` strings, and this is the one conversion, gamut-mapped by the
854
- * catalogue's own `oklchToHex`. A value that is already hex, carries alpha
855
- * (`rgba()`), or is not a plain colour (`color-mix()`, `var()`) is left byte for
856
- * byte, because converting would either lose the alpha or be a guess. Suitable as
857
- * `ThemeProvider`'s `transformTokens`.
858
- */
859
- export function tokensAsHex(tokens: Readonly<Record<string, string>>): Record<string, string> {
860
- const converted: Record<string, string> = {}
861
- for (const [name, value] of Object.entries(tokens)) {
862
- const trimmed = value.trim()
863
- // `parseOklch` discards alpha, so a translucent oklch() stays as written.
864
- const opaque = trimmed.startsWith('oklch(') && !trimmed.includes('/')
865
- const parsed = opaque ? parseColor(trimmed) : undefined
866
- converted[name] = parsed ? oklchToHex(parsed) : value
867
- }
868
- return converted
869
- }
870
-
871
710
  /* ---------------------------------------------------------------------------
872
711
  * Validation
873
712
  *
@@ -914,8 +753,5 @@ export function validateThemeRegistry(
914
753
  return [...orphaned, ...validateCatalogue(records).map(toFinding)]
915
754
  }
916
755
 
917
- export const defaultLightThemeId = 'adea-light'
918
- export const defaultDarkThemeId = 'adea-dark'
919
-
920
756
  /** Re-exported so a consumer measuring a colour does not need a second import. */
921
757
  export { contrastRatio } from '@adea-ai/themes'
@@ -17,7 +17,6 @@
17
17
  * token exists" a property the build enforces rather than a promise.
18
18
  */
19
19
 
20
- import { ACCENTS } from '@adea-ai/themes'
21
20
  export { fontOptions } from './font-catalog'
22
21
  export type { FontOption } from './font-catalog'
23
22
 
@@ -705,40 +704,7 @@ export const zIndexTokens: TokenDefinition[] = [
705
704
  },
706
705
  ]
707
706
 
708
- /**
709
- * The accent axis.
710
- *
711
- * adea's accent presets, as a selection rather than a constant. `theme` is the
712
- * default and means "the variant's own primary" — monochrome in adea's palette —
713
- * and each named preset overrides the interactive roles through the
714
- * `[data-accent]` blocks in `theme.css`.
715
- *
716
- * These are the same six presets `accentPresets` exports in adea's own
717
- * `appearance.ts`, and the values match. A consumer's appearance picker and the
718
- * workshop's theme toolbar read this one list, so the two cannot disagree about
719
- * what a preset is called or what colour it is.
720
- */
721
- export type AccentPreset = {
722
- /** The `data-accent` value. `theme` is the variant's own primary. */
723
- id: string
724
- label: string
725
- /** What the preset is for, in the gallery and in a picker. */
726
- description: string
727
- /** The accent as it appears in the light theme. Absent for `theme`. */
728
- light?: string
729
- /** The accent as it appears in the dark theme. Absent for `theme`. */
730
- dark?: string
731
- }
732
-
733
- export const accentPresets: readonly AccentPreset[] = Object.freeze([
734
- {
735
- id: 'theme',
736
- label: 'Theme',
737
- description:
738
- "The variant's own primary. Neutral in adea's palette, so the interface stays monochrome.",
739
- },
740
- ...ACCENTS,
741
- ])
707
+ export { accentPresets, type AccentPreset } from './accent-presets'
742
708
 
743
709
  /** Every token, in gallery order. */
744
710
  export const designTokens = {
@@ -28,11 +28,26 @@
28
28
  "type": "registry:ui",
29
29
  "target": "components/theming/index.ts"
30
30
  },
31
+ {
32
+ "path": "src/components/theme/lazy.ts",
33
+ "type": "registry:ui",
34
+ "target": "components/theming/lazy.ts"
35
+ },
36
+ {
37
+ "path": "src/components/theme/theme-catalogue-source.ts",
38
+ "type": "registry:ui",
39
+ "target": "components/theming/theme-catalogue-source.ts"
40
+ },
31
41
  {
32
42
  "path": "src/components/theme/theme-context.ts",
33
43
  "type": "registry:ui",
34
44
  "target": "components/theming/theme-context.ts"
35
45
  },
46
+ {
47
+ "path": "src/components/theme/theme-document-core.ts",
48
+ "type": "registry:ui",
49
+ "target": "components/theming/theme-document-core.ts"
50
+ },
36
51
  {
37
52
  "path": "src/components/theme/theme-document.ts",
38
53
  "type": "registry:ui",
@@ -53,6 +68,21 @@
53
68
  "type": "registry:ui",
54
69
  "target": "components/theming/theme-picker.tsx"
55
70
  },
71
+ {
72
+ "path": "src/components/theme/theme-provider-core.tsx",
73
+ "type": "registry:ui",
74
+ "target": "components/theming/theme-provider-core.tsx"
75
+ },
76
+ {
77
+ "path": "src/components/theme/theme-provider-lazy.tsx",
78
+ "type": "registry:ui",
79
+ "target": "components/theming/theme-provider-lazy.tsx"
80
+ },
81
+ {
82
+ "path": "src/components/theme/theme-provider-value.ts",
83
+ "type": "registry:ui",
84
+ "target": "components/theming/theme-provider-value.ts"
85
+ },
56
86
  {
57
87
  "path": "src/components/theme/theme-provider.tsx",
58
88
  "type": "registry:ui",
@@ -63,6 +93,11 @@
63
93
  "type": "registry:ui",
64
94
  "target": "components/theming/theme-script.ts"
65
95
  },
96
+ {
97
+ "path": "src/components/theme/theme-state-core.ts",
98
+ "type": "registry:ui",
99
+ "target": "components/theming/theme-state-core.ts"
100
+ },
66
101
  {
67
102
  "path": "src/components/theme/theme-state.ts",
68
103
  "type": "registry:ui",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adea-ai/ui",
3
- "version": "0.128.1",
3
+ "version": "0.128.3",
4
4
  "description": "The Adea design system: Kobalte-backed Solid components, semantic OKLCH tokens, and the app-shell layout primitives shared by Adea and Cortana.",
5
5
  "keywords": [
6
6
  "adea",
@@ -74,6 +74,12 @@
74
74
  "./fonts.css": "./src/styles/fonts.css",
75
75
  "./registry.json": "./registry.json",
76
76
  "./package.json": "./package.json",
77
+ "./components/theme/lazy": {
78
+ "types": "./dist/components/theme/lazy.d.ts",
79
+ "solid": "./src/components/theme/lazy.ts",
80
+ "development": "./src/components/theme/lazy.ts",
81
+ "import": "./dist/components/theme/lazy.js"
82
+ },
77
83
  "./components/layout/split-layout/model": {
78
84
  "types": "./dist/components/layout/split-layout/model.d.ts",
79
85
  "solid": "./src/components/layout/split-layout/model.ts",
@@ -109,10 +115,13 @@
109
115
  "cn:check": "bun scripts/check-cn-tables.ts",
110
116
  "registry:build": "bun run cn:build && bun scripts/build-registry.ts",
111
117
  "registry:validate": "bun run cn:check && bun scripts/validate-registry.ts",
112
- "pack:check": "bun scripts/check-pack.ts",
113
- "check:tree-shaking": "bun scripts/check-tree-shaking.ts",
118
+ "pack:check": "bun scripts/check-pack.ts && bun scripts/check-lib-exports.ts",
119
+ "check:lib-exports": "bun scripts/check-lib-exports.ts",
120
+ "check:tree-shaking": "bun scripts/check-tree-shaking.ts && bun scripts/check-theme-startup.ts",
121
+ "check:theme-startup": "bun scripts/check-theme-startup.ts",
114
122
  "theme:build": "bun scripts/build-default-theme.ts",
115
123
  "theme:check": "bun scripts/build-default-theme.ts --check",
124
+ "theme:defaults": "bun scripts/build-theme-defaults.ts",
116
125
  "design-system:build": "bun scripts/design-system/build.ts",
117
126
  "check:packed-layout": "node --test scripts/check-packed-layout-process.test.mjs && node scripts/check-packed-layout.mjs && node scripts/check-packed-layout-tree.mjs",
118
127
  "check:packed-lint": "node scripts/check-packed-lint.mjs",
package/registry.json CHANGED
@@ -2527,11 +2527,26 @@
2527
2527
  "type": "registry:ui",
2528
2528
  "target": "components/theming/index.ts"
2529
2529
  },
2530
+ {
2531
+ "path": "src/components/theme/lazy.ts",
2532
+ "type": "registry:ui",
2533
+ "target": "components/theming/lazy.ts"
2534
+ },
2535
+ {
2536
+ "path": "src/components/theme/theme-catalogue-source.ts",
2537
+ "type": "registry:ui",
2538
+ "target": "components/theming/theme-catalogue-source.ts"
2539
+ },
2530
2540
  {
2531
2541
  "path": "src/components/theme/theme-context.ts",
2532
2542
  "type": "registry:ui",
2533
2543
  "target": "components/theming/theme-context.ts"
2534
2544
  },
2545
+ {
2546
+ "path": "src/components/theme/theme-document-core.ts",
2547
+ "type": "registry:ui",
2548
+ "target": "components/theming/theme-document-core.ts"
2549
+ },
2535
2550
  {
2536
2551
  "path": "src/components/theme/theme-document.ts",
2537
2552
  "type": "registry:ui",
@@ -2552,6 +2567,21 @@
2552
2567
  "type": "registry:ui",
2553
2568
  "target": "components/theming/theme-picker.tsx"
2554
2569
  },
2570
+ {
2571
+ "path": "src/components/theme/theme-provider-core.tsx",
2572
+ "type": "registry:ui",
2573
+ "target": "components/theming/theme-provider-core.tsx"
2574
+ },
2575
+ {
2576
+ "path": "src/components/theme/theme-provider-lazy.tsx",
2577
+ "type": "registry:ui",
2578
+ "target": "components/theming/theme-provider-lazy.tsx"
2579
+ },
2580
+ {
2581
+ "path": "src/components/theme/theme-provider-value.ts",
2582
+ "type": "registry:ui",
2583
+ "target": "components/theming/theme-provider-value.ts"
2584
+ },
2555
2585
  {
2556
2586
  "path": "src/components/theme/theme-provider.tsx",
2557
2587
  "type": "registry:ui",
@@ -2562,6 +2592,11 @@
2562
2592
  "type": "registry:ui",
2563
2593
  "target": "components/theming/theme-script.ts"
2564
2594
  },
2595
+ {
2596
+ "path": "src/components/theme/theme-state-core.ts",
2597
+ "type": "registry:ui",
2598
+ "target": "components/theming/theme-state-core.ts"
2599
+ },
2565
2600
  {
2566
2601
  "path": "src/components/theme/theme-state.ts",
2567
2602
  "type": "registry:ui",
@@ -2654,6 +2689,11 @@
2654
2689
  ],
2655
2690
  "registryDependencies": [],
2656
2691
  "files": [
2692
+ {
2693
+ "path": "src/lib/accent-presets.ts",
2694
+ "type": "registry:lib",
2695
+ "target": "lib/accent-presets.ts"
2696
+ },
2657
2697
  {
2658
2698
  "path": "src/lib/accent-roles.ts",
2659
2699
  "type": "registry:lib",
@@ -2719,6 +2759,36 @@
2719
2759
  "type": "registry:lib",
2720
2760
  "target": "lib/theme-accents.ts"
2721
2761
  },
2762
+ {
2763
+ "path": "src/lib/theme-catalogue.ts",
2764
+ "type": "registry:lib",
2765
+ "target": "lib/theme-catalogue.ts"
2766
+ },
2767
+ {
2768
+ "path": "src/lib/theme-css.ts",
2769
+ "type": "registry:lib",
2770
+ "target": "lib/theme-css.ts"
2771
+ },
2772
+ {
2773
+ "path": "src/lib/theme-defaults.generated.ts",
2774
+ "type": "registry:lib",
2775
+ "target": "lib/theme-defaults.generated.ts"
2776
+ },
2777
+ {
2778
+ "path": "src/lib/theme-defaults.ts",
2779
+ "type": "registry:lib",
2780
+ "target": "lib/theme-defaults.ts"
2781
+ },
2782
+ {
2783
+ "path": "src/lib/theme-engine-light.ts",
2784
+ "type": "registry:lib",
2785
+ "target": "lib/theme-engine-light.ts"
2786
+ },
2787
+ {
2788
+ "path": "src/lib/theme-engine.ts",
2789
+ "type": "registry:lib",
2790
+ "target": "lib/theme-engine.ts"
2791
+ },
2722
2792
  {
2723
2793
  "path": "src/lib/theme-surface.ts",
2724
2794
  "type": "registry:lib",
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The theme provider with the catalogue out of the start-up path.
3
+ *
4
+ * Everything here is free of the 34-theme catalogue: `import` this entry instead of
5
+ * `@adea-ai/ui/components/theme` in a host that paints its theme from a stylesheet.
6
+ * The catalogue loads, in a chunk of its own, the first time a stored or previewed
7
+ * theme needs it. See {@link ThemeProvider} for the rules and `docs/consumption.md`
8
+ * for the setup.
9
+ */
10
+ export { loadThemeCatalogue } from './theme-catalogue-source'
11
+ export { ThemeProvider } from './theme-provider-lazy'
12
+ export {
13
+ createVersionedPersistence,
14
+ defaultThemeSelection,
15
+ inlineScriptLiteral,
16
+ localStoragePersistence,
17
+ resolvedDensity,
18
+ themeScript,
19
+ useOptionalTheme,
20
+ useTheme,
21
+ type EditorRolesMode,
22
+ type ThemeCatalogueSource,
23
+ type ThemeContextValue,
24
+ type ThemeDensity,
25
+ type ThemePersistence,
26
+ type ThemeProviderProps,
27
+ type ThemeScriptOptions,
28
+ type ThemeSelection,
29
+ type ThemeStorageSchema,
30
+ type ThemeSurface,
31
+ type VersionedCodec,
32
+ type VersionedPersistenceOptions,
33
+ } from './theme-provider-core'
34
+ export { ThemeToggle, type ThemeToggleProps } from './theme-toggle'
35
+ export { ThemeModeToggle, type ThemeModeToggleProps } from './theme-mode-toggle'
@@ -0,0 +1,59 @@
1
+ import { createSignal } from 'solid-js'
2
+ import type { ThemeEngine } from '#lib/theme-engine'
3
+ import { lightThemeEngine } from '#lib/theme-engine-light'
4
+ import type { ThemeCatalogueSource } from './theme-provider-value'
5
+
6
+ /**
7
+ * The full catalogue engine once something has asked for it, shared by every lazy
8
+ * provider and every caller of {@link loadThemeCatalogue} in the page. A provider
9
+ * created after the load starts with it already in hand.
10
+ */
11
+ let loadedEngine: ThemeEngine | undefined
12
+ let loading: Promise<ThemeEngine> | undefined
13
+
14
+ /**
15
+ * Load the whole theme catalogue (about 129 KB raw, 34 KB gzipped) and resolve to the
16
+ * engine backed by it. Idempotent: every call shares one import, and a failed import is
17
+ * forgotten so the next call retries.
18
+ *
19
+ * The lazy provider calls this itself the moment a selection needs a theme beyond the
20
+ * default pair. Call it earlier — when a settings page mounts, or on hover of its
21
+ * entry — to have the picker ready by the time it opens.
22
+ */
23
+ export function loadThemeCatalogue(): Promise<ThemeEngine> {
24
+ if (loadedEngine) return Promise.resolve(loadedEngine)
25
+ loading ??= import('#lib/theme-catalogue').then(
26
+ (module) => {
27
+ loadedEngine = module.catalogueThemeEngine
28
+ return loadedEngine
29
+ },
30
+ (error: unknown) => {
31
+ loading = undefined
32
+ throw error
33
+ }
34
+ )
35
+ return loading
36
+ }
37
+
38
+ /** A catalogue source for one provider: the shipped defaults until the load resolves. */
39
+ export function createLazyCatalogue(): ThemeCatalogueSource {
40
+ const [full, setFull] = createSignal<ThemeEngine | undefined>(loadedEngine)
41
+ const [failed, setFailed] = createSignal(false)
42
+ const load = () =>
43
+ loadThemeCatalogue().then(
44
+ (loaded) => {
45
+ setFailed(false)
46
+ setFull(() => loaded)
47
+ },
48
+ () => {
49
+ // The theme the stylesheet painted stays; the next request retries.
50
+ setFailed(true)
51
+ }
52
+ )
53
+ return {
54
+ engine: () => full() ?? lightThemeEngine,
55
+ loaded: () => full() !== undefined,
56
+ failed,
57
+ load,
58
+ }
59
+ }