@number10/jsx-core 5.0.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/LICENSE +667 -0
- package/README.md +38 -0
- package/dist/animation/animated-signal.cjs +19 -0
- package/dist/animation/animated-signal.cjs.map +1 -0
- package/dist/animation/animated-signal.d.ts +35 -0
- package/dist/animation/animated-signal.d.ts.map +1 -0
- package/dist/animation/animated-signal.js +19 -0
- package/dist/animation/animated-signal.js.map +1 -0
- package/dist/animation/create-spring.cjs +80 -0
- package/dist/animation/create-spring.cjs.map +1 -0
- package/dist/animation/create-spring.d.ts +56 -0
- package/dist/animation/create-spring.d.ts.map +1 -0
- package/dist/animation/create-spring.js +80 -0
- package/dist/animation/create-spring.js.map +1 -0
- package/dist/animation/easing.cjs +76 -0
- package/dist/animation/easing.cjs.map +1 -0
- package/dist/animation/easing.d.ts +45 -0
- package/dist/animation/easing.d.ts.map +1 -0
- package/dist/animation/easing.js +76 -0
- package/dist/animation/easing.js.map +1 -0
- package/dist/animation/effect-definitions.cjs +441 -0
- package/dist/animation/effect-definitions.cjs.map +1 -0
- package/dist/animation/effect-definitions.d.ts +60 -0
- package/dist/animation/effect-definitions.d.ts.map +1 -0
- package/dist/animation/effect-definitions.js +441 -0
- package/dist/animation/effect-definitions.js.map +1 -0
- package/dist/animation/effect-engine.cjs +189 -0
- package/dist/animation/effect-engine.cjs.map +1 -0
- package/dist/animation/effect-engine.d.ts +70 -0
- package/dist/animation/effect-engine.d.ts.map +1 -0
- package/dist/animation/effect-engine.js +189 -0
- package/dist/animation/effect-engine.js.map +1 -0
- package/dist/animation/index.d.ts +24 -0
- package/dist/animation/index.d.ts.map +1 -0
- package/dist/animation/spring-physics.cjs +94 -0
- package/dist/animation/spring-physics.cjs.map +1 -0
- package/dist/animation/spring-physics.d.ts +145 -0
- package/dist/animation/spring-physics.d.ts.map +1 -0
- package/dist/animation/spring-physics.js +94 -0
- package/dist/animation/spring-physics.js.map +1 -0
- package/dist/animation/tween.cjs +67 -0
- package/dist/animation/tween.cjs.map +1 -0
- package/dist/animation/tween.d.ts +60 -0
- package/dist/animation/tween.d.ts.map +1 -0
- package/dist/animation/tween.js +67 -0
- package/dist/animation/tween.js.map +1 -0
- package/dist/animation/types.d.ts +31 -0
- package/dist/animation/types.d.ts.map +1 -0
- package/dist/animation/useSpring.cjs +152 -0
- package/dist/animation/useSpring.cjs.map +1 -0
- package/dist/animation/useSpring.d.ts +55 -0
- package/dist/animation/useSpring.d.ts.map +1 -0
- package/dist/animation/useSpring.js +149 -0
- package/dist/animation/useSpring.js.map +1 -0
- package/dist/animation/useTween.cjs +208 -0
- package/dist/animation/useTween.cjs.map +1 -0
- package/dist/animation/useTween.d.ts +116 -0
- package/dist/animation/useTween.d.ts.map +1 -0
- package/dist/animation/useTween.js +208 -0
- package/dist/animation/useTween.js.map +1 -0
- package/dist/border-geometry.cjs +447 -0
- package/dist/border-geometry.cjs.map +1 -0
- package/dist/border-geometry.d.ts +114 -0
- package/dist/border-geometry.d.ts.map +1 -0
- package/dist/border-geometry.js +447 -0
- package/dist/border-geometry.js.map +1 -0
- package/dist/colors/color-presets.cjs +236 -0
- package/dist/colors/color-presets.cjs.map +1 -0
- package/dist/colors/color-presets.d.ts +89 -0
- package/dist/colors/color-presets.d.ts.map +1 -0
- package/dist/colors/color-presets.js +236 -0
- package/dist/colors/color-presets.js.map +1 -0
- package/dist/colors/color-theme-helpers.cjs +32 -0
- package/dist/colors/color-theme-helpers.cjs.map +1 -0
- package/dist/colors/color-theme-helpers.d.ts +65 -0
- package/dist/colors/color-theme-helpers.d.ts.map +1 -0
- package/dist/colors/color-theme-helpers.js +32 -0
- package/dist/colors/color-theme-helpers.js.map +1 -0
- package/dist/colors/color-types.cjs +38 -0
- package/dist/colors/color-types.cjs.map +1 -0
- package/dist/colors/color-types.d.ts +112 -0
- package/dist/colors/color-types.d.ts.map +1 -0
- package/dist/colors/color-types.js +38 -0
- package/dist/colors/color-types.js.map +1 -0
- package/dist/colors/color-utils.cjs +197 -0
- package/dist/colors/color-utils.cjs.map +1 -0
- package/dist/colors/color-utils.d.ts +216 -0
- package/dist/colors/color-utils.d.ts.map +1 -0
- package/dist/colors/color-utils.js +197 -0
- package/dist/colors/color-utils.js.map +1 -0
- package/dist/colors/contrast-contracts.cjs +265 -0
- package/dist/colors/contrast-contracts.cjs.map +1 -0
- package/dist/colors/contrast-contracts.d.ts +289 -0
- package/dist/colors/contrast-contracts.d.ts.map +1 -0
- package/dist/colors/contrast-contracts.js +265 -0
- package/dist/colors/contrast-contracts.js.map +1 -0
- package/dist/colors/index.cjs +55 -0
- package/dist/colors/index.cjs.map +1 -0
- package/dist/colors/index.d.ts +16 -0
- package/dist/colors/index.d.ts.map +1 -0
- package/dist/colors/index.js +55 -0
- package/dist/colors/index.js.map +1 -0
- package/dist/core-props.cjs +66 -0
- package/dist/core-props.cjs.map +1 -0
- package/dist/core-props.d.ts +395 -0
- package/dist/core-props.d.ts.map +1 -0
- package/dist/core-props.js +66 -0
- package/dist/core-props.js.map +1 -0
- package/dist/design-tokens/design-token-presets.cjs +91 -0
- package/dist/design-tokens/design-token-presets.cjs.map +1 -0
- package/dist/design-tokens/design-token-presets.d.ts +34 -0
- package/dist/design-tokens/design-token-presets.d.ts.map +1 -0
- package/dist/design-tokens/design-token-presets.js +91 -0
- package/dist/design-tokens/design-token-presets.js.map +1 -0
- package/dist/design-tokens/design-token-types.d.ts +97 -0
- package/dist/design-tokens/design-token-types.d.ts.map +1 -0
- package/dist/design-tokens/index.cjs +10 -0
- package/dist/design-tokens/index.cjs.map +1 -0
- package/dist/design-tokens/index.d.ts +9 -0
- package/dist/design-tokens/index.d.ts.map +1 -0
- package/dist/design-tokens/index.js +10 -0
- package/dist/design-tokens/index.js.map +1 -0
- package/dist/dev-config.cjs +296 -0
- package/dist/dev-config.cjs.map +1 -0
- package/dist/dev-config.d.ts +238 -0
- package/dist/dev-config.d.ts.map +1 -0
- package/dist/dev-config.js +296 -0
- package/dist/dev-config.js.map +1 -0
- package/dist/effects.cjs +69 -0
- package/dist/effects.cjs.map +1 -0
- package/dist/effects.d.ts +152 -0
- package/dist/effects.d.ts.map +1 -0
- package/dist/effects.js +69 -0
- package/dist/effects.js.map +1 -0
- package/dist/global-registry.cjs +25 -0
- package/dist/global-registry.cjs.map +1 -0
- package/dist/global-registry.d.ts +19 -0
- package/dist/global-registry.d.ts.map +1 -0
- package/dist/global-registry.js +25 -0
- package/dist/global-registry.js.map +1 -0
- package/dist/hooks.cjs +378 -0
- package/dist/hooks.cjs.map +1 -0
- package/dist/hooks.d.ts +322 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +378 -0
- package/dist/hooks.js.map +1 -0
- package/dist/host-adapter.d.ts +414 -0
- package/dist/host-adapter.d.ts.map +1 -0
- package/dist/index.cjs +229 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +226 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx-dev-runtime.cjs +10 -0
- package/dist/jsx-dev-runtime.cjs.map +1 -0
- package/dist/jsx-dev-runtime.d.ts +5 -0
- package/dist/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/jsx-dev-runtime.js +11 -0
- package/dist/jsx-dev-runtime.js.map +1 -0
- package/dist/jsx-runtime.cjs +44 -0
- package/dist/jsx-runtime.cjs.map +1 -0
- package/dist/jsx-runtime.d.ts +24 -0
- package/dist/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx-runtime.js +44 -0
- package/dist/jsx-runtime.js.map +1 -0
- package/dist/jsx-types.d.ts +25 -0
- package/dist/jsx-types.d.ts.map +1 -0
- package/dist/layout/appliers/container-applier.cjs +20 -0
- package/dist/layout/appliers/container-applier.cjs.map +1 -0
- package/dist/layout/appliers/container-applier.d.ts +9 -0
- package/dist/layout/appliers/container-applier.d.ts.map +1 -0
- package/dist/layout/appliers/container-applier.js +20 -0
- package/dist/layout/appliers/container-applier.js.map +1 -0
- package/dist/layout/appliers/position-applier.cjs +31 -0
- package/dist/layout/appliers/position-applier.cjs.map +1 -0
- package/dist/layout/appliers/position-applier.d.ts +8 -0
- package/dist/layout/appliers/position-applier.d.ts.map +1 -0
- package/dist/layout/appliers/position-applier.js +31 -0
- package/dist/layout/appliers/position-applier.js.map +1 -0
- package/dist/layout/layout-engine-test-utils.d.ts +26 -0
- package/dist/layout/layout-engine-test-utils.d.ts.map +1 -0
- package/dist/layout/layout-engine.cjs +628 -0
- package/dist/layout/layout-engine.cjs.map +1 -0
- package/dist/layout/layout-engine.d.ts +140 -0
- package/dist/layout/layout-engine.d.ts.map +1 -0
- package/dist/layout/layout-engine.js +628 -0
- package/dist/layout/layout-engine.js.map +1 -0
- package/dist/layout/strategies/base-strategy.cjs +31 -0
- package/dist/layout/strategies/base-strategy.cjs.map +1 -0
- package/dist/layout/strategies/base-strategy.d.ts +59 -0
- package/dist/layout/strategies/base-strategy.d.ts.map +1 -0
- package/dist/layout/strategies/base-strategy.js +31 -0
- package/dist/layout/strategies/base-strategy.js.map +1 -0
- package/dist/layout/strategies/column-layout.cjs +145 -0
- package/dist/layout/strategies/column-layout.cjs.map +1 -0
- package/dist/layout/strategies/column-layout.d.ts +38 -0
- package/dist/layout/strategies/column-layout.d.ts.map +1 -0
- package/dist/layout/strategies/column-layout.js +145 -0
- package/dist/layout/strategies/column-layout.js.map +1 -0
- package/dist/layout/strategies/row-layout.cjs +145 -0
- package/dist/layout/strategies/row-layout.cjs.map +1 -0
- package/dist/layout/strategies/row-layout.d.ts +38 -0
- package/dist/layout/strategies/row-layout.d.ts.map +1 -0
- package/dist/layout/strategies/row-layout.js +145 -0
- package/dist/layout/strategies/row-layout.js.map +1 -0
- package/dist/layout/strategies/stack-layout.cjs +94 -0
- package/dist/layout/strategies/stack-layout.cjs.map +1 -0
- package/dist/layout/strategies/stack-layout.d.ts +30 -0
- package/dist/layout/strategies/stack-layout.d.ts.map +1 -0
- package/dist/layout/strategies/stack-layout.js +94 -0
- package/dist/layout/strategies/stack-layout.js.map +1 -0
- package/dist/layout/types.d.ts +134 -0
- package/dist/layout/types.d.ts.map +1 -0
- package/dist/layout/utils/child-utils.cjs +129 -0
- package/dist/layout/utils/child-utils.cjs.map +1 -0
- package/dist/layout/utils/child-utils.d.ts +54 -0
- package/dist/layout/utils/child-utils.d.ts.map +1 -0
- package/dist/layout/utils/child-utils.js +129 -0
- package/dist/layout/utils/child-utils.js.map +1 -0
- package/dist/layout/utils/dimension-calculator.cjs +109 -0
- package/dist/layout/utils/dimension-calculator.cjs.map +1 -0
- package/dist/layout/utils/dimension-calculator.d.ts +59 -0
- package/dist/layout/utils/dimension-calculator.d.ts.map +1 -0
- package/dist/layout/utils/dimension-calculator.js +109 -0
- package/dist/layout/utils/dimension-calculator.js.map +1 -0
- package/dist/layout/utils/flex-distributor.cjs +173 -0
- package/dist/layout/utils/flex-distributor.cjs.map +1 -0
- package/dist/layout/utils/flex-distributor.d.ts +18 -0
- package/dist/layout/utils/flex-distributor.d.ts.map +1 -0
- package/dist/layout/utils/flex-distributor.js +173 -0
- package/dist/layout/utils/flex-distributor.js.map +1 -0
- package/dist/layout/utils/size-resolver.cjs +280 -0
- package/dist/layout/utils/size-resolver.cjs.map +1 -0
- package/dist/layout/utils/size-resolver.d.ts +84 -0
- package/dist/layout/utils/size-resolver.d.ts.map +1 -0
- package/dist/layout/utils/size-resolver.js +280 -0
- package/dist/layout/utils/size-resolver.js.map +1 -0
- package/dist/layout/utils/spacing-calculator.cjs +50 -0
- package/dist/layout/utils/spacing-calculator.cjs.map +1 -0
- package/dist/layout/utils/spacing-calculator.d.ts +27 -0
- package/dist/layout/utils/spacing-calculator.d.ts.map +1 -0
- package/dist/layout/utils/spacing-calculator.js +50 -0
- package/dist/layout/utils/spacing-calculator.js.map +1 -0
- package/dist/memo.cjs +18 -0
- package/dist/memo.cjs.map +1 -0
- package/dist/memo.d.ts +29 -0
- package/dist/memo.d.ts.map +1 -0
- package/dist/memo.js +18 -0
- package/dist/memo.js.map +1 -0
- package/dist/nineslice-contract.cjs +60 -0
- package/dist/nineslice-contract.cjs.map +1 -0
- package/dist/nineslice-contract.d.ts +107 -0
- package/dist/nineslice-contract.d.ts.map +1 -0
- package/dist/nineslice-contract.js +60 -0
- package/dist/nineslice-contract.js.map +1 -0
- package/dist/placeholder.cjs +12 -0
- package/dist/placeholder.cjs.map +1 -0
- package/dist/placeholder.d.ts +44 -0
- package/dist/placeholder.d.ts.map +1 -0
- package/dist/placeholder.js +12 -0
- package/dist/placeholder.js.map +1 -0
- package/dist/portal.cjs +89 -0
- package/dist/portal.cjs.map +1 -0
- package/dist/portal.d.ts +62 -0
- package/dist/portal.d.ts.map +1 -0
- package/dist/portal.js +89 -0
- package/dist/portal.js.map +1 -0
- package/dist/primitive-contracts.cjs +12 -0
- package/dist/primitive-contracts.cjs.map +1 -0
- package/dist/primitive-contracts.d.ts +186 -0
- package/dist/primitive-contracts.d.ts.map +1 -0
- package/dist/primitive-contracts.js +12 -0
- package/dist/primitive-contracts.js.map +1 -0
- package/dist/theme.cjs +332 -0
- package/dist/theme.cjs.map +1 -0
- package/dist/theme.d.ts +204 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +332 -0
- package/dist/theme.js.map +1 -0
- package/dist/types.d.ts +86 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/vdom/create-runtime.cjs +79 -0
- package/dist/vdom/create-runtime.cjs.map +1 -0
- package/dist/vdom/create-runtime.d.ts +7 -0
- package/dist/vdom/create-runtime.d.ts.map +1 -0
- package/dist/vdom/create-runtime.js +79 -0
- package/dist/vdom/create-runtime.js.map +1 -0
- package/dist/vdom/index.cjs +8 -0
- package/dist/vdom/index.cjs.map +1 -0
- package/dist/vdom/index.d.ts +4 -0
- package/dist/vdom/index.d.ts.map +1 -0
- package/dist/vdom/index.js +8 -0
- package/dist/vdom/index.js.map +1 -0
- package/dist/vdom/mount.cjs +161 -0
- package/dist/vdom/mount.cjs.map +1 -0
- package/dist/vdom/mount.d.ts +6 -0
- package/dist/vdom/mount.d.ts.map +1 -0
- package/dist/vdom/mount.js +161 -0
- package/dist/vdom/mount.js.map +1 -0
- package/dist/vdom/patch.cjs +163 -0
- package/dist/vdom/patch.cjs.map +1 -0
- package/dist/vdom/patch.d.ts +3 -0
- package/dist/vdom/patch.d.ts.map +1 -0
- package/dist/vdom/patch.js +163 -0
- package/dist/vdom/patch.js.map +1 -0
- package/dist/vdom/registry.cjs +85 -0
- package/dist/vdom/registry.cjs.map +1 -0
- package/dist/vdom/registry.d.ts +28 -0
- package/dist/vdom/registry.d.ts.map +1 -0
- package/dist/vdom/registry.js +85 -0
- package/dist/vdom/registry.js.map +1 -0
- package/dist/vdom/runtime-helpers.cjs +23 -0
- package/dist/vdom/runtime-helpers.cjs.map +1 -0
- package/dist/vdom/runtime-helpers.d.ts +8 -0
- package/dist/vdom/runtime-helpers.d.ts.map +1 -0
- package/dist/vdom/runtime-helpers.js +23 -0
- package/dist/vdom/runtime-helpers.js.map +1 -0
- package/dist/vdom/surface.cjs +107 -0
- package/dist/vdom/surface.cjs.map +1 -0
- package/dist/vdom/surface.d.ts +9 -0
- package/dist/vdom/surface.d.ts.map +1 -0
- package/dist/vdom/surface.js +107 -0
- package/dist/vdom/surface.js.map +1 -0
- package/dist/vdom/types.d.ts +104 -0
- package/dist/vdom/types.d.ts.map +1 -0
- package/dist/vdom/utils.cjs +146 -0
- package/dist/vdom/utils.cjs.map +1 -0
- package/dist/vdom/utils.d.ts +24 -0
- package/dist/vdom/utils.d.ts.map +1 -0
- package/dist/vdom/utils.js +146 -0
- package/dist/vdom/utils.js.map +1 -0
- package/dist/vdom.d.ts +4 -0
- package/dist/vdom.d.ts.map +1 -0
- package/dist/vector-draw-context.d.ts +63 -0
- package/dist/vector-draw-context.d.ts.map +1 -0
- package/package.json +161 -0
- package/vdom/index.cjs +1 -0
- package/vdom/index.d.ts +1 -0
- package/vdom/index.js +1 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { BackgroundProps, GestureProps, LayoutProps, SizeValue, TransformProps } from './core-props';
|
|
2
|
+
import { PropsContainerExtension, PropsDefaultExtension } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Stable host-node type names for renderer-neutral primitives.
|
|
5
|
+
*
|
|
6
|
+
* These are the `type` values passed to `HostAdapter.create()` and used
|
|
7
|
+
* in JSX as lowercase tags (`<view/>`, `<text/>`, ...).
|
|
8
|
+
* Each renderer registers HostDescriptors for these names.
|
|
9
|
+
*
|
|
10
|
+
* Portable components MUST NOT use these directly in JSX.
|
|
11
|
+
* They use the uppercase wrappers from `@number10/jsx-components/primitives`.
|
|
12
|
+
*/
|
|
13
|
+
export declare const PRIMITIVE_NODES: {
|
|
14
|
+
readonly View: "view";
|
|
15
|
+
readonly Text: "text";
|
|
16
|
+
readonly Image: "image";
|
|
17
|
+
readonly Sprite: "sprite";
|
|
18
|
+
readonly VectorDrawContent: "vectorDraw";
|
|
19
|
+
readonly NineSlice: "nineslice";
|
|
20
|
+
};
|
|
21
|
+
/** Host-node type names for renderer-neutral primitives */
|
|
22
|
+
export type PrimitiveNodeType = (typeof PRIMITIVE_NODES)[keyof typeof PRIMITIVE_NODES];
|
|
23
|
+
/**
|
|
24
|
+
* Portable props for the View primitive.
|
|
25
|
+
* Every renderer must support: layout, transform, background styling, and alpha.
|
|
26
|
+
*/
|
|
27
|
+
export interface ViewPrimitiveProps extends TransformProps, LayoutProps, BackgroundProps, GestureProps {
|
|
28
|
+
/**
|
|
29
|
+
* Alpha transparency of the element.
|
|
30
|
+
* - 0: Fully transparent
|
|
31
|
+
* - 1: Fully opaque (default)
|
|
32
|
+
*/
|
|
33
|
+
alpha?: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Complete View props including JSX extensions.
|
|
37
|
+
* The generic parameter allows renderers to specify their native node type for Refs.
|
|
38
|
+
*
|
|
39
|
+
* @typeParam TNode - The renderer's native node type (e.g., Phaser.GameObjects.Container)
|
|
40
|
+
*/
|
|
41
|
+
export interface ViewPrimitivePropsComplete<TNode = unknown> extends ViewPrimitiveProps, PropsDefaultExtension<TNode>, PropsContainerExtension {
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Portable text style — renderer-neutral text formatting.
|
|
45
|
+
* Each renderer maps this to its native text style type.
|
|
46
|
+
*/
|
|
47
|
+
export interface PortableTextStyle {
|
|
48
|
+
fontSize?: string | number;
|
|
49
|
+
fontFamily?: string;
|
|
50
|
+
fontStyle?: string;
|
|
51
|
+
fontWeight?: string | number;
|
|
52
|
+
color?: string | number;
|
|
53
|
+
backgroundColor?: string | number;
|
|
54
|
+
align?: 'left' | 'center' | 'right' | 'justify';
|
|
55
|
+
lineHeight?: number;
|
|
56
|
+
shadow?: {
|
|
57
|
+
color?: string | number;
|
|
58
|
+
blur?: number;
|
|
59
|
+
offsetX?: number;
|
|
60
|
+
offsetY?: number;
|
|
61
|
+
alpha?: number;
|
|
62
|
+
fill?: boolean;
|
|
63
|
+
stroke?: boolean;
|
|
64
|
+
} | undefined;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Portable props for the Text primitive.
|
|
68
|
+
*/
|
|
69
|
+
export interface TextPrimitiveProps extends TransformProps, LayoutProps, GestureProps {
|
|
70
|
+
/** The text content to display */
|
|
71
|
+
text: string | undefined;
|
|
72
|
+
/** Maximum width for text wrapping */
|
|
73
|
+
maxWidth?: SizeValue;
|
|
74
|
+
/** Portable text style — renderer maps to native style. Named 'style' for compat with Phaser's TextProps. */
|
|
75
|
+
style?: PortableTextStyle | undefined;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Complete Text props including JSX extensions.
|
|
79
|
+
*/
|
|
80
|
+
export interface TextPrimitivePropsComplete<TNode = unknown> extends TextPrimitiveProps, PropsDefaultExtension<TNode>, PropsContainerExtension {
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Portable props for the Image primitive.
|
|
84
|
+
*/
|
|
85
|
+
export interface ImagePrimitiveProps extends TransformProps, LayoutProps {
|
|
86
|
+
/** Texture key or URL */
|
|
87
|
+
texture: string;
|
|
88
|
+
/** Optional tint color */
|
|
89
|
+
tint?: number | undefined;
|
|
90
|
+
/** Optional frame from texture atlas */
|
|
91
|
+
frame?: string | undefined;
|
|
92
|
+
/**
|
|
93
|
+
* Optional explicit source region within the texture/frame.
|
|
94
|
+
*
|
|
95
|
+
* When set, the image only renders this sub-rectangle of the source
|
|
96
|
+
* texture. Coordinates are relative to the frame origin (if `frame`
|
|
97
|
+
* is specified) or the texture origin otherwise.
|
|
98
|
+
*
|
|
99
|
+
* Enables portable NineSlice: each slice cell is an `<Image>` with
|
|
100
|
+
* its own `sourceRect` computed from the frame geometry.
|
|
101
|
+
*/
|
|
102
|
+
sourceRect?: {
|
|
103
|
+
x: number;
|
|
104
|
+
y: number;
|
|
105
|
+
w: number;
|
|
106
|
+
h: number;
|
|
107
|
+
} | undefined;
|
|
108
|
+
/** Display width — scaled rendering size (defaults to texture width) */
|
|
109
|
+
displayWidth?: number | undefined;
|
|
110
|
+
/** Display height — scaled rendering size (defaults to texture height) */
|
|
111
|
+
displayHeight?: number | undefined;
|
|
112
|
+
/**
|
|
113
|
+
* How image fits within displayWidth/displayHeight bounds.
|
|
114
|
+
* - 'fill': Stretch to fill (default, may distort aspect ratio)
|
|
115
|
+
* - 'contain': Scale to fit within bounds, preserve aspect ratio
|
|
116
|
+
* - 'cover': Scale to cover bounds, preserve aspect ratio (may crop)
|
|
117
|
+
*/
|
|
118
|
+
fit?: 'fill' | 'contain' | 'cover' | undefined;
|
|
119
|
+
/** Origin X anchor point (0-1, default 0.5 for headless, 0 for layout) */
|
|
120
|
+
originX?: number | undefined;
|
|
121
|
+
/** Origin Y anchor point (0-1, default 0.5 for headless, 0 for layout) */
|
|
122
|
+
originY?: number | undefined;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Complete Image props including JSX extensions.
|
|
126
|
+
*/
|
|
127
|
+
export interface ImagePrimitivePropsComplete<TNode = unknown> extends ImagePrimitiveProps, PropsDefaultExtension<TNode> {
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Portable props for the Sprite primitive.
|
|
131
|
+
*/
|
|
132
|
+
export interface SpritePrimitiveProps extends TransformProps, LayoutProps {
|
|
133
|
+
/** Texture key or URL */
|
|
134
|
+
texture: string;
|
|
135
|
+
/** Optional tint color */
|
|
136
|
+
tint?: number;
|
|
137
|
+
/** Optional frame from texture atlas */
|
|
138
|
+
frame?: string;
|
|
139
|
+
/** Optional animation key to play on mount */
|
|
140
|
+
anim?: string;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Complete Sprite props including JSX extensions.
|
|
144
|
+
*/
|
|
145
|
+
export interface SpritePrimitivePropsComplete<TNode = unknown> extends SpritePrimitiveProps, PropsDefaultExtension<TNode> {
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Portable Components MUST follow this import style:
|
|
149
|
+
*
|
|
150
|
+
* ```typescript
|
|
151
|
+
* // ✅ CORRECT — only Core imports
|
|
152
|
+
* import type { ViewPrimitiveProps, TextPrimitiveProps } from '@number10/jsx-core'
|
|
153
|
+
* import { useState, useEffect, useTheme } from '@number10/jsx-core'
|
|
154
|
+
* import type { LayoutProps, TransformProps } from '@number10/jsx-core'
|
|
155
|
+
* import type { VNode, Ref } from '@number10/jsx-core'
|
|
156
|
+
*
|
|
157
|
+
* // ✅ CORRECT — renderer provides the actual primitives
|
|
158
|
+
* // (imported by the app, passed via JSX or context, not imported in the component)
|
|
159
|
+
*
|
|
160
|
+
* // ❌ WRONG — Phaser-specific imports in portable components
|
|
161
|
+
* // import type { PhaserProps } from '@number10/jsx-phaser'
|
|
162
|
+
* // import { useScene } from '@number10/jsx-phaser'
|
|
163
|
+
* // import type * as Phaser from 'phaser'
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
/**
|
|
167
|
+
* The following primitives are OPTIONAL capabilities. A renderer MAY support
|
|
168
|
+
* them. Portable components SHOULD NOT depend on them unless the capability
|
|
169
|
+
* is explicitly checked via `SurfaceContext.capabilities`.
|
|
170
|
+
*
|
|
171
|
+
* | Primitive | Capability Key | Type in PRIMITIVE_NODES | Notes |
|
|
172
|
+
* |-------------|-----------------|-------------------------|-------|
|
|
173
|
+
* | NineSlice | `nineslice` | `'nineslice'` | First-class primitive in PRIMITIVE_NODES; single-node native 9-slice |
|
|
174
|
+
* | TileSprite | `tilesprite` | — | Tiled texture background |
|
|
175
|
+
* | VectorDraw | `drawing` | `'vectorDraw'` | Portable imperative drawing API |
|
|
176
|
+
* | Particles | `particles` | — | Renderer-native particle system |
|
|
177
|
+
*
|
|
178
|
+
* Portable components that need these should:
|
|
179
|
+
* 1. Check `SurfaceContext.capabilities.has('nineslice')` before use
|
|
180
|
+
* 2. Provide a fallback (e.g., use View+Image instead of NineSlice)
|
|
181
|
+
* 3. OR accept them as optional child/overlay via props
|
|
182
|
+
*/
|
|
183
|
+
export { computeSourceSlices, computeTargetXs, computeTargetYs, deriveTargetRects, } from './nineslice-contract';
|
|
184
|
+
export type { NineSlicePrimitiveProps, NineSlicePrimitivePropsComplete, SliceRect, } from './nineslice-contract';
|
|
185
|
+
export type { VectorDrawContentPrimitivePropsComplete } from './vector-draw-context';
|
|
186
|
+
//# sourceMappingURL=primitive-contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitive-contracts.d.ts","sourceRoot":"","sources":["../src/primitive-contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitive-contracts.js","sources":["../src/primitive-contracts.ts"],"sourcesContent":["/**\n * Portable Primitive Contracts — renderer-neutral prop interfaces for\n * View, Text, Image, and Sprite primitives.\n *\n * These contracts define the MINIMAL prop set that every renderer must\n * support. Each renderer package extends these with renderer-specific\n * props (e.g., Phaser adds PhaserProps and onReady).\n *\n * Portable Components MUST only import from this file and other Core modules.\n * They MUST NOT import from renderer-specific packages or Phaser directly.\n *\n * @migration(audit:scene-portal-mount) Phase 4B — defined in @number10/jsx-core.\n * Renderer implementations live in the renderer package.\n */\n\nimport type {\n BackgroundProps,\n GestureProps,\n LayoutProps,\n SizeValue,\n TransformProps,\n} from './core-props'\nimport type { PropsContainerExtension, PropsDefaultExtension } from './types'\n\n// ---------------------------------------------------------------------------\n// Primitive Host-Node Names\n// ---------------------------------------------------------------------------\n\n/**\n * Stable host-node type names for renderer-neutral primitives.\n *\n * These are the `type` values passed to `HostAdapter.create()` and used\n * in JSX as lowercase tags (`<view/>`, `<text/>`, ...).\n * Each renderer registers HostDescriptors for these names.\n *\n * Portable components MUST NOT use these directly in JSX.\n * They use the uppercase wrappers from `@number10/jsx-components/primitives`.\n */\nexport const PRIMITIVE_NODES = {\n View: 'view',\n Text: 'text',\n Image: 'image',\n Sprite: 'sprite',\n VectorDrawContent: 'vectorDraw',\n NineSlice: 'nineslice',\n} as const\n\n/** Host-node type names for renderer-neutral primitives */\nexport type PrimitiveNodeType = (typeof PRIMITIVE_NODES)[keyof typeof PRIMITIVE_NODES]\n\n// ---------------------------------------------------------------------------\n// View — the fundamental layout container\n// ---------------------------------------------------------------------------\n\n/**\n * Portable props for the View primitive.\n * Every renderer must support: layout, transform, background styling, and alpha.\n */\nexport interface ViewPrimitiveProps\n extends TransformProps, LayoutProps, BackgroundProps, GestureProps {\n /**\n * Alpha transparency of the element.\n * - 0: Fully transparent\n * - 1: Fully opaque (default)\n */\n alpha?: number\n}\n\n/**\n * Complete View props including JSX extensions.\n * The generic parameter allows renderers to specify their native node type for Refs.\n *\n * @typeParam TNode - The renderer's native node type (e.g., Phaser.GameObjects.Container)\n */\nexport interface ViewPrimitivePropsComplete<TNode = unknown>\n extends ViewPrimitiveProps, PropsDefaultExtension<TNode>, PropsContainerExtension {}\n\n// ---------------------------------------------------------------------------\n// Text — text rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Portable text style — renderer-neutral text formatting.\n * Each renderer maps this to its native text style type.\n */\nexport interface PortableTextStyle {\n fontSize?: string | number\n fontFamily?: string\n fontStyle?: string\n fontWeight?: string | number\n color?: string | number\n backgroundColor?: string | number\n align?: 'left' | 'center' | 'right' | 'justify'\n lineHeight?: number\n shadow?:\n | {\n color?: string | number\n blur?: number\n offsetX?: number\n offsetY?: number\n alpha?: number\n fill?: boolean\n stroke?: boolean\n }\n | undefined\n}\n\n/**\n * Portable props for the Text primitive.\n */\nexport interface TextPrimitiveProps extends TransformProps, LayoutProps, GestureProps {\n /** The text content to display */\n text: string | undefined\n /** Maximum width for text wrapping */\n maxWidth?: SizeValue\n /** Portable text style — renderer maps to native style. Named 'style' for compat with Phaser's TextProps. */\n style?: PortableTextStyle | undefined\n}\n\n/**\n * Complete Text props including JSX extensions.\n */\nexport interface TextPrimitivePropsComplete<TNode = unknown>\n extends TextPrimitiveProps, PropsDefaultExtension<TNode>, PropsContainerExtension {}\n\n// ---------------------------------------------------------------------------\n// Image — texture-backed image display\n// ---------------------------------------------------------------------------\n\n/**\n * Portable props for the Image primitive.\n */\nexport interface ImagePrimitiveProps extends TransformProps, LayoutProps {\n /** Texture key or URL */\n texture: string\n /** Optional tint color */\n tint?: number | undefined\n /** Optional frame from texture atlas */\n frame?: string | undefined\n /**\n * Optional explicit source region within the texture/frame.\n *\n * When set, the image only renders this sub-rectangle of the source\n * texture. Coordinates are relative to the frame origin (if `frame`\n * is specified) or the texture origin otherwise.\n *\n * Enables portable NineSlice: each slice cell is an `<Image>` with\n * its own `sourceRect` computed from the frame geometry.\n */\n sourceRect?: { x: number; y: number; w: number; h: number } | undefined\n /** Display width — scaled rendering size (defaults to texture width) */\n displayWidth?: number | undefined\n /** Display height — scaled rendering size (defaults to texture height) */\n displayHeight?: number | undefined\n /**\n * How image fits within displayWidth/displayHeight bounds.\n * - 'fill': Stretch to fill (default, may distort aspect ratio)\n * - 'contain': Scale to fit within bounds, preserve aspect ratio\n * - 'cover': Scale to cover bounds, preserve aspect ratio (may crop)\n */\n fit?: 'fill' | 'contain' | 'cover' | undefined\n /** Origin X anchor point (0-1, default 0.5 for headless, 0 for layout) */\n originX?: number | undefined\n /** Origin Y anchor point (0-1, default 0.5 for headless, 0 for layout) */\n originY?: number | undefined\n}\n\n/**\n * Complete Image props including JSX extensions.\n */\nexport interface ImagePrimitivePropsComplete<TNode = unknown>\n extends ImagePrimitiveProps, PropsDefaultExtension<TNode> {}\n\n// ---------------------------------------------------------------------------\n// Sprite — animated texture-backed display\n// ---------------------------------------------------------------------------\n\n/**\n * Portable props for the Sprite primitive.\n */\nexport interface SpritePrimitiveProps extends TransformProps, LayoutProps {\n /** Texture key or URL */\n texture: string\n /** Optional tint color */\n tint?: number\n /** Optional frame from texture atlas */\n frame?: string\n /** Optional animation key to play on mount */\n anim?: string\n}\n\n/**\n * Complete Sprite props including JSX extensions.\n */\nexport interface SpritePrimitivePropsComplete<TNode = unknown>\n extends SpritePrimitiveProps, PropsDefaultExtension<TNode> {}\n\n// ---------------------------------------------------------------------------\n// Component Import Style — the contract for portable components\n// ---------------------------------------------------------------------------\n\n/**\n * Portable Components MUST follow this import style:\n *\n * ```typescript\n * // ✅ CORRECT — only Core imports\n * import type { ViewPrimitiveProps, TextPrimitiveProps } from '@number10/jsx-core'\n * import { useState, useEffect, useTheme } from '@number10/jsx-core'\n * import type { LayoutProps, TransformProps } from '@number10/jsx-core'\n * import type { VNode, Ref } from '@number10/jsx-core'\n *\n * // ✅ CORRECT — renderer provides the actual primitives\n * // (imported by the app, passed via JSX or context, not imported in the component)\n *\n * // ❌ WRONG — Phaser-specific imports in portable components\n * // import type { PhaserProps } from '@number10/jsx-phaser'\n * // import { useScene } from '@number10/jsx-phaser'\n * // import type * as Phaser from 'phaser'\n * ```\n */\n\n// ---------------------------------------------------------------------------\n// Optional Primitive Capabilities\n// ---------------------------------------------------------------------------\n\n/**\n * The following primitives are OPTIONAL capabilities. A renderer MAY support\n * them. Portable components SHOULD NOT depend on them unless the capability\n * is explicitly checked via `SurfaceContext.capabilities`.\n *\n * | Primitive | Capability Key | Type in PRIMITIVE_NODES | Notes |\n * |-------------|-----------------|-------------------------|-------|\n * | NineSlice | `nineslice` | `'nineslice'` | First-class primitive in PRIMITIVE_NODES; single-node native 9-slice |\n * | TileSprite | `tilesprite` | — | Tiled texture background |\n * | VectorDraw | `drawing` | `'vectorDraw'` | Portable imperative drawing API |\n * | Particles | `particles` | — | Renderer-native particle system |\n *\n * Portable components that need these should:\n * 1. Check `SurfaceContext.capabilities.has('nineslice')` before use\n * 2. Provide a fallback (e.g., use View+Image instead of NineSlice)\n * 3. OR accept them as optional child/overlay via props\n */\n\nexport {\n computeSourceSlices,\n computeTargetXs,\n computeTargetYs,\n deriveTargetRects,\n} from './nineslice-contract'\nexport type {\n NineSlicePrimitiveProps,\n NineSlicePrimitivePropsComplete,\n SliceRect,\n} from './nineslice-contract'\n\nexport type { VectorDrawContentPrimitivePropsComplete } from './vector-draw-context'\n"],"names":[],"mappings":"AAsCO,MAAM,kBAAkB;AAAA,EAC7B,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,mBAAmB;AAAA,EACnB,WAAW;AACb;"}
|
package/dist/theme.cjs
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const colorPresets = require("./colors/color-presets.cjs");
|
|
4
|
+
const devConfig = require("./dev-config.cjs");
|
|
5
|
+
function extractNestedThemes(props, knownComponents) {
|
|
6
|
+
const ownProps = { ...props };
|
|
7
|
+
const nestedThemes = {};
|
|
8
|
+
for (const key of knownComponents) {
|
|
9
|
+
if (key in ownProps) {
|
|
10
|
+
nestedThemes[key] = ownProps[key];
|
|
11
|
+
delete ownProps[key];
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
ownProps,
|
|
16
|
+
nestedThemes
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function deepMergeDefined(base, override) {
|
|
20
|
+
const result = { ...base };
|
|
21
|
+
for (const key of Object.keys(override)) {
|
|
22
|
+
const overrideVal = override[key];
|
|
23
|
+
if (overrideVal === void 0) continue;
|
|
24
|
+
if (isPlainObject(overrideVal) && isPlainObject(result[key])) {
|
|
25
|
+
result[key] = deepMergeDefined(result[key], overrideVal);
|
|
26
|
+
} else {
|
|
27
|
+
result[key] = overrideVal;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
const PRIMITIVE_THEME_COMPONENT_NAMES = {
|
|
33
|
+
view: "View",
|
|
34
|
+
text: "Text",
|
|
35
|
+
image: "Image",
|
|
36
|
+
sprite: "Sprite"
|
|
37
|
+
};
|
|
38
|
+
function normalizeThemeComponentName(componentName) {
|
|
39
|
+
return PRIMITIVE_THEME_COMPONENT_NAMES[componentName] ?? componentName;
|
|
40
|
+
}
|
|
41
|
+
function mergeThemes(base, override) {
|
|
42
|
+
if (!base) return override ?? {};
|
|
43
|
+
if (!override) return base;
|
|
44
|
+
const result = { ...base };
|
|
45
|
+
for (const key of Object.keys(override)) {
|
|
46
|
+
const overrideVal = override[key];
|
|
47
|
+
if (overrideVal === void 0) continue;
|
|
48
|
+
if (isPlainObject(overrideVal) && isPlainObject(result[key])) {
|
|
49
|
+
result[key] = deepMergeDefined(result[key], overrideVal);
|
|
50
|
+
} else {
|
|
51
|
+
result[key] = overrideVal;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
function isPlainObject(value) {
|
|
57
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
58
|
+
}
|
|
59
|
+
function resolveThemeComponentTheme(theme, componentName) {
|
|
60
|
+
if (!theme) return {};
|
|
61
|
+
const normalizedName = normalizeThemeComponentName(componentName);
|
|
62
|
+
const candidates = normalizedName === componentName ? [componentName] : [normalizedName, componentName];
|
|
63
|
+
let merged = {};
|
|
64
|
+
for (const candidate of candidates) {
|
|
65
|
+
const entry = theme[candidate];
|
|
66
|
+
if (!entry) continue;
|
|
67
|
+
merged = deepMergeDefined(merged, entry);
|
|
68
|
+
}
|
|
69
|
+
return merged;
|
|
70
|
+
}
|
|
71
|
+
function resolveComponentTheme(options) {
|
|
72
|
+
const { componentName, globalTheme, localTheme, explicitProps = {}, knownComponents } = options;
|
|
73
|
+
const normalizedComponentName = normalizeThemeComponentName(componentName);
|
|
74
|
+
const componentSet = knownComponents ?? /* @__PURE__ */ new Set();
|
|
75
|
+
const globalComponentTheme = resolveThemeComponentTheme(globalTheme, normalizedComponentName);
|
|
76
|
+
const { ownProps: globalOwnProps, nestedThemes: globalNested } = extractNestedThemes(
|
|
77
|
+
globalComponentTheme,
|
|
78
|
+
componentSet
|
|
79
|
+
);
|
|
80
|
+
const localComponentTheme = resolveThemeComponentTheme(localTheme, normalizedComponentName);
|
|
81
|
+
const { ownProps: localOwnProps, nestedThemes: localNested } = extractNestedThemes(
|
|
82
|
+
localComponentTheme,
|
|
83
|
+
componentSet
|
|
84
|
+
);
|
|
85
|
+
const { nestedThemes: localThemeNested } = extractNestedThemes(
|
|
86
|
+
localTheme ?? {},
|
|
87
|
+
componentSet
|
|
88
|
+
);
|
|
89
|
+
const { ownProps: explicitOwnProps, nestedThemes: explicitNested } = extractNestedThemes(
|
|
90
|
+
explicitProps,
|
|
91
|
+
componentSet
|
|
92
|
+
);
|
|
93
|
+
const mergedProps = deepMergeDefined(
|
|
94
|
+
deepMergeDefined(globalOwnProps, localOwnProps),
|
|
95
|
+
explicitOwnProps
|
|
96
|
+
);
|
|
97
|
+
const mergedNested = mergeThemes(
|
|
98
|
+
mergeThemes(mergeThemes(globalNested, localNested), localThemeNested),
|
|
99
|
+
explicitNested
|
|
100
|
+
);
|
|
101
|
+
return { props: mergedProps, nestedTheme: mergedNested };
|
|
102
|
+
}
|
|
103
|
+
const _themeDefaults = {};
|
|
104
|
+
const _themeDefaultProviders = {};
|
|
105
|
+
let themeRemountHandler = null;
|
|
106
|
+
function assignThemeDefaults(target, source) {
|
|
107
|
+
for (const key of Object.keys(target)) {
|
|
108
|
+
delete target[key];
|
|
109
|
+
}
|
|
110
|
+
Object.assign(target, source);
|
|
111
|
+
return target;
|
|
112
|
+
}
|
|
113
|
+
function providerFromInput(input) {
|
|
114
|
+
return typeof input === "function" ? input : () => input;
|
|
115
|
+
}
|
|
116
|
+
function rebuildRegisteredDefaults(presetName = "oceanBlue", mode = "light") {
|
|
117
|
+
const preset = colorPresets.getPresetWithMode(presetName, mode);
|
|
118
|
+
return assignThemeDefaults(_themeDefaults, createDefaultTheme(presetName, mode, preset.colors));
|
|
119
|
+
}
|
|
120
|
+
function setThemeRemountHandler(handler) {
|
|
121
|
+
themeRemountHandler = handler;
|
|
122
|
+
}
|
|
123
|
+
const KNOWN_COMPONENTS = /* @__PURE__ */ new Set(["View", "Text", "Icon", "Image", "Sprite"]);
|
|
124
|
+
function registerComponentThemeDefaults(componentName, defaults) {
|
|
125
|
+
_themeDefaultProviders[componentName] = providerFromInput(defaults);
|
|
126
|
+
KNOWN_COMPONENTS.add(componentName);
|
|
127
|
+
rebuildRegisteredDefaults();
|
|
128
|
+
}
|
|
129
|
+
function registerComponentDefaults(componentName, defaults) {
|
|
130
|
+
registerComponentThemeDefaults(componentName, defaults);
|
|
131
|
+
}
|
|
132
|
+
function registerComponentDefaultsIfMissing(componentName, defaults) {
|
|
133
|
+
if (_themeDefaultProviders[componentName]) {
|
|
134
|
+
KNOWN_COMPONENTS.add(componentName);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
registerComponentThemeDefaults(componentName, defaults);
|
|
138
|
+
}
|
|
139
|
+
function createDefaultTheme(presetName = "oceanBlue", mode = "light", colors = colorPresets.getPresetWithMode(presetName, mode).colors) {
|
|
140
|
+
const theme = {};
|
|
141
|
+
for (const [componentName, provider] of Object.entries(_themeDefaultProviders)) {
|
|
142
|
+
theme[componentName] = provider(colors);
|
|
143
|
+
}
|
|
144
|
+
return theme;
|
|
145
|
+
}
|
|
146
|
+
const defaultTheme = _themeDefaults;
|
|
147
|
+
class ThemeRegistry {
|
|
148
|
+
globalTheme = void 0;
|
|
149
|
+
customThemes = /* @__PURE__ */ new Map();
|
|
150
|
+
colorTokens = void 0;
|
|
151
|
+
colorMode = "light";
|
|
152
|
+
currentPresetName = void 0;
|
|
153
|
+
listeners = /* @__PURE__ */ new Set();
|
|
154
|
+
cachedComponentNames = null;
|
|
155
|
+
invalidateComponentNamesCache() {
|
|
156
|
+
this.cachedComponentNames = null;
|
|
157
|
+
}
|
|
158
|
+
getAllComponentNames() {
|
|
159
|
+
if (this.cachedComponentNames) return this.cachedComponentNames;
|
|
160
|
+
const internalPrimitiveNames = /* @__PURE__ */ new Set([
|
|
161
|
+
"view",
|
|
162
|
+
"text",
|
|
163
|
+
"nineslice",
|
|
164
|
+
"sprite",
|
|
165
|
+
"image",
|
|
166
|
+
"graphics",
|
|
167
|
+
"vectorDraw",
|
|
168
|
+
"tilesprite",
|
|
169
|
+
"particles"
|
|
170
|
+
]);
|
|
171
|
+
this.cachedComponentNames = new Set(
|
|
172
|
+
Object.keys(this.getGlobalTheme()).concat(Array.from(this.customThemes.keys())).filter((key) => key !== "__colorPreset" && !internalPrimitiveNames.has(key))
|
|
173
|
+
);
|
|
174
|
+
return this.cachedComponentNames;
|
|
175
|
+
}
|
|
176
|
+
getGlobalTheme() {
|
|
177
|
+
return {
|
|
178
|
+
...defaultTheme,
|
|
179
|
+
...this.globalTheme ?? {},
|
|
180
|
+
...Object.fromEntries(this.customThemes)
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
updateGlobalTheme(theme) {
|
|
184
|
+
const nextTheme = { ...this.globalTheme ?? {} };
|
|
185
|
+
for (const [component, styles] of Object.entries(theme)) {
|
|
186
|
+
if (component === "__colorPreset") {
|
|
187
|
+
nextTheme[component] = styles;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
const existing = nextTheme[component] ?? this.getGlobalTheme()[component] ?? {};
|
|
191
|
+
nextTheme[component] = deepMergeDefined(existing, styles ?? {});
|
|
192
|
+
devConfig.DebugLogger.log("theme", `Updated ${component} theme:`, nextTheme[component]);
|
|
193
|
+
}
|
|
194
|
+
this.globalTheme = nextTheme;
|
|
195
|
+
this.notifyListeners();
|
|
196
|
+
this.invalidateComponentNamesCache();
|
|
197
|
+
}
|
|
198
|
+
setGlobalTheme(theme) {
|
|
199
|
+
this.globalTheme = { ...theme };
|
|
200
|
+
this.invalidateComponentNamesCache();
|
|
201
|
+
}
|
|
202
|
+
resetGlobalTheme() {
|
|
203
|
+
this.globalTheme = void 0;
|
|
204
|
+
this.customThemes.clear();
|
|
205
|
+
this.invalidateComponentNamesCache();
|
|
206
|
+
}
|
|
207
|
+
registerCustomComponent(componentName, defaultStyles) {
|
|
208
|
+
this.customThemes.set(componentName, defaultStyles);
|
|
209
|
+
KNOWN_COMPONENTS.add(componentName);
|
|
210
|
+
this.invalidateComponentNamesCache();
|
|
211
|
+
}
|
|
212
|
+
getComponentTheme(componentName) {
|
|
213
|
+
return this.getGlobalTheme()[componentName] ?? this.customThemes.get(componentName) ?? {};
|
|
214
|
+
}
|
|
215
|
+
getCustomComponentNames() {
|
|
216
|
+
return new Set(this.customThemes.keys());
|
|
217
|
+
}
|
|
218
|
+
setColorTokens(colors) {
|
|
219
|
+
this.colorTokens = colors;
|
|
220
|
+
}
|
|
221
|
+
getColorTokens() {
|
|
222
|
+
return this.colorTokens;
|
|
223
|
+
}
|
|
224
|
+
getColorMode() {
|
|
225
|
+
return this.colorMode;
|
|
226
|
+
}
|
|
227
|
+
setColorMode(mode) {
|
|
228
|
+
if (this.colorMode === mode) return;
|
|
229
|
+
this.colorMode = mode;
|
|
230
|
+
if (this.currentPresetName) {
|
|
231
|
+
const preset = colorPresets.getPresetWithMode(this.currentPresetName, mode);
|
|
232
|
+
this.colorTokens = preset.colors;
|
|
233
|
+
rebuildRegisteredDefaults(this.currentPresetName, mode);
|
|
234
|
+
this.setGlobalTheme(createDefaultTheme(this.currentPresetName, mode, preset.colors));
|
|
235
|
+
}
|
|
236
|
+
setTimeout(() => {
|
|
237
|
+
themeRemountHandler?.();
|
|
238
|
+
}, 0);
|
|
239
|
+
this.notifyListeners();
|
|
240
|
+
}
|
|
241
|
+
getCurrentPresetName() {
|
|
242
|
+
return this.currentPresetName;
|
|
243
|
+
}
|
|
244
|
+
setCurrentPresetName(name, skipNotify = false) {
|
|
245
|
+
if (this.currentPresetName === name) return;
|
|
246
|
+
this.currentPresetName = name;
|
|
247
|
+
if (!skipNotify) {
|
|
248
|
+
this.notifyListeners();
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
subscribe(listener) {
|
|
252
|
+
this.listeners.add(listener);
|
|
253
|
+
return () => {
|
|
254
|
+
this.listeners.delete(listener);
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
notifyListeners() {
|
|
258
|
+
this.listeners.forEach((listener) => listener());
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
const themeRegistry = new ThemeRegistry();
|
|
262
|
+
function createTheme(theme, colorPreset) {
|
|
263
|
+
if (colorPreset) {
|
|
264
|
+
themeRegistry.setColorTokens(colorPreset.colors);
|
|
265
|
+
return {
|
|
266
|
+
...theme,
|
|
267
|
+
__colorPreset: {
|
|
268
|
+
name: colorPreset.name,
|
|
269
|
+
mode: colorPreset.mode ?? "light"
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
return theme;
|
|
274
|
+
}
|
|
275
|
+
function getThemedProps(componentName, localTheme, explicitProps) {
|
|
276
|
+
return resolveComponentTheme({
|
|
277
|
+
componentName: normalizeThemeComponentName(componentName),
|
|
278
|
+
globalTheme: themeRegistry.getGlobalTheme(),
|
|
279
|
+
localTheme,
|
|
280
|
+
explicitProps,
|
|
281
|
+
knownComponents: themeRegistry.getAllComponentNames()
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
function setColorPreset(presetName, colorMode) {
|
|
285
|
+
const targetMode = colorMode ?? themeRegistry.getColorMode();
|
|
286
|
+
const preset = colorPresets.getPresetWithMode(presetName, targetMode);
|
|
287
|
+
themeRegistry.setColorTokens(preset.colors);
|
|
288
|
+
rebuildRegisteredDefaults(presetName, targetMode);
|
|
289
|
+
themeRegistry.setGlobalTheme(createDefaultTheme(presetName, targetMode, preset.colors));
|
|
290
|
+
themeRegistry.setCurrentPresetName(presetName, true);
|
|
291
|
+
if (colorMode && themeRegistry.getColorMode() !== colorMode) {
|
|
292
|
+
themeRegistry.setColorMode(colorMode);
|
|
293
|
+
} else {
|
|
294
|
+
setTimeout(() => {
|
|
295
|
+
themeRemountHandler?.();
|
|
296
|
+
}, 0);
|
|
297
|
+
themeRegistry.notifyListeners();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function getCurrentPreset() {
|
|
301
|
+
return themeRegistry.getCurrentPresetName();
|
|
302
|
+
}
|
|
303
|
+
function setColorMode(mode) {
|
|
304
|
+
themeRegistry.setColorMode(mode);
|
|
305
|
+
}
|
|
306
|
+
function getAvailablePresets() {
|
|
307
|
+
return Object.keys(colorPresets.presets);
|
|
308
|
+
}
|
|
309
|
+
function getGlobalThemeDefaults() {
|
|
310
|
+
return _themeDefaults;
|
|
311
|
+
}
|
|
312
|
+
exports.KNOWN_COMPONENTS = KNOWN_COMPONENTS;
|
|
313
|
+
exports.createDefaultTheme = createDefaultTheme;
|
|
314
|
+
exports.createTheme = createTheme;
|
|
315
|
+
exports.deepMergeDefined = deepMergeDefined;
|
|
316
|
+
exports.defaultTheme = defaultTheme;
|
|
317
|
+
exports.extractNestedThemes = extractNestedThemes;
|
|
318
|
+
exports.getAvailablePresets = getAvailablePresets;
|
|
319
|
+
exports.getCurrentPreset = getCurrentPreset;
|
|
320
|
+
exports.getGlobalThemeDefaults = getGlobalThemeDefaults;
|
|
321
|
+
exports.getThemedProps = getThemedProps;
|
|
322
|
+
exports.mergeThemes = mergeThemes;
|
|
323
|
+
exports.normalizeThemeComponentName = normalizeThemeComponentName;
|
|
324
|
+
exports.registerComponentDefaults = registerComponentDefaults;
|
|
325
|
+
exports.registerComponentDefaultsIfMissing = registerComponentDefaultsIfMissing;
|
|
326
|
+
exports.registerComponentThemeDefaults = registerComponentThemeDefaults;
|
|
327
|
+
exports.resolveComponentTheme = resolveComponentTheme;
|
|
328
|
+
exports.setColorMode = setColorMode;
|
|
329
|
+
exports.setColorPreset = setColorPreset;
|
|
330
|
+
exports.setThemeRemountHandler = setThemeRemountHandler;
|
|
331
|
+
exports.themeRegistry = themeRegistry;
|
|
332
|
+
//# sourceMappingURL=theme.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.cjs","sources":["../src/theme.ts"],"sourcesContent":["/**\n * Theme type helpers — renderer-neutral theme system contracts.\n *\n * These generic types form the foundation of the theme system. Each renderer\n * package defines its own ComponentThemes with renderer-specific prop types.\n *\n * @migration(audit:scene-portal-mount) Phase 3D — extracted from packages/ui/src/theme-base.ts.\n * Generic type helpers live here. Component-specific theme interfaces\n * (ViewTheme, TextTheme, ...) remain in the renderer package.\n */\nimport { getPresetWithMode, presets, type ColorTokens, type PresetName } from './colors'\nimport { DebugLogger } from './dev-config'\n\n// ---------------------------------------------------------------------------\n// Generic theme types\n// ---------------------------------------------------------------------------\n\n/**\n * Partial theme — allows overriding specific component styles.\n * Generic over the component theme map type.\n *\n * @example\n * ```ts\n * const theme: PartialTheme<PhaserComponentThemes> = {\n * View: { backgroundColor: 0xff0000 },\n * Text: { fontSize: 20 }\n * }\n * ```\n */\ntype ComponentThemeMap<T> = { [K in keyof T]: object }\n\n/**\n * Augmentable portable custom component theme map.\n *\n * Apps can extend this via:\n * `declare module '@number10/jsx-core' { interface CustomComponentThemes { ... } }`\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface CustomComponentThemes {}\n\nexport type PartialTheme<T extends ComponentThemeMap<T> = Record<string, object>> = {\n [K in keyof T]?: Partial<T[K]>\n} & {\n /** Optional color preset configuration */\n __colorPreset?: {\n name: string\n mode?: 'light' | 'dark'\n }\n}\n\n/**\n * Complete theme with all component styles defined.\n * Built-in components are required, custom components are optional.\n *\n * @param TBuiltIn - Required built-in component themes\n * @param TCustom - Optional custom component themes (defaults to empty object)\n */\nexport type Theme<\n TBuiltIn extends Record<string, Record<string, unknown>>,\n TCustom extends Record<string, Record<string, unknown>> = Record<string, never>,\n> = {\n [K in keyof TBuiltIn]: TBuiltIn[K]\n} & {\n [K in keyof TCustom]?: TCustom[K]\n}\n\n/**\n * Type helper for nested component themes.\n * Allows a component theme to include nested themes for child components.\n *\n * @param TComponentThemes - The full component theme map\n * @param TExclude - Keys to exclude (e.g., lowercase primitives)\n */\nexport type NestedComponentThemes<\n TComponentThemes extends ComponentThemeMap<TComponentThemes>,\n TExclude extends keyof TComponentThemes = never,\n> = {\n [K in Exclude<keyof TComponentThemes, TExclude>]?: Partial<TComponentThemes[K]>\n}\n\n// ---------------------------------------------------------------------------\n// Theme utility types\n// ---------------------------------------------------------------------------\n\n/**\n * Extract nested theme keys from a props object.\n * Keys that match known component names are treated as nested themes.\n *\n * @param props - The props object to scan\n * @param knownComponents - Set of known component names\n * @returns Tuple of [ownProps, nestedThemes]\n */\nexport function extractNestedThemes<T extends Record<string, unknown>>(\n props: T,\n knownComponents: ReadonlySet<string>\n): { ownProps: Partial<T>; nestedThemes: PartialTheme } {\n const ownProps: Record<string, unknown> = { ...props }\n const nestedThemes: Record<string, unknown> = {}\n\n for (const key of knownComponents) {\n if (key in ownProps) {\n nestedThemes[key] = ownProps[key]\n delete ownProps[key]\n }\n }\n\n return {\n ownProps: ownProps as Partial<T>,\n nestedThemes: nestedThemes as PartialTheme,\n }\n}\n\n/**\n * Deep-merge two objects, only overwriting defined values (not undefined).\n */\nexport function deepMergeDefined<T extends object>(base: T, override: Partial<T>): T {\n const result = { ...base }\n\n for (const key of Object.keys(override) as (keyof T)[]) {\n const overrideVal = override[key]\n if (overrideVal === undefined) continue\n\n if (isPlainObject(overrideVal) && isPlainObject(result[key])) {\n result[key] = deepMergeDefined(result[key] as object, overrideVal as object) as T[keyof T]\n } else {\n result[key] = overrideVal as T[keyof T]\n }\n }\n\n return result\n}\n\nconst PRIMITIVE_THEME_COMPONENT_NAMES: Record<string, string> = {\n view: 'View',\n text: 'Text',\n image: 'Image',\n sprite: 'Sprite',\n}\n\n/**\n * Normalize primitive host-node names to their canonical theme component names.\n * Non-primitive component names pass through unchanged.\n */\nexport function normalizeThemeComponentName(componentName: string): string {\n return PRIMITIVE_THEME_COMPONENT_NAMES[componentName] ?? componentName\n}\n\n/**\n * Merge theme objects (nested themes). Shallow merge for each component key.\n */\nexport function mergeThemes(\n base: PartialTheme | undefined,\n override: PartialTheme | undefined\n): PartialTheme {\n if (!base) return override ?? ({} as PartialTheme)\n if (!override) return base\n\n const result: Record<string, unknown> = { ...base }\n\n for (const key of Object.keys(override)) {\n const overrideVal = override[key]\n if (overrideVal === undefined) continue\n\n if (isPlainObject(overrideVal) && isPlainObject(result[key])) {\n result[key] = deepMergeDefined(result[key] as object, overrideVal as object)\n } else {\n result[key] = overrideVal\n }\n }\n\n return result as PartialTheme\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n// ---------------------------------------------------------------------------\n// Portable component theme resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Options for `resolveComponentTheme`.\n */\nexport interface ResolveComponentThemeOptions {\n /** The component's name (e.g., 'Badge', 'ProgressBar', 'View') */\n componentName: string\n /** The component's global theme defaults (from the theme registry) */\n globalTheme?: PartialTheme | undefined\n /** The local theme context (propagated from parent or __theme) */\n localTheme?: PartialTheme | undefined\n /** Explicit props passed to the component */\n explicitProps?: Record<string, unknown> | undefined\n /** Set of known component names for nested theme detection */\n knownComponents?: ReadonlySet<string> | undefined\n}\n\nfunction resolveThemeComponentTheme(\n theme: PartialTheme | undefined,\n componentName: string\n): Record<string, unknown> {\n if (!theme) return {}\n\n const normalizedName = normalizeThemeComponentName(componentName)\n const candidates =\n normalizedName === componentName ? [componentName] : [normalizedName, componentName]\n\n let merged: Record<string, unknown> = {}\n\n for (const candidate of candidates) {\n const entry = theme[candidate] as Record<string, unknown> | undefined\n if (!entry) continue\n merged = deepMergeDefined(merged, entry)\n }\n\n return merged\n}\n\n/**\n * Resolves themed props for a portable component.\n *\n * Merges global theme defaults, local theme context, and explicit props\n * in priority order: global < local < explicit. Only defined values overwrite.\n *\n * Also extracts nested component themes for propagation to children.\n *\n * @returns Themed props and nested theme for children.\n *\n * @example\n * ```ts\n * const { props, nestedTheme } = resolveComponentTheme({\n * componentName: 'Badge',\n * globalTheme: { Badge: { backgroundColor: 0xeeeeee, Icon: { size: 16 } } },\n * localTheme: theme, // from useTheme()\n * explicitProps: { tone: 'primary' },\n * knownComponents: new Set(['View', 'Text', 'Icon', 'Badge'])\n * })\n * // props = { backgroundColor: 0xeeeeee, tone: 'primary' }\n * // nestedTheme = { Icon: { size: 16 } }\n * ```\n */\nexport function resolveComponentTheme<T extends object = Record<string, unknown>>(\n options: ResolveComponentThemeOptions\n): {\n props: T\n nestedTheme: PartialTheme\n} {\n const { componentName, globalTheme, localTheme, explicitProps = {}, knownComponents } = options\n const normalizedComponentName = normalizeThemeComponentName(componentName)\n const componentSet = knownComponents ?? new Set()\n\n // 1. Start with global theme for this component\n const globalComponentTheme = resolveThemeComponentTheme(globalTheme, normalizedComponentName)\n const { ownProps: globalOwnProps, nestedThemes: globalNested } = extractNestedThemes(\n globalComponentTheme,\n componentSet\n )\n\n // 2. Apply local theme override\n const localComponentTheme = resolveThemeComponentTheme(localTheme, normalizedComponentName)\n const { ownProps: localOwnProps, nestedThemes: localNested } = extractNestedThemes(\n localComponentTheme,\n componentSet\n )\n\n // 3. Also extract nested themes directly from localTheme (for __theme propagation)\n const { nestedThemes: localThemeNested } = extractNestedThemes(\n (localTheme ?? {}) as Record<string, unknown>,\n componentSet\n )\n\n // 4. Extract nested themes from explicit props\n const { ownProps: explicitOwnProps, nestedThemes: explicitNested } = extractNestedThemes(\n explicitProps,\n componentSet\n )\n\n // 5. Merge: global < local < explicit\n const mergedProps = deepMergeDefined(\n deepMergeDefined(globalOwnProps as object, localOwnProps),\n explicitOwnProps\n ) as T\n\n // 6. Merge nested themes: global < localComponent < localTheme < explicit\n const mergedNested = mergeThemes(\n mergeThemes(mergeThemes(globalNested, localNested), localThemeNested),\n explicitNested\n )\n\n return { props: mergedProps, nestedTheme: mergedNested }\n}\n\n// ---------------------------------------------------------------------------\n// Global theme defaults registry\n// ---------------------------------------------------------------------------\n\ntype ThemeDefaults = Record<string, Record<string, unknown>>\nexport type ComponentThemeDefaultsProvider = (colors: ColorTokens) => object\nexport type ComponentThemeDefaultsInput = object | ComponentThemeDefaultsProvider\n\nconst _themeDefaults: ThemeDefaults = {}\nconst _themeDefaultProviders: Record<string, ComponentThemeDefaultsProvider> = {}\n\nlet themeRemountHandler: (() => void) | null = null\n\nfunction assignThemeDefaults(target: ThemeDefaults, source: ThemeDefaults): ThemeDefaults {\n for (const key of Object.keys(target)) {\n delete target[key]\n }\n\n Object.assign(target, source)\n return target\n}\n\nfunction providerFromInput(input: ComponentThemeDefaultsInput): ComponentThemeDefaultsProvider {\n return typeof input === 'function' ? (input as ComponentThemeDefaultsProvider) : () => input\n}\n\nfunction rebuildRegisteredDefaults(\n presetName: PresetName = 'oceanBlue',\n mode: 'light' | 'dark' = 'light'\n): ThemeDefaults {\n const preset = getPresetWithMode(presetName, mode)\n return assignThemeDefaults(_themeDefaults, createDefaultTheme(presetName, mode, preset.colors))\n}\n\nexport function setThemeRemountHandler(handler: (() => void) | null): void {\n themeRemountHandler = handler\n}\n\n/**\n * Set of known component names. Components register themselves here\n * so resolveComponentTheme can detect nested component themes.\n */\nexport const KNOWN_COMPONENTS = new Set<string>(['View', 'Text', 'Icon', 'Image', 'Sprite'])\n\n/**\n * Register preset-aware defaults for a component.\n *\n * Renderer-agnostic components register from @number10/jsx-components.\n * Renderer packages register their own host/component defaults as side effects.\n */\nexport function registerComponentThemeDefaults(\n componentName: string,\n defaults: ComponentThemeDefaultsInput\n): void {\n _themeDefaultProviders[componentName] = providerFromInput(defaults)\n KNOWN_COMPONENTS.add(componentName)\n rebuildRegisteredDefaults()\n}\n\n/**\n * Register global theme defaults for a component.\n * Also adds the component name to KNOWN_COMPONENTS.\n */\nexport function registerComponentDefaults(\n componentName: string,\n defaults: Record<string, unknown>\n): void {\n registerComponentThemeDefaults(componentName, defaults)\n}\n\n/**\n * Register component defaults only when no defaults exist yet.\n * Useful for portable fallback themes that must not override\n * renderer-provided defaults registered later in the stack.\n */\nexport function registerComponentDefaultsIfMissing(\n componentName: string,\n defaults: Record<string, unknown>\n): void {\n if (_themeDefaultProviders[componentName]) {\n KNOWN_COMPONENTS.add(componentName)\n return\n }\n\n registerComponentThemeDefaults(componentName, defaults)\n}\n\n/**\n * Create a default theme from all currently registered component defaults.\n */\nexport function createDefaultTheme(\n presetName: PresetName = 'oceanBlue',\n mode: 'light' | 'dark' = 'light',\n colors: ColorTokens = getPresetWithMode(presetName, mode).colors\n): ThemeDefaults {\n const theme: ThemeDefaults = {}\n\n for (const [componentName, provider] of Object.entries(_themeDefaultProviders)) {\n theme[componentName] = provider(colors) as Record<string, unknown>\n }\n\n return theme\n}\n\n/**\n * Mutable default theme cache for the default oceanBlue/light preset.\n * It is updated as component packages register their defaults.\n */\nexport const defaultTheme: ThemeDefaults = _themeDefaults\n\nclass ThemeRegistry {\n private globalTheme: PartialTheme | undefined = undefined\n private customThemes: Map<string, Record<string, unknown>> = new Map()\n private colorTokens: ColorTokens | undefined = undefined\n private colorMode: 'light' | 'dark' = 'light'\n private currentPresetName: PresetName | undefined = undefined\n private listeners: Set<() => void> = new Set()\n private cachedComponentNames: Set<string> | null = null\n\n private invalidateComponentNamesCache(): void {\n this.cachedComponentNames = null\n }\n\n getAllComponentNames(): Set<string> {\n if (this.cachedComponentNames) return this.cachedComponentNames\n\n const internalPrimitiveNames = new Set([\n 'view',\n 'text',\n 'nineslice',\n 'sprite',\n 'image',\n 'graphics',\n 'vectorDraw',\n 'tilesprite',\n 'particles',\n ])\n\n this.cachedComponentNames = new Set(\n Object.keys(this.getGlobalTheme())\n .concat(Array.from(this.customThemes.keys()))\n .filter((key) => key !== '__colorPreset' && !internalPrimitiveNames.has(key))\n )\n return this.cachedComponentNames\n }\n\n getGlobalTheme(): Readonly<PartialTheme> {\n return {\n ...defaultTheme,\n ...(this.globalTheme ?? {}),\n ...Object.fromEntries(this.customThemes),\n } as PartialTheme\n }\n\n updateGlobalTheme(theme: PartialTheme): void {\n const nextTheme = { ...(this.globalTheme ?? {}) } as Record<string, unknown>\n\n for (const [component, styles] of Object.entries(theme)) {\n if (component === '__colorPreset') {\n nextTheme[component] = styles\n continue\n }\n\n const existing =\n (nextTheme[component] as object | undefined) ??\n (this.getGlobalTheme()[component] as object | undefined) ??\n {}\n nextTheme[component] = deepMergeDefined(existing, (styles ?? {}) as object)\n DebugLogger.log('theme', `Updated ${component} theme:`, nextTheme[component])\n }\n\n this.globalTheme = nextTheme as PartialTheme\n this.notifyListeners()\n this.invalidateComponentNamesCache()\n }\n\n setGlobalTheme(theme: PartialTheme): void {\n this.globalTheme = { ...theme }\n this.invalidateComponentNamesCache()\n }\n\n resetGlobalTheme(): void {\n this.globalTheme = undefined\n this.customThemes.clear()\n this.invalidateComponentNamesCache()\n }\n\n registerCustomComponent<T extends Record<string, unknown>>(\n componentName: string,\n defaultStyles: T\n ): void {\n this.customThemes.set(componentName, defaultStyles)\n KNOWN_COMPONENTS.add(componentName)\n this.invalidateComponentNamesCache()\n }\n\n getComponentTheme<T extends object = Record<string, unknown>>(componentName: string): T {\n return ((this.getGlobalTheme()[componentName] as T | undefined) ??\n this.customThemes.get(componentName) ??\n {}) as T\n }\n\n getCustomComponentNames(): Set<string> {\n return new Set(this.customThemes.keys())\n }\n\n setColorTokens(colors: ColorTokens | undefined): void {\n this.colorTokens = colors\n }\n\n getColorTokens(): ColorTokens | undefined {\n return this.colorTokens\n }\n\n getColorMode(): 'light' | 'dark' {\n return this.colorMode\n }\n\n setColorMode(mode: 'light' | 'dark'): void {\n if (this.colorMode === mode) return\n\n this.colorMode = mode\n\n if (this.currentPresetName) {\n const preset = getPresetWithMode(this.currentPresetName, mode)\n this.colorTokens = preset.colors\n rebuildRegisteredDefaults(this.currentPresetName, mode)\n this.setGlobalTheme(createDefaultTheme(this.currentPresetName, mode, preset.colors))\n }\n\n setTimeout(() => {\n themeRemountHandler?.()\n }, 0)\n\n this.notifyListeners()\n }\n\n getCurrentPresetName(): string | undefined {\n return this.currentPresetName\n }\n\n setCurrentPresetName(name: string | undefined, skipNotify = false): void {\n if (this.currentPresetName === name) return\n\n this.currentPresetName = name as PresetName | undefined\n if (!skipNotify) {\n this.notifyListeners()\n }\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n notifyListeners(): void {\n this.listeners.forEach((listener) => listener())\n }\n}\n\nexport const themeRegistry = new ThemeRegistry()\n\nexport function createTheme(\n theme: PartialTheme,\n colorPreset?: { name: string; colors: ColorTokens; mode?: 'light' | 'dark' }\n): PartialTheme {\n if (colorPreset) {\n themeRegistry.setColorTokens(colorPreset.colors)\n\n return {\n ...theme,\n __colorPreset: {\n name: colorPreset.name,\n mode: colorPreset.mode ?? 'light',\n },\n }\n }\n\n return theme\n}\n\nexport function getThemedProps<T extends object = Record<string, unknown>>(\n componentName: string,\n localTheme: PartialTheme | undefined,\n explicitProps: Record<string, unknown>\n): { props: T; nestedTheme: PartialTheme } {\n return resolveComponentTheme<T>({\n componentName: normalizeThemeComponentName(componentName),\n globalTheme: themeRegistry.getGlobalTheme(),\n localTheme,\n explicitProps,\n knownComponents: themeRegistry.getAllComponentNames(),\n })\n}\n\nexport function setColorPreset(presetName: PresetName, colorMode?: 'light' | 'dark'): void {\n const targetMode = colorMode ?? themeRegistry.getColorMode()\n const preset = getPresetWithMode(presetName, targetMode)\n\n themeRegistry.setColorTokens(preset.colors)\n rebuildRegisteredDefaults(presetName, targetMode)\n themeRegistry.setGlobalTheme(createDefaultTheme(presetName, targetMode, preset.colors))\n themeRegistry.setCurrentPresetName(presetName, true)\n\n if (colorMode && themeRegistry.getColorMode() !== colorMode) {\n themeRegistry.setColorMode(colorMode)\n } else {\n setTimeout(() => {\n themeRemountHandler?.()\n }, 0)\n themeRegistry.notifyListeners()\n }\n}\n\nexport function getCurrentPreset(): string | undefined {\n return themeRegistry.getCurrentPresetName()\n}\n\nexport function setColorMode(mode: 'light' | 'dark'): void {\n themeRegistry.setColorMode(mode)\n}\n\nexport function getAvailablePresets(): PresetName[] {\n return Object.keys(presets) as PresetName[]\n}\n\n/**\n * Get all registered global theme defaults as a PartialTheme-like record.\n */\nexport function getGlobalThemeDefaults(): Record<string, Record<string, unknown>> {\n return _themeDefaults\n}\n"],"names":["getPresetWithMode","DebugLogger","presets"],"mappings":"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"}
|