@number10/phaserjsx 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/{TransformOriginView-CrzevUOh.cjs → TransformOriginView-DyhDBexY.cjs} +520 -539
  2. package/dist/TransformOriginView-DyhDBexY.cjs.map +1 -0
  3. package/dist/{TransformOriginView-TeXhLqNs.js → TransformOriginView-Y2LMZNcF.js} +587 -606
  4. package/dist/TransformOriginView-Y2LMZNcF.js.map +1 -0
  5. package/dist/animation/useSpring.d.ts.map +1 -1
  6. package/dist/colors/preset-manager.d.ts.map +1 -1
  7. package/dist/components/appliers/applyLayout.d.ts +4 -0
  8. package/dist/components/appliers/applyLayout.d.ts.map +1 -1
  9. package/dist/components/custom/Portal.d.ts.map +1 -1
  10. package/dist/components/custom/index.cjs +34 -34
  11. package/dist/components/custom/index.js +1 -1
  12. package/dist/effects/use-effect.d.ts +5 -0
  13. package/dist/effects/use-effect.d.ts.map +1 -1
  14. package/dist/hooks-svg.d.ts +1 -1
  15. package/dist/hooks-svg.d.ts.map +1 -1
  16. package/dist/hooks.d.ts +5 -0
  17. package/dist/hooks.d.ts.map +1 -1
  18. package/dist/host.d.ts +1 -1
  19. package/dist/host.d.ts.map +1 -1
  20. package/dist/index.cjs +496 -285
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.ts +1 -0
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +292 -81
  25. package/dist/index.js.map +1 -1
  26. package/dist/render-context.d.ts +1 -1
  27. package/dist/render-context.d.ts.map +1 -1
  28. package/dist/scene-backgrounds.d.ts +19 -0
  29. package/dist/scene-backgrounds.d.ts.map +1 -0
  30. package/dist/theme.d.ts.map +1 -1
  31. package/dist/utils/phaser-guards.d.ts +7 -0
  32. package/dist/utils/phaser-guards.d.ts.map +1 -0
  33. package/dist/vdom.d.ts.map +1 -1
  34. package/jsx-dev-runtime.d.ts +1 -0
  35. package/jsx-runtime.d.ts +1 -0
  36. package/package.json +4 -2
  37. package/dist/TransformOriginView-CrzevUOh.cjs.map +0 -1
  38. package/dist/TransformOriginView-TeXhLqNs.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { jsx, Fragment, jsxs } from "./jsx-runtime.js";
2
- import * as Phaser$1 from "phaser";
2
+ import * as Phaser from "phaser";
3
3
  import { signal } from "@preact/signals-core";
4
4
  function _mergeNamespaces(n, m) {
5
5
  for (var i = 0; i < m.length; i++) {
@@ -20,6 +20,16 @@ function _mergeNamespaces(n, m) {
20
20
  }
21
21
  return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: "Module" }));
22
22
  }
23
+ function isPhaserScene(value) {
24
+ if (!value || typeof value !== "object") return false;
25
+ const maybe = value;
26
+ return typeof maybe.sys === "object" && typeof maybe.add === "object";
27
+ }
28
+ function isPhaserContainer(value) {
29
+ if (!value || typeof value !== "object") return false;
30
+ const maybe = value;
31
+ return Array.isArray(maybe.list) && typeof maybe.add === "function" && typeof maybe.remove === "function";
32
+ }
23
33
  const nodeRegistry = {};
24
34
  function register(type, descriptor) {
25
35
  nodeRegistry[type] = descriptor;
@@ -60,9 +70,9 @@ const host = {
60
70
  * @param child - Child node to append
61
71
  */
62
72
  append(parent, child) {
63
- if (parent instanceof Phaser$1.GameObjects.Container) {
73
+ if (isPhaserContainer(parent)) {
64
74
  parent.add(child);
65
- } else if (parent && typeof parent === "object" && "sys" in parent) {
75
+ } else if (isPhaserScene(parent)) {
66
76
  const scene = parent;
67
77
  scene.add.existing(child);
68
78
  } else if (parent && typeof parent === "object" && "scene" in parent) {
@@ -80,7 +90,7 @@ const host = {
80
90
  remove(parent, child) {
81
91
  const childObj = child;
82
92
  if (!childObj.scene) return;
83
- if (parent instanceof Phaser$1.GameObjects.Container) {
93
+ if (isPhaserContainer(parent)) {
84
94
  parent.remove(childObj, false);
85
95
  }
86
96
  if (childObj.destroy) {
@@ -8803,18 +8813,6 @@ function getPresetWithMode(name, mode) {
8803
8813
  const preset2 = getPreset(name);
8804
8814
  return mode === "light" ? applyLightMode(preset2) : applyDarkMode(preset2);
8805
8815
  }
8806
- const colorPresets = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
8807
- __proto__: null,
8808
- applyDarkMode,
8809
- applyLightMode,
8810
- forestGreenPreset,
8811
- generateColorScale,
8812
- getPreset,
8813
- getPresetWithMode,
8814
- midnightPreset,
8815
- oceanBluePreset,
8816
- presets
8817
- }, Symbol.toStringTag, { value: "Module" }));
8818
8816
  const defaultSpacingTokens = {
8819
8817
  xs: 4,
8820
8818
  sm: 8,
@@ -9391,253 +9389,6 @@ function createDefaultTheme(presetName = "oceanBlue", mode = "light") {
9391
9389
  const presetForMode = getPresetWithMode(presetName, mode);
9392
9390
  return buildDefaultTheme(presetForMode.colors);
9393
9391
  }
9394
- class ThemeRegistry {
9395
- globalTheme = { ...defaultTheme };
9396
- customThemes = /* @__PURE__ */ new Map();
9397
- colorTokens = void 0;
9398
- colorMode = "light";
9399
- currentPresetName = void 0;
9400
- listeners = /* @__PURE__ */ new Set();
9401
- /**
9402
- * Get the complete global theme
9403
- */
9404
- getGlobalTheme() {
9405
- return { ...this.globalTheme, ...Object.fromEntries(this.customThemes) };
9406
- }
9407
- /**
9408
- * Update global theme (deep merge)
9409
- * @param theme - Partial theme to merge with current global theme
9410
- */
9411
- updateGlobalTheme(theme) {
9412
- for (const [component, styles] of Object.entries(theme)) {
9413
- if (component in this.globalTheme) {
9414
- this.globalTheme[component] = {
9415
- ...this.globalTheme[component],
9416
- ...styles
9417
- };
9418
- DebugLogger.log(
9419
- "theme",
9420
- `Updated ${component} theme:`,
9421
- this.globalTheme[component]
9422
- );
9423
- } else {
9424
- const existing = this.customThemes.get(component) ?? {};
9425
- this.customThemes.set(component, { ...existing, ...styles });
9426
- }
9427
- }
9428
- }
9429
- /**
9430
- * Set the entire global theme (replaces current theme)
9431
- * @param theme - Complete theme to set
9432
- */
9433
- setGlobalTheme(theme) {
9434
- this.globalTheme = { ...theme };
9435
- }
9436
- /**
9437
- * Reset global theme to default values
9438
- */
9439
- resetGlobalTheme() {
9440
- this.globalTheme = { ...defaultTheme };
9441
- this.customThemes.clear();
9442
- }
9443
- /**
9444
- * Register a custom component theme
9445
- * @param componentName - Name of the custom component
9446
- * @param defaultStyles - Default styles for the component
9447
- */
9448
- registerCustomComponent(componentName, defaultStyles) {
9449
- this.customThemes.set(componentName, defaultStyles);
9450
- }
9451
- /**
9452
- * Get theme for a specific component
9453
- * @param componentName - Component name
9454
- * @returns Theme for the component
9455
- */
9456
- getComponentTheme(componentName) {
9457
- if (componentName in this.globalTheme) {
9458
- const theme = this.globalTheme[componentName];
9459
- return theme;
9460
- }
9461
- return this.customThemes.get(componentName) ?? {};
9462
- }
9463
- /**
9464
- * Get all registered custom component names
9465
- * @returns Set of custom component names
9466
- */
9467
- getCustomComponentNames() {
9468
- return new Set(this.customThemes.keys());
9469
- }
9470
- /**
9471
- * Set color tokens for the global theme
9472
- * @param colors - ColorTokens to use globally
9473
- */
9474
- setColorTokens(colors) {
9475
- this.colorTokens = colors;
9476
- }
9477
- /**
9478
- * Get current color tokens
9479
- * @returns Current ColorTokens or undefined
9480
- */
9481
- getColorTokens() {
9482
- return this.colorTokens;
9483
- }
9484
- /**
9485
- * Get current color mode
9486
- * @returns Current color mode
9487
- */
9488
- getColorMode() {
9489
- return this.colorMode;
9490
- }
9491
- /**
9492
- * Set color mode and trigger complete remount
9493
- * Updates color tokens if a preset is active
9494
- * Triggers complete remount of all active mountJSX instances
9495
- * @param mode - Color mode to set
9496
- */
9497
- setColorMode(mode) {
9498
- if (this.colorMode !== mode) {
9499
- this.colorMode = mode;
9500
- if (this.currentPresetName) {
9501
- Promise.resolve().then(() => colorPresets).then(({ getPresetWithMode: getPresetWithMode2 }) => {
9502
- const preset2 = getPresetWithMode2(
9503
- this.currentPresetName,
9504
- mode
9505
- );
9506
- this.colorTokens = preset2.colors;
9507
- });
9508
- }
9509
- setTimeout(() => {
9510
- Promise.resolve().then(() => vdom).then(({ remountAll: remountAll2 }) => {
9511
- remountAll2();
9512
- });
9513
- }, 0);
9514
- }
9515
- }
9516
- /**
9517
- * Get current preset name
9518
- * @returns Current preset name or undefined
9519
- */
9520
- getCurrentPresetName() {
9521
- return this.currentPresetName;
9522
- }
9523
- /**
9524
- * Set current preset name
9525
- * @param name - Preset name
9526
- * @param skipNotify - If true, skip notifying listeners (used during remount)
9527
- */
9528
- setCurrentPresetName(name, skipNotify = false) {
9529
- if (this.currentPresetName !== name) {
9530
- this.currentPresetName = name;
9531
- if (!skipNotify) {
9532
- this.notifyListeners();
9533
- }
9534
- }
9535
- }
9536
- /**
9537
- * Subscribe to theme changes
9538
- * @param listener - Callback to invoke on theme change
9539
- * @returns Unsubscribe function
9540
- */
9541
- subscribe(listener) {
9542
- this.listeners.add(listener);
9543
- return () => {
9544
- this.listeners.delete(listener);
9545
- };
9546
- }
9547
- /**
9548
- * Notify all listeners of theme change
9549
- */
9550
- notifyListeners() {
9551
- this.listeners.forEach((listener) => listener());
9552
- }
9553
- }
9554
- const themeRegistry = new ThemeRegistry();
9555
- function mergeThemes(base, override) {
9556
- const result = { ...base };
9557
- for (const [component, styles] of Object.entries(override)) {
9558
- if (component in result) {
9559
- result[component] = {
9560
- ...result[component],
9561
- ...styles
9562
- };
9563
- } else {
9564
- result[component] = styles;
9565
- }
9566
- }
9567
- return result;
9568
- }
9569
- function createTheme(theme, colorPreset) {
9570
- if (colorPreset) {
9571
- themeRegistry.setColorTokens(colorPreset.colors);
9572
- return {
9573
- ...theme,
9574
- __colorPreset: {
9575
- name: colorPreset.name,
9576
- mode: colorPreset.mode ?? "light"
9577
- }
9578
- };
9579
- }
9580
- return theme;
9581
- }
9582
- function deepMergeDefined(base, override) {
9583
- const result = { ...base };
9584
- for (const key in override) {
9585
- const value = override[key];
9586
- if (value !== void 0) {
9587
- if (typeof value === "object" && value !== null && !Array.isArray(value) && typeof base[key] === "object" && base[key] !== null) {
9588
- result[key] = deepMergeDefined(
9589
- base[key],
9590
- value
9591
- );
9592
- } else {
9593
- result[key] = value;
9594
- }
9595
- }
9596
- }
9597
- return result;
9598
- }
9599
- function extractNestedThemes(theme) {
9600
- const ownProps = { ...theme };
9601
- const nestedThemes = {};
9602
- const allComponentNames = /* @__PURE__ */ new Set([
9603
- "View",
9604
- "Text",
9605
- "NineSlice",
9606
- ...Array.from(themeRegistry.getCustomComponentNames())
9607
- ]);
9608
- for (const key in ownProps) {
9609
- if (allComponentNames.has(key)) {
9610
- nestedThemes[key] = ownProps[key];
9611
- delete ownProps[key];
9612
- }
9613
- }
9614
- return { ownProps, nestedThemes };
9615
- }
9616
- function getThemedProps(componentName, localTheme, explicitProps) {
9617
- const globalComponentTheme = themeRegistry.getComponentTheme(componentName);
9618
- const { ownProps: globalOwnProps, nestedThemes: globalNestedThemes } = extractNestedThemes(globalComponentTheme);
9619
- const localComponentTheme = localTheme?.[componentName] ?? {};
9620
- const { ownProps: localOwnProps, nestedThemes: localNestedThemes } = extractNestedThemes(localComponentTheme);
9621
- const { nestedThemes: localThemeNested } = extractNestedThemes(localTheme ?? {});
9622
- const { ownProps: explicitOwnProps, nestedThemes: explicitNestedThemes } = extractNestedThemes(explicitProps);
9623
- const mergedProps = {
9624
- ...deepMergeDefined(globalOwnProps, localOwnProps),
9625
- ...deepMergeDefined({}, explicitOwnProps)
9626
- };
9627
- const mergedNestedThemes = mergeThemes(
9628
- mergeThemes(mergeThemes(globalNestedThemes, localNestedThemes), localThemeNested),
9629
- explicitNestedThemes
9630
- );
9631
- DebugLogger.log(
9632
- "theme",
9633
- `getThemedProps(${String(componentName)}): FINAL mergedProps:`,
9634
- mergedProps
9635
- );
9636
- return {
9637
- props: mergedProps,
9638
- nestedTheme: mergedNestedThemes
9639
- };
9640
- }
9641
9392
  class RenderContext {
9642
9393
  constructor(scene) {
9643
9394
  this.scene = scene;
@@ -9769,11 +9520,11 @@ class RenderContext {
9769
9520
  }
9770
9521
  }
9771
9522
  function getRenderContext(parentOrScene) {
9772
- const scene = parentOrScene instanceof Phaser$1.Scene ? parentOrScene : parentOrScene.scene;
9523
+ const scene = isPhaserScene(parentOrScene) ? parentOrScene : parentOrScene.scene;
9773
9524
  if (!scene || !scene.data || !scene.sys || !scene.sys.settings.active) {
9774
9525
  throw new Error("getRenderContext: Invalid scene or scene.data is undefined");
9775
9526
  }
9776
- const containerKey = parentOrScene instanceof Phaser$1.GameObjects.Container ? `__renderContext_${parentOrScene.name || parentOrScene.id || "container"}__` : "__renderContext_scene__";
9527
+ const containerKey = isPhaserContainer(parentOrScene) ? `__renderContext_${parentOrScene.name || parentOrScene.id || "container"}__` : "__renderContext_scene__";
9777
9528
  let context = scene.data.get(containerKey);
9778
9529
  if (!context) {
9779
9530
  context = new RenderContext(scene);
@@ -9793,18 +9544,268 @@ function getContextFromParent(parent) {
9793
9544
  }
9794
9545
  return getRenderContext(parent);
9795
9546
  }
9796
- function View(props) {
9797
- const localTheme = useTheme();
9798
- const { props: themed, nestedTheme } = getThemedProps("View", localTheme, props);
9799
- return /* @__PURE__ */ jsx("view", { ...themed, theme: nestedTheme });
9800
- }
9801
- function SceneWrapper(props) {
9802
- const { width, height, children } = props;
9803
- return /* @__PURE__ */ jsx(View, { width, height, children });
9547
+ function getCurrent() {
9548
+ return _currentCtx;
9804
9549
  }
9805
- class PortalRegistry {
9806
- portals = /* @__PURE__ */ new Map();
9807
- idCounter = 0;
9550
+ let _currentCtx = null;
9551
+ function withHooks(ctx, render) {
9552
+ const scene = isPhaserScene(ctx.parent) ? ctx.parent : ctx.parent.scene;
9553
+ if (!scene || !scene.sys || !scene.sys.settings.active) {
9554
+ return null;
9555
+ }
9556
+ const renderContext = getContextFromParent(ctx.parent);
9557
+ if (renderContext.isShutdown()) {
9558
+ return null;
9559
+ }
9560
+ const prev = renderContext.getCurrent();
9561
+ const prevModule = _currentCtx;
9562
+ renderContext.setCurrent(ctx);
9563
+ _currentCtx = ctx;
9564
+ ctx.index = 0;
9565
+ ctx.effects = [];
9566
+ const out = render();
9567
+ renderContext.setCurrent(prev);
9568
+ _currentCtx = prevModule;
9569
+ return out;
9570
+ }
9571
+ function useState(initial) {
9572
+ const c = getCurrent();
9573
+ const i = c.index++;
9574
+ if (i >= c.slots.length)
9575
+ c.slots[i] = typeof initial === "function" ? initial() : initial;
9576
+ const value = c.slots[i];
9577
+ const set = (v) => {
9578
+ const next = typeof v === "function" ? v(c.slots[i]) : v;
9579
+ if (Object.is(next, c.slots[i])) return;
9580
+ c.slots[i] = next;
9581
+ scheduleUpdate(c);
9582
+ };
9583
+ return [value, set];
9584
+ }
9585
+ function useRef(val) {
9586
+ const c = getCurrent();
9587
+ const i = c.index++;
9588
+ if (i >= c.slots.length) c.slots[i] = { current: val };
9589
+ return c.slots[i];
9590
+ }
9591
+ function useForceRedraw(first, ...rest) {
9592
+ const [, setForceRedraw] = useState(0);
9593
+ const throttleMs = typeof first === "number" ? first : void 0;
9594
+ const signals = typeof first === "number" ? rest : [first, ...rest];
9595
+ useEffect(() => {
9596
+ const unsubscribes = [];
9597
+ let lastUpdate = 0;
9598
+ const triggerUpdate = () => {
9599
+ const now = Date.now();
9600
+ if (throttleMs && now - lastUpdate < throttleMs) return;
9601
+ lastUpdate = now;
9602
+ setForceRedraw({});
9603
+ };
9604
+ for (const signal2 of signals) {
9605
+ if (signal2 && typeof signal2 === "object" && "subscribe" in signal2) {
9606
+ const subscriptions = signal2.subscribe(triggerUpdate);
9607
+ unsubscribes.push(subscriptions);
9608
+ }
9609
+ }
9610
+ return () => {
9611
+ unsubscribes.forEach((unsubscribe) => unsubscribe());
9612
+ };
9613
+ }, [throttleMs, ...signals]);
9614
+ }
9615
+ function useMemo(fn, deps) {
9616
+ const c = getCurrent();
9617
+ const i = c.index++;
9618
+ const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, value: void 0 });
9619
+ if (!depsChanged(slot.deps, deps)) return slot.value;
9620
+ slot.value = fn();
9621
+ slot.deps = deps;
9622
+ return slot.value;
9623
+ }
9624
+ function useCallback(fn, deps) {
9625
+ return useMemo(() => fn, deps);
9626
+ }
9627
+ function useTheme() {
9628
+ return getCurrent()?.theme;
9629
+ }
9630
+ function useScene() {
9631
+ const ctx = getCurrent();
9632
+ if (!ctx) throw new Error("useScene must be called within a component");
9633
+ const renderContext = getContextFromParent(ctx.parent);
9634
+ return renderContext.scene;
9635
+ }
9636
+ function useViewportSize() {
9637
+ const ctx = getCurrent();
9638
+ if (!ctx) {
9639
+ throw new Error("useViewportSize must be called within a component");
9640
+ }
9641
+ const renderContext = getContextFromParent(ctx.parent);
9642
+ return renderContext.getViewport();
9643
+ }
9644
+ function getLayoutSize(container) {
9645
+ if (!container) return void 0;
9646
+ const withLayout = container;
9647
+ return withLayout.__getLayoutSize?.();
9648
+ }
9649
+ function useLayoutSize(ref) {
9650
+ return getLayoutSize(ref.current);
9651
+ }
9652
+ function getLayoutProps(container) {
9653
+ if (!container) return void 0;
9654
+ const withLayout = container;
9655
+ return withLayout.__layoutProps;
9656
+ }
9657
+ function getBackgroundGraphics(container) {
9658
+ if (!container) return void 0;
9659
+ const withBackground = container;
9660
+ return withBackground.__background;
9661
+ }
9662
+ function useBackgroundGraphics(ref) {
9663
+ return getBackgroundGraphics(ref.current);
9664
+ }
9665
+ function getLayoutRect(container) {
9666
+ if (!container) return void 0;
9667
+ const size = getLayoutSize(container);
9668
+ if (!size) return void 0;
9669
+ return {
9670
+ x: container.x,
9671
+ y: container.y,
9672
+ width: size.width,
9673
+ height: size.height
9674
+ };
9675
+ }
9676
+ function useLayoutRect(ref) {
9677
+ return getLayoutRect(ref.current);
9678
+ }
9679
+ function getWorldLayoutRect(container) {
9680
+ if (!container) return void 0;
9681
+ const size = getLayoutSize(container);
9682
+ if (!size) return void 0;
9683
+ const matrix = container.getWorldTransformMatrix();
9684
+ const worldX = matrix.tx;
9685
+ const worldY = matrix.ty;
9686
+ const worldWidth = size.width * Math.abs(matrix.scaleX);
9687
+ const worldHeight = size.height * Math.abs(matrix.scaleY);
9688
+ return {
9689
+ x: worldX,
9690
+ y: worldY,
9691
+ width: worldWidth,
9692
+ height: worldHeight
9693
+ };
9694
+ }
9695
+ function useWorldLayoutRect(ref) {
9696
+ return getWorldLayoutRect(ref.current);
9697
+ }
9698
+ function useEffect(fn, deps) {
9699
+ const c = getCurrent();
9700
+ const i = c.index++;
9701
+ const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, cleanup: void 0 });
9702
+ c.effects.push(() => {
9703
+ if (!depsChanged(slot.deps, deps)) return;
9704
+ if (typeof slot.cleanup === "function") slot.cleanup();
9705
+ slot.cleanup = fn();
9706
+ if (deps !== void 0) {
9707
+ slot.deps = deps;
9708
+ }
9709
+ });
9710
+ }
9711
+ function useLayoutEffect(fn, deps) {
9712
+ const c = getCurrent();
9713
+ const i = c.index++;
9714
+ const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, cleanup: void 0 });
9715
+ c.effects.push(() => {
9716
+ if (!depsChanged(slot.deps, deps)) return;
9717
+ if (typeof slot.cleanup === "function") slot.cleanup();
9718
+ requestAnimationFrame(() => {
9719
+ slot.cleanup = fn();
9720
+ });
9721
+ if (deps !== void 0) {
9722
+ slot.deps = deps;
9723
+ }
9724
+ });
9725
+ }
9726
+ function depsChanged(a, b) {
9727
+ if (!a || !b) return true;
9728
+ if (a.length !== b.length) return true;
9729
+ for (let i = 0; i < a.length; i++) {
9730
+ if (!Object.is(a[i], b[i])) return true;
9731
+ }
9732
+ return false;
9733
+ }
9734
+ function shallowEqual(a, b) {
9735
+ if (Object.is(a, b)) return true;
9736
+ if (a == null || b == null) return false;
9737
+ if (typeof a !== "object" || typeof b !== "object") return false;
9738
+ const keysA = Object.keys(a);
9739
+ const keysB = Object.keys(b);
9740
+ if (keysA.length !== keysB.length) return false;
9741
+ for (const key of keysA) {
9742
+ if (!Object.prototype.hasOwnProperty.call(b, key) || !Object.is(a[key], b[key])) {
9743
+ return false;
9744
+ }
9745
+ }
9746
+ return true;
9747
+ }
9748
+ function shouldComponentUpdate(ctx, newProps) {
9749
+ if (ctx.memoized === false) return true;
9750
+ if (ctx.componentVNode.__memo === false) return true;
9751
+ if (ctx.lastProps === void 0) {
9752
+ ctx.lastProps = newProps;
9753
+ return true;
9754
+ }
9755
+ const hasChanged = !shallowEqual(ctx.lastProps, newProps);
9756
+ ctx.lastProps = newProps;
9757
+ return hasChanged;
9758
+ }
9759
+ function useRedraw() {
9760
+ const c = getCurrent();
9761
+ return () => {
9762
+ if (c != null) scheduleUpdate(c);
9763
+ };
9764
+ }
9765
+ function scheduleUpdate(c) {
9766
+ if (c.updater) return;
9767
+ c.updater = () => {
9768
+ c.updater = void 0;
9769
+ if (c.disposed) {
9770
+ return;
9771
+ }
9772
+ const scene = isPhaserScene(c.parent) ? c.parent : c.parent.scene;
9773
+ if (!scene || !scene.sys || !scene.sys.settings.active) {
9774
+ return;
9775
+ }
9776
+ const componentProps = c.componentVNode.props ?? {};
9777
+ const propsWithChildren = c.componentVNode.children?.length ? { ...componentProps, children: c.componentVNode.children } : componentProps;
9778
+ const nextVNode = normalizeVNodeLike(withHooks(c, () => c.function(propsWithChildren)));
9779
+ patchVNode(c.parent, c.vnode, nextVNode);
9780
+ c.vnode = nextVNode;
9781
+ for (const run of c.effects) run();
9782
+ };
9783
+ queueMicrotask(c.updater);
9784
+ }
9785
+ function disposeCtx(c) {
9786
+ c.disposed = true;
9787
+ for (const cl of c.cleanups) {
9788
+ if (typeof cl === "function") cl();
9789
+ }
9790
+ for (const slot of c.slots) {
9791
+ if (slot && typeof slot === "object" && "cleanup" in slot && typeof slot.cleanup === "function") {
9792
+ slot.cleanup();
9793
+ }
9794
+ }
9795
+ c.cleanups.length = 0;
9796
+ }
9797
+ function View(props) {
9798
+ const localTheme = useTheme();
9799
+ const { props: themed, nestedTheme } = getThemedProps("View", localTheme, props);
9800
+ return /* @__PURE__ */ jsx("view", { ...themed, theme: nestedTheme });
9801
+ }
9802
+ function SceneWrapper(props) {
9803
+ const { width, height, children } = props;
9804
+ return /* @__PURE__ */ jsx(View, { width, height, children });
9805
+ }
9806
+ class PortalRegistry {
9807
+ portals = /* @__PURE__ */ new Map();
9808
+ idCounter = 0;
9808
9809
  portalRoots = /* @__PURE__ */ new Map();
9809
9810
  viewportSizes = /* @__PURE__ */ new Map();
9810
9811
  /**
@@ -10000,7 +10001,7 @@ class MountRegistry {
10000
10001
  */
10001
10002
  findByParentAndKey(parent, key) {
10002
10003
  for (const entry of this.entries.values()) {
10003
- const scene = entry.parent instanceof Phaser$1.Scene ? entry.parent : entry.parent.scene;
10004
+ const scene = isPhaserScene(entry.parent) ? entry.parent : entry.parent.scene;
10004
10005
  if (!scene || !scene.sys || !scene.sys.settings.active) {
10005
10006
  DebugLogger.log("vdom", `Removing mount ${entry.id} - scene inactive`);
10006
10007
  this.unregister(entry.id);
@@ -10055,7 +10056,7 @@ class MountRegistry {
10055
10056
  if (key) {
10056
10057
  byKey.set(key, (byKey.get(key) ?? 0) + 1);
10057
10058
  }
10058
- const parentType = entry.parent instanceof Phaser$1.Scene ? "Scene" : "Container";
10059
+ const parentType = isPhaserScene(entry.parent) ? "Scene" : "Container";
10059
10060
  const mountInfo = {
10060
10061
  id: entry.id,
10061
10062
  type: typeName,
@@ -10096,13 +10097,13 @@ function remountAll() {
10096
10097
  console.log(`[REMOUNT] Starting remount of ${entries.length} root(s)`);
10097
10098
  entries.forEach((entry) => {
10098
10099
  try {
10099
- const scene = entry.parent instanceof Phaser$1.Scene ? entry.parent : entry.parent.scene;
10100
+ const scene = isPhaserScene(entry.parent) ? entry.parent : entry.parent.scene;
10100
10101
  if (!scene || !scene.sys) {
10101
10102
  console.warn("[REMOUNT] Scene is invalid, skipping remount");
10102
10103
  return;
10103
10104
  }
10104
10105
  const currentVNode = scene.__rootVNode;
10105
- if (entry.rootNode instanceof Phaser$1.GameObjects.Container) {
10106
+ if (isPhaserContainer(entry.rootNode)) {
10106
10107
  const children = entry.rootNode.getAll();
10107
10108
  children.forEach((child) => {
10108
10109
  ;
@@ -10143,7 +10144,7 @@ function remountAll() {
10143
10144
  ;
10144
10145
  scene.__rootVNode = vnode;
10145
10146
  const rootNode = mount(entry.parent, vnode);
10146
- if (rootNode instanceof Phaser$1.GameObjects.Container) {
10147
+ if (isPhaserContainer(rootNode)) {
10147
10148
  ;
10148
10149
  rootNode.__mountRootId = generateMountRootId();
10149
10150
  }
@@ -10288,7 +10289,7 @@ function updateGestureHitAreaAfterLayout(container) {
10288
10289
  if (!manager.hasContainer(container)) return;
10289
10290
  const width = container.width;
10290
10291
  const height = container.height;
10291
- const hitArea = new Phaser$1.Geom.Rectangle(0, 0, width, height);
10292
+ const hitArea = new Phaser.Geom.Rectangle(0, 0, width, height);
10292
10293
  manager.updateHitArea(container, hitArea);
10293
10294
  } catch {
10294
10295
  }
@@ -10401,7 +10402,7 @@ function mount(parentOrScene, vnode) {
10401
10402
  vnode.__theme
10402
10403
  );
10403
10404
  }
10404
- const scene2 = parentOrScene instanceof Phaser$1.Scene ? parentOrScene : parentOrScene.scene;
10405
+ const scene2 = isPhaserScene(parentOrScene) ? parentOrScene : parentOrScene.scene;
10405
10406
  const ctx = {
10406
10407
  index: 0,
10407
10408
  slots: [],
@@ -10516,7 +10517,7 @@ function mount(parentOrScene, vnode) {
10516
10517
  if (node && "list" in node && Array.isArray(node.list)) {
10517
10518
  const container = node;
10518
10519
  let parentSize;
10519
- if (parentOrScene instanceof Phaser$1.GameObjects.Container) {
10520
+ if (isPhaserContainer(parentOrScene)) {
10520
10521
  const parentContainer = parentOrScene;
10521
10522
  if (parentContainer.__getLayoutSize) {
10522
10523
  const parentTotalSize = parentContainer.__getLayoutSize();
@@ -10815,7 +10816,7 @@ function patchVNode(parent, oldV, newV) {
10815
10816
  const container = oldV.__node;
10816
10817
  if (container.__layoutProps) {
10817
10818
  let parentSize;
10818
- if (parent instanceof Phaser$1.GameObjects.Container) {
10819
+ if (isPhaserContainer(parent)) {
10819
10820
  const parentContainer = parent;
10820
10821
  if (parentContainer.__getLayoutSize) {
10821
10822
  const parentTotalSize = parentContainer.__getLayoutSize();
@@ -10907,7 +10908,7 @@ Solution: Add unique keys like { key: 'sidebar', ... } and { key: 'main', ... }`
10907
10908
  return handle2;
10908
10909
  }
10909
10910
  const { width, height, disableAutoSize = false, key: _key, ...componentProps } = props;
10910
- const scene = parentOrScene instanceof Phaser$1.Scene ? parentOrScene : parentOrScene.scene;
10911
+ const scene = isPhaserScene(parentOrScene) ? parentOrScene : parentOrScene.scene;
10911
10912
  if (scene) {
10912
10913
  const renderContext = getRenderContext(parentOrScene);
10913
10914
  renderContext.setViewport(width, height, scene);
@@ -10940,7 +10941,7 @@ Solution: Add unique keys like { key: 'sidebar', ... } and { key: 'main', ... }`
10940
10941
  scene.__rootVNode = vnode;
10941
10942
  }
10942
10943
  const rootNode = mount(parentOrScene, vnode);
10943
- if (rootNode instanceof Phaser$1.GameObjects.Container) {
10944
+ if (isPhaserContainer(rootNode)) {
10944
10945
  rootNode.__mountRootId = generateMountRootId();
10945
10946
  }
10946
10947
  rootNode.__rootVNode = vnode;
@@ -10951,7 +10952,7 @@ Solution: Add unique keys like { key: 'sidebar', ... } and { key: 'main', ... }`
10951
10952
  return handle;
10952
10953
  }
10953
10954
  function unmountJSX(target) {
10954
- const scene = target instanceof Phaser$1.Scene ? target : target.scene;
10955
+ const scene = isPhaserScene(target) ? target : target.scene;
10955
10956
  const targetWithVNode = target;
10956
10957
  const sceneWithVNode = scene;
10957
10958
  const rootVNode = targetWithVNode.__rootVNode ?? sceneWithVNode?.__rootVNode;
@@ -10974,267 +10975,248 @@ function unmountJSX(target) {
10974
10975
  }
10975
10976
  DebugLogger.log("vdom", "unmountJSX called but no root VNode found on target");
10976
10977
  }
10977
- const vdom = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
10978
- __proto__: null,
10979
- createElement,
10980
- getMountStats,
10981
- mount,
10982
- mountJSX,
10983
- normalizeVNodeLike,
10984
- patchVNode,
10985
- remountAll,
10986
- unmount,
10987
- unmountJSX
10988
- }, Symbol.toStringTag, { value: "Module" }));
10989
- function getCurrent() {
10990
- return _currentCtx;
10991
- }
10992
- let _currentCtx = null;
10993
- function withHooks(ctx, render) {
10994
- const scene = ctx.parent instanceof Phaser.Scene ? ctx.parent : ctx.parent.scene;
10995
- if (!scene || !scene.sys || !scene.sys.settings.active) {
10996
- return null;
10978
+ class ThemeRegistry {
10979
+ globalTheme = { ...defaultTheme };
10980
+ customThemes = /* @__PURE__ */ new Map();
10981
+ colorTokens = void 0;
10982
+ colorMode = "light";
10983
+ currentPresetName = void 0;
10984
+ listeners = /* @__PURE__ */ new Set();
10985
+ /**
10986
+ * Get the complete global theme
10987
+ */
10988
+ getGlobalTheme() {
10989
+ return { ...this.globalTheme, ...Object.fromEntries(this.customThemes) };
10997
10990
  }
10998
- const renderContext = getContextFromParent(ctx.parent);
10999
- if (renderContext.isShutdown()) {
11000
- return null;
10991
+ /**
10992
+ * Update global theme (deep merge)
10993
+ * @param theme - Partial theme to merge with current global theme
10994
+ */
10995
+ updateGlobalTheme(theme) {
10996
+ for (const [component, styles] of Object.entries(theme)) {
10997
+ if (component in this.globalTheme) {
10998
+ this.globalTheme[component] = {
10999
+ ...this.globalTheme[component],
11000
+ ...styles
11001
+ };
11002
+ DebugLogger.log(
11003
+ "theme",
11004
+ `Updated ${component} theme:`,
11005
+ this.globalTheme[component]
11006
+ );
11007
+ } else {
11008
+ const existing = this.customThemes.get(component) ?? {};
11009
+ this.customThemes.set(component, { ...existing, ...styles });
11010
+ }
11011
+ }
11001
11012
  }
11002
- const prev = renderContext.getCurrent();
11003
- const prevModule = _currentCtx;
11004
- renderContext.setCurrent(ctx);
11005
- _currentCtx = ctx;
11006
- ctx.index = 0;
11007
- ctx.effects = [];
11008
- const out = render();
11009
- renderContext.setCurrent(prev);
11010
- _currentCtx = prevModule;
11011
- return out;
11012
- }
11013
- function useState(initial) {
11014
- const c = getCurrent();
11015
- const i = c.index++;
11016
- if (i >= c.slots.length)
11017
- c.slots[i] = typeof initial === "function" ? initial() : initial;
11018
- const value = c.slots[i];
11019
- const set = (v) => {
11020
- const next = typeof v === "function" ? v(c.slots[i]) : v;
11021
- if (Object.is(next, c.slots[i])) return;
11022
- c.slots[i] = next;
11023
- scheduleUpdate(c);
11024
- };
11025
- return [value, set];
11026
- }
11027
- function useRef(val) {
11028
- const c = getCurrent();
11029
- const i = c.index++;
11030
- if (i >= c.slots.length) c.slots[i] = { current: val };
11031
- return c.slots[i];
11032
- }
11033
- function useForceRedraw(first, ...rest) {
11034
- const [, setForceRedraw] = useState(0);
11035
- const throttleMs = typeof first === "number" ? first : void 0;
11036
- const signals = typeof first === "number" ? rest : [first, ...rest];
11037
- useEffect(() => {
11038
- const unsubscribes = [];
11039
- let lastUpdate = 0;
11040
- const triggerUpdate = () => {
11041
- const now = Date.now();
11042
- if (throttleMs && now - lastUpdate < throttleMs) return;
11043
- lastUpdate = now;
11044
- setForceRedraw({});
11045
- };
11046
- for (const signal2 of signals) {
11047
- if (signal2 && typeof signal2 === "object" && "subscribe" in signal2) {
11048
- const subscriptions = signal2.subscribe(triggerUpdate);
11049
- unsubscribes.push(subscriptions);
11013
+ /**
11014
+ * Set the entire global theme (replaces current theme)
11015
+ * @param theme - Complete theme to set
11016
+ */
11017
+ setGlobalTheme(theme) {
11018
+ this.globalTheme = { ...theme };
11019
+ }
11020
+ /**
11021
+ * Reset global theme to default values
11022
+ */
11023
+ resetGlobalTheme() {
11024
+ this.globalTheme = { ...defaultTheme };
11025
+ this.customThemes.clear();
11026
+ }
11027
+ /**
11028
+ * Register a custom component theme
11029
+ * @param componentName - Name of the custom component
11030
+ * @param defaultStyles - Default styles for the component
11031
+ */
11032
+ registerCustomComponent(componentName, defaultStyles) {
11033
+ this.customThemes.set(componentName, defaultStyles);
11034
+ }
11035
+ /**
11036
+ * Get theme for a specific component
11037
+ * @param componentName - Component name
11038
+ * @returns Theme for the component
11039
+ */
11040
+ getComponentTheme(componentName) {
11041
+ if (componentName in this.globalTheme) {
11042
+ const theme = this.globalTheme[componentName];
11043
+ return theme;
11044
+ }
11045
+ return this.customThemes.get(componentName) ?? {};
11046
+ }
11047
+ /**
11048
+ * Get all registered custom component names
11049
+ * @returns Set of custom component names
11050
+ */
11051
+ getCustomComponentNames() {
11052
+ return new Set(this.customThemes.keys());
11053
+ }
11054
+ /**
11055
+ * Set color tokens for the global theme
11056
+ * @param colors - ColorTokens to use globally
11057
+ */
11058
+ setColorTokens(colors) {
11059
+ this.colorTokens = colors;
11060
+ }
11061
+ /**
11062
+ * Get current color tokens
11063
+ * @returns Current ColorTokens or undefined
11064
+ */
11065
+ getColorTokens() {
11066
+ return this.colorTokens;
11067
+ }
11068
+ /**
11069
+ * Get current color mode
11070
+ * @returns Current color mode
11071
+ */
11072
+ getColorMode() {
11073
+ return this.colorMode;
11074
+ }
11075
+ /**
11076
+ * Set color mode and trigger complete remount
11077
+ * Updates color tokens if a preset is active
11078
+ * Triggers complete remount of all active mountJSX instances
11079
+ * @param mode - Color mode to set
11080
+ */
11081
+ setColorMode(mode) {
11082
+ if (this.colorMode !== mode) {
11083
+ this.colorMode = mode;
11084
+ if (this.currentPresetName) {
11085
+ const preset2 = getPresetWithMode(
11086
+ this.currentPresetName,
11087
+ mode
11088
+ );
11089
+ this.colorTokens = preset2.colors;
11090
+ }
11091
+ setTimeout(() => {
11092
+ remountAll();
11093
+ }, 0);
11094
+ }
11095
+ }
11096
+ /**
11097
+ * Get current preset name
11098
+ * @returns Current preset name or undefined
11099
+ */
11100
+ getCurrentPresetName() {
11101
+ return this.currentPresetName;
11102
+ }
11103
+ /**
11104
+ * Set current preset name
11105
+ * @param name - Preset name
11106
+ * @param skipNotify - If true, skip notifying listeners (used during remount)
11107
+ */
11108
+ setCurrentPresetName(name, skipNotify = false) {
11109
+ if (this.currentPresetName !== name) {
11110
+ this.currentPresetName = name;
11111
+ if (!skipNotify) {
11112
+ this.notifyListeners();
11050
11113
  }
11051
11114
  }
11115
+ }
11116
+ /**
11117
+ * Subscribe to theme changes
11118
+ * @param listener - Callback to invoke on theme change
11119
+ * @returns Unsubscribe function
11120
+ */
11121
+ subscribe(listener) {
11122
+ this.listeners.add(listener);
11052
11123
  return () => {
11053
- unsubscribes.forEach((unsubscribe) => unsubscribe());
11124
+ this.listeners.delete(listener);
11054
11125
  };
11055
- }, [throttleMs, ...signals]);
11056
- }
11057
- function useMemo(fn, deps) {
11058
- const c = getCurrent();
11059
- const i = c.index++;
11060
- const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, value: void 0 });
11061
- if (!depsChanged(slot.deps, deps)) return slot.value;
11062
- slot.value = fn();
11063
- slot.deps = deps;
11064
- return slot.value;
11065
- }
11066
- function useCallback(fn, deps) {
11067
- return useMemo(() => fn, deps);
11068
- }
11069
- function useTheme() {
11070
- return getCurrent()?.theme;
11071
- }
11072
- function useScene() {
11073
- const ctx = getCurrent();
11074
- if (!ctx) throw new Error("useScene must be called within a component");
11075
- const renderContext = getContextFromParent(ctx.parent);
11076
- return renderContext.scene;
11077
- }
11078
- function useViewportSize() {
11079
- const ctx = getCurrent();
11080
- if (!ctx) {
11081
- throw new Error("useViewportSize must be called within a component");
11082
11126
  }
11083
- const renderContext = getContextFromParent(ctx.parent);
11084
- return renderContext.getViewport();
11085
- }
11086
- function getLayoutSize(container) {
11087
- if (!container) return void 0;
11088
- const withLayout = container;
11089
- return withLayout.__getLayoutSize?.();
11090
- }
11091
- function useLayoutSize(ref) {
11092
- return getLayoutSize(ref.current);
11093
- }
11094
- function getLayoutProps(container) {
11095
- if (!container) return void 0;
11096
- const withLayout = container;
11097
- return withLayout.__layoutProps;
11098
- }
11099
- function getBackgroundGraphics(container) {
11100
- if (!container) return void 0;
11101
- const withBackground = container;
11102
- return withBackground.__background;
11103
- }
11104
- function useBackgroundGraphics(ref) {
11105
- return getBackgroundGraphics(ref.current);
11106
- }
11107
- function getLayoutRect(container) {
11108
- if (!container) return void 0;
11109
- const size = getLayoutSize(container);
11110
- if (!size) return void 0;
11111
- return {
11112
- x: container.x,
11113
- y: container.y,
11114
- width: size.width,
11115
- height: size.height
11116
- };
11117
- }
11118
- function useLayoutRect(ref) {
11119
- return getLayoutRect(ref.current);
11120
- }
11121
- function getWorldLayoutRect(container) {
11122
- if (!container) return void 0;
11123
- const size = getLayoutSize(container);
11124
- if (!size) return void 0;
11125
- const matrix = container.getWorldTransformMatrix();
11126
- const worldX = matrix.tx;
11127
- const worldY = matrix.ty;
11128
- const worldWidth = size.width * Math.abs(matrix.scaleX);
11129
- const worldHeight = size.height * Math.abs(matrix.scaleY);
11130
- return {
11131
- x: worldX,
11132
- y: worldY,
11133
- width: worldWidth,
11134
- height: worldHeight
11135
- };
11136
- }
11137
- function useWorldLayoutRect(ref) {
11138
- return getWorldLayoutRect(ref.current);
11139
- }
11140
- function useEffect(fn, deps) {
11141
- const c = getCurrent();
11142
- const i = c.index++;
11143
- const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, cleanup: void 0 });
11144
- c.effects.push(() => {
11145
- if (!depsChanged(slot.deps, deps)) return;
11146
- if (typeof slot.cleanup === "function") slot.cleanup();
11147
- slot.cleanup = fn();
11148
- if (deps !== void 0) {
11149
- slot.deps = deps;
11150
- }
11151
- });
11127
+ /**
11128
+ * Notify all listeners of theme change
11129
+ */
11130
+ notifyListeners() {
11131
+ this.listeners.forEach((listener) => listener());
11132
+ }
11152
11133
  }
11153
- function useLayoutEffect(fn, deps) {
11154
- const c = getCurrent();
11155
- const i = c.index++;
11156
- const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, cleanup: void 0 });
11157
- c.effects.push(() => {
11158
- if (!depsChanged(slot.deps, deps)) return;
11159
- if (typeof slot.cleanup === "function") slot.cleanup();
11160
- requestAnimationFrame(() => {
11161
- slot.cleanup = fn();
11162
- });
11163
- if (deps !== void 0) {
11164
- slot.deps = deps;
11134
+ const themeRegistry = new ThemeRegistry();
11135
+ function mergeThemes(base, override) {
11136
+ const result = { ...base };
11137
+ for (const [component, styles] of Object.entries(override)) {
11138
+ if (component in result) {
11139
+ result[component] = {
11140
+ ...result[component],
11141
+ ...styles
11142
+ };
11143
+ } else {
11144
+ result[component] = styles;
11165
11145
  }
11166
- });
11146
+ }
11147
+ return result;
11167
11148
  }
11168
- function depsChanged(a, b) {
11169
- if (!a || !b) return true;
11170
- if (a.length !== b.length) return true;
11171
- for (let i = 0; i < a.length; i++) {
11172
- if (!Object.is(a[i], b[i])) return true;
11149
+ function createTheme(theme, colorPreset) {
11150
+ if (colorPreset) {
11151
+ themeRegistry.setColorTokens(colorPreset.colors);
11152
+ return {
11153
+ ...theme,
11154
+ __colorPreset: {
11155
+ name: colorPreset.name,
11156
+ mode: colorPreset.mode ?? "light"
11157
+ }
11158
+ };
11173
11159
  }
11174
- return false;
11160
+ return theme;
11175
11161
  }
11176
- function shallowEqual(a, b) {
11177
- if (Object.is(a, b)) return true;
11178
- if (a == null || b == null) return false;
11179
- if (typeof a !== "object" || typeof b !== "object") return false;
11180
- const keysA = Object.keys(a);
11181
- const keysB = Object.keys(b);
11182
- if (keysA.length !== keysB.length) return false;
11183
- for (const key of keysA) {
11184
- if (!Object.prototype.hasOwnProperty.call(b, key) || !Object.is(a[key], b[key])) {
11185
- return false;
11162
+ function deepMergeDefined(base, override) {
11163
+ const result = { ...base };
11164
+ for (const key in override) {
11165
+ const value = override[key];
11166
+ if (value !== void 0) {
11167
+ if (typeof value === "object" && value !== null && !Array.isArray(value) && typeof base[key] === "object" && base[key] !== null) {
11168
+ result[key] = deepMergeDefined(
11169
+ base[key],
11170
+ value
11171
+ );
11172
+ } else {
11173
+ result[key] = value;
11174
+ }
11186
11175
  }
11187
11176
  }
11188
- return true;
11177
+ return result;
11189
11178
  }
11190
- function shouldComponentUpdate(ctx, newProps) {
11191
- if (ctx.memoized === false) return true;
11192
- if (ctx.componentVNode.__memo === false) return true;
11193
- if (ctx.lastProps === void 0) {
11194
- ctx.lastProps = newProps;
11195
- return true;
11179
+ function extractNestedThemes(theme) {
11180
+ const ownProps = { ...theme };
11181
+ const nestedThemes = {};
11182
+ const allComponentNames = /* @__PURE__ */ new Set([
11183
+ "View",
11184
+ "Text",
11185
+ "NineSlice",
11186
+ ...Array.from(themeRegistry.getCustomComponentNames())
11187
+ ]);
11188
+ for (const key in ownProps) {
11189
+ if (allComponentNames.has(key)) {
11190
+ nestedThemes[key] = ownProps[key];
11191
+ delete ownProps[key];
11192
+ }
11196
11193
  }
11197
- const hasChanged = !shallowEqual(ctx.lastProps, newProps);
11198
- ctx.lastProps = newProps;
11199
- return hasChanged;
11194
+ return { ownProps, nestedThemes };
11200
11195
  }
11201
- function useRedraw() {
11202
- const c = getCurrent();
11203
- return () => {
11204
- if (c != null) scheduleUpdate(c);
11196
+ function getThemedProps(componentName, localTheme, explicitProps) {
11197
+ const globalComponentTheme = themeRegistry.getComponentTheme(componentName);
11198
+ const { ownProps: globalOwnProps, nestedThemes: globalNestedThemes } = extractNestedThemes(globalComponentTheme);
11199
+ const localComponentTheme = localTheme?.[componentName] ?? {};
11200
+ const { ownProps: localOwnProps, nestedThemes: localNestedThemes } = extractNestedThemes(localComponentTheme);
11201
+ const { nestedThemes: localThemeNested } = extractNestedThemes(localTheme ?? {});
11202
+ const { ownProps: explicitOwnProps, nestedThemes: explicitNestedThemes } = extractNestedThemes(explicitProps);
11203
+ const mergedProps = {
11204
+ ...deepMergeDefined(globalOwnProps, localOwnProps),
11205
+ ...deepMergeDefined({}, explicitOwnProps)
11205
11206
  };
11206
- }
11207
- function scheduleUpdate(c) {
11208
- if (c.updater) return;
11209
- c.updater = () => {
11210
- c.updater = void 0;
11211
- if (c.disposed) {
11212
- return;
11213
- }
11214
- const scene = c.parent instanceof Phaser.Scene ? c.parent : c.parent.scene;
11215
- if (!scene || !scene.sys || !scene.sys.settings.active) {
11216
- return;
11217
- }
11218
- const componentProps = c.componentVNode.props ?? {};
11219
- const propsWithChildren = c.componentVNode.children?.length ? { ...componentProps, children: c.componentVNode.children } : componentProps;
11220
- const nextVNode = normalizeVNodeLike(withHooks(c, () => c.function(propsWithChildren)));
11221
- patchVNode(c.parent, c.vnode, nextVNode);
11222
- c.vnode = nextVNode;
11223
- for (const run of c.effects) run();
11207
+ const mergedNestedThemes = mergeThemes(
11208
+ mergeThemes(mergeThemes(globalNestedThemes, localNestedThemes), localThemeNested),
11209
+ explicitNestedThemes
11210
+ );
11211
+ DebugLogger.log(
11212
+ "theme",
11213
+ `getThemedProps(${String(componentName)}): FINAL mergedProps:`,
11214
+ mergedProps
11215
+ );
11216
+ return {
11217
+ props: mergedProps,
11218
+ nestedTheme: mergedNestedThemes
11224
11219
  };
11225
- queueMicrotask(c.updater);
11226
- }
11227
- function disposeCtx(c) {
11228
- c.disposed = true;
11229
- for (const cl of c.cleanups) {
11230
- if (typeof cl === "function") cl();
11231
- }
11232
- for (const slot of c.slots) {
11233
- if (slot && typeof slot === "object" && "cleanup" in slot && typeof slot.cleanup === "function") {
11234
- slot.cleanup();
11235
- }
11236
- }
11237
- c.cleanups.length = 0;
11238
11220
  }
11239
11221
  const positionStates = /* @__PURE__ */ new WeakMap();
11240
11222
  function getPositionState(obj) {
@@ -12280,7 +12262,7 @@ function releaseAllSVGTextures() {
12280
12262
  function useSVGTexture(key, svg, width = 32, height = 32) {
12281
12263
  const [ready, setReady] = useState(false);
12282
12264
  const ctx = getCurrent() || {};
12283
- const scene = ctx.parent instanceof Phaser$1.Scene ? ctx.parent : ctx.parent?.scene;
12265
+ const scene = isPhaserScene(ctx.parent) ? ctx.parent : ctx.parent?.scene;
12284
12266
  useEffect(() => {
12285
12267
  if (!scene) return;
12286
12268
  let cancelled = false;
@@ -12301,7 +12283,7 @@ function useSVGTexture(key, svg, width = 32, height = 32) {
12301
12283
  function useSVGTextures(configs) {
12302
12284
  const [ready, setReady] = useState(false);
12303
12285
  const ctx = getCurrent() || {};
12304
- const scene = ctx.parent instanceof Phaser$1.Scene ? ctx.parent : ctx.parent?.scene;
12286
+ const scene = isPhaserScene(ctx.parent) ? ctx.parent : ctx.parent?.scene;
12305
12287
  const configKey = useMemo(
12306
12288
  () => configs.map((c) => `${c.key}:${c.width ?? 32}:${c.height ?? 32}`).join("|"),
12307
12289
  [configs]
@@ -12797,7 +12779,7 @@ function useSpring(initialValue, config, onComplete) {
12797
12779
  valueSignal.current = animatedSignal(initialValue);
12798
12780
  }
12799
12781
  const ctx = getCurrent();
12800
- const scene = ctx ? ctx.parent instanceof Phaser$1.Scene ? ctx.parent : ctx.parent.scene : null;
12782
+ const scene = ctx ? isPhaserScene(ctx.parent) ? ctx.parent : ctx.parent.scene : null;
12801
12783
  const state = useRef({ value: initialValue, velocity: 0 });
12802
12784
  const target = useRef({ value: initialValue });
12803
12785
  const physics = useRef(new SpringPhysics(resolvedConfig));
@@ -12870,7 +12852,7 @@ function useSprings(initialValues, config) {
12870
12852
  }
12871
12853
  });
12872
12854
  const ctx = getCurrent();
12873
- const scene = ctx ? ctx.parent instanceof Phaser$1.Scene ? ctx.parent : ctx.parent.scene : null;
12855
+ const scene = ctx ? isPhaserScene(ctx.parent) ? ctx.parent : ctx.parent.scene : null;
12874
12856
  if (scene && sceneRef.current !== scene) {
12875
12857
  sceneRef.current = scene;
12876
12858
  }
@@ -16967,77 +16949,77 @@ export {
16967
16949
  useState as Z,
16968
16950
  getPresetWithMode as _,
16969
16951
  AlertDialog as a,
16970
- nodeRegistry as a$,
16971
- defaultRadiusTokens as a0,
16972
- defaultSizeTokens as a1,
16973
- defaultSpacingTokens as a2,
16974
- createTextStyleTokens as a3,
16975
- normalizeCornerRadius as a4,
16976
- normalizeEdgeInsets as a5,
16977
- DOMInputElement as a6,
16978
- KeyboardInputManager as a7,
16979
- getMountStats as a8,
16980
- getRenderContext as a9,
16981
- createWobbleEffect as aA,
16982
- createZoomInEffect as aB,
16983
- createZoomOutEffect as aC,
16984
- getCurrent as aD,
16985
- withHooks as aE,
16986
- useForceRedraw as aF,
16987
- useMemo as aG,
16988
- useViewportSize as aH,
16989
- getLayoutSize as aI,
16990
- useLayoutSize as aJ,
16991
- getLayoutProps as aK,
16992
- getBackgroundGraphics as aL,
16993
- useBackgroundGraphics as aM,
16994
- getLayoutRect as aN,
16995
- useLayoutRect as aO,
16996
- getWorldLayoutRect as aP,
16997
- useWorldLayoutRect as aQ,
16998
- useLayoutEffect as aR,
16999
- shallowEqual as aS,
17000
- shouldComponentUpdate as aT,
17001
- useRedraw as aU,
17002
- disposeCtx as aV,
17003
- releaseSVGTexture as aW,
17004
- releaseSVGTextures as aX,
17005
- releaseAllSVGTextures as aY,
17006
- useSVGTexture as aZ,
17007
- useSVGTextures as a_,
17008
- DevConfig as aa,
17009
- DevPresets as ab,
17010
- svgToTexture as ac,
17011
- useGameObjectEffect as ad,
17012
- DEFAULT_EFFECT as ae,
17013
- EFFECT_REGISTRY as af,
17014
- applyEffectByName as ag,
17015
- resolveEffect as ah,
17016
- createBounceEffect as ai,
17017
- createBreatheEffect as aj,
17018
- createFadeEffect as ak,
17019
- createFlashEffect as al,
17020
- createFlipInEffect as am,
17021
- createFlipOutEffect as an,
17022
- createFloatEffect as ao,
17023
- createJelloEffect as ap,
17024
- createNoneEffect as aq,
17025
- createPressEffect as ar,
17026
- createPulseEffect as as,
17027
- createShakeEffect as at,
17028
- createSlideInEffect as au,
17029
- createSlideOutEffect as av,
17030
- createSpinEffect as aw,
17031
- createSwingEffect as ax,
17032
- createTadaEffect as ay,
17033
- createWiggleEffect as az,
16952
+ useSVGTextures as a$,
16953
+ remountAll as a0,
16954
+ defaultRadiusTokens as a1,
16955
+ defaultSizeTokens as a2,
16956
+ defaultSpacingTokens as a3,
16957
+ createTextStyleTokens as a4,
16958
+ normalizeCornerRadius as a5,
16959
+ normalizeEdgeInsets as a6,
16960
+ DOMInputElement as a7,
16961
+ KeyboardInputManager as a8,
16962
+ getMountStats as a9,
16963
+ createWiggleEffect as aA,
16964
+ createWobbleEffect as aB,
16965
+ createZoomInEffect as aC,
16966
+ createZoomOutEffect as aD,
16967
+ getCurrent as aE,
16968
+ withHooks as aF,
16969
+ useForceRedraw as aG,
16970
+ useMemo as aH,
16971
+ useViewportSize as aI,
16972
+ getLayoutSize as aJ,
16973
+ useLayoutSize as aK,
16974
+ getLayoutProps as aL,
16975
+ getBackgroundGraphics as aM,
16976
+ useBackgroundGraphics as aN,
16977
+ getLayoutRect as aO,
16978
+ useLayoutRect as aP,
16979
+ getWorldLayoutRect as aQ,
16980
+ useWorldLayoutRect as aR,
16981
+ useLayoutEffect as aS,
16982
+ shallowEqual as aT,
16983
+ shouldComponentUpdate as aU,
16984
+ useRedraw as aV,
16985
+ disposeCtx as aW,
16986
+ releaseSVGTexture as aX,
16987
+ releaseSVGTextures as aY,
16988
+ releaseAllSVGTextures as aZ,
16989
+ useSVGTexture as a_,
16990
+ getRenderContext as aa,
16991
+ DevConfig as ab,
16992
+ DevPresets as ac,
16993
+ svgToTexture as ad,
16994
+ useGameObjectEffect as ae,
16995
+ DEFAULT_EFFECT as af,
16996
+ EFFECT_REGISTRY as ag,
16997
+ applyEffectByName as ah,
16998
+ resolveEffect as ai,
16999
+ createBounceEffect as aj,
17000
+ createBreatheEffect as ak,
17001
+ createFadeEffect as al,
17002
+ createFlashEffect as am,
17003
+ createFlipInEffect as an,
17004
+ createFlipOutEffect as ao,
17005
+ createFloatEffect as ap,
17006
+ createJelloEffect as aq,
17007
+ createNoneEffect as ar,
17008
+ createPressEffect as as,
17009
+ createPulseEffect as at,
17010
+ createShakeEffect as au,
17011
+ createSlideInEffect as av,
17012
+ createSlideOutEffect as aw,
17013
+ createSpinEffect as ax,
17014
+ createSwingEffect as ay,
17015
+ createTadaEffect as az,
17034
17016
  CharTextInput as b,
17035
- host as b0,
17036
- createDefaultTheme as b1,
17037
- defaultTheme as b2,
17038
- mergeThemes as b3,
17039
- createTheme as b4,
17040
- remountAll as b5,
17017
+ nodeRegistry as b0,
17018
+ host as b1,
17019
+ createDefaultTheme as b2,
17020
+ defaultTheme as b3,
17021
+ mergeThemes as b4,
17022
+ createTheme as b5,
17041
17023
  normalizeVNodeLike as b6,
17042
17024
  createElement as b7,
17043
17025
  mount as b8,
@@ -17052,7 +17034,6 @@ export {
17052
17034
  oceanBluePreset as bH,
17053
17035
  presets as bI,
17054
17036
  defaultTextStyleTokens as bJ,
17055
- vdom as bK,
17056
17037
  patchVNode as ba,
17057
17038
  unmountJSX as bb,
17058
17039
  Graphics as bc,
@@ -17104,4 +17085,4 @@ export {
17104
17085
  getGestureManager as y,
17105
17086
  calculateLayout as z
17106
17087
  };
17107
- //# sourceMappingURL=TransformOriginView-TeXhLqNs.js.map
17088
+ //# sourceMappingURL=TransformOriginView-Y2LMZNcF.js.map