@number10/phaserjsx 4.1.0 → 4.3.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 (67) hide show
  1. package/README.md +14 -1
  2. package/dist/clip/index.cjs +7 -695
  3. package/dist/clip/index.js +1 -687
  4. package/dist/clip/stencil-clip-depth.d.ts +10 -0
  5. package/dist/clip/stencil-clip-depth.d.ts.map +1 -0
  6. package/dist/clip/stencil-clip-fbo-bridge.d.ts +7 -0
  7. package/dist/clip/stencil-clip-fbo-bridge.d.ts.map +1 -0
  8. package/dist/clip/stencil-clip-renderer.d.ts +7 -0
  9. package/dist/clip/stencil-clip-renderer.d.ts.map +1 -0
  10. package/dist/clip/stencil-clip-state.d.ts +28 -0
  11. package/dist/clip/stencil-clip-state.d.ts.map +1 -0
  12. package/dist/clip/stencil-clip-types.d.ts +67 -0
  13. package/dist/clip/stencil-clip-types.d.ts.map +1 -0
  14. package/dist/clip/stencil-clip.d.ts +3 -84
  15. package/dist/clip/stencil-clip.d.ts.map +1 -1
  16. package/dist/clip-CHmjztBQ.cjs +705 -0
  17. package/dist/clip-CHmjztBQ.cjs.map +1 -0
  18. package/dist/clip-CPufWCSD.js +668 -0
  19. package/dist/clip-CPufWCSD.js.map +1 -0
  20. package/dist/components/appliers/applyParticles.d.ts.map +1 -1
  21. package/dist/components/custom/Badge.d.ts +73 -0
  22. package/dist/components/custom/Badge.d.ts.map +1 -0
  23. package/dist/components/custom/Checkbox.d.ts +41 -0
  24. package/dist/components/custom/Checkbox.d.ts.map +1 -0
  25. package/dist/components/custom/DebugPanel.d.ts +30 -0
  26. package/dist/components/custom/DebugPanel.d.ts.map +1 -0
  27. package/dist/components/custom/Particles.d.ts +14 -3
  28. package/dist/components/custom/Particles.d.ts.map +1 -1
  29. package/dist/components/custom/Popover.d.ts +89 -0
  30. package/dist/components/custom/Popover.d.ts.map +1 -0
  31. package/dist/components/custom/ProgressBar.d.ts +52 -0
  32. package/dist/components/custom/ProgressBar.d.ts.map +1 -0
  33. package/dist/components/custom/Toggle.d.ts.map +1 -1
  34. package/dist/components/custom/index.cjs +15 -1
  35. package/dist/components/custom/index.d.ts +5 -0
  36. package/dist/components/custom/index.d.ts.map +1 -1
  37. package/dist/components/custom/index.js +2 -2
  38. package/dist/components/index.d.ts +5 -1
  39. package/dist/components/index.d.ts.map +1 -1
  40. package/dist/components/primitives/graphics.d.ts +2 -2
  41. package/dist/components/primitives/particles.d.ts +14 -4
  42. package/dist/components/primitives/particles.d.ts.map +1 -1
  43. package/dist/components/primitives/tilesprite.d.ts +15 -19
  44. package/dist/components/primitives/tilesprite.d.ts.map +1 -1
  45. package/dist/{custom-Dp3yAJdU.cjs → custom-37gL0VZG.cjs} +1578 -264
  46. package/dist/custom-37gL0VZG.cjs.map +1 -0
  47. package/dist/{custom-C_w8D39m.js → custom-DMZASXll.js} +1455 -231
  48. package/dist/custom-DMZASXll.js.map +1 -0
  49. package/dist/gestures/gesture-manager.d.ts +1 -1
  50. package/dist/index.cjs +49 -111
  51. package/dist/index.cjs.map +1 -1
  52. package/dist/index.js +29 -105
  53. package/dist/index.js.map +1 -1
  54. package/dist/particles/emit-zone.d.ts +34 -12
  55. package/dist/particles/emit-zone.d.ts.map +1 -1
  56. package/dist/particles/index.d.ts +1 -1
  57. package/dist/particles/index.d.ts.map +1 -1
  58. package/dist/particles/use-particles.d.ts +6 -2
  59. package/dist/particles/use-particles.d.ts.map +1 -1
  60. package/dist/theme-custom.d.ts +68 -0
  61. package/dist/theme-custom.d.ts.map +1 -1
  62. package/dist/theme-defaults.d.ts.map +1 -1
  63. package/package.json +3 -2
  64. package/dist/clip/index.cjs.map +0 -1
  65. package/dist/clip/index.js.map +0 -1
  66. package/dist/custom-C_w8D39m.js.map +0 -1
  67. package/dist/custom-Dp3yAJdU.cjs.map +0 -1
@@ -549,9 +549,6 @@ var nineSlicePatcher = (node, prev, next) => {
549
549
  };
550
550
  //#endregion
551
551
  //#region src/particles/emit-zone.ts
552
- /**
553
- * Emit zone helpers for particle emitters
554
- */
555
552
  function resolveNumericSize(value) {
556
553
  return typeof value === "number" ? value : void 0;
557
554
  }
@@ -563,18 +560,164 @@ function resolveZoneSize(zone, fallback) {
563
560
  if (height !== void 0) size.height = height;
564
561
  return size;
565
562
  }
563
+ function withPoint(point, x, y) {
564
+ if (point) {
565
+ point.x = x;
566
+ point.y = y;
567
+ return point;
568
+ }
569
+ return {
570
+ x,
571
+ y
572
+ };
573
+ }
574
+ function createRectSource(x, y, width, height) {
575
+ return {
576
+ x,
577
+ y,
578
+ width,
579
+ height,
580
+ contains: (px, py) => px >= x && px <= x + width && py >= y && py <= y + height,
581
+ getRandomPoint: (point) => withPoint(point, x + Math.random() * width, y + Math.random() * height),
582
+ getPoints: (quantity = 1) => {
583
+ const count = Math.max(1, quantity);
584
+ return Array.from({ length: count }, (_, index) => {
585
+ const distance = (count === 1 ? 0 : index / (count - 1)) * (2 * (width + height));
586
+ if (distance <= width) return {
587
+ x: x + distance,
588
+ y
589
+ };
590
+ if (distance <= width + height) return {
591
+ x: x + width,
592
+ y: y + distance - width
593
+ };
594
+ if (distance <= width * 2 + height) return {
595
+ x: x + width - (distance - width - height),
596
+ y: y + height
597
+ };
598
+ return {
599
+ x,
600
+ y: y + height - (distance - width * 2 - height)
601
+ };
602
+ });
603
+ }
604
+ };
605
+ }
606
+ function createCircleSource(x, y, radius) {
607
+ return {
608
+ x,
609
+ y,
610
+ radius,
611
+ contains: (px, py) => {
612
+ const dx = px - x;
613
+ const dy = py - y;
614
+ return dx * dx + dy * dy <= radius * radius;
615
+ },
616
+ getRandomPoint: (point) => {
617
+ const angle = Math.random() * Math.PI * 2;
618
+ const distance = Math.sqrt(Math.random()) * radius;
619
+ return withPoint(point, x + Math.cos(angle) * distance, y + Math.sin(angle) * distance);
620
+ },
621
+ getPoints: (quantity = 1) => {
622
+ const count = Math.max(1, quantity);
623
+ return Array.from({ length: count }, (_, index) => {
624
+ const angle = index / count * Math.PI * 2;
625
+ return {
626
+ x: x + Math.cos(angle) * radius,
627
+ y: y + Math.sin(angle) * radius
628
+ };
629
+ });
630
+ }
631
+ };
632
+ }
633
+ function createEllipseSource(x, y, width, height) {
634
+ const radiusX = width / 2;
635
+ const radiusY = height / 2;
636
+ return {
637
+ x,
638
+ y,
639
+ width,
640
+ height,
641
+ contains: (px, py) => {
642
+ const dx = (px - x) / radiusX;
643
+ const dy = (py - y) / radiusY;
644
+ return dx * dx + dy * dy <= 1;
645
+ },
646
+ getRandomPoint: (point) => {
647
+ const angle = Math.random() * Math.PI * 2;
648
+ const distance = Math.sqrt(Math.random());
649
+ return withPoint(point, x + Math.cos(angle) * radiusX * distance, y + Math.sin(angle) * radiusY * distance);
650
+ },
651
+ getPoints: (quantity = 1) => {
652
+ const count = Math.max(1, quantity);
653
+ return Array.from({ length: count }, (_, index) => {
654
+ const angle = index / count * Math.PI * 2;
655
+ return {
656
+ x: x + Math.cos(angle) * radiusX,
657
+ y: y + Math.sin(angle) * radiusY
658
+ };
659
+ });
660
+ }
661
+ };
662
+ }
663
+ function createLineSource(x, y, endX, endY) {
664
+ return {
665
+ x,
666
+ y,
667
+ contains: (px, py) => {
668
+ const lengthSquared = (endX - x) ** 2 + (endY - y) ** 2;
669
+ if (lengthSquared === 0) return px === x && py === y;
670
+ const progress = Math.max(0, Math.min(1, ((px - x) * (endX - x) + (py - y) * (endY - y)) / lengthSquared));
671
+ const closestX = x + progress * (endX - x);
672
+ const closestY = y + progress * (endY - y);
673
+ return Math.hypot(px - closestX, py - closestY) <= .5;
674
+ },
675
+ getRandomPoint: (point) => {
676
+ const progress = Math.random();
677
+ return withPoint(point, x + (endX - x) * progress, y + (endY - y) * progress);
678
+ },
679
+ getPoints: (quantity = 1) => {
680
+ const count = Math.max(1, quantity);
681
+ return Array.from({ length: count }, (_, index) => {
682
+ const progress = count === 1 ? 0 : index / (count - 1);
683
+ return {
684
+ x: x + (endX - x) * progress,
685
+ y: y + (endY - y) * progress
686
+ };
687
+ });
688
+ }
689
+ };
690
+ }
566
691
  function buildZoneSource(zone, fallbackSize) {
567
692
  const baseX = zone.x ?? 0;
568
693
  const baseY = zone.y ?? 0;
569
694
  const { width, height } = resolveZoneSize(zone, fallbackSize);
570
695
  switch (zone.shape) {
571
- case "rect": return new phaser.Geom.Rectangle(baseX, baseY, width ?? 1, height ?? 1);
572
- case "circle": return new phaser.Geom.Circle(baseX, baseY, zone.radius ?? 1);
573
- case "ellipse": return new phaser.Geom.Ellipse(baseX, baseY, width ?? 1, height ?? 1);
574
- case "line": return new phaser.Geom.Line(baseX, baseY, zone.endX ?? baseX + (width ?? 1), zone.endY ?? baseY + (height ?? 1));
696
+ case "rect": return createRectSource(baseX, baseY, width ?? 1, height ?? 1);
697
+ case "circle": return createCircleSource(baseX, baseY, zone.radius ?? 1);
698
+ case "ellipse": return createEllipseSource(baseX, baseY, width ?? 1, height ?? 1);
699
+ case "line": return createLineSource(baseX, baseY, zone.endX ?? baseX + (width ?? 1), zone.endY ?? baseY + (height ?? 1));
575
700
  default: return;
576
701
  }
577
702
  }
703
+ function getTransformOwner(value) {
704
+ if (!value || typeof value !== "object") return void 0;
705
+ if (typeof value.getWorldTransformMatrix !== "function") return;
706
+ return value;
707
+ }
708
+ function createLocalDeathZoneSource(source, owner) {
709
+ const transformOwner = getTransformOwner(owner);
710
+ if (!transformOwner) return source;
711
+ return {
712
+ ...source,
713
+ contains: (worldX, worldY) => {
714
+ const matrix = transformOwner.getWorldTransformMatrix?.();
715
+ if (!matrix) return source.contains(worldX, worldY);
716
+ const localPoint = matrix.applyInverse(worldX, worldY);
717
+ return source.contains(localPoint.x, localPoint.y);
718
+ }
719
+ };
720
+ }
578
721
  /**
579
722
  * Build a Phaser emitZone config from a lightweight zone definition
580
723
  */
@@ -599,21 +742,21 @@ function buildEmitZoneFromLayout(zone, width, height) {
599
742
  return buildEmitZone(zone, fallback);
600
743
  }
601
744
  /**
602
- * Build a Phaser deathZone config from a lightweight exclusion definition
745
+ * Build a Phaser deathZone config from a lightweight death zone definition
603
746
  */
604
- function buildDeathZone(zone, fallbackSize = {}) {
747
+ function buildDeathZone(zone, fallbackSize = {}, owner) {
605
748
  const type = zone.mode ?? "onEnter";
606
749
  const source = buildZoneSource(zone, fallbackSize);
607
750
  if (!source) return void 0;
608
751
  return {
609
752
  type,
610
- source
753
+ source: createLocalDeathZoneSource(source, owner)
611
754
  };
612
755
  }
613
756
  /**
614
757
  * Create death zones using layout size as a fallback
615
758
  */
616
- function buildDeathZonesFromLayout(zones, width, height) {
759
+ function buildDeathZonesFromLayout(zones, width, height, owner) {
617
760
  if (!zones) return void 0;
618
761
  const list = Array.isArray(zones) ? zones : [zones];
619
762
  const fallback = {};
@@ -621,7 +764,7 @@ function buildDeathZonesFromLayout(zones, width, height) {
621
764
  const resolvedHeight = resolveNumericSize(height);
622
765
  if (resolvedWidth !== void 0) fallback.width = resolvedWidth;
623
766
  if (resolvedHeight !== void 0) fallback.height = resolvedHeight;
624
- const deathZones = list.map((zone) => buildDeathZone(zone, fallback)).filter((zone) => Boolean(zone));
767
+ const deathZones = list.map((zone) => buildDeathZone(zone, fallback, owner)).filter((zone) => Boolean(zone));
625
768
  return deathZones.length > 0 ? deathZones : void 0;
626
769
  }
627
770
  //#endregion
@@ -812,7 +955,7 @@ function mergeDeathZones(base, extra) {
812
955
  function applyParticlesProps(manager, prev, next) {
813
956
  if (!manager) return;
814
957
  if ((prev.texture !== next.texture || prev.frame !== next.frame) && next.texture && "setTexture" in manager && manager.setTexture) manager.setTexture(next.texture, next.frame);
815
- if (prev.preset !== next.preset || prev.config !== next.config || prev.zone !== next.zone || prev.excludeZones !== next.excludeZones || prev.width !== next.width || prev.height !== next.height) {
958
+ if (prev.preset !== next.preset || prev.config !== next.config || prev.emitZone !== next.emitZone || prev.zone !== next.zone || prev.deathZones !== next.deathZones || prev.excludeZones !== next.excludeZones || prev.width !== next.width || prev.height !== next.height) {
816
959
  const resolvedConfig = resolveParticlePreset(next.preset, next.config);
817
960
  let emitter;
818
961
  if (isParticleEmitter(manager)) emitter = manager;
@@ -824,11 +967,13 @@ function applyParticlesProps(manager, prev, next) {
824
967
  }
825
968
  if (!emitter) return;
826
969
  applyEmitterConfig(emitter, resolvedConfig);
827
- if (next.zone) {
828
- const emitZone = buildEmitZoneFromLayout(next.zone, next.width, next.height);
970
+ const emitZoneProps = next.emitZone ?? next.zone;
971
+ const deathZoneProps = next.deathZones ?? next.excludeZones;
972
+ if (emitZoneProps) {
973
+ const emitZone = buildEmitZoneFromLayout(emitZoneProps, next.width, next.height);
829
974
  if (emitZone) applyEmitZone(emitter, emitZone);
830
975
  }
831
- const deathZones = buildDeathZonesFromLayout(next.excludeZones, next.width, next.height);
976
+ const deathZones = buildDeathZonesFromLayout(deathZoneProps, next.width, next.height, manager);
832
977
  const combined = mergeDeathZones(resolvedConfig.deathZone, deathZones);
833
978
  applyDeathZone(emitter, combined);
834
979
  }
@@ -864,8 +1009,10 @@ function createParticlesLayout(particles, props) {
864
1009
  */
865
1010
  var particlesCreator = (scene, props) => {
866
1011
  const resolvedConfig = { ...resolveParticlePreset(props.preset, props.config) };
867
- if (props.zone) {
868
- const emitZone = buildEmitZoneFromLayout(props.zone, props.width, props.height);
1012
+ const emitZoneProps = props.emitZone ?? props.zone;
1013
+ const deathZoneProps = props.deathZones ?? props.excludeZones;
1014
+ if (emitZoneProps) {
1015
+ const emitZone = buildEmitZoneFromLayout(emitZoneProps, props.width, props.height);
869
1016
  if (emitZone) {
870
1017
  const configWithZone = resolvedConfig;
871
1018
  configWithZone.emitZone = emitZone;
@@ -883,8 +1030,8 @@ var particlesCreator = (scene, props) => {
883
1030
  createTransform(particles, props);
884
1031
  createPhaser(particles, props);
885
1032
  createParticlesLayout(particles, props);
886
- if (props.excludeZones && emitter) {
887
- const deathZones = buildDeathZonesFromLayout(props.excludeZones, props.width, props.height);
1033
+ if (deathZoneProps && emitter) {
1034
+ const deathZones = buildDeathZonesFromLayout(deathZoneProps, props.width, props.height, particles);
888
1035
  const combinedDeathZones = mergeDeathZones(resolvedConfig.deathZone, deathZones);
889
1036
  if (combinedDeathZones) applyDeathZone(emitter, combinedDeathZones);
890
1037
  }
@@ -16539,18 +16686,54 @@ var textPatcher = (node, prev, next) => {
16539
16686
  //#endregion
16540
16687
  //#region src/components/primitives/tilesprite.ts
16541
16688
  /**
16542
- * TileSprite creator - NOT IMPLEMENTED YET
16543
- * @throws Error indicating component is not implemented
16689
+ * Creates layout infrastructure for TileSprite.
16544
16690
  */
16545
- var tileSpriteCreator = (_scene, _props) => {
16546
- throw new Error("TileSprite component not implemented yet. This is a placeholder for architecture planning.");
16691
+ function createTileSpriteLayout(tileSprite, props) {
16692
+ tileSprite.__layoutProps = props;
16693
+ tileSprite.__getLayoutSize = () => {
16694
+ if (tileSprite.__layoutProps?.headless) return {
16695
+ width: .01,
16696
+ height: .01
16697
+ };
16698
+ return {
16699
+ width: tileSprite.width,
16700
+ height: tileSprite.height
16701
+ };
16702
+ };
16703
+ }
16704
+ function applyTileSpriteProps(tileSprite, prev, next) {
16705
+ if ((prev.texture !== next.texture || prev.frame !== next.frame) && next.texture) tileSprite.setTexture(next.texture, next.frame);
16706
+ if ((prev.width !== next.width || prev.height !== next.height) && typeof next.width === "number" && typeof next.height === "number") tileSprite.setSize(next.width, next.height);
16707
+ if (prev.tilePositionX !== next.tilePositionX && typeof next.tilePositionX === "number") tileSprite.tilePositionX = next.tilePositionX;
16708
+ if (prev.tilePositionY !== next.tilePositionY && typeof next.tilePositionY === "number") tileSprite.tilePositionY = next.tilePositionY;
16709
+ if (prev.tileScaleX !== next.tileScaleX && typeof next.tileScaleX === "number") tileSprite.tileScaleX = next.tileScaleX;
16710
+ if (prev.tileScaleY !== next.tileScaleY && typeof next.tileScaleY === "number") tileSprite.tileScaleY = next.tileScaleY;
16711
+ if (prev.tint !== next.tint) if (typeof next.tint === "number") tileSprite.setTint(next.tint);
16712
+ else tileSprite.clearTint();
16713
+ if (prev.originX !== next.originX || prev.originY !== next.originY) tileSprite.setOrigin(next.originX ?? tileSprite.originX, next.originY ?? tileSprite.originY);
16714
+ }
16715
+ /**
16716
+ * TileSprite creator - creates a Phaser TileSprite object.
16717
+ */
16718
+ var tileSpriteCreator = (scene, props) => {
16719
+ const tileSprite = scene.add.tileSprite(props.x ?? 0, props.y ?? 0, props.width, props.height, props.texture, props.frame);
16720
+ tileSprite.setOrigin(props.originX ?? 0, props.originY ?? 0);
16721
+ createTransform(tileSprite, props);
16722
+ createPhaser(tileSprite, props);
16723
+ applyTileSpriteProps(tileSprite, {}, props);
16724
+ createTileSpriteLayout(tileSprite, props);
16725
+ props.onReady?.(tileSprite);
16726
+ return tileSprite;
16547
16727
  };
16548
16728
  /**
16549
- * TileSprite patcher - NOT IMPLEMENTED YET
16550
- * @throws Error indicating component is not implemented
16729
+ * TileSprite patcher - updates texture, size, tiling and shared display props.
16551
16730
  */
16552
- var tileSpritePatcher = (_node, _prev, _next) => {
16553
- throw new Error("TileSprite component not implemented yet. This is a placeholder for architecture planning.");
16731
+ var tileSpritePatcher = (node, prev, next) => {
16732
+ applyTransformProps(node, prev, next);
16733
+ applyPhaserProps(node, prev, next);
16734
+ applyTileSpriteProps(node, prev, next);
16735
+ const tileSprite = node;
16736
+ if (tileSprite.__layoutProps) tileSprite.__layoutProps = next;
16554
16737
  };
16555
16738
  //#endregion
16556
16739
  //#region src/components/backgroundImage.ts
@@ -16938,7 +17121,7 @@ var GestureManager = class {
16938
17121
  /**
16939
17122
  * Handle global pointer down event
16940
17123
  * Registers all containers that were hit for move event tracking
16941
- * Only the topmost gets touch/longpress callbacks
17124
+ * Only the topmost gets touch/long-press callbacks
16942
17125
  */
16943
17126
  handlePointerDown(pointer) {
16944
17127
  const hitContainers = /* @__PURE__ */ new Set();
@@ -19806,6 +19989,91 @@ function buildDefaultTheme(colors) {
19806
19989
  fontSize: "14px"
19807
19990
  }
19808
19991
  },
19992
+ Checkbox: {
19993
+ checkedColor: colors.primary.DEFAULT.toNumber(),
19994
+ indeterminateColor: colors.primary.medium.toNumber(),
19995
+ color: colors.border.medium.toNumber(),
19996
+ gap: 10,
19997
+ size: 20,
19998
+ disabledAlpha: .5,
19999
+ labelPosition: "right",
20000
+ labelStyle: {
20001
+ color: colors.text.DEFAULT.toString(),
20002
+ fontSize: "14px"
20003
+ }
20004
+ },
20005
+ Badge: {
20006
+ tone: "neutral",
20007
+ variant: "solid",
20008
+ size: "medium",
20009
+ maxCount: 99,
20010
+ disabledAlpha: .5,
20011
+ textStyle: { fontStyle: "bold" }
20012
+ },
20013
+ Tag: {
20014
+ tone: "neutral",
20015
+ variant: "soft",
20016
+ size: "medium",
20017
+ closeSize: 16,
20018
+ disabledAlpha: .5,
20019
+ textStyle: { fontStyle: "bold" }
20020
+ },
20021
+ Popover: {
20022
+ placement: "bottom",
20023
+ offset: 8,
20024
+ depth: 1100,
20025
+ closeOnOutside: true,
20026
+ closeOnEscape: true,
20027
+ viewportPadding: 8,
20028
+ backgroundColor: colors.surface.dark.toNumber(),
20029
+ borderColor: colors.border.medium.toNumber(),
20030
+ borderWidth: 1,
20031
+ cornerRadius: 8,
20032
+ padding: 10,
20033
+ gap: 8
20034
+ },
20035
+ ContextMenu: {
20036
+ width: 220,
20037
+ itemHeight: 34,
20038
+ itemGap: 8,
20039
+ itemPadding: {
20040
+ left: 10,
20041
+ right: 10,
20042
+ top: 6,
20043
+ bottom: 6
20044
+ },
20045
+ itemCornerRadius: 5,
20046
+ backgroundColor: colors.surface.dark.toNumber(),
20047
+ borderColor: colors.border.medium.toNumber(),
20048
+ borderWidth: 1,
20049
+ cornerRadius: 8,
20050
+ padding: 6,
20051
+ gap: 2,
20052
+ textStyle: {
20053
+ ...textStyles.small,
20054
+ color: colors.text.medium.toString()
20055
+ },
20056
+ disabledTextColor: colors.text.lightest.toString(),
20057
+ dangerTextColor: colors.error.darkest.toString(),
20058
+ dangerBackgroundColor: colors.error.dark.toNumber()
20059
+ },
20060
+ ProgressBar: {
20061
+ width: 240,
20062
+ height: 22,
20063
+ orientation: "horizontal",
20064
+ labelPosition: "right",
20065
+ trackColor: colors.surface.dark.toNumber(),
20066
+ fillColor: colors.success.DEFAULT.toNumber(),
20067
+ borderColor: colors.border.medium.toNumber(),
20068
+ borderWidth: 1,
20069
+ cornerRadius: 11,
20070
+ gap: 8,
20071
+ disabledAlpha: .5,
20072
+ labelStyle: {
20073
+ color: colors.text.DEFAULT.toString(),
20074
+ fontSize: "13px"
20075
+ }
20076
+ },
19809
20077
  ScrollSlider: {
19810
20078
  borderColor: colors.border.dark.toNumber(),
19811
20079
  trackColor: colors.surface.dark.toNumber(),
@@ -20618,7 +20886,7 @@ function useViewportSize() {
20618
20886
  * @param container - Phaser container with layout
20619
20887
  * @returns Layout size or undefined if container has no layout
20620
20888
  */
20621
- function getLayoutSize(container) {
20889
+ function getLayoutSize$1(container) {
20622
20890
  if (!container) return void 0;
20623
20891
  return container.__getLayoutSize?.();
20624
20892
  }
@@ -20630,7 +20898,7 @@ function getLayoutSize(container) {
20630
20898
  * @returns Current layout size or undefined
20631
20899
  */
20632
20900
  function useLayoutSize(ref) {
20633
- return getLayoutSize(ref.current);
20901
+ return getLayoutSize$1(ref.current);
20634
20902
  }
20635
20903
  /**
20636
20904
  * Utility function to get layout props from a container
@@ -20671,7 +20939,7 @@ function useBackgroundGraphics(ref) {
20671
20939
  */
20672
20940
  function getLayoutRect(container) {
20673
20941
  if (!container) return void 0;
20674
- const size = getLayoutSize(container);
20942
+ const size = getLayoutSize$1(container);
20675
20943
  if (!size) return void 0;
20676
20944
  return {
20677
20945
  x: container.x,
@@ -20704,7 +20972,7 @@ function useLayoutRect(ref) {
20704
20972
  */
20705
20973
  function getWorldLayoutRect(container) {
20706
20974
  if (!container) return void 0;
20707
- const size = getLayoutSize(container);
20975
+ const size = getLayoutSize$1(container);
20708
20976
  if (!size) return void 0;
20709
20977
  const matrix = container.getWorldTransformMatrix();
20710
20978
  return {
@@ -22870,6 +23138,241 @@ var viewPatcher = (node, prev, next) => {
22870
23138
  applyLayoutProps(container, normalizedPrev, normalizedNext);
22871
23139
  };
22872
23140
  //#endregion
23141
+ //#region src/components/custom/Badge.tsx
23142
+ /** @jsxImportSource ../.. */
23143
+ /**
23144
+ * Badge and Tag components - compact labels for counts, status, filters, and inventory metadata.
23145
+ */
23146
+ var DEFAULT_TONES = {
23147
+ neutral: {
23148
+ backgroundColor: 4674921,
23149
+ softBackgroundColor: 1976635,
23150
+ borderColor: 6583435,
23151
+ textColor: "#ffffff",
23152
+ outlineTextColor: "#cbd5e1"
23153
+ },
23154
+ primary: {
23155
+ backgroundColor: 2450411,
23156
+ softBackgroundColor: 1981066,
23157
+ borderColor: 6333946,
23158
+ textColor: "#ffffff",
23159
+ outlineTextColor: "#93c5fd"
23160
+ },
23161
+ success: {
23162
+ backgroundColor: 1483594,
23163
+ softBackgroundColor: 1332013,
23164
+ borderColor: 4906624,
23165
+ textColor: "#ffffff",
23166
+ outlineTextColor: "#86efac"
23167
+ },
23168
+ warning: {
23169
+ backgroundColor: 16096779,
23170
+ softBackgroundColor: 7877903,
23171
+ borderColor: 16498468,
23172
+ textColor: "#111827",
23173
+ outlineTextColor: "#fde68a"
23174
+ },
23175
+ danger: {
23176
+ backgroundColor: 14427686,
23177
+ softBackgroundColor: 8330525,
23178
+ borderColor: 16281969,
23179
+ textColor: "#ffffff",
23180
+ outlineTextColor: "#fecaca"
23181
+ },
23182
+ info: {
23183
+ backgroundColor: 561586,
23184
+ softBackgroundColor: 1461859,
23185
+ borderColor: 2282478,
23186
+ textColor: "#ffffff",
23187
+ outlineTextColor: "#a5f3fc"
23188
+ }
23189
+ };
23190
+ var DEFAULT_SIZES = {
23191
+ small: {
23192
+ height: 20,
23193
+ padding: {
23194
+ left: 7,
23195
+ right: 7,
23196
+ top: 2,
23197
+ bottom: 2
23198
+ },
23199
+ fontSize: 11,
23200
+ cornerRadius: 10,
23201
+ gap: 5,
23202
+ dotSize: 8
23203
+ },
23204
+ medium: {
23205
+ height: 24,
23206
+ padding: {
23207
+ left: 9,
23208
+ right: 9,
23209
+ top: 3,
23210
+ bottom: 3
23211
+ },
23212
+ fontSize: 13,
23213
+ cornerRadius: 12,
23214
+ gap: 6,
23215
+ dotSize: 10
23216
+ },
23217
+ large: {
23218
+ height: 30,
23219
+ padding: {
23220
+ left: 12,
23221
+ right: 12,
23222
+ top: 4,
23223
+ bottom: 4
23224
+ },
23225
+ fontSize: 18,
23226
+ cornerRadius: 15,
23227
+ gap: 8,
23228
+ dotSize: 12
23229
+ }
23230
+ };
23231
+ function formatBadgeCount({ count, maxCount = 99 }) {
23232
+ if (!Number.isFinite(count)) return "0";
23233
+ const normalizedCount = Math.max(0, Math.floor(count ?? 0));
23234
+ const normalizedMax = Math.max(0, Math.floor(maxCount));
23235
+ return normalizedCount > normalizedMax ? `${normalizedMax}+` : `${normalizedCount}`;
23236
+ }
23237
+ function getBadgeText(props) {
23238
+ if (props.count !== void 0) return formatBadgeCount(props);
23239
+ if (props.label !== void 0) return `${props.label}`;
23240
+ return "";
23241
+ }
23242
+ function resolveBadgeColors(tone, variant) {
23243
+ const toneColors = DEFAULT_TONES[tone];
23244
+ if (variant === "outline") return {
23245
+ backgroundColor: 0,
23246
+ backgroundAlpha: 0,
23247
+ borderColor: toneColors.borderColor,
23248
+ borderWidth: 1,
23249
+ textColor: toneColors.outlineTextColor
23250
+ };
23251
+ if (variant === "soft") return {
23252
+ backgroundColor: toneColors.softBackgroundColor,
23253
+ backgroundAlpha: 1,
23254
+ borderColor: toneColors.borderColor,
23255
+ borderWidth: 1,
23256
+ textColor: toneColors.outlineTextColor
23257
+ };
23258
+ return {
23259
+ backgroundColor: toneColors.backgroundColor,
23260
+ backgroundAlpha: 1,
23261
+ borderColor: toneColors.borderColor,
23262
+ borderWidth: 0,
23263
+ textColor: toneColors.textColor
23264
+ };
23265
+ }
23266
+ function getBadgeSizeConfig(size) {
23267
+ return DEFAULT_SIZES[size];
23268
+ }
23269
+ function resolveBadgeTextStyle(options) {
23270
+ const sizeConfig = getBadgeSizeConfig(options.size);
23271
+ return {
23272
+ color: options.textColor,
23273
+ fontSize: `${sizeConfig.fontSize}px`,
23274
+ ...options.themedTextStyle ?? {},
23275
+ ...options.explicitTextStyle ?? {}
23276
+ };
23277
+ }
23278
+ function Badge(props) {
23279
+ const { children, label, count, maxCount, dot = false, tone: explicitTone, variant: explicitVariant, size: explicitSize, textStyle: explicitTextStyle, disabled = false, disabledAlpha: explicitDisabledAlpha, theme, width, height, padding, gap, cornerRadius, backgroundColor, backgroundAlpha, borderColor, borderWidth, alpha, ...viewProps } = props;
23280
+ const { props: themed, nestedTheme } = getThemedProps("Badge", useTheme(), theme ?? {});
23281
+ const tone = explicitTone ?? themed.tone ?? "neutral";
23282
+ const variant = explicitVariant ?? themed.variant ?? "solid";
23283
+ const size = explicitSize ?? themed.size ?? "medium";
23284
+ const sizeConfig = getBadgeSizeConfig(size);
23285
+ const colors = resolveBadgeColors(tone, variant);
23286
+ const disabledAlpha = explicitDisabledAlpha ?? themed.disabledAlpha ?? .5;
23287
+ const effectiveAlpha = disabled ? disabledAlpha : alpha;
23288
+ const resolvedMaxCount = maxCount ?? themed.maxCount ?? 99;
23289
+ const text = count !== void 0 ? formatBadgeCount({
23290
+ count,
23291
+ maxCount: resolvedMaxCount
23292
+ }) : label !== void 0 ? `${label}` : "";
23293
+ const resolvedTextStyle = resolveBadgeTextStyle({
23294
+ size,
23295
+ textColor: colors.textColor,
23296
+ themedTextStyle: themed.textStyle,
23297
+ explicitTextStyle
23298
+ });
23299
+ const dotSize = themed.dotSize ?? sizeConfig.dotSize;
23300
+ if (dot) return /* @__PURE__ */ require_jsx_runtime.jsx(View, {
23301
+ ...viewProps,
23302
+ width: width ?? dotSize,
23303
+ height: height ?? dotSize,
23304
+ backgroundColor: backgroundColor ?? themed.backgroundColor ?? colors.backgroundColor,
23305
+ backgroundAlpha: backgroundAlpha ?? themed.backgroundAlpha ?? colors.backgroundAlpha,
23306
+ borderColor: borderColor ?? themed.borderColor ?? colors.borderColor,
23307
+ borderWidth: borderWidth ?? themed.borderWidth ?? colors.borderWidth,
23308
+ cornerRadius: cornerRadius ?? themed.cornerRadius ?? dotSize / 2,
23309
+ ...effectiveAlpha !== void 0 ? { alpha: effectiveAlpha } : {},
23310
+ theme: nestedTheme
23311
+ });
23312
+ return /* @__PURE__ */ require_jsx_runtime.jsx(View, {
23313
+ ...viewProps,
23314
+ width: width ?? themed.width ?? "auto",
23315
+ height: height ?? themed.height ?? sizeConfig.height,
23316
+ direction: "row",
23317
+ alignItems: "center",
23318
+ justifyContent: "center",
23319
+ gap: gap ?? themed.gap ?? sizeConfig.gap,
23320
+ padding: padding ?? themed.padding ?? sizeConfig.padding,
23321
+ backgroundColor: backgroundColor ?? themed.backgroundColor ?? colors.backgroundColor,
23322
+ backgroundAlpha: backgroundAlpha ?? themed.backgroundAlpha ?? colors.backgroundAlpha,
23323
+ borderColor: borderColor ?? themed.borderColor ?? colors.borderColor,
23324
+ borderWidth: borderWidth ?? themed.borderWidth ?? colors.borderWidth,
23325
+ cornerRadius: cornerRadius ?? themed.cornerRadius ?? sizeConfig.cornerRadius,
23326
+ ...effectiveAlpha !== void 0 ? { alpha: effectiveAlpha } : {},
23327
+ theme: nestedTheme,
23328
+ children: children ?? /* @__PURE__ */ require_jsx_runtime.jsx(Text, {
23329
+ text,
23330
+ style: resolvedTextStyle
23331
+ })
23332
+ });
23333
+ }
23334
+ function Tag(props) {
23335
+ const { selected = false, onRemove, closeLabel = "x", tone, variant, size, theme, children, label, textStyle, ...badgeProps } = props;
23336
+ const { props: themed, nestedTheme } = getThemedProps("Tag", useTheme(), theme ?? {});
23337
+ const resolvedTone = tone ?? themed.tone ?? (selected ? "primary" : "neutral");
23338
+ const resolvedVariant = variant ?? themed.variant ?? (selected ? "solid" : "soft");
23339
+ const resolvedSize = size ?? themed.size ?? "medium";
23340
+ const resolvedTextStyle = resolveBadgeTextStyle({
23341
+ size: resolvedSize,
23342
+ textColor: resolveBadgeColors(resolvedTone, resolvedVariant).textColor,
23343
+ themedTextStyle: themed.textStyle,
23344
+ explicitTextStyle: textStyle
23345
+ });
23346
+ const text = label !== void 0 ? `${label}` : "";
23347
+ return /* @__PURE__ */ require_jsx_runtime.jsxs(Badge, {
23348
+ ...badgeProps,
23349
+ tone: resolvedTone,
23350
+ variant: resolvedVariant,
23351
+ size: resolvedSize,
23352
+ textStyle: resolvedTextStyle,
23353
+ theme: nestedTheme,
23354
+ children: [
23355
+ label !== void 0 && /* @__PURE__ */ require_jsx_runtime.jsx(Text, {
23356
+ text,
23357
+ style: resolvedTextStyle
23358
+ }),
23359
+ children,
23360
+ onRemove && /* @__PURE__ */ require_jsx_runtime.jsx(Button, {
23361
+ width: themed.closeSize ?? 16,
23362
+ height: themed.closeSize ?? 16,
23363
+ padding: 0,
23364
+ cornerRadius: (themed.closeSize ?? 16) / 2,
23365
+ onClick: onRemove,
23366
+ theme: nestedTheme,
23367
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(Text, {
23368
+ text: closeLabel,
23369
+ style: resolvedTextStyle
23370
+ })
23371
+ })
23372
+ ]
23373
+ });
23374
+ }
23375
+ //#endregion
22873
23376
  //#region src/effects/use-effect.ts
22874
23377
  /**
22875
23378
  * Custom hook for Phaser game object effects (shake, pulse, etc.)
@@ -23852,83 +24355,437 @@ function Button(props) {
23852
24355
  });
23853
24356
  }
23854
24357
  //#endregion
23855
- //#region src/components/custom/Graphics.tsx
23856
- /**
23857
- * Graphics component
23858
- * Renders custom vector shapes via imperative drawing API
23859
- *
23860
- * @example
23861
- * ```tsx
23862
- * <Graphics
23863
- * onDraw={(g) => {
23864
- * g.fillStyle(0xff0000, 1)
23865
- * g.fillCircle(50, 50, 50)
23866
- * }}
23867
- * />
23868
- * ```
23869
- */
23870
- function Graphics(props) {
23871
- const { props: themed, nestedTheme } = getThemedProps("Graphics", useTheme(), props);
23872
- return /* @__PURE__ */ require_jsx_runtime.jsx("graphics", {
23873
- ...themed,
23874
- theme: nestedTheme
23875
- });
24358
+ //#region src/components/custom/Checkbox.tsx
24359
+ function getNextCheckedState(checked, tristate) {
24360
+ if (!tristate) return checked === true ? false : true;
24361
+ if (checked === false) return true;
24362
+ if (checked === true) return "indeterminate";
24363
+ return false;
23876
24364
  }
23877
- //#endregion
23878
- //#region src/components/custom/RadioButton.tsx
23879
- /** @jsxImportSource ../.. */
23880
- /**
23881
- * RadioButton component - Selectable option with circle indicator and label
23882
- */
23883
- /**
23884
- * RadioButton component - displays a selectable circle with label
23885
- * @param props - RadioButton properties
23886
- * @returns RadioButton JSX element
23887
- */
23888
- function RadioButton(props) {
23889
- const { props: themed, nestedTheme } = getThemedProps("RadioButton", void 0, {});
23890
- const size = themed.size ?? 16;
23891
- const innerSize = themed.innerSize ?? size * .75;
23892
- const innerRadius = innerSize * .5;
23893
- const outerRadius = size * .5;
24365
+ function normalizeCheckedState(checked, tristate) {
24366
+ return checked === "indeterminate" && !tristate ? false : checked;
24367
+ }
24368
+ function drawDefaultIndicator(graphics, indicatorProps) {
24369
+ const { checked, disabled, size, color, checkedColor, indeterminateColor } = indicatorProps;
24370
+ const borderWidth = Math.max(2, Math.round(size * .1));
24371
+ const inset = Math.max(4, Math.round(size * .22));
24372
+ const radius = Math.max(2, Math.round(size * .15));
24373
+ const alpha = disabled ? .45 : 1;
24374
+ graphics.clear();
24375
+ graphics.lineStyle(borderWidth, checked === false ? color : checkedColor, alpha);
24376
+ graphics.strokeRoundedRect(borderWidth / 2, borderWidth / 2, size - borderWidth, size - borderWidth, radius);
24377
+ if (checked === true) {
24378
+ graphics.lineStyle(borderWidth + 1, checkedColor, alpha);
24379
+ graphics.beginPath();
24380
+ graphics.moveTo(inset, size * .52);
24381
+ graphics.lineTo(size * .43, size - inset);
24382
+ graphics.lineTo(size - inset, inset);
24383
+ graphics.strokePath();
24384
+ }
24385
+ if (checked === "indeterminate") {
24386
+ graphics.lineStyle(borderWidth + 1, indeterminateColor, alpha);
24387
+ graphics.beginPath();
24388
+ graphics.moveTo(inset, size / 2);
24389
+ graphics.lineTo(size - inset, size / 2);
24390
+ graphics.strokePath();
24391
+ }
24392
+ }
24393
+ function Checkbox(props) {
24394
+ const { props: themed, nestedTheme } = getThemedProps("Checkbox", useTheme(), props.theme ?? {});
24395
+ const size = themed.size ?? 20;
24396
+ const gap = themed.gap ?? 8;
24397
+ const labelPosition = props.labelPosition ?? themed.labelPosition ?? "right";
24398
+ const disabled = props.disabled ?? false;
24399
+ const disabledAlpha = themed.disabledAlpha ?? .5;
24400
+ const tristate = props.tristate ?? false;
24401
+ const [checked, setChecked] = useState(normalizeCheckedState(props.checked ?? props.defaultChecked ?? false, tristate));
24402
+ useEffect(() => {
24403
+ if (props.checked !== void 0) setChecked(normalizeCheckedState(props.checked, tristate));
24404
+ }, [props.checked, tristate]);
24405
+ const indicatorProps = {
24406
+ checked,
24407
+ disabled,
24408
+ size,
24409
+ color: themed.color ?? 7829367,
24410
+ checkedColor: themed.checkedColor ?? 5025616,
24411
+ indeterminateColor: themed.indeterminateColor ?? themed.checkedColor ?? 5025616
24412
+ };
24413
+ const handleToggle = () => {
24414
+ if (disabled) return;
24415
+ const nextChecked = getNextCheckedState(checked, tristate);
24416
+ if (props.checked === void 0) setChecked(nextChecked);
24417
+ props.onChange?.(nextChecked);
24418
+ };
24419
+ const indicator = props.indicator ?? props.renderIndicator?.(indicatorProps) ?? /* @__PURE__ */ require_jsx_runtime.jsx(Graphics, {
24420
+ width: size,
24421
+ height: size,
24422
+ headless: false,
24423
+ dependencies: [
24424
+ indicatorProps.checked,
24425
+ indicatorProps.disabled,
24426
+ indicatorProps.size,
24427
+ indicatorProps.color,
24428
+ indicatorProps.checkedColor,
24429
+ indicatorProps.indeterminateColor
24430
+ ],
24431
+ onDraw: (graphics) => drawDefaultIndicator(graphics, indicatorProps)
24432
+ });
24433
+ const label = props.label && labelPosition !== "none" ? /* @__PURE__ */ require_jsx_runtime.jsx(Text, {
24434
+ text: props.label,
24435
+ style: themed.labelStyle,
24436
+ alpha: disabled ? disabledAlpha : 1
24437
+ }) : null;
23894
24438
  return /* @__PURE__ */ require_jsx_runtime.jsxs(View, {
23895
24439
  direction: "row",
23896
24440
  alignItems: "center",
23897
- enableGestures: true,
23898
- onTouch: () => props.onClick?.(),
24441
+ enableGestures: !disabled,
24442
+ onTouch: handleToggle,
23899
24443
  theme: nestedTheme,
23900
- gap: themed.gap,
23901
- children: [/* @__PURE__ */ require_jsx_runtime.jsx(View, {
23902
- width: size,
23903
- height: size,
23904
- backgroundColor: themed.color,
23905
- alignItems: "center",
23906
- justifyContent: "center",
23907
- backgroundAlpha: 1,
23908
- padding: 0,
23909
- cornerRadius: outerRadius,
23910
- children: /* @__PURE__ */ require_jsx_runtime.jsx(View, {
23911
- width: innerSize,
23912
- height: innerSize,
23913
- backgroundColor: themed.selectedColor,
23914
- visible: props.selected ?? false,
23915
- cornerRadius: innerRadius
23916
- })
23917
- }), /* @__PURE__ */ require_jsx_runtime.jsx(Text, {
23918
- text: props.label,
23919
- style: themed.labelStyle
23920
- })]
24444
+ gap,
24445
+ alpha: disabled ? disabledAlpha : 1,
24446
+ children: [
24447
+ labelPosition === "left" && label,
24448
+ indicator,
24449
+ labelPosition !== "left" && label
24450
+ ]
23921
24451
  }, props.key);
23922
24452
  }
23923
24453
  //#endregion
23924
- //#region src/components/custom/RadioGroup.tsx
23925
- /** @jsxImportSource ../.. */
24454
+ //#region src/design-tokens/use-theme-tokens.ts
23926
24455
  /**
23927
- * RadioGroup component - Manages a group of radio buttons with single-selection logic
24456
+ * Hook to access complete design token system
24457
+ * Combines colors with text styles, spacing, sizes, and radius tokens
23928
24458
  */
23929
24459
  /**
23930
- * RadioGroup component - displays a group of radio buttons with single-selection
23931
- * @param props - RadioGroup properties
24460
+ * Hook to access complete design token system from theme context
24461
+ * Provides colors, text styles, spacing, sizes, and radius tokens
24462
+ * Automatically updates when color mode or preset changes
24463
+ * @returns Current DesignTokens or undefined
24464
+ * @example
24465
+ * ```typescript
24466
+ * function MyComponent() {
24467
+ * const tokens = useThemeTokens()
24468
+ *
24469
+ * if (!tokens) return null
24470
+ *
24471
+ * return (
24472
+ * <View
24473
+ * backgroundColor={tokens.colors.surface.DEFAULT}
24474
+ * padding={tokens.spacing.lg}
24475
+ * cornerRadius={tokens.radius.md}
24476
+ * >
24477
+ * <Text text="Title" style={tokens.textStyles.title} />
24478
+ * <Text text="Body text" style={tokens.textStyles.DEFAULT} />
24479
+ * </View>
24480
+ * )
24481
+ * }
24482
+ * ```
24483
+ */
24484
+ function useThemeTokens() {
24485
+ const localTheme = useTheme();
24486
+ const getInitialTokens = () => {
24487
+ if (localTheme?.__colorPreset) {
24488
+ const preset = getPresetWithMode(localTheme.__colorPreset.name, localTheme.__colorPreset.mode ?? "light");
24489
+ return {
24490
+ colors: preset.colors,
24491
+ textStyles: createTextStyleTokens(preset.colors.text.DEFAULT.toString()),
24492
+ spacing: defaultSpacingTokens,
24493
+ sizes: defaultSizeTokens,
24494
+ radius: defaultRadiusTokens
24495
+ };
24496
+ }
24497
+ const colors = themeRegistry.getColorTokens();
24498
+ if (!colors) return void 0;
24499
+ return {
24500
+ colors,
24501
+ textStyles: createTextStyleTokens(colors.text.DEFAULT.toString()),
24502
+ spacing: defaultSpacingTokens,
24503
+ sizes: defaultSizeTokens,
24504
+ radius: defaultRadiusTokens
24505
+ };
24506
+ };
24507
+ const [tokens, setTokens] = useState(getInitialTokens());
24508
+ const [, forceUpdate] = useState(0);
24509
+ useEffect(() => {
24510
+ return themeRegistry.subscribe(() => {
24511
+ if (localTheme?.__colorPreset) {
24512
+ const currentMode = themeRegistry.getColorMode();
24513
+ const preset = getPresetWithMode(localTheme.__colorPreset.name, currentMode);
24514
+ setTokens({
24515
+ colors: preset.colors,
24516
+ textStyles: createTextStyleTokens(preset.colors.text.DEFAULT.toString()),
24517
+ spacing: defaultSpacingTokens,
24518
+ sizes: defaultSizeTokens,
24519
+ radius: defaultRadiusTokens
24520
+ });
24521
+ } else {
24522
+ const colors = themeRegistry.getColorTokens();
24523
+ if (colors) setTokens({
24524
+ colors,
24525
+ textStyles: createTextStyleTokens(colors.text.DEFAULT.toString()),
24526
+ spacing: defaultSpacingTokens,
24527
+ sizes: defaultSizeTokens,
24528
+ radius: defaultRadiusTokens
24529
+ });
24530
+ }
24531
+ forceUpdate((n) => n + 1);
24532
+ });
24533
+ }, [localTheme]);
24534
+ return tokens;
24535
+ }
24536
+ //#endregion
24537
+ //#region src/components/custom/DebugPanel.tsx
24538
+ /** @jsxImportSource ../.. */
24539
+ /**
24540
+ * DebugPanel component - lightweight runtime diagnostics for Phaser + PhaserJSX
24541
+ * Renders selected metrics as text rows or a compact single-line summary.
24542
+ */
24543
+ var PRESET_METRICS = {
24544
+ fps: ["fps", "frameMs"],
24545
+ perf: [
24546
+ "fps",
24547
+ "frameMs",
24548
+ "renderer",
24549
+ "viewport"
24550
+ ],
24551
+ vdom: [
24552
+ "mountsTotal",
24553
+ "mountsByType",
24554
+ "mountsByParent",
24555
+ "mountsByKey"
24556
+ ],
24557
+ textures: ["textureCount"],
24558
+ full: [
24559
+ "fps",
24560
+ "frameMs",
24561
+ "phaserVersion",
24562
+ "renderer",
24563
+ "viewport",
24564
+ "textureCount",
24565
+ "mountsTotal",
24566
+ "mountsByType",
24567
+ "mountsByParent",
24568
+ "mountsByKey",
24569
+ "debugFlags"
24570
+ ]
24571
+ };
24572
+ var DEFAULT_LABELS = {
24573
+ fps: "FPS",
24574
+ frameMs: "Frame ms",
24575
+ phaserVersion: "Phaser",
24576
+ renderer: "Renderer",
24577
+ viewport: "Viewport",
24578
+ textureCount: "Textures",
24579
+ mountsTotal: "Mounts",
24580
+ mountsByType: "Mounts/type",
24581
+ mountsByParent: "Mounts/parent",
24582
+ mountsByKey: "Mounts/key",
24583
+ debugFlags: "Debug flags"
24584
+ };
24585
+ function resolveRendererName(scene) {
24586
+ const renderer = scene.renderer;
24587
+ const canvasType = phaser.CANVAS;
24588
+ if (renderer.type === phaser.WEBGL) return "WebGL";
24589
+ if (canvasType !== void 0 && renderer.type === canvasType) return "Canvas";
24590
+ if (renderer.constructor?.name) return renderer.constructor.name;
24591
+ if (typeof renderer.type === "number") return `Type ${renderer.type}`;
24592
+ return "Unknown";
24593
+ }
24594
+ function resolveTextureCount(scene) {
24595
+ const manager = scene.textures;
24596
+ const keys = typeof manager.getTextureKeys === "function" ? manager.getTextureKeys() : Object.keys(manager.list ?? {});
24597
+ const internalKeys = new Set([
24598
+ "__DEFAULT",
24599
+ "__MISSING",
24600
+ "__NORMAL",
24601
+ "__WHITE"
24602
+ ]);
24603
+ return keys.filter((key) => !internalKeys.has(key.toUpperCase())).length;
24604
+ }
24605
+ function resolveFrameStats(scene) {
24606
+ const loop = scene.game.loop;
24607
+ const rawFps = loop?.actualFps ?? loop?.fps ?? 0;
24608
+ const rawFrameMs = loop?.delta ?? loop?.frameDelta ?? 0;
24609
+ return {
24610
+ fps: Number.isFinite(rawFps) ? Number(rawFps.toFixed(1)) : 0,
24611
+ frameMs: Number.isFinite(rawFrameMs) ? Number(rawFrameMs.toFixed(2)) : 0
24612
+ };
24613
+ }
24614
+ function summarizeMap(map, maxEntries = 3) {
24615
+ return Array.from(map.entries()).sort((a, b) => b[1] - a[1]).slice(0, maxEntries).map(([key, value]) => `${String(key)}:${value}`).join(" | ") || "-";
24616
+ }
24617
+ function resolveDebugFlags() {
24618
+ const debugConfig = DevConfig.debug;
24619
+ if (!debugConfig.enabled) return "off";
24620
+ const enabledFlags = Object.entries(debugConfig).filter(([key, value]) => key !== "enabled" && value).map(([key]) => key);
24621
+ return enabledFlags.length ? enabledFlags.join(",") : "enabled";
24622
+ }
24623
+ function collectSnapshot(scene) {
24624
+ const { fps, frameMs } = resolveFrameStats(scene);
24625
+ const mountStats = getMountStats();
24626
+ return {
24627
+ fps,
24628
+ frameMs,
24629
+ phaserVersion: phaser.VERSION,
24630
+ renderer: resolveRendererName(scene),
24631
+ viewport: `${scene.scale.width}x${scene.scale.height}`,
24632
+ textureCount: resolveTextureCount(scene),
24633
+ mountsTotal: mountStats.totalMounts,
24634
+ mountsByType: summarizeMap(mountStats.byType),
24635
+ mountsByParent: summarizeMap(mountStats.byParent),
24636
+ mountsByKey: summarizeMap(mountStats.byKey),
24637
+ debugFlags: resolveDebugFlags()
24638
+ };
24639
+ }
24640
+ function formatDefault(value) {
24641
+ return typeof value === "number" ? String(value) : value;
24642
+ }
24643
+ /**
24644
+ * DebugPanel component
24645
+ * Shows selected diagnostics from Phaser + PhaserJSX as overlay-ready content.
24646
+ */
24647
+ function DebugPanel(props) {
24648
+ const scene = useScene();
24649
+ const { preset = "fps", metrics, intervalMs = 250, compact = false, maxRows, labels, formatters, innerProps, ...viewProps } = props;
24650
+ const selectedMetrics = useMemo(() => {
24651
+ const source = metrics && metrics.length > 0 ? metrics : PRESET_METRICS[preset];
24652
+ return Array.from(new Set(source));
24653
+ }, [metrics, preset]);
24654
+ const [snapshot, setSnapshot] = useState(collectSnapshot(scene));
24655
+ useEffect(() => {
24656
+ const delay = Math.max(50, intervalMs);
24657
+ setSnapshot(collectSnapshot(scene));
24658
+ const timer = window.setInterval(() => {
24659
+ setSnapshot(collectSnapshot(scene));
24660
+ }, delay);
24661
+ return () => {
24662
+ window.clearInterval(timer);
24663
+ };
24664
+ }, [
24665
+ scene,
24666
+ intervalMs,
24667
+ selectedMetrics
24668
+ ]);
24669
+ const tokens = useThemeTokens();
24670
+ const rowStyle = tokens?.textStyles.small;
24671
+ const valueStyle = tokens?.textStyles.small;
24672
+ const rows = selectedMetrics.map((metric) => {
24673
+ const rawValue = snapshot[metric];
24674
+ const label = labels?.[metric] ?? DEFAULT_LABELS[metric];
24675
+ const formatter = formatters?.[metric];
24676
+ return {
24677
+ metric,
24678
+ label,
24679
+ value: formatter ? formatter(rawValue) : formatDefault(rawValue)
24680
+ };
24681
+ });
24682
+ const limitedRows = typeof maxRows === "number" ? rows.slice(0, Math.max(1, maxRows)) : rows;
24683
+ if (compact) {
24684
+ const compactText = limitedRows.map((row) => `${row.label} ${row.value}`).join(" | ");
24685
+ return /* @__PURE__ */ require_jsx_runtime.jsx(View, {
24686
+ ...viewProps,
24687
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(Text, {
24688
+ text: compactText,
24689
+ style: valueStyle
24690
+ })
24691
+ });
24692
+ }
24693
+ return /* @__PURE__ */ require_jsx_runtime.jsx(View, {
24694
+ direction: "column",
24695
+ gap: 4,
24696
+ ...viewProps,
24697
+ children: limitedRows.map((row) => /* @__PURE__ */ require_jsx_runtime.jsxs(View, {
24698
+ direction: "row",
24699
+ gap: 8,
24700
+ ...innerProps,
24701
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx(Text, {
24702
+ text: `${row.label}:`,
24703
+ style: rowStyle
24704
+ }), /* @__PURE__ */ require_jsx_runtime.jsx(Text, {
24705
+ text: row.value,
24706
+ style: valueStyle
24707
+ })]
24708
+ }, `debug-${row.metric}`))
24709
+ });
24710
+ }
24711
+ //#endregion
24712
+ //#region src/components/custom/Graphics.tsx
24713
+ /**
24714
+ * Graphics component
24715
+ * Renders custom vector shapes via imperative drawing API
24716
+ *
24717
+ * @example
24718
+ * ```tsx
24719
+ * <Graphics
24720
+ * onDraw={(g) => {
24721
+ * g.fillStyle(0xff0000, 1)
24722
+ * g.fillCircle(50, 50, 50)
24723
+ * }}
24724
+ * />
24725
+ * ```
24726
+ */
24727
+ function Graphics(props) {
24728
+ const { props: themed, nestedTheme } = getThemedProps("Graphics", useTheme(), props);
24729
+ return /* @__PURE__ */ require_jsx_runtime.jsx("graphics", {
24730
+ ...themed,
24731
+ theme: nestedTheme
24732
+ });
24733
+ }
24734
+ //#endregion
24735
+ //#region src/components/custom/RadioButton.tsx
24736
+ /** @jsxImportSource ../.. */
24737
+ /**
24738
+ * RadioButton component - Selectable option with circle indicator and label
24739
+ */
24740
+ /**
24741
+ * RadioButton component - displays a selectable circle with label
24742
+ * @param props - RadioButton properties
24743
+ * @returns RadioButton JSX element
24744
+ */
24745
+ function RadioButton(props) {
24746
+ const { props: themed, nestedTheme } = getThemedProps("RadioButton", void 0, {});
24747
+ const size = themed.size ?? 16;
24748
+ const innerSize = themed.innerSize ?? size * .75;
24749
+ const innerRadius = innerSize * .5;
24750
+ const outerRadius = size * .5;
24751
+ return /* @__PURE__ */ require_jsx_runtime.jsxs(View, {
24752
+ direction: "row",
24753
+ alignItems: "center",
24754
+ enableGestures: true,
24755
+ onTouch: () => props.onClick?.(),
24756
+ theme: nestedTheme,
24757
+ gap: themed.gap,
24758
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx(View, {
24759
+ width: size,
24760
+ height: size,
24761
+ backgroundColor: themed.color,
24762
+ alignItems: "center",
24763
+ justifyContent: "center",
24764
+ backgroundAlpha: 1,
24765
+ padding: 0,
24766
+ cornerRadius: outerRadius,
24767
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(View, {
24768
+ width: innerSize,
24769
+ height: innerSize,
24770
+ backgroundColor: themed.selectedColor,
24771
+ visible: props.selected ?? false,
24772
+ cornerRadius: innerRadius
24773
+ })
24774
+ }), /* @__PURE__ */ require_jsx_runtime.jsx(Text, {
24775
+ text: props.label,
24776
+ style: themed.labelStyle
24777
+ })]
24778
+ }, props.key);
24779
+ }
24780
+ //#endregion
24781
+ //#region src/components/custom/RadioGroup.tsx
24782
+ /** @jsxImportSource ../.. */
24783
+ /**
24784
+ * RadioGroup component - Manages a group of radio buttons with single-selection logic
24785
+ */
24786
+ /**
24787
+ * RadioGroup component - displays a group of radio buttons with single-selection
24788
+ * @param props - RadioGroup properties
23932
24789
  * @returns RadioGroup JSX element
23933
24790
  */
23934
24791
  function RadioGroup(props) {
@@ -24031,42 +24888,537 @@ function Text(props) {
24031
24888
  });
24032
24889
  }
24033
24890
  //#endregion
24034
- //#region src/components/custom/TileSprite.tsx
24891
+ //#region src/components/custom/TileSprite.tsx
24892
+ /**
24893
+ * TileSprite component
24894
+ * Displays repeating texture patterns for backgrounds and effects
24895
+ *
24896
+ * @example
24897
+ * ```tsx
24898
+ * // Scrolling background
24899
+ * <TileSprite
24900
+ * texture="clouds"
24901
+ * width={800}
24902
+ * height={200}
24903
+ * tilePositionX={scrollOffset}
24904
+ * />
24905
+ *
24906
+ * // Scaled tiles
24907
+ * <TileSprite
24908
+ * texture="pattern"
24909
+ * width={400}
24910
+ * height={400}
24911
+ * tileScaleX={2}
24912
+ * tileScaleY={2}
24913
+ * />
24914
+ * ```
24915
+ */
24916
+ function TileSprite(props) {
24917
+ const { props: themed, nestedTheme } = getThemedProps("TileSprite", useTheme(), props);
24918
+ return /* @__PURE__ */ require_jsx_runtime.jsx("tilesprite", {
24919
+ ...themed,
24920
+ theme: nestedTheme
24921
+ });
24922
+ }
24923
+ //#endregion
24924
+ //#region src/components/custom/Particles.tsx
24925
+ function Particles(props) {
24926
+ return /* @__PURE__ */ require_jsx_runtime.jsx("particles", { ...props });
24927
+ }
24928
+ //#endregion
24929
+ //#region src/components/custom/Portal.tsx
24930
+ /** @jsxImportSource ../.. */
24931
+ /**
24932
+ * Portal component - renders children into a separate tree at specified depth
24933
+ * Enables overlays, modals, tooltips without affecting parent tree layout
24934
+ */
24935
+ /**
24936
+ * Portal component
24937
+ * Renders child VNode into a separate container tree at specified depth.
24938
+ * Automatically injects event blockers to prevent click-through and scrolling.
24939
+ *
24940
+ * @example
24941
+ * ```tsx
24942
+ * // Basic portal (automatically blocks events in content area)
24943
+ * <Portal depth={1000}>
24944
+ * <View>Overlay content</View>
24945
+ * </Portal>
24946
+ *
24947
+ * // Non-blocking portal (allows click-through)
24948
+ * <Portal depth={500} blockEvents={false}>
24949
+ * <View>Info overlay - clickable background</View>
24950
+ * </Portal>
24951
+ *
24952
+ * // Portal with custom event handling (original handlers are preserved)
24953
+ * <Portal depth={1000}>
24954
+ * <View onTouch={(e) => console.log('clicked')}>
24955
+ * Content
24956
+ * </View>
24957
+ * </Portal>
24958
+ * ```
24959
+ */
24960
+ function Portal(props) {
24961
+ const portalId = useMemo(() => props.id ?? portalRegistry.generateId(), [props.id]);
24962
+ const depth = props.depth ?? 1e3;
24963
+ const scene = useScene();
24964
+ const blockEvents = props.blockEvents ?? true;
24965
+ const mountedNodesRef = useRef([]);
24966
+ const previousChildrenRef = useRef([]);
24967
+ const normalizeChildren = (children) => {
24968
+ if (!children) return [];
24969
+ return (Array.isArray(children) ? children.flat(Infinity) : [children]).filter((child) => !!child && typeof child === "object" && "type" in child);
24970
+ };
24971
+ useEffect(() => {
24972
+ const portalContainer = portalRegistry.register(portalId, depth, scene, {
24973
+ type: "View",
24974
+ props: {},
24975
+ children: []
24976
+ }, scene.add.container(0, 0));
24977
+ let blockerContainer = null;
24978
+ if (blockEvents) {
24979
+ blockerContainer = scene.add.container(0, 0);
24980
+ portalContainer.add(blockerContainer);
24981
+ blockerContainer.setDepth(-1);
24982
+ }
24983
+ const children = normalizeChildren(props.children);
24984
+ const mountedNodes = [];
24985
+ for (const child of children) if (child) {
24986
+ const mountedNode = mount(portalContainer, child);
24987
+ if (mountedNode) {
24988
+ portalContainer.add(mountedNode);
24989
+ mountedNodes.push(mountedNode);
24990
+ }
24991
+ }
24992
+ mountedNodesRef.current = mountedNodes;
24993
+ previousChildrenRef.current = children;
24994
+ const gestureManager = getGestureManager(scene);
24995
+ if (blockEvents && blockerContainer) {
24996
+ const blocker = blockerContainer;
24997
+ DeferredLayoutQueue.defer(() => {
24998
+ const firstChild = portalContainer.getAt(1);
24999
+ if (!firstChild) return;
25000
+ const { width, height } = firstChild.__cachedLayoutSize ? firstChild.__cachedLayoutSize : firstChild.__getLayoutSize ? firstChild.__getLayoutSize() : (() => {
25001
+ const bounds = firstChild.getBounds();
25002
+ return {
25003
+ width: bounds.width,
25004
+ height: bounds.height
25005
+ };
25006
+ })();
25007
+ const x = firstChild.x;
25008
+ const y = firstChild.y;
25009
+ blocker.setPosition(x, y);
25010
+ const hitArea = new phaser.Geom.Rectangle(0, 0, width, height);
25011
+ gestureManager.registerContainer(blocker, {
25012
+ onTouch: (e) => {
25013
+ e.stopPropagation();
25014
+ },
25015
+ onTouchMove: (e) => {
25016
+ e.stopPropagation();
25017
+ }
25018
+ }, hitArea);
25019
+ });
25020
+ }
25021
+ return () => {
25022
+ if (blockEvents && blockerContainer) gestureManager.unregisterContainer(blockerContainer);
25023
+ portalRegistry.unregister(portalId);
25024
+ };
25025
+ }, [
25026
+ portalId,
25027
+ depth,
25028
+ scene,
25029
+ blockEvents
25030
+ ]);
25031
+ useEffect(() => {
25032
+ const portal = portalRegistry.get(portalId);
25033
+ if (!portal) return;
25034
+ const portalContainer = portal.container;
25035
+ const newChildren = normalizeChildren(props.children);
25036
+ const oldChildren = previousChildrenRef.current;
25037
+ const maxLen = Math.max(oldChildren.length, newChildren.length);
25038
+ for (let i = 0; i < maxLen; i++) {
25039
+ const oldChild = oldChildren[i];
25040
+ const newChild = newChildren[i];
25041
+ if (oldChild && newChild) patchVNode(portalContainer, oldChild, newChild);
25042
+ else if (!oldChild && newChild) {
25043
+ const mountedNode = mount(portalContainer, newChild);
25044
+ if (mountedNode) {
25045
+ portalContainer.add(mountedNode);
25046
+ mountedNodesRef.current.push(mountedNode);
25047
+ }
25048
+ } else if (oldChild && !newChild) unmount(oldChild);
25049
+ }
25050
+ previousChildrenRef.current = newChildren;
25051
+ }, [props.children, portalId]);
25052
+ return null;
25053
+ }
25054
+ //#endregion
25055
+ //#region src/components/custom/Popover.tsx
25056
+ function getMainPlacement(placement) {
25057
+ return placement.split("-")[0];
25058
+ }
25059
+ function getCrossPlacement(placement) {
25060
+ return placement.split("-")[1] ?? "center";
25061
+ }
25062
+ function calculateOverlayPosition(options) {
25063
+ const { anchor, content, placement, offset } = options;
25064
+ const main = getMainPlacement(placement);
25065
+ const cross = getCrossPlacement(placement);
25066
+ let x;
25067
+ let y;
25068
+ if (main === "top" || main === "bottom") {
25069
+ y = main === "top" ? anchor.y - content.height - offset : anchor.y + anchor.height + offset;
25070
+ if (cross === "start") x = anchor.x;
25071
+ else if (cross === "end") x = anchor.x + anchor.width - content.width;
25072
+ else x = anchor.x + (anchor.width - content.width) / 2;
25073
+ } else {
25074
+ x = main === "left" ? anchor.x - content.width - offset : anchor.x + anchor.width + offset;
25075
+ if (cross === "start") y = anchor.y;
25076
+ else if (cross === "end") y = anchor.y + anchor.height - content.height;
25077
+ else y = anchor.y + (anchor.height - content.height) / 2;
25078
+ }
25079
+ const viewport = options.viewport;
25080
+ if (viewport) {
25081
+ const padding = options.viewportPadding ?? 8;
25082
+ x = Math.min(Math.max(padding, x), Math.max(padding, viewport.width - content.width - padding));
25083
+ y = Math.min(Math.max(padding, y), Math.max(padding, viewport.height - content.height - padding));
25084
+ }
25085
+ return {
25086
+ x,
25087
+ y,
25088
+ placement
25089
+ };
25090
+ }
25091
+ function getLayoutSize(container) {
25092
+ const withLayout = container;
25093
+ return withLayout?.__getLayoutSize?.() ?? withLayout?.__cachedLayoutSize ?? {
25094
+ width: 0,
25095
+ height: 0
25096
+ };
25097
+ }
25098
+ function getWorldPosition(container) {
25099
+ const matrix = container.getWorldTransformMatrix?.();
25100
+ if (matrix) return {
25101
+ x: matrix.tx,
25102
+ y: matrix.ty
25103
+ };
25104
+ return {
25105
+ x: container.x ?? 0,
25106
+ y: container.y ?? 0
25107
+ };
25108
+ }
25109
+ function getAnchorRect(container) {
25110
+ if (!container) return {
25111
+ x: 0,
25112
+ y: 0,
25113
+ width: 0,
25114
+ height: 0
25115
+ };
25116
+ const size = getLayoutSize(container);
25117
+ const position = getWorldPosition(container);
25118
+ return {
25119
+ x: position.x,
25120
+ y: position.y,
25121
+ width: size.width,
25122
+ height: size.height
25123
+ };
25124
+ }
25125
+ var FALLBACK_CONTENT_SIZE = {
25126
+ width: 220,
25127
+ height: 120
25128
+ };
25129
+ function assignRef(ref, value) {
25130
+ if (!ref) return;
25131
+ if (typeof ref === "function") {
25132
+ ref(value);
25133
+ return;
25134
+ }
25135
+ ref.current = value;
25136
+ }
25137
+ function Popover(props) {
25138
+ const { props: themed, nestedTheme } = getThemedProps("Popover", useTheme(), props.theme ?? {});
25139
+ const scene = useScene();
25140
+ const triggerRef = useRef(null);
25141
+ const contentRef = useRef(null);
25142
+ const [measuredContentSize, setMeasuredContentSize] = useState(null);
25143
+ const [internalOpen, setInternalOpen] = useState(props.defaultOpen ?? false);
25144
+ const isControlled = props.isOpen !== void 0;
25145
+ const isOpen = isControlled ? props.isOpen === true : internalOpen;
25146
+ const placement = props.placement ?? themed.placement ?? "bottom";
25147
+ const offset = props.offset ?? themed.offset ?? 8;
25148
+ const depth = props.depth ?? themed.depth ?? 1100;
25149
+ const closeOnOutside = props.closeOnOutside ?? themed.closeOnOutside ?? true;
25150
+ const closeOnEscape = props.closeOnEscape ?? themed.closeOnEscape ?? true;
25151
+ const viewportPadding = props.viewportPadding ?? themed.viewportPadding ?? 8;
25152
+ const explicitContentWidth = props.contentWidth ?? themed.contentWidth;
25153
+ const explicitContentHeight = props.contentHeight ?? themed.contentHeight;
25154
+ const viewport = portalRegistry.getViewportSize(scene);
25155
+ const anchor = getAnchorRect(triggerRef.current);
25156
+ const measuredWidth = measuredContentSize?.width ?? FALLBACK_CONTENT_SIZE.width;
25157
+ const measuredHeight = measuredContentSize?.height ?? FALLBACK_CONTENT_SIZE.height;
25158
+ const isPositionReady = !(explicitContentWidth === void 0 || explicitContentHeight === void 0) || measuredContentSize !== null;
25159
+ const contentWidth = props.matchTriggerWidth ? Math.max(anchor.width, explicitContentWidth ?? measuredWidth) : explicitContentWidth ?? measuredWidth;
25160
+ const overlayPosition = calculateOverlayPosition({
25161
+ anchor,
25162
+ content: {
25163
+ width: contentWidth,
25164
+ height: explicitContentHeight ?? measuredHeight
25165
+ },
25166
+ placement,
25167
+ offset,
25168
+ viewport,
25169
+ viewportPadding
25170
+ });
25171
+ const setOpen = (open) => {
25172
+ if (props.disabled && open) return;
25173
+ if (!isControlled) setInternalOpen(open);
25174
+ props.onOpenChange?.(open);
25175
+ };
25176
+ const toggleOpen = (event) => {
25177
+ event.stopPropagation();
25178
+ setOpen(!isOpen);
25179
+ };
25180
+ const close = (event) => {
25181
+ event?.stopPropagation();
25182
+ setOpen(false);
25183
+ };
25184
+ const contentProps = props.contentProps ?? {};
25185
+ const contentPropsRef = contentProps.ref;
25186
+ const contentPropsAlpha = contentProps.alpha;
25187
+ const handleContentRef = (container) => {
25188
+ contentRef.current = container;
25189
+ assignRef(contentPropsRef, container);
25190
+ };
25191
+ useEffect(() => {
25192
+ if (!closeOnEscape || !isOpen) return;
25193
+ const handleKeyDown = (event) => {
25194
+ if (event.key === "Escape") setOpen(false);
25195
+ };
25196
+ window.addEventListener("keydown", handleKeyDown);
25197
+ return () => window.removeEventListener("keydown", handleKeyDown);
25198
+ }, [closeOnEscape, isOpen]);
25199
+ useEffect(() => {
25200
+ if (!isOpen) return;
25201
+ DeferredLayoutQueue.defer(() => {
25202
+ const size = getLayoutSize(contentRef.current);
25203
+ if (size.width <= 0 || size.height <= 0) return;
25204
+ setMeasuredContentSize((current) => {
25205
+ if (current?.width === size.width && current?.height === size.height) return current;
25206
+ return {
25207
+ width: size.width,
25208
+ height: size.height
25209
+ };
25210
+ });
25211
+ });
25212
+ }, [
25213
+ isOpen,
25214
+ props.children,
25215
+ explicitContentWidth,
25216
+ explicitContentHeight
25217
+ ]);
25218
+ return /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [/* @__PURE__ */ require_jsx_runtime.jsx(View, {
25219
+ ...props.triggerProps ?? {},
25220
+ ref: triggerRef,
25221
+ enableGestures: !props.disabled,
25222
+ onTouch: toggleOpen,
25223
+ children: props.trigger
25224
+ }), isOpen && /* @__PURE__ */ require_jsx_runtime.jsxs(Portal, {
25225
+ depth,
25226
+ blockEvents: false,
25227
+ children: [closeOnOutside && /* @__PURE__ */ require_jsx_runtime.jsx(View, {
25228
+ width: viewport.width,
25229
+ height: viewport.height,
25230
+ backgroundColor: 0,
25231
+ backgroundAlpha: 0,
25232
+ onTouch: close,
25233
+ onTouchMove: (event) => event.stopPropagation()
25234
+ }), /* @__PURE__ */ require_jsx_runtime.jsx(View, {
25235
+ ...contentProps,
25236
+ ref: handleContentRef,
25237
+ x: overlayPosition.x,
25238
+ y: overlayPosition.y,
25239
+ ...props.matchTriggerWidth || explicitContentWidth !== void 0 ? { width: contentWidth } : {},
25240
+ direction: "column",
25241
+ backgroundColor: themed.backgroundColor ?? 1120295,
25242
+ borderColor: themed.borderColor ?? 3359061,
25243
+ borderWidth: themed.borderWidth ?? 1,
25244
+ cornerRadius: themed.cornerRadius ?? 8,
25245
+ padding: themed.padding ?? 10,
25246
+ gap: themed.gap ?? 8,
25247
+ ...isPositionReady ? contentPropsAlpha !== void 0 ? { alpha: contentPropsAlpha } : {} : { alpha: 0 },
25248
+ onTouch: (event) => event.stopPropagation(),
25249
+ theme: nestedTheme,
25250
+ children: props.children
25251
+ })]
25252
+ })] });
25253
+ }
25254
+ function ContextMenu(props) {
25255
+ const { items, width: explicitWidth, onSelect, isOpen: explicitOpen, defaultOpen, onOpenChange, ...popoverProps } = props;
25256
+ const { props: themed, nestedTheme } = getThemedProps("ContextMenu", useTheme(), props.theme ?? {});
25257
+ const [internalOpen, setInternalOpen] = useState(defaultOpen ?? false);
25258
+ const isControlled = explicitOpen !== void 0;
25259
+ const isOpen = isControlled ? explicitOpen === true : internalOpen;
25260
+ const width = explicitWidth ?? themed.width ?? 220;
25261
+ const itemHeight = themed.itemHeight ?? 34;
25262
+ const setOpen = (open) => {
25263
+ if (!isControlled) setInternalOpen(open);
25264
+ onOpenChange?.(open);
25265
+ };
25266
+ const handleSelect = (item) => {
25267
+ if (item.disabled) return;
25268
+ item.onSelect?.();
25269
+ onSelect?.(item);
25270
+ setOpen(false);
25271
+ };
25272
+ return /* @__PURE__ */ require_jsx_runtime.jsx(Popover, {
25273
+ ...popoverProps,
25274
+ isOpen,
25275
+ onOpenChange: setOpen,
25276
+ contentWidth: width,
25277
+ contentHeight: Math.max(1, items.length) * itemHeight + 20,
25278
+ contentProps: {
25279
+ padding: themed.padding ?? 6,
25280
+ gap: themed.gap ?? 2,
25281
+ backgroundColor: themed.backgroundColor,
25282
+ borderColor: themed.borderColor,
25283
+ borderWidth: themed.borderWidth,
25284
+ cornerRadius: themed.cornerRadius,
25285
+ theme: nestedTheme
25286
+ },
25287
+ children: items.map((item) => {
25288
+ const textColor = item.disabled ? themed.disabledTextColor ?? "#64748b" : item.danger ? themed.dangerTextColor ?? "#fecaca" : themed.textStyle?.color ?? "#f8fafc";
25289
+ return /* @__PURE__ */ require_jsx_runtime.jsxs(View, {
25290
+ width: "fill",
25291
+ height: itemHeight,
25292
+ direction: "row",
25293
+ alignItems: "center",
25294
+ gap: themed.itemGap ?? 8,
25295
+ padding: themed.itemPadding ?? {
25296
+ left: 10,
25297
+ right: 10,
25298
+ top: 6,
25299
+ bottom: 6
25300
+ },
25301
+ cornerRadius: themed.itemCornerRadius ?? 5,
25302
+ backgroundColor: item.danger ? themed.dangerBackgroundColor ?? 2042167 : 0,
25303
+ backgroundAlpha: item.danger ? .35 : 0,
25304
+ enableGestures: !item.disabled,
25305
+ onTouch: (event) => {
25306
+ event.stopPropagation();
25307
+ handleSelect(item);
25308
+ },
25309
+ children: [
25310
+ item.prefix,
25311
+ /* @__PURE__ */ require_jsx_runtime.jsx(View, {
25312
+ flex: 1,
25313
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(Text, {
25314
+ text: item.label,
25315
+ style: {
25316
+ ...themed.textStyle ?? {},
25317
+ color: textColor
25318
+ }
25319
+ })
25320
+ }),
25321
+ item.suffix
25322
+ ]
25323
+ }, item.id);
25324
+ })
25325
+ });
25326
+ }
25327
+ //#endregion
25328
+ //#region src/components/custom/ProgressBar.tsx
25329
+ /** @jsxImportSource ../.. */
24035
25330
  /**
24036
- * TileSprite component
24037
- * Displays repeating texture patterns for backgrounds and effects
24038
- *
24039
- * @example
24040
- * ```tsx
24041
- * // Scrolling background
24042
- * <TileSprite
24043
- * texture="clouds"
24044
- * width={800}
24045
- * height={200}
24046
- * tilePositionX={scrollOffset}
24047
- * />
24048
- *
24049
- * // Scaled tiles
24050
- * <TileSprite
24051
- * texture="pattern"
24052
- * width={400}
24053
- * height={400}
24054
- * tileScaleX={2}
24055
- * tileScaleY={2}
24056
- * />
24057
- * ```
25331
+ * ProgressBar component - determinate progress indicator for health, loading, cooldowns, and XP.
24058
25332
  */
24059
- function TileSprite(props) {
24060
- const { props: themed, nestedTheme } = getThemedProps("TileSprite", useTheme(), props);
24061
- return /* @__PURE__ */ require_jsx_runtime.jsx("tilesprite", {
24062
- ...themed,
24063
- theme: nestedTheme
24064
- });
25333
+ function clampProgressValue(value, min, max) {
25334
+ if (!Number.isFinite(value)) return min;
25335
+ return Math.min(Math.max(value, min), max);
24065
25336
  }
24066
- //#endregion
24067
- //#region src/components/custom/Particles.tsx
24068
- function Particles(props) {
24069
- return /* @__PURE__ */ require_jsx_runtime.jsx("particles", { ...props });
25337
+ function getProgressRatio(value, min, max) {
25338
+ if (!Number.isFinite(min) || !Number.isFinite(max) || min === max) return 0;
25339
+ const normalizedMin = Math.min(min, max);
25340
+ const normalizedMax = Math.max(min, max);
25341
+ return (clampProgressValue(value, normalizedMin, normalizedMax) - normalizedMin) / (normalizedMax - normalizedMin);
25342
+ }
25343
+ function formatDefaultValue(props) {
25344
+ return `${Math.round(props.percent)}%`;
25345
+ }
25346
+ function ProgressBar(props) {
25347
+ const { value, min = 0, max = 100, orientation: explicitOrientation, label, showValue, labelPosition: explicitLabelPosition, formatValue, trackColor: explicitTrackColor, fillColor: explicitFillColor, borderColor: explicitBorderColor, borderWidth: explicitBorderWidth, cornerRadius: explicitCornerRadius, labelStyle: explicitLabelStyle, disabled = false, disabledAlpha: explicitDisabledAlpha, theme, width, height, alpha, ...viewProps } = props;
25348
+ const { props: themed, nestedTheme } = getThemedProps("ProgressBar", useTheme(), theme ?? {});
25349
+ const orientation = explicitOrientation ?? themed.orientation ?? "horizontal";
25350
+ const ratio = getProgressRatio(value, min, max);
25351
+ const percent = ratio * 100;
25352
+ const labelPosition = explicitLabelPosition ?? themed.labelPosition ?? (showValue || label ? "right" : "none");
25353
+ const shouldShowText = labelPosition !== "none" && Boolean(showValue || label);
25354
+ const text = shouldShowText ? [label, showValue ? (formatValue ?? themed.formatValue ?? formatDefaultValue)({
25355
+ value,
25356
+ min,
25357
+ max,
25358
+ ratio,
25359
+ percent
25360
+ }) : void 0].filter(Boolean).join(" ") : "";
25361
+ const resolvedWidth = width ?? themed.width ?? (orientation === "horizontal" ? 240 : 24);
25362
+ const resolvedHeight = height ?? themed.height ?? (orientation === "horizontal" ? 22 : 160);
25363
+ const trackColor = explicitTrackColor ?? themed.trackColor ?? 2042167;
25364
+ const fillColor = explicitFillColor ?? themed.fillColor ?? 2278750;
25365
+ const borderColor = explicitBorderColor ?? themed.borderColor ?? 3359061;
25366
+ const borderWidth = explicitBorderWidth ?? themed.borderWidth ?? 1;
25367
+ const cornerRadius = explicitCornerRadius ?? themed.cornerRadius ?? (orientation === "horizontal" ? 11 : 8);
25368
+ const labelStyle = explicitLabelStyle ?? themed.labelStyle ?? {
25369
+ color: "#ffffff",
25370
+ fontSize: "12px"
25371
+ };
25372
+ const disabledAlpha = explicitDisabledAlpha ?? themed.disabledAlpha ?? .5;
25373
+ const effectiveAlpha = disabled ? disabledAlpha : alpha;
25374
+ const rootDirection = labelPosition === "left" || labelPosition === "right" ? "row" : labelPosition === "top" || labelPosition === "bottom" ? "column" : "column";
25375
+ const labelNode = shouldShowText ? /* @__PURE__ */ require_jsx_runtime.jsx(Text, {
25376
+ text,
25377
+ style: labelStyle
25378
+ }) : null;
25379
+ const fillProps = orientation === "horizontal" ? {
25380
+ width: `${percent}%`,
25381
+ height: "fill"
25382
+ } : {
25383
+ width: "fill",
25384
+ height: `${percent}%`
25385
+ };
25386
+ const track = /* @__PURE__ */ require_jsx_runtime.jsxs(View, {
25387
+ width: resolvedWidth,
25388
+ height: resolvedHeight,
25389
+ direction: orientation === "horizontal" ? "stack" : "column",
25390
+ justifyContent: orientation === "vertical" ? "end" : "start",
25391
+ backgroundColor: trackColor,
25392
+ borderColor,
25393
+ borderWidth,
25394
+ cornerRadius,
25395
+ overflow: "hidden",
25396
+ theme: nestedTheme,
25397
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx(View, {
25398
+ ...fillProps,
25399
+ backgroundColor: fillColor,
25400
+ cornerRadius
25401
+ }), labelPosition === "inside" && shouldShowText && /* @__PURE__ */ require_jsx_runtime.jsx(View, {
25402
+ width: "fill",
25403
+ height: "fill",
25404
+ justifyContent: "center",
25405
+ alignItems: "center",
25406
+ children: labelNode
25407
+ })]
25408
+ });
25409
+ return /* @__PURE__ */ require_jsx_runtime.jsxs(View, {
25410
+ ...viewProps,
25411
+ direction: rootDirection,
25412
+ alignItems: "center",
25413
+ gap: themed.gap ?? 8,
25414
+ ...effectiveAlpha !== void 0 ? { alpha: effectiveAlpha } : {},
25415
+ theme: nestedTheme,
25416
+ children: [
25417
+ labelPosition === "top" || labelPosition === "left" ? labelNode : null,
25418
+ track,
25419
+ labelPosition !== "inside" && (labelPosition === "bottom" || labelPosition === "right") ? labelNode : null
25420
+ ]
25421
+ });
24070
25422
  }
24071
25423
  //#endregion
24072
25424
  //#region src/components/index.ts
@@ -24082,7 +25434,6 @@ function Particles(props) {
24082
25434
  /**
24083
25435
  * Registers all built-in components with the host
24084
25436
  * This should be called during library initialization
24085
- * Note: TileSprite is currently dummy (throws on use)
24086
25437
  */
24087
25438
  function registerBuiltins() {
24088
25439
  register("view", {
@@ -24155,7 +25506,7 @@ function registerBuiltins() {
24155
25506
  /**
24156
25507
  * Preprocesses SVG string to ensure tinting works correctly
24157
25508
  * Replaces fill/stroke="currentColor" and other colors with white (#FFFFFF)
24158
- * This allows Phaser's tint to work multiplicatively (white × tint = tint color)
25509
+ * This allows Phaser's tint to work by multiplication (white × tint = tint color)
24159
25510
  * @param svg - Raw SVG string
24160
25511
  * @returns Preprocessed SVG string with white fills/strokes
24161
25512
  */
@@ -25217,132 +26568,6 @@ function Accordion(props) {
25217
26568
  }, props.key);
25218
26569
  }
25219
26570
  //#endregion
25220
- //#region src/components/custom/Portal.tsx
25221
- /** @jsxImportSource ../.. */
25222
- /**
25223
- * Portal component - renders children into a separate tree at specified depth
25224
- * Enables overlays, modals, tooltips without affecting parent tree layout
25225
- */
25226
- /**
25227
- * Portal component
25228
- * Renders child VNode into a separate container tree at specified depth.
25229
- * Automatically injects event blockers to prevent click-through and scrolling.
25230
- *
25231
- * @example
25232
- * ```tsx
25233
- * // Basic portal (automatically blocks events in content area)
25234
- * <Portal depth={1000}>
25235
- * <View>Overlay content</View>
25236
- * </Portal>
25237
- *
25238
- * // Non-blocking portal (allows click-through)
25239
- * <Portal depth={500} blockEvents={false}>
25240
- * <View>Info overlay - clickable background</View>
25241
- * </Portal>
25242
- *
25243
- * // Portal with custom event handling (original handlers are preserved)
25244
- * <Portal depth={1000}>
25245
- * <View onTouch={(e) => console.log('clicked')}>
25246
- * Content
25247
- * </View>
25248
- * </Portal>
25249
- * ```
25250
- */
25251
- function Portal(props) {
25252
- const portalId = useMemo(() => props.id ?? portalRegistry.generateId(), [props.id]);
25253
- const depth = props.depth ?? 1e3;
25254
- const scene = useScene();
25255
- const blockEvents = props.blockEvents ?? true;
25256
- const mountedNodesRef = useRef([]);
25257
- const previousChildrenRef = useRef([]);
25258
- const normalizeChildren = (children) => {
25259
- if (!children) return [];
25260
- return (Array.isArray(children) ? children.flat(Infinity) : [children]).filter((child) => !!child && typeof child === "object" && "type" in child);
25261
- };
25262
- useEffect(() => {
25263
- const portalContainer = portalRegistry.register(portalId, depth, scene, {
25264
- type: "View",
25265
- props: {},
25266
- children: []
25267
- }, scene.add.container(0, 0));
25268
- let blockerContainer = null;
25269
- if (blockEvents) {
25270
- blockerContainer = scene.add.container(0, 0);
25271
- portalContainer.add(blockerContainer);
25272
- blockerContainer.setDepth(-1);
25273
- }
25274
- const children = normalizeChildren(props.children);
25275
- const mountedNodes = [];
25276
- for (const child of children) if (child) {
25277
- const mountedNode = mount(portalContainer, child);
25278
- if (mountedNode) {
25279
- portalContainer.add(mountedNode);
25280
- mountedNodes.push(mountedNode);
25281
- }
25282
- }
25283
- mountedNodesRef.current = mountedNodes;
25284
- previousChildrenRef.current = children;
25285
- const gestureManager = getGestureManager(scene);
25286
- if (blockEvents && blockerContainer) {
25287
- const blocker = blockerContainer;
25288
- DeferredLayoutQueue.defer(() => {
25289
- const firstChild = portalContainer.getAt(1);
25290
- if (!firstChild) return;
25291
- const { width, height } = firstChild.__cachedLayoutSize ? firstChild.__cachedLayoutSize : firstChild.__getLayoutSize ? firstChild.__getLayoutSize() : (() => {
25292
- const bounds = firstChild.getBounds();
25293
- return {
25294
- width: bounds.width,
25295
- height: bounds.height
25296
- };
25297
- })();
25298
- const x = firstChild.x;
25299
- const y = firstChild.y;
25300
- blocker.setPosition(x, y);
25301
- const hitArea = new phaser.Geom.Rectangle(0, 0, width, height);
25302
- gestureManager.registerContainer(blocker, {
25303
- onTouch: (e) => {
25304
- e.stopPropagation();
25305
- },
25306
- onTouchMove: (e) => {
25307
- e.stopPropagation();
25308
- }
25309
- }, hitArea);
25310
- });
25311
- }
25312
- return () => {
25313
- if (blockEvents && blockerContainer) gestureManager.unregisterContainer(blockerContainer);
25314
- portalRegistry.unregister(portalId);
25315
- };
25316
- }, [
25317
- portalId,
25318
- depth,
25319
- scene,
25320
- blockEvents
25321
- ]);
25322
- useEffect(() => {
25323
- const portal = portalRegistry.get(portalId);
25324
- if (!portal) return;
25325
- const portalContainer = portal.container;
25326
- const newChildren = normalizeChildren(props.children);
25327
- const oldChildren = previousChildrenRef.current;
25328
- const maxLen = Math.max(oldChildren.length, newChildren.length);
25329
- for (let i = 0; i < maxLen; i++) {
25330
- const oldChild = oldChildren[i];
25331
- const newChild = newChildren[i];
25332
- if (oldChild && newChild) patchVNode(portalContainer, oldChild, newChild);
25333
- else if (!oldChild && newChild) {
25334
- const mountedNode = mount(portalContainer, newChild);
25335
- if (mountedNode) {
25336
- portalContainer.add(mountedNode);
25337
- mountedNodesRef.current.push(mountedNode);
25338
- }
25339
- } else if (oldChild && !newChild) unmount(oldChild);
25340
- }
25341
- previousChildrenRef.current = newChildren;
25342
- }, [props.children, portalId]);
25343
- return null;
25344
- }
25345
- //#endregion
25346
26571
  //#region src/components/custom/Modal.tsx
25347
26572
  /** @jsxImportSource ../.. */
25348
26573
  /**
@@ -28108,7 +29333,7 @@ function Joystick(props) {
28108
29333
  y: 0
28109
29334
  });
28110
29335
  useLayoutEffect(() => {
28111
- const size = getLayoutSize(outerRef.current);
29336
+ const size = getLayoutSize$1(outerRef.current);
28112
29337
  if (size != null) {
28113
29338
  const newCenter = {
28114
29339
  x: size.width / 2,
@@ -29199,7 +30424,6 @@ function Toggle(props) {
29199
30424
  setIsAnimating(true);
29200
30425
  const endX = newChecked ? thumbOffsetOn : thumbOffsetOff;
29201
30426
  const startX = thumbX;
29202
- console.log("Duration:", duration.current);
29203
30427
  scene.tweens.addCounter({
29204
30428
  from: 0,
29205
30429
  to: 1,
@@ -29378,6 +30602,12 @@ Object.defineProperty(exports, "AlertDialog", {
29378
30602
  return AlertDialog;
29379
30603
  }
29380
30604
  });
30605
+ Object.defineProperty(exports, "Badge", {
30606
+ enumerable: true,
30607
+ get: function() {
30608
+ return Badge;
30609
+ }
30610
+ });
29381
30611
  Object.defineProperty(exports, "Button", {
29382
30612
  enumerable: true,
29383
30613
  get: function() {
@@ -29396,6 +30626,18 @@ Object.defineProperty(exports, "CharTextInput", {
29396
30626
  return CharTextInput;
29397
30627
  }
29398
30628
  });
30629
+ Object.defineProperty(exports, "Checkbox", {
30630
+ enumerable: true,
30631
+ get: function() {
30632
+ return Checkbox;
30633
+ }
30634
+ });
30635
+ Object.defineProperty(exports, "ContextMenu", {
30636
+ enumerable: true,
30637
+ get: function() {
30638
+ return ContextMenu;
30639
+ }
30640
+ });
29399
30641
  Object.defineProperty(exports, "DEFAULT_EFFECT", {
29400
30642
  enumerable: true,
29401
30643
  get: function() {
@@ -29420,6 +30662,12 @@ Object.defineProperty(exports, "DebugLogger", {
29420
30662
  return DebugLogger;
29421
30663
  }
29422
30664
  });
30665
+ Object.defineProperty(exports, "DebugPanel", {
30666
+ enumerable: true,
30667
+ get: function() {
30668
+ return DebugPanel;
30669
+ }
30670
+ });
29423
30671
  Object.defineProperty(exports, "DevConfig", {
29424
30672
  enumerable: true,
29425
30673
  get: function() {
@@ -29522,12 +30770,24 @@ Object.defineProperty(exports, "Particles", {
29522
30770
  return Particles;
29523
30771
  }
29524
30772
  });
30773
+ Object.defineProperty(exports, "Popover", {
30774
+ enumerable: true,
30775
+ get: function() {
30776
+ return Popover;
30777
+ }
30778
+ });
29525
30779
  Object.defineProperty(exports, "Portal", {
29526
30780
  enumerable: true,
29527
30781
  get: function() {
29528
30782
  return Portal;
29529
30783
  }
29530
30784
  });
30785
+ Object.defineProperty(exports, "ProgressBar", {
30786
+ enumerable: true,
30787
+ get: function() {
30788
+ return ProgressBar;
30789
+ }
30790
+ });
29531
30791
  Object.defineProperty(exports, "RadioButton", {
29532
30792
  enumerable: true,
29533
30793
  get: function() {
@@ -29612,6 +30872,12 @@ Object.defineProperty(exports, "Tabs", {
29612
30872
  return Tabs;
29613
30873
  }
29614
30874
  });
30875
+ Object.defineProperty(exports, "Tag", {
30876
+ enumerable: true,
30877
+ get: function() {
30878
+ return Tag;
30879
+ }
30880
+ });
29615
30881
  Object.defineProperty(exports, "Text", {
29616
30882
  enumerable: true,
29617
30883
  get: function() {
@@ -29714,12 +30980,24 @@ Object.defineProperty(exports, "buildEmitZoneFromLayout", {
29714
30980
  return buildEmitZoneFromLayout;
29715
30981
  }
29716
30982
  });
30983
+ Object.defineProperty(exports, "calculateOverlayPosition", {
30984
+ enumerable: true,
30985
+ get: function() {
30986
+ return calculateOverlayPosition;
30987
+ }
30988
+ });
29717
30989
  Object.defineProperty(exports, "calculateSliderSize", {
29718
30990
  enumerable: true,
29719
30991
  get: function() {
29720
30992
  return calculateSliderSize;
29721
30993
  }
29722
30994
  });
30995
+ Object.defineProperty(exports, "clampProgressValue", {
30996
+ enumerable: true,
30997
+ get: function() {
30998
+ return clampProgressValue;
30999
+ }
31000
+ });
29723
31001
  Object.defineProperty(exports, "createBounceEffect", {
29724
31002
  enumerable: true,
29725
31003
  get: function() {
@@ -29942,6 +31220,12 @@ Object.defineProperty(exports, "forestGreenPreset", {
29942
31220
  return forestGreenPreset;
29943
31221
  }
29944
31222
  });
31223
+ Object.defineProperty(exports, "formatBadgeCount", {
31224
+ enumerable: true,
31225
+ get: function() {
31226
+ return formatBadgeCount;
31227
+ }
31228
+ });
29945
31229
  Object.defineProperty(exports, "generateColorScale", {
29946
31230
  enumerable: true,
29947
31231
  get: function() {
@@ -29954,6 +31238,18 @@ Object.defineProperty(exports, "getBackgroundGraphics", {
29954
31238
  return getBackgroundGraphics;
29955
31239
  }
29956
31240
  });
31241
+ Object.defineProperty(exports, "getBadgeSizeConfig", {
31242
+ enumerable: true,
31243
+ get: function() {
31244
+ return getBadgeSizeConfig;
31245
+ }
31246
+ });
31247
+ Object.defineProperty(exports, "getBadgeText", {
31248
+ enumerable: true,
31249
+ get: function() {
31250
+ return getBadgeText;
31251
+ }
31252
+ });
29957
31253
  Object.defineProperty(exports, "getContrastRatio", {
29958
31254
  enumerable: true,
29959
31255
  get: function() {
@@ -29987,7 +31283,7 @@ Object.defineProperty(exports, "getLayoutRect", {
29987
31283
  Object.defineProperty(exports, "getLayoutSize", {
29988
31284
  enumerable: true,
29989
31285
  get: function() {
29990
- return getLayoutSize;
31286
+ return getLayoutSize$1;
29991
31287
  }
29992
31288
  });
29993
31289
  Object.defineProperty(exports, "getMountStats", {
@@ -30008,6 +31304,12 @@ Object.defineProperty(exports, "getPresetWithMode", {
30008
31304
  return getPresetWithMode;
30009
31305
  }
30010
31306
  });
31307
+ Object.defineProperty(exports, "getProgressRatio", {
31308
+ enumerable: true,
31309
+ get: function() {
31310
+ return getProgressRatio;
31311
+ }
31312
+ });
30011
31313
  Object.defineProperty(exports, "getRenderContext", {
30012
31314
  enumerable: true,
30013
31315
  get: function() {
@@ -30242,6 +31544,12 @@ Object.defineProperty(exports, "remountAll", {
30242
31544
  return remountAll;
30243
31545
  }
30244
31546
  });
31547
+ Object.defineProperty(exports, "resolveBadgeTextStyle", {
31548
+ enumerable: true,
31549
+ get: function() {
31550
+ return resolveBadgeTextStyle;
31551
+ }
31552
+ });
30245
31553
  Object.defineProperty(exports, "resolveEffect", {
30246
31554
  enumerable: true,
30247
31555
  get: function() {
@@ -30458,6 +31766,12 @@ Object.defineProperty(exports, "useTheme", {
30458
31766
  return useTheme;
30459
31767
  }
30460
31768
  });
31769
+ Object.defineProperty(exports, "useThemeTokens", {
31770
+ enumerable: true,
31771
+ get: function() {
31772
+ return useThemeTokens;
31773
+ }
31774
+ });
30461
31775
  Object.defineProperty(exports, "useViewportSize", {
30462
31776
  enumerable: true,
30463
31777
  get: function() {
@@ -30495,4 +31809,4 @@ Object.defineProperty(exports, "withHooks", {
30495
31809
  }
30496
31810
  });
30497
31811
 
30498
- //# sourceMappingURL=custom-Dp3yAJdU.cjs.map
31812
+ //# sourceMappingURL=custom-37gL0VZG.cjs.map