@easemate/web-kit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +824 -0
- package/build/components/code/index.cjs +152 -0
- package/build/components/code/index.d.cts +11 -0
- package/build/components/code/index.d.ts +11 -0
- package/build/components/code/index.js +148 -0
- package/build/components/code/utils/highlight-api.cjs +18 -0
- package/build/components/code/utils/highlight-api.d.cts +7 -0
- package/build/components/code/utils/highlight-api.d.ts +7 -0
- package/build/components/code/utils/highlight-api.js +14 -0
- package/build/components/code/utils/syntax-grammars.cjs +62 -0
- package/build/components/code/utils/syntax-grammars.d.cts +7 -0
- package/build/components/code/utils/syntax-grammars.d.ts +7 -0
- package/build/components/code/utils/syntax-grammars.js +59 -0
- package/build/components/code/utils/syntax-highlighter-theme.cjs +27 -0
- package/build/components/code/utils/syntax-highlighter-theme.d.cts +3 -0
- package/build/components/code/utils/syntax-highlighter-theme.d.ts +3 -0
- package/build/components/code/utils/syntax-highlighter-theme.js +23 -0
- package/build/components/code/utils/syntax-highlighter-types.cjs +2 -0
- package/build/components/code/utils/syntax-highlighter-types.d.cts +12 -0
- package/build/components/code/utils/syntax-highlighter-types.d.ts +12 -0
- package/build/components/code/utils/syntax-highlighter-types.js +1 -0
- package/build/components/code/utils/syntax-tokenizer.cjs +63 -0
- package/build/components/code/utils/syntax-tokenizer.d.cts +3 -0
- package/build/components/code/utils/syntax-tokenizer.d.ts +3 -0
- package/build/components/code/utils/syntax-tokenizer.js +58 -0
- package/build/components/curve/bezier-conversion.cjs +23 -0
- package/build/components/curve/bezier-conversion.d.cts +2 -0
- package/build/components/curve/bezier-conversion.d.ts +2 -0
- package/build/components/curve/bezier-conversion.js +19 -0
- package/build/components/curve/canvas-controls.cjs +300 -0
- package/build/components/curve/canvas-controls.d.cts +12 -0
- package/build/components/curve/canvas-controls.d.ts +12 -0
- package/build/components/curve/canvas-controls.js +296 -0
- package/build/components/curve/canvas.cjs +1208 -0
- package/build/components/curve/canvas.d.cts +24 -0
- package/build/components/curve/canvas.d.ts +24 -0
- package/build/components/curve/canvas.js +1204 -0
- package/build/components/curve/constants.cjs +203 -0
- package/build/components/curve/constants.d.cts +23 -0
- package/build/components/curve/constants.d.ts +23 -0
- package/build/components/curve/constants.js +200 -0
- package/build/components/curve/controls.cjs +942 -0
- package/build/components/curve/controls.d.cts +37 -0
- package/build/components/curve/controls.d.ts +37 -0
- package/build/components/curve/controls.js +938 -0
- package/build/components/curve/index.cjs +335 -0
- package/build/components/curve/index.d.cts +31 -0
- package/build/components/curve/index.d.ts +31 -0
- package/build/components/curve/index.js +330 -0
- package/build/components/curve/output.cjs +141 -0
- package/build/components/curve/output.d.cts +19 -0
- package/build/components/curve/output.d.ts +19 -0
- package/build/components/curve/output.js +137 -0
- package/build/components/curve/styles.cjs +493 -0
- package/build/components/curve/styles.d.cts +6 -0
- package/build/components/curve/styles.d.ts +6 -0
- package/build/components/curve/styles.js +490 -0
- package/build/components/curve/svg-renderer.cjs +185 -0
- package/build/components/curve/svg-renderer.d.cts +9 -0
- package/build/components/curve/svg-renderer.d.ts +9 -0
- package/build/components/curve/svg-renderer.js +175 -0
- package/build/components/curve/toolbar.cjs +368 -0
- package/build/components/curve/toolbar.d.cts +26 -0
- package/build/components/curve/toolbar.d.ts +26 -0
- package/build/components/curve/toolbar.js +364 -0
- package/build/components/curve/types.cjs +10 -0
- package/build/components/curve/types.d.cts +33 -0
- package/build/components/curve/types.d.ts +33 -0
- package/build/components/curve/types.js +7 -0
- package/build/components/curve/utils.cjs +541 -0
- package/build/components/curve/utils.d.cts +33 -0
- package/build/components/curve/utils.d.ts +33 -0
- package/build/components/curve/utils.js +521 -0
- package/build/components/index.cjs +18 -0
- package/build/components/index.d.cts +2 -0
- package/build/components/index.d.ts +2 -0
- package/build/components/index.js +2 -0
- package/build/decorators/Component.cjs +127 -0
- package/build/decorators/Component.d.cts +28 -0
- package/build/decorators/Component.d.ts +28 -0
- package/build/decorators/Component.js +123 -0
- package/build/decorators/Listen.cjs +154 -0
- package/build/decorators/Listen.d.cts +18 -0
- package/build/decorators/Listen.d.ts +18 -0
- package/build/decorators/Listen.js +151 -0
- package/build/decorators/OutsideClick.cjs +64 -0
- package/build/decorators/OutsideClick.d.cts +16 -0
- package/build/decorators/OutsideClick.d.ts +16 -0
- package/build/decorators/OutsideClick.js +59 -0
- package/build/decorators/Prop.cjs +273 -0
- package/build/decorators/Prop.d.cts +22 -0
- package/build/decorators/Prop.d.ts +22 -0
- package/build/decorators/Prop.js +270 -0
- package/build/decorators/Query.cjs +79 -0
- package/build/decorators/Query.d.cts +27 -0
- package/build/decorators/Query.d.ts +27 -0
- package/build/decorators/Query.js +76 -0
- package/build/decorators/Watch.cjs +52 -0
- package/build/decorators/Watch.d.cts +11 -0
- package/build/decorators/Watch.d.ts +11 -0
- package/build/decorators/Watch.js +49 -0
- package/build/decorators/index.cjs +15 -0
- package/build/decorators/index.d.cts +6 -0
- package/build/decorators/index.d.ts +6 -0
- package/build/decorators/index.js +6 -0
- package/build/elements/button/index.cjs +214 -0
- package/build/elements/button/index.d.cts +11 -0
- package/build/elements/button/index.d.ts +11 -0
- package/build/elements/button/index.js +210 -0
- package/build/elements/checkbox/index.cjs +316 -0
- package/build/elements/checkbox/index.d.cts +14 -0
- package/build/elements/checkbox/index.d.ts +14 -0
- package/build/elements/checkbox/index.js +312 -0
- package/build/elements/color/index.cjs +154 -0
- package/build/elements/color/index.d.cts +18 -0
- package/build/elements/color/index.d.ts +18 -0
- package/build/elements/color/index.js +150 -0
- package/build/elements/color/picker.cjs +544 -0
- package/build/elements/color/picker.d.cts +37 -0
- package/build/elements/color/picker.d.ts +37 -0
- package/build/elements/color/picker.js +540 -0
- package/build/elements/color/utils.cjs +235 -0
- package/build/elements/color/utils.d.cts +37 -0
- package/build/elements/color/utils.d.ts +37 -0
- package/build/elements/color/utils.js +218 -0
- package/build/elements/dropdown/index.cjs +875 -0
- package/build/elements/dropdown/index.d.cts +30 -0
- package/build/elements/dropdown/index.d.ts +30 -0
- package/build/elements/dropdown/index.js +871 -0
- package/build/elements/field/index.cjs +82 -0
- package/build/elements/field/index.d.cts +4 -0
- package/build/elements/field/index.d.ts +4 -0
- package/build/elements/field/index.js +78 -0
- package/build/elements/icons/animation/chevron.cjs +57 -0
- package/build/elements/icons/animation/chevron.d.cts +10 -0
- package/build/elements/icons/animation/chevron.d.ts +10 -0
- package/build/elements/icons/animation/chevron.js +53 -0
- package/build/elements/icons/animation/clear.cjs +74 -0
- package/build/elements/icons/animation/clear.d.cts +3 -0
- package/build/elements/icons/animation/clear.d.ts +3 -0
- package/build/elements/icons/animation/clear.js +70 -0
- package/build/elements/icons/animation/grid.cjs +77 -0
- package/build/elements/icons/animation/grid.d.cts +8 -0
- package/build/elements/icons/animation/grid.d.ts +8 -0
- package/build/elements/icons/animation/grid.js +73 -0
- package/build/elements/icons/animation/loading.cjs +68 -0
- package/build/elements/icons/animation/loading.d.cts +3 -0
- package/build/elements/icons/animation/loading.d.ts +3 -0
- package/build/elements/icons/animation/loading.js +64 -0
- package/build/elements/icons/animation/snap.cjs +133 -0
- package/build/elements/icons/animation/snap.d.cts +8 -0
- package/build/elements/icons/animation/snap.d.ts +8 -0
- package/build/elements/icons/animation/snap.js +129 -0
- package/build/elements/icons/index.cjs +40 -0
- package/build/elements/icons/index.d.cts +24 -0
- package/build/elements/icons/index.d.ts +24 -0
- package/build/elements/icons/index.js +24 -0
- package/build/elements/icons/interface/anchor-add.cjs +35 -0
- package/build/elements/icons/interface/anchor-add.d.cts +3 -0
- package/build/elements/icons/interface/anchor-add.d.ts +3 -0
- package/build/elements/icons/interface/anchor-add.js +31 -0
- package/build/elements/icons/interface/anchor-remove.cjs +34 -0
- package/build/elements/icons/interface/anchor-remove.d.cts +3 -0
- package/build/elements/icons/interface/anchor-remove.d.ts +3 -0
- package/build/elements/icons/interface/anchor-remove.js +30 -0
- package/build/elements/icons/interface/arrow-up.cjs +30 -0
- package/build/elements/icons/interface/arrow-up.d.cts +3 -0
- package/build/elements/icons/interface/arrow-up.d.ts +3 -0
- package/build/elements/icons/interface/arrow-up.js +26 -0
- package/build/elements/icons/interface/arrows-vertical.cjs +30 -0
- package/build/elements/icons/interface/arrows-vertical.d.cts +3 -0
- package/build/elements/icons/interface/arrows-vertical.d.ts +3 -0
- package/build/elements/icons/interface/arrows-vertical.js +26 -0
- package/build/elements/icons/interface/bezier-angle.cjs +33 -0
- package/build/elements/icons/interface/bezier-angle.d.cts +3 -0
- package/build/elements/icons/interface/bezier-angle.d.ts +3 -0
- package/build/elements/icons/interface/bezier-angle.js +29 -0
- package/build/elements/icons/interface/bezier-distribute.cjs +34 -0
- package/build/elements/icons/interface/bezier-distribute.d.cts +3 -0
- package/build/elements/icons/interface/bezier-distribute.d.ts +3 -0
- package/build/elements/icons/interface/bezier-distribute.js +30 -0
- package/build/elements/icons/interface/bezier-length.cjs +31 -0
- package/build/elements/icons/interface/bezier-length.d.cts +3 -0
- package/build/elements/icons/interface/bezier-length.d.ts +3 -0
- package/build/elements/icons/interface/bezier-length.js +27 -0
- package/build/elements/icons/interface/bezier-mirror.cjs +31 -0
- package/build/elements/icons/interface/bezier-mirror.d.cts +3 -0
- package/build/elements/icons/interface/bezier-mirror.d.ts +3 -0
- package/build/elements/icons/interface/bezier-mirror.js +27 -0
- package/build/elements/icons/interface/bezier.cjs +26 -0
- package/build/elements/icons/interface/bezier.d.cts +3 -0
- package/build/elements/icons/interface/bezier.d.ts +3 -0
- package/build/elements/icons/interface/bezier.js +22 -0
- package/build/elements/icons/interface/check.cjs +30 -0
- package/build/elements/icons/interface/check.d.cts +3 -0
- package/build/elements/icons/interface/check.d.ts +3 -0
- package/build/elements/icons/interface/check.js +26 -0
- package/build/elements/icons/interface/circle-arrow-left.cjs +30 -0
- package/build/elements/icons/interface/circle-arrow-left.d.cts +3 -0
- package/build/elements/icons/interface/circle-arrow-left.d.ts +3 -0
- package/build/elements/icons/interface/circle-arrow-left.js +26 -0
- package/build/elements/icons/interface/circle-arrow-right.cjs +30 -0
- package/build/elements/icons/interface/circle-arrow-right.d.cts +3 -0
- package/build/elements/icons/interface/circle-arrow-right.d.ts +3 -0
- package/build/elements/icons/interface/circle-arrow-right.js +26 -0
- package/build/elements/icons/interface/code.cjs +30 -0
- package/build/elements/icons/interface/code.d.cts +3 -0
- package/build/elements/icons/interface/code.d.ts +3 -0
- package/build/elements/icons/interface/code.js +26 -0
- package/build/elements/icons/interface/dots.cjs +32 -0
- package/build/elements/icons/interface/dots.d.cts +3 -0
- package/build/elements/icons/interface/dots.d.ts +3 -0
- package/build/elements/icons/interface/dots.js +28 -0
- package/build/elements/icons/interface/mention.cjs +30 -0
- package/build/elements/icons/interface/mention.d.cts +3 -0
- package/build/elements/icons/interface/mention.d.ts +3 -0
- package/build/elements/icons/interface/mention.js +26 -0
- package/build/elements/icons/interface/minus.cjs +30 -0
- package/build/elements/icons/interface/minus.d.cts +3 -0
- package/build/elements/icons/interface/minus.d.ts +3 -0
- package/build/elements/icons/interface/minus.js +26 -0
- package/build/elements/icons/interface/picker.cjs +34 -0
- package/build/elements/icons/interface/picker.d.cts +3 -0
- package/build/elements/icons/interface/picker.d.ts +3 -0
- package/build/elements/icons/interface/picker.js +30 -0
- package/build/elements/icons/interface/plus.cjs +30 -0
- package/build/elements/icons/interface/plus.d.cts +3 -0
- package/build/elements/icons/interface/plus.d.ts +3 -0
- package/build/elements/icons/interface/plus.js +26 -0
- package/build/elements/icons/interface/settings.cjs +30 -0
- package/build/elements/icons/interface/settings.d.cts +3 -0
- package/build/elements/icons/interface/settings.d.ts +3 -0
- package/build/elements/icons/interface/settings.js +26 -0
- package/build/elements/index.cjs +62 -0
- package/build/elements/index.d.cts +22 -0
- package/build/elements/index.d.ts +22 -0
- package/build/elements/index.js +22 -0
- package/build/elements/input/index.cjs +273 -0
- package/build/elements/input/index.d.cts +17 -0
- package/build/elements/input/index.d.ts +17 -0
- package/build/elements/input/index.js +269 -0
- package/build/elements/logo/index.cjs +732 -0
- package/build/elements/logo/index.d.cts +17 -0
- package/build/elements/logo/index.d.ts +17 -0
- package/build/elements/logo/index.js +728 -0
- package/build/elements/monitor/fps.cjs +432 -0
- package/build/elements/monitor/fps.d.cts +21 -0
- package/build/elements/monitor/fps.d.ts +21 -0
- package/build/elements/monitor/fps.js +428 -0
- package/build/elements/monitor/index.cjs +670 -0
- package/build/elements/monitor/index.d.cts +112 -0
- package/build/elements/monitor/index.d.ts +112 -0
- package/build/elements/monitor/index.js +666 -0
- package/build/elements/number/index.cjs +173 -0
- package/build/elements/number/index.d.cts +19 -0
- package/build/elements/number/index.d.ts +19 -0
- package/build/elements/number/index.js +169 -0
- package/build/elements/origin/index.cjs +169 -0
- package/build/elements/origin/index.d.cts +12 -0
- package/build/elements/origin/index.d.ts +12 -0
- package/build/elements/origin/index.js +165 -0
- package/build/elements/popover/index.cjs +209 -0
- package/build/elements/popover/index.d.cts +19 -0
- package/build/elements/popover/index.d.ts +19 -0
- package/build/elements/popover/index.js +205 -0
- package/build/elements/radio/index.cjs +301 -0
- package/build/elements/radio/index.d.cts +13 -0
- package/build/elements/radio/index.d.ts +13 -0
- package/build/elements/radio/index.js +283 -0
- package/build/elements/radio/input.cjs +329 -0
- package/build/elements/radio/input.d.cts +15 -0
- package/build/elements/radio/input.d.ts +15 -0
- package/build/elements/radio/input.js +325 -0
- package/build/elements/radio/option.cjs +15 -0
- package/build/elements/radio/option.d.cts +3 -0
- package/build/elements/radio/option.d.ts +3 -0
- package/build/elements/radio/option.js +11 -0
- package/build/elements/shared.cjs +66 -0
- package/build/elements/shared.d.cts +40 -0
- package/build/elements/shared.d.ts +40 -0
- package/build/elements/shared.js +59 -0
- package/build/elements/slider/index.cjs +232 -0
- package/build/elements/slider/index.d.cts +20 -0
- package/build/elements/slider/index.d.ts +20 -0
- package/build/elements/slider/index.js +228 -0
- package/build/elements/state/index.cjs +681 -0
- package/build/elements/state/index.d.cts +86 -0
- package/build/elements/state/index.d.ts +86 -0
- package/build/elements/state/index.js +677 -0
- package/build/elements/toggle/index.cjs +151 -0
- package/build/elements/toggle/index.d.cts +9 -0
- package/build/elements/toggle/index.d.ts +9 -0
- package/build/elements/toggle/index.js +147 -0
- package/build/elements/tooltip/index.cjs +187 -0
- package/build/elements/tooltip/index.d.cts +17 -0
- package/build/elements/tooltip/index.d.ts +17 -0
- package/build/elements/tooltip/index.js +183 -0
- package/build/index.cjs +40 -0
- package/build/index.d.cts +6 -0
- package/build/index.d.ts +6 -0
- package/build/index.js +12 -0
- package/build/init.cjs +325 -0
- package/build/init.d.cts +157 -0
- package/build/init.d.ts +157 -0
- package/build/init.js +289 -0
- package/build/internal/component-loaders.cjs +206 -0
- package/build/internal/component-loaders.d.cts +52 -0
- package/build/internal/component-loaders.d.ts +52 -0
- package/build/internal/component-loaders.js +167 -0
- package/build/internal/fonts.cjs +128 -0
- package/build/internal/fonts.d.cts +32 -0
- package/build/internal/fonts.d.ts +32 -0
- package/build/internal/fonts.js +123 -0
- package/build/internal/lazy-load.cjs +89 -0
- package/build/internal/lazy-load.d.cts +32 -0
- package/build/internal/lazy-load.d.ts +32 -0
- package/build/internal/lazy-load.js +86 -0
- package/build/internal/style-inject.cjs +236 -0
- package/build/internal/style-inject.d.cts +44 -0
- package/build/internal/style-inject.d.ts +44 -0
- package/build/internal/style-inject.js +226 -0
- package/build/register.cjs +36 -0
- package/build/register.d.cts +32 -0
- package/build/register.d.ts +32 -0
- package/build/register.js +34 -0
- package/build/theme/index.cjs +452 -0
- package/build/theme/index.d.cts +146 -0
- package/build/theme/index.d.ts +146 -0
- package/build/theme/index.js +423 -0
- package/build/theme/presets.cjs +54 -0
- package/build/theme/presets.d.cts +19 -0
- package/build/theme/presets.d.ts +19 -0
- package/build/theme/presets.js +51 -0
- package/build/theme/registry.cjs +204 -0
- package/build/theme/registry.d.cts +99 -0
- package/build/theme/registry.d.ts +99 -0
- package/build/theme/registry.js +194 -0
- package/build/theme/tokens.cjs +148 -0
- package/build/theme/tokens.d.cts +163 -0
- package/build/theme/tokens.d.ts +163 -0
- package/build/theme/tokens.js +145 -0
- package/build/utils/dismiss-controller.cjs +77 -0
- package/build/utils/dismiss-controller.d.cts +14 -0
- package/build/utils/dismiss-controller.d.ts +14 -0
- package/build/utils/dismiss-controller.js +73 -0
- package/build/utils/index.cjs +18 -0
- package/build/utils/index.d.cts +3 -0
- package/build/utils/index.d.ts +3 -0
- package/build/utils/index.js +3 -0
- package/build/utils/outside-click.cjs +82 -0
- package/build/utils/outside-click.d.cts +18 -0
- package/build/utils/outside-click.d.ts +18 -0
- package/build/utils/outside-click.js +74 -0
- package/build/utils/template-helpers.cjs +39 -0
- package/build/utils/template-helpers.d.cts +13 -0
- package/build/utils/template-helpers.d.ts +13 -0
- package/build/utils/template-helpers.js +28 -0
- package/package.json +96 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { defaultColors, defaultRadii, defaultSpacing, defaultTypography } from "./tokens.js";
|
|
2
|
+
/**
|
|
3
|
+
* Default ease UI kit CSS variables (--ease-*).
|
|
4
|
+
* These are component-level design tokens that components consume.
|
|
5
|
+
*/
|
|
6
|
+
export const defaultEaseVars = {
|
|
7
|
+
// Typography aliases
|
|
8
|
+
'--ease-font-family': 'var(--font-family)',
|
|
9
|
+
'--ease-font-mono': 'var(--font-mono)',
|
|
10
|
+
'--ease-font-size': 'var(--font-size)',
|
|
11
|
+
'--ease-font-size-sm': '12px',
|
|
12
|
+
'--ease-line-height': 'var(--font-line-height)',
|
|
13
|
+
// Panel (ease-state)
|
|
14
|
+
'--ease-panel-max-width': '332px',
|
|
15
|
+
'--ease-panel-padding': 'var(--spacing-md)',
|
|
16
|
+
'--ease-panel-radius': 'var(--radii-lg)',
|
|
17
|
+
'--ease-panel-border-color': 'var(--color-white-6)',
|
|
18
|
+
'--ease-panel-background': 'var(--color-gray-1000)',
|
|
19
|
+
'--ease-panel-shadow': '0 0 40px 0 var(--color-white-2) inset',
|
|
20
|
+
'--ease-panel-title-font-size': '14px',
|
|
21
|
+
'--ease-panel-title-font-weight': '500',
|
|
22
|
+
'--ease-panel-title-line-height': '24px',
|
|
23
|
+
'--ease-panel-title-color': 'var(--color-blue-100)',
|
|
24
|
+
// Field (ease-field)
|
|
25
|
+
'--ease-field-label-width': '36%',
|
|
26
|
+
'--ease-field-column-gap': 'var(--spacing-md)',
|
|
27
|
+
'--ease-field-row-gap': '6px',
|
|
28
|
+
'--ease-field-min-height': '30px',
|
|
29
|
+
'--ease-field-label-font-size': 'var(--ease-font-size-sm)',
|
|
30
|
+
'--ease-field-label-color': 'var(--color-gray-600)',
|
|
31
|
+
'--ease-field-label-padding-left': '4px'
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The complete default (dark) theme configuration.
|
|
35
|
+
* Includes colors, radii, spacing, typography, and component-level --ease-* vars.
|
|
36
|
+
*/
|
|
37
|
+
export const defaultThemeConfig = {
|
|
38
|
+
colors: defaultColors,
|
|
39
|
+
radii: defaultRadii,
|
|
40
|
+
spacing: defaultSpacing,
|
|
41
|
+
typography: defaultTypography,
|
|
42
|
+
vars: defaultEaseVars
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Default built-in theme name.
|
|
46
|
+
*/
|
|
47
|
+
export const DEFAULT_THEME_NAME = 'default';
|
|
48
|
+
/**
|
|
49
|
+
* Legacy alias for the built-in dark theme.
|
|
50
|
+
*/
|
|
51
|
+
export const DARK_THEME_ALIAS = 'dark';
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isThemeConfig = exports.isThemeRef = void 0;
|
|
4
|
+
exports.registerTheme = registerTheme;
|
|
5
|
+
exports.getTheme = getTheme;
|
|
6
|
+
exports.hasTheme = hasTheme;
|
|
7
|
+
exports.getThemeNames = getThemeNames;
|
|
8
|
+
exports.themeRef = themeRef;
|
|
9
|
+
const presets_1 = require("./presets.cjs");
|
|
10
|
+
// --------------------------
|
|
11
|
+
// Registry implementation
|
|
12
|
+
// --------------------------
|
|
13
|
+
const registry = new Map();
|
|
14
|
+
/**
|
|
15
|
+
* Deep merge two theme configs.
|
|
16
|
+
*/
|
|
17
|
+
const mergeConfigs = (base, overrides) => {
|
|
18
|
+
return {
|
|
19
|
+
colors: {
|
|
20
|
+
...base.colors,
|
|
21
|
+
...overrides.colors,
|
|
22
|
+
gray: { ...base.colors?.gray, ...overrides.colors?.gray },
|
|
23
|
+
blue: { ...base.colors?.blue, ...overrides.colors?.blue },
|
|
24
|
+
green: { ...base.colors?.green, ...overrides.colors?.green },
|
|
25
|
+
red: { ...base.colors?.red, ...overrides.colors?.red },
|
|
26
|
+
orange: { ...base.colors?.orange, ...overrides.colors?.orange },
|
|
27
|
+
yellow: { ...base.colors?.yellow, ...overrides.colors?.yellow },
|
|
28
|
+
whiteAlpha: { ...base.colors?.whiteAlpha, ...overrides.colors?.whiteAlpha },
|
|
29
|
+
blackAlpha: { ...base.colors?.blackAlpha, ...overrides.colors?.blackAlpha }
|
|
30
|
+
},
|
|
31
|
+
radii: { ...base.radii, ...overrides.radii },
|
|
32
|
+
spacing: { ...base.spacing, ...overrides.spacing },
|
|
33
|
+
typography: { ...base.typography, ...overrides.typography },
|
|
34
|
+
vars: { ...base.vars, ...overrides.vars }
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Resolve a theme by name, following base chain.
|
|
39
|
+
*/
|
|
40
|
+
const resolveThemeConfig = (name, visited = new Set()) => {
|
|
41
|
+
if (visited.has(name)) {
|
|
42
|
+
throw new Error(`[web-kit] Circular theme dependency detected: ${Array.from(visited).join(' -> ')} -> ${name}`);
|
|
43
|
+
}
|
|
44
|
+
const entry = registry.get(name);
|
|
45
|
+
if (!entry) {
|
|
46
|
+
throw new Error(`[web-kit] Theme "${name}" is not registered.`);
|
|
47
|
+
}
|
|
48
|
+
// Return cached resolution
|
|
49
|
+
if (entry.resolved) {
|
|
50
|
+
return entry.resolved;
|
|
51
|
+
}
|
|
52
|
+
visited.add(name);
|
|
53
|
+
let resolved;
|
|
54
|
+
if (entry.base === null) {
|
|
55
|
+
// No base - use config as-is
|
|
56
|
+
resolved = entry.config;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// Resolve base first
|
|
60
|
+
const baseConfig = resolveThemeConfig(entry.base, visited);
|
|
61
|
+
resolved = mergeConfigs(baseConfig, entry.config);
|
|
62
|
+
}
|
|
63
|
+
// Cache the resolution
|
|
64
|
+
entry.resolved = resolved;
|
|
65
|
+
return resolved;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Initialize built-in themes.
|
|
69
|
+
*/
|
|
70
|
+
const initBuiltInThemes = () => {
|
|
71
|
+
if (registry.has(presets_1.DEFAULT_THEME_NAME)) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// Register 'default' theme
|
|
75
|
+
registry.set(presets_1.DEFAULT_THEME_NAME, {
|
|
76
|
+
name: presets_1.DEFAULT_THEME_NAME,
|
|
77
|
+
base: null,
|
|
78
|
+
config: presets_1.defaultThemeConfig,
|
|
79
|
+
resolved: presets_1.defaultThemeConfig
|
|
80
|
+
});
|
|
81
|
+
// Register 'dark' as alias to 'default'
|
|
82
|
+
registry.set(presets_1.DARK_THEME_ALIAS, {
|
|
83
|
+
name: presets_1.DARK_THEME_ALIAS,
|
|
84
|
+
base: presets_1.DEFAULT_THEME_NAME,
|
|
85
|
+
config: {},
|
|
86
|
+
resolved: null
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
// Initialize on module load
|
|
90
|
+
initBuiltInThemes();
|
|
91
|
+
// --------------------------
|
|
92
|
+
// Public API
|
|
93
|
+
// --------------------------
|
|
94
|
+
/**
|
|
95
|
+
* Check if a value is a theme ref.
|
|
96
|
+
*/
|
|
97
|
+
const isThemeRef = (value) => typeof value === 'object' && value !== null && '__brand' in value && value.__brand === 'WebKitThemeRef';
|
|
98
|
+
exports.isThemeRef = isThemeRef;
|
|
99
|
+
/**
|
|
100
|
+
* Check if a value is a theme config object.
|
|
101
|
+
*/
|
|
102
|
+
const isThemeConfig = (value) => {
|
|
103
|
+
if (typeof value !== 'object' || value === null) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
if ((0, exports.isThemeRef)(value)) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
// Check if it looks like a ThemeConfig
|
|
110
|
+
const obj = value;
|
|
111
|
+
return (obj.colors !== undefined ||
|
|
112
|
+
obj.radii !== undefined ||
|
|
113
|
+
obj.spacing !== undefined ||
|
|
114
|
+
obj.typography !== undefined ||
|
|
115
|
+
obj.vars !== undefined);
|
|
116
|
+
};
|
|
117
|
+
exports.isThemeConfig = isThemeConfig;
|
|
118
|
+
/**
|
|
119
|
+
* Register a custom theme.
|
|
120
|
+
*
|
|
121
|
+
* @param name - Theme name (must be unique)
|
|
122
|
+
* @param options - Theme options (base + config)
|
|
123
|
+
* @returns A typed theme reference
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* const custom = registerTheme('custom', {
|
|
128
|
+
* base: 'default',
|
|
129
|
+
* config: {
|
|
130
|
+
* vars: { '--ease-panel-radius': '14px' }
|
|
131
|
+
* }
|
|
132
|
+
* });
|
|
133
|
+
*
|
|
134
|
+
* initWebKit({ theme: custom });
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
function registerTheme(name, options = {}) {
|
|
138
|
+
const { base = presets_1.DEFAULT_THEME_NAME, config = {} } = options;
|
|
139
|
+
// Resolve base name
|
|
140
|
+
let baseName = null;
|
|
141
|
+
if (base !== null) {
|
|
142
|
+
baseName = (0, exports.isThemeRef)(base) ? base.name : base;
|
|
143
|
+
// Validate base exists
|
|
144
|
+
if (!registry.has(baseName)) {
|
|
145
|
+
throw new Error(`[web-kit] Base theme "${baseName}" is not registered.`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Invalidate cache for themes that depend on this one (if re-registering)
|
|
149
|
+
if (registry.has(name)) {
|
|
150
|
+
for (const entry of registry.values()) {
|
|
151
|
+
if (entry.base === name) {
|
|
152
|
+
entry.resolved = null;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
registry.set(name, {
|
|
157
|
+
name,
|
|
158
|
+
base: baseName,
|
|
159
|
+
config,
|
|
160
|
+
resolved: null
|
|
161
|
+
});
|
|
162
|
+
return {
|
|
163
|
+
__brand: 'WebKitThemeRef',
|
|
164
|
+
name
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get a theme's resolved configuration.
|
|
169
|
+
*
|
|
170
|
+
* @param theme - Theme name, ref, or inline config
|
|
171
|
+
* @returns Resolved theme configuration
|
|
172
|
+
*/
|
|
173
|
+
function getTheme(theme) {
|
|
174
|
+
if ((0, exports.isThemeConfig)(theme)) {
|
|
175
|
+
return theme;
|
|
176
|
+
}
|
|
177
|
+
const name = (0, exports.isThemeRef)(theme) ? theme.name : theme;
|
|
178
|
+
return resolveThemeConfig(name);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Check if a theme is registered.
|
|
182
|
+
*/
|
|
183
|
+
function hasTheme(name) {
|
|
184
|
+
return registry.has(name);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Get all registered theme names.
|
|
188
|
+
*/
|
|
189
|
+
function getThemeNames() {
|
|
190
|
+
return Array.from(registry.keys());
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Create a theme ref for a registered theme name.
|
|
194
|
+
* Useful for type-safe references without module augmentation.
|
|
195
|
+
*/
|
|
196
|
+
function themeRef(name) {
|
|
197
|
+
if (!registry.has(name)) {
|
|
198
|
+
throw new Error(`[web-kit] Theme "${name}" is not registered.`);
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
__brand: 'WebKitThemeRef',
|
|
202
|
+
name
|
|
203
|
+
};
|
|
204
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { ThemeConfig } from "./tokens.cjs";
|
|
2
|
+
/**
|
|
3
|
+
* Augmentable interface for theme names.
|
|
4
|
+
* Consumers can extend this via module augmentation to add custom theme names:
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* declare module '@easemate/web-kit' {
|
|
9
|
+
* interface WebKitThemeRegistry {
|
|
10
|
+
* custom: true;
|
|
11
|
+
* brand: true;
|
|
12
|
+
* }
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export interface WebKitThemeRegistry {
|
|
17
|
+
default: true;
|
|
18
|
+
dark: true;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Union of all registered theme names.
|
|
22
|
+
*/
|
|
23
|
+
export type WebKitThemeName = keyof WebKitThemeRegistry;
|
|
24
|
+
/**
|
|
25
|
+
* A strongly-typed theme reference.
|
|
26
|
+
* Use this for type-safe theme references without module augmentation.
|
|
27
|
+
*/
|
|
28
|
+
export interface WebKitThemeRef<Name extends string = string> {
|
|
29
|
+
readonly __brand: 'WebKitThemeRef';
|
|
30
|
+
readonly name: Name;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Valid theme input for APIs: a registered theme name, a theme ref, or an inline config.
|
|
34
|
+
*/
|
|
35
|
+
export type ThemeInput = WebKitThemeName | WebKitThemeRef | ThemeConfig;
|
|
36
|
+
/**
|
|
37
|
+
* Options for registering a theme.
|
|
38
|
+
*/
|
|
39
|
+
export interface RegisterThemeOptions {
|
|
40
|
+
/**
|
|
41
|
+
* Base theme to extend from.
|
|
42
|
+
* - `'default'` (or any registered name) - extends that theme
|
|
43
|
+
* - `null` - no base, starts from scratch
|
|
44
|
+
* - `undefined` - defaults to `'default'`
|
|
45
|
+
*/
|
|
46
|
+
base?: WebKitThemeName | WebKitThemeRef | null;
|
|
47
|
+
/**
|
|
48
|
+
* Theme configuration (overrides on top of base).
|
|
49
|
+
*/
|
|
50
|
+
config?: ThemeConfig;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check if a value is a theme ref.
|
|
54
|
+
*/
|
|
55
|
+
export declare const isThemeRef: (value: unknown) => value is WebKitThemeRef;
|
|
56
|
+
/**
|
|
57
|
+
* Check if a value is a theme config object.
|
|
58
|
+
*/
|
|
59
|
+
export declare const isThemeConfig: (value: unknown) => value is ThemeConfig;
|
|
60
|
+
/**
|
|
61
|
+
* Register a custom theme.
|
|
62
|
+
*
|
|
63
|
+
* @param name - Theme name (must be unique)
|
|
64
|
+
* @param options - Theme options (base + config)
|
|
65
|
+
* @returns A typed theme reference
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* const custom = registerTheme('custom', {
|
|
70
|
+
* base: 'default',
|
|
71
|
+
* config: {
|
|
72
|
+
* vars: { '--ease-panel-radius': '14px' }
|
|
73
|
+
* }
|
|
74
|
+
* });
|
|
75
|
+
*
|
|
76
|
+
* initWebKit({ theme: custom });
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export declare function registerTheme<Name extends string>(name: Name, options?: RegisterThemeOptions): WebKitThemeRef<Name>;
|
|
80
|
+
/**
|
|
81
|
+
* Get a theme's resolved configuration.
|
|
82
|
+
*
|
|
83
|
+
* @param theme - Theme name, ref, or inline config
|
|
84
|
+
* @returns Resolved theme configuration
|
|
85
|
+
*/
|
|
86
|
+
export declare function getTheme(theme: ThemeInput): ThemeConfig;
|
|
87
|
+
/**
|
|
88
|
+
* Check if a theme is registered.
|
|
89
|
+
*/
|
|
90
|
+
export declare function hasTheme(name: string): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Get all registered theme names.
|
|
93
|
+
*/
|
|
94
|
+
export declare function getThemeNames(): string[];
|
|
95
|
+
/**
|
|
96
|
+
* Create a theme ref for a registered theme name.
|
|
97
|
+
* Useful for type-safe references without module augmentation.
|
|
98
|
+
*/
|
|
99
|
+
export declare function themeRef<Name extends WebKitThemeName>(name: Name): WebKitThemeRef<Name>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { ThemeConfig } from "./tokens.js";
|
|
2
|
+
/**
|
|
3
|
+
* Augmentable interface for theme names.
|
|
4
|
+
* Consumers can extend this via module augmentation to add custom theme names:
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* declare module '@easemate/web-kit' {
|
|
9
|
+
* interface WebKitThemeRegistry {
|
|
10
|
+
* custom: true;
|
|
11
|
+
* brand: true;
|
|
12
|
+
* }
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export interface WebKitThemeRegistry {
|
|
17
|
+
default: true;
|
|
18
|
+
dark: true;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Union of all registered theme names.
|
|
22
|
+
*/
|
|
23
|
+
export type WebKitThemeName = keyof WebKitThemeRegistry;
|
|
24
|
+
/**
|
|
25
|
+
* A strongly-typed theme reference.
|
|
26
|
+
* Use this for type-safe theme references without module augmentation.
|
|
27
|
+
*/
|
|
28
|
+
export interface WebKitThemeRef<Name extends string = string> {
|
|
29
|
+
readonly __brand: 'WebKitThemeRef';
|
|
30
|
+
readonly name: Name;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Valid theme input for APIs: a registered theme name, a theme ref, or an inline config.
|
|
34
|
+
*/
|
|
35
|
+
export type ThemeInput = WebKitThemeName | WebKitThemeRef | ThemeConfig;
|
|
36
|
+
/**
|
|
37
|
+
* Options for registering a theme.
|
|
38
|
+
*/
|
|
39
|
+
export interface RegisterThemeOptions {
|
|
40
|
+
/**
|
|
41
|
+
* Base theme to extend from.
|
|
42
|
+
* - `'default'` (or any registered name) - extends that theme
|
|
43
|
+
* - `null` - no base, starts from scratch
|
|
44
|
+
* - `undefined` - defaults to `'default'`
|
|
45
|
+
*/
|
|
46
|
+
base?: WebKitThemeName | WebKitThemeRef | null;
|
|
47
|
+
/**
|
|
48
|
+
* Theme configuration (overrides on top of base).
|
|
49
|
+
*/
|
|
50
|
+
config?: ThemeConfig;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check if a value is a theme ref.
|
|
54
|
+
*/
|
|
55
|
+
export declare const isThemeRef: (value: unknown) => value is WebKitThemeRef;
|
|
56
|
+
/**
|
|
57
|
+
* Check if a value is a theme config object.
|
|
58
|
+
*/
|
|
59
|
+
export declare const isThemeConfig: (value: unknown) => value is ThemeConfig;
|
|
60
|
+
/**
|
|
61
|
+
* Register a custom theme.
|
|
62
|
+
*
|
|
63
|
+
* @param name - Theme name (must be unique)
|
|
64
|
+
* @param options - Theme options (base + config)
|
|
65
|
+
* @returns A typed theme reference
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* const custom = registerTheme('custom', {
|
|
70
|
+
* base: 'default',
|
|
71
|
+
* config: {
|
|
72
|
+
* vars: { '--ease-panel-radius': '14px' }
|
|
73
|
+
* }
|
|
74
|
+
* });
|
|
75
|
+
*
|
|
76
|
+
* initWebKit({ theme: custom });
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export declare function registerTheme<Name extends string>(name: Name, options?: RegisterThemeOptions): WebKitThemeRef<Name>;
|
|
80
|
+
/**
|
|
81
|
+
* Get a theme's resolved configuration.
|
|
82
|
+
*
|
|
83
|
+
* @param theme - Theme name, ref, or inline config
|
|
84
|
+
* @returns Resolved theme configuration
|
|
85
|
+
*/
|
|
86
|
+
export declare function getTheme(theme: ThemeInput): ThemeConfig;
|
|
87
|
+
/**
|
|
88
|
+
* Check if a theme is registered.
|
|
89
|
+
*/
|
|
90
|
+
export declare function hasTheme(name: string): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Get all registered theme names.
|
|
93
|
+
*/
|
|
94
|
+
export declare function getThemeNames(): string[];
|
|
95
|
+
/**
|
|
96
|
+
* Create a theme ref for a registered theme name.
|
|
97
|
+
* Useful for type-safe references without module augmentation.
|
|
98
|
+
*/
|
|
99
|
+
export declare function themeRef<Name extends WebKitThemeName>(name: Name): WebKitThemeRef<Name>;
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { DARK_THEME_ALIAS, DEFAULT_THEME_NAME, defaultThemeConfig } from "./presets.js";
|
|
2
|
+
// --------------------------
|
|
3
|
+
// Registry implementation
|
|
4
|
+
// --------------------------
|
|
5
|
+
const registry = new Map();
|
|
6
|
+
/**
|
|
7
|
+
* Deep merge two theme configs.
|
|
8
|
+
*/
|
|
9
|
+
const mergeConfigs = (base, overrides) => {
|
|
10
|
+
return {
|
|
11
|
+
colors: {
|
|
12
|
+
...base.colors,
|
|
13
|
+
...overrides.colors,
|
|
14
|
+
gray: { ...base.colors?.gray, ...overrides.colors?.gray },
|
|
15
|
+
blue: { ...base.colors?.blue, ...overrides.colors?.blue },
|
|
16
|
+
green: { ...base.colors?.green, ...overrides.colors?.green },
|
|
17
|
+
red: { ...base.colors?.red, ...overrides.colors?.red },
|
|
18
|
+
orange: { ...base.colors?.orange, ...overrides.colors?.orange },
|
|
19
|
+
yellow: { ...base.colors?.yellow, ...overrides.colors?.yellow },
|
|
20
|
+
whiteAlpha: { ...base.colors?.whiteAlpha, ...overrides.colors?.whiteAlpha },
|
|
21
|
+
blackAlpha: { ...base.colors?.blackAlpha, ...overrides.colors?.blackAlpha }
|
|
22
|
+
},
|
|
23
|
+
radii: { ...base.radii, ...overrides.radii },
|
|
24
|
+
spacing: { ...base.spacing, ...overrides.spacing },
|
|
25
|
+
typography: { ...base.typography, ...overrides.typography },
|
|
26
|
+
vars: { ...base.vars, ...overrides.vars }
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Resolve a theme by name, following base chain.
|
|
31
|
+
*/
|
|
32
|
+
const resolveThemeConfig = (name, visited = new Set()) => {
|
|
33
|
+
if (visited.has(name)) {
|
|
34
|
+
throw new Error(`[web-kit] Circular theme dependency detected: ${Array.from(visited).join(' -> ')} -> ${name}`);
|
|
35
|
+
}
|
|
36
|
+
const entry = registry.get(name);
|
|
37
|
+
if (!entry) {
|
|
38
|
+
throw new Error(`[web-kit] Theme "${name}" is not registered.`);
|
|
39
|
+
}
|
|
40
|
+
// Return cached resolution
|
|
41
|
+
if (entry.resolved) {
|
|
42
|
+
return entry.resolved;
|
|
43
|
+
}
|
|
44
|
+
visited.add(name);
|
|
45
|
+
let resolved;
|
|
46
|
+
if (entry.base === null) {
|
|
47
|
+
// No base - use config as-is
|
|
48
|
+
resolved = entry.config;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
// Resolve base first
|
|
52
|
+
const baseConfig = resolveThemeConfig(entry.base, visited);
|
|
53
|
+
resolved = mergeConfigs(baseConfig, entry.config);
|
|
54
|
+
}
|
|
55
|
+
// Cache the resolution
|
|
56
|
+
entry.resolved = resolved;
|
|
57
|
+
return resolved;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Initialize built-in themes.
|
|
61
|
+
*/
|
|
62
|
+
const initBuiltInThemes = () => {
|
|
63
|
+
if (registry.has(DEFAULT_THEME_NAME)) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// Register 'default' theme
|
|
67
|
+
registry.set(DEFAULT_THEME_NAME, {
|
|
68
|
+
name: DEFAULT_THEME_NAME,
|
|
69
|
+
base: null,
|
|
70
|
+
config: defaultThemeConfig,
|
|
71
|
+
resolved: defaultThemeConfig
|
|
72
|
+
});
|
|
73
|
+
// Register 'dark' as alias to 'default'
|
|
74
|
+
registry.set(DARK_THEME_ALIAS, {
|
|
75
|
+
name: DARK_THEME_ALIAS,
|
|
76
|
+
base: DEFAULT_THEME_NAME,
|
|
77
|
+
config: {},
|
|
78
|
+
resolved: null
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
// Initialize on module load
|
|
82
|
+
initBuiltInThemes();
|
|
83
|
+
// --------------------------
|
|
84
|
+
// Public API
|
|
85
|
+
// --------------------------
|
|
86
|
+
/**
|
|
87
|
+
* Check if a value is a theme ref.
|
|
88
|
+
*/
|
|
89
|
+
export const isThemeRef = (value) => typeof value === 'object' && value !== null && '__brand' in value && value.__brand === 'WebKitThemeRef';
|
|
90
|
+
/**
|
|
91
|
+
* Check if a value is a theme config object.
|
|
92
|
+
*/
|
|
93
|
+
export const isThemeConfig = (value) => {
|
|
94
|
+
if (typeof value !== 'object' || value === null) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
if (isThemeRef(value)) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
// Check if it looks like a ThemeConfig
|
|
101
|
+
const obj = value;
|
|
102
|
+
return (obj.colors !== undefined ||
|
|
103
|
+
obj.radii !== undefined ||
|
|
104
|
+
obj.spacing !== undefined ||
|
|
105
|
+
obj.typography !== undefined ||
|
|
106
|
+
obj.vars !== undefined);
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Register a custom theme.
|
|
110
|
+
*
|
|
111
|
+
* @param name - Theme name (must be unique)
|
|
112
|
+
* @param options - Theme options (base + config)
|
|
113
|
+
* @returns A typed theme reference
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* const custom = registerTheme('custom', {
|
|
118
|
+
* base: 'default',
|
|
119
|
+
* config: {
|
|
120
|
+
* vars: { '--ease-panel-radius': '14px' }
|
|
121
|
+
* }
|
|
122
|
+
* });
|
|
123
|
+
*
|
|
124
|
+
* initWebKit({ theme: custom });
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
export function registerTheme(name, options = {}) {
|
|
128
|
+
const { base = DEFAULT_THEME_NAME, config = {} } = options;
|
|
129
|
+
// Resolve base name
|
|
130
|
+
let baseName = null;
|
|
131
|
+
if (base !== null) {
|
|
132
|
+
baseName = isThemeRef(base) ? base.name : base;
|
|
133
|
+
// Validate base exists
|
|
134
|
+
if (!registry.has(baseName)) {
|
|
135
|
+
throw new Error(`[web-kit] Base theme "${baseName}" is not registered.`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Invalidate cache for themes that depend on this one (if re-registering)
|
|
139
|
+
if (registry.has(name)) {
|
|
140
|
+
for (const entry of registry.values()) {
|
|
141
|
+
if (entry.base === name) {
|
|
142
|
+
entry.resolved = null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
registry.set(name, {
|
|
147
|
+
name,
|
|
148
|
+
base: baseName,
|
|
149
|
+
config,
|
|
150
|
+
resolved: null
|
|
151
|
+
});
|
|
152
|
+
return {
|
|
153
|
+
__brand: 'WebKitThemeRef',
|
|
154
|
+
name
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get a theme's resolved configuration.
|
|
159
|
+
*
|
|
160
|
+
* @param theme - Theme name, ref, or inline config
|
|
161
|
+
* @returns Resolved theme configuration
|
|
162
|
+
*/
|
|
163
|
+
export function getTheme(theme) {
|
|
164
|
+
if (isThemeConfig(theme)) {
|
|
165
|
+
return theme;
|
|
166
|
+
}
|
|
167
|
+
const name = isThemeRef(theme) ? theme.name : theme;
|
|
168
|
+
return resolveThemeConfig(name);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Check if a theme is registered.
|
|
172
|
+
*/
|
|
173
|
+
export function hasTheme(name) {
|
|
174
|
+
return registry.has(name);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Get all registered theme names.
|
|
178
|
+
*/
|
|
179
|
+
export function getThemeNames() {
|
|
180
|
+
return Array.from(registry.keys());
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Create a theme ref for a registered theme name.
|
|
184
|
+
* Useful for type-safe references without module augmentation.
|
|
185
|
+
*/
|
|
186
|
+
export function themeRef(name) {
|
|
187
|
+
if (!registry.has(name)) {
|
|
188
|
+
throw new Error(`[web-kit] Theme "${name}" is not registered.`);
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
__brand: 'WebKitThemeRef',
|
|
192
|
+
name
|
|
193
|
+
};
|
|
194
|
+
}
|