@12nil/theme-registry-package 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  isThemeTokensV2,
4
4
  themeRegistry,
5
5
  validateTheme
6
- } from "./chunk-GUPUN2GN.js";
6
+ } from "./chunk-4HGH6QM7.js";
7
7
 
8
8
  // theme-provider.tsx
9
9
  import { createContext, useContext, useEffect, useState, useCallback } from "react";
@@ -21,6 +21,16 @@ function semanticTokensToCSSVariables(tokens) {
21
21
  variables[`--theme-${category}-${keyName}`] = value;
22
22
  if (category === "colors") {
23
23
  variables[`--color-theme-${keyName}`] = value;
24
+ variables[`--theme-${keyName}`] = value;
25
+ }
26
+ if (category === "surface") {
27
+ variables[`--surface-${keyName}`] = value;
28
+ }
29
+ if (category === "text") {
30
+ variables[`--text-${keyName}`] = value;
31
+ }
32
+ if (category === "border") {
33
+ variables[`--border-${keyName}`] = value;
24
34
  }
25
35
  });
26
36
  };
@@ -35,7 +45,9 @@ function legacyTokensToCSSVariables(tokens) {
35
45
  Object.entries(tokens).forEach(([key, value]) => {
36
46
  if (key === "tertiary" && !value) return;
37
47
  if (!value) return;
38
- variables[`--color-theme-${String(key)}`] = value;
48
+ const keyName = String(key);
49
+ variables[`--color-theme-${keyName}`] = value;
50
+ variables[`--theme-${keyName}`] = value;
39
51
  });
40
52
  return variables;
41
53
  }
@@ -76,18 +88,87 @@ function applyThemeToDocument(theme, mode) {
76
88
  document.documentElement.style.setProperty(name, value);
77
89
  });
78
90
  }
91
+ function createTailwindThemeColorMap() {
92
+ return {
93
+ primary: "var(--theme-primary)",
94
+ secondary: "var(--theme-secondary)",
95
+ background: "var(--theme-background)",
96
+ text: "var(--theme-text)",
97
+ accent: "var(--theme-accent)",
98
+ muted: "var(--theme-muted)",
99
+ error: "var(--theme-error)",
100
+ warning: "var(--theme-warning)",
101
+ success: "var(--theme-success)",
102
+ info: "var(--theme-info)",
103
+ "surface-page": "var(--surface-page)",
104
+ "surface-card": "var(--surface-card)",
105
+ "surface-sidebar": "var(--surface-sidebar)",
106
+ "surface-modal": "var(--surface-modal)",
107
+ "surface-popover": "var(--surface-popover)",
108
+ "text-primary": "var(--text-primary)",
109
+ "text-secondary": "var(--text-secondary)",
110
+ "text-tertiary": "var(--text-tertiary)",
111
+ "text-disabled": "var(--text-disabled)",
112
+ "border-default": "var(--border-default)",
113
+ "border-subtle": "var(--border-subtle)",
114
+ "border-strong": "var(--border-strong)"
115
+ };
116
+ }
79
117
 
80
118
  // theme-provider.tsx
81
119
  import { jsx } from "react/jsx-runtime";
120
+ var THEME_UTILITY_STYLE_ID = "runtime-theme-registry-utility-classes";
121
+ var THEME_UTILITY_CSS = `
122
+ .bg-primary{background-color:var(--theme-primary)!important}
123
+ .bg-secondary{background-color:var(--theme-secondary)!important}
124
+ .bg-background{background-color:var(--theme-background)!important}
125
+ .bg-accent{background-color:var(--theme-accent)!important}
126
+ .bg-muted{background-color:var(--theme-muted)!important}
127
+ .bg-error{background-color:var(--theme-error)!important}
128
+ .bg-warning{background-color:var(--theme-warning)!important}
129
+ .bg-success{background-color:var(--theme-success)!important}
130
+ .bg-info{background-color:var(--theme-info)!important}
131
+ .bg-surface-card{background-color:var(--surface-card)!important}
132
+ .bg-surface-page{background-color:var(--surface-page)!important}
133
+
134
+ .text-primary{color:var(--theme-primary)!important}
135
+ .text-secondary{color:var(--theme-secondary)!important}
136
+ .text-background{color:var(--theme-background)!important}
137
+ .text-text{color:var(--theme-text)!important}
138
+ .text-accent{color:var(--theme-accent)!important}
139
+ .text-muted{color:var(--theme-muted)!important}
140
+ .text-error{color:var(--theme-error)!important}
141
+ .text-warning{color:var(--theme-warning)!important}
142
+ .text-success{color:var(--theme-success)!important}
143
+ .text-info{color:var(--theme-info)!important}
144
+ .text-text-primary{color:var(--text-primary)!important}
145
+ .text-text-secondary{color:var(--text-secondary)!important}
146
+ .text-text-tertiary{color:var(--text-tertiary)!important}
147
+ .text-text-disabled{color:var(--text-disabled)!important}
148
+
149
+ .border-border-default{border-color:var(--border-default)!important}
150
+ .border-border-subtle{border-color:var(--border-subtle)!important}
151
+ .border-border-strong{border-color:var(--border-strong)!important}
152
+ `;
82
153
  var ThemeContext = createContext(void 0);
83
- function ThemeProvider({ children }) {
154
+ function ThemeProvider({ children, injectUtilityClasses = true }) {
84
155
  const [currentTheme, setCurrentTheme] = useState(null);
85
156
  const [currentMode, setCurrentMode] = useState(null);
86
157
  const [themes, setThemes] = useState([]);
158
+ useEffect(() => {
159
+ if (!injectUtilityClasses) return;
160
+ if (typeof document === "undefined") return;
161
+ const existing = document.getElementById(THEME_UTILITY_STYLE_ID);
162
+ if (existing) return;
163
+ const style = document.createElement("style");
164
+ style.id = THEME_UTILITY_STYLE_ID;
165
+ style.textContent = THEME_UTILITY_CSS;
166
+ document.head.appendChild(style);
167
+ }, [injectUtilityClasses]);
87
168
  useEffect(() => {
88
169
  const registeredThemes = themeRegistry.getAll();
89
170
  if (registeredThemes.length === 0) {
90
- import("./app_theme-K3SQNO7I.js").then(() => {
171
+ import("./app_theme-ED547XU4.js").then(() => {
91
172
  setThemes(themeRegistry.getAll());
92
173
  });
93
174
  } else {
@@ -155,10 +236,153 @@ function useTheme() {
155
236
  }
156
237
  return context;
157
238
  }
239
+
240
+ // theme-switcher.tsx
241
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
242
+ function getDefaultModeForTheme(themes, themeName, fallbackMode) {
243
+ const nextTheme = themes.find((theme) => theme.name === themeName);
244
+ if (!nextTheme) return null;
245
+ if (fallbackMode && nextTheme.modes[fallbackMode]) {
246
+ return fallbackMode;
247
+ }
248
+ const firstMode = Object.keys(nextTheme.modes)[0];
249
+ return firstMode ?? null;
250
+ }
251
+ function ThemeSwitcher({
252
+ className,
253
+ themeLabel = "Theme",
254
+ modeLabel = "Mode",
255
+ showModeSelector = true,
256
+ idPrefix = "runtime-theme-switcher",
257
+ onThemeChanged,
258
+ onModeChanged
259
+ }) {
260
+ const { themes, currentTheme, currentMode, availableModes, setTheme, setMode } = useTheme();
261
+ if (themes.length === 0) {
262
+ return null;
263
+ }
264
+ const handleThemeChange = (event) => {
265
+ const nextThemeName = event.target.value;
266
+ const nextMode = getDefaultModeForTheme(themes, nextThemeName, currentMode);
267
+ if (!nextMode) return;
268
+ setTheme(nextThemeName, nextMode);
269
+ onThemeChanged?.(nextThemeName, nextMode);
270
+ };
271
+ const handleModeChange = (event) => {
272
+ const nextMode = event.target.value;
273
+ setMode(nextMode);
274
+ onModeChanged?.(nextMode);
275
+ };
276
+ const themeSelectId = `${idPrefix}-theme`;
277
+ const modeSelectId = `${idPrefix}-mode`;
278
+ return /* @__PURE__ */ jsxs("div", { className, children: [
279
+ /* @__PURE__ */ jsx2("label", { htmlFor: themeSelectId, children: themeLabel }),
280
+ /* @__PURE__ */ jsx2("select", { id: themeSelectId, value: currentTheme ?? "", onChange: handleThemeChange, children: themes.map((theme) => /* @__PURE__ */ jsx2("option", { value: theme.name, children: theme.name }, theme.name)) }),
281
+ showModeSelector ? /* @__PURE__ */ jsxs(Fragment, { children: [
282
+ /* @__PURE__ */ jsx2("label", { htmlFor: modeSelectId, children: modeLabel }),
283
+ /* @__PURE__ */ jsx2("select", { id: modeSelectId, value: currentMode ?? "", onChange: handleModeChange, children: availableModes.map((mode) => /* @__PURE__ */ jsx2("option", { value: mode, children: mode }, mode)) })
284
+ ] }) : null
285
+ ] });
286
+ }
287
+ function ThemeSwitcherStyled({
288
+ className,
289
+ title = "Theme",
290
+ subtitle = "Switch appearance and mode",
291
+ themeLabel = "Theme",
292
+ modeLabel = "Mode",
293
+ showModeSelector = true,
294
+ idPrefix = "runtime-theme-switcher-styled",
295
+ onThemeChanged,
296
+ onModeChanged
297
+ }) {
298
+ const { themes, currentTheme, currentMode, availableModes, setTheme, setMode } = useTheme();
299
+ if (themes.length === 0) {
300
+ return null;
301
+ }
302
+ const handleThemeChange = (event) => {
303
+ const nextThemeName = event.target.value;
304
+ const nextMode = getDefaultModeForTheme(themes, nextThemeName, currentMode);
305
+ if (!nextMode) return;
306
+ setTheme(nextThemeName, nextMode);
307
+ onThemeChanged?.(nextThemeName, nextMode);
308
+ };
309
+ const handleModeClick = (mode) => {
310
+ setMode(mode);
311
+ onModeChanged?.(mode);
312
+ };
313
+ const themeSelectId = `${idPrefix}-theme`;
314
+ return /* @__PURE__ */ jsxs(
315
+ "section",
316
+ {
317
+ className,
318
+ style: {
319
+ border: "1px solid var(--theme-border-subtle, #d1d5db)",
320
+ borderRadius: 12,
321
+ padding: 12,
322
+ background: "var(--theme-surface-card, var(--color-theme-background, #ffffff))",
323
+ color: "var(--theme-text-primary, var(--color-theme-text, #111827))",
324
+ display: "grid",
325
+ gap: 10,
326
+ maxWidth: 360
327
+ },
328
+ children: [
329
+ /* @__PURE__ */ jsxs("header", { style: { display: "grid", gap: 2 }, children: [
330
+ /* @__PURE__ */ jsx2("strong", { children: title }),
331
+ /* @__PURE__ */ jsx2("small", { style: { opacity: 0.8 }, children: subtitle })
332
+ ] }),
333
+ /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 6 }, children: [
334
+ /* @__PURE__ */ jsx2("label", { htmlFor: themeSelectId, children: themeLabel }),
335
+ /* @__PURE__ */ jsx2(
336
+ "select",
337
+ {
338
+ id: themeSelectId,
339
+ value: currentTheme ?? "",
340
+ onChange: handleThemeChange,
341
+ style: {
342
+ border: "1px solid var(--theme-border-default, #9ca3af)",
343
+ borderRadius: 8,
344
+ padding: "8px 10px",
345
+ background: "var(--theme-surface-page, var(--color-theme-background, #ffffff))",
346
+ color: "inherit"
347
+ },
348
+ children: themes.map((theme) => /* @__PURE__ */ jsx2("option", { value: theme.name, children: theme.name }, theme.name))
349
+ }
350
+ )
351
+ ] }),
352
+ showModeSelector ? /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 6 }, children: [
353
+ /* @__PURE__ */ jsx2("span", { children: modeLabel }),
354
+ /* @__PURE__ */ jsx2("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: availableModes.map((mode) => {
355
+ const isActive = mode === currentMode;
356
+ return /* @__PURE__ */ jsx2(
357
+ "button",
358
+ {
359
+ type: "button",
360
+ onClick: () => handleModeClick(mode),
361
+ style: {
362
+ border: "1px solid var(--theme-border-default, #9ca3af)",
363
+ borderRadius: 999,
364
+ padding: "6px 12px",
365
+ cursor: "pointer",
366
+ background: isActive ? "var(--theme-colors-primary, var(--color-theme-primary, #2563eb))" : "var(--theme-surface-page, var(--color-theme-background, #ffffff))",
367
+ color: isActive ? "var(--theme-surface-page, var(--color-theme-background, #ffffff))" : "inherit"
368
+ },
369
+ children: mode
370
+ },
371
+ mode
372
+ );
373
+ }) })
374
+ ] }) : null
375
+ ]
376
+ }
377
+ );
378
+ }
158
379
  export {
159
380
  RUNTIME_THEME_REGISTRY_VERSION,
160
381
  ThemeProvider,
382
+ ThemeSwitcher,
383
+ ThemeSwitcherStyled,
161
384
  applyThemeToDocument,
385
+ createTailwindThemeColorMap,
162
386
  themeRegistry as default,
163
387
  generateAllThemesCSS,
164
388
  generateThemeCSS,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../theme-provider.tsx","../theme-utils.ts"],"sourcesContent":["'use client'\r\n\r\nimport React, { createContext, useContext, useEffect, useState, useCallback } from 'react'\r\nimport { themeRegistry } from './theme-registry'\r\nimport type { ThemeDefinition, ThemeTokenSet } from './theme-registry'\r\nimport { tokenSetToCSSVariables } from './theme-utils'\r\nimport './app_theme'\r\n\r\ninterface ThemeContextType {\r\n currentTheme: string | null\r\n currentMode: string | null\r\n themes: ThemeDefinition[]\r\n setTheme: (themeName: string, mode: string) => void\r\n setMode: (mode: string) => void\r\n availableModes: string[]\r\n getThemeColors: () => ThemeTokenSet | null\r\n}\r\n\r\nconst ThemeContext = createContext<ThemeContextType | undefined>(undefined)\r\n\r\nexport function ThemeProvider({ children }: { children: React.ReactNode }) {\r\n const [currentTheme, setCurrentTheme] = useState<string | null>(null)\r\n const [currentMode, setCurrentMode] = useState<string | null>(null)\r\n const [themes, setThemes] = useState<ThemeDefinition[]>([])\r\n\r\n useEffect(() => {\r\n // Initialize themes from registry\r\n const registeredThemes = themeRegistry.getAll()\r\n \r\n // If no themes are registered, try to dynamically import app_theme\r\n if (registeredThemes.length === 0) {\r\n import('./app_theme').then(() => {\r\n setThemes(themeRegistry.getAll())\r\n })\r\n } else {\r\n setThemes(registeredThemes)\r\n }\r\n\r\n if (registeredThemes.length > 0) {\r\n // Try to load from localStorage\r\n const saved = localStorage.getItem('fnp-theme') as string | null\r\n const savedMode = localStorage.getItem('fnp-mode') as string | null\r\n\r\n const resolved = themeRegistry.resolveSelection(saved, savedMode)\r\n if (!resolved.themeName || !resolved.modeName || !resolved.tokens) return\r\n\r\n setCurrentTheme(resolved.themeName)\r\n setCurrentMode(resolved.modeName)\r\n themeRegistry.setCurrent(resolved.themeName, resolved.modeName)\r\n applyTheme(resolved.tokens)\r\n\r\n localStorage.setItem('fnp-theme', resolved.themeName)\r\n localStorage.setItem('fnp-mode', resolved.modeName)\r\n }\r\n }, [])\r\n\r\n const applyTheme = useCallback((tokens: ThemeTokenSet) => {\r\n const root = document.documentElement\r\n const variables = tokenSetToCSSVariables(tokens)\r\n Object.entries(variables).forEach(([name, value]) => {\r\n root.style.setProperty(name, value)\r\n })\r\n }, [])\r\n\r\n const setTheme = useCallback((themeName: string, mode: string) => {\r\n const resolved = themeRegistry.resolveSelection(themeName, mode)\r\n if (!resolved.themeName || !resolved.modeName || !resolved.tokens) return\r\n\r\n setCurrentTheme(resolved.themeName)\r\n setCurrentMode(resolved.modeName)\r\n themeRegistry.setCurrent(resolved.themeName, resolved.modeName)\r\n applyTheme(resolved.tokens)\r\n\r\n localStorage.setItem('fnp-theme', resolved.themeName)\r\n localStorage.setItem('fnp-mode', resolved.modeName)\r\n }, [applyTheme])\r\n\r\n const setMode = useCallback((mode: string) => {\r\n if (!currentTheme) return\r\n setTheme(currentTheme, mode)\r\n }, [currentTheme, setTheme])\r\n\r\n const getThemeColors = useCallback(() => {\r\n if (!currentTheme || !currentMode) return null\r\n return themeRegistry.getTokens(currentTheme, currentMode) ?? null\r\n }, [currentTheme, currentMode])\r\n\r\n const availableModes = currentTheme ? themeRegistry.getModes(currentTheme) : []\r\n\r\n return (\r\n <ThemeContext.Provider\r\n value={{\r\n currentTheme,\r\n currentMode,\r\n themes,\r\n setTheme,\r\n setMode,\r\n availableModes,\r\n getThemeColors,\r\n }}\r\n >\r\n {children}\r\n </ThemeContext.Provider>\r\n )\r\n}\r\n\r\nexport function useTheme() {\r\n const context = useContext(ThemeContext)\r\n if (context === undefined) {\r\n throw new Error('useTheme must be used within a ThemeProvider')\r\n }\r\n return context\r\n}","import type { ThemePalette, ThemeDefinition, ThemeTokenSet, ThemeTokensV2 } from './theme-registry'\r\nimport { isThemeTokensV2 } from './theme-registry'\r\n\r\nexport function paletteToCSSVariables(palette: ThemePalette): Record<string, string> {\r\n return tokenSetToCSSVariables(palette)\r\n}\r\n\r\nfunction semanticTokensToCSSVariables(tokens: ThemeTokensV2): Record<string, string> {\r\n const variables: Record<string, string> = {}\r\n\r\n const appendCategory = <T extends { [K in keyof T]: string }>(category: string, categoryValues: T) => {\r\n ;(Object.entries(categoryValues) as Array<[keyof T, string]>).forEach(([key, value]) => {\r\n const keyName = String(key)\r\n variables[`--theme-${category}-${keyName}`] = value\r\n\r\n // Keep color alias vars for easy migration from legacy palettes.\r\n if (category === 'colors') {\r\n variables[`--color-theme-${keyName}`] = value\r\n }\r\n })\r\n }\r\n\r\n appendCategory('colors', tokens.colors)\r\n appendCategory('surface', tokens.surface)\r\n appendCategory('text', tokens.text)\r\n appendCategory('border', tokens.border)\r\n\r\n return variables\r\n}\r\n\r\nfunction legacyTokensToCSSVariables(tokens: ThemePalette): Record<string, string> {\r\n const variables: Record<string, string> = {}\r\n\r\n ;(Object.entries(tokens) as Array<[keyof ThemePalette, string | undefined]>).forEach(([key, value]) => {\r\n if (key === 'tertiary' && !value) return\r\n if (!value) return\r\n variables[`--color-theme-${String(key)}`] = value\r\n })\r\n\r\n return variables\r\n}\r\n\r\nexport function tokenSetToCSSVariables(tokens: ThemeTokenSet): Record<string, string> {\r\n if (isThemeTokensV2(tokens)) {\r\n return semanticTokensToCSSVariables(tokens)\r\n }\r\n\r\n return legacyTokensToCSSVariables(tokens)\r\n}\r\n\r\nexport function generateThemeCSS(theme: ThemeDefinition): string {\r\n const modes = Object.entries(theme.modes)\r\n \r\n let css = `/* Theme: ${theme.name} */\\n`\r\n \r\n modes.forEach(([modeName, tokens]) => {\r\n css += `\\n[data-theme=\"${theme.name}\"][data-mode=\"${modeName}\"] {\\n`\r\n\r\n const variables = tokenSetToCSSVariables(tokens)\r\n Object.entries(variables).forEach(([name, value]) => {\r\n css += ` ${name}: ${value};\\n`\r\n })\r\n\r\n css += `}\\n`\r\n })\r\n\r\n return css\r\n}\r\n\r\nexport function generateAllThemesCSS(themes: ThemeDefinition[]): string {\r\n return themes.map(generateThemeCSS).join('\\n')\r\n}\r\n\r\nexport function applyThemeToDocument(theme: ThemeDefinition, mode: string) {\r\n const tokens = theme.modes[mode]\r\n if (!tokens) return\r\n\r\n document.documentElement.setAttribute('data-theme', theme.name)\r\n document.documentElement.setAttribute('data-mode', mode)\r\n\r\n const variables = tokenSetToCSSVariables(tokens)\r\n Object.entries(variables).forEach(([name, value]) => {\r\n document.documentElement.style.setProperty(name, value)\r\n })\r\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../theme-provider.tsx","../theme-utils.ts","../theme-switcher.tsx"],"sourcesContent":["'use client'\r\n\r\nimport React, { createContext, useContext, useEffect, useState, useCallback } from 'react'\r\nimport { themeRegistry } from './theme-registry'\r\nimport type { ThemeDefinition, ThemeTokenSet } from './theme-registry'\r\nimport { tokenSetToCSSVariables } from './theme-utils'\r\nimport './app_theme'\r\n\r\nconst THEME_UTILITY_STYLE_ID = 'runtime-theme-registry-utility-classes'\r\n\r\nconst THEME_UTILITY_CSS = `\r\n.bg-primary{background-color:var(--theme-primary)!important}\r\n.bg-secondary{background-color:var(--theme-secondary)!important}\r\n.bg-background{background-color:var(--theme-background)!important}\r\n.bg-accent{background-color:var(--theme-accent)!important}\r\n.bg-muted{background-color:var(--theme-muted)!important}\r\n.bg-error{background-color:var(--theme-error)!important}\r\n.bg-warning{background-color:var(--theme-warning)!important}\r\n.bg-success{background-color:var(--theme-success)!important}\r\n.bg-info{background-color:var(--theme-info)!important}\r\n.bg-surface-card{background-color:var(--surface-card)!important}\r\n.bg-surface-page{background-color:var(--surface-page)!important}\r\n\r\n.text-primary{color:var(--theme-primary)!important}\r\n.text-secondary{color:var(--theme-secondary)!important}\r\n.text-background{color:var(--theme-background)!important}\r\n.text-text{color:var(--theme-text)!important}\r\n.text-accent{color:var(--theme-accent)!important}\r\n.text-muted{color:var(--theme-muted)!important}\r\n.text-error{color:var(--theme-error)!important}\r\n.text-warning{color:var(--theme-warning)!important}\r\n.text-success{color:var(--theme-success)!important}\r\n.text-info{color:var(--theme-info)!important}\r\n.text-text-primary{color:var(--text-primary)!important}\r\n.text-text-secondary{color:var(--text-secondary)!important}\r\n.text-text-tertiary{color:var(--text-tertiary)!important}\r\n.text-text-disabled{color:var(--text-disabled)!important}\r\n\r\n.border-border-default{border-color:var(--border-default)!important}\r\n.border-border-subtle{border-color:var(--border-subtle)!important}\r\n.border-border-strong{border-color:var(--border-strong)!important}\r\n`\r\n\r\ninterface ThemeContextType {\r\n currentTheme: string | null\r\n currentMode: string | null\r\n themes: ThemeDefinition[]\r\n setTheme: (themeName: string, mode: string) => void\r\n setMode: (mode: string) => void\r\n availableModes: string[]\r\n getThemeColors: () => ThemeTokenSet | null\r\n}\r\n\r\nexport interface ThemeProviderProps {\r\n children: React.ReactNode\r\n injectUtilityClasses?: boolean\r\n}\r\n\r\nconst ThemeContext = createContext<ThemeContextType | undefined>(undefined)\r\n\r\nexport function ThemeProvider({ children, injectUtilityClasses = true }: ThemeProviderProps) {\r\n const [currentTheme, setCurrentTheme] = useState<string | null>(null)\r\n const [currentMode, setCurrentMode] = useState<string | null>(null)\r\n const [themes, setThemes] = useState<ThemeDefinition[]>([])\r\n\r\n useEffect(() => {\r\n if (!injectUtilityClasses) return\r\n if (typeof document === 'undefined') return\r\n\r\n const existing = document.getElementById(THEME_UTILITY_STYLE_ID)\r\n if (existing) return\r\n\r\n const style = document.createElement('style')\r\n style.id = THEME_UTILITY_STYLE_ID\r\n style.textContent = THEME_UTILITY_CSS\r\n document.head.appendChild(style)\r\n }, [injectUtilityClasses])\r\n\r\n useEffect(() => {\r\n // Initialize themes from registry\r\n const registeredThemes = themeRegistry.getAll()\r\n \r\n // If no themes are registered, try to dynamically import app_theme\r\n if (registeredThemes.length === 0) {\r\n import('./app_theme').then(() => {\r\n setThemes(themeRegistry.getAll())\r\n })\r\n } else {\r\n setThemes(registeredThemes)\r\n }\r\n\r\n if (registeredThemes.length > 0) {\r\n // Try to load from localStorage\r\n const saved = localStorage.getItem('fnp-theme') as string | null\r\n const savedMode = localStorage.getItem('fnp-mode') as string | null\r\n\r\n const resolved = themeRegistry.resolveSelection(saved, savedMode)\r\n if (!resolved.themeName || !resolved.modeName || !resolved.tokens) return\r\n\r\n setCurrentTheme(resolved.themeName)\r\n setCurrentMode(resolved.modeName)\r\n themeRegistry.setCurrent(resolved.themeName, resolved.modeName)\r\n applyTheme(resolved.tokens)\r\n\r\n localStorage.setItem('fnp-theme', resolved.themeName)\r\n localStorage.setItem('fnp-mode', resolved.modeName)\r\n }\r\n }, [])\r\n\r\n const applyTheme = useCallback((tokens: ThemeTokenSet) => {\r\n const root = document.documentElement\r\n const variables = tokenSetToCSSVariables(tokens)\r\n Object.entries(variables).forEach(([name, value]) => {\r\n root.style.setProperty(name, value)\r\n })\r\n }, [])\r\n\r\n const setTheme = useCallback((themeName: string, mode: string) => {\r\n const resolved = themeRegistry.resolveSelection(themeName, mode)\r\n if (!resolved.themeName || !resolved.modeName || !resolved.tokens) return\r\n\r\n setCurrentTheme(resolved.themeName)\r\n setCurrentMode(resolved.modeName)\r\n themeRegistry.setCurrent(resolved.themeName, resolved.modeName)\r\n applyTheme(resolved.tokens)\r\n\r\n localStorage.setItem('fnp-theme', resolved.themeName)\r\n localStorage.setItem('fnp-mode', resolved.modeName)\r\n }, [applyTheme])\r\n\r\n const setMode = useCallback((mode: string) => {\r\n if (!currentTheme) return\r\n setTheme(currentTheme, mode)\r\n }, [currentTheme, setTheme])\r\n\r\n const getThemeColors = useCallback(() => {\r\n if (!currentTheme || !currentMode) return null\r\n return themeRegistry.getTokens(currentTheme, currentMode) ?? null\r\n }, [currentTheme, currentMode])\r\n\r\n const availableModes = currentTheme ? themeRegistry.getModes(currentTheme) : []\r\n\r\n return (\r\n <ThemeContext.Provider\r\n value={{\r\n currentTheme,\r\n currentMode,\r\n themes,\r\n setTheme,\r\n setMode,\r\n availableModes,\r\n getThemeColors,\r\n }}\r\n >\r\n {children}\r\n </ThemeContext.Provider>\r\n )\r\n}\r\n\r\nexport function useTheme() {\r\n const context = useContext(ThemeContext)\r\n if (context === undefined) {\r\n throw new Error('useTheme must be used within a ThemeProvider')\r\n }\r\n return context\r\n}","import type { ThemePalette, ThemeDefinition, ThemeTokenSet, ThemeTokensV2 } from './theme-registry'\r\nimport { isThemeTokensV2 } from './theme-registry'\r\n\r\nexport interface TailwindThemeColorMap {\r\n [colorName: string]: string\r\n}\r\n\r\nexport function paletteToCSSVariables(palette: ThemePalette): Record<string, string> {\r\n return tokenSetToCSSVariables(palette)\r\n}\r\n\r\nfunction semanticTokensToCSSVariables(tokens: ThemeTokensV2): Record<string, string> {\r\n const variables: Record<string, string> = {}\r\n\r\n const appendCategory = <T extends { [K in keyof T]: string }>(category: string, categoryValues: T) => {\r\n ;(Object.entries(categoryValues) as Array<[keyof T, string]>).forEach(([key, value]) => {\r\n const keyName = String(key)\r\n variables[`--theme-${category}-${keyName}`] = value\r\n\r\n // Keep color alias vars for easy migration from legacy palettes.\r\n if (category === 'colors') {\r\n variables[`--color-theme-${keyName}`] = value\r\n variables[`--theme-${keyName}`] = value\r\n }\r\n\r\n if (category === 'surface') {\r\n variables[`--surface-${keyName}`] = value\r\n }\r\n\r\n if (category === 'text') {\r\n variables[`--text-${keyName}`] = value\r\n }\r\n\r\n if (category === 'border') {\r\n variables[`--border-${keyName}`] = value\r\n }\r\n })\r\n }\r\n\r\n appendCategory('colors', tokens.colors)\r\n appendCategory('surface', tokens.surface)\r\n appendCategory('text', tokens.text)\r\n appendCategory('border', tokens.border)\r\n\r\n return variables\r\n}\r\n\r\nfunction legacyTokensToCSSVariables(tokens: ThemePalette): Record<string, string> {\r\n const variables: Record<string, string> = {}\r\n\r\n ;(Object.entries(tokens) as Array<[keyof ThemePalette, string | undefined]>).forEach(([key, value]) => {\r\n if (key === 'tertiary' && !value) return\r\n if (!value) return\r\n const keyName = String(key)\r\n variables[`--color-theme-${keyName}`] = value\r\n variables[`--theme-${keyName}`] = value\r\n })\r\n\r\n return variables\r\n}\r\n\r\nexport function tokenSetToCSSVariables(tokens: ThemeTokenSet): Record<string, string> {\r\n if (isThemeTokensV2(tokens)) {\r\n return semanticTokensToCSSVariables(tokens)\r\n }\r\n\r\n return legacyTokensToCSSVariables(tokens)\r\n}\r\n\r\nexport function generateThemeCSS(theme: ThemeDefinition): string {\r\n const modes = Object.entries(theme.modes)\r\n \r\n let css = `/* Theme: ${theme.name} */\\n`\r\n \r\n modes.forEach(([modeName, tokens]) => {\r\n css += `\\n[data-theme=\"${theme.name}\"][data-mode=\"${modeName}\"] {\\n`\r\n\r\n const variables = tokenSetToCSSVariables(tokens)\r\n Object.entries(variables).forEach(([name, value]) => {\r\n css += ` ${name}: ${value};\\n`\r\n })\r\n\r\n css += `}\\n`\r\n })\r\n\r\n return css\r\n}\r\n\r\nexport function generateAllThemesCSS(themes: ThemeDefinition[]): string {\r\n return themes.map(generateThemeCSS).join('\\n')\r\n}\r\n\r\nexport function applyThemeToDocument(theme: ThemeDefinition, mode: string) {\r\n const tokens = theme.modes[mode]\r\n if (!tokens) return\r\n\r\n document.documentElement.setAttribute('data-theme', theme.name)\r\n document.documentElement.setAttribute('data-mode', mode)\r\n\r\n const variables = tokenSetToCSSVariables(tokens)\r\n Object.entries(variables).forEach(([name, value]) => {\r\n document.documentElement.style.setProperty(name, value)\r\n })\r\n}\r\n\r\n/**\r\n * Tailwind-friendly color map, so consumers can use classes like bg-primary/text-muted.\r\n */\r\nexport function createTailwindThemeColorMap(): TailwindThemeColorMap {\r\n return {\r\n primary: 'var(--theme-primary)',\r\n secondary: 'var(--theme-secondary)',\r\n background: 'var(--theme-background)',\r\n text: 'var(--theme-text)',\r\n accent: 'var(--theme-accent)',\r\n muted: 'var(--theme-muted)',\r\n error: 'var(--theme-error)',\r\n warning: 'var(--theme-warning)',\r\n success: 'var(--theme-success)',\r\n info: 'var(--theme-info)',\r\n 'surface-page': 'var(--surface-page)',\r\n 'surface-card': 'var(--surface-card)',\r\n 'surface-sidebar': 'var(--surface-sidebar)',\r\n 'surface-modal': 'var(--surface-modal)',\r\n 'surface-popover': 'var(--surface-popover)',\r\n 'text-primary': 'var(--text-primary)',\r\n 'text-secondary': 'var(--text-secondary)',\r\n 'text-tertiary': 'var(--text-tertiary)',\r\n 'text-disabled': 'var(--text-disabled)',\r\n 'border-default': 'var(--border-default)',\r\n 'border-subtle': 'var(--border-subtle)',\r\n 'border-strong': 'var(--border-strong)',\r\n }\r\n}","'use client'\r\n\r\nimport React from 'react'\r\nimport { useTheme } from './theme-provider'\r\n\r\nexport interface ThemeSwitcherProps {\r\n className?: string\r\n themeLabel?: string\r\n modeLabel?: string\r\n showModeSelector?: boolean\r\n idPrefix?: string\r\n onThemeChanged?: (themeName: string, modeName: string) => void\r\n onModeChanged?: (modeName: string) => void\r\n}\r\n\r\nexport interface StyledThemeSwitcherProps extends ThemeSwitcherProps {\r\n title?: string\r\n subtitle?: string\r\n}\r\n\r\nfunction getDefaultModeForTheme(\r\n themes: ReturnType<typeof useTheme>['themes'],\r\n themeName: string,\r\n fallbackMode: string | null,\r\n): string | null {\r\n const nextTheme = themes.find((theme) => theme.name === themeName)\r\n if (!nextTheme) return null\r\n\r\n if (fallbackMode && nextTheme.modes[fallbackMode]) {\r\n return fallbackMode\r\n }\r\n\r\n const firstMode = Object.keys(nextTheme.modes)[0]\r\n return firstMode ?? null\r\n}\r\n\r\nexport function ThemeSwitcher({\r\n className,\r\n themeLabel = 'Theme',\r\n modeLabel = 'Mode',\r\n showModeSelector = true,\r\n idPrefix = 'runtime-theme-switcher',\r\n onThemeChanged,\r\n onModeChanged,\r\n}: ThemeSwitcherProps) {\r\n const { themes, currentTheme, currentMode, availableModes, setTheme, setMode } = useTheme()\r\n\r\n if (themes.length === 0) {\r\n return null\r\n }\r\n\r\n const handleThemeChange = (event: React.ChangeEvent<HTMLSelectElement>) => {\r\n const nextThemeName = event.target.value\r\n const nextMode = getDefaultModeForTheme(themes, nextThemeName, currentMode)\r\n if (!nextMode) return\r\n\r\n setTheme(nextThemeName, nextMode)\r\n onThemeChanged?.(nextThemeName, nextMode)\r\n }\r\n\r\n const handleModeChange = (event: React.ChangeEvent<HTMLSelectElement>) => {\r\n const nextMode = event.target.value\r\n setMode(nextMode)\r\n onModeChanged?.(nextMode)\r\n }\r\n\r\n const themeSelectId = `${idPrefix}-theme`\r\n const modeSelectId = `${idPrefix}-mode`\r\n\r\n return (\r\n <div className={className}>\r\n <label htmlFor={themeSelectId}>{themeLabel}</label>\r\n <select id={themeSelectId} value={currentTheme ?? ''} onChange={handleThemeChange}>\r\n {themes.map((theme) => (\r\n <option key={theme.name} value={theme.name}>\r\n {theme.name}\r\n </option>\r\n ))}\r\n </select>\r\n\r\n {showModeSelector ? (\r\n <>\r\n <label htmlFor={modeSelectId}>{modeLabel}</label>\r\n <select id={modeSelectId} value={currentMode ?? ''} onChange={handleModeChange}>\r\n {availableModes.map((mode) => (\r\n <option key={mode} value={mode}>\r\n {mode}\r\n </option>\r\n ))}\r\n </select>\r\n </>\r\n ) : null}\r\n </div>\r\n )\r\n}\r\n\r\nexport function ThemeSwitcherStyled({\r\n className,\r\n title = 'Theme',\r\n subtitle = 'Switch appearance and mode',\r\n themeLabel = 'Theme',\r\n modeLabel = 'Mode',\r\n showModeSelector = true,\r\n idPrefix = 'runtime-theme-switcher-styled',\r\n onThemeChanged,\r\n onModeChanged,\r\n}: StyledThemeSwitcherProps) {\r\n const { themes, currentTheme, currentMode, availableModes, setTheme, setMode } = useTheme()\r\n\r\n if (themes.length === 0) {\r\n return null\r\n }\r\n\r\n const handleThemeChange = (event: React.ChangeEvent<HTMLSelectElement>) => {\r\n const nextThemeName = event.target.value\r\n const nextMode = getDefaultModeForTheme(themes, nextThemeName, currentMode)\r\n if (!nextMode) return\r\n\r\n setTheme(nextThemeName, nextMode)\r\n onThemeChanged?.(nextThemeName, nextMode)\r\n }\r\n\r\n const handleModeClick = (mode: string) => {\r\n setMode(mode)\r\n onModeChanged?.(mode)\r\n }\r\n\r\n const themeSelectId = `${idPrefix}-theme`\r\n\r\n return (\r\n <section\r\n className={className}\r\n style={{\r\n border: '1px solid var(--theme-border-subtle, #d1d5db)',\r\n borderRadius: 12,\r\n padding: 12,\r\n background: 'var(--theme-surface-card, var(--color-theme-background, #ffffff))',\r\n color: 'var(--theme-text-primary, var(--color-theme-text, #111827))',\r\n display: 'grid',\r\n gap: 10,\r\n maxWidth: 360,\r\n }}\r\n >\r\n <header style={{ display: 'grid', gap: 2 }}>\r\n <strong>{title}</strong>\r\n <small style={{ opacity: 0.8 }}>{subtitle}</small>\r\n </header>\r\n\r\n <div style={{ display: 'grid', gap: 6 }}>\r\n <label htmlFor={themeSelectId}>{themeLabel}</label>\r\n <select\r\n id={themeSelectId}\r\n value={currentTheme ?? ''}\r\n onChange={handleThemeChange}\r\n style={{\r\n border: '1px solid var(--theme-border-default, #9ca3af)',\r\n borderRadius: 8,\r\n padding: '8px 10px',\r\n background: 'var(--theme-surface-page, var(--color-theme-background, #ffffff))',\r\n color: 'inherit',\r\n }}\r\n >\r\n {themes.map((theme) => (\r\n <option key={theme.name} value={theme.name}>\r\n {theme.name}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n {showModeSelector ? (\r\n <div style={{ display: 'grid', gap: 6 }}>\r\n <span>{modeLabel}</span>\r\n <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>\r\n {availableModes.map((mode) => {\r\n const isActive = mode === currentMode\r\n return (\r\n <button\r\n key={mode}\r\n type=\"button\"\r\n onClick={() => handleModeClick(mode)}\r\n style={{\r\n border: '1px solid var(--theme-border-default, #9ca3af)',\r\n borderRadius: 999,\r\n padding: '6px 12px',\r\n cursor: 'pointer',\r\n background: isActive\r\n ? 'var(--theme-colors-primary, var(--color-theme-primary, #2563eb))'\r\n : 'var(--theme-surface-page, var(--color-theme-background, #ffffff))',\r\n color: isActive\r\n ? 'var(--theme-surface-page, var(--color-theme-background, #ffffff))'\r\n : 'inherit',\r\n }}\r\n >\r\n {mode}\r\n </button>\r\n )\r\n })}\r\n </div>\r\n </div>\r\n ) : null}\r\n </section>\r\n )\r\n}\r\n"],"mappings":"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","names":["jsx"]}
package/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "@12nil/theme-registry-package",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Theme registry and React provider utilities",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "./dist/index.cjs",
8
8
  "module": "./dist/index.js",
9
9
  "types": "./dist/index.d.ts",
10
+ "bin": {
11
+ "runtime-theme-registry": "./bin/runtime-theme-registry.mjs"
12
+ },
10
13
  "exports": {
11
14
  ".": {
12
15
  "types": "./dist/index.d.ts",
@@ -16,6 +19,7 @@
16
19
  },
17
20
  "files": [
18
21
  "dist",
22
+ "bin",
19
23
  "README.md",
20
24
  "LICENSE"
21
25
  ],
@@ -1,7 +0,0 @@
1
- import {
2
- themeRegistry
3
- } from "./chunk-GUPUN2GN.js";
4
- export {
5
- themeRegistry
6
- };
7
- //# sourceMappingURL=app_theme-K3SQNO7I.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../theme-registry.ts","../app_theme.ts"],"sourcesContent":["export const RUNTIME_THEME_REGISTRY_VERSION = '0.2.0'\r\n\r\nexport interface ThemePalette {\r\n primary: string\r\n secondary: string\r\n tertiary?: string\r\n background: string\r\n text: string\r\n accent: string\r\n muted: string\r\n error: string\r\n warning: string\r\n success: string\r\n info: string\r\n}\r\n\r\nexport interface SemanticColorTokens {\r\n primary: string\r\n secondary: string\r\n destructive: string\r\n success: string\r\n warning: string\r\n info: string\r\n}\r\n\r\nexport interface SemanticSurfaceTokens {\r\n page: string\r\n card: string\r\n sidebar: string\r\n modal: string\r\n popover: string\r\n}\r\n\r\nexport interface SemanticTextTokens {\r\n primary: string\r\n secondary: string\r\n tertiary: string\r\n disabled: string\r\n}\r\n\r\nexport interface SemanticBorderTokens {\r\n default: string\r\n subtle: string\r\n strong: string\r\n}\r\n\r\nexport interface ThemeTokensV2 {\r\n colors: SemanticColorTokens\r\n surface: SemanticSurfaceTokens\r\n text: SemanticTextTokens\r\n border: SemanticBorderTokens\r\n}\r\n\r\nexport type ThemeTokenSet = ThemePalette | ThemeTokensV2\r\n\r\nexport interface ThemeCompatibility {\r\n minRegistryVersion?: string\r\n}\r\n\r\nexport interface ThemeMetadata {\r\n author?: string\r\n version?: string\r\n description?: string\r\n homepage?: string\r\n license?: string\r\n compatibility?: ThemeCompatibility\r\n}\r\n\r\nexport interface ThemeDefinition {\r\n name: string\r\n modes: Record<string, ThemeTokenSet>\r\n metadata?: ThemeMetadata\r\n}\r\n\r\nexport type ThemeRegistrationConflict = 'throw' | 'replace' | 'merge'\r\n\r\nexport interface ThemeRegistrationOptions {\r\n ifExists?: ThemeRegistrationConflict\r\n validate?: boolean\r\n}\r\n\r\nexport interface ThemeFallbackConfig {\r\n themeName?: string\r\n modeName?: string\r\n}\r\n\r\nexport interface ThemeValidationIssue {\r\n path: string\r\n message: string\r\n}\r\n\r\nexport interface ThemeValidationResult {\r\n valid: boolean\r\n issues: ThemeValidationIssue[]\r\n}\r\n\r\nexport interface ThemeResolutionResult {\r\n themeName: string | null\r\n modeName: string | null\r\n tokens: ThemeTokenSet | null\r\n}\r\n\r\nexport interface ThemePluginDefinition {\r\n name: string\r\n version?: string\r\n description?: string\r\n author?: string\r\n homepage?: string\r\n license?: string\r\n minRegistryVersion?: string\r\n theme?: ThemeDefinition\r\n themes?: ThemeDefinition[]\r\n icons?: Record<string, string>\r\n fonts?: Record<string, string>\r\n spacing?: Record<string, string | number>\r\n typography?: Record<string, string | number>\r\n metadata?: Record<string, unknown>\r\n}\r\n\r\nexport interface ThemePluginContributions {\r\n icons: Record<string, string>\r\n fonts: Record<string, string>\r\n spacing: Record<string, string | number>\r\n typography: Record<string, string | number>\r\n metadata: Record<string, unknown>\r\n}\r\n\r\nexport type ThemeCompositionLayerType = 'brand' | 'appearance' | 'accessibility'\r\n\r\nexport interface ThemeCompositionLayerDefinition {\r\n type: ThemeCompositionLayerType\r\n name: string\r\n tokens: ThemeTokenSet\r\n metadata?: Record<string, unknown>\r\n}\r\n\r\nexport interface ThemeCompositionSelection {\r\n brand?: string | null\r\n appearance?: string | null\r\n accessibility?: string | null\r\n}\r\n\r\nexport interface ThemeCompositionResult {\r\n selection: ThemeCompositionSelection\r\n tokens: ThemeTokenSet | null\r\n appliedLayers: ThemeCompositionLayerDefinition[]\r\n}\r\n\r\nexport type ThemeLoadSource = string | (() => Promise<ThemeDefinition | ThemeDefinition[]>)\r\n\r\nexport interface ThemeLoadOptions {\r\n ifExists?: ThemeRegistrationConflict\r\n validate?: boolean\r\n cacheKey?: string\r\n maxAgeMs?: number\r\n forceRefresh?: boolean\r\n}\r\n\r\nexport interface ThemeLoadResult {\r\n loaded: number\r\n themes: string[]\r\n source: string\r\n fromCache: boolean\r\n}\r\n\r\nexport interface ThemeLoadCacheEntry {\r\n themes: ThemeDefinition[]\r\n loadedAt: number\r\n source: string\r\n}\r\n\r\nexport interface ThemeDocumentAttributes {\r\n 'data-theme': string\r\n 'data-mode': string\r\n}\r\n\r\nexport type PluginRegistrationConflict = 'throw' | 'replace' | 'merge'\r\n\r\nexport interface PluginRegistrationOptions {\r\n ifExists?: PluginRegistrationConflict\r\n themeIfExists?: ThemeRegistrationConflict\r\n validateThemes?: boolean\r\n}\r\n\r\nexport interface ThemeRegistryEventPayloadMap {\r\n registered: { themeName: string }\r\n replaced: { themeName: string }\r\n merged: { themeName: string }\r\n unregistered: { themeName: string }\r\n variantAdded: { themeName: string; variantName: string }\r\n themeChanged: { themeName: string; modeName: string }\r\n loaded: { source: string; count: number; fromCache: boolean }\r\n composed: { appliedLayers: string[] }\r\n pluginRegistered: { pluginName: string }\r\n pluginUnregistered: { pluginName: string }\r\n destroyed: { timestamp: string }\r\n}\r\n\r\nexport type ThemeRegistryEvent = keyof ThemeRegistryEventPayloadMap\r\nexport type ThemeRegistryEventHandler<K extends ThemeRegistryEvent> = (payload: ThemeRegistryEventPayloadMap[K]) => void\r\n\r\nconst LEGACY_REQUIRED_KEYS = ['primary', 'secondary', 'background', 'text', 'accent', 'muted', 'error', 'warning', 'success', 'info'] as const\r\nconst LEGACY_ALLOWED_KEYS = [...LEGACY_REQUIRED_KEYS, 'tertiary'] as const\r\n\r\nconst SEMANTIC_SCHEMA: Record<string, readonly string[]> = {\r\n colors: ['primary', 'secondary', 'destructive', 'success', 'warning', 'info'],\r\n surface: ['page', 'card', 'sidebar', 'modal', 'popover'],\r\n text: ['primary', 'secondary', 'tertiary', 'disabled'],\r\n border: ['default', 'subtle', 'strong'],\r\n}\r\n\r\nfunction isRecord(value: unknown): value is Record<string, unknown> {\r\n return typeof value === 'object' && value !== null && !Array.isArray(value)\r\n}\r\n\r\nfunction isLikelyColor(value: string): boolean {\r\n const trimmed = value.trim()\r\n return (\r\n /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(trimmed) ||\r\n /^rgba?\\(.+\\)$/.test(trimmed) ||\r\n /^hsla?\\(.+\\)$/.test(trimmed) ||\r\n /^var\\(--.+\\)$/.test(trimmed) ||\r\n /^[a-zA-Z]+$/.test(trimmed)\r\n )\r\n}\r\n\r\nfunction parseSemver(version: string): [number, number, number] | null {\r\n const normalized = version.split('-')[0]\r\n const parts = normalized.split('.')\r\n if (parts.length < 3) return null\r\n\r\n const major = Number(parts[0])\r\n const minor = Number(parts[1])\r\n const patch = Number(parts[2])\r\n\r\n if (Number.isNaN(major) || Number.isNaN(minor) || Number.isNaN(patch)) {\r\n return null\r\n }\r\n\r\n return [major, minor, patch]\r\n}\r\n\r\nfunction compareSemver(a: string, b: string): number {\r\n const av = parseSemver(a)\r\n const bv = parseSemver(b)\r\n if (!av || !bv) return 0\r\n\r\n for (let i = 0; i < 3; i += 1) {\r\n if (av[i] > bv[i]) return 1\r\n if (av[i] < bv[i]) return -1\r\n }\r\n\r\n return 0\r\n}\r\n\r\nfunction assertCompatibility(minVersion: string | undefined, label: string) {\r\n if (!minVersion) return\r\n\r\n if (compareSemver(RUNTIME_THEME_REGISTRY_VERSION, minVersion) < 0) {\r\n throw new Error(\r\n `${label} requires Runtime Theme Registry >= ${minVersion}, current version is ${RUNTIME_THEME_REGISTRY_VERSION}`,\r\n )\r\n }\r\n}\r\n\r\nfunction validateMetadata(metadata: ThemeMetadata | undefined): ThemeValidationIssue[] {\r\n const issues: ThemeValidationIssue[] = []\r\n if (!metadata) return issues\r\n\r\n if (metadata.version && !parseSemver(metadata.version)) {\r\n issues.push({ path: 'theme.metadata.version', message: 'Expected semver format like 1.0.0' })\r\n }\r\n\r\n if (metadata.compatibility?.minRegistryVersion && !parseSemver(metadata.compatibility.minRegistryVersion)) {\r\n issues.push({ path: 'theme.metadata.compatibility.minRegistryVersion', message: 'Expected semver format like 1.0.0' })\r\n }\r\n\r\n return issues\r\n}\r\n\r\nexport function isThemeTokensV2(tokens: ThemeTokenSet): tokens is ThemeTokensV2 {\r\n return isRecord(tokens) && 'colors' in tokens && 'surface' in tokens && 'text' in tokens && 'border' in tokens\r\n}\r\n\r\nfunction validateLegacyTokens(tokens: Record<string, unknown>, modePath: string): ThemeValidationIssue[] {\r\n const issues: ThemeValidationIssue[] = []\r\n\r\n for (const key of LEGACY_REQUIRED_KEYS) {\r\n if (!(key in tokens)) {\r\n issues.push({ path: `${modePath}.${key}`, message: 'Missing required token' })\r\n }\r\n }\r\n\r\n for (const [key, value] of Object.entries(tokens)) {\r\n if (!LEGACY_ALLOWED_KEYS.includes(key as (typeof LEGACY_ALLOWED_KEYS)[number])) {\r\n issues.push({ path: `${modePath}.${key}`, message: 'Unknown token property' })\r\n continue\r\n }\r\n\r\n if (typeof value !== 'string' || !isLikelyColor(value)) {\r\n issues.push({ path: `${modePath}.${key}`, message: 'Invalid color value' })\r\n }\r\n }\r\n\r\n return issues\r\n}\r\n\r\nfunction validateSemanticTokens(tokens: Record<string, unknown>, modePath: string): ThemeValidationIssue[] {\r\n const issues: ThemeValidationIssue[] = []\r\n\r\n for (const category of Object.keys(SEMANTIC_SCHEMA)) {\r\n if (!(category in tokens)) {\r\n issues.push({ path: `${modePath}.${category}`, message: 'Missing required category' })\r\n continue\r\n }\r\n\r\n const categoryValue = tokens[category]\r\n if (!isRecord(categoryValue)) {\r\n issues.push({ path: `${modePath}.${category}`, message: 'Category must be an object' })\r\n continue\r\n }\r\n\r\n const requiredKeys = SEMANTIC_SCHEMA[category]\r\n for (const key of requiredKeys) {\r\n if (!(key in categoryValue)) {\r\n issues.push({ path: `${modePath}.${category}.${key}`, message: 'Missing required token' })\r\n }\r\n }\r\n\r\n for (const [key, value] of Object.entries(categoryValue)) {\r\n if (!requiredKeys.includes(key)) {\r\n issues.push({ path: `${modePath}.${category}.${key}`, message: 'Unknown token property' })\r\n continue\r\n }\r\n\r\n if (typeof value !== 'string' || !isLikelyColor(value)) {\r\n issues.push({ path: `${modePath}.${category}.${key}`, message: 'Invalid color value' })\r\n }\r\n }\r\n }\r\n\r\n for (const key of Object.keys(tokens)) {\r\n if (!(key in SEMANTIC_SCHEMA)) {\r\n issues.push({ path: `${modePath}.${key}`, message: 'Unknown category' })\r\n }\r\n }\r\n\r\n return issues\r\n}\r\n\r\nexport function validateTheme(theme: ThemeDefinition): ThemeValidationResult {\r\n const issues: ThemeValidationIssue[] = []\r\n\r\n if (!theme.name || !theme.name.trim()) {\r\n issues.push({ path: 'theme.name', message: 'Theme name is required' })\r\n }\r\n\r\n issues.push(...validateMetadata(theme.metadata))\r\n\r\n if (!isRecord(theme.modes) || Object.keys(theme.modes).length === 0) {\r\n issues.push({ path: 'theme.modes', message: 'At least one mode is required' })\r\n return { valid: issues.length === 0, issues }\r\n }\r\n\r\n for (const [modeName, tokens] of Object.entries(theme.modes)) {\r\n const modePath = `theme.modes.${modeName}`\r\n\r\n if (!isRecord(tokens)) {\r\n issues.push({ path: modePath, message: 'Mode tokens must be an object' })\r\n continue\r\n }\r\n\r\n if (isThemeTokensV2(tokens as ThemeTokenSet)) {\r\n issues.push(...validateSemanticTokens(tokens, modePath))\r\n } else {\r\n issues.push(...validateLegacyTokens(tokens, modePath))\r\n }\r\n }\r\n\r\n return {\r\n valid: issues.length === 0,\r\n issues,\r\n }\r\n}\r\n\r\nfunction mergeTokenSets(existing: ThemeTokenSet, incoming: ThemeTokenSet): ThemeTokenSet {\r\n if (isThemeTokensV2(existing) && isThemeTokensV2(incoming)) {\r\n return {\r\n colors: { ...existing.colors, ...incoming.colors },\r\n surface: { ...existing.surface, ...incoming.surface },\r\n text: { ...existing.text, ...incoming.text },\r\n border: { ...existing.border, ...incoming.border },\r\n }\r\n }\r\n\r\n return { ...existing, ...incoming }\r\n}\r\n\r\nfunction mergePlugins(existing: ThemePluginDefinition, incoming: ThemePluginDefinition): ThemePluginDefinition {\r\n return {\r\n ...existing,\r\n ...incoming,\r\n icons: { ...(existing.icons ?? {}), ...(incoming.icons ?? {}) },\r\n fonts: { ...(existing.fonts ?? {}), ...(incoming.fonts ?? {}) },\r\n spacing: { ...(existing.spacing ?? {}), ...(incoming.spacing ?? {}) },\r\n typography: { ...(existing.typography ?? {}), ...(incoming.typography ?? {}) },\r\n metadata: { ...(existing.metadata ?? {}), ...(incoming.metadata ?? {}) },\r\n }\r\n}\r\n\r\nfunction toPluginContributions(plugin: ThemePluginDefinition): ThemePluginContributions {\r\n return {\r\n icons: { ...(plugin.icons ?? {}) },\r\n fonts: { ...(plugin.fonts ?? {}) },\r\n spacing: { ...(plugin.spacing ?? {}) },\r\n typography: { ...(plugin.typography ?? {}) },\r\n metadata: { ...(plugin.metadata ?? {}) },\r\n }\r\n}\r\n\r\nfunction mergePluginContributions(\r\n target: ThemePluginContributions,\r\n source: ThemePluginContributions,\r\n): ThemePluginContributions {\r\n return {\r\n icons: { ...target.icons, ...source.icons },\r\n fonts: { ...target.fonts, ...source.fonts },\r\n spacing: { ...target.spacing, ...source.spacing },\r\n typography: { ...target.typography, ...source.typography },\r\n metadata: { ...target.metadata, ...source.metadata },\r\n }\r\n}\r\n\r\nfunction createEmptyContributions(): ThemePluginContributions {\r\n return {\r\n icons: {},\r\n fonts: {},\r\n spacing: {},\r\n typography: {},\r\n metadata: {},\r\n }\r\n}\r\n\r\nfunction createCompositionLayerMaps(): Record<ThemeCompositionLayerType, Map<string, ThemeCompositionLayerDefinition>> {\r\n return {\r\n brand: new Map(),\r\n appearance: new Map(),\r\n accessibility: new Map(),\r\n }\r\n}\r\n\r\nfunction normalizeLoadedThemes(payload: ThemeDefinition | ThemeDefinition[]): ThemeDefinition[] {\r\n return Array.isArray(payload) ? payload : [payload]\r\n}\r\n\r\nfunction tokenSetToCssVariables(tokens: ThemeTokenSet): Record<string, string> {\r\n const variables: Record<string, string> = {}\r\n\r\n if (isThemeTokensV2(tokens)) {\r\n const appendCategory = <T extends { [K in keyof T]: string }>(category: string, categoryValues: T) => {\r\n ;(Object.entries(categoryValues) as Array<[keyof T, string]>).forEach(([key, value]) => {\r\n const keyName = String(key)\r\n variables[`--theme-${category}-${keyName}`] = value\r\n if (category === 'colors') {\r\n variables[`--color-theme-${keyName}`] = value\r\n }\r\n })\r\n }\r\n\r\n appendCategory('colors', tokens.colors)\r\n appendCategory('surface', tokens.surface)\r\n appendCategory('text', tokens.text)\r\n appendCategory('border', tokens.border)\r\n\r\n return variables\r\n }\r\n\r\n Object.entries(tokens).forEach(([key, value]) => {\r\n if (key === 'tertiary' && !value) return\r\n variables[`--color-theme-${key}`] = value\r\n })\r\n\r\n return variables\r\n}\r\n\r\nfunction isCacheEntryFresh(entry: ThemeLoadCacheEntry, maxAgeMs: number | undefined): boolean {\r\n if (typeof maxAgeMs !== 'number') return true\r\n return Date.now() - entry.loadedAt <= maxAgeMs\r\n}\r\n\r\nclass ThemeRegistry {\r\n private themes: Map<string, ThemeDefinition> = new Map()\r\n private plugins: Map<string, ThemePluginDefinition> = new Map()\r\n private compositionLayers = createCompositionLayerMaps()\r\n private loadedThemeCache = new Map<string, ThemeLoadCacheEntry>()\r\n private currentTheme: string | null = null\r\n private currentMode: string | null = null\r\n private fallbackConfig: ThemeFallbackConfig = {}\r\n private listeners = new Map<ThemeRegistryEvent, Set<(payload: unknown) => void>>()\r\n\r\n getVersion() {\r\n return RUNTIME_THEME_REGISTRY_VERSION\r\n }\r\n\r\n on<K extends ThemeRegistryEvent>(event: K, handler: ThemeRegistryEventHandler<K>): () => void {\r\n const existing = this.listeners.get(event) ?? new Set<(payload: unknown) => void>()\r\n existing.add(handler as (payload: unknown) => void)\r\n this.listeners.set(event, existing)\r\n\r\n return () => {\r\n existing.delete(handler as (payload: unknown) => void)\r\n if (existing.size === 0) {\r\n this.listeners.delete(event)\r\n }\r\n }\r\n }\r\n\r\n onRegistered(handler: ThemeRegistryEventHandler<'registered'>) {\r\n return this.on('registered', handler)\r\n }\r\n\r\n onThemeChanged(handler: ThemeRegistryEventHandler<'themeChanged'>) {\r\n return this.on('themeChanged', handler)\r\n }\r\n\r\n onVariantAdded(handler: ThemeRegistryEventHandler<'variantAdded'>) {\r\n return this.on('variantAdded', handler)\r\n }\r\n\r\n onDestroyed(handler: ThemeRegistryEventHandler<'destroyed'>) {\r\n return this.on('destroyed', handler)\r\n }\r\n\r\n onLoaded(handler: ThemeRegistryEventHandler<'loaded'>) {\r\n return this.on('loaded', handler)\r\n }\r\n\r\n onComposed(handler: ThemeRegistryEventHandler<'composed'>) {\r\n return this.on('composed', handler)\r\n }\r\n\r\n private emit<K extends ThemeRegistryEvent>(event: K, payload: ThemeRegistryEventPayloadMap[K]) {\r\n const handlers = this.listeners.get(event)\r\n if (!handlers) return\r\n\r\n handlers.forEach((handler) => {\r\n ;(handler as ThemeRegistryEventHandler<K>)(payload)\r\n })\r\n }\r\n\r\n register(theme: ThemeDefinition, options: ThemeRegistrationOptions = {}) {\r\n const ifExists = options.ifExists ?? 'throw'\r\n const shouldValidate = options.validate ?? true\r\n\r\n assertCompatibility(theme.metadata?.compatibility?.minRegistryVersion, `Theme \"${theme.name}\"`)\r\n\r\n if (shouldValidate) {\r\n const validation = validateTheme(theme)\r\n if (!validation.valid) {\r\n const details = validation.issues.map((issue) => `${issue.path}: ${issue.message}`).join('\\n')\r\n throw new Error(`Theme \"${theme.name}\" failed validation:\\n${details}`)\r\n }\r\n }\r\n\r\n const exists = this.themes.has(theme.name)\r\n if (!exists) {\r\n this.themes.set(theme.name, theme)\r\n this.emit('registered', { themeName: theme.name })\r\n return\r\n }\r\n\r\n if (ifExists === 'throw') {\r\n throw new Error(`Theme \"${theme.name}\" already exists`)\r\n }\r\n\r\n if (ifExists === 'replace') {\r\n this.themes.set(theme.name, theme)\r\n this.emit('replaced', { themeName: theme.name })\r\n return\r\n }\r\n\r\n const existing = this.themes.get(theme.name)\r\n if (!existing) {\r\n this.themes.set(theme.name, theme)\r\n this.emit('registered', { themeName: theme.name })\r\n return\r\n }\r\n\r\n const mergedModes: Record<string, ThemeTokenSet> = { ...existing.modes }\r\n for (const [modeName, tokens] of Object.entries(theme.modes)) {\r\n if (mergedModes[modeName]) {\r\n mergedModes[modeName] = mergeTokenSets(mergedModes[modeName], tokens)\r\n } else {\r\n mergedModes[modeName] = tokens\r\n }\r\n }\r\n\r\n this.themes.set(theme.name, {\r\n ...existing,\r\n ...theme,\r\n metadata: { ...(existing.metadata ?? {}), ...(theme.metadata ?? {}) },\r\n modes: mergedModes,\r\n })\r\n\r\n this.emit('merged', { themeName: theme.name })\r\n }\r\n\r\n replace(themeName: string, theme: ThemeDefinition) {\r\n if (themeName !== theme.name) {\r\n throw new Error('replace() requires matching themeName and theme.name')\r\n }\r\n this.register(theme, { ifExists: 'replace' })\r\n }\r\n\r\n merge(themeName: string, theme: ThemeDefinition) {\r\n if (themeName !== theme.name) {\r\n throw new Error('merge() requires matching themeName and theme.name')\r\n }\r\n this.register(theme, { ifExists: 'merge' })\r\n }\r\n\r\n unregister(themeName: string): boolean {\r\n const removed = this.themes.delete(themeName)\r\n if (removed) {\r\n this.emit('unregistered', { themeName })\r\n }\r\n\r\n if (removed && this.currentTheme === themeName) {\r\n this.currentTheme = null\r\n this.currentMode = null\r\n }\r\n\r\n return removed\r\n }\r\n\r\n setFallback(config: ThemeFallbackConfig) {\r\n this.fallbackConfig = { ...this.fallbackConfig, ...config }\r\n }\r\n\r\n registerPlugin(plugin: ThemePluginDefinition, options: PluginRegistrationOptions = {}) {\r\n const ifExists = options.ifExists ?? 'throw'\r\n const themeIfExists = options.themeIfExists ?? 'merge'\r\n const validateThemes = options.validateThemes ?? true\r\n\r\n assertCompatibility(plugin.minRegistryVersion, `Plugin \"${plugin.name}\"`)\r\n\r\n const exists = this.plugins.has(plugin.name)\r\n if (exists && ifExists === 'throw') {\r\n throw new Error(`Plugin \"${plugin.name}\" already exists`)\r\n }\r\n\r\n let pluginToStore = plugin\r\n if (exists && ifExists === 'merge') {\r\n const existing = this.plugins.get(plugin.name)\r\n if (existing) {\r\n pluginToStore = mergePlugins(existing, plugin)\r\n }\r\n }\r\n\r\n this.plugins.set(plugin.name, pluginToStore)\r\n\r\n const pluginThemes: ThemeDefinition[] = [\r\n ...(pluginToStore.theme ? [pluginToStore.theme] : []),\r\n ...(pluginToStore.themes ?? []),\r\n ]\r\n\r\n for (const theme of pluginThemes) {\r\n this.register(theme, { ifExists: themeIfExists, validate: validateThemes })\r\n }\r\n\r\n this.emit('pluginRegistered', { pluginName: plugin.name })\r\n }\r\n\r\n registerCompositionLayer(layer: ThemeCompositionLayerDefinition, options: ThemeRegistrationOptions = {}) {\r\n const targetMap = this.compositionLayers[layer.type]\r\n const ifExists = options.ifExists ?? 'throw'\r\n\r\n const exists = targetMap.has(layer.name)\r\n if (exists && ifExists === 'throw') {\r\n throw new Error(`Composition layer \"${layer.type}:${layer.name}\" already exists`)\r\n }\r\n\r\n if (exists && ifExists === 'merge') {\r\n const existing = targetMap.get(layer.name)\r\n if (existing) {\r\n targetMap.set(layer.name, {\r\n ...existing,\r\n ...layer,\r\n metadata: { ...(existing.metadata ?? {}), ...(layer.metadata ?? {}) },\r\n tokens: mergeTokenSets(existing.tokens, layer.tokens),\r\n })\r\n return\r\n }\r\n }\r\n\r\n targetMap.set(layer.name, layer)\r\n }\r\n\r\n getCompositionLayer(type: ThemeCompositionLayerType, name: string): ThemeCompositionLayerDefinition | undefined {\r\n return this.compositionLayers[type].get(name)\r\n }\r\n\r\n getCompositionLayers(type?: ThemeCompositionLayerType): ThemeCompositionLayerDefinition[] {\r\n if (type) {\r\n return Array.from(this.compositionLayers[type].values())\r\n }\r\n\r\n return [\r\n ...Array.from(this.compositionLayers.brand.values()),\r\n ...Array.from(this.compositionLayers.appearance.values()),\r\n ...Array.from(this.compositionLayers.accessibility.values()),\r\n ]\r\n }\r\n\r\n compose(selection: ThemeCompositionSelection): ThemeCompositionResult {\r\n const appliedLayers: ThemeCompositionLayerDefinition[] = []\r\n let composedTokens: ThemeTokenSet | null = null\r\n\r\n const resolutionOrder: Array<[ThemeCompositionLayerType, string | null | undefined]> = [\r\n ['brand', selection.brand],\r\n ['appearance', selection.appearance],\r\n ['accessibility', selection.accessibility],\r\n ]\r\n\r\n resolutionOrder.forEach(([type, layerName]) => {\r\n if (!layerName) return\r\n const layer = this.compositionLayers[type].get(layerName)\r\n if (!layer) return\r\n\r\n appliedLayers.push(layer)\r\n composedTokens = composedTokens ? mergeTokenSets(composedTokens, layer.tokens) : layer.tokens\r\n })\r\n\r\n this.emit('composed', {\r\n appliedLayers: appliedLayers.map((layer) => `${layer.type}:${layer.name}`),\r\n })\r\n\r\n return {\r\n selection,\r\n tokens: composedTokens,\r\n appliedLayers,\r\n }\r\n }\r\n\r\n getInitialThemeAttributes(themeName: string | null, modeName: string | null): ThemeDocumentAttributes | null {\r\n const resolved = this.resolveSelection(themeName, modeName)\r\n if (!resolved.themeName || !resolved.modeName) return null\r\n\r\n return {\r\n 'data-theme': resolved.themeName,\r\n 'data-mode': resolved.modeName,\r\n }\r\n }\r\n\r\n hydrateThemeOnDocument(themeName: string | null, modeName: string | null): ThemeResolutionResult {\r\n const resolved = this.resolveSelection(themeName, modeName)\r\n if (!resolved.themeName || !resolved.modeName || !resolved.tokens) {\r\n return resolved\r\n }\r\n\r\n if (typeof document !== 'undefined') {\r\n document.documentElement.setAttribute('data-theme', resolved.themeName)\r\n document.documentElement.setAttribute('data-mode', resolved.modeName)\r\n\r\n const cssVariables = tokenSetToCssVariables(resolved.tokens)\r\n Object.entries(cssVariables).forEach(([name, value]) => {\r\n document.documentElement.style.setProperty(name, value)\r\n })\r\n }\r\n\r\n this.currentTheme = resolved.themeName\r\n this.currentMode = resolved.modeName\r\n this.emit('themeChanged', { themeName: resolved.themeName, modeName: resolved.modeName })\r\n\r\n return resolved\r\n }\r\n\r\n async load(source: ThemeLoadSource, options: ThemeLoadOptions = {}): Promise<ThemeLoadResult> {\r\n const ifExists = options.ifExists ?? 'merge'\r\n const validate = options.validate ?? true\r\n const cacheKey = options.cacheKey ?? (typeof source === 'string' ? source : undefined)\r\n const forceRefresh = options.forceRefresh ?? false\r\n const maxAgeMs = options.maxAgeMs\r\n\r\n if (cacheKey && !forceRefresh && this.loadedThemeCache.has(cacheKey)) {\r\n const entry = this.loadedThemeCache.get(cacheKey)\r\n if (entry && isCacheEntryFresh(entry, maxAgeMs)) {\r\n const names = entry.themes.map((theme) => theme.name)\r\n\r\n this.emit('loaded', {\r\n source: entry.source,\r\n count: names.length,\r\n fromCache: true,\r\n })\r\n\r\n return {\r\n loaded: names.length,\r\n themes: names,\r\n source: entry.source,\r\n fromCache: true,\r\n }\r\n }\r\n }\r\n\r\n let loadedThemes: ThemeDefinition[] = []\r\n if (typeof source === 'string') {\r\n const response = await fetch(source)\r\n if (!response.ok) {\r\n throw new Error(`Failed to load themes from ${source}: ${response.status} ${response.statusText}`)\r\n }\r\n const payload = (await response.json()) as ThemeDefinition | ThemeDefinition[]\r\n loadedThemes = normalizeLoadedThemes(payload)\r\n } else {\r\n const payload = await source()\r\n loadedThemes = normalizeLoadedThemes(payload)\r\n }\r\n\r\n const names: string[] = []\r\n loadedThemes.forEach((theme) => {\r\n this.register(theme, { ifExists, validate })\r\n names.push(theme.name)\r\n })\r\n\r\n const sourceName = typeof source === 'string' ? source : 'loader'\r\n if (cacheKey) {\r\n this.loadedThemeCache.set(cacheKey, {\r\n themes: loadedThemes,\r\n loadedAt: Date.now(),\r\n source: sourceName,\r\n })\r\n }\r\n\r\n this.emit('loaded', {\r\n source: sourceName,\r\n count: names.length,\r\n fromCache: false,\r\n })\r\n\r\n return {\r\n loaded: names.length,\r\n themes: names,\r\n source: sourceName,\r\n fromCache: false,\r\n }\r\n }\r\n\r\n clearLoadCache(cacheKey?: string) {\r\n if (cacheKey) {\r\n this.loadedThemeCache.delete(cacheKey)\r\n return\r\n }\r\n\r\n this.loadedThemeCache.clear()\r\n }\r\n\r\n unregisterPlugin(pluginName: string): boolean {\r\n const removed = this.plugins.delete(pluginName)\r\n if (removed) {\r\n this.emit('pluginUnregistered', { pluginName })\r\n }\r\n return removed\r\n }\r\n\r\n getPlugin(name: string): ThemePluginDefinition | undefined {\r\n return this.plugins.get(name)\r\n }\r\n\r\n getPlugins(): ThemePluginDefinition[] {\r\n return Array.from(this.plugins.values())\r\n }\r\n\r\n getPluginContributions(pluginName: string): ThemePluginContributions | undefined {\r\n const plugin = this.plugins.get(pluginName)\r\n if (!plugin) return undefined\r\n return toPluginContributions(plugin)\r\n }\r\n\r\n getMergedPluginContributions(): ThemePluginContributions {\r\n let merged = createEmptyContributions()\r\n\r\n this.plugins.forEach((plugin) => {\r\n merged = mergePluginContributions(merged, toPluginContributions(plugin))\r\n })\r\n\r\n return merged\r\n }\r\n\r\n /**\r\n * Dynamically register a theme mode - useful for packages to add their own modes\r\n * @param themeName - The name of the existing theme to add the mode to\r\n * @param modeName - The name of the mode (e.g., 'ocean', 'forest', 'high-contrast')\r\n * @param tokens - The tokens for this mode\r\n */\r\n registerMode(themeName: string, modeName: string, tokens: ThemeTokenSet) {\r\n const theme = this.themes.get(themeName)\r\n if (!theme) {\r\n throw new Error(`Theme \"${themeName}\" not found. Register the theme first with themeRegistry.register(theme)`)\r\n }\r\n\r\n theme.modes[modeName] = tokens\r\n const validation = validateTheme(theme)\r\n if (!validation.valid) {\r\n delete theme.modes[modeName]\r\n const details = validation.issues.map((issue) => `${issue.path}: ${issue.message}`).join('\\n')\r\n throw new Error(`Invalid mode \"${modeName}\" for theme \"${themeName}\":\\n${details}`)\r\n }\r\n\r\n this.emit('variantAdded', { themeName, variantName: modeName })\r\n }\r\n\r\n /**\r\n * Register multiple modes at once for a theme\r\n */\r\n registerModes(themeName: string, modes: Record<string, ThemeTokenSet>) {\r\n const theme = this.themes.get(themeName)\r\n if (!theme) {\r\n throw new Error(`Theme \"${themeName}\" not found. Register the theme first with themeRegistry.register(theme)`)\r\n }\r\n\r\n const originalModes = { ...theme.modes }\r\n Object.assign(theme.modes, modes)\r\n\r\n const validation = validateTheme(theme)\r\n if (!validation.valid) {\r\n theme.modes = originalModes\r\n const details = validation.issues.map((issue) => `${issue.path}: ${issue.message}`).join('\\n')\r\n throw new Error(`Invalid modes for theme \"${themeName}\":\\n${details}`)\r\n }\r\n\r\n Object.keys(modes).forEach((modeName) => {\r\n this.emit('variantAdded', { themeName, variantName: modeName })\r\n })\r\n }\r\n\r\n /**\r\n * Create and register a new theme with specific modes\r\n * Useful for packages that want to add their own themes dynamically\r\n */\r\n createTheme(name: string, modes: Record<string, ThemeTokenSet>) {\r\n const theme: ThemeDefinition = { name, modes }\r\n this.register(theme)\r\n }\r\n\r\n private getFallbackThemeName(): string | null {\r\n if (this.fallbackConfig.themeName && this.themes.has(this.fallbackConfig.themeName)) {\r\n return this.fallbackConfig.themeName\r\n }\r\n\r\n const firstTheme = this.themes.keys().next().value\r\n return firstTheme ?? null\r\n }\r\n\r\n private resolveModeName(theme: ThemeDefinition, requestedMode: string | null | undefined): string | null {\r\n if (requestedMode && theme.modes[requestedMode]) {\r\n return requestedMode\r\n }\r\n\r\n if (this.fallbackConfig.modeName && theme.modes[this.fallbackConfig.modeName]) {\r\n return this.fallbackConfig.modeName\r\n }\r\n\r\n const firstMode = Object.keys(theme.modes)[0]\r\n return firstMode ?? null\r\n }\r\n\r\n resolveSelection(themeName: string | null, modeName: string | null): ThemeResolutionResult {\r\n const effectiveThemeName = themeName && this.themes.has(themeName) ? themeName : this.getFallbackThemeName()\r\n if (!effectiveThemeName) {\r\n return { themeName: null, modeName: null, tokens: null }\r\n }\r\n\r\n const theme = this.themes.get(effectiveThemeName)\r\n if (!theme) {\r\n return { themeName: null, modeName: null, tokens: null }\r\n }\r\n\r\n const effectiveModeName = this.resolveModeName(theme, modeName)\r\n if (!effectiveModeName) {\r\n return { themeName: theme.name, modeName: null, tokens: null }\r\n }\r\n\r\n return {\r\n themeName: theme.name,\r\n modeName: effectiveModeName,\r\n tokens: theme.modes[effectiveModeName] ?? null,\r\n }\r\n }\r\n\r\n get(name: string): ThemeDefinition | undefined {\r\n return this.themes.get(name)\r\n }\r\n\r\n getAll(): ThemeDefinition[] {\r\n return Array.from(this.themes.values())\r\n }\r\n\r\n getTokens(themeName: string, modeName: string): ThemeTokenSet | undefined {\r\n const theme = this.themes.get(themeName)\r\n return theme?.modes[modeName]\r\n }\r\n\r\n setCurrent(themeName: string, modeName: string) {\r\n const resolved = this.resolveSelection(themeName, modeName)\r\n if (!resolved.themeName || !resolved.modeName) {\r\n throw new Error(`No valid theme selection for \"${themeName}\" and mode \"${modeName}\"`)\r\n }\r\n\r\n this.currentTheme = resolved.themeName\r\n this.currentMode = resolved.modeName\r\n this.emit('themeChanged', { themeName: resolved.themeName, modeName: resolved.modeName })\r\n }\r\n\r\n getCurrent() {\r\n return {\r\n theme: this.currentTheme,\r\n mode: this.currentMode,\r\n }\r\n }\r\n\r\n has(themeName: string): boolean {\r\n return this.themes.has(themeName)\r\n }\r\n\r\n getModes(themeName: string): string[] {\r\n const theme = this.themes.get(themeName)\r\n return theme ? Object.keys(theme.modes) : []\r\n }\r\n\r\n getVariants(themeName: string): string[] {\r\n return this.getModes(themeName)\r\n }\r\n\r\n destroy() {\r\n this.themes.clear()\r\n this.plugins.clear()\r\n this.compositionLayers = createCompositionLayerMaps()\r\n this.loadedThemeCache.clear()\r\n this.currentTheme = null\r\n this.currentMode = null\r\n this.fallbackConfig = {}\r\n this.emit('destroyed', { timestamp: new Date().toISOString() })\r\n this.listeners.clear()\r\n }\r\n}\r\n\r\nexport const themeRegistry = new ThemeRegistry()\r\n","import { themeRegistry } from './theme-registry'\r\nimport type { ThemePalette } from './theme-registry'\r\n\r\nconst fnpTheme: { name: string; modes: Record<string, ThemePalette> } = {\r\n name: 'fnp',\r\n modes: {\r\n light: {\r\n primary: '#031011',\r\n secondary: '#153e46',\r\n tertiary: '#378d93',\r\n background: '#ffffff',\r\n text: '#031011',\r\n accent: '#378d93',\r\n muted: '#667085',\r\n error: '#DF1C41',\r\n warning: '#F4C790',\r\n success: '#27AE60',\r\n info: '#378d93',\r\n },\r\n dark: {\r\n primary: '#c4e8ee',\r\n secondary: '#378d93',\r\n tertiary: '#153e46',\r\n background: '#031011',\r\n text: '#c4e8ee',\r\n accent: '#378d93',\r\n muted: '#667085',\r\n error: '#DF1C41',\r\n warning: '#F4C790',\r\n success: '#27AE60',\r\n info: '#378d93',\r\n },\r\n },\r\n}\r\n\r\n// Register theme on module load - this is your \"package-like\" registration\r\nthemeRegistry.register(fnpTheme)\r\n\r\nexport { themeRegistry }"],"mappings":"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","names":["names"]}