@almadar/ui 5.62.0 → 5.63.2
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/dist/avl/index.cjs +526 -161
- package/dist/avl/index.js +526 -161
- package/dist/components/core/atoms/Box.d.ts +2 -0
- package/dist/components/core/molecules/CalendarGrid.d.ts +9 -1
- package/dist/components/core/molecules/PositionedCanvas.d.ts +14 -1
- package/dist/components/core/molecules/ReplyTree.d.ts +13 -1
- package/dist/components/game/molecules/three/index.cjs +64 -0
- package/dist/components/game/molecules/three/index.js +64 -0
- package/dist/components/game/organisms/hooks/useCamera.d.ts +16 -0
- package/dist/components/index.cjs +526 -162
- package/dist/components/index.js +526 -162
- package/dist/components/marketing/organisms/CaseStudyOrganism.d.ts +10 -1
- package/dist/components/marketing/organisms/FeatureGridOrganism.d.ts +10 -1
- package/dist/components/marketing/organisms/HeroOrganism.d.ts +24 -1
- package/dist/components/marketing/organisms/PricingOrganism.d.ts +14 -1
- package/dist/components/marketing/organisms/ShowcaseOrganism.d.ts +14 -1
- package/dist/components/marketing/organisms/StatsOrganism.d.ts +6 -1
- package/dist/components/marketing/organisms/StepFlowOrganism.d.ts +9 -1
- package/dist/components/marketing/organisms/TeamOrganism.d.ts +10 -1
- package/dist/docs/index.cjs +64 -0
- package/dist/docs/index.d.cts +2 -0
- package/dist/docs/index.js +64 -0
- package/dist/hooks/index.cjs +148 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.js +147 -1
- package/dist/hooks/useCanvasGestures.d.ts +44 -0
- package/dist/hooks/useTapReveal.d.ts +32 -0
- package/dist/marketing/index.cjs +59 -0
- package/dist/marketing/index.d.cts +2 -0
- package/dist/marketing/index.js +59 -0
- package/dist/providers/index.cjs +526 -161
- package/dist/providers/index.js +526 -161
- package/dist/runtime/index.cjs +526 -161
- package/dist/runtime/index.js +526 -161
- package/package.json +2 -2
package/dist/runtime/index.js
CHANGED
|
@@ -288,12 +288,60 @@ var init_useEventBus = __esm({
|
|
|
288
288
|
useEventBus_default = useEventBus;
|
|
289
289
|
}
|
|
290
290
|
});
|
|
291
|
+
function useTapReveal(options = {}) {
|
|
292
|
+
const { onReveal, onDismiss, refs, enabled = true } = options;
|
|
293
|
+
const [revealed, setRevealed] = useState(false);
|
|
294
|
+
const onRevealRef = useRef(onReveal);
|
|
295
|
+
const onDismissRef = useRef(onDismiss);
|
|
296
|
+
onRevealRef.current = onReveal;
|
|
297
|
+
onDismissRef.current = onDismiss;
|
|
298
|
+
const reveal = useCallback(() => {
|
|
299
|
+
setRevealed((wasRevealed) => {
|
|
300
|
+
if (!wasRevealed) onRevealRef.current?.();
|
|
301
|
+
return true;
|
|
302
|
+
});
|
|
303
|
+
}, []);
|
|
304
|
+
const dismiss = useCallback(() => {
|
|
305
|
+
setRevealed((wasRevealed) => {
|
|
306
|
+
if (wasRevealed) onDismissRef.current?.();
|
|
307
|
+
return false;
|
|
308
|
+
});
|
|
309
|
+
}, []);
|
|
310
|
+
const onPointerDown = useCallback(
|
|
311
|
+
(e) => {
|
|
312
|
+
if (!enabled || e.pointerType === "mouse") return;
|
|
313
|
+
if (revealed) dismiss();
|
|
314
|
+
else reveal();
|
|
315
|
+
},
|
|
316
|
+
[enabled, revealed, reveal, dismiss]
|
|
317
|
+
);
|
|
318
|
+
useEffect(() => {
|
|
319
|
+
if (!revealed || typeof document === "undefined") return;
|
|
320
|
+
const onDocDown = (ev) => {
|
|
321
|
+
const target = ev.target;
|
|
322
|
+
if (!(target instanceof Node)) return;
|
|
323
|
+
const inside = (refs ?? []).some((r) => r.current?.contains(target));
|
|
324
|
+
if (!inside) dismiss();
|
|
325
|
+
};
|
|
326
|
+
const id = setTimeout(() => document.addEventListener("pointerdown", onDocDown), 0);
|
|
327
|
+
return () => {
|
|
328
|
+
clearTimeout(id);
|
|
329
|
+
document.removeEventListener("pointerdown", onDocDown);
|
|
330
|
+
};
|
|
331
|
+
}, [revealed, refs, dismiss]);
|
|
332
|
+
return { revealed, triggerProps: { onPointerDown }, reveal, dismiss };
|
|
333
|
+
}
|
|
334
|
+
var init_useTapReveal = __esm({
|
|
335
|
+
"hooks/useTapReveal.ts"() {
|
|
336
|
+
}
|
|
337
|
+
});
|
|
291
338
|
var paddingStyles, paddingXStyles, paddingYStyles, marginStyles, marginXStyles, marginYStyles, bgStyles, roundedStyles, shadowStyles, displayStyles, overflowStyles, positionStyles, Box;
|
|
292
339
|
var init_Box = __esm({
|
|
293
340
|
"components/core/atoms/Box.tsx"() {
|
|
294
341
|
"use client";
|
|
295
342
|
init_cn();
|
|
296
343
|
init_useEventBus();
|
|
344
|
+
init_useTapReveal();
|
|
297
345
|
paddingStyles = {
|
|
298
346
|
none: "p-0",
|
|
299
347
|
xs: "p-1",
|
|
@@ -419,10 +467,12 @@ var init_Box = __esm({
|
|
|
419
467
|
action,
|
|
420
468
|
actionPayload,
|
|
421
469
|
hoverEvent,
|
|
470
|
+
tapReveal = true,
|
|
422
471
|
maxWidth,
|
|
423
472
|
onClick,
|
|
424
473
|
onMouseEnter,
|
|
425
474
|
onMouseLeave,
|
|
475
|
+
onPointerDown,
|
|
426
476
|
...rest
|
|
427
477
|
}, ref) => {
|
|
428
478
|
const eventBus = useEventBus();
|
|
@@ -445,6 +495,19 @@ var init_Box = __esm({
|
|
|
445
495
|
}
|
|
446
496
|
onMouseLeave?.(e);
|
|
447
497
|
}, [hoverEvent, eventBus, onMouseLeave]);
|
|
498
|
+
const { triggerProps } = useTapReveal({
|
|
499
|
+
enabled: tapReveal && !!hoverEvent,
|
|
500
|
+
onReveal: useCallback(() => {
|
|
501
|
+
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
|
|
502
|
+
}, [hoverEvent, eventBus]),
|
|
503
|
+
onDismiss: useCallback(() => {
|
|
504
|
+
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
|
|
505
|
+
}, [hoverEvent, eventBus])
|
|
506
|
+
});
|
|
507
|
+
const handlePointerDown = useCallback((e) => {
|
|
508
|
+
if (hoverEvent && tapReveal) triggerProps.onPointerDown(e);
|
|
509
|
+
onPointerDown?.(e);
|
|
510
|
+
}, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
|
|
448
511
|
const isClickable = action || onClick;
|
|
449
512
|
return React84__default.createElement(
|
|
450
513
|
Component2,
|
|
@@ -472,6 +535,7 @@ var init_Box = __esm({
|
|
|
472
535
|
onClick: isClickable ? handleClick : void 0,
|
|
473
536
|
onMouseEnter: hoverEvent || onMouseEnter ? handleMouseEnter : void 0,
|
|
474
537
|
onMouseLeave: hoverEvent || onMouseLeave ? handleMouseLeave : void 0,
|
|
538
|
+
onPointerDown: hoverEvent && tapReveal || onPointerDown ? handlePointerDown : void 0,
|
|
475
539
|
style: maxWidth ? { maxWidth, ...rest.style } : rest.style,
|
|
476
540
|
...rest
|
|
477
541
|
},
|
|
@@ -4882,6 +4946,11 @@ var init_TextHighlight = __esm({
|
|
|
4882
4946
|
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: false, annotationId });
|
|
4883
4947
|
onMouseLeave?.();
|
|
4884
4948
|
},
|
|
4949
|
+
onPointerDown: (e) => {
|
|
4950
|
+
if (e.pointerType === "mouse") return;
|
|
4951
|
+
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: true, annotationId });
|
|
4952
|
+
onMouseEnter?.();
|
|
4953
|
+
},
|
|
4885
4954
|
role: "button",
|
|
4886
4955
|
tabIndex: 0,
|
|
4887
4956
|
onKeyDown: (e) => {
|
|
@@ -5057,6 +5126,7 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5057
5126
|
init_Typography();
|
|
5058
5127
|
init_Divider();
|
|
5059
5128
|
init_cn();
|
|
5129
|
+
init_useTapReveal();
|
|
5060
5130
|
positionStyles2 = {
|
|
5061
5131
|
top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
|
|
5062
5132
|
bottom: "top-full left-1/2 -translate-x-1/2 mt-2",
|
|
@@ -5078,6 +5148,7 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5078
5148
|
const { t } = useTranslate();
|
|
5079
5149
|
const [isVisible, setIsVisible] = React84__default.useState(false);
|
|
5080
5150
|
const timeoutRef = React84__default.useRef(null);
|
|
5151
|
+
const triggerRef = React84__default.useRef(null);
|
|
5081
5152
|
const handleMouseEnter = () => {
|
|
5082
5153
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
5083
5154
|
timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
|
|
@@ -5086,6 +5157,8 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5086
5157
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
5087
5158
|
setIsVisible(false);
|
|
5088
5159
|
};
|
|
5160
|
+
const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
|
|
5161
|
+
const open = isVisible || revealed;
|
|
5089
5162
|
React84__default.useEffect(() => {
|
|
5090
5163
|
return () => {
|
|
5091
5164
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
@@ -5094,6 +5167,7 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5094
5167
|
return /* @__PURE__ */ jsxs(
|
|
5095
5168
|
Box,
|
|
5096
5169
|
{
|
|
5170
|
+
ref: triggerRef,
|
|
5097
5171
|
as: "span",
|
|
5098
5172
|
position: "relative",
|
|
5099
5173
|
display: "inline-block",
|
|
@@ -5102,9 +5176,10 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5102
5176
|
onMouseLeave: handleMouseLeave,
|
|
5103
5177
|
onFocus: handleMouseEnter,
|
|
5104
5178
|
onBlur: handleMouseLeave,
|
|
5179
|
+
onPointerDown: triggerProps.onPointerDown,
|
|
5105
5180
|
children: [
|
|
5106
5181
|
children,
|
|
5107
|
-
|
|
5182
|
+
open && /* @__PURE__ */ jsxs(
|
|
5108
5183
|
Box,
|
|
5109
5184
|
{
|
|
5110
5185
|
padding: "sm",
|
|
@@ -10520,6 +10595,36 @@ function useCamera() {
|
|
|
10520
10595
|
cameraRef.current.zoom = Math.max(0.5, Math.min(3, cameraRef.current.zoom * zoomDelta));
|
|
10521
10596
|
drawFn?.();
|
|
10522
10597
|
}, []);
|
|
10598
|
+
const handlePointerDown = useCallback((e) => {
|
|
10599
|
+
handleMouseDown(e);
|
|
10600
|
+
}, [handleMouseDown]);
|
|
10601
|
+
const handlePointerUp = useCallback(() => {
|
|
10602
|
+
handleMouseUp();
|
|
10603
|
+
}, [handleMouseUp]);
|
|
10604
|
+
const handlePointerMove = useCallback((e, drawFn) => {
|
|
10605
|
+
return handleMouseMove(e, drawFn);
|
|
10606
|
+
}, [handleMouseMove]);
|
|
10607
|
+
const panBy = useCallback((dx, dy, drawFn) => {
|
|
10608
|
+
cameraRef.current.x -= dx;
|
|
10609
|
+
cameraRef.current.y -= dy;
|
|
10610
|
+
targetCameraRef.current = null;
|
|
10611
|
+
drawFn?.();
|
|
10612
|
+
}, []);
|
|
10613
|
+
const zoomAtPoint = useCallback((factor, centerX, centerY, viewportSize, drawFn) => {
|
|
10614
|
+
const cam = cameraRef.current;
|
|
10615
|
+
const oldZoom = cam.zoom;
|
|
10616
|
+
const newZoom = Math.max(0.5, Math.min(3, oldZoom * factor));
|
|
10617
|
+
if (newZoom === oldZoom) {
|
|
10618
|
+
drawFn?.();
|
|
10619
|
+
return;
|
|
10620
|
+
}
|
|
10621
|
+
const inv = 1 / oldZoom - 1 / newZoom;
|
|
10622
|
+
cam.x += (centerX - viewportSize.width / 2) * inv;
|
|
10623
|
+
cam.y += (centerY - viewportSize.height / 2) * inv;
|
|
10624
|
+
cam.zoom = newZoom;
|
|
10625
|
+
targetCameraRef.current = null;
|
|
10626
|
+
drawFn?.();
|
|
10627
|
+
}, []);
|
|
10523
10628
|
const screenToWorld = useCallback((clientX, clientY, canvas, viewportSize) => {
|
|
10524
10629
|
const rect = canvas.getBoundingClientRect();
|
|
10525
10630
|
const screenX = clientX - rect.left;
|
|
@@ -10551,6 +10656,11 @@ function useCamera() {
|
|
|
10551
10656
|
handleMouseMove,
|
|
10552
10657
|
handleMouseLeave,
|
|
10553
10658
|
handleWheel,
|
|
10659
|
+
handlePointerDown,
|
|
10660
|
+
handlePointerUp,
|
|
10661
|
+
handlePointerMove,
|
|
10662
|
+
panBy,
|
|
10663
|
+
zoomAtPoint,
|
|
10554
10664
|
screenToWorld,
|
|
10555
10665
|
lerpToTarget
|
|
10556
10666
|
};
|
|
@@ -10560,6 +10670,113 @@ var init_useCamera = __esm({
|
|
|
10560
10670
|
"use client";
|
|
10561
10671
|
}
|
|
10562
10672
|
});
|
|
10673
|
+
function localPoint(canvas, clientX, clientY) {
|
|
10674
|
+
if (!canvas) return { x: clientX, y: clientY };
|
|
10675
|
+
const rect = canvas.getBoundingClientRect();
|
|
10676
|
+
return { x: clientX - rect.left, y: clientY - rect.top };
|
|
10677
|
+
}
|
|
10678
|
+
function useCanvasGestures(options) {
|
|
10679
|
+
const {
|
|
10680
|
+
canvasRef,
|
|
10681
|
+
enabled = true,
|
|
10682
|
+
wheelStep = 1.1,
|
|
10683
|
+
onPointerDown,
|
|
10684
|
+
onPointerMove,
|
|
10685
|
+
onPointerUp,
|
|
10686
|
+
onZoom,
|
|
10687
|
+
onPanDelta,
|
|
10688
|
+
onMultiTouchStart
|
|
10689
|
+
} = options;
|
|
10690
|
+
const pointers = useRef(/* @__PURE__ */ new Map());
|
|
10691
|
+
const pinch = useRef(null);
|
|
10692
|
+
const computePinch = useCallback(() => {
|
|
10693
|
+
const pts = [...pointers.current.values()];
|
|
10694
|
+
const dx = pts[1].x - pts[0].x;
|
|
10695
|
+
const dy = pts[1].y - pts[0].y;
|
|
10696
|
+
return {
|
|
10697
|
+
distance: Math.hypot(dx, dy) || 1,
|
|
10698
|
+
centroid: { x: (pts[0].x + pts[1].x) / 2, y: (pts[0].y + pts[1].y) / 2 }
|
|
10699
|
+
};
|
|
10700
|
+
}, []);
|
|
10701
|
+
const handlePointerDown = useCallback(
|
|
10702
|
+
(e) => {
|
|
10703
|
+
if (!enabled) return;
|
|
10704
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
10705
|
+
pointers.current.set(e.pointerId, localPoint(canvasRef.current, e.clientX, e.clientY));
|
|
10706
|
+
if (pointers.current.size === 2) {
|
|
10707
|
+
onMultiTouchStart?.();
|
|
10708
|
+
pinch.current = computePinch();
|
|
10709
|
+
} else if (pointers.current.size === 1) {
|
|
10710
|
+
onPointerDown?.(e);
|
|
10711
|
+
}
|
|
10712
|
+
},
|
|
10713
|
+
[enabled, canvasRef, onMultiTouchStart, computePinch, onPointerDown]
|
|
10714
|
+
);
|
|
10715
|
+
const handlePointerMove = useCallback(
|
|
10716
|
+
(e) => {
|
|
10717
|
+
if (!enabled) return;
|
|
10718
|
+
if (pointers.current.has(e.pointerId)) {
|
|
10719
|
+
pointers.current.set(e.pointerId, localPoint(canvasRef.current, e.clientX, e.clientY));
|
|
10720
|
+
}
|
|
10721
|
+
if (pointers.current.size >= 2 && pinch.current) {
|
|
10722
|
+
const next = computePinch();
|
|
10723
|
+
const prev = pinch.current;
|
|
10724
|
+
if (next.distance !== prev.distance) {
|
|
10725
|
+
onZoom?.(next.distance / prev.distance, next.centroid.x, next.centroid.y);
|
|
10726
|
+
}
|
|
10727
|
+
onPanDelta?.(next.centroid.x - prev.centroid.x, next.centroid.y - prev.centroid.y);
|
|
10728
|
+
pinch.current = next;
|
|
10729
|
+
return;
|
|
10730
|
+
}
|
|
10731
|
+
onPointerMove?.(e);
|
|
10732
|
+
},
|
|
10733
|
+
[enabled, canvasRef, computePinch, onZoom, onPanDelta, onPointerMove]
|
|
10734
|
+
);
|
|
10735
|
+
const endPointer = useCallback(
|
|
10736
|
+
(e, fireUp) => {
|
|
10737
|
+
const wasMulti = pointers.current.size >= 2;
|
|
10738
|
+
pointers.current.delete(e.pointerId);
|
|
10739
|
+
if (pointers.current.size < 2) pinch.current = null;
|
|
10740
|
+
if (wasMulti && pointers.current.size === 1) return;
|
|
10741
|
+
if (pointers.current.size === 0 && fireUp) onPointerUp?.(e);
|
|
10742
|
+
},
|
|
10743
|
+
[onPointerUp]
|
|
10744
|
+
);
|
|
10745
|
+
const handlePointerUp = useCallback(
|
|
10746
|
+
(e) => {
|
|
10747
|
+
if (!enabled) return;
|
|
10748
|
+
endPointer(e, true);
|
|
10749
|
+
},
|
|
10750
|
+
[enabled, endPointer]
|
|
10751
|
+
);
|
|
10752
|
+
const handlePointerCancel = useCallback(
|
|
10753
|
+
(e) => {
|
|
10754
|
+
if (!enabled) return;
|
|
10755
|
+
endPointer(e, false);
|
|
10756
|
+
},
|
|
10757
|
+
[enabled, endPointer]
|
|
10758
|
+
);
|
|
10759
|
+
const handleWheel = useCallback(
|
|
10760
|
+
(e) => {
|
|
10761
|
+
if (!enabled) return;
|
|
10762
|
+
e.preventDefault();
|
|
10763
|
+
const { x, y } = localPoint(canvasRef.current, e.clientX, e.clientY);
|
|
10764
|
+
onZoom?.(e.deltaY < 0 ? wheelStep : 1 / wheelStep, x, y);
|
|
10765
|
+
},
|
|
10766
|
+
[enabled, canvasRef, wheelStep, onZoom]
|
|
10767
|
+
);
|
|
10768
|
+
return {
|
|
10769
|
+
onPointerDown: handlePointerDown,
|
|
10770
|
+
onPointerMove: handlePointerMove,
|
|
10771
|
+
onPointerUp: handlePointerUp,
|
|
10772
|
+
onPointerCancel: handlePointerCancel,
|
|
10773
|
+
onWheel: handleWheel
|
|
10774
|
+
};
|
|
10775
|
+
}
|
|
10776
|
+
var init_useCanvasGestures = __esm({
|
|
10777
|
+
"hooks/useCanvasGestures.ts"() {
|
|
10778
|
+
}
|
|
10779
|
+
});
|
|
10563
10780
|
function unitAtlasUrl(unit) {
|
|
10564
10781
|
if (unit.spriteSheet) return unit.spriteSheet;
|
|
10565
10782
|
const sprite = unit.sprite;
|
|
@@ -10938,11 +11155,12 @@ function IsometricCanvas({
|
|
|
10938
11155
|
cameraRef,
|
|
10939
11156
|
targetCameraRef,
|
|
10940
11157
|
dragDistance,
|
|
10941
|
-
handleMouseDown,
|
|
10942
|
-
handleMouseUp,
|
|
10943
|
-
handleMouseMove,
|
|
10944
11158
|
handleMouseLeave,
|
|
10945
|
-
|
|
11159
|
+
handlePointerDown,
|
|
11160
|
+
handlePointerUp,
|
|
11161
|
+
handlePointerMove,
|
|
11162
|
+
panBy,
|
|
11163
|
+
zoomAtPoint,
|
|
10946
11164
|
screenToWorld,
|
|
10947
11165
|
lerpToTarget
|
|
10948
11166
|
} = useCamera();
|
|
@@ -11377,11 +11595,16 @@ function IsometricCanvas({
|
|
|
11377
11595
|
cancelAnimationFrame(rafIdRef.current);
|
|
11378
11596
|
};
|
|
11379
11597
|
}, [draw, units.length, validMoves.length, attackTargets.length, selectedUnitId, hasActiveEffects2, pendingCount, atlasPending, lerpToTarget, targetCameraRef]);
|
|
11380
|
-
const
|
|
11381
|
-
|
|
11382
|
-
|
|
11383
|
-
|
|
11384
|
-
|
|
11598
|
+
const singlePointerActiveRef = useRef(false);
|
|
11599
|
+
const handleCanvasPointerDown = useCallback((e) => {
|
|
11600
|
+
singlePointerActiveRef.current = true;
|
|
11601
|
+
if (enableCamera) handlePointerDown(e);
|
|
11602
|
+
}, [enableCamera, handlePointerDown]);
|
|
11603
|
+
const handleCanvasPointerMove = useCallback((e) => {
|
|
11604
|
+
if (enableCamera) handlePointerMove(e, () => draw(animTimeRef.current));
|
|
11605
|
+
}, [enableCamera, handlePointerMove, draw]);
|
|
11606
|
+
const handleCanvasHover = useCallback((e) => {
|
|
11607
|
+
if (singlePointerActiveRef.current) return;
|
|
11385
11608
|
if (!onTileHover && !tileHoverEvent || !canvasRef.current) return;
|
|
11386
11609
|
const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
|
|
11387
11610
|
const adjustedX = world.x - scaledTileWidth / 2;
|
|
@@ -11392,26 +11615,10 @@ function IsometricCanvas({
|
|
|
11392
11615
|
if (tileHoverEvent) eventBus.emit(`UI:${tileHoverEvent}`, { x: isoPos.x, y: isoPos.y });
|
|
11393
11616
|
onTileHover?.(isoPos.x, isoPos.y);
|
|
11394
11617
|
}
|
|
11395
|
-
}, [
|
|
11396
|
-
const
|
|
11397
|
-
|
|
11398
|
-
if (
|
|
11399
|
-
onTileLeave?.();
|
|
11400
|
-
}, [handleMouseLeave, onTileLeave, tileLeaveEvent, eventBus]);
|
|
11401
|
-
const handleWheelWithCamera = useCallback((e) => {
|
|
11402
|
-
if (enableCamera) {
|
|
11403
|
-
handleWheel(e, () => draw(animTimeRef.current));
|
|
11404
|
-
}
|
|
11405
|
-
}, [enableCamera, handleWheel, draw]);
|
|
11406
|
-
useEffect(() => {
|
|
11407
|
-
const canvas = canvasRef.current;
|
|
11408
|
-
if (!canvas) return;
|
|
11409
|
-
canvas.addEventListener("wheel", handleWheelWithCamera, { passive: false });
|
|
11410
|
-
return () => {
|
|
11411
|
-
canvas.removeEventListener("wheel", handleWheelWithCamera);
|
|
11412
|
-
};
|
|
11413
|
-
}, [handleWheelWithCamera]);
|
|
11414
|
-
const handleClick = useCallback((e) => {
|
|
11618
|
+
}, [onTileHover, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, tilesProp, tileHoverEvent, eventBus]);
|
|
11619
|
+
const handleCanvasPointerUp = useCallback((e) => {
|
|
11620
|
+
singlePointerActiveRef.current = false;
|
|
11621
|
+
if (enableCamera) handlePointerUp();
|
|
11415
11622
|
if (dragDistance() > 5) return;
|
|
11416
11623
|
if (!canvasRef.current) return;
|
|
11417
11624
|
const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
|
|
@@ -11429,7 +11636,32 @@ function IsometricCanvas({
|
|
|
11429
11636
|
onTileClick?.(isoPos.x, isoPos.y);
|
|
11430
11637
|
}
|
|
11431
11638
|
}
|
|
11432
|
-
}, [dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, units, tilesProp, onUnitClick, onTileClick, unitClickEvent, tileClickEvent, eventBus]);
|
|
11639
|
+
}, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, units, tilesProp, onUnitClick, onTileClick, unitClickEvent, tileClickEvent, eventBus]);
|
|
11640
|
+
const handleCanvasPointerLeave = useCallback(() => {
|
|
11641
|
+
handleMouseLeave();
|
|
11642
|
+
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
11643
|
+
onTileLeave?.();
|
|
11644
|
+
}, [handleMouseLeave, onTileLeave, tileLeaveEvent, eventBus]);
|
|
11645
|
+
const applyZoom = useCallback((factor, centerX, centerY) => {
|
|
11646
|
+
if (enableCamera) zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw(animTimeRef.current));
|
|
11647
|
+
}, [enableCamera, zoomAtPoint, viewportSize, draw]);
|
|
11648
|
+
const applyPanDelta = useCallback((dx, dy) => {
|
|
11649
|
+
if (enableCamera) panBy(dx, dy, () => draw(animTimeRef.current));
|
|
11650
|
+
}, [enableCamera, panBy, draw]);
|
|
11651
|
+
const cancelSinglePointer = useCallback(() => {
|
|
11652
|
+
singlePointerActiveRef.current = false;
|
|
11653
|
+
if (enableCamera) handlePointerUp();
|
|
11654
|
+
}, [enableCamera, handlePointerUp]);
|
|
11655
|
+
const gestureHandlers = useCanvasGestures({
|
|
11656
|
+
canvasRef,
|
|
11657
|
+
enabled: enableCamera || !!onTileHover || !!tileHoverEvent || !!onTileClick || !!tileClickEvent || !!onUnitClick || !!unitClickEvent,
|
|
11658
|
+
onPointerDown: handleCanvasPointerDown,
|
|
11659
|
+
onPointerMove: handleCanvasPointerMove,
|
|
11660
|
+
onPointerUp: handleCanvasPointerUp,
|
|
11661
|
+
onZoom: applyZoom,
|
|
11662
|
+
onPanDelta: applyPanDelta,
|
|
11663
|
+
onMultiTouchStart: cancelSinglePointer
|
|
11664
|
+
});
|
|
11433
11665
|
if (error) {
|
|
11434
11666
|
return /* @__PURE__ */ jsx(ErrorState, { title: t("canvas.errorTitle"), message: error.message, className });
|
|
11435
11667
|
}
|
|
@@ -11461,13 +11693,17 @@ function IsometricCanvas({
|
|
|
11461
11693
|
{
|
|
11462
11694
|
ref: canvasRef,
|
|
11463
11695
|
"data-testid": "game-canvas",
|
|
11464
|
-
|
|
11465
|
-
|
|
11466
|
-
|
|
11467
|
-
|
|
11468
|
-
|
|
11696
|
+
onPointerDown: gestureHandlers.onPointerDown,
|
|
11697
|
+
onPointerMove: (e) => {
|
|
11698
|
+
gestureHandlers.onPointerMove(e);
|
|
11699
|
+
handleCanvasHover(e);
|
|
11700
|
+
},
|
|
11701
|
+
onPointerUp: gestureHandlers.onPointerUp,
|
|
11702
|
+
onPointerCancel: gestureHandlers.onPointerCancel,
|
|
11703
|
+
onPointerLeave: handleCanvasPointerLeave,
|
|
11704
|
+
onWheel: gestureHandlers.onWheel,
|
|
11469
11705
|
onContextMenu: (e) => e.preventDefault(),
|
|
11470
|
-
className: "cursor-pointer",
|
|
11706
|
+
className: "cursor-pointer touch-none",
|
|
11471
11707
|
style: {
|
|
11472
11708
|
width: viewportSize.width,
|
|
11473
11709
|
height: viewportSize.height
|
|
@@ -11521,6 +11757,7 @@ var init_IsometricCanvas = __esm({
|
|
|
11521
11757
|
init_ErrorState();
|
|
11522
11758
|
init_useImageCache();
|
|
11523
11759
|
init_useCamera();
|
|
11760
|
+
init_useCanvasGestures();
|
|
11524
11761
|
init_useUnitSpriteAtlas();
|
|
11525
11762
|
init_verificationRegistry();
|
|
11526
11763
|
init_isometric();
|
|
@@ -14636,6 +14873,10 @@ var init_StateMachineView = __esm({
|
|
|
14636
14873
|
const handleMouseLeave2 = () => {
|
|
14637
14874
|
onHover(null, 0, 0);
|
|
14638
14875
|
};
|
|
14876
|
+
const handlePointerDown2 = (e) => {
|
|
14877
|
+
if (e.pointerType === "mouse") return;
|
|
14878
|
+
handleMouseEnter2();
|
|
14879
|
+
};
|
|
14639
14880
|
return /* @__PURE__ */ jsxs(
|
|
14640
14881
|
"g",
|
|
14641
14882
|
{
|
|
@@ -14645,6 +14886,7 @@ var init_StateMachineView = __esm({
|
|
|
14645
14886
|
onClick: () => onClick?.(bundle),
|
|
14646
14887
|
onMouseEnter: handleMouseEnter2,
|
|
14647
14888
|
onMouseLeave: handleMouseLeave2,
|
|
14889
|
+
onPointerDown: handlePointerDown2,
|
|
14648
14890
|
style: { pointerEvents: "auto" },
|
|
14649
14891
|
children: [
|
|
14650
14892
|
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
@@ -14762,6 +15004,10 @@ var init_StateMachineView = __esm({
|
|
|
14762
15004
|
const handleMouseLeave = useCallback(() => {
|
|
14763
15005
|
onHover(null, 0, 0);
|
|
14764
15006
|
}, [onHover]);
|
|
15007
|
+
const handlePointerDown = useCallback((e) => {
|
|
15008
|
+
if (e.pointerType === "mouse") return;
|
|
15009
|
+
handleMouseEnter();
|
|
15010
|
+
}, [handleMouseEnter]);
|
|
14765
15011
|
const uniqueMarkerId = `arrow-${bundle.id}`;
|
|
14766
15012
|
const hasDetails = bundle.labels.some((l) => l.hasDetails);
|
|
14767
15013
|
return /* @__PURE__ */ jsxs(
|
|
@@ -14773,6 +15019,7 @@ var init_StateMachineView = __esm({
|
|
|
14773
15019
|
onClick: () => onClick?.(bundle),
|
|
14774
15020
|
onMouseEnter: handleMouseEnter,
|
|
14775
15021
|
onMouseLeave: handleMouseLeave,
|
|
15022
|
+
onPointerDown: handlePointerDown,
|
|
14776
15023
|
style: { pointerEvents: "auto" },
|
|
14777
15024
|
children: [
|
|
14778
15025
|
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
@@ -23271,10 +23518,84 @@ function SubMenu({
|
|
|
23271
23518
|
);
|
|
23272
23519
|
return typeof document !== "undefined" ? createPortal(panel, document.body) : panel;
|
|
23273
23520
|
}
|
|
23521
|
+
function MenuItemRow({
|
|
23522
|
+
item,
|
|
23523
|
+
itemId,
|
|
23524
|
+
hasSubMenu,
|
|
23525
|
+
isDanger,
|
|
23526
|
+
direction,
|
|
23527
|
+
isSubMenuOpen,
|
|
23528
|
+
activeSubMenuRef,
|
|
23529
|
+
eventBus,
|
|
23530
|
+
onItemClick,
|
|
23531
|
+
openSubMenu
|
|
23532
|
+
}) {
|
|
23533
|
+
const rowRef = useRef(null);
|
|
23534
|
+
const { triggerProps } = useTapReveal({
|
|
23535
|
+
enabled: hasSubMenu,
|
|
23536
|
+
onReveal: () => openSubMenu(itemId, rowRef.current),
|
|
23537
|
+
refs: [rowRef]
|
|
23538
|
+
});
|
|
23539
|
+
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
23540
|
+
/* @__PURE__ */ jsx(
|
|
23541
|
+
Box,
|
|
23542
|
+
{
|
|
23543
|
+
ref: rowRef,
|
|
23544
|
+
as: "button",
|
|
23545
|
+
onClick: () => onItemClick({ ...item, id: itemId }, itemId),
|
|
23546
|
+
"aria-disabled": item.disabled || void 0,
|
|
23547
|
+
onMouseEnter: (e) => {
|
|
23548
|
+
if (hasSubMenu) openSubMenu(itemId, e.currentTarget);
|
|
23549
|
+
},
|
|
23550
|
+
onPointerDown: hasSubMenu ? triggerProps.onPointerDown : void 0,
|
|
23551
|
+
"data-testid": item.event ? `action-${item.event}` : void 0,
|
|
23552
|
+
className: cn(
|
|
23553
|
+
"w-full flex items-center justify-between gap-3 px-4 py-2 text-start",
|
|
23554
|
+
"text-sm transition-colors",
|
|
23555
|
+
"hover:bg-muted",
|
|
23556
|
+
"focus:outline-none focus:bg-muted",
|
|
23557
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
23558
|
+
item.disabled && "cursor-not-allowed",
|
|
23559
|
+
isDanger && "text-error hover:bg-error/10"
|
|
23560
|
+
),
|
|
23561
|
+
children: /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
23562
|
+
item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, size: "sm", className: "flex-shrink-0" }) : /* @__PURE__ */ jsx(Icon, { icon: item.icon, size: "sm", className: "flex-shrink-0" })),
|
|
23563
|
+
/* @__PURE__ */ jsx(
|
|
23564
|
+
Typography,
|
|
23565
|
+
{
|
|
23566
|
+
variant: "small",
|
|
23567
|
+
className: cn("flex-1", isDanger && "text-red-600"),
|
|
23568
|
+
children: item.label
|
|
23569
|
+
}
|
|
23570
|
+
),
|
|
23571
|
+
item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: item.badge }),
|
|
23572
|
+
hasSubMenu && /* @__PURE__ */ jsx(
|
|
23573
|
+
Icon,
|
|
23574
|
+
{
|
|
23575
|
+
name: direction === "rtl" ? "chevron-left" : "chevron-right",
|
|
23576
|
+
size: "sm",
|
|
23577
|
+
className: "flex-shrink-0"
|
|
23578
|
+
}
|
|
23579
|
+
)
|
|
23580
|
+
] })
|
|
23581
|
+
}
|
|
23582
|
+
),
|
|
23583
|
+
hasSubMenu && isSubMenuOpen && item.subMenu && /* @__PURE__ */ jsx(
|
|
23584
|
+
SubMenu,
|
|
23585
|
+
{
|
|
23586
|
+
items: item.subMenu,
|
|
23587
|
+
itemRef: activeSubMenuRef,
|
|
23588
|
+
direction,
|
|
23589
|
+
eventBus
|
|
23590
|
+
}
|
|
23591
|
+
)
|
|
23592
|
+
] });
|
|
23593
|
+
}
|
|
23274
23594
|
var MENU_GAP, menuContainerStyles, Menu;
|
|
23275
23595
|
var init_Menu = __esm({
|
|
23276
23596
|
"components/core/molecules/Menu.tsx"() {
|
|
23277
23597
|
"use client";
|
|
23598
|
+
init_useTapReveal();
|
|
23278
23599
|
init_Box();
|
|
23279
23600
|
init_Icon();
|
|
23280
23601
|
init_Divider();
|
|
@@ -23329,6 +23650,10 @@ var init_Menu = __esm({
|
|
|
23329
23650
|
setIsOpen(false);
|
|
23330
23651
|
}
|
|
23331
23652
|
};
|
|
23653
|
+
const openSubMenu = (itemId, el) => {
|
|
23654
|
+
setActiveSubMenu(itemId);
|
|
23655
|
+
setActiveSubMenuRef(el);
|
|
23656
|
+
};
|
|
23332
23657
|
useEffect(() => {
|
|
23333
23658
|
if (isOpen) {
|
|
23334
23659
|
updatePosition();
|
|
@@ -23372,61 +23697,22 @@ var init_Menu = __esm({
|
|
|
23372
23697
|
if (isDivider) {
|
|
23373
23698
|
return /* @__PURE__ */ jsx(Divider, { className: "my-1" }, `divider-${index}`);
|
|
23374
23699
|
}
|
|
23375
|
-
return /* @__PURE__ */
|
|
23376
|
-
|
|
23377
|
-
|
|
23378
|
-
|
|
23379
|
-
|
|
23380
|
-
|
|
23381
|
-
|
|
23382
|
-
|
|
23383
|
-
|
|
23384
|
-
|
|
23385
|
-
|
|
23386
|
-
|
|
23387
|
-
|
|
23388
|
-
|
|
23389
|
-
|
|
23390
|
-
|
|
23391
|
-
"text-sm transition-colors",
|
|
23392
|
-
"hover:bg-muted",
|
|
23393
|
-
"focus:outline-none focus:bg-muted",
|
|
23394
|
-
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
23395
|
-
item.disabled && "cursor-not-allowed",
|
|
23396
|
-
isDanger && "text-error hover:bg-error/10"
|
|
23397
|
-
),
|
|
23398
|
-
children: /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
23399
|
-
item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, size: "sm", className: "flex-shrink-0" }) : /* @__PURE__ */ jsx(Icon, { icon: item.icon, size: "sm", className: "flex-shrink-0" })),
|
|
23400
|
-
/* @__PURE__ */ jsx(
|
|
23401
|
-
Typography,
|
|
23402
|
-
{
|
|
23403
|
-
variant: "small",
|
|
23404
|
-
className: cn("flex-1", isDanger && "text-red-600"),
|
|
23405
|
-
children: item.label
|
|
23406
|
-
}
|
|
23407
|
-
),
|
|
23408
|
-
item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: item.badge }),
|
|
23409
|
-
hasSubMenu && /* @__PURE__ */ jsx(
|
|
23410
|
-
Icon,
|
|
23411
|
-
{
|
|
23412
|
-
name: direction === "rtl" ? "chevron-left" : "chevron-right",
|
|
23413
|
-
size: "sm",
|
|
23414
|
-
className: "flex-shrink-0"
|
|
23415
|
-
}
|
|
23416
|
-
)
|
|
23417
|
-
] })
|
|
23418
|
-
}
|
|
23419
|
-
),
|
|
23420
|
-
hasSubMenu && activeSubMenu === itemId && item.subMenu && /* @__PURE__ */ jsx(
|
|
23421
|
-
SubMenu,
|
|
23422
|
-
{
|
|
23423
|
-
items: item.subMenu,
|
|
23424
|
-
itemRef: activeSubMenuRef,
|
|
23425
|
-
direction,
|
|
23426
|
-
eventBus
|
|
23427
|
-
}
|
|
23428
|
-
)
|
|
23429
|
-
] }, itemId);
|
|
23700
|
+
return /* @__PURE__ */ jsx(
|
|
23701
|
+
MenuItemRow,
|
|
23702
|
+
{
|
|
23703
|
+
item,
|
|
23704
|
+
itemId,
|
|
23705
|
+
hasSubMenu,
|
|
23706
|
+
isDanger,
|
|
23707
|
+
direction,
|
|
23708
|
+
isSubMenuOpen: activeSubMenu === itemId,
|
|
23709
|
+
activeSubMenuRef,
|
|
23710
|
+
eventBus,
|
|
23711
|
+
onItemClick: handleItemClick,
|
|
23712
|
+
openSubMenu
|
|
23713
|
+
},
|
|
23714
|
+
itemId
|
|
23715
|
+
);
|
|
23430
23716
|
});
|
|
23431
23717
|
const panel = isOpen && triggerRect ? /* @__PURE__ */ jsxs(
|
|
23432
23718
|
"div",
|
|
@@ -25729,6 +26015,7 @@ var init_Popover = __esm({
|
|
|
25729
26015
|
"use client";
|
|
25730
26016
|
init_Typography();
|
|
25731
26017
|
init_cn();
|
|
26018
|
+
init_useTapReveal();
|
|
25732
26019
|
arrowClasses = {
|
|
25733
26020
|
top: "top-full left-1/2 -translate-x-1/2 border-t-white border-l-transparent border-r-transparent border-b-transparent",
|
|
25734
26021
|
bottom: "bottom-full left-1/2 -translate-x-1/2 border-b-white border-l-transparent border-r-transparent border-t-transparent",
|
|
@@ -25799,18 +26086,32 @@ var init_Popover = __esm({
|
|
|
25799
26086
|
document.addEventListener("mousedown", handleClickOutside);
|
|
25800
26087
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
25801
26088
|
}, [isOpen, trigger]);
|
|
25802
|
-
const triggerProps
|
|
26089
|
+
const { triggerProps: tapTriggerProps } = useTapReveal({
|
|
26090
|
+
enabled: trigger === "hover",
|
|
26091
|
+
onReveal: handleOpen,
|
|
26092
|
+
onDismiss: handleClose,
|
|
26093
|
+
refs: [triggerRef, popoverRef]
|
|
26094
|
+
});
|
|
26095
|
+
const handlerProps = trigger === "click" ? {
|
|
25803
26096
|
onClick: handleToggle
|
|
25804
26097
|
} : {
|
|
25805
26098
|
onMouseEnter: handleOpen,
|
|
25806
|
-
onMouseLeave: handleClose
|
|
26099
|
+
onMouseLeave: handleClose,
|
|
26100
|
+
onPointerDown: tapTriggerProps.onPointerDown
|
|
25807
26101
|
};
|
|
25808
26102
|
const childElement = React84__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
26103
|
+
const childPointerDown = childElement.props.onPointerDown;
|
|
25809
26104
|
const triggerElement = React84__default.cloneElement(
|
|
25810
26105
|
childElement,
|
|
25811
26106
|
{
|
|
25812
26107
|
ref: triggerRef,
|
|
25813
|
-
...
|
|
26108
|
+
...handlerProps,
|
|
26109
|
+
...trigger === "hover" ? {
|
|
26110
|
+
onPointerDown: (e) => {
|
|
26111
|
+
tapTriggerProps.onPointerDown(e);
|
|
26112
|
+
childPointerDown?.(e);
|
|
26113
|
+
}
|
|
26114
|
+
} : void 0
|
|
25814
26115
|
}
|
|
25815
26116
|
);
|
|
25816
26117
|
const panel = isOpen && triggerRect ? /* @__PURE__ */ jsxs(
|
|
@@ -26341,6 +26642,7 @@ var init_Tooltip = __esm({
|
|
|
26341
26642
|
"use client";
|
|
26342
26643
|
init_Typography();
|
|
26343
26644
|
init_cn();
|
|
26645
|
+
init_useTapReveal();
|
|
26344
26646
|
TRIGGER_GAP2 = 8;
|
|
26345
26647
|
arrowClasses2 = {
|
|
26346
26648
|
top: "top-full left-1/2 -translate-x-1/2 border-t-primary border-l-transparent border-r-transparent border-b-transparent",
|
|
@@ -26385,6 +26687,11 @@ var init_Tooltip = __esm({
|
|
|
26385
26687
|
setIsVisible(false);
|
|
26386
26688
|
}, hideDelay);
|
|
26387
26689
|
};
|
|
26690
|
+
const { triggerProps } = useTapReveal({
|
|
26691
|
+
onReveal: handleMouseEnter,
|
|
26692
|
+
onDismiss: handleMouseLeave,
|
|
26693
|
+
refs: [triggerRef, tooltipRef]
|
|
26694
|
+
});
|
|
26388
26695
|
useLayoutEffect(() => {
|
|
26389
26696
|
if (isVisible) {
|
|
26390
26697
|
updatePosition();
|
|
@@ -26397,12 +26704,17 @@ var init_Tooltip = __esm({
|
|
|
26397
26704
|
};
|
|
26398
26705
|
}, []);
|
|
26399
26706
|
const triggerElement = React84__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
26707
|
+
const childPointerDown = triggerElement.props.onPointerDown;
|
|
26400
26708
|
const trigger = React84__default.cloneElement(triggerElement, {
|
|
26401
26709
|
ref: triggerRef,
|
|
26402
26710
|
onMouseEnter: handleMouseEnter,
|
|
26403
26711
|
onMouseLeave: handleMouseLeave,
|
|
26404
26712
|
onFocus: handleMouseEnter,
|
|
26405
|
-
onBlur: handleMouseLeave
|
|
26713
|
+
onBlur: handleMouseLeave,
|
|
26714
|
+
onPointerDown: (e) => {
|
|
26715
|
+
triggerProps.onPointerDown(e);
|
|
26716
|
+
childPointerDown?.(e);
|
|
26717
|
+
}
|
|
26406
26718
|
});
|
|
26407
26719
|
const tooltipContent = isVisible && triggerRect ? /* @__PURE__ */ jsxs(
|
|
26408
26720
|
"div",
|
|
@@ -29752,6 +30064,14 @@ var init_GraphView = __esm({
|
|
|
29752
30064
|
},
|
|
29753
30065
|
[onNodeClick]
|
|
29754
30066
|
);
|
|
30067
|
+
const handleNodePointerDown = useCallback(
|
|
30068
|
+
(e, node) => {
|
|
30069
|
+
if (e.pointerType === "mouse") return;
|
|
30070
|
+
handleNodeMouseEnter(node);
|
|
30071
|
+
handleNodeClickInternal(node);
|
|
30072
|
+
},
|
|
30073
|
+
[handleNodeMouseEnter, handleNodeClickInternal]
|
|
30074
|
+
);
|
|
29755
30075
|
if (nodes.length === 0) {
|
|
29756
30076
|
return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center", className), style: { width: w, height: h }, children: /* @__PURE__ */ jsx(Box, { className: "text-muted-foreground text-sm", children: t("display.noGraphData") }) });
|
|
29757
30077
|
}
|
|
@@ -29811,6 +30131,7 @@ var init_GraphView = __esm({
|
|
|
29811
30131
|
onMouseEnter: () => handleNodeMouseEnter(node),
|
|
29812
30132
|
onMouseLeave: handleNodeMouseLeave,
|
|
29813
30133
|
onClick: () => handleNodeClickInternal(node),
|
|
30134
|
+
onPointerDown: (e) => handleNodePointerDown(e, node),
|
|
29814
30135
|
children: [
|
|
29815
30136
|
/* @__PURE__ */ jsx(
|
|
29816
30137
|
"circle",
|
|
@@ -29891,13 +30212,13 @@ var init_MapView = __esm({
|
|
|
29891
30212
|
shadowSize: [41, 41]
|
|
29892
30213
|
});
|
|
29893
30214
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
29894
|
-
const { useEffect:
|
|
30215
|
+
const { useEffect: useEffect84, useRef: useRef80, useCallback: useCallback126, useState: useState115 } = React84__default;
|
|
29895
30216
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
29896
30217
|
const { useEventBus: useEventBus4 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
29897
30218
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
29898
30219
|
const map = useMap();
|
|
29899
|
-
const prevRef =
|
|
29900
|
-
|
|
30220
|
+
const prevRef = useRef80({ centerLat, centerLng, zoom });
|
|
30221
|
+
useEffect84(() => {
|
|
29901
30222
|
const prev = prevRef.current;
|
|
29902
30223
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
29903
30224
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -29908,7 +30229,7 @@ var init_MapView = __esm({
|
|
|
29908
30229
|
}
|
|
29909
30230
|
function MapClickHandler({ onMapClick }) {
|
|
29910
30231
|
const map = useMap();
|
|
29911
|
-
|
|
30232
|
+
useEffect84(() => {
|
|
29912
30233
|
if (!onMapClick) return;
|
|
29913
30234
|
const handler = (e) => {
|
|
29914
30235
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -29936,8 +30257,8 @@ var init_MapView = __esm({
|
|
|
29936
30257
|
showAttribution = true
|
|
29937
30258
|
}) {
|
|
29938
30259
|
const eventBus = useEventBus4();
|
|
29939
|
-
const [clickedPosition, setClickedPosition] =
|
|
29940
|
-
const handleMapClick =
|
|
30260
|
+
const [clickedPosition, setClickedPosition] = useState115(null);
|
|
30261
|
+
const handleMapClick = useCallback126((lat, lng) => {
|
|
29941
30262
|
if (showClickedPin) {
|
|
29942
30263
|
setClickedPosition({ lat, lng });
|
|
29943
30264
|
}
|
|
@@ -29946,7 +30267,7 @@ var init_MapView = __esm({
|
|
|
29946
30267
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
29947
30268
|
}
|
|
29948
30269
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
29949
|
-
const handleMarkerClick =
|
|
30270
|
+
const handleMarkerClick = useCallback126((marker) => {
|
|
29950
30271
|
onMarkerClick?.(marker);
|
|
29951
30272
|
if (markerClickEvent) {
|
|
29952
30273
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -30287,7 +30608,7 @@ var init_StarRating = __esm({
|
|
|
30287
30608
|
"aria-valuenow": value,
|
|
30288
30609
|
tabIndex: readOnly ? void 0 : 0,
|
|
30289
30610
|
onKeyDown: handleKeyDown,
|
|
30290
|
-
|
|
30611
|
+
onPointerLeave: () => setHoverValue(null),
|
|
30291
30612
|
children: Array.from({ length: max }, (_, i) => {
|
|
30292
30613
|
const fillLevel = Math.max(0, Math.min(1, displayValue - i));
|
|
30293
30614
|
const isFull = fillLevel >= 1;
|
|
@@ -30297,7 +30618,7 @@ var init_StarRating = __esm({
|
|
|
30297
30618
|
{
|
|
30298
30619
|
className: "relative inline-block",
|
|
30299
30620
|
onClick: () => handleStarClick(i, false),
|
|
30300
|
-
|
|
30621
|
+
onPointerMove: (e) => {
|
|
30301
30622
|
if (readOnly) return;
|
|
30302
30623
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
30303
30624
|
const isLeftHalf = e.clientX - rect.left < rect.width / 2;
|
|
@@ -34187,7 +34508,7 @@ var init_PositionedCanvas = __esm({
|
|
|
34187
34508
|
{
|
|
34188
34509
|
ref: containerRef,
|
|
34189
34510
|
"data-testid": "positioned-canvas",
|
|
34190
|
-
className: "relative bg-background border border-border rounded-container overflow-hidden",
|
|
34511
|
+
className: "relative bg-background border border-border rounded-container overflow-hidden touch-none",
|
|
34191
34512
|
style: { width, height },
|
|
34192
34513
|
onClick: handleContainerClick,
|
|
34193
34514
|
children: items.map((item) => {
|
|
@@ -38334,6 +38655,13 @@ var init_DocumentViewer = __esm({
|
|
|
38334
38655
|
DocumentViewer.displayName = "DocumentViewer";
|
|
38335
38656
|
}
|
|
38336
38657
|
});
|
|
38658
|
+
function measureLabelWidth(text) {
|
|
38659
|
+
if (typeof document === "undefined") return text.length * 6;
|
|
38660
|
+
if (!labelMeasureCtx) labelMeasureCtx = document.createElement("canvas").getContext("2d");
|
|
38661
|
+
if (!labelMeasureCtx) return text.length * 6;
|
|
38662
|
+
labelMeasureCtx.font = "10px system-ui";
|
|
38663
|
+
return labelMeasureCtx.measureText(text).width;
|
|
38664
|
+
}
|
|
38337
38665
|
function getGroupColor(group, groups) {
|
|
38338
38666
|
if (!group) return GROUP_COLORS2[0];
|
|
38339
38667
|
const idx = groups.indexOf(group);
|
|
@@ -38345,7 +38673,7 @@ function resolveColor2(color, el) {
|
|
|
38345
38673
|
const resolved = getComputedStyle(el).getPropertyValue(m[1]).trim();
|
|
38346
38674
|
return resolved || (m[2]?.trim() ?? "#888888");
|
|
38347
38675
|
}
|
|
38348
|
-
var GROUP_COLORS2, GraphCanvas;
|
|
38676
|
+
var GROUP_COLORS2, labelMeasureCtx, GraphCanvas;
|
|
38349
38677
|
var init_GraphCanvas = __esm({
|
|
38350
38678
|
"components/core/molecules/GraphCanvas.tsx"() {
|
|
38351
38679
|
"use client";
|
|
@@ -38356,6 +38684,7 @@ var init_GraphCanvas = __esm({
|
|
|
38356
38684
|
init_ErrorState();
|
|
38357
38685
|
init_EmptyState();
|
|
38358
38686
|
init_useEventBus();
|
|
38687
|
+
init_useCanvasGestures();
|
|
38359
38688
|
GROUP_COLORS2 = [
|
|
38360
38689
|
"var(--color-primary)",
|
|
38361
38690
|
"var(--color-success)",
|
|
@@ -38364,6 +38693,7 @@ var init_GraphCanvas = __esm({
|
|
|
38364
38693
|
"var(--color-info)",
|
|
38365
38694
|
"var(--color-accent)"
|
|
38366
38695
|
];
|
|
38696
|
+
labelMeasureCtx = null;
|
|
38367
38697
|
GraphCanvas = ({
|
|
38368
38698
|
title,
|
|
38369
38699
|
nodes: propNodes = [],
|
|
@@ -38393,6 +38723,10 @@ var init_GraphCanvas = __esm({
|
|
|
38393
38723
|
const animRef = useRef(0);
|
|
38394
38724
|
const [zoom, setZoom] = useState(1);
|
|
38395
38725
|
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
|
38726
|
+
const zoomRef = useRef(zoom);
|
|
38727
|
+
zoomRef.current = zoom;
|
|
38728
|
+
const offsetRef = useRef(offset);
|
|
38729
|
+
offsetRef.current = offset;
|
|
38396
38730
|
const [hoveredNode, setHoveredNode] = useState(null);
|
|
38397
38731
|
const nodesRef = useRef([]);
|
|
38398
38732
|
const [, forceUpdate] = useState(0);
|
|
@@ -38540,22 +38874,36 @@ var init_GraphCanvas = __esm({
|
|
|
38540
38874
|
node.x = Math.max(30, Math.min(w - 30, node.x));
|
|
38541
38875
|
node.y = Math.max(30, Math.min(h - 30, node.y));
|
|
38542
38876
|
}
|
|
38877
|
+
const LABEL_GAP = 12;
|
|
38878
|
+
const LABEL_H = 12;
|
|
38879
|
+
const pad = nodeSpacing / 2;
|
|
38543
38880
|
for (let i = 0; i < nodes.length; i++) {
|
|
38544
38881
|
for (let j = i + 1; j < nodes.length; j++) {
|
|
38545
38882
|
const a = nodes[i];
|
|
38546
38883
|
const b = nodes[j];
|
|
38547
|
-
const
|
|
38548
|
-
const
|
|
38549
|
-
|
|
38550
|
-
|
|
38551
|
-
|
|
38552
|
-
|
|
38553
|
-
|
|
38554
|
-
|
|
38555
|
-
|
|
38556
|
-
|
|
38557
|
-
|
|
38558
|
-
|
|
38884
|
+
const ar = a.size || 8;
|
|
38885
|
+
const br = b.size || 8;
|
|
38886
|
+
if (showLabels) {
|
|
38887
|
+
if (a.labelW === void 0) a.labelW = a.label ? measureLabelWidth(a.label) : 0;
|
|
38888
|
+
if (b.labelW === void 0) b.labelW = b.label ? measureLabelWidth(b.label) : 0;
|
|
38889
|
+
}
|
|
38890
|
+
const labelBelow = showLabels ? LABEL_GAP + LABEL_H : 0;
|
|
38891
|
+
const aHalfW = Math.max(ar, (a.labelW ?? 0) / 2) + pad;
|
|
38892
|
+
const bHalfW = Math.max(br, (b.labelW ?? 0) / 2) + pad;
|
|
38893
|
+
const aTop = a.y - ar - pad, aBot = a.y + ar + labelBelow + pad;
|
|
38894
|
+
const bTop = b.y - br - pad, bBot = b.y + br + labelBelow + pad;
|
|
38895
|
+
const overlapX = Math.min(a.x + aHalfW, b.x + bHalfW) - Math.max(a.x - aHalfW, b.x - bHalfW);
|
|
38896
|
+
const overlapY = Math.min(aBot, bBot) - Math.max(aTop, bTop);
|
|
38897
|
+
if (overlapX > 0 && overlapY > 0) {
|
|
38898
|
+
if (overlapX <= overlapY) {
|
|
38899
|
+
const push2 = overlapX / 2 * (b.x >= a.x ? 1 : -1);
|
|
38900
|
+
a.x = Math.max(30, Math.min(w - 30, a.x - push2));
|
|
38901
|
+
b.x = Math.max(30, Math.min(w - 30, b.x + push2));
|
|
38902
|
+
} else {
|
|
38903
|
+
const push2 = overlapY / 2 * (bTop + bBot >= aTop + aBot ? 1 : -1);
|
|
38904
|
+
a.y = Math.max(30, Math.min(h - 30, a.y - push2));
|
|
38905
|
+
b.y = Math.max(30, Math.min(h - 30, b.y + push2));
|
|
38906
|
+
}
|
|
38559
38907
|
}
|
|
38560
38908
|
}
|
|
38561
38909
|
}
|
|
@@ -38572,7 +38920,7 @@ var init_GraphCanvas = __esm({
|
|
|
38572
38920
|
return () => {
|
|
38573
38921
|
cancelAnimationFrame(animRef.current);
|
|
38574
38922
|
};
|
|
38575
|
-
}, [propNodes, propEdges, layout, repulsion, linkDistance, nodeSpacing, logicalW, height]);
|
|
38923
|
+
}, [propNodes, propEdges, layout, repulsion, linkDistance, nodeSpacing, showLabels, logicalW, height]);
|
|
38576
38924
|
useEffect(() => {
|
|
38577
38925
|
const canvas = canvasRef.current;
|
|
38578
38926
|
if (!canvas) return;
|
|
@@ -38652,25 +39000,27 @@ var init_GraphCanvas = __esm({
|
|
|
38652
39000
|
setZoom(1);
|
|
38653
39001
|
setOffset({ x: 0, y: 0 });
|
|
38654
39002
|
}, []);
|
|
38655
|
-
const
|
|
38656
|
-
(
|
|
38657
|
-
|
|
38658
|
-
|
|
38659
|
-
|
|
38660
|
-
|
|
38661
|
-
|
|
38662
|
-
|
|
38663
|
-
|
|
38664
|
-
|
|
38665
|
-
|
|
38666
|
-
|
|
38667
|
-
|
|
38668
|
-
|
|
38669
|
-
|
|
38670
|
-
|
|
38671
|
-
|
|
38672
|
-
|
|
38673
|
-
|
|
39003
|
+
const applyZoom = useCallback((factor, cx, cy) => {
|
|
39004
|
+
if (!interactive) return;
|
|
39005
|
+
const oldZoom = zoomRef.current;
|
|
39006
|
+
const newZoom = Math.max(0.3, Math.min(3, oldZoom * factor));
|
|
39007
|
+
if (newZoom === oldZoom) return;
|
|
39008
|
+
const o = offsetRef.current;
|
|
39009
|
+
setOffset({
|
|
39010
|
+
x: cx - (cx - o.x) * (newZoom / oldZoom),
|
|
39011
|
+
y: cy - (cy - o.y) * (newZoom / oldZoom)
|
|
39012
|
+
});
|
|
39013
|
+
setZoom(newZoom);
|
|
39014
|
+
}, [interactive]);
|
|
39015
|
+
const applyPanDelta = useCallback((dx, dy) => {
|
|
39016
|
+
if (!interactive) return;
|
|
39017
|
+
setOffset((o) => ({ x: o.x + dx, y: o.y + dy }));
|
|
39018
|
+
}, [interactive]);
|
|
39019
|
+
const cancelSinglePointer = useCallback(() => {
|
|
39020
|
+
interactionRef.current.mode = "none";
|
|
39021
|
+
interactionRef.current.dragNodeId = null;
|
|
39022
|
+
}, []);
|
|
39023
|
+
const handlePointerDown = useCallback(
|
|
38674
39024
|
(e) => {
|
|
38675
39025
|
const coords = toCoords(e);
|
|
38676
39026
|
if (!coords) return;
|
|
@@ -38692,7 +39042,7 @@ var init_GraphCanvas = __esm({
|
|
|
38692
39042
|
},
|
|
38693
39043
|
[toCoords, nodeAt, draggable, interactive, offset]
|
|
38694
39044
|
);
|
|
38695
|
-
const
|
|
39045
|
+
const handlePointerMove = useCallback(
|
|
38696
39046
|
(e) => {
|
|
38697
39047
|
const state = interactionRef.current;
|
|
38698
39048
|
if (state.mode === "panning") {
|
|
@@ -38721,7 +39071,7 @@ var init_GraphCanvas = __esm({
|
|
|
38721
39071
|
},
|
|
38722
39072
|
[toCoords, nodeAt]
|
|
38723
39073
|
);
|
|
38724
|
-
const
|
|
39074
|
+
const handlePointerUp = useCallback(
|
|
38725
39075
|
(e) => {
|
|
38726
39076
|
const state = interactionRef.current;
|
|
38727
39077
|
const moved = Math.abs(e.clientX - state.downPos.x) + Math.abs(e.clientY - state.downPos.y);
|
|
@@ -38738,11 +39088,19 @@ var init_GraphCanvas = __esm({
|
|
|
38738
39088
|
},
|
|
38739
39089
|
[toCoords, nodeAt, handleNodeClick]
|
|
38740
39090
|
);
|
|
38741
|
-
const
|
|
38742
|
-
interactionRef.current.mode = "none";
|
|
38743
|
-
interactionRef.current.dragNodeId = null;
|
|
39091
|
+
const handlePointerLeave = useCallback(() => {
|
|
38744
39092
|
setHoveredNode(null);
|
|
38745
39093
|
}, []);
|
|
39094
|
+
const gestureHandlers = useCanvasGestures({
|
|
39095
|
+
canvasRef,
|
|
39096
|
+
enabled: interactive || draggable,
|
|
39097
|
+
onPointerDown: handlePointerDown,
|
|
39098
|
+
onPointerMove: handlePointerMove,
|
|
39099
|
+
onPointerUp: handlePointerUp,
|
|
39100
|
+
onZoom: applyZoom,
|
|
39101
|
+
onPanDelta: applyPanDelta,
|
|
39102
|
+
onMultiTouchStart: cancelSinglePointer
|
|
39103
|
+
});
|
|
38746
39104
|
const handleDoubleClick = useCallback(
|
|
38747
39105
|
(e) => {
|
|
38748
39106
|
const coords = toCoords(e);
|
|
@@ -38811,13 +39169,14 @@ var init_GraphCanvas = __esm({
|
|
|
38811
39169
|
ref: canvasRef,
|
|
38812
39170
|
width: Math.round(logicalW * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
|
|
38813
39171
|
height: Math.round(height * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
|
|
38814
|
-
className: "w-full cursor-grab active:cursor-grabbing",
|
|
39172
|
+
className: "w-full cursor-grab active:cursor-grabbing touch-none",
|
|
38815
39173
|
style: { height },
|
|
38816
|
-
|
|
38817
|
-
|
|
38818
|
-
|
|
38819
|
-
|
|
38820
|
-
|
|
39174
|
+
onPointerDown: gestureHandlers.onPointerDown,
|
|
39175
|
+
onPointerMove: gestureHandlers.onPointerMove,
|
|
39176
|
+
onPointerUp: gestureHandlers.onPointerUp,
|
|
39177
|
+
onPointerCancel: gestureHandlers.onPointerCancel,
|
|
39178
|
+
onPointerLeave: handlePointerLeave,
|
|
39179
|
+
onWheel: gestureHandlers.onWheel,
|
|
38821
39180
|
onDoubleClick: handleDoubleClick
|
|
38822
39181
|
}
|
|
38823
39182
|
) }),
|
|
@@ -43289,6 +43648,9 @@ var init_GameCanvas3D2 = __esm({
|
|
|
43289
43648
|
target: cameraTarget,
|
|
43290
43649
|
enableDamping: true,
|
|
43291
43650
|
dampingFactor: 0.05,
|
|
43651
|
+
enableZoom: true,
|
|
43652
|
+
enablePan: true,
|
|
43653
|
+
touches: { ONE: THREE3.TOUCH.ROTATE, TWO: THREE3.TOUCH.DOLLY_PAN },
|
|
43292
43654
|
minDistance: 2,
|
|
43293
43655
|
maxDistance: 100,
|
|
43294
43656
|
maxPolarAngle: Math.PI / 2 - 0.1
|
|
@@ -48619,20 +48981,21 @@ var init_SplitPane = __esm({
|
|
|
48619
48981
|
const [ratio, setRatio] = useState(initialRatio);
|
|
48620
48982
|
const containerRef = useRef(null);
|
|
48621
48983
|
const isDragging = useRef(false);
|
|
48622
|
-
const
|
|
48984
|
+
const handlePointerDown = useCallback(
|
|
48623
48985
|
(e) => {
|
|
48624
48986
|
if (!resizable) return;
|
|
48625
48987
|
e.preventDefault();
|
|
48626
48988
|
isDragging.current = true;
|
|
48627
|
-
|
|
48989
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
48990
|
+
const handlePointerMove = (ev) => {
|
|
48628
48991
|
if (!isDragging.current || !containerRef.current) return;
|
|
48629
48992
|
const rect = containerRef.current.getBoundingClientRect();
|
|
48630
48993
|
let newRatio;
|
|
48631
48994
|
if (direction === "horizontal") {
|
|
48632
|
-
const x =
|
|
48995
|
+
const x = ev.clientX - rect.left;
|
|
48633
48996
|
newRatio = x / rect.width * 100;
|
|
48634
48997
|
} else {
|
|
48635
|
-
const y =
|
|
48998
|
+
const y = ev.clientY - rect.top;
|
|
48636
48999
|
newRatio = y / rect.height * 100;
|
|
48637
49000
|
}
|
|
48638
49001
|
const minRatio = minSize / (direction === "horizontal" ? rect.width : rect.height) * 100;
|
|
@@ -48640,13 +49003,15 @@ var init_SplitPane = __esm({
|
|
|
48640
49003
|
newRatio = Math.max(minRatio, Math.min(maxRatio, newRatio));
|
|
48641
49004
|
setRatio(newRatio);
|
|
48642
49005
|
};
|
|
48643
|
-
const
|
|
49006
|
+
const handlePointerUp = () => {
|
|
48644
49007
|
isDragging.current = false;
|
|
48645
|
-
document.removeEventListener("
|
|
48646
|
-
document.removeEventListener("
|
|
49008
|
+
document.removeEventListener("pointermove", handlePointerMove);
|
|
49009
|
+
document.removeEventListener("pointerup", handlePointerUp);
|
|
49010
|
+
document.removeEventListener("pointercancel", handlePointerUp);
|
|
48647
49011
|
};
|
|
48648
|
-
document.addEventListener("
|
|
48649
|
-
document.addEventListener("
|
|
49012
|
+
document.addEventListener("pointermove", handlePointerMove);
|
|
49013
|
+
document.addEventListener("pointerup", handlePointerUp);
|
|
49014
|
+
document.addEventListener("pointercancel", handlePointerUp);
|
|
48650
49015
|
},
|
|
48651
49016
|
[direction, minSize, resizable]
|
|
48652
49017
|
);
|
|
@@ -48675,9 +49040,9 @@ var init_SplitPane = __esm({
|
|
|
48675
49040
|
resizable && /* @__PURE__ */ jsx(
|
|
48676
49041
|
"div",
|
|
48677
49042
|
{
|
|
48678
|
-
|
|
49043
|
+
onPointerDown: handlePointerDown,
|
|
48679
49044
|
className: cn(
|
|
48680
|
-
"flex-shrink-0 bg-border transition-colors",
|
|
49045
|
+
"flex-shrink-0 bg-border transition-colors touch-none",
|
|
48681
49046
|
isHorizontal ? "w-1 cursor-col-resize hover:w-1.5 hover:bg-muted-foreground" : "h-1 cursor-row-resize hover:h-1.5 hover:bg-muted-foreground"
|
|
48682
49047
|
)
|
|
48683
49048
|
}
|