@number10/phaserjsx 0.4.2 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) 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/plugin.d.ts +1 -1
  27. package/dist/plugin.d.ts.map +1 -1
  28. package/dist/render-context.d.ts +1 -1
  29. package/dist/render-context.d.ts.map +1 -1
  30. package/dist/scene-backgrounds.d.ts +19 -0
  31. package/dist/scene-backgrounds.d.ts.map +1 -0
  32. package/dist/theme.d.ts.map +1 -1
  33. package/dist/utils/phaser-guards.d.ts +7 -0
  34. package/dist/utils/phaser-guards.d.ts.map +1 -0
  35. package/dist/vdom.d.ts.map +1 -1
  36. package/jsx-dev-runtime.d.ts +1 -0
  37. package/jsx-runtime.d.ts +1 -0
  38. package/package.json +4 -2
  39. package/dist/TransformOriginView-CrzevUOh.cjs.map +0 -1
  40. package/dist/TransformOriginView-TeXhLqNs.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  const jsxRuntime = require("./jsx-runtime.cjs");
3
- const Phaser$1 = require("phaser");
3
+ const Phaser = require("phaser");
4
4
  const signalsCore = require("@preact/signals-core");
5
5
  function _interopNamespaceDefault(e) {
6
6
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -37,7 +37,17 @@ function _mergeNamespaces(n, m) {
37
37
  }
38
38
  return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: "Module" }));
39
39
  }
40
- const Phaser__namespace = /* @__PURE__ */ _interopNamespaceDefault(Phaser$1);
40
+ const Phaser__namespace = /* @__PURE__ */ _interopNamespaceDefault(Phaser);
41
+ function isPhaserScene(value) {
42
+ if (!value || typeof value !== "object") return false;
43
+ const maybe = value;
44
+ return typeof maybe.sys === "object" && typeof maybe.add === "object";
45
+ }
46
+ function isPhaserContainer(value) {
47
+ if (!value || typeof value !== "object") return false;
48
+ const maybe = value;
49
+ return Array.isArray(maybe.list) && typeof maybe.add === "function" && typeof maybe.remove === "function";
50
+ }
41
51
  const nodeRegistry = {};
42
52
  function register(type, descriptor) {
43
53
  nodeRegistry[type] = descriptor;
@@ -78,9 +88,9 @@ const host = {
78
88
  * @param child - Child node to append
79
89
  */
80
90
  append(parent, child) {
81
- if (parent instanceof Phaser__namespace.GameObjects.Container) {
91
+ if (isPhaserContainer(parent)) {
82
92
  parent.add(child);
83
- } else if (parent && typeof parent === "object" && "sys" in parent) {
93
+ } else if (isPhaserScene(parent)) {
84
94
  const scene = parent;
85
95
  scene.add.existing(child);
86
96
  } else if (parent && typeof parent === "object" && "scene" in parent) {
@@ -98,7 +108,7 @@ const host = {
98
108
  remove(parent, child) {
99
109
  const childObj = child;
100
110
  if (!childObj.scene) return;
101
- if (parent instanceof Phaser__namespace.GameObjects.Container) {
111
+ if (isPhaserContainer(parent)) {
102
112
  parent.remove(childObj, false);
103
113
  }
104
114
  if (childObj.destroy) {
@@ -8821,18 +8831,6 @@ function getPresetWithMode(name, mode) {
8821
8831
  const preset2 = getPreset(name);
8822
8832
  return mode === "light" ? applyLightMode(preset2) : applyDarkMode(preset2);
8823
8833
  }
8824
- const colorPresets = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
8825
- __proto__: null,
8826
- applyDarkMode,
8827
- applyLightMode,
8828
- forestGreenPreset,
8829
- generateColorScale,
8830
- getPreset,
8831
- getPresetWithMode,
8832
- midnightPreset,
8833
- oceanBluePreset,
8834
- presets
8835
- }, Symbol.toStringTag, { value: "Module" }));
8836
8834
  const defaultSpacingTokens = {
8837
8835
  xs: 4,
8838
8836
  sm: 8,
@@ -9409,253 +9407,6 @@ function createDefaultTheme(presetName = "oceanBlue", mode = "light") {
9409
9407
  const presetForMode = getPresetWithMode(presetName, mode);
9410
9408
  return buildDefaultTheme(presetForMode.colors);
9411
9409
  }
9412
- class ThemeRegistry {
9413
- globalTheme = { ...defaultTheme };
9414
- customThemes = /* @__PURE__ */ new Map();
9415
- colorTokens = void 0;
9416
- colorMode = "light";
9417
- currentPresetName = void 0;
9418
- listeners = /* @__PURE__ */ new Set();
9419
- /**
9420
- * Get the complete global theme
9421
- */
9422
- getGlobalTheme() {
9423
- return { ...this.globalTheme, ...Object.fromEntries(this.customThemes) };
9424
- }
9425
- /**
9426
- * Update global theme (deep merge)
9427
- * @param theme - Partial theme to merge with current global theme
9428
- */
9429
- updateGlobalTheme(theme) {
9430
- for (const [component, styles] of Object.entries(theme)) {
9431
- if (component in this.globalTheme) {
9432
- this.globalTheme[component] = {
9433
- ...this.globalTheme[component],
9434
- ...styles
9435
- };
9436
- DebugLogger.log(
9437
- "theme",
9438
- `Updated ${component} theme:`,
9439
- this.globalTheme[component]
9440
- );
9441
- } else {
9442
- const existing = this.customThemes.get(component) ?? {};
9443
- this.customThemes.set(component, { ...existing, ...styles });
9444
- }
9445
- }
9446
- }
9447
- /**
9448
- * Set the entire global theme (replaces current theme)
9449
- * @param theme - Complete theme to set
9450
- */
9451
- setGlobalTheme(theme) {
9452
- this.globalTheme = { ...theme };
9453
- }
9454
- /**
9455
- * Reset global theme to default values
9456
- */
9457
- resetGlobalTheme() {
9458
- this.globalTheme = { ...defaultTheme };
9459
- this.customThemes.clear();
9460
- }
9461
- /**
9462
- * Register a custom component theme
9463
- * @param componentName - Name of the custom component
9464
- * @param defaultStyles - Default styles for the component
9465
- */
9466
- registerCustomComponent(componentName, defaultStyles) {
9467
- this.customThemes.set(componentName, defaultStyles);
9468
- }
9469
- /**
9470
- * Get theme for a specific component
9471
- * @param componentName - Component name
9472
- * @returns Theme for the component
9473
- */
9474
- getComponentTheme(componentName) {
9475
- if (componentName in this.globalTheme) {
9476
- const theme = this.globalTheme[componentName];
9477
- return theme;
9478
- }
9479
- return this.customThemes.get(componentName) ?? {};
9480
- }
9481
- /**
9482
- * Get all registered custom component names
9483
- * @returns Set of custom component names
9484
- */
9485
- getCustomComponentNames() {
9486
- return new Set(this.customThemes.keys());
9487
- }
9488
- /**
9489
- * Set color tokens for the global theme
9490
- * @param colors - ColorTokens to use globally
9491
- */
9492
- setColorTokens(colors) {
9493
- this.colorTokens = colors;
9494
- }
9495
- /**
9496
- * Get current color tokens
9497
- * @returns Current ColorTokens or undefined
9498
- */
9499
- getColorTokens() {
9500
- return this.colorTokens;
9501
- }
9502
- /**
9503
- * Get current color mode
9504
- * @returns Current color mode
9505
- */
9506
- getColorMode() {
9507
- return this.colorMode;
9508
- }
9509
- /**
9510
- * Set color mode and trigger complete remount
9511
- * Updates color tokens if a preset is active
9512
- * Triggers complete remount of all active mountJSX instances
9513
- * @param mode - Color mode to set
9514
- */
9515
- setColorMode(mode) {
9516
- if (this.colorMode !== mode) {
9517
- this.colorMode = mode;
9518
- if (this.currentPresetName) {
9519
- Promise.resolve().then(() => colorPresets).then(({ getPresetWithMode: getPresetWithMode2 }) => {
9520
- const preset2 = getPresetWithMode2(
9521
- this.currentPresetName,
9522
- mode
9523
- );
9524
- this.colorTokens = preset2.colors;
9525
- });
9526
- }
9527
- setTimeout(() => {
9528
- Promise.resolve().then(() => vdom).then(({ remountAll: remountAll2 }) => {
9529
- remountAll2();
9530
- });
9531
- }, 0);
9532
- }
9533
- }
9534
- /**
9535
- * Get current preset name
9536
- * @returns Current preset name or undefined
9537
- */
9538
- getCurrentPresetName() {
9539
- return this.currentPresetName;
9540
- }
9541
- /**
9542
- * Set current preset name
9543
- * @param name - Preset name
9544
- * @param skipNotify - If true, skip notifying listeners (used during remount)
9545
- */
9546
- setCurrentPresetName(name, skipNotify = false) {
9547
- if (this.currentPresetName !== name) {
9548
- this.currentPresetName = name;
9549
- if (!skipNotify) {
9550
- this.notifyListeners();
9551
- }
9552
- }
9553
- }
9554
- /**
9555
- * Subscribe to theme changes
9556
- * @param listener - Callback to invoke on theme change
9557
- * @returns Unsubscribe function
9558
- */
9559
- subscribe(listener) {
9560
- this.listeners.add(listener);
9561
- return () => {
9562
- this.listeners.delete(listener);
9563
- };
9564
- }
9565
- /**
9566
- * Notify all listeners of theme change
9567
- */
9568
- notifyListeners() {
9569
- this.listeners.forEach((listener) => listener());
9570
- }
9571
- }
9572
- const themeRegistry = new ThemeRegistry();
9573
- function mergeThemes(base, override) {
9574
- const result = { ...base };
9575
- for (const [component, styles] of Object.entries(override)) {
9576
- if (component in result) {
9577
- result[component] = {
9578
- ...result[component],
9579
- ...styles
9580
- };
9581
- } else {
9582
- result[component] = styles;
9583
- }
9584
- }
9585
- return result;
9586
- }
9587
- function createTheme(theme, colorPreset) {
9588
- if (colorPreset) {
9589
- themeRegistry.setColorTokens(colorPreset.colors);
9590
- return {
9591
- ...theme,
9592
- __colorPreset: {
9593
- name: colorPreset.name,
9594
- mode: colorPreset.mode ?? "light"
9595
- }
9596
- };
9597
- }
9598
- return theme;
9599
- }
9600
- function deepMergeDefined(base, override) {
9601
- const result = { ...base };
9602
- for (const key in override) {
9603
- const value = override[key];
9604
- if (value !== void 0) {
9605
- if (typeof value === "object" && value !== null && !Array.isArray(value) && typeof base[key] === "object" && base[key] !== null) {
9606
- result[key] = deepMergeDefined(
9607
- base[key],
9608
- value
9609
- );
9610
- } else {
9611
- result[key] = value;
9612
- }
9613
- }
9614
- }
9615
- return result;
9616
- }
9617
- function extractNestedThemes(theme) {
9618
- const ownProps = { ...theme };
9619
- const nestedThemes = {};
9620
- const allComponentNames = /* @__PURE__ */ new Set([
9621
- "View",
9622
- "Text",
9623
- "NineSlice",
9624
- ...Array.from(themeRegistry.getCustomComponentNames())
9625
- ]);
9626
- for (const key in ownProps) {
9627
- if (allComponentNames.has(key)) {
9628
- nestedThemes[key] = ownProps[key];
9629
- delete ownProps[key];
9630
- }
9631
- }
9632
- return { ownProps, nestedThemes };
9633
- }
9634
- function getThemedProps(componentName, localTheme, explicitProps) {
9635
- const globalComponentTheme = themeRegistry.getComponentTheme(componentName);
9636
- const { ownProps: globalOwnProps, nestedThemes: globalNestedThemes } = extractNestedThemes(globalComponentTheme);
9637
- const localComponentTheme = localTheme?.[componentName] ?? {};
9638
- const { ownProps: localOwnProps, nestedThemes: localNestedThemes } = extractNestedThemes(localComponentTheme);
9639
- const { nestedThemes: localThemeNested } = extractNestedThemes(localTheme ?? {});
9640
- const { ownProps: explicitOwnProps, nestedThemes: explicitNestedThemes } = extractNestedThemes(explicitProps);
9641
- const mergedProps = {
9642
- ...deepMergeDefined(globalOwnProps, localOwnProps),
9643
- ...deepMergeDefined({}, explicitOwnProps)
9644
- };
9645
- const mergedNestedThemes = mergeThemes(
9646
- mergeThemes(mergeThemes(globalNestedThemes, localNestedThemes), localThemeNested),
9647
- explicitNestedThemes
9648
- );
9649
- DebugLogger.log(
9650
- "theme",
9651
- `getThemedProps(${String(componentName)}): FINAL mergedProps:`,
9652
- mergedProps
9653
- );
9654
- return {
9655
- props: mergedProps,
9656
- nestedTheme: mergedNestedThemes
9657
- };
9658
- }
9659
9410
  class RenderContext {
9660
9411
  constructor(scene) {
9661
9412
  this.scene = scene;
@@ -9787,11 +9538,11 @@ class RenderContext {
9787
9538
  }
9788
9539
  }
9789
9540
  function getRenderContext(parentOrScene) {
9790
- const scene = parentOrScene instanceof Phaser__namespace.Scene ? parentOrScene : parentOrScene.scene;
9541
+ const scene = isPhaserScene(parentOrScene) ? parentOrScene : parentOrScene.scene;
9791
9542
  if (!scene || !scene.data || !scene.sys || !scene.sys.settings.active) {
9792
9543
  throw new Error("getRenderContext: Invalid scene or scene.data is undefined");
9793
9544
  }
9794
- const containerKey = parentOrScene instanceof Phaser__namespace.GameObjects.Container ? `__renderContext_${parentOrScene.name || parentOrScene.id || "container"}__` : "__renderContext_scene__";
9545
+ const containerKey = isPhaserContainer(parentOrScene) ? `__renderContext_${parentOrScene.name || parentOrScene.id || "container"}__` : "__renderContext_scene__";
9795
9546
  let context = scene.data.get(containerKey);
9796
9547
  if (!context) {
9797
9548
  context = new RenderContext(scene);
@@ -9811,18 +9562,268 @@ function getContextFromParent(parent) {
9811
9562
  }
9812
9563
  return getRenderContext(parent);
9813
9564
  }
9814
- function View(props) {
9815
- const localTheme = useTheme();
9816
- const { props: themed, nestedTheme } = getThemedProps("View", localTheme, props);
9817
- return /* @__PURE__ */ jsxRuntime.jsx("view", { ...themed, theme: nestedTheme });
9818
- }
9819
- function SceneWrapper(props) {
9820
- const { width, height, children } = props;
9821
- return /* @__PURE__ */ jsxRuntime.jsx(View, { width, height, children });
9565
+ function getCurrent() {
9566
+ return _currentCtx;
9822
9567
  }
9823
- class PortalRegistry {
9824
- portals = /* @__PURE__ */ new Map();
9825
- idCounter = 0;
9568
+ let _currentCtx = null;
9569
+ function withHooks(ctx, render) {
9570
+ const scene = isPhaserScene(ctx.parent) ? ctx.parent : ctx.parent.scene;
9571
+ if (!scene || !scene.sys || !scene.sys.settings.active) {
9572
+ return null;
9573
+ }
9574
+ const renderContext = getContextFromParent(ctx.parent);
9575
+ if (renderContext.isShutdown()) {
9576
+ return null;
9577
+ }
9578
+ const prev = renderContext.getCurrent();
9579
+ const prevModule = _currentCtx;
9580
+ renderContext.setCurrent(ctx);
9581
+ _currentCtx = ctx;
9582
+ ctx.index = 0;
9583
+ ctx.effects = [];
9584
+ const out = render();
9585
+ renderContext.setCurrent(prev);
9586
+ _currentCtx = prevModule;
9587
+ return out;
9588
+ }
9589
+ function useState(initial) {
9590
+ const c = getCurrent();
9591
+ const i = c.index++;
9592
+ if (i >= c.slots.length)
9593
+ c.slots[i] = typeof initial === "function" ? initial() : initial;
9594
+ const value = c.slots[i];
9595
+ const set = (v) => {
9596
+ const next = typeof v === "function" ? v(c.slots[i]) : v;
9597
+ if (Object.is(next, c.slots[i])) return;
9598
+ c.slots[i] = next;
9599
+ scheduleUpdate(c);
9600
+ };
9601
+ return [value, set];
9602
+ }
9603
+ function useRef(val) {
9604
+ const c = getCurrent();
9605
+ const i = c.index++;
9606
+ if (i >= c.slots.length) c.slots[i] = { current: val };
9607
+ return c.slots[i];
9608
+ }
9609
+ function useForceRedraw(first, ...rest) {
9610
+ const [, setForceRedraw] = useState(0);
9611
+ const throttleMs = typeof first === "number" ? first : void 0;
9612
+ const signals = typeof first === "number" ? rest : [first, ...rest];
9613
+ useEffect(() => {
9614
+ const unsubscribes = [];
9615
+ let lastUpdate = 0;
9616
+ const triggerUpdate = () => {
9617
+ const now = Date.now();
9618
+ if (throttleMs && now - lastUpdate < throttleMs) return;
9619
+ lastUpdate = now;
9620
+ setForceRedraw({});
9621
+ };
9622
+ for (const signal of signals) {
9623
+ if (signal && typeof signal === "object" && "subscribe" in signal) {
9624
+ const subscriptions = signal.subscribe(triggerUpdate);
9625
+ unsubscribes.push(subscriptions);
9626
+ }
9627
+ }
9628
+ return () => {
9629
+ unsubscribes.forEach((unsubscribe) => unsubscribe());
9630
+ };
9631
+ }, [throttleMs, ...signals]);
9632
+ }
9633
+ function useMemo(fn, deps) {
9634
+ const c = getCurrent();
9635
+ const i = c.index++;
9636
+ const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, value: void 0 });
9637
+ if (!depsChanged(slot.deps, deps)) return slot.value;
9638
+ slot.value = fn();
9639
+ slot.deps = deps;
9640
+ return slot.value;
9641
+ }
9642
+ function useCallback(fn, deps) {
9643
+ return useMemo(() => fn, deps);
9644
+ }
9645
+ function useTheme() {
9646
+ return getCurrent()?.theme;
9647
+ }
9648
+ function useScene() {
9649
+ const ctx = getCurrent();
9650
+ if (!ctx) throw new Error("useScene must be called within a component");
9651
+ const renderContext = getContextFromParent(ctx.parent);
9652
+ return renderContext.scene;
9653
+ }
9654
+ function useViewportSize() {
9655
+ const ctx = getCurrent();
9656
+ if (!ctx) {
9657
+ throw new Error("useViewportSize must be called within a component");
9658
+ }
9659
+ const renderContext = getContextFromParent(ctx.parent);
9660
+ return renderContext.getViewport();
9661
+ }
9662
+ function getLayoutSize(container) {
9663
+ if (!container) return void 0;
9664
+ const withLayout = container;
9665
+ return withLayout.__getLayoutSize?.();
9666
+ }
9667
+ function useLayoutSize(ref) {
9668
+ return getLayoutSize(ref.current);
9669
+ }
9670
+ function getLayoutProps(container) {
9671
+ if (!container) return void 0;
9672
+ const withLayout = container;
9673
+ return withLayout.__layoutProps;
9674
+ }
9675
+ function getBackgroundGraphics(container) {
9676
+ if (!container) return void 0;
9677
+ const withBackground = container;
9678
+ return withBackground.__background;
9679
+ }
9680
+ function useBackgroundGraphics(ref) {
9681
+ return getBackgroundGraphics(ref.current);
9682
+ }
9683
+ function getLayoutRect(container) {
9684
+ if (!container) return void 0;
9685
+ const size = getLayoutSize(container);
9686
+ if (!size) return void 0;
9687
+ return {
9688
+ x: container.x,
9689
+ y: container.y,
9690
+ width: size.width,
9691
+ height: size.height
9692
+ };
9693
+ }
9694
+ function useLayoutRect(ref) {
9695
+ return getLayoutRect(ref.current);
9696
+ }
9697
+ function getWorldLayoutRect(container) {
9698
+ if (!container) return void 0;
9699
+ const size = getLayoutSize(container);
9700
+ if (!size) return void 0;
9701
+ const matrix = container.getWorldTransformMatrix();
9702
+ const worldX = matrix.tx;
9703
+ const worldY = matrix.ty;
9704
+ const worldWidth = size.width * Math.abs(matrix.scaleX);
9705
+ const worldHeight = size.height * Math.abs(matrix.scaleY);
9706
+ return {
9707
+ x: worldX,
9708
+ y: worldY,
9709
+ width: worldWidth,
9710
+ height: worldHeight
9711
+ };
9712
+ }
9713
+ function useWorldLayoutRect(ref) {
9714
+ return getWorldLayoutRect(ref.current);
9715
+ }
9716
+ function useEffect(fn, deps) {
9717
+ const c = getCurrent();
9718
+ const i = c.index++;
9719
+ const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, cleanup: void 0 });
9720
+ c.effects.push(() => {
9721
+ if (!depsChanged(slot.deps, deps)) return;
9722
+ if (typeof slot.cleanup === "function") slot.cleanup();
9723
+ slot.cleanup = fn();
9724
+ if (deps !== void 0) {
9725
+ slot.deps = deps;
9726
+ }
9727
+ });
9728
+ }
9729
+ function useLayoutEffect(fn, deps) {
9730
+ const c = getCurrent();
9731
+ const i = c.index++;
9732
+ const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, cleanup: void 0 });
9733
+ c.effects.push(() => {
9734
+ if (!depsChanged(slot.deps, deps)) return;
9735
+ if (typeof slot.cleanup === "function") slot.cleanup();
9736
+ requestAnimationFrame(() => {
9737
+ slot.cleanup = fn();
9738
+ });
9739
+ if (deps !== void 0) {
9740
+ slot.deps = deps;
9741
+ }
9742
+ });
9743
+ }
9744
+ function depsChanged(a, b) {
9745
+ if (!a || !b) return true;
9746
+ if (a.length !== b.length) return true;
9747
+ for (let i = 0; i < a.length; i++) {
9748
+ if (!Object.is(a[i], b[i])) return true;
9749
+ }
9750
+ return false;
9751
+ }
9752
+ function shallowEqual(a, b) {
9753
+ if (Object.is(a, b)) return true;
9754
+ if (a == null || b == null) return false;
9755
+ if (typeof a !== "object" || typeof b !== "object") return false;
9756
+ const keysA = Object.keys(a);
9757
+ const keysB = Object.keys(b);
9758
+ if (keysA.length !== keysB.length) return false;
9759
+ for (const key of keysA) {
9760
+ if (!Object.prototype.hasOwnProperty.call(b, key) || !Object.is(a[key], b[key])) {
9761
+ return false;
9762
+ }
9763
+ }
9764
+ return true;
9765
+ }
9766
+ function shouldComponentUpdate(ctx, newProps) {
9767
+ if (ctx.memoized === false) return true;
9768
+ if (ctx.componentVNode.__memo === false) return true;
9769
+ if (ctx.lastProps === void 0) {
9770
+ ctx.lastProps = newProps;
9771
+ return true;
9772
+ }
9773
+ const hasChanged = !shallowEqual(ctx.lastProps, newProps);
9774
+ ctx.lastProps = newProps;
9775
+ return hasChanged;
9776
+ }
9777
+ function useRedraw() {
9778
+ const c = getCurrent();
9779
+ return () => {
9780
+ if (c != null) scheduleUpdate(c);
9781
+ };
9782
+ }
9783
+ function scheduleUpdate(c) {
9784
+ if (c.updater) return;
9785
+ c.updater = () => {
9786
+ c.updater = void 0;
9787
+ if (c.disposed) {
9788
+ return;
9789
+ }
9790
+ const scene = isPhaserScene(c.parent) ? c.parent : c.parent.scene;
9791
+ if (!scene || !scene.sys || !scene.sys.settings.active) {
9792
+ return;
9793
+ }
9794
+ const componentProps = c.componentVNode.props ?? {};
9795
+ const propsWithChildren = c.componentVNode.children?.length ? { ...componentProps, children: c.componentVNode.children } : componentProps;
9796
+ const nextVNode = normalizeVNodeLike(withHooks(c, () => c.function(propsWithChildren)));
9797
+ patchVNode(c.parent, c.vnode, nextVNode);
9798
+ c.vnode = nextVNode;
9799
+ for (const run of c.effects) run();
9800
+ };
9801
+ queueMicrotask(c.updater);
9802
+ }
9803
+ function disposeCtx(c) {
9804
+ c.disposed = true;
9805
+ for (const cl of c.cleanups) {
9806
+ if (typeof cl === "function") cl();
9807
+ }
9808
+ for (const slot of c.slots) {
9809
+ if (slot && typeof slot === "object" && "cleanup" in slot && typeof slot.cleanup === "function") {
9810
+ slot.cleanup();
9811
+ }
9812
+ }
9813
+ c.cleanups.length = 0;
9814
+ }
9815
+ function View(props) {
9816
+ const localTheme = useTheme();
9817
+ const { props: themed, nestedTheme } = getThemedProps("View", localTheme, props);
9818
+ return /* @__PURE__ */ jsxRuntime.jsx("view", { ...themed, theme: nestedTheme });
9819
+ }
9820
+ function SceneWrapper(props) {
9821
+ const { width, height, children } = props;
9822
+ return /* @__PURE__ */ jsxRuntime.jsx(View, { width, height, children });
9823
+ }
9824
+ class PortalRegistry {
9825
+ portals = /* @__PURE__ */ new Map();
9826
+ idCounter = 0;
9826
9827
  portalRoots = /* @__PURE__ */ new Map();
9827
9828
  viewportSizes = /* @__PURE__ */ new Map();
9828
9829
  /**
@@ -10018,7 +10019,7 @@ class MountRegistry {
10018
10019
  */
10019
10020
  findByParentAndKey(parent, key) {
10020
10021
  for (const entry of this.entries.values()) {
10021
- const scene = entry.parent instanceof Phaser__namespace.Scene ? entry.parent : entry.parent.scene;
10022
+ const scene = isPhaserScene(entry.parent) ? entry.parent : entry.parent.scene;
10022
10023
  if (!scene || !scene.sys || !scene.sys.settings.active) {
10023
10024
  DebugLogger.log("vdom", `Removing mount ${entry.id} - scene inactive`);
10024
10025
  this.unregister(entry.id);
@@ -10073,7 +10074,7 @@ class MountRegistry {
10073
10074
  if (key) {
10074
10075
  byKey.set(key, (byKey.get(key) ?? 0) + 1);
10075
10076
  }
10076
- const parentType = entry.parent instanceof Phaser__namespace.Scene ? "Scene" : "Container";
10077
+ const parentType = isPhaserScene(entry.parent) ? "Scene" : "Container";
10077
10078
  const mountInfo = {
10078
10079
  id: entry.id,
10079
10080
  type: typeName,
@@ -10114,13 +10115,13 @@ function remountAll() {
10114
10115
  console.log(`[REMOUNT] Starting remount of ${entries.length} root(s)`);
10115
10116
  entries.forEach((entry) => {
10116
10117
  try {
10117
- const scene = entry.parent instanceof Phaser__namespace.Scene ? entry.parent : entry.parent.scene;
10118
+ const scene = isPhaserScene(entry.parent) ? entry.parent : entry.parent.scene;
10118
10119
  if (!scene || !scene.sys) {
10119
10120
  console.warn("[REMOUNT] Scene is invalid, skipping remount");
10120
10121
  return;
10121
10122
  }
10122
10123
  const currentVNode = scene.__rootVNode;
10123
- if (entry.rootNode instanceof Phaser__namespace.GameObjects.Container) {
10124
+ if (isPhaserContainer(entry.rootNode)) {
10124
10125
  const children = entry.rootNode.getAll();
10125
10126
  children.forEach((child) => {
10126
10127
  ;
@@ -10161,7 +10162,7 @@ function remountAll() {
10161
10162
  ;
10162
10163
  scene.__rootVNode = vnode;
10163
10164
  const rootNode = mount(entry.parent, vnode);
10164
- if (rootNode instanceof Phaser__namespace.GameObjects.Container) {
10165
+ if (isPhaserContainer(rootNode)) {
10165
10166
  ;
10166
10167
  rootNode.__mountRootId = generateMountRootId();
10167
10168
  }
@@ -10419,7 +10420,7 @@ function mount(parentOrScene, vnode) {
10419
10420
  vnode.__theme
10420
10421
  );
10421
10422
  }
10422
- const scene2 = parentOrScene instanceof Phaser__namespace.Scene ? parentOrScene : parentOrScene.scene;
10423
+ const scene2 = isPhaserScene(parentOrScene) ? parentOrScene : parentOrScene.scene;
10423
10424
  const ctx = {
10424
10425
  index: 0,
10425
10426
  slots: [],
@@ -10534,7 +10535,7 @@ function mount(parentOrScene, vnode) {
10534
10535
  if (node && "list" in node && Array.isArray(node.list)) {
10535
10536
  const container = node;
10536
10537
  let parentSize;
10537
- if (parentOrScene instanceof Phaser__namespace.GameObjects.Container) {
10538
+ if (isPhaserContainer(parentOrScene)) {
10538
10539
  const parentContainer = parentOrScene;
10539
10540
  if (parentContainer.__getLayoutSize) {
10540
10541
  const parentTotalSize = parentContainer.__getLayoutSize();
@@ -10833,7 +10834,7 @@ function patchVNode(parent, oldV, newV) {
10833
10834
  const container = oldV.__node;
10834
10835
  if (container.__layoutProps) {
10835
10836
  let parentSize;
10836
- if (parent instanceof Phaser__namespace.GameObjects.Container) {
10837
+ if (isPhaserContainer(parent)) {
10837
10838
  const parentContainer = parent;
10838
10839
  if (parentContainer.__getLayoutSize) {
10839
10840
  const parentTotalSize = parentContainer.__getLayoutSize();
@@ -10925,7 +10926,7 @@ Solution: Add unique keys like { key: 'sidebar', ... } and { key: 'main', ... }`
10925
10926
  return handle2;
10926
10927
  }
10927
10928
  const { width, height, disableAutoSize = false, key: _key, ...componentProps } = props;
10928
- const scene = parentOrScene instanceof Phaser__namespace.Scene ? parentOrScene : parentOrScene.scene;
10929
+ const scene = isPhaserScene(parentOrScene) ? parentOrScene : parentOrScene.scene;
10929
10930
  if (scene) {
10930
10931
  const renderContext = getRenderContext(parentOrScene);
10931
10932
  renderContext.setViewport(width, height, scene);
@@ -10958,7 +10959,7 @@ Solution: Add unique keys like { key: 'sidebar', ... } and { key: 'main', ... }`
10958
10959
  scene.__rootVNode = vnode;
10959
10960
  }
10960
10961
  const rootNode = mount(parentOrScene, vnode);
10961
- if (rootNode instanceof Phaser__namespace.GameObjects.Container) {
10962
+ if (isPhaserContainer(rootNode)) {
10962
10963
  rootNode.__mountRootId = generateMountRootId();
10963
10964
  }
10964
10965
  rootNode.__rootVNode = vnode;
@@ -10969,7 +10970,7 @@ Solution: Add unique keys like { key: 'sidebar', ... } and { key: 'main', ... }`
10969
10970
  return handle;
10970
10971
  }
10971
10972
  function unmountJSX(target) {
10972
- const scene = target instanceof Phaser__namespace.Scene ? target : target.scene;
10973
+ const scene = isPhaserScene(target) ? target : target.scene;
10973
10974
  const targetWithVNode = target;
10974
10975
  const sceneWithVNode = scene;
10975
10976
  const rootVNode = targetWithVNode.__rootVNode ?? sceneWithVNode?.__rootVNode;
@@ -10992,267 +10993,248 @@ function unmountJSX(target) {
10992
10993
  }
10993
10994
  DebugLogger.log("vdom", "unmountJSX called but no root VNode found on target");
10994
10995
  }
10995
- const vdom = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
10996
- __proto__: null,
10997
- createElement,
10998
- getMountStats,
10999
- mount,
11000
- mountJSX,
11001
- normalizeVNodeLike,
11002
- patchVNode,
11003
- remountAll,
11004
- unmount,
11005
- unmountJSX
11006
- }, Symbol.toStringTag, { value: "Module" }));
11007
- function getCurrent() {
11008
- return _currentCtx;
11009
- }
11010
- let _currentCtx = null;
11011
- function withHooks(ctx, render) {
11012
- const scene = ctx.parent instanceof Phaser.Scene ? ctx.parent : ctx.parent.scene;
11013
- if (!scene || !scene.sys || !scene.sys.settings.active) {
11014
- return null;
10996
+ class ThemeRegistry {
10997
+ globalTheme = { ...defaultTheme };
10998
+ customThemes = /* @__PURE__ */ new Map();
10999
+ colorTokens = void 0;
11000
+ colorMode = "light";
11001
+ currentPresetName = void 0;
11002
+ listeners = /* @__PURE__ */ new Set();
11003
+ /**
11004
+ * Get the complete global theme
11005
+ */
11006
+ getGlobalTheme() {
11007
+ return { ...this.globalTheme, ...Object.fromEntries(this.customThemes) };
11015
11008
  }
11016
- const renderContext = getContextFromParent(ctx.parent);
11017
- if (renderContext.isShutdown()) {
11018
- return null;
11009
+ /**
11010
+ * Update global theme (deep merge)
11011
+ * @param theme - Partial theme to merge with current global theme
11012
+ */
11013
+ updateGlobalTheme(theme) {
11014
+ for (const [component, styles] of Object.entries(theme)) {
11015
+ if (component in this.globalTheme) {
11016
+ this.globalTheme[component] = {
11017
+ ...this.globalTheme[component],
11018
+ ...styles
11019
+ };
11020
+ DebugLogger.log(
11021
+ "theme",
11022
+ `Updated ${component} theme:`,
11023
+ this.globalTheme[component]
11024
+ );
11025
+ } else {
11026
+ const existing = this.customThemes.get(component) ?? {};
11027
+ this.customThemes.set(component, { ...existing, ...styles });
11028
+ }
11029
+ }
11019
11030
  }
11020
- const prev = renderContext.getCurrent();
11021
- const prevModule = _currentCtx;
11022
- renderContext.setCurrent(ctx);
11023
- _currentCtx = ctx;
11024
- ctx.index = 0;
11025
- ctx.effects = [];
11026
- const out = render();
11027
- renderContext.setCurrent(prev);
11028
- _currentCtx = prevModule;
11029
- return out;
11030
- }
11031
- function useState(initial) {
11032
- const c = getCurrent();
11033
- const i = c.index++;
11034
- if (i >= c.slots.length)
11035
- c.slots[i] = typeof initial === "function" ? initial() : initial;
11036
- const value = c.slots[i];
11037
- const set = (v) => {
11038
- const next = typeof v === "function" ? v(c.slots[i]) : v;
11039
- if (Object.is(next, c.slots[i])) return;
11040
- c.slots[i] = next;
11041
- scheduleUpdate(c);
11042
- };
11043
- return [value, set];
11044
- }
11045
- function useRef(val) {
11046
- const c = getCurrent();
11047
- const i = c.index++;
11048
- if (i >= c.slots.length) c.slots[i] = { current: val };
11049
- return c.slots[i];
11050
- }
11051
- function useForceRedraw(first, ...rest) {
11052
- const [, setForceRedraw] = useState(0);
11053
- const throttleMs = typeof first === "number" ? first : void 0;
11054
- const signals = typeof first === "number" ? rest : [first, ...rest];
11055
- useEffect(() => {
11056
- const unsubscribes = [];
11057
- let lastUpdate = 0;
11058
- const triggerUpdate = () => {
11059
- const now = Date.now();
11060
- if (throttleMs && now - lastUpdate < throttleMs) return;
11061
- lastUpdate = now;
11062
- setForceRedraw({});
11063
- };
11064
- for (const signal of signals) {
11065
- if (signal && typeof signal === "object" && "subscribe" in signal) {
11066
- const subscriptions = signal.subscribe(triggerUpdate);
11067
- unsubscribes.push(subscriptions);
11031
+ /**
11032
+ * Set the entire global theme (replaces current theme)
11033
+ * @param theme - Complete theme to set
11034
+ */
11035
+ setGlobalTheme(theme) {
11036
+ this.globalTheme = { ...theme };
11037
+ }
11038
+ /**
11039
+ * Reset global theme to default values
11040
+ */
11041
+ resetGlobalTheme() {
11042
+ this.globalTheme = { ...defaultTheme };
11043
+ this.customThemes.clear();
11044
+ }
11045
+ /**
11046
+ * Register a custom component theme
11047
+ * @param componentName - Name of the custom component
11048
+ * @param defaultStyles - Default styles for the component
11049
+ */
11050
+ registerCustomComponent(componentName, defaultStyles) {
11051
+ this.customThemes.set(componentName, defaultStyles);
11052
+ }
11053
+ /**
11054
+ * Get theme for a specific component
11055
+ * @param componentName - Component name
11056
+ * @returns Theme for the component
11057
+ */
11058
+ getComponentTheme(componentName) {
11059
+ if (componentName in this.globalTheme) {
11060
+ const theme = this.globalTheme[componentName];
11061
+ return theme;
11062
+ }
11063
+ return this.customThemes.get(componentName) ?? {};
11064
+ }
11065
+ /**
11066
+ * Get all registered custom component names
11067
+ * @returns Set of custom component names
11068
+ */
11069
+ getCustomComponentNames() {
11070
+ return new Set(this.customThemes.keys());
11071
+ }
11072
+ /**
11073
+ * Set color tokens for the global theme
11074
+ * @param colors - ColorTokens to use globally
11075
+ */
11076
+ setColorTokens(colors) {
11077
+ this.colorTokens = colors;
11078
+ }
11079
+ /**
11080
+ * Get current color tokens
11081
+ * @returns Current ColorTokens or undefined
11082
+ */
11083
+ getColorTokens() {
11084
+ return this.colorTokens;
11085
+ }
11086
+ /**
11087
+ * Get current color mode
11088
+ * @returns Current color mode
11089
+ */
11090
+ getColorMode() {
11091
+ return this.colorMode;
11092
+ }
11093
+ /**
11094
+ * Set color mode and trigger complete remount
11095
+ * Updates color tokens if a preset is active
11096
+ * Triggers complete remount of all active mountJSX instances
11097
+ * @param mode - Color mode to set
11098
+ */
11099
+ setColorMode(mode) {
11100
+ if (this.colorMode !== mode) {
11101
+ this.colorMode = mode;
11102
+ if (this.currentPresetName) {
11103
+ const preset2 = getPresetWithMode(
11104
+ this.currentPresetName,
11105
+ mode
11106
+ );
11107
+ this.colorTokens = preset2.colors;
11108
+ }
11109
+ setTimeout(() => {
11110
+ remountAll();
11111
+ }, 0);
11112
+ }
11113
+ }
11114
+ /**
11115
+ * Get current preset name
11116
+ * @returns Current preset name or undefined
11117
+ */
11118
+ getCurrentPresetName() {
11119
+ return this.currentPresetName;
11120
+ }
11121
+ /**
11122
+ * Set current preset name
11123
+ * @param name - Preset name
11124
+ * @param skipNotify - If true, skip notifying listeners (used during remount)
11125
+ */
11126
+ setCurrentPresetName(name, skipNotify = false) {
11127
+ if (this.currentPresetName !== name) {
11128
+ this.currentPresetName = name;
11129
+ if (!skipNotify) {
11130
+ this.notifyListeners();
11068
11131
  }
11069
11132
  }
11133
+ }
11134
+ /**
11135
+ * Subscribe to theme changes
11136
+ * @param listener - Callback to invoke on theme change
11137
+ * @returns Unsubscribe function
11138
+ */
11139
+ subscribe(listener) {
11140
+ this.listeners.add(listener);
11070
11141
  return () => {
11071
- unsubscribes.forEach((unsubscribe) => unsubscribe());
11142
+ this.listeners.delete(listener);
11072
11143
  };
11073
- }, [throttleMs, ...signals]);
11074
- }
11075
- function useMemo(fn, deps) {
11076
- const c = getCurrent();
11077
- const i = c.index++;
11078
- const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, value: void 0 });
11079
- if (!depsChanged(slot.deps, deps)) return slot.value;
11080
- slot.value = fn();
11081
- slot.deps = deps;
11082
- return slot.value;
11083
- }
11084
- function useCallback(fn, deps) {
11085
- return useMemo(() => fn, deps);
11086
- }
11087
- function useTheme() {
11088
- return getCurrent()?.theme;
11089
- }
11090
- function useScene() {
11091
- const ctx = getCurrent();
11092
- if (!ctx) throw new Error("useScene must be called within a component");
11093
- const renderContext = getContextFromParent(ctx.parent);
11094
- return renderContext.scene;
11095
- }
11096
- function useViewportSize() {
11097
- const ctx = getCurrent();
11098
- if (!ctx) {
11099
- throw new Error("useViewportSize must be called within a component");
11100
11144
  }
11101
- const renderContext = getContextFromParent(ctx.parent);
11102
- return renderContext.getViewport();
11103
- }
11104
- function getLayoutSize(container) {
11105
- if (!container) return void 0;
11106
- const withLayout = container;
11107
- return withLayout.__getLayoutSize?.();
11108
- }
11109
- function useLayoutSize(ref) {
11110
- return getLayoutSize(ref.current);
11111
- }
11112
- function getLayoutProps(container) {
11113
- if (!container) return void 0;
11114
- const withLayout = container;
11115
- return withLayout.__layoutProps;
11116
- }
11117
- function getBackgroundGraphics(container) {
11118
- if (!container) return void 0;
11119
- const withBackground = container;
11120
- return withBackground.__background;
11121
- }
11122
- function useBackgroundGraphics(ref) {
11123
- return getBackgroundGraphics(ref.current);
11124
- }
11125
- function getLayoutRect(container) {
11126
- if (!container) return void 0;
11127
- const size = getLayoutSize(container);
11128
- if (!size) return void 0;
11129
- return {
11130
- x: container.x,
11131
- y: container.y,
11132
- width: size.width,
11133
- height: size.height
11134
- };
11135
- }
11136
- function useLayoutRect(ref) {
11137
- return getLayoutRect(ref.current);
11138
- }
11139
- function getWorldLayoutRect(container) {
11140
- if (!container) return void 0;
11141
- const size = getLayoutSize(container);
11142
- if (!size) return void 0;
11143
- const matrix = container.getWorldTransformMatrix();
11144
- const worldX = matrix.tx;
11145
- const worldY = matrix.ty;
11146
- const worldWidth = size.width * Math.abs(matrix.scaleX);
11147
- const worldHeight = size.height * Math.abs(matrix.scaleY);
11148
- return {
11149
- x: worldX,
11150
- y: worldY,
11151
- width: worldWidth,
11152
- height: worldHeight
11153
- };
11154
- }
11155
- function useWorldLayoutRect(ref) {
11156
- return getWorldLayoutRect(ref.current);
11157
- }
11158
- function useEffect(fn, deps) {
11159
- const c = getCurrent();
11160
- const i = c.index++;
11161
- const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, cleanup: void 0 });
11162
- c.effects.push(() => {
11163
- if (!depsChanged(slot.deps, deps)) return;
11164
- if (typeof slot.cleanup === "function") slot.cleanup();
11165
- slot.cleanup = fn();
11166
- if (deps !== void 0) {
11167
- slot.deps = deps;
11168
- }
11169
- });
11145
+ /**
11146
+ * Notify all listeners of theme change
11147
+ */
11148
+ notifyListeners() {
11149
+ this.listeners.forEach((listener) => listener());
11150
+ }
11170
11151
  }
11171
- function useLayoutEffect(fn, deps) {
11172
- const c = getCurrent();
11173
- const i = c.index++;
11174
- const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, cleanup: void 0 });
11175
- c.effects.push(() => {
11176
- if (!depsChanged(slot.deps, deps)) return;
11177
- if (typeof slot.cleanup === "function") slot.cleanup();
11178
- requestAnimationFrame(() => {
11179
- slot.cleanup = fn();
11180
- });
11181
- if (deps !== void 0) {
11182
- slot.deps = deps;
11152
+ const themeRegistry = new ThemeRegistry();
11153
+ function mergeThemes(base, override) {
11154
+ const result = { ...base };
11155
+ for (const [component, styles] of Object.entries(override)) {
11156
+ if (component in result) {
11157
+ result[component] = {
11158
+ ...result[component],
11159
+ ...styles
11160
+ };
11161
+ } else {
11162
+ result[component] = styles;
11183
11163
  }
11184
- });
11164
+ }
11165
+ return result;
11185
11166
  }
11186
- function depsChanged(a, b) {
11187
- if (!a || !b) return true;
11188
- if (a.length !== b.length) return true;
11189
- for (let i = 0; i < a.length; i++) {
11190
- if (!Object.is(a[i], b[i])) return true;
11167
+ function createTheme(theme, colorPreset) {
11168
+ if (colorPreset) {
11169
+ themeRegistry.setColorTokens(colorPreset.colors);
11170
+ return {
11171
+ ...theme,
11172
+ __colorPreset: {
11173
+ name: colorPreset.name,
11174
+ mode: colorPreset.mode ?? "light"
11175
+ }
11176
+ };
11191
11177
  }
11192
- return false;
11178
+ return theme;
11193
11179
  }
11194
- function shallowEqual(a, b) {
11195
- if (Object.is(a, b)) return true;
11196
- if (a == null || b == null) return false;
11197
- if (typeof a !== "object" || typeof b !== "object") return false;
11198
- const keysA = Object.keys(a);
11199
- const keysB = Object.keys(b);
11200
- if (keysA.length !== keysB.length) return false;
11201
- for (const key of keysA) {
11202
- if (!Object.prototype.hasOwnProperty.call(b, key) || !Object.is(a[key], b[key])) {
11203
- return false;
11180
+ function deepMergeDefined(base, override) {
11181
+ const result = { ...base };
11182
+ for (const key in override) {
11183
+ const value = override[key];
11184
+ if (value !== void 0) {
11185
+ if (typeof value === "object" && value !== null && !Array.isArray(value) && typeof base[key] === "object" && base[key] !== null) {
11186
+ result[key] = deepMergeDefined(
11187
+ base[key],
11188
+ value
11189
+ );
11190
+ } else {
11191
+ result[key] = value;
11192
+ }
11204
11193
  }
11205
11194
  }
11206
- return true;
11195
+ return result;
11207
11196
  }
11208
- function shouldComponentUpdate(ctx, newProps) {
11209
- if (ctx.memoized === false) return true;
11210
- if (ctx.componentVNode.__memo === false) return true;
11211
- if (ctx.lastProps === void 0) {
11212
- ctx.lastProps = newProps;
11213
- return true;
11197
+ function extractNestedThemes(theme) {
11198
+ const ownProps = { ...theme };
11199
+ const nestedThemes = {};
11200
+ const allComponentNames = /* @__PURE__ */ new Set([
11201
+ "View",
11202
+ "Text",
11203
+ "NineSlice",
11204
+ ...Array.from(themeRegistry.getCustomComponentNames())
11205
+ ]);
11206
+ for (const key in ownProps) {
11207
+ if (allComponentNames.has(key)) {
11208
+ nestedThemes[key] = ownProps[key];
11209
+ delete ownProps[key];
11210
+ }
11214
11211
  }
11215
- const hasChanged = !shallowEqual(ctx.lastProps, newProps);
11216
- ctx.lastProps = newProps;
11217
- return hasChanged;
11212
+ return { ownProps, nestedThemes };
11218
11213
  }
11219
- function useRedraw() {
11220
- const c = getCurrent();
11221
- return () => {
11222
- if (c != null) scheduleUpdate(c);
11214
+ function getThemedProps(componentName, localTheme, explicitProps) {
11215
+ const globalComponentTheme = themeRegistry.getComponentTheme(componentName);
11216
+ const { ownProps: globalOwnProps, nestedThemes: globalNestedThemes } = extractNestedThemes(globalComponentTheme);
11217
+ const localComponentTheme = localTheme?.[componentName] ?? {};
11218
+ const { ownProps: localOwnProps, nestedThemes: localNestedThemes } = extractNestedThemes(localComponentTheme);
11219
+ const { nestedThemes: localThemeNested } = extractNestedThemes(localTheme ?? {});
11220
+ const { ownProps: explicitOwnProps, nestedThemes: explicitNestedThemes } = extractNestedThemes(explicitProps);
11221
+ const mergedProps = {
11222
+ ...deepMergeDefined(globalOwnProps, localOwnProps),
11223
+ ...deepMergeDefined({}, explicitOwnProps)
11223
11224
  };
11224
- }
11225
- function scheduleUpdate(c) {
11226
- if (c.updater) return;
11227
- c.updater = () => {
11228
- c.updater = void 0;
11229
- if (c.disposed) {
11230
- return;
11231
- }
11232
- const scene = c.parent instanceof Phaser.Scene ? c.parent : c.parent.scene;
11233
- if (!scene || !scene.sys || !scene.sys.settings.active) {
11234
- return;
11235
- }
11236
- const componentProps = c.componentVNode.props ?? {};
11237
- const propsWithChildren = c.componentVNode.children?.length ? { ...componentProps, children: c.componentVNode.children } : componentProps;
11238
- const nextVNode = normalizeVNodeLike(withHooks(c, () => c.function(propsWithChildren)));
11239
- patchVNode(c.parent, c.vnode, nextVNode);
11240
- c.vnode = nextVNode;
11241
- for (const run of c.effects) run();
11225
+ const mergedNestedThemes = mergeThemes(
11226
+ mergeThemes(mergeThemes(globalNestedThemes, localNestedThemes), localThemeNested),
11227
+ explicitNestedThemes
11228
+ );
11229
+ DebugLogger.log(
11230
+ "theme",
11231
+ `getThemedProps(${String(componentName)}): FINAL mergedProps:`,
11232
+ mergedProps
11233
+ );
11234
+ return {
11235
+ props: mergedProps,
11236
+ nestedTheme: mergedNestedThemes
11242
11237
  };
11243
- queueMicrotask(c.updater);
11244
- }
11245
- function disposeCtx(c) {
11246
- c.disposed = true;
11247
- for (const cl of c.cleanups) {
11248
- if (typeof cl === "function") cl();
11249
- }
11250
- for (const slot of c.slots) {
11251
- if (slot && typeof slot === "object" && "cleanup" in slot && typeof slot.cleanup === "function") {
11252
- slot.cleanup();
11253
- }
11254
- }
11255
- c.cleanups.length = 0;
11256
11238
  }
11257
11239
  const positionStates = /* @__PURE__ */ new WeakMap();
11258
11240
  function getPositionState(obj) {
@@ -11343,8 +11325,8 @@ const createShakeEffect = (obj, config) => {
11343
11325
  const progress = tween.progress;
11344
11326
  const decayFactor = Math.pow(1 - progress, 2);
11345
11327
  const mag = magnitude * decayFactor;
11346
- const newX = baseX + Phaser.Math.Between(-mag, mag) - state.scaleOffsetX;
11347
- const newY = baseY + Phaser.Math.Between(-mag, mag) - state.scaleOffsetY;
11328
+ const newX = baseX + Phaser__namespace.Math.Between(-mag, mag) - state.scaleOffsetX;
11329
+ const newY = baseY + Phaser__namespace.Math.Between(-mag, mag) - state.scaleOffsetY;
11348
11330
  obj.setPosition(newX, newY);
11349
11331
  },
11350
11332
  onComplete: () => {
@@ -12298,7 +12280,7 @@ function releaseAllSVGTextures() {
12298
12280
  function useSVGTexture(key, svg, width = 32, height = 32) {
12299
12281
  const [ready, setReady] = useState(false);
12300
12282
  const ctx = getCurrent() || {};
12301
- const scene = ctx.parent instanceof Phaser__namespace.Scene ? ctx.parent : ctx.parent?.scene;
12283
+ const scene = isPhaserScene(ctx.parent) ? ctx.parent : ctx.parent?.scene;
12302
12284
  useEffect(() => {
12303
12285
  if (!scene) return;
12304
12286
  let cancelled = false;
@@ -12319,7 +12301,7 @@ function useSVGTexture(key, svg, width = 32, height = 32) {
12319
12301
  function useSVGTextures(configs) {
12320
12302
  const [ready, setReady] = useState(false);
12321
12303
  const ctx = getCurrent() || {};
12322
- const scene = ctx.parent instanceof Phaser__namespace.Scene ? ctx.parent : ctx.parent?.scene;
12304
+ const scene = isPhaserScene(ctx.parent) ? ctx.parent : ctx.parent?.scene;
12323
12305
  const configKey = useMemo(
12324
12306
  () => configs.map((c) => `${c.key}:${c.width ?? 32}:${c.height ?? 32}`).join("|"),
12325
12307
  [configs]
@@ -12815,7 +12797,7 @@ function useSpring(initialValue, config, onComplete) {
12815
12797
  valueSignal.current = animatedSignal(initialValue);
12816
12798
  }
12817
12799
  const ctx = getCurrent();
12818
- const scene = ctx ? ctx.parent instanceof Phaser__namespace.Scene ? ctx.parent : ctx.parent.scene : null;
12800
+ const scene = ctx ? isPhaserScene(ctx.parent) ? ctx.parent : ctx.parent.scene : null;
12819
12801
  const state = useRef({ value: initialValue, velocity: 0 });
12820
12802
  const target = useRef({ value: initialValue });
12821
12803
  const physics = useRef(new SpringPhysics(resolvedConfig));
@@ -12888,7 +12870,7 @@ function useSprings(initialValues, config) {
12888
12870
  }
12889
12871
  });
12890
12872
  const ctx = getCurrent();
12891
- const scene = ctx ? ctx.parent instanceof Phaser__namespace.Scene ? ctx.parent : ctx.parent.scene : null;
12873
+ const scene = ctx ? isPhaserScene(ctx.parent) ? ctx.parent : ctx.parent.scene : null;
12892
12874
  if (scene && sceneRef.current !== scene) {
12893
12875
  sceneRef.current = scene;
12894
12876
  }
@@ -13092,7 +13074,7 @@ function Portal(props) {
13092
13074
  x = firstChild.x;
13093
13075
  y = firstChild.y;
13094
13076
  blocker.setPosition(x, y);
13095
- const hitArea = new Phaser.Geom.Rectangle(0, 0, width, height);
13077
+ const hitArea = new Phaser__namespace.Geom.Rectangle(0, 0, width, height);
13096
13078
  gestureManager.registerContainer(
13097
13079
  blocker,
13098
13080
  {
@@ -17117,7 +17099,6 @@ exports.useState = useState;
17117
17099
  exports.useTheme = useTheme;
17118
17100
  exports.useViewportSize = useViewportSize;
17119
17101
  exports.useWorldLayoutRect = useWorldLayoutRect;
17120
- exports.vdom = vdom;
17121
17102
  exports.viewportRegistry = viewportRegistry;
17122
17103
  exports.withHooks = withHooks;
17123
- //# sourceMappingURL=TransformOriginView-CrzevUOh.cjs.map
17104
+ //# sourceMappingURL=TransformOriginView-DyhDBexY.cjs.map