@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.
- package/README.md +14 -1
- package/dist/clip/index.cjs +7 -695
- package/dist/clip/index.js +1 -687
- package/dist/clip/stencil-clip-depth.d.ts +10 -0
- package/dist/clip/stencil-clip-depth.d.ts.map +1 -0
- package/dist/clip/stencil-clip-fbo-bridge.d.ts +7 -0
- package/dist/clip/stencil-clip-fbo-bridge.d.ts.map +1 -0
- package/dist/clip/stencil-clip-renderer.d.ts +7 -0
- package/dist/clip/stencil-clip-renderer.d.ts.map +1 -0
- package/dist/clip/stencil-clip-state.d.ts +28 -0
- package/dist/clip/stencil-clip-state.d.ts.map +1 -0
- package/dist/clip/stencil-clip-types.d.ts +67 -0
- package/dist/clip/stencil-clip-types.d.ts.map +1 -0
- package/dist/clip/stencil-clip.d.ts +3 -84
- package/dist/clip/stencil-clip.d.ts.map +1 -1
- package/dist/clip-CHmjztBQ.cjs +705 -0
- package/dist/clip-CHmjztBQ.cjs.map +1 -0
- package/dist/clip-CPufWCSD.js +668 -0
- package/dist/clip-CPufWCSD.js.map +1 -0
- package/dist/components/appliers/applyParticles.d.ts.map +1 -1
- package/dist/components/custom/Badge.d.ts +73 -0
- package/dist/components/custom/Badge.d.ts.map +1 -0
- package/dist/components/custom/Checkbox.d.ts +41 -0
- package/dist/components/custom/Checkbox.d.ts.map +1 -0
- package/dist/components/custom/DebugPanel.d.ts +30 -0
- package/dist/components/custom/DebugPanel.d.ts.map +1 -0
- package/dist/components/custom/Particles.d.ts +14 -3
- package/dist/components/custom/Particles.d.ts.map +1 -1
- package/dist/components/custom/Popover.d.ts +89 -0
- package/dist/components/custom/Popover.d.ts.map +1 -0
- package/dist/components/custom/ProgressBar.d.ts +52 -0
- package/dist/components/custom/ProgressBar.d.ts.map +1 -0
- package/dist/components/custom/Toggle.d.ts.map +1 -1
- package/dist/components/custom/index.cjs +15 -1
- package/dist/components/custom/index.d.ts +5 -0
- package/dist/components/custom/index.d.ts.map +1 -1
- package/dist/components/custom/index.js +2 -2
- package/dist/components/index.d.ts +5 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/primitives/graphics.d.ts +2 -2
- package/dist/components/primitives/particles.d.ts +14 -4
- package/dist/components/primitives/particles.d.ts.map +1 -1
- package/dist/components/primitives/tilesprite.d.ts +15 -19
- package/dist/components/primitives/tilesprite.d.ts.map +1 -1
- package/dist/{custom-Dp3yAJdU.cjs → custom-37gL0VZG.cjs} +1578 -264
- package/dist/custom-37gL0VZG.cjs.map +1 -0
- package/dist/{custom-C_w8D39m.js → custom-DMZASXll.js} +1455 -231
- package/dist/custom-DMZASXll.js.map +1 -0
- package/dist/gestures/gesture-manager.d.ts +1 -1
- package/dist/index.cjs +49 -111
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +29 -105
- package/dist/index.js.map +1 -1
- package/dist/particles/emit-zone.d.ts +34 -12
- package/dist/particles/emit-zone.d.ts.map +1 -1
- package/dist/particles/index.d.ts +1 -1
- package/dist/particles/index.d.ts.map +1 -1
- package/dist/particles/use-particles.d.ts +6 -2
- package/dist/particles/use-particles.d.ts.map +1 -1
- package/dist/theme-custom.d.ts +68 -0
- package/dist/theme-custom.d.ts.map +1 -1
- package/dist/theme-defaults.d.ts.map +1 -1
- package/package.json +3 -2
- package/dist/clip/index.cjs.map +0 -1
- package/dist/clip/index.js.map +0 -1
- package/dist/custom-C_w8D39m.js.map +0 -1
- package/dist/custom-Dp3yAJdU.cjs.map +0 -1
|
@@ -570,9 +570,6 @@ var nineSlicePatcher = (node, prev, next) => {
|
|
|
570
570
|
};
|
|
571
571
|
//#endregion
|
|
572
572
|
//#region src/particles/emit-zone.ts
|
|
573
|
-
/**
|
|
574
|
-
* Emit zone helpers for particle emitters
|
|
575
|
-
*/
|
|
576
573
|
function resolveNumericSize(value) {
|
|
577
574
|
return typeof value === "number" ? value : void 0;
|
|
578
575
|
}
|
|
@@ -584,18 +581,164 @@ function resolveZoneSize(zone, fallback) {
|
|
|
584
581
|
if (height !== void 0) size.height = height;
|
|
585
582
|
return size;
|
|
586
583
|
}
|
|
584
|
+
function withPoint(point, x, y) {
|
|
585
|
+
if (point) {
|
|
586
|
+
point.x = x;
|
|
587
|
+
point.y = y;
|
|
588
|
+
return point;
|
|
589
|
+
}
|
|
590
|
+
return {
|
|
591
|
+
x,
|
|
592
|
+
y
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
function createRectSource(x, y, width, height) {
|
|
596
|
+
return {
|
|
597
|
+
x,
|
|
598
|
+
y,
|
|
599
|
+
width,
|
|
600
|
+
height,
|
|
601
|
+
contains: (px, py) => px >= x && px <= x + width && py >= y && py <= y + height,
|
|
602
|
+
getRandomPoint: (point) => withPoint(point, x + Math.random() * width, y + Math.random() * height),
|
|
603
|
+
getPoints: (quantity = 1) => {
|
|
604
|
+
const count = Math.max(1, quantity);
|
|
605
|
+
return Array.from({ length: count }, (_, index) => {
|
|
606
|
+
const distance = (count === 1 ? 0 : index / (count - 1)) * (2 * (width + height));
|
|
607
|
+
if (distance <= width) return {
|
|
608
|
+
x: x + distance,
|
|
609
|
+
y
|
|
610
|
+
};
|
|
611
|
+
if (distance <= width + height) return {
|
|
612
|
+
x: x + width,
|
|
613
|
+
y: y + distance - width
|
|
614
|
+
};
|
|
615
|
+
if (distance <= width * 2 + height) return {
|
|
616
|
+
x: x + width - (distance - width - height),
|
|
617
|
+
y: y + height
|
|
618
|
+
};
|
|
619
|
+
return {
|
|
620
|
+
x,
|
|
621
|
+
y: y + height - (distance - width * 2 - height)
|
|
622
|
+
};
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
function createCircleSource(x, y, radius) {
|
|
628
|
+
return {
|
|
629
|
+
x,
|
|
630
|
+
y,
|
|
631
|
+
radius,
|
|
632
|
+
contains: (px, py) => {
|
|
633
|
+
const dx = px - x;
|
|
634
|
+
const dy = py - y;
|
|
635
|
+
return dx * dx + dy * dy <= radius * radius;
|
|
636
|
+
},
|
|
637
|
+
getRandomPoint: (point) => {
|
|
638
|
+
const angle = Math.random() * Math.PI * 2;
|
|
639
|
+
const distance = Math.sqrt(Math.random()) * radius;
|
|
640
|
+
return withPoint(point, x + Math.cos(angle) * distance, y + Math.sin(angle) * distance);
|
|
641
|
+
},
|
|
642
|
+
getPoints: (quantity = 1) => {
|
|
643
|
+
const count = Math.max(1, quantity);
|
|
644
|
+
return Array.from({ length: count }, (_, index) => {
|
|
645
|
+
const angle = index / count * Math.PI * 2;
|
|
646
|
+
return {
|
|
647
|
+
x: x + Math.cos(angle) * radius,
|
|
648
|
+
y: y + Math.sin(angle) * radius
|
|
649
|
+
};
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
function createEllipseSource(x, y, width, height) {
|
|
655
|
+
const radiusX = width / 2;
|
|
656
|
+
const radiusY = height / 2;
|
|
657
|
+
return {
|
|
658
|
+
x,
|
|
659
|
+
y,
|
|
660
|
+
width,
|
|
661
|
+
height,
|
|
662
|
+
contains: (px, py) => {
|
|
663
|
+
const dx = (px - x) / radiusX;
|
|
664
|
+
const dy = (py - y) / radiusY;
|
|
665
|
+
return dx * dx + dy * dy <= 1;
|
|
666
|
+
},
|
|
667
|
+
getRandomPoint: (point) => {
|
|
668
|
+
const angle = Math.random() * Math.PI * 2;
|
|
669
|
+
const distance = Math.sqrt(Math.random());
|
|
670
|
+
return withPoint(point, x + Math.cos(angle) * radiusX * distance, y + Math.sin(angle) * radiusY * distance);
|
|
671
|
+
},
|
|
672
|
+
getPoints: (quantity = 1) => {
|
|
673
|
+
const count = Math.max(1, quantity);
|
|
674
|
+
return Array.from({ length: count }, (_, index) => {
|
|
675
|
+
const angle = index / count * Math.PI * 2;
|
|
676
|
+
return {
|
|
677
|
+
x: x + Math.cos(angle) * radiusX,
|
|
678
|
+
y: y + Math.sin(angle) * radiusY
|
|
679
|
+
};
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
function createLineSource(x, y, endX, endY) {
|
|
685
|
+
return {
|
|
686
|
+
x,
|
|
687
|
+
y,
|
|
688
|
+
contains: (px, py) => {
|
|
689
|
+
const lengthSquared = (endX - x) ** 2 + (endY - y) ** 2;
|
|
690
|
+
if (lengthSquared === 0) return px === x && py === y;
|
|
691
|
+
const progress = Math.max(0, Math.min(1, ((px - x) * (endX - x) + (py - y) * (endY - y)) / lengthSquared));
|
|
692
|
+
const closestX = x + progress * (endX - x);
|
|
693
|
+
const closestY = y + progress * (endY - y);
|
|
694
|
+
return Math.hypot(px - closestX, py - closestY) <= .5;
|
|
695
|
+
},
|
|
696
|
+
getRandomPoint: (point) => {
|
|
697
|
+
const progress = Math.random();
|
|
698
|
+
return withPoint(point, x + (endX - x) * progress, y + (endY - y) * progress);
|
|
699
|
+
},
|
|
700
|
+
getPoints: (quantity = 1) => {
|
|
701
|
+
const count = Math.max(1, quantity);
|
|
702
|
+
return Array.from({ length: count }, (_, index) => {
|
|
703
|
+
const progress = count === 1 ? 0 : index / (count - 1);
|
|
704
|
+
return {
|
|
705
|
+
x: x + (endX - x) * progress,
|
|
706
|
+
y: y + (endY - y) * progress
|
|
707
|
+
};
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
}
|
|
587
712
|
function buildZoneSource(zone, fallbackSize) {
|
|
588
713
|
const baseX = zone.x ?? 0;
|
|
589
714
|
const baseY = zone.y ?? 0;
|
|
590
715
|
const { width, height } = resolveZoneSize(zone, fallbackSize);
|
|
591
716
|
switch (zone.shape) {
|
|
592
|
-
case "rect": return
|
|
593
|
-
case "circle": return
|
|
594
|
-
case "ellipse": return
|
|
595
|
-
case "line": return
|
|
717
|
+
case "rect": return createRectSource(baseX, baseY, width ?? 1, height ?? 1);
|
|
718
|
+
case "circle": return createCircleSource(baseX, baseY, zone.radius ?? 1);
|
|
719
|
+
case "ellipse": return createEllipseSource(baseX, baseY, width ?? 1, height ?? 1);
|
|
720
|
+
case "line": return createLineSource(baseX, baseY, zone.endX ?? baseX + (width ?? 1), zone.endY ?? baseY + (height ?? 1));
|
|
596
721
|
default: return;
|
|
597
722
|
}
|
|
598
723
|
}
|
|
724
|
+
function getTransformOwner(value) {
|
|
725
|
+
if (!value || typeof value !== "object") return void 0;
|
|
726
|
+
if (typeof value.getWorldTransformMatrix !== "function") return;
|
|
727
|
+
return value;
|
|
728
|
+
}
|
|
729
|
+
function createLocalDeathZoneSource(source, owner) {
|
|
730
|
+
const transformOwner = getTransformOwner(owner);
|
|
731
|
+
if (!transformOwner) return source;
|
|
732
|
+
return {
|
|
733
|
+
...source,
|
|
734
|
+
contains: (worldX, worldY) => {
|
|
735
|
+
const matrix = transformOwner.getWorldTransformMatrix?.();
|
|
736
|
+
if (!matrix) return source.contains(worldX, worldY);
|
|
737
|
+
const localPoint = matrix.applyInverse(worldX, worldY);
|
|
738
|
+
return source.contains(localPoint.x, localPoint.y);
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
}
|
|
599
742
|
/**
|
|
600
743
|
* Build a Phaser emitZone config from a lightweight zone definition
|
|
601
744
|
*/
|
|
@@ -620,21 +763,21 @@ function buildEmitZoneFromLayout(zone, width, height) {
|
|
|
620
763
|
return buildEmitZone(zone, fallback);
|
|
621
764
|
}
|
|
622
765
|
/**
|
|
623
|
-
* Build a Phaser deathZone config from a lightweight
|
|
766
|
+
* Build a Phaser deathZone config from a lightweight death zone definition
|
|
624
767
|
*/
|
|
625
|
-
function buildDeathZone(zone, fallbackSize = {}) {
|
|
768
|
+
function buildDeathZone(zone, fallbackSize = {}, owner) {
|
|
626
769
|
const type = zone.mode ?? "onEnter";
|
|
627
770
|
const source = buildZoneSource(zone, fallbackSize);
|
|
628
771
|
if (!source) return void 0;
|
|
629
772
|
return {
|
|
630
773
|
type,
|
|
631
|
-
source
|
|
774
|
+
source: createLocalDeathZoneSource(source, owner)
|
|
632
775
|
};
|
|
633
776
|
}
|
|
634
777
|
/**
|
|
635
778
|
* Create death zones using layout size as a fallback
|
|
636
779
|
*/
|
|
637
|
-
function buildDeathZonesFromLayout(zones, width, height) {
|
|
780
|
+
function buildDeathZonesFromLayout(zones, width, height, owner) {
|
|
638
781
|
if (!zones) return void 0;
|
|
639
782
|
const list = Array.isArray(zones) ? zones : [zones];
|
|
640
783
|
const fallback = {};
|
|
@@ -642,7 +785,7 @@ function buildDeathZonesFromLayout(zones, width, height) {
|
|
|
642
785
|
const resolvedHeight = resolveNumericSize(height);
|
|
643
786
|
if (resolvedWidth !== void 0) fallback.width = resolvedWidth;
|
|
644
787
|
if (resolvedHeight !== void 0) fallback.height = resolvedHeight;
|
|
645
|
-
const deathZones = list.map((zone) => buildDeathZone(zone, fallback)).filter((zone) => Boolean(zone));
|
|
788
|
+
const deathZones = list.map((zone) => buildDeathZone(zone, fallback, owner)).filter((zone) => Boolean(zone));
|
|
646
789
|
return deathZones.length > 0 ? deathZones : void 0;
|
|
647
790
|
}
|
|
648
791
|
//#endregion
|
|
@@ -833,7 +976,7 @@ function mergeDeathZones(base, extra) {
|
|
|
833
976
|
function applyParticlesProps(manager, prev, next) {
|
|
834
977
|
if (!manager) return;
|
|
835
978
|
if ((prev.texture !== next.texture || prev.frame !== next.frame) && next.texture && "setTexture" in manager && manager.setTexture) manager.setTexture(next.texture, next.frame);
|
|
836
|
-
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) {
|
|
979
|
+
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) {
|
|
837
980
|
const resolvedConfig = resolveParticlePreset(next.preset, next.config);
|
|
838
981
|
let emitter;
|
|
839
982
|
if (isParticleEmitter(manager)) emitter = manager;
|
|
@@ -845,11 +988,13 @@ function applyParticlesProps(manager, prev, next) {
|
|
|
845
988
|
}
|
|
846
989
|
if (!emitter) return;
|
|
847
990
|
applyEmitterConfig(emitter, resolvedConfig);
|
|
848
|
-
|
|
849
|
-
|
|
991
|
+
const emitZoneProps = next.emitZone ?? next.zone;
|
|
992
|
+
const deathZoneProps = next.deathZones ?? next.excludeZones;
|
|
993
|
+
if (emitZoneProps) {
|
|
994
|
+
const emitZone = buildEmitZoneFromLayout(emitZoneProps, next.width, next.height);
|
|
850
995
|
if (emitZone) applyEmitZone(emitter, emitZone);
|
|
851
996
|
}
|
|
852
|
-
const deathZones = buildDeathZonesFromLayout(
|
|
997
|
+
const deathZones = buildDeathZonesFromLayout(deathZoneProps, next.width, next.height, manager);
|
|
853
998
|
const combined = mergeDeathZones(resolvedConfig.deathZone, deathZones);
|
|
854
999
|
applyDeathZone(emitter, combined);
|
|
855
1000
|
}
|
|
@@ -885,8 +1030,10 @@ function createParticlesLayout(particles, props) {
|
|
|
885
1030
|
*/
|
|
886
1031
|
var particlesCreator = (scene, props) => {
|
|
887
1032
|
const resolvedConfig = { ...resolveParticlePreset(props.preset, props.config) };
|
|
888
|
-
|
|
889
|
-
|
|
1033
|
+
const emitZoneProps = props.emitZone ?? props.zone;
|
|
1034
|
+
const deathZoneProps = props.deathZones ?? props.excludeZones;
|
|
1035
|
+
if (emitZoneProps) {
|
|
1036
|
+
const emitZone = buildEmitZoneFromLayout(emitZoneProps, props.width, props.height);
|
|
890
1037
|
if (emitZone) {
|
|
891
1038
|
const configWithZone = resolvedConfig;
|
|
892
1039
|
configWithZone.emitZone = emitZone;
|
|
@@ -904,8 +1051,8 @@ var particlesCreator = (scene, props) => {
|
|
|
904
1051
|
createTransform(particles, props);
|
|
905
1052
|
createPhaser(particles, props);
|
|
906
1053
|
createParticlesLayout(particles, props);
|
|
907
|
-
if (
|
|
908
|
-
const deathZones = buildDeathZonesFromLayout(
|
|
1054
|
+
if (deathZoneProps && emitter) {
|
|
1055
|
+
const deathZones = buildDeathZonesFromLayout(deathZoneProps, props.width, props.height, particles);
|
|
909
1056
|
const combinedDeathZones = mergeDeathZones(resolvedConfig.deathZone, deathZones);
|
|
910
1057
|
if (combinedDeathZones) applyDeathZone(emitter, combinedDeathZones);
|
|
911
1058
|
}
|
|
@@ -16557,18 +16704,54 @@ var textPatcher = (node, prev, next) => {
|
|
|
16557
16704
|
//#endregion
|
|
16558
16705
|
//#region src/components/primitives/tilesprite.ts
|
|
16559
16706
|
/**
|
|
16560
|
-
*
|
|
16561
|
-
* @throws Error indicating component is not implemented
|
|
16707
|
+
* Creates layout infrastructure for TileSprite.
|
|
16562
16708
|
*/
|
|
16563
|
-
|
|
16564
|
-
|
|
16709
|
+
function createTileSpriteLayout(tileSprite, props) {
|
|
16710
|
+
tileSprite.__layoutProps = props;
|
|
16711
|
+
tileSprite.__getLayoutSize = () => {
|
|
16712
|
+
if (tileSprite.__layoutProps?.headless) return {
|
|
16713
|
+
width: .01,
|
|
16714
|
+
height: .01
|
|
16715
|
+
};
|
|
16716
|
+
return {
|
|
16717
|
+
width: tileSprite.width,
|
|
16718
|
+
height: tileSprite.height
|
|
16719
|
+
};
|
|
16720
|
+
};
|
|
16721
|
+
}
|
|
16722
|
+
function applyTileSpriteProps(tileSprite, prev, next) {
|
|
16723
|
+
if ((prev.texture !== next.texture || prev.frame !== next.frame) && next.texture) tileSprite.setTexture(next.texture, next.frame);
|
|
16724
|
+
if ((prev.width !== next.width || prev.height !== next.height) && typeof next.width === "number" && typeof next.height === "number") tileSprite.setSize(next.width, next.height);
|
|
16725
|
+
if (prev.tilePositionX !== next.tilePositionX && typeof next.tilePositionX === "number") tileSprite.tilePositionX = next.tilePositionX;
|
|
16726
|
+
if (prev.tilePositionY !== next.tilePositionY && typeof next.tilePositionY === "number") tileSprite.tilePositionY = next.tilePositionY;
|
|
16727
|
+
if (prev.tileScaleX !== next.tileScaleX && typeof next.tileScaleX === "number") tileSprite.tileScaleX = next.tileScaleX;
|
|
16728
|
+
if (prev.tileScaleY !== next.tileScaleY && typeof next.tileScaleY === "number") tileSprite.tileScaleY = next.tileScaleY;
|
|
16729
|
+
if (prev.tint !== next.tint) if (typeof next.tint === "number") tileSprite.setTint(next.tint);
|
|
16730
|
+
else tileSprite.clearTint();
|
|
16731
|
+
if (prev.originX !== next.originX || prev.originY !== next.originY) tileSprite.setOrigin(next.originX ?? tileSprite.originX, next.originY ?? tileSprite.originY);
|
|
16732
|
+
}
|
|
16733
|
+
/**
|
|
16734
|
+
* TileSprite creator - creates a Phaser TileSprite object.
|
|
16735
|
+
*/
|
|
16736
|
+
var tileSpriteCreator = (scene, props) => {
|
|
16737
|
+
const tileSprite = scene.add.tileSprite(props.x ?? 0, props.y ?? 0, props.width, props.height, props.texture, props.frame);
|
|
16738
|
+
tileSprite.setOrigin(props.originX ?? 0, props.originY ?? 0);
|
|
16739
|
+
createTransform(tileSprite, props);
|
|
16740
|
+
createPhaser(tileSprite, props);
|
|
16741
|
+
applyTileSpriteProps(tileSprite, {}, props);
|
|
16742
|
+
createTileSpriteLayout(tileSprite, props);
|
|
16743
|
+
props.onReady?.(tileSprite);
|
|
16744
|
+
return tileSprite;
|
|
16565
16745
|
};
|
|
16566
16746
|
/**
|
|
16567
|
-
* TileSprite patcher -
|
|
16568
|
-
* @throws Error indicating component is not implemented
|
|
16747
|
+
* TileSprite patcher - updates texture, size, tiling and shared display props.
|
|
16569
16748
|
*/
|
|
16570
|
-
var tileSpritePatcher = (
|
|
16571
|
-
|
|
16749
|
+
var tileSpritePatcher = (node, prev, next) => {
|
|
16750
|
+
applyTransformProps(node, prev, next);
|
|
16751
|
+
applyPhaserProps(node, prev, next);
|
|
16752
|
+
applyTileSpriteProps(node, prev, next);
|
|
16753
|
+
const tileSprite = node;
|
|
16754
|
+
if (tileSprite.__layoutProps) tileSprite.__layoutProps = next;
|
|
16572
16755
|
};
|
|
16573
16756
|
//#endregion
|
|
16574
16757
|
//#region src/components/backgroundImage.ts
|
|
@@ -16948,7 +17131,7 @@ var GestureManager = class {
|
|
|
16948
17131
|
/**
|
|
16949
17132
|
* Handle global pointer down event
|
|
16950
17133
|
* Registers all containers that were hit for move event tracking
|
|
16951
|
-
* Only the topmost gets touch/
|
|
17134
|
+
* Only the topmost gets touch/long-press callbacks
|
|
16952
17135
|
*/
|
|
16953
17136
|
handlePointerDown(pointer) {
|
|
16954
17137
|
const hitContainers = /* @__PURE__ */ new Set();
|
|
@@ -19812,6 +19995,91 @@ function buildDefaultTheme(colors) {
|
|
|
19812
19995
|
fontSize: "14px"
|
|
19813
19996
|
}
|
|
19814
19997
|
},
|
|
19998
|
+
Checkbox: {
|
|
19999
|
+
checkedColor: colors.primary.DEFAULT.toNumber(),
|
|
20000
|
+
indeterminateColor: colors.primary.medium.toNumber(),
|
|
20001
|
+
color: colors.border.medium.toNumber(),
|
|
20002
|
+
gap: 10,
|
|
20003
|
+
size: 20,
|
|
20004
|
+
disabledAlpha: .5,
|
|
20005
|
+
labelPosition: "right",
|
|
20006
|
+
labelStyle: {
|
|
20007
|
+
color: colors.text.DEFAULT.toString(),
|
|
20008
|
+
fontSize: "14px"
|
|
20009
|
+
}
|
|
20010
|
+
},
|
|
20011
|
+
Badge: {
|
|
20012
|
+
tone: "neutral",
|
|
20013
|
+
variant: "solid",
|
|
20014
|
+
size: "medium",
|
|
20015
|
+
maxCount: 99,
|
|
20016
|
+
disabledAlpha: .5,
|
|
20017
|
+
textStyle: { fontStyle: "bold" }
|
|
20018
|
+
},
|
|
20019
|
+
Tag: {
|
|
20020
|
+
tone: "neutral",
|
|
20021
|
+
variant: "soft",
|
|
20022
|
+
size: "medium",
|
|
20023
|
+
closeSize: 16,
|
|
20024
|
+
disabledAlpha: .5,
|
|
20025
|
+
textStyle: { fontStyle: "bold" }
|
|
20026
|
+
},
|
|
20027
|
+
Popover: {
|
|
20028
|
+
placement: "bottom",
|
|
20029
|
+
offset: 8,
|
|
20030
|
+
depth: 1100,
|
|
20031
|
+
closeOnOutside: true,
|
|
20032
|
+
closeOnEscape: true,
|
|
20033
|
+
viewportPadding: 8,
|
|
20034
|
+
backgroundColor: colors.surface.dark.toNumber(),
|
|
20035
|
+
borderColor: colors.border.medium.toNumber(),
|
|
20036
|
+
borderWidth: 1,
|
|
20037
|
+
cornerRadius: 8,
|
|
20038
|
+
padding: 10,
|
|
20039
|
+
gap: 8
|
|
20040
|
+
},
|
|
20041
|
+
ContextMenu: {
|
|
20042
|
+
width: 220,
|
|
20043
|
+
itemHeight: 34,
|
|
20044
|
+
itemGap: 8,
|
|
20045
|
+
itemPadding: {
|
|
20046
|
+
left: 10,
|
|
20047
|
+
right: 10,
|
|
20048
|
+
top: 6,
|
|
20049
|
+
bottom: 6
|
|
20050
|
+
},
|
|
20051
|
+
itemCornerRadius: 5,
|
|
20052
|
+
backgroundColor: colors.surface.dark.toNumber(),
|
|
20053
|
+
borderColor: colors.border.medium.toNumber(),
|
|
20054
|
+
borderWidth: 1,
|
|
20055
|
+
cornerRadius: 8,
|
|
20056
|
+
padding: 6,
|
|
20057
|
+
gap: 2,
|
|
20058
|
+
textStyle: {
|
|
20059
|
+
...textStyles.small,
|
|
20060
|
+
color: colors.text.medium.toString()
|
|
20061
|
+
},
|
|
20062
|
+
disabledTextColor: colors.text.lightest.toString(),
|
|
20063
|
+
dangerTextColor: colors.error.darkest.toString(),
|
|
20064
|
+
dangerBackgroundColor: colors.error.dark.toNumber()
|
|
20065
|
+
},
|
|
20066
|
+
ProgressBar: {
|
|
20067
|
+
width: 240,
|
|
20068
|
+
height: 22,
|
|
20069
|
+
orientation: "horizontal",
|
|
20070
|
+
labelPosition: "right",
|
|
20071
|
+
trackColor: colors.surface.dark.toNumber(),
|
|
20072
|
+
fillColor: colors.success.DEFAULT.toNumber(),
|
|
20073
|
+
borderColor: colors.border.medium.toNumber(),
|
|
20074
|
+
borderWidth: 1,
|
|
20075
|
+
cornerRadius: 11,
|
|
20076
|
+
gap: 8,
|
|
20077
|
+
disabledAlpha: .5,
|
|
20078
|
+
labelStyle: {
|
|
20079
|
+
color: colors.text.DEFAULT.toString(),
|
|
20080
|
+
fontSize: "13px"
|
|
20081
|
+
}
|
|
20082
|
+
},
|
|
19815
20083
|
ScrollSlider: {
|
|
19816
20084
|
borderColor: colors.border.dark.toNumber(),
|
|
19817
20085
|
trackColor: colors.surface.dark.toNumber(),
|
|
@@ -20624,7 +20892,7 @@ function useViewportSize() {
|
|
|
20624
20892
|
* @param container - Phaser container with layout
|
|
20625
20893
|
* @returns Layout size or undefined if container has no layout
|
|
20626
20894
|
*/
|
|
20627
|
-
function getLayoutSize(container) {
|
|
20895
|
+
function getLayoutSize$1(container) {
|
|
20628
20896
|
if (!container) return void 0;
|
|
20629
20897
|
return container.__getLayoutSize?.();
|
|
20630
20898
|
}
|
|
@@ -20636,7 +20904,7 @@ function getLayoutSize(container) {
|
|
|
20636
20904
|
* @returns Current layout size or undefined
|
|
20637
20905
|
*/
|
|
20638
20906
|
function useLayoutSize(ref) {
|
|
20639
|
-
return getLayoutSize(ref.current);
|
|
20907
|
+
return getLayoutSize$1(ref.current);
|
|
20640
20908
|
}
|
|
20641
20909
|
/**
|
|
20642
20910
|
* Utility function to get layout props from a container
|
|
@@ -20677,7 +20945,7 @@ function useBackgroundGraphics(ref) {
|
|
|
20677
20945
|
*/
|
|
20678
20946
|
function getLayoutRect(container) {
|
|
20679
20947
|
if (!container) return void 0;
|
|
20680
|
-
const size = getLayoutSize(container);
|
|
20948
|
+
const size = getLayoutSize$1(container);
|
|
20681
20949
|
if (!size) return void 0;
|
|
20682
20950
|
return {
|
|
20683
20951
|
x: container.x,
|
|
@@ -20710,7 +20978,7 @@ function useLayoutRect(ref) {
|
|
|
20710
20978
|
*/
|
|
20711
20979
|
function getWorldLayoutRect(container) {
|
|
20712
20980
|
if (!container) return void 0;
|
|
20713
|
-
const size = getLayoutSize(container);
|
|
20981
|
+
const size = getLayoutSize$1(container);
|
|
20714
20982
|
if (!size) return void 0;
|
|
20715
20983
|
const matrix = container.getWorldTransformMatrix();
|
|
20716
20984
|
return {
|
|
@@ -22766,6 +23034,241 @@ var viewPatcher = (node, prev, next) => {
|
|
|
22766
23034
|
applyLayoutProps(container, normalizedPrev, normalizedNext);
|
|
22767
23035
|
};
|
|
22768
23036
|
//#endregion
|
|
23037
|
+
//#region src/components/custom/Badge.tsx
|
|
23038
|
+
/** @jsxImportSource ../.. */
|
|
23039
|
+
/**
|
|
23040
|
+
* Badge and Tag components - compact labels for counts, status, filters, and inventory metadata.
|
|
23041
|
+
*/
|
|
23042
|
+
var DEFAULT_TONES = {
|
|
23043
|
+
neutral: {
|
|
23044
|
+
backgroundColor: 4674921,
|
|
23045
|
+
softBackgroundColor: 1976635,
|
|
23046
|
+
borderColor: 6583435,
|
|
23047
|
+
textColor: "#ffffff",
|
|
23048
|
+
outlineTextColor: "#cbd5e1"
|
|
23049
|
+
},
|
|
23050
|
+
primary: {
|
|
23051
|
+
backgroundColor: 2450411,
|
|
23052
|
+
softBackgroundColor: 1981066,
|
|
23053
|
+
borderColor: 6333946,
|
|
23054
|
+
textColor: "#ffffff",
|
|
23055
|
+
outlineTextColor: "#93c5fd"
|
|
23056
|
+
},
|
|
23057
|
+
success: {
|
|
23058
|
+
backgroundColor: 1483594,
|
|
23059
|
+
softBackgroundColor: 1332013,
|
|
23060
|
+
borderColor: 4906624,
|
|
23061
|
+
textColor: "#ffffff",
|
|
23062
|
+
outlineTextColor: "#86efac"
|
|
23063
|
+
},
|
|
23064
|
+
warning: {
|
|
23065
|
+
backgroundColor: 16096779,
|
|
23066
|
+
softBackgroundColor: 7877903,
|
|
23067
|
+
borderColor: 16498468,
|
|
23068
|
+
textColor: "#111827",
|
|
23069
|
+
outlineTextColor: "#fde68a"
|
|
23070
|
+
},
|
|
23071
|
+
danger: {
|
|
23072
|
+
backgroundColor: 14427686,
|
|
23073
|
+
softBackgroundColor: 8330525,
|
|
23074
|
+
borderColor: 16281969,
|
|
23075
|
+
textColor: "#ffffff",
|
|
23076
|
+
outlineTextColor: "#fecaca"
|
|
23077
|
+
},
|
|
23078
|
+
info: {
|
|
23079
|
+
backgroundColor: 561586,
|
|
23080
|
+
softBackgroundColor: 1461859,
|
|
23081
|
+
borderColor: 2282478,
|
|
23082
|
+
textColor: "#ffffff",
|
|
23083
|
+
outlineTextColor: "#a5f3fc"
|
|
23084
|
+
}
|
|
23085
|
+
};
|
|
23086
|
+
var DEFAULT_SIZES = {
|
|
23087
|
+
small: {
|
|
23088
|
+
height: 20,
|
|
23089
|
+
padding: {
|
|
23090
|
+
left: 7,
|
|
23091
|
+
right: 7,
|
|
23092
|
+
top: 2,
|
|
23093
|
+
bottom: 2
|
|
23094
|
+
},
|
|
23095
|
+
fontSize: 11,
|
|
23096
|
+
cornerRadius: 10,
|
|
23097
|
+
gap: 5,
|
|
23098
|
+
dotSize: 8
|
|
23099
|
+
},
|
|
23100
|
+
medium: {
|
|
23101
|
+
height: 24,
|
|
23102
|
+
padding: {
|
|
23103
|
+
left: 9,
|
|
23104
|
+
right: 9,
|
|
23105
|
+
top: 3,
|
|
23106
|
+
bottom: 3
|
|
23107
|
+
},
|
|
23108
|
+
fontSize: 13,
|
|
23109
|
+
cornerRadius: 12,
|
|
23110
|
+
gap: 6,
|
|
23111
|
+
dotSize: 10
|
|
23112
|
+
},
|
|
23113
|
+
large: {
|
|
23114
|
+
height: 30,
|
|
23115
|
+
padding: {
|
|
23116
|
+
left: 12,
|
|
23117
|
+
right: 12,
|
|
23118
|
+
top: 4,
|
|
23119
|
+
bottom: 4
|
|
23120
|
+
},
|
|
23121
|
+
fontSize: 18,
|
|
23122
|
+
cornerRadius: 15,
|
|
23123
|
+
gap: 8,
|
|
23124
|
+
dotSize: 12
|
|
23125
|
+
}
|
|
23126
|
+
};
|
|
23127
|
+
function formatBadgeCount({ count, maxCount = 99 }) {
|
|
23128
|
+
if (!Number.isFinite(count)) return "0";
|
|
23129
|
+
const normalizedCount = Math.max(0, Math.floor(count ?? 0));
|
|
23130
|
+
const normalizedMax = Math.max(0, Math.floor(maxCount));
|
|
23131
|
+
return normalizedCount > normalizedMax ? `${normalizedMax}+` : `${normalizedCount}`;
|
|
23132
|
+
}
|
|
23133
|
+
function getBadgeText(props) {
|
|
23134
|
+
if (props.count !== void 0) return formatBadgeCount(props);
|
|
23135
|
+
if (props.label !== void 0) return `${props.label}`;
|
|
23136
|
+
return "";
|
|
23137
|
+
}
|
|
23138
|
+
function resolveBadgeColors(tone, variant) {
|
|
23139
|
+
const toneColors = DEFAULT_TONES[tone];
|
|
23140
|
+
if (variant === "outline") return {
|
|
23141
|
+
backgroundColor: 0,
|
|
23142
|
+
backgroundAlpha: 0,
|
|
23143
|
+
borderColor: toneColors.borderColor,
|
|
23144
|
+
borderWidth: 1,
|
|
23145
|
+
textColor: toneColors.outlineTextColor
|
|
23146
|
+
};
|
|
23147
|
+
if (variant === "soft") return {
|
|
23148
|
+
backgroundColor: toneColors.softBackgroundColor,
|
|
23149
|
+
backgroundAlpha: 1,
|
|
23150
|
+
borderColor: toneColors.borderColor,
|
|
23151
|
+
borderWidth: 1,
|
|
23152
|
+
textColor: toneColors.outlineTextColor
|
|
23153
|
+
};
|
|
23154
|
+
return {
|
|
23155
|
+
backgroundColor: toneColors.backgroundColor,
|
|
23156
|
+
backgroundAlpha: 1,
|
|
23157
|
+
borderColor: toneColors.borderColor,
|
|
23158
|
+
borderWidth: 0,
|
|
23159
|
+
textColor: toneColors.textColor
|
|
23160
|
+
};
|
|
23161
|
+
}
|
|
23162
|
+
function getBadgeSizeConfig(size) {
|
|
23163
|
+
return DEFAULT_SIZES[size];
|
|
23164
|
+
}
|
|
23165
|
+
function resolveBadgeTextStyle(options) {
|
|
23166
|
+
const sizeConfig = getBadgeSizeConfig(options.size);
|
|
23167
|
+
return {
|
|
23168
|
+
color: options.textColor,
|
|
23169
|
+
fontSize: `${sizeConfig.fontSize}px`,
|
|
23170
|
+
...options.themedTextStyle ?? {},
|
|
23171
|
+
...options.explicitTextStyle ?? {}
|
|
23172
|
+
};
|
|
23173
|
+
}
|
|
23174
|
+
function Badge(props) {
|
|
23175
|
+
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;
|
|
23176
|
+
const { props: themed, nestedTheme } = getThemedProps("Badge", useTheme(), theme ?? {});
|
|
23177
|
+
const tone = explicitTone ?? themed.tone ?? "neutral";
|
|
23178
|
+
const variant = explicitVariant ?? themed.variant ?? "solid";
|
|
23179
|
+
const size = explicitSize ?? themed.size ?? "medium";
|
|
23180
|
+
const sizeConfig = getBadgeSizeConfig(size);
|
|
23181
|
+
const colors = resolveBadgeColors(tone, variant);
|
|
23182
|
+
const disabledAlpha = explicitDisabledAlpha ?? themed.disabledAlpha ?? .5;
|
|
23183
|
+
const effectiveAlpha = disabled ? disabledAlpha : alpha;
|
|
23184
|
+
const resolvedMaxCount = maxCount ?? themed.maxCount ?? 99;
|
|
23185
|
+
const text = count !== void 0 ? formatBadgeCount({
|
|
23186
|
+
count,
|
|
23187
|
+
maxCount: resolvedMaxCount
|
|
23188
|
+
}) : label !== void 0 ? `${label}` : "";
|
|
23189
|
+
const resolvedTextStyle = resolveBadgeTextStyle({
|
|
23190
|
+
size,
|
|
23191
|
+
textColor: colors.textColor,
|
|
23192
|
+
themedTextStyle: themed.textStyle,
|
|
23193
|
+
explicitTextStyle
|
|
23194
|
+
});
|
|
23195
|
+
const dotSize = themed.dotSize ?? sizeConfig.dotSize;
|
|
23196
|
+
if (dot) return /* @__PURE__ */ jsx(View, {
|
|
23197
|
+
...viewProps,
|
|
23198
|
+
width: width ?? dotSize,
|
|
23199
|
+
height: height ?? dotSize,
|
|
23200
|
+
backgroundColor: backgroundColor ?? themed.backgroundColor ?? colors.backgroundColor,
|
|
23201
|
+
backgroundAlpha: backgroundAlpha ?? themed.backgroundAlpha ?? colors.backgroundAlpha,
|
|
23202
|
+
borderColor: borderColor ?? themed.borderColor ?? colors.borderColor,
|
|
23203
|
+
borderWidth: borderWidth ?? themed.borderWidth ?? colors.borderWidth,
|
|
23204
|
+
cornerRadius: cornerRadius ?? themed.cornerRadius ?? dotSize / 2,
|
|
23205
|
+
...effectiveAlpha !== void 0 ? { alpha: effectiveAlpha } : {},
|
|
23206
|
+
theme: nestedTheme
|
|
23207
|
+
});
|
|
23208
|
+
return /* @__PURE__ */ jsx(View, {
|
|
23209
|
+
...viewProps,
|
|
23210
|
+
width: width ?? themed.width ?? "auto",
|
|
23211
|
+
height: height ?? themed.height ?? sizeConfig.height,
|
|
23212
|
+
direction: "row",
|
|
23213
|
+
alignItems: "center",
|
|
23214
|
+
justifyContent: "center",
|
|
23215
|
+
gap: gap ?? themed.gap ?? sizeConfig.gap,
|
|
23216
|
+
padding: padding ?? themed.padding ?? sizeConfig.padding,
|
|
23217
|
+
backgroundColor: backgroundColor ?? themed.backgroundColor ?? colors.backgroundColor,
|
|
23218
|
+
backgroundAlpha: backgroundAlpha ?? themed.backgroundAlpha ?? colors.backgroundAlpha,
|
|
23219
|
+
borderColor: borderColor ?? themed.borderColor ?? colors.borderColor,
|
|
23220
|
+
borderWidth: borderWidth ?? themed.borderWidth ?? colors.borderWidth,
|
|
23221
|
+
cornerRadius: cornerRadius ?? themed.cornerRadius ?? sizeConfig.cornerRadius,
|
|
23222
|
+
...effectiveAlpha !== void 0 ? { alpha: effectiveAlpha } : {},
|
|
23223
|
+
theme: nestedTheme,
|
|
23224
|
+
children: children ?? /* @__PURE__ */ jsx(Text, {
|
|
23225
|
+
text,
|
|
23226
|
+
style: resolvedTextStyle
|
|
23227
|
+
})
|
|
23228
|
+
});
|
|
23229
|
+
}
|
|
23230
|
+
function Tag(props) {
|
|
23231
|
+
const { selected = false, onRemove, closeLabel = "x", tone, variant, size, theme, children, label, textStyle, ...badgeProps } = props;
|
|
23232
|
+
const { props: themed, nestedTheme } = getThemedProps("Tag", useTheme(), theme ?? {});
|
|
23233
|
+
const resolvedTone = tone ?? themed.tone ?? (selected ? "primary" : "neutral");
|
|
23234
|
+
const resolvedVariant = variant ?? themed.variant ?? (selected ? "solid" : "soft");
|
|
23235
|
+
const resolvedSize = size ?? themed.size ?? "medium";
|
|
23236
|
+
const resolvedTextStyle = resolveBadgeTextStyle({
|
|
23237
|
+
size: resolvedSize,
|
|
23238
|
+
textColor: resolveBadgeColors(resolvedTone, resolvedVariant).textColor,
|
|
23239
|
+
themedTextStyle: themed.textStyle,
|
|
23240
|
+
explicitTextStyle: textStyle
|
|
23241
|
+
});
|
|
23242
|
+
const text = label !== void 0 ? `${label}` : "";
|
|
23243
|
+
return /* @__PURE__ */ jsxs(Badge, {
|
|
23244
|
+
...badgeProps,
|
|
23245
|
+
tone: resolvedTone,
|
|
23246
|
+
variant: resolvedVariant,
|
|
23247
|
+
size: resolvedSize,
|
|
23248
|
+
textStyle: resolvedTextStyle,
|
|
23249
|
+
theme: nestedTheme,
|
|
23250
|
+
children: [
|
|
23251
|
+
label !== void 0 && /* @__PURE__ */ jsx(Text, {
|
|
23252
|
+
text,
|
|
23253
|
+
style: resolvedTextStyle
|
|
23254
|
+
}),
|
|
23255
|
+
children,
|
|
23256
|
+
onRemove && /* @__PURE__ */ jsx(Button, {
|
|
23257
|
+
width: themed.closeSize ?? 16,
|
|
23258
|
+
height: themed.closeSize ?? 16,
|
|
23259
|
+
padding: 0,
|
|
23260
|
+
cornerRadius: (themed.closeSize ?? 16) / 2,
|
|
23261
|
+
onClick: onRemove,
|
|
23262
|
+
theme: nestedTheme,
|
|
23263
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
23264
|
+
text: closeLabel,
|
|
23265
|
+
style: resolvedTextStyle
|
|
23266
|
+
})
|
|
23267
|
+
})
|
|
23268
|
+
]
|
|
23269
|
+
});
|
|
23270
|
+
}
|
|
23271
|
+
//#endregion
|
|
22769
23272
|
//#region src/effects/use-effect.ts
|
|
22770
23273
|
/**
|
|
22771
23274
|
* Custom hook for Phaser game object effects (shake, pulse, etc.)
|
|
@@ -23748,83 +24251,437 @@ function Button(props) {
|
|
|
23748
24251
|
});
|
|
23749
24252
|
}
|
|
23750
24253
|
//#endregion
|
|
23751
|
-
//#region src/components/custom/
|
|
23752
|
-
|
|
23753
|
-
|
|
23754
|
-
|
|
23755
|
-
|
|
23756
|
-
|
|
23757
|
-
* ```tsx
|
|
23758
|
-
* <Graphics
|
|
23759
|
-
* onDraw={(g) => {
|
|
23760
|
-
* g.fillStyle(0xff0000, 1)
|
|
23761
|
-
* g.fillCircle(50, 50, 50)
|
|
23762
|
-
* }}
|
|
23763
|
-
* />
|
|
23764
|
-
* ```
|
|
23765
|
-
*/
|
|
23766
|
-
function Graphics(props) {
|
|
23767
|
-
const { props: themed, nestedTheme } = getThemedProps("Graphics", useTheme(), props);
|
|
23768
|
-
return /* @__PURE__ */ jsx("graphics", {
|
|
23769
|
-
...themed,
|
|
23770
|
-
theme: nestedTheme
|
|
23771
|
-
});
|
|
24254
|
+
//#region src/components/custom/Checkbox.tsx
|
|
24255
|
+
function getNextCheckedState(checked, tristate) {
|
|
24256
|
+
if (!tristate) return checked === true ? false : true;
|
|
24257
|
+
if (checked === false) return true;
|
|
24258
|
+
if (checked === true) return "indeterminate";
|
|
24259
|
+
return false;
|
|
23772
24260
|
}
|
|
23773
|
-
|
|
23774
|
-
|
|
23775
|
-
|
|
23776
|
-
|
|
23777
|
-
|
|
23778
|
-
|
|
23779
|
-
|
|
23780
|
-
|
|
23781
|
-
|
|
23782
|
-
|
|
23783
|
-
|
|
23784
|
-
|
|
23785
|
-
|
|
23786
|
-
|
|
23787
|
-
|
|
23788
|
-
|
|
23789
|
-
|
|
24261
|
+
function normalizeCheckedState(checked, tristate) {
|
|
24262
|
+
return checked === "indeterminate" && !tristate ? false : checked;
|
|
24263
|
+
}
|
|
24264
|
+
function drawDefaultIndicator(graphics, indicatorProps) {
|
|
24265
|
+
const { checked, disabled, size, color, checkedColor, indeterminateColor } = indicatorProps;
|
|
24266
|
+
const borderWidth = Math.max(2, Math.round(size * .1));
|
|
24267
|
+
const inset = Math.max(4, Math.round(size * .22));
|
|
24268
|
+
const radius = Math.max(2, Math.round(size * .15));
|
|
24269
|
+
const alpha = disabled ? .45 : 1;
|
|
24270
|
+
graphics.clear();
|
|
24271
|
+
graphics.lineStyle(borderWidth, checked === false ? color : checkedColor, alpha);
|
|
24272
|
+
graphics.strokeRoundedRect(borderWidth / 2, borderWidth / 2, size - borderWidth, size - borderWidth, radius);
|
|
24273
|
+
if (checked === true) {
|
|
24274
|
+
graphics.lineStyle(borderWidth + 1, checkedColor, alpha);
|
|
24275
|
+
graphics.beginPath();
|
|
24276
|
+
graphics.moveTo(inset, size * .52);
|
|
24277
|
+
graphics.lineTo(size * .43, size - inset);
|
|
24278
|
+
graphics.lineTo(size - inset, inset);
|
|
24279
|
+
graphics.strokePath();
|
|
24280
|
+
}
|
|
24281
|
+
if (checked === "indeterminate") {
|
|
24282
|
+
graphics.lineStyle(borderWidth + 1, indeterminateColor, alpha);
|
|
24283
|
+
graphics.beginPath();
|
|
24284
|
+
graphics.moveTo(inset, size / 2);
|
|
24285
|
+
graphics.lineTo(size - inset, size / 2);
|
|
24286
|
+
graphics.strokePath();
|
|
24287
|
+
}
|
|
24288
|
+
}
|
|
24289
|
+
function Checkbox(props) {
|
|
24290
|
+
const { props: themed, nestedTheme } = getThemedProps("Checkbox", useTheme(), props.theme ?? {});
|
|
24291
|
+
const size = themed.size ?? 20;
|
|
24292
|
+
const gap = themed.gap ?? 8;
|
|
24293
|
+
const labelPosition = props.labelPosition ?? themed.labelPosition ?? "right";
|
|
24294
|
+
const disabled = props.disabled ?? false;
|
|
24295
|
+
const disabledAlpha = themed.disabledAlpha ?? .5;
|
|
24296
|
+
const tristate = props.tristate ?? false;
|
|
24297
|
+
const [checked, setChecked] = useState(normalizeCheckedState(props.checked ?? props.defaultChecked ?? false, tristate));
|
|
24298
|
+
useEffect(() => {
|
|
24299
|
+
if (props.checked !== void 0) setChecked(normalizeCheckedState(props.checked, tristate));
|
|
24300
|
+
}, [props.checked, tristate]);
|
|
24301
|
+
const indicatorProps = {
|
|
24302
|
+
checked,
|
|
24303
|
+
disabled,
|
|
24304
|
+
size,
|
|
24305
|
+
color: themed.color ?? 7829367,
|
|
24306
|
+
checkedColor: themed.checkedColor ?? 5025616,
|
|
24307
|
+
indeterminateColor: themed.indeterminateColor ?? themed.checkedColor ?? 5025616
|
|
24308
|
+
};
|
|
24309
|
+
const handleToggle = () => {
|
|
24310
|
+
if (disabled) return;
|
|
24311
|
+
const nextChecked = getNextCheckedState(checked, tristate);
|
|
24312
|
+
if (props.checked === void 0) setChecked(nextChecked);
|
|
24313
|
+
props.onChange?.(nextChecked);
|
|
24314
|
+
};
|
|
24315
|
+
const indicator = props.indicator ?? props.renderIndicator?.(indicatorProps) ?? /* @__PURE__ */ jsx(Graphics, {
|
|
24316
|
+
width: size,
|
|
24317
|
+
height: size,
|
|
24318
|
+
headless: false,
|
|
24319
|
+
dependencies: [
|
|
24320
|
+
indicatorProps.checked,
|
|
24321
|
+
indicatorProps.disabled,
|
|
24322
|
+
indicatorProps.size,
|
|
24323
|
+
indicatorProps.color,
|
|
24324
|
+
indicatorProps.checkedColor,
|
|
24325
|
+
indicatorProps.indeterminateColor
|
|
24326
|
+
],
|
|
24327
|
+
onDraw: (graphics) => drawDefaultIndicator(graphics, indicatorProps)
|
|
24328
|
+
});
|
|
24329
|
+
const label = props.label && labelPosition !== "none" ? /* @__PURE__ */ jsx(Text, {
|
|
24330
|
+
text: props.label,
|
|
24331
|
+
style: themed.labelStyle,
|
|
24332
|
+
alpha: disabled ? disabledAlpha : 1
|
|
24333
|
+
}) : null;
|
|
23790
24334
|
return /* @__PURE__ */ jsxs(View, {
|
|
23791
24335
|
direction: "row",
|
|
23792
24336
|
alignItems: "center",
|
|
23793
|
-
enableGestures:
|
|
23794
|
-
onTouch:
|
|
24337
|
+
enableGestures: !disabled,
|
|
24338
|
+
onTouch: handleToggle,
|
|
23795
24339
|
theme: nestedTheme,
|
|
23796
|
-
gap
|
|
23797
|
-
|
|
23798
|
-
|
|
23799
|
-
|
|
23800
|
-
|
|
23801
|
-
|
|
23802
|
-
|
|
23803
|
-
backgroundAlpha: 1,
|
|
23804
|
-
padding: 0,
|
|
23805
|
-
cornerRadius: outerRadius,
|
|
23806
|
-
children: /* @__PURE__ */ jsx(View, {
|
|
23807
|
-
width: innerSize,
|
|
23808
|
-
height: innerSize,
|
|
23809
|
-
backgroundColor: themed.selectedColor,
|
|
23810
|
-
visible: props.selected ?? false,
|
|
23811
|
-
cornerRadius: innerRadius
|
|
23812
|
-
})
|
|
23813
|
-
}), /* @__PURE__ */ jsx(Text, {
|
|
23814
|
-
text: props.label,
|
|
23815
|
-
style: themed.labelStyle
|
|
23816
|
-
})]
|
|
24340
|
+
gap,
|
|
24341
|
+
alpha: disabled ? disabledAlpha : 1,
|
|
24342
|
+
children: [
|
|
24343
|
+
labelPosition === "left" && label,
|
|
24344
|
+
indicator,
|
|
24345
|
+
labelPosition !== "left" && label
|
|
24346
|
+
]
|
|
23817
24347
|
}, props.key);
|
|
23818
24348
|
}
|
|
23819
24349
|
//#endregion
|
|
23820
|
-
//#region src/
|
|
23821
|
-
/** @jsxImportSource ../.. */
|
|
24350
|
+
//#region src/design-tokens/use-theme-tokens.ts
|
|
23822
24351
|
/**
|
|
23823
|
-
*
|
|
24352
|
+
* Hook to access complete design token system
|
|
24353
|
+
* Combines colors with text styles, spacing, sizes, and radius tokens
|
|
23824
24354
|
*/
|
|
23825
24355
|
/**
|
|
23826
|
-
*
|
|
23827
|
-
*
|
|
24356
|
+
* Hook to access complete design token system from theme context
|
|
24357
|
+
* Provides colors, text styles, spacing, sizes, and radius tokens
|
|
24358
|
+
* Automatically updates when color mode or preset changes
|
|
24359
|
+
* @returns Current DesignTokens or undefined
|
|
24360
|
+
* @example
|
|
24361
|
+
* ```typescript
|
|
24362
|
+
* function MyComponent() {
|
|
24363
|
+
* const tokens = useThemeTokens()
|
|
24364
|
+
*
|
|
24365
|
+
* if (!tokens) return null
|
|
24366
|
+
*
|
|
24367
|
+
* return (
|
|
24368
|
+
* <View
|
|
24369
|
+
* backgroundColor={tokens.colors.surface.DEFAULT}
|
|
24370
|
+
* padding={tokens.spacing.lg}
|
|
24371
|
+
* cornerRadius={tokens.radius.md}
|
|
24372
|
+
* >
|
|
24373
|
+
* <Text text="Title" style={tokens.textStyles.title} />
|
|
24374
|
+
* <Text text="Body text" style={tokens.textStyles.DEFAULT} />
|
|
24375
|
+
* </View>
|
|
24376
|
+
* )
|
|
24377
|
+
* }
|
|
24378
|
+
* ```
|
|
24379
|
+
*/
|
|
24380
|
+
function useThemeTokens() {
|
|
24381
|
+
const localTheme = useTheme();
|
|
24382
|
+
const getInitialTokens = () => {
|
|
24383
|
+
if (localTheme?.__colorPreset) {
|
|
24384
|
+
const preset = getPresetWithMode(localTheme.__colorPreset.name, localTheme.__colorPreset.mode ?? "light");
|
|
24385
|
+
return {
|
|
24386
|
+
colors: preset.colors,
|
|
24387
|
+
textStyles: createTextStyleTokens(preset.colors.text.DEFAULT.toString()),
|
|
24388
|
+
spacing: defaultSpacingTokens,
|
|
24389
|
+
sizes: defaultSizeTokens,
|
|
24390
|
+
radius: defaultRadiusTokens
|
|
24391
|
+
};
|
|
24392
|
+
}
|
|
24393
|
+
const colors = themeRegistry.getColorTokens();
|
|
24394
|
+
if (!colors) return void 0;
|
|
24395
|
+
return {
|
|
24396
|
+
colors,
|
|
24397
|
+
textStyles: createTextStyleTokens(colors.text.DEFAULT.toString()),
|
|
24398
|
+
spacing: defaultSpacingTokens,
|
|
24399
|
+
sizes: defaultSizeTokens,
|
|
24400
|
+
radius: defaultRadiusTokens
|
|
24401
|
+
};
|
|
24402
|
+
};
|
|
24403
|
+
const [tokens, setTokens] = useState(getInitialTokens());
|
|
24404
|
+
const [, forceUpdate] = useState(0);
|
|
24405
|
+
useEffect(() => {
|
|
24406
|
+
return themeRegistry.subscribe(() => {
|
|
24407
|
+
if (localTheme?.__colorPreset) {
|
|
24408
|
+
const currentMode = themeRegistry.getColorMode();
|
|
24409
|
+
const preset = getPresetWithMode(localTheme.__colorPreset.name, currentMode);
|
|
24410
|
+
setTokens({
|
|
24411
|
+
colors: preset.colors,
|
|
24412
|
+
textStyles: createTextStyleTokens(preset.colors.text.DEFAULT.toString()),
|
|
24413
|
+
spacing: defaultSpacingTokens,
|
|
24414
|
+
sizes: defaultSizeTokens,
|
|
24415
|
+
radius: defaultRadiusTokens
|
|
24416
|
+
});
|
|
24417
|
+
} else {
|
|
24418
|
+
const colors = themeRegistry.getColorTokens();
|
|
24419
|
+
if (colors) setTokens({
|
|
24420
|
+
colors,
|
|
24421
|
+
textStyles: createTextStyleTokens(colors.text.DEFAULT.toString()),
|
|
24422
|
+
spacing: defaultSpacingTokens,
|
|
24423
|
+
sizes: defaultSizeTokens,
|
|
24424
|
+
radius: defaultRadiusTokens
|
|
24425
|
+
});
|
|
24426
|
+
}
|
|
24427
|
+
forceUpdate((n) => n + 1);
|
|
24428
|
+
});
|
|
24429
|
+
}, [localTheme]);
|
|
24430
|
+
return tokens;
|
|
24431
|
+
}
|
|
24432
|
+
//#endregion
|
|
24433
|
+
//#region src/components/custom/DebugPanel.tsx
|
|
24434
|
+
/** @jsxImportSource ../.. */
|
|
24435
|
+
/**
|
|
24436
|
+
* DebugPanel component - lightweight runtime diagnostics for Phaser + PhaserJSX
|
|
24437
|
+
* Renders selected metrics as text rows or a compact single-line summary.
|
|
24438
|
+
*/
|
|
24439
|
+
var PRESET_METRICS = {
|
|
24440
|
+
fps: ["fps", "frameMs"],
|
|
24441
|
+
perf: [
|
|
24442
|
+
"fps",
|
|
24443
|
+
"frameMs",
|
|
24444
|
+
"renderer",
|
|
24445
|
+
"viewport"
|
|
24446
|
+
],
|
|
24447
|
+
vdom: [
|
|
24448
|
+
"mountsTotal",
|
|
24449
|
+
"mountsByType",
|
|
24450
|
+
"mountsByParent",
|
|
24451
|
+
"mountsByKey"
|
|
24452
|
+
],
|
|
24453
|
+
textures: ["textureCount"],
|
|
24454
|
+
full: [
|
|
24455
|
+
"fps",
|
|
24456
|
+
"frameMs",
|
|
24457
|
+
"phaserVersion",
|
|
24458
|
+
"renderer",
|
|
24459
|
+
"viewport",
|
|
24460
|
+
"textureCount",
|
|
24461
|
+
"mountsTotal",
|
|
24462
|
+
"mountsByType",
|
|
24463
|
+
"mountsByParent",
|
|
24464
|
+
"mountsByKey",
|
|
24465
|
+
"debugFlags"
|
|
24466
|
+
]
|
|
24467
|
+
};
|
|
24468
|
+
var DEFAULT_LABELS = {
|
|
24469
|
+
fps: "FPS",
|
|
24470
|
+
frameMs: "Frame ms",
|
|
24471
|
+
phaserVersion: "Phaser",
|
|
24472
|
+
renderer: "Renderer",
|
|
24473
|
+
viewport: "Viewport",
|
|
24474
|
+
textureCount: "Textures",
|
|
24475
|
+
mountsTotal: "Mounts",
|
|
24476
|
+
mountsByType: "Mounts/type",
|
|
24477
|
+
mountsByParent: "Mounts/parent",
|
|
24478
|
+
mountsByKey: "Mounts/key",
|
|
24479
|
+
debugFlags: "Debug flags"
|
|
24480
|
+
};
|
|
24481
|
+
function resolveRendererName(scene) {
|
|
24482
|
+
const renderer = scene.renderer;
|
|
24483
|
+
const canvasType = Phaser.CANVAS;
|
|
24484
|
+
if (renderer.type === Phaser.WEBGL) return "WebGL";
|
|
24485
|
+
if (canvasType !== void 0 && renderer.type === canvasType) return "Canvas";
|
|
24486
|
+
if (renderer.constructor?.name) return renderer.constructor.name;
|
|
24487
|
+
if (typeof renderer.type === "number") return `Type ${renderer.type}`;
|
|
24488
|
+
return "Unknown";
|
|
24489
|
+
}
|
|
24490
|
+
function resolveTextureCount(scene) {
|
|
24491
|
+
const manager = scene.textures;
|
|
24492
|
+
const keys = typeof manager.getTextureKeys === "function" ? manager.getTextureKeys() : Object.keys(manager.list ?? {});
|
|
24493
|
+
const internalKeys = new Set([
|
|
24494
|
+
"__DEFAULT",
|
|
24495
|
+
"__MISSING",
|
|
24496
|
+
"__NORMAL",
|
|
24497
|
+
"__WHITE"
|
|
24498
|
+
]);
|
|
24499
|
+
return keys.filter((key) => !internalKeys.has(key.toUpperCase())).length;
|
|
24500
|
+
}
|
|
24501
|
+
function resolveFrameStats(scene) {
|
|
24502
|
+
const loop = scene.game.loop;
|
|
24503
|
+
const rawFps = loop?.actualFps ?? loop?.fps ?? 0;
|
|
24504
|
+
const rawFrameMs = loop?.delta ?? loop?.frameDelta ?? 0;
|
|
24505
|
+
return {
|
|
24506
|
+
fps: Number.isFinite(rawFps) ? Number(rawFps.toFixed(1)) : 0,
|
|
24507
|
+
frameMs: Number.isFinite(rawFrameMs) ? Number(rawFrameMs.toFixed(2)) : 0
|
|
24508
|
+
};
|
|
24509
|
+
}
|
|
24510
|
+
function summarizeMap(map, maxEntries = 3) {
|
|
24511
|
+
return Array.from(map.entries()).sort((a, b) => b[1] - a[1]).slice(0, maxEntries).map(([key, value]) => `${String(key)}:${value}`).join(" | ") || "-";
|
|
24512
|
+
}
|
|
24513
|
+
function resolveDebugFlags() {
|
|
24514
|
+
const debugConfig = DevConfig.debug;
|
|
24515
|
+
if (!debugConfig.enabled) return "off";
|
|
24516
|
+
const enabledFlags = Object.entries(debugConfig).filter(([key, value]) => key !== "enabled" && value).map(([key]) => key);
|
|
24517
|
+
return enabledFlags.length ? enabledFlags.join(",") : "enabled";
|
|
24518
|
+
}
|
|
24519
|
+
function collectSnapshot(scene) {
|
|
24520
|
+
const { fps, frameMs } = resolveFrameStats(scene);
|
|
24521
|
+
const mountStats = getMountStats();
|
|
24522
|
+
return {
|
|
24523
|
+
fps,
|
|
24524
|
+
frameMs,
|
|
24525
|
+
phaserVersion: Phaser.VERSION,
|
|
24526
|
+
renderer: resolveRendererName(scene),
|
|
24527
|
+
viewport: `${scene.scale.width}x${scene.scale.height}`,
|
|
24528
|
+
textureCount: resolveTextureCount(scene),
|
|
24529
|
+
mountsTotal: mountStats.totalMounts,
|
|
24530
|
+
mountsByType: summarizeMap(mountStats.byType),
|
|
24531
|
+
mountsByParent: summarizeMap(mountStats.byParent),
|
|
24532
|
+
mountsByKey: summarizeMap(mountStats.byKey),
|
|
24533
|
+
debugFlags: resolveDebugFlags()
|
|
24534
|
+
};
|
|
24535
|
+
}
|
|
24536
|
+
function formatDefault(value) {
|
|
24537
|
+
return typeof value === "number" ? String(value) : value;
|
|
24538
|
+
}
|
|
24539
|
+
/**
|
|
24540
|
+
* DebugPanel component
|
|
24541
|
+
* Shows selected diagnostics from Phaser + PhaserJSX as overlay-ready content.
|
|
24542
|
+
*/
|
|
24543
|
+
function DebugPanel(props) {
|
|
24544
|
+
const scene = useScene();
|
|
24545
|
+
const { preset = "fps", metrics, intervalMs = 250, compact = false, maxRows, labels, formatters, innerProps, ...viewProps } = props;
|
|
24546
|
+
const selectedMetrics = useMemo(() => {
|
|
24547
|
+
const source = metrics && metrics.length > 0 ? metrics : PRESET_METRICS[preset];
|
|
24548
|
+
return Array.from(new Set(source));
|
|
24549
|
+
}, [metrics, preset]);
|
|
24550
|
+
const [snapshot, setSnapshot] = useState(collectSnapshot(scene));
|
|
24551
|
+
useEffect(() => {
|
|
24552
|
+
const delay = Math.max(50, intervalMs);
|
|
24553
|
+
setSnapshot(collectSnapshot(scene));
|
|
24554
|
+
const timer = window.setInterval(() => {
|
|
24555
|
+
setSnapshot(collectSnapshot(scene));
|
|
24556
|
+
}, delay);
|
|
24557
|
+
return () => {
|
|
24558
|
+
window.clearInterval(timer);
|
|
24559
|
+
};
|
|
24560
|
+
}, [
|
|
24561
|
+
scene,
|
|
24562
|
+
intervalMs,
|
|
24563
|
+
selectedMetrics
|
|
24564
|
+
]);
|
|
24565
|
+
const tokens = useThemeTokens();
|
|
24566
|
+
const rowStyle = tokens?.textStyles.small;
|
|
24567
|
+
const valueStyle = tokens?.textStyles.small;
|
|
24568
|
+
const rows = selectedMetrics.map((metric) => {
|
|
24569
|
+
const rawValue = snapshot[metric];
|
|
24570
|
+
const label = labels?.[metric] ?? DEFAULT_LABELS[metric];
|
|
24571
|
+
const formatter = formatters?.[metric];
|
|
24572
|
+
return {
|
|
24573
|
+
metric,
|
|
24574
|
+
label,
|
|
24575
|
+
value: formatter ? formatter(rawValue) : formatDefault(rawValue)
|
|
24576
|
+
};
|
|
24577
|
+
});
|
|
24578
|
+
const limitedRows = typeof maxRows === "number" ? rows.slice(0, Math.max(1, maxRows)) : rows;
|
|
24579
|
+
if (compact) {
|
|
24580
|
+
const compactText = limitedRows.map((row) => `${row.label} ${row.value}`).join(" | ");
|
|
24581
|
+
return /* @__PURE__ */ jsx(View, {
|
|
24582
|
+
...viewProps,
|
|
24583
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
24584
|
+
text: compactText,
|
|
24585
|
+
style: valueStyle
|
|
24586
|
+
})
|
|
24587
|
+
});
|
|
24588
|
+
}
|
|
24589
|
+
return /* @__PURE__ */ jsx(View, {
|
|
24590
|
+
direction: "column",
|
|
24591
|
+
gap: 4,
|
|
24592
|
+
...viewProps,
|
|
24593
|
+
children: limitedRows.map((row) => /* @__PURE__ */ jsxs(View, {
|
|
24594
|
+
direction: "row",
|
|
24595
|
+
gap: 8,
|
|
24596
|
+
...innerProps,
|
|
24597
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
24598
|
+
text: `${row.label}:`,
|
|
24599
|
+
style: rowStyle
|
|
24600
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
24601
|
+
text: row.value,
|
|
24602
|
+
style: valueStyle
|
|
24603
|
+
})]
|
|
24604
|
+
}, `debug-${row.metric}`))
|
|
24605
|
+
});
|
|
24606
|
+
}
|
|
24607
|
+
//#endregion
|
|
24608
|
+
//#region src/components/custom/Graphics.tsx
|
|
24609
|
+
/**
|
|
24610
|
+
* Graphics component
|
|
24611
|
+
* Renders custom vector shapes via imperative drawing API
|
|
24612
|
+
*
|
|
24613
|
+
* @example
|
|
24614
|
+
* ```tsx
|
|
24615
|
+
* <Graphics
|
|
24616
|
+
* onDraw={(g) => {
|
|
24617
|
+
* g.fillStyle(0xff0000, 1)
|
|
24618
|
+
* g.fillCircle(50, 50, 50)
|
|
24619
|
+
* }}
|
|
24620
|
+
* />
|
|
24621
|
+
* ```
|
|
24622
|
+
*/
|
|
24623
|
+
function Graphics(props) {
|
|
24624
|
+
const { props: themed, nestedTheme } = getThemedProps("Graphics", useTheme(), props);
|
|
24625
|
+
return /* @__PURE__ */ jsx("graphics", {
|
|
24626
|
+
...themed,
|
|
24627
|
+
theme: nestedTheme
|
|
24628
|
+
});
|
|
24629
|
+
}
|
|
24630
|
+
//#endregion
|
|
24631
|
+
//#region src/components/custom/RadioButton.tsx
|
|
24632
|
+
/** @jsxImportSource ../.. */
|
|
24633
|
+
/**
|
|
24634
|
+
* RadioButton component - Selectable option with circle indicator and label
|
|
24635
|
+
*/
|
|
24636
|
+
/**
|
|
24637
|
+
* RadioButton component - displays a selectable circle with label
|
|
24638
|
+
* @param props - RadioButton properties
|
|
24639
|
+
* @returns RadioButton JSX element
|
|
24640
|
+
*/
|
|
24641
|
+
function RadioButton(props) {
|
|
24642
|
+
const { props: themed, nestedTheme } = getThemedProps("RadioButton", void 0, {});
|
|
24643
|
+
const size = themed.size ?? 16;
|
|
24644
|
+
const innerSize = themed.innerSize ?? size * .75;
|
|
24645
|
+
const innerRadius = innerSize * .5;
|
|
24646
|
+
const outerRadius = size * .5;
|
|
24647
|
+
return /* @__PURE__ */ jsxs(View, {
|
|
24648
|
+
direction: "row",
|
|
24649
|
+
alignItems: "center",
|
|
24650
|
+
enableGestures: true,
|
|
24651
|
+
onTouch: () => props.onClick?.(),
|
|
24652
|
+
theme: nestedTheme,
|
|
24653
|
+
gap: themed.gap,
|
|
24654
|
+
children: [/* @__PURE__ */ jsx(View, {
|
|
24655
|
+
width: size,
|
|
24656
|
+
height: size,
|
|
24657
|
+
backgroundColor: themed.color,
|
|
24658
|
+
alignItems: "center",
|
|
24659
|
+
justifyContent: "center",
|
|
24660
|
+
backgroundAlpha: 1,
|
|
24661
|
+
padding: 0,
|
|
24662
|
+
cornerRadius: outerRadius,
|
|
24663
|
+
children: /* @__PURE__ */ jsx(View, {
|
|
24664
|
+
width: innerSize,
|
|
24665
|
+
height: innerSize,
|
|
24666
|
+
backgroundColor: themed.selectedColor,
|
|
24667
|
+
visible: props.selected ?? false,
|
|
24668
|
+
cornerRadius: innerRadius
|
|
24669
|
+
})
|
|
24670
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
24671
|
+
text: props.label,
|
|
24672
|
+
style: themed.labelStyle
|
|
24673
|
+
})]
|
|
24674
|
+
}, props.key);
|
|
24675
|
+
}
|
|
24676
|
+
//#endregion
|
|
24677
|
+
//#region src/components/custom/RadioGroup.tsx
|
|
24678
|
+
/** @jsxImportSource ../.. */
|
|
24679
|
+
/**
|
|
24680
|
+
* RadioGroup component - Manages a group of radio buttons with single-selection logic
|
|
24681
|
+
*/
|
|
24682
|
+
/**
|
|
24683
|
+
* RadioGroup component - displays a group of radio buttons with single-selection
|
|
24684
|
+
* @param props - RadioGroup properties
|
|
23828
24685
|
* @returns RadioGroup JSX element
|
|
23829
24686
|
*/
|
|
23830
24687
|
function RadioGroup(props) {
|
|
@@ -23965,6 +24822,501 @@ function Particles(props) {
|
|
|
23965
24822
|
return /* @__PURE__ */ jsx("particles", { ...props });
|
|
23966
24823
|
}
|
|
23967
24824
|
//#endregion
|
|
24825
|
+
//#region src/components/custom/Portal.tsx
|
|
24826
|
+
/** @jsxImportSource ../.. */
|
|
24827
|
+
/**
|
|
24828
|
+
* Portal component - renders children into a separate tree at specified depth
|
|
24829
|
+
* Enables overlays, modals, tooltips without affecting parent tree layout
|
|
24830
|
+
*/
|
|
24831
|
+
/**
|
|
24832
|
+
* Portal component
|
|
24833
|
+
* Renders child VNode into a separate container tree at specified depth.
|
|
24834
|
+
* Automatically injects event blockers to prevent click-through and scrolling.
|
|
24835
|
+
*
|
|
24836
|
+
* @example
|
|
24837
|
+
* ```tsx
|
|
24838
|
+
* // Basic portal (automatically blocks events in content area)
|
|
24839
|
+
* <Portal depth={1000}>
|
|
24840
|
+
* <View>Overlay content</View>
|
|
24841
|
+
* </Portal>
|
|
24842
|
+
*
|
|
24843
|
+
* // Non-blocking portal (allows click-through)
|
|
24844
|
+
* <Portal depth={500} blockEvents={false}>
|
|
24845
|
+
* <View>Info overlay - clickable background</View>
|
|
24846
|
+
* </Portal>
|
|
24847
|
+
*
|
|
24848
|
+
* // Portal with custom event handling (original handlers are preserved)
|
|
24849
|
+
* <Portal depth={1000}>
|
|
24850
|
+
* <View onTouch={(e) => console.log('clicked')}>
|
|
24851
|
+
* Content
|
|
24852
|
+
* </View>
|
|
24853
|
+
* </Portal>
|
|
24854
|
+
* ```
|
|
24855
|
+
*/
|
|
24856
|
+
function Portal(props) {
|
|
24857
|
+
const portalId = useMemo(() => props.id ?? portalRegistry.generateId(), [props.id]);
|
|
24858
|
+
const depth = props.depth ?? 1e3;
|
|
24859
|
+
const scene = useScene();
|
|
24860
|
+
const blockEvents = props.blockEvents ?? true;
|
|
24861
|
+
const mountedNodesRef = useRef([]);
|
|
24862
|
+
const previousChildrenRef = useRef([]);
|
|
24863
|
+
const normalizeChildren = (children) => {
|
|
24864
|
+
if (!children) return [];
|
|
24865
|
+
return (Array.isArray(children) ? children.flat(Infinity) : [children]).filter((child) => !!child && typeof child === "object" && "type" in child);
|
|
24866
|
+
};
|
|
24867
|
+
useEffect(() => {
|
|
24868
|
+
const portalContainer = portalRegistry.register(portalId, depth, scene, {
|
|
24869
|
+
type: "View",
|
|
24870
|
+
props: {},
|
|
24871
|
+
children: []
|
|
24872
|
+
}, scene.add.container(0, 0));
|
|
24873
|
+
let blockerContainer = null;
|
|
24874
|
+
if (blockEvents) {
|
|
24875
|
+
blockerContainer = scene.add.container(0, 0);
|
|
24876
|
+
portalContainer.add(blockerContainer);
|
|
24877
|
+
blockerContainer.setDepth(-1);
|
|
24878
|
+
}
|
|
24879
|
+
const children = normalizeChildren(props.children);
|
|
24880
|
+
const mountedNodes = [];
|
|
24881
|
+
for (const child of children) if (child) {
|
|
24882
|
+
const mountedNode = mount(portalContainer, child);
|
|
24883
|
+
if (mountedNode) {
|
|
24884
|
+
portalContainer.add(mountedNode);
|
|
24885
|
+
mountedNodes.push(mountedNode);
|
|
24886
|
+
}
|
|
24887
|
+
}
|
|
24888
|
+
mountedNodesRef.current = mountedNodes;
|
|
24889
|
+
previousChildrenRef.current = children;
|
|
24890
|
+
const gestureManager = getGestureManager(scene);
|
|
24891
|
+
if (blockEvents && blockerContainer) {
|
|
24892
|
+
const blocker = blockerContainer;
|
|
24893
|
+
DeferredLayoutQueue.defer(() => {
|
|
24894
|
+
const firstChild = portalContainer.getAt(1);
|
|
24895
|
+
if (!firstChild) return;
|
|
24896
|
+
const { width, height } = firstChild.__cachedLayoutSize ? firstChild.__cachedLayoutSize : firstChild.__getLayoutSize ? firstChild.__getLayoutSize() : (() => {
|
|
24897
|
+
const bounds = firstChild.getBounds();
|
|
24898
|
+
return {
|
|
24899
|
+
width: bounds.width,
|
|
24900
|
+
height: bounds.height
|
|
24901
|
+
};
|
|
24902
|
+
})();
|
|
24903
|
+
const x = firstChild.x;
|
|
24904
|
+
const y = firstChild.y;
|
|
24905
|
+
blocker.setPosition(x, y);
|
|
24906
|
+
const hitArea = new Phaser.Geom.Rectangle(0, 0, width, height);
|
|
24907
|
+
gestureManager.registerContainer(blocker, {
|
|
24908
|
+
onTouch: (e) => {
|
|
24909
|
+
e.stopPropagation();
|
|
24910
|
+
},
|
|
24911
|
+
onTouchMove: (e) => {
|
|
24912
|
+
e.stopPropagation();
|
|
24913
|
+
}
|
|
24914
|
+
}, hitArea);
|
|
24915
|
+
});
|
|
24916
|
+
}
|
|
24917
|
+
return () => {
|
|
24918
|
+
if (blockEvents && blockerContainer) gestureManager.unregisterContainer(blockerContainer);
|
|
24919
|
+
portalRegistry.unregister(portalId);
|
|
24920
|
+
};
|
|
24921
|
+
}, [
|
|
24922
|
+
portalId,
|
|
24923
|
+
depth,
|
|
24924
|
+
scene,
|
|
24925
|
+
blockEvents
|
|
24926
|
+
]);
|
|
24927
|
+
useEffect(() => {
|
|
24928
|
+
const portal = portalRegistry.get(portalId);
|
|
24929
|
+
if (!portal) return;
|
|
24930
|
+
const portalContainer = portal.container;
|
|
24931
|
+
const newChildren = normalizeChildren(props.children);
|
|
24932
|
+
const oldChildren = previousChildrenRef.current;
|
|
24933
|
+
const maxLen = Math.max(oldChildren.length, newChildren.length);
|
|
24934
|
+
for (let i = 0; i < maxLen; i++) {
|
|
24935
|
+
const oldChild = oldChildren[i];
|
|
24936
|
+
const newChild = newChildren[i];
|
|
24937
|
+
if (oldChild && newChild) patchVNode(portalContainer, oldChild, newChild);
|
|
24938
|
+
else if (!oldChild && newChild) {
|
|
24939
|
+
const mountedNode = mount(portalContainer, newChild);
|
|
24940
|
+
if (mountedNode) {
|
|
24941
|
+
portalContainer.add(mountedNode);
|
|
24942
|
+
mountedNodesRef.current.push(mountedNode);
|
|
24943
|
+
}
|
|
24944
|
+
} else if (oldChild && !newChild) unmount(oldChild);
|
|
24945
|
+
}
|
|
24946
|
+
previousChildrenRef.current = newChildren;
|
|
24947
|
+
}, [props.children, portalId]);
|
|
24948
|
+
return null;
|
|
24949
|
+
}
|
|
24950
|
+
//#endregion
|
|
24951
|
+
//#region src/components/custom/Popover.tsx
|
|
24952
|
+
function getMainPlacement(placement) {
|
|
24953
|
+
return placement.split("-")[0];
|
|
24954
|
+
}
|
|
24955
|
+
function getCrossPlacement(placement) {
|
|
24956
|
+
return placement.split("-")[1] ?? "center";
|
|
24957
|
+
}
|
|
24958
|
+
function calculateOverlayPosition(options) {
|
|
24959
|
+
const { anchor, content, placement, offset } = options;
|
|
24960
|
+
const main = getMainPlacement(placement);
|
|
24961
|
+
const cross = getCrossPlacement(placement);
|
|
24962
|
+
let x;
|
|
24963
|
+
let y;
|
|
24964
|
+
if (main === "top" || main === "bottom") {
|
|
24965
|
+
y = main === "top" ? anchor.y - content.height - offset : anchor.y + anchor.height + offset;
|
|
24966
|
+
if (cross === "start") x = anchor.x;
|
|
24967
|
+
else if (cross === "end") x = anchor.x + anchor.width - content.width;
|
|
24968
|
+
else x = anchor.x + (anchor.width - content.width) / 2;
|
|
24969
|
+
} else {
|
|
24970
|
+
x = main === "left" ? anchor.x - content.width - offset : anchor.x + anchor.width + offset;
|
|
24971
|
+
if (cross === "start") y = anchor.y;
|
|
24972
|
+
else if (cross === "end") y = anchor.y + anchor.height - content.height;
|
|
24973
|
+
else y = anchor.y + (anchor.height - content.height) / 2;
|
|
24974
|
+
}
|
|
24975
|
+
const viewport = options.viewport;
|
|
24976
|
+
if (viewport) {
|
|
24977
|
+
const padding = options.viewportPadding ?? 8;
|
|
24978
|
+
x = Math.min(Math.max(padding, x), Math.max(padding, viewport.width - content.width - padding));
|
|
24979
|
+
y = Math.min(Math.max(padding, y), Math.max(padding, viewport.height - content.height - padding));
|
|
24980
|
+
}
|
|
24981
|
+
return {
|
|
24982
|
+
x,
|
|
24983
|
+
y,
|
|
24984
|
+
placement
|
|
24985
|
+
};
|
|
24986
|
+
}
|
|
24987
|
+
function getLayoutSize(container) {
|
|
24988
|
+
const withLayout = container;
|
|
24989
|
+
return withLayout?.__getLayoutSize?.() ?? withLayout?.__cachedLayoutSize ?? {
|
|
24990
|
+
width: 0,
|
|
24991
|
+
height: 0
|
|
24992
|
+
};
|
|
24993
|
+
}
|
|
24994
|
+
function getWorldPosition(container) {
|
|
24995
|
+
const matrix = container.getWorldTransformMatrix?.();
|
|
24996
|
+
if (matrix) return {
|
|
24997
|
+
x: matrix.tx,
|
|
24998
|
+
y: matrix.ty
|
|
24999
|
+
};
|
|
25000
|
+
return {
|
|
25001
|
+
x: container.x ?? 0,
|
|
25002
|
+
y: container.y ?? 0
|
|
25003
|
+
};
|
|
25004
|
+
}
|
|
25005
|
+
function getAnchorRect(container) {
|
|
25006
|
+
if (!container) return {
|
|
25007
|
+
x: 0,
|
|
25008
|
+
y: 0,
|
|
25009
|
+
width: 0,
|
|
25010
|
+
height: 0
|
|
25011
|
+
};
|
|
25012
|
+
const size = getLayoutSize(container);
|
|
25013
|
+
const position = getWorldPosition(container);
|
|
25014
|
+
return {
|
|
25015
|
+
x: position.x,
|
|
25016
|
+
y: position.y,
|
|
25017
|
+
width: size.width,
|
|
25018
|
+
height: size.height
|
|
25019
|
+
};
|
|
25020
|
+
}
|
|
25021
|
+
var FALLBACK_CONTENT_SIZE = {
|
|
25022
|
+
width: 220,
|
|
25023
|
+
height: 120
|
|
25024
|
+
};
|
|
25025
|
+
function assignRef(ref, value) {
|
|
25026
|
+
if (!ref) return;
|
|
25027
|
+
if (typeof ref === "function") {
|
|
25028
|
+
ref(value);
|
|
25029
|
+
return;
|
|
25030
|
+
}
|
|
25031
|
+
ref.current = value;
|
|
25032
|
+
}
|
|
25033
|
+
function Popover(props) {
|
|
25034
|
+
const { props: themed, nestedTheme } = getThemedProps("Popover", useTheme(), props.theme ?? {});
|
|
25035
|
+
const scene = useScene();
|
|
25036
|
+
const triggerRef = useRef(null);
|
|
25037
|
+
const contentRef = useRef(null);
|
|
25038
|
+
const [measuredContentSize, setMeasuredContentSize] = useState(null);
|
|
25039
|
+
const [internalOpen, setInternalOpen] = useState(props.defaultOpen ?? false);
|
|
25040
|
+
const isControlled = props.isOpen !== void 0;
|
|
25041
|
+
const isOpen = isControlled ? props.isOpen === true : internalOpen;
|
|
25042
|
+
const placement = props.placement ?? themed.placement ?? "bottom";
|
|
25043
|
+
const offset = props.offset ?? themed.offset ?? 8;
|
|
25044
|
+
const depth = props.depth ?? themed.depth ?? 1100;
|
|
25045
|
+
const closeOnOutside = props.closeOnOutside ?? themed.closeOnOutside ?? true;
|
|
25046
|
+
const closeOnEscape = props.closeOnEscape ?? themed.closeOnEscape ?? true;
|
|
25047
|
+
const viewportPadding = props.viewportPadding ?? themed.viewportPadding ?? 8;
|
|
25048
|
+
const explicitContentWidth = props.contentWidth ?? themed.contentWidth;
|
|
25049
|
+
const explicitContentHeight = props.contentHeight ?? themed.contentHeight;
|
|
25050
|
+
const viewport = portalRegistry.getViewportSize(scene);
|
|
25051
|
+
const anchor = getAnchorRect(triggerRef.current);
|
|
25052
|
+
const measuredWidth = measuredContentSize?.width ?? FALLBACK_CONTENT_SIZE.width;
|
|
25053
|
+
const measuredHeight = measuredContentSize?.height ?? FALLBACK_CONTENT_SIZE.height;
|
|
25054
|
+
const isPositionReady = !(explicitContentWidth === void 0 || explicitContentHeight === void 0) || measuredContentSize !== null;
|
|
25055
|
+
const contentWidth = props.matchTriggerWidth ? Math.max(anchor.width, explicitContentWidth ?? measuredWidth) : explicitContentWidth ?? measuredWidth;
|
|
25056
|
+
const overlayPosition = calculateOverlayPosition({
|
|
25057
|
+
anchor,
|
|
25058
|
+
content: {
|
|
25059
|
+
width: contentWidth,
|
|
25060
|
+
height: explicitContentHeight ?? measuredHeight
|
|
25061
|
+
},
|
|
25062
|
+
placement,
|
|
25063
|
+
offset,
|
|
25064
|
+
viewport,
|
|
25065
|
+
viewportPadding
|
|
25066
|
+
});
|
|
25067
|
+
const setOpen = (open) => {
|
|
25068
|
+
if (props.disabled && open) return;
|
|
25069
|
+
if (!isControlled) setInternalOpen(open);
|
|
25070
|
+
props.onOpenChange?.(open);
|
|
25071
|
+
};
|
|
25072
|
+
const toggleOpen = (event) => {
|
|
25073
|
+
event.stopPropagation();
|
|
25074
|
+
setOpen(!isOpen);
|
|
25075
|
+
};
|
|
25076
|
+
const close = (event) => {
|
|
25077
|
+
event?.stopPropagation();
|
|
25078
|
+
setOpen(false);
|
|
25079
|
+
};
|
|
25080
|
+
const contentProps = props.contentProps ?? {};
|
|
25081
|
+
const contentPropsRef = contentProps.ref;
|
|
25082
|
+
const contentPropsAlpha = contentProps.alpha;
|
|
25083
|
+
const handleContentRef = (container) => {
|
|
25084
|
+
contentRef.current = container;
|
|
25085
|
+
assignRef(contentPropsRef, container);
|
|
25086
|
+
};
|
|
25087
|
+
useEffect(() => {
|
|
25088
|
+
if (!closeOnEscape || !isOpen) return;
|
|
25089
|
+
const handleKeyDown = (event) => {
|
|
25090
|
+
if (event.key === "Escape") setOpen(false);
|
|
25091
|
+
};
|
|
25092
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
25093
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
25094
|
+
}, [closeOnEscape, isOpen]);
|
|
25095
|
+
useEffect(() => {
|
|
25096
|
+
if (!isOpen) return;
|
|
25097
|
+
DeferredLayoutQueue.defer(() => {
|
|
25098
|
+
const size = getLayoutSize(contentRef.current);
|
|
25099
|
+
if (size.width <= 0 || size.height <= 0) return;
|
|
25100
|
+
setMeasuredContentSize((current) => {
|
|
25101
|
+
if (current?.width === size.width && current?.height === size.height) return current;
|
|
25102
|
+
return {
|
|
25103
|
+
width: size.width,
|
|
25104
|
+
height: size.height
|
|
25105
|
+
};
|
|
25106
|
+
});
|
|
25107
|
+
});
|
|
25108
|
+
}, [
|
|
25109
|
+
isOpen,
|
|
25110
|
+
props.children,
|
|
25111
|
+
explicitContentWidth,
|
|
25112
|
+
explicitContentHeight
|
|
25113
|
+
]);
|
|
25114
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(View, {
|
|
25115
|
+
...props.triggerProps ?? {},
|
|
25116
|
+
ref: triggerRef,
|
|
25117
|
+
enableGestures: !props.disabled,
|
|
25118
|
+
onTouch: toggleOpen,
|
|
25119
|
+
children: props.trigger
|
|
25120
|
+
}), isOpen && /* @__PURE__ */ jsxs(Portal, {
|
|
25121
|
+
depth,
|
|
25122
|
+
blockEvents: false,
|
|
25123
|
+
children: [closeOnOutside && /* @__PURE__ */ jsx(View, {
|
|
25124
|
+
width: viewport.width,
|
|
25125
|
+
height: viewport.height,
|
|
25126
|
+
backgroundColor: 0,
|
|
25127
|
+
backgroundAlpha: 0,
|
|
25128
|
+
onTouch: close,
|
|
25129
|
+
onTouchMove: (event) => event.stopPropagation()
|
|
25130
|
+
}), /* @__PURE__ */ jsx(View, {
|
|
25131
|
+
...contentProps,
|
|
25132
|
+
ref: handleContentRef,
|
|
25133
|
+
x: overlayPosition.x,
|
|
25134
|
+
y: overlayPosition.y,
|
|
25135
|
+
...props.matchTriggerWidth || explicitContentWidth !== void 0 ? { width: contentWidth } : {},
|
|
25136
|
+
direction: "column",
|
|
25137
|
+
backgroundColor: themed.backgroundColor ?? 1120295,
|
|
25138
|
+
borderColor: themed.borderColor ?? 3359061,
|
|
25139
|
+
borderWidth: themed.borderWidth ?? 1,
|
|
25140
|
+
cornerRadius: themed.cornerRadius ?? 8,
|
|
25141
|
+
padding: themed.padding ?? 10,
|
|
25142
|
+
gap: themed.gap ?? 8,
|
|
25143
|
+
...isPositionReady ? contentPropsAlpha !== void 0 ? { alpha: contentPropsAlpha } : {} : { alpha: 0 },
|
|
25144
|
+
onTouch: (event) => event.stopPropagation(),
|
|
25145
|
+
theme: nestedTheme,
|
|
25146
|
+
children: props.children
|
|
25147
|
+
})]
|
|
25148
|
+
})] });
|
|
25149
|
+
}
|
|
25150
|
+
function ContextMenu(props) {
|
|
25151
|
+
const { items, width: explicitWidth, onSelect, isOpen: explicitOpen, defaultOpen, onOpenChange, ...popoverProps } = props;
|
|
25152
|
+
const { props: themed, nestedTheme } = getThemedProps("ContextMenu", useTheme(), props.theme ?? {});
|
|
25153
|
+
const [internalOpen, setInternalOpen] = useState(defaultOpen ?? false);
|
|
25154
|
+
const isControlled = explicitOpen !== void 0;
|
|
25155
|
+
const isOpen = isControlled ? explicitOpen === true : internalOpen;
|
|
25156
|
+
const width = explicitWidth ?? themed.width ?? 220;
|
|
25157
|
+
const itemHeight = themed.itemHeight ?? 34;
|
|
25158
|
+
const setOpen = (open) => {
|
|
25159
|
+
if (!isControlled) setInternalOpen(open);
|
|
25160
|
+
onOpenChange?.(open);
|
|
25161
|
+
};
|
|
25162
|
+
const handleSelect = (item) => {
|
|
25163
|
+
if (item.disabled) return;
|
|
25164
|
+
item.onSelect?.();
|
|
25165
|
+
onSelect?.(item);
|
|
25166
|
+
setOpen(false);
|
|
25167
|
+
};
|
|
25168
|
+
return /* @__PURE__ */ jsx(Popover, {
|
|
25169
|
+
...popoverProps,
|
|
25170
|
+
isOpen,
|
|
25171
|
+
onOpenChange: setOpen,
|
|
25172
|
+
contentWidth: width,
|
|
25173
|
+
contentHeight: Math.max(1, items.length) * itemHeight + 20,
|
|
25174
|
+
contentProps: {
|
|
25175
|
+
padding: themed.padding ?? 6,
|
|
25176
|
+
gap: themed.gap ?? 2,
|
|
25177
|
+
backgroundColor: themed.backgroundColor,
|
|
25178
|
+
borderColor: themed.borderColor,
|
|
25179
|
+
borderWidth: themed.borderWidth,
|
|
25180
|
+
cornerRadius: themed.cornerRadius,
|
|
25181
|
+
theme: nestedTheme
|
|
25182
|
+
},
|
|
25183
|
+
children: items.map((item) => {
|
|
25184
|
+
const textColor = item.disabled ? themed.disabledTextColor ?? "#64748b" : item.danger ? themed.dangerTextColor ?? "#fecaca" : themed.textStyle?.color ?? "#f8fafc";
|
|
25185
|
+
return /* @__PURE__ */ jsxs(View, {
|
|
25186
|
+
width: "fill",
|
|
25187
|
+
height: itemHeight,
|
|
25188
|
+
direction: "row",
|
|
25189
|
+
alignItems: "center",
|
|
25190
|
+
gap: themed.itemGap ?? 8,
|
|
25191
|
+
padding: themed.itemPadding ?? {
|
|
25192
|
+
left: 10,
|
|
25193
|
+
right: 10,
|
|
25194
|
+
top: 6,
|
|
25195
|
+
bottom: 6
|
|
25196
|
+
},
|
|
25197
|
+
cornerRadius: themed.itemCornerRadius ?? 5,
|
|
25198
|
+
backgroundColor: item.danger ? themed.dangerBackgroundColor ?? 2042167 : 0,
|
|
25199
|
+
backgroundAlpha: item.danger ? .35 : 0,
|
|
25200
|
+
enableGestures: !item.disabled,
|
|
25201
|
+
onTouch: (event) => {
|
|
25202
|
+
event.stopPropagation();
|
|
25203
|
+
handleSelect(item);
|
|
25204
|
+
},
|
|
25205
|
+
children: [
|
|
25206
|
+
item.prefix,
|
|
25207
|
+
/* @__PURE__ */ jsx(View, {
|
|
25208
|
+
flex: 1,
|
|
25209
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
25210
|
+
text: item.label,
|
|
25211
|
+
style: {
|
|
25212
|
+
...themed.textStyle ?? {},
|
|
25213
|
+
color: textColor
|
|
25214
|
+
}
|
|
25215
|
+
})
|
|
25216
|
+
}),
|
|
25217
|
+
item.suffix
|
|
25218
|
+
]
|
|
25219
|
+
}, item.id);
|
|
25220
|
+
})
|
|
25221
|
+
});
|
|
25222
|
+
}
|
|
25223
|
+
//#endregion
|
|
25224
|
+
//#region src/components/custom/ProgressBar.tsx
|
|
25225
|
+
/** @jsxImportSource ../.. */
|
|
25226
|
+
/**
|
|
25227
|
+
* ProgressBar component - determinate progress indicator for health, loading, cooldowns, and XP.
|
|
25228
|
+
*/
|
|
25229
|
+
function clampProgressValue(value, min, max) {
|
|
25230
|
+
if (!Number.isFinite(value)) return min;
|
|
25231
|
+
return Math.min(Math.max(value, min), max);
|
|
25232
|
+
}
|
|
25233
|
+
function getProgressRatio(value, min, max) {
|
|
25234
|
+
if (!Number.isFinite(min) || !Number.isFinite(max) || min === max) return 0;
|
|
25235
|
+
const normalizedMin = Math.min(min, max);
|
|
25236
|
+
const normalizedMax = Math.max(min, max);
|
|
25237
|
+
return (clampProgressValue(value, normalizedMin, normalizedMax) - normalizedMin) / (normalizedMax - normalizedMin);
|
|
25238
|
+
}
|
|
25239
|
+
function formatDefaultValue(props) {
|
|
25240
|
+
return `${Math.round(props.percent)}%`;
|
|
25241
|
+
}
|
|
25242
|
+
function ProgressBar(props) {
|
|
25243
|
+
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;
|
|
25244
|
+
const { props: themed, nestedTheme } = getThemedProps("ProgressBar", useTheme(), theme ?? {});
|
|
25245
|
+
const orientation = explicitOrientation ?? themed.orientation ?? "horizontal";
|
|
25246
|
+
const ratio = getProgressRatio(value, min, max);
|
|
25247
|
+
const percent = ratio * 100;
|
|
25248
|
+
const labelPosition = explicitLabelPosition ?? themed.labelPosition ?? (showValue || label ? "right" : "none");
|
|
25249
|
+
const shouldShowText = labelPosition !== "none" && Boolean(showValue || label);
|
|
25250
|
+
const text = shouldShowText ? [label, showValue ? (formatValue ?? themed.formatValue ?? formatDefaultValue)({
|
|
25251
|
+
value,
|
|
25252
|
+
min,
|
|
25253
|
+
max,
|
|
25254
|
+
ratio,
|
|
25255
|
+
percent
|
|
25256
|
+
}) : void 0].filter(Boolean).join(" ") : "";
|
|
25257
|
+
const resolvedWidth = width ?? themed.width ?? (orientation === "horizontal" ? 240 : 24);
|
|
25258
|
+
const resolvedHeight = height ?? themed.height ?? (orientation === "horizontal" ? 22 : 160);
|
|
25259
|
+
const trackColor = explicitTrackColor ?? themed.trackColor ?? 2042167;
|
|
25260
|
+
const fillColor = explicitFillColor ?? themed.fillColor ?? 2278750;
|
|
25261
|
+
const borderColor = explicitBorderColor ?? themed.borderColor ?? 3359061;
|
|
25262
|
+
const borderWidth = explicitBorderWidth ?? themed.borderWidth ?? 1;
|
|
25263
|
+
const cornerRadius = explicitCornerRadius ?? themed.cornerRadius ?? (orientation === "horizontal" ? 11 : 8);
|
|
25264
|
+
const labelStyle = explicitLabelStyle ?? themed.labelStyle ?? {
|
|
25265
|
+
color: "#ffffff",
|
|
25266
|
+
fontSize: "12px"
|
|
25267
|
+
};
|
|
25268
|
+
const disabledAlpha = explicitDisabledAlpha ?? themed.disabledAlpha ?? .5;
|
|
25269
|
+
const effectiveAlpha = disabled ? disabledAlpha : alpha;
|
|
25270
|
+
const rootDirection = labelPosition === "left" || labelPosition === "right" ? "row" : labelPosition === "top" || labelPosition === "bottom" ? "column" : "column";
|
|
25271
|
+
const labelNode = shouldShowText ? /* @__PURE__ */ jsx(Text, {
|
|
25272
|
+
text,
|
|
25273
|
+
style: labelStyle
|
|
25274
|
+
}) : null;
|
|
25275
|
+
const fillProps = orientation === "horizontal" ? {
|
|
25276
|
+
width: `${percent}%`,
|
|
25277
|
+
height: "fill"
|
|
25278
|
+
} : {
|
|
25279
|
+
width: "fill",
|
|
25280
|
+
height: `${percent}%`
|
|
25281
|
+
};
|
|
25282
|
+
const track = /* @__PURE__ */ jsxs(View, {
|
|
25283
|
+
width: resolvedWidth,
|
|
25284
|
+
height: resolvedHeight,
|
|
25285
|
+
direction: orientation === "horizontal" ? "stack" : "column",
|
|
25286
|
+
justifyContent: orientation === "vertical" ? "end" : "start",
|
|
25287
|
+
backgroundColor: trackColor,
|
|
25288
|
+
borderColor,
|
|
25289
|
+
borderWidth,
|
|
25290
|
+
cornerRadius,
|
|
25291
|
+
overflow: "hidden",
|
|
25292
|
+
theme: nestedTheme,
|
|
25293
|
+
children: [/* @__PURE__ */ jsx(View, {
|
|
25294
|
+
...fillProps,
|
|
25295
|
+
backgroundColor: fillColor,
|
|
25296
|
+
cornerRadius
|
|
25297
|
+
}), labelPosition === "inside" && shouldShowText && /* @__PURE__ */ jsx(View, {
|
|
25298
|
+
width: "fill",
|
|
25299
|
+
height: "fill",
|
|
25300
|
+
justifyContent: "center",
|
|
25301
|
+
alignItems: "center",
|
|
25302
|
+
children: labelNode
|
|
25303
|
+
})]
|
|
25304
|
+
});
|
|
25305
|
+
return /* @__PURE__ */ jsxs(View, {
|
|
25306
|
+
...viewProps,
|
|
25307
|
+
direction: rootDirection,
|
|
25308
|
+
alignItems: "center",
|
|
25309
|
+
gap: themed.gap ?? 8,
|
|
25310
|
+
...effectiveAlpha !== void 0 ? { alpha: effectiveAlpha } : {},
|
|
25311
|
+
theme: nestedTheme,
|
|
25312
|
+
children: [
|
|
25313
|
+
labelPosition === "top" || labelPosition === "left" ? labelNode : null,
|
|
25314
|
+
track,
|
|
25315
|
+
labelPosition !== "inside" && (labelPosition === "bottom" || labelPosition === "right") ? labelNode : null
|
|
25316
|
+
]
|
|
25317
|
+
});
|
|
25318
|
+
}
|
|
25319
|
+
//#endregion
|
|
23968
25320
|
//#region src/components/index.ts
|
|
23969
25321
|
/**
|
|
23970
25322
|
* Built-in component implementations
|
|
@@ -23978,7 +25330,6 @@ function Particles(props) {
|
|
|
23978
25330
|
/**
|
|
23979
25331
|
* Registers all built-in components with the host
|
|
23980
25332
|
* This should be called during library initialization
|
|
23981
|
-
* Note: TileSprite is currently dummy (throws on use)
|
|
23982
25333
|
*/
|
|
23983
25334
|
function registerBuiltins() {
|
|
23984
25335
|
register("view", {
|
|
@@ -24051,7 +25402,7 @@ function registerBuiltins() {
|
|
|
24051
25402
|
/**
|
|
24052
25403
|
* Preprocesses SVG string to ensure tinting works correctly
|
|
24053
25404
|
* Replaces fill/stroke="currentColor" and other colors with white (#FFFFFF)
|
|
24054
|
-
* This allows Phaser's tint to work
|
|
25405
|
+
* This allows Phaser's tint to work by multiplication (white × tint = tint color)
|
|
24055
25406
|
* @param svg - Raw SVG string
|
|
24056
25407
|
* @returns Preprocessed SVG string with white fills/strokes
|
|
24057
25408
|
*/
|
|
@@ -25113,132 +26464,6 @@ function Accordion(props) {
|
|
|
25113
26464
|
}, props.key);
|
|
25114
26465
|
}
|
|
25115
26466
|
//#endregion
|
|
25116
|
-
//#region src/components/custom/Portal.tsx
|
|
25117
|
-
/** @jsxImportSource ../.. */
|
|
25118
|
-
/**
|
|
25119
|
-
* Portal component - renders children into a separate tree at specified depth
|
|
25120
|
-
* Enables overlays, modals, tooltips without affecting parent tree layout
|
|
25121
|
-
*/
|
|
25122
|
-
/**
|
|
25123
|
-
* Portal component
|
|
25124
|
-
* Renders child VNode into a separate container tree at specified depth.
|
|
25125
|
-
* Automatically injects event blockers to prevent click-through and scrolling.
|
|
25126
|
-
*
|
|
25127
|
-
* @example
|
|
25128
|
-
* ```tsx
|
|
25129
|
-
* // Basic portal (automatically blocks events in content area)
|
|
25130
|
-
* <Portal depth={1000}>
|
|
25131
|
-
* <View>Overlay content</View>
|
|
25132
|
-
* </Portal>
|
|
25133
|
-
*
|
|
25134
|
-
* // Non-blocking portal (allows click-through)
|
|
25135
|
-
* <Portal depth={500} blockEvents={false}>
|
|
25136
|
-
* <View>Info overlay - clickable background</View>
|
|
25137
|
-
* </Portal>
|
|
25138
|
-
*
|
|
25139
|
-
* // Portal with custom event handling (original handlers are preserved)
|
|
25140
|
-
* <Portal depth={1000}>
|
|
25141
|
-
* <View onTouch={(e) => console.log('clicked')}>
|
|
25142
|
-
* Content
|
|
25143
|
-
* </View>
|
|
25144
|
-
* </Portal>
|
|
25145
|
-
* ```
|
|
25146
|
-
*/
|
|
25147
|
-
function Portal(props) {
|
|
25148
|
-
const portalId = useMemo(() => props.id ?? portalRegistry.generateId(), [props.id]);
|
|
25149
|
-
const depth = props.depth ?? 1e3;
|
|
25150
|
-
const scene = useScene();
|
|
25151
|
-
const blockEvents = props.blockEvents ?? true;
|
|
25152
|
-
const mountedNodesRef = useRef([]);
|
|
25153
|
-
const previousChildrenRef = useRef([]);
|
|
25154
|
-
const normalizeChildren = (children) => {
|
|
25155
|
-
if (!children) return [];
|
|
25156
|
-
return (Array.isArray(children) ? children.flat(Infinity) : [children]).filter((child) => !!child && typeof child === "object" && "type" in child);
|
|
25157
|
-
};
|
|
25158
|
-
useEffect(() => {
|
|
25159
|
-
const portalContainer = portalRegistry.register(portalId, depth, scene, {
|
|
25160
|
-
type: "View",
|
|
25161
|
-
props: {},
|
|
25162
|
-
children: []
|
|
25163
|
-
}, scene.add.container(0, 0));
|
|
25164
|
-
let blockerContainer = null;
|
|
25165
|
-
if (blockEvents) {
|
|
25166
|
-
blockerContainer = scene.add.container(0, 0);
|
|
25167
|
-
portalContainer.add(blockerContainer);
|
|
25168
|
-
blockerContainer.setDepth(-1);
|
|
25169
|
-
}
|
|
25170
|
-
const children = normalizeChildren(props.children);
|
|
25171
|
-
const mountedNodes = [];
|
|
25172
|
-
for (const child of children) if (child) {
|
|
25173
|
-
const mountedNode = mount(portalContainer, child);
|
|
25174
|
-
if (mountedNode) {
|
|
25175
|
-
portalContainer.add(mountedNode);
|
|
25176
|
-
mountedNodes.push(mountedNode);
|
|
25177
|
-
}
|
|
25178
|
-
}
|
|
25179
|
-
mountedNodesRef.current = mountedNodes;
|
|
25180
|
-
previousChildrenRef.current = children;
|
|
25181
|
-
const gestureManager = getGestureManager(scene);
|
|
25182
|
-
if (blockEvents && blockerContainer) {
|
|
25183
|
-
const blocker = blockerContainer;
|
|
25184
|
-
DeferredLayoutQueue.defer(() => {
|
|
25185
|
-
const firstChild = portalContainer.getAt(1);
|
|
25186
|
-
if (!firstChild) return;
|
|
25187
|
-
const { width, height } = firstChild.__cachedLayoutSize ? firstChild.__cachedLayoutSize : firstChild.__getLayoutSize ? firstChild.__getLayoutSize() : (() => {
|
|
25188
|
-
const bounds = firstChild.getBounds();
|
|
25189
|
-
return {
|
|
25190
|
-
width: bounds.width,
|
|
25191
|
-
height: bounds.height
|
|
25192
|
-
};
|
|
25193
|
-
})();
|
|
25194
|
-
const x = firstChild.x;
|
|
25195
|
-
const y = firstChild.y;
|
|
25196
|
-
blocker.setPosition(x, y);
|
|
25197
|
-
const hitArea = new Phaser.Geom.Rectangle(0, 0, width, height);
|
|
25198
|
-
gestureManager.registerContainer(blocker, {
|
|
25199
|
-
onTouch: (e) => {
|
|
25200
|
-
e.stopPropagation();
|
|
25201
|
-
},
|
|
25202
|
-
onTouchMove: (e) => {
|
|
25203
|
-
e.stopPropagation();
|
|
25204
|
-
}
|
|
25205
|
-
}, hitArea);
|
|
25206
|
-
});
|
|
25207
|
-
}
|
|
25208
|
-
return () => {
|
|
25209
|
-
if (blockEvents && blockerContainer) gestureManager.unregisterContainer(blockerContainer);
|
|
25210
|
-
portalRegistry.unregister(portalId);
|
|
25211
|
-
};
|
|
25212
|
-
}, [
|
|
25213
|
-
portalId,
|
|
25214
|
-
depth,
|
|
25215
|
-
scene,
|
|
25216
|
-
blockEvents
|
|
25217
|
-
]);
|
|
25218
|
-
useEffect(() => {
|
|
25219
|
-
const portal = portalRegistry.get(portalId);
|
|
25220
|
-
if (!portal) return;
|
|
25221
|
-
const portalContainer = portal.container;
|
|
25222
|
-
const newChildren = normalizeChildren(props.children);
|
|
25223
|
-
const oldChildren = previousChildrenRef.current;
|
|
25224
|
-
const maxLen = Math.max(oldChildren.length, newChildren.length);
|
|
25225
|
-
for (let i = 0; i < maxLen; i++) {
|
|
25226
|
-
const oldChild = oldChildren[i];
|
|
25227
|
-
const newChild = newChildren[i];
|
|
25228
|
-
if (oldChild && newChild) patchVNode(portalContainer, oldChild, newChild);
|
|
25229
|
-
else if (!oldChild && newChild) {
|
|
25230
|
-
const mountedNode = mount(portalContainer, newChild);
|
|
25231
|
-
if (mountedNode) {
|
|
25232
|
-
portalContainer.add(mountedNode);
|
|
25233
|
-
mountedNodesRef.current.push(mountedNode);
|
|
25234
|
-
}
|
|
25235
|
-
} else if (oldChild && !newChild) unmount(oldChild);
|
|
25236
|
-
}
|
|
25237
|
-
previousChildrenRef.current = newChildren;
|
|
25238
|
-
}, [props.children, portalId]);
|
|
25239
|
-
return null;
|
|
25240
|
-
}
|
|
25241
|
-
//#endregion
|
|
25242
26467
|
//#region src/components/custom/Modal.tsx
|
|
25243
26468
|
/** @jsxImportSource ../.. */
|
|
25244
26469
|
/**
|
|
@@ -27996,7 +29221,7 @@ function Joystick(props) {
|
|
|
27996
29221
|
y: 0
|
|
27997
29222
|
});
|
|
27998
29223
|
useLayoutEffect(() => {
|
|
27999
|
-
const size = getLayoutSize(outerRef.current);
|
|
29224
|
+
const size = getLayoutSize$1(outerRef.current);
|
|
28000
29225
|
if (size != null) {
|
|
28001
29226
|
const newCenter = {
|
|
28002
29227
|
x: size.width / 2,
|
|
@@ -29087,7 +30312,6 @@ function Toggle(props) {
|
|
|
29087
30312
|
setIsAnimating(true);
|
|
29088
30313
|
const endX = newChecked ? thumbOffsetOn : thumbOffsetOff;
|
|
29089
30314
|
const startX = thumbX;
|
|
29090
|
-
console.log("Duration:", duration.current);
|
|
29091
30315
|
scene.tweens.addCounter({
|
|
29092
30316
|
from: 0,
|
|
29093
30317
|
to: 1,
|
|
@@ -29254,6 +30478,6 @@ function TransformOriginView({ originX = .5, originY = .5, width, height, x = 0,
|
|
|
29254
30478
|
});
|
|
29255
30479
|
}
|
|
29256
30480
|
//#endregion
|
|
29257
|
-
export {
|
|
30481
|
+
export { Portal as $, getContrastRatio as $n, normalizeVNodeLike as $t, useSpring as A, withHooks as An, resolveParticlePreset as Ar, createSwingEffect as At, releaseAllSVGTextures as B, applyLightMode as Bn, host as Br, getBadgeSizeConfig as Bt, CharText as C, useRedraw as Cn, particlesPatcher as Cr, createNoneEffect as Ct, Modal as D, useTheme as Dn, getFirstEmitter as Dr, createSlideInEffect as Dt, Dialog as E, useState as En, applyEmitterConfig as Er, createShakeEffect as Et, animatedSignal as F, defaultRadiusTokens as Fn, nineSlicePatcher as Fr, createZoomOutEffect as Ft, svgToTexture as G, midnightPreset as Gn, createTheme as Gt, releaseSVGTextures as H, generateColorScale as Hn, register as Hr, resolveBadgeTextStyle as Ht, isAnimatedSignal as I, defaultSizeTokens as In, imageCreator as Ir, useGameObjectEffect as It, clampProgressValue as J, alpha as Jn, themeRegistry as Jt, registerBuiltins as K, oceanBluePreset as Kn, getThemedProps as Kt, unwrapSignal as L, defaultSpacingTokens as Ln, imagePatcher as Lr, Badge as Lt, DEFAULT_SPRING_CONFIG as M, createDefaultTheme as Mn, buildEmitZone as Mr, createWiggleEffect as Mt, SPRING_PRESETS as N, defaultTheme as Nn, buildEmitZoneFromLayout as Nr, createWobbleEffect as Nt, Accordion as O, useViewportSize as On, isParticleEmitter as Or, createSlideOutEffect as Ot, SpringPhysics as P, createTextStyleTokens as Pn, nineSliceCreator as Pr, createZoomInEffect as Pt, calculateOverlayPosition as Q, ensureContrast as Qn, mountJSX as Qt, KeyboardInputManager as R, defaultTextStyleTokens as Rn, graphicsCreator as Rr, Tag as Rt, CharTextInput as S, useMemo as Sn, particlesCreator as Sr, createJelloEffect as St, WrapText as T, useScene as Tn, applyEmitZone as Tr, createPulseEffect as Tt, useSVGTexture as U, getPreset as Un, viewCreator as Ut, releaseSVGTexture as V, forestGreenPreset as Vn, nodeRegistry as Vr, getBadgeText as Vt, useSVGTextures as W, getPresetWithMode as Wn, viewPatcher as Wt, ContextMenu as X, darken as Xn, getMountStats as Xt, getProgressRatio as Y, createTextStyle as Yn, createElement as Yt, Popover as Z, darkenHex as Zn, mount as Zt, Dropdown as _, useEffect as _n, DebugLogger as _r, createFadeEffect as _t, Tabs as a, View as an, numberToRgb as ar, RadioButton as at, calculateSliderSize as b, useLayoutRect as bn, spriteCreator as br, createFlipOutEffect as bt, Sidebar as c, getCurrent as cn, HexColor as cr, useThemeTokens as ct, NineSlice as d, getLayoutSize$1 as dn, normalizeGap as dr, DEFAULT_EFFECT as dt, patchVNode as en, hex as er, Particles as et, Joystick as f, getWorldLayoutRect as fn, tileSpriteCreator as fr, EFFECT_REGISTRY as ft, Image$1 as g, useCallback as gn, viewportRegistry as gr, createBreatheEffect as gt, useIconPreload as h, useBackgroundGraphics as hn, textPatcher as hr, createBounceEffect as ht, TabPanel as i, portalRegistry as in, numberToHex as ir, RadioGroup as it, useSprings as j, getRenderContext as jn, buildDeathZonesFromLayout as jr, createTadaEffect as jt, computed as k, useWorldLayoutRect as kn, PARTICLE_PRESET_REGISTRY as kr, createSpinEffect as kt, RefOriginView as l, getLayoutProps as ln, normalizeCornerRadius as lr, Checkbox as lt, createIconComponent as m, shouldComponentUpdate as mn, textCreator as mr, resolveEffect as mt, Toggle as n, unmount as nn, lighten as nr, Text as nt, RangeSlider as o, disposeCtx as on, rgbToHsl as or, Graphics as ot, Icon as p, shallowEqual as pn, tileSpritePatcher as pr, applyEffectByName as pt, ProgressBar as q, presets as qn, mergeThemes as qt, Tab as r, unmountJSX as rn, lightenHex as rr, Sprite as rt, Slider as s, getBackgroundGraphics as sn, rgbToNumber as sr, DebugPanel as st, TransformOriginView as t, remountAll as tn, hexToNumber as tr, TileSprite as tt, NineSliceButton as u, getLayoutRect as un, normalizeEdgeInsets as ur, Button as ut, ScrollView as v, useForceRedraw as vn, DevConfig as vr, createFlashEffect as vt, AlertDialog as w, useRef as wn, applyDeathZone as wr, createPressEffect as wt, Divider as x, useLayoutSize as xn, spritePatcher as xr, createFloatEffect as xt, ScrollSlider as y, useLayoutEffect as yn, DevPresets as yr, createFlipInEffect as yt, DOMInputElement as z, applyDarkMode as zn, graphicsPatcher as zr, formatBadgeCount as zt };
|
|
29258
30482
|
|
|
29259
|
-
//# sourceMappingURL=custom-
|
|
30483
|
+
//# sourceMappingURL=custom-DMZASXll.js.map
|