@almadar/ui 5.62.0 → 5.63.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/avl/index.cjs +490 -147
- package/dist/avl/index.js +490 -147
- 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 +490 -148
- package/dist/components/index.js +490 -148
- 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 +490 -147
- package/dist/providers/index.js +490 -147
- package/dist/runtime/index.cjs +490 -147
- package/dist/runtime/index.js +490 -147
- package/package.json +2 -2
package/dist/providers/index.js
CHANGED
|
@@ -246,12 +246,60 @@ var init_cn = __esm({
|
|
|
246
246
|
"lib/cn.ts"() {
|
|
247
247
|
}
|
|
248
248
|
});
|
|
249
|
+
function useTapReveal(options = {}) {
|
|
250
|
+
const { onReveal, onDismiss, refs, enabled = true } = options;
|
|
251
|
+
const [revealed, setRevealed] = useState(false);
|
|
252
|
+
const onRevealRef = useRef(onReveal);
|
|
253
|
+
const onDismissRef = useRef(onDismiss);
|
|
254
|
+
onRevealRef.current = onReveal;
|
|
255
|
+
onDismissRef.current = onDismiss;
|
|
256
|
+
const reveal = useCallback(() => {
|
|
257
|
+
setRevealed((wasRevealed) => {
|
|
258
|
+
if (!wasRevealed) onRevealRef.current?.();
|
|
259
|
+
return true;
|
|
260
|
+
});
|
|
261
|
+
}, []);
|
|
262
|
+
const dismiss = useCallback(() => {
|
|
263
|
+
setRevealed((wasRevealed) => {
|
|
264
|
+
if (wasRevealed) onDismissRef.current?.();
|
|
265
|
+
return false;
|
|
266
|
+
});
|
|
267
|
+
}, []);
|
|
268
|
+
const onPointerDown = useCallback(
|
|
269
|
+
(e) => {
|
|
270
|
+
if (!enabled || e.pointerType === "mouse") return;
|
|
271
|
+
if (revealed) dismiss();
|
|
272
|
+
else reveal();
|
|
273
|
+
},
|
|
274
|
+
[enabled, revealed, reveal, dismiss]
|
|
275
|
+
);
|
|
276
|
+
useEffect(() => {
|
|
277
|
+
if (!revealed || typeof document === "undefined") return;
|
|
278
|
+
const onDocDown = (ev) => {
|
|
279
|
+
const target = ev.target;
|
|
280
|
+
if (!(target instanceof Node)) return;
|
|
281
|
+
const inside = (refs ?? []).some((r) => r.current?.contains(target));
|
|
282
|
+
if (!inside) dismiss();
|
|
283
|
+
};
|
|
284
|
+
const id = setTimeout(() => document.addEventListener("pointerdown", onDocDown), 0);
|
|
285
|
+
return () => {
|
|
286
|
+
clearTimeout(id);
|
|
287
|
+
document.removeEventListener("pointerdown", onDocDown);
|
|
288
|
+
};
|
|
289
|
+
}, [revealed, refs, dismiss]);
|
|
290
|
+
return { revealed, triggerProps: { onPointerDown }, reveal, dismiss };
|
|
291
|
+
}
|
|
292
|
+
var init_useTapReveal = __esm({
|
|
293
|
+
"hooks/useTapReveal.ts"() {
|
|
294
|
+
}
|
|
295
|
+
});
|
|
249
296
|
var paddingStyles, paddingXStyles, paddingYStyles, marginStyles, marginXStyles, marginYStyles, bgStyles, roundedStyles, shadowStyles, displayStyles, overflowStyles, positionStyles, Box;
|
|
250
297
|
var init_Box = __esm({
|
|
251
298
|
"components/core/atoms/Box.tsx"() {
|
|
252
299
|
"use client";
|
|
253
300
|
init_cn();
|
|
254
301
|
init_useEventBus();
|
|
302
|
+
init_useTapReveal();
|
|
255
303
|
paddingStyles = {
|
|
256
304
|
none: "p-0",
|
|
257
305
|
xs: "p-1",
|
|
@@ -377,10 +425,12 @@ var init_Box = __esm({
|
|
|
377
425
|
action,
|
|
378
426
|
actionPayload,
|
|
379
427
|
hoverEvent,
|
|
428
|
+
tapReveal = true,
|
|
380
429
|
maxWidth,
|
|
381
430
|
onClick,
|
|
382
431
|
onMouseEnter,
|
|
383
432
|
onMouseLeave,
|
|
433
|
+
onPointerDown,
|
|
384
434
|
...rest
|
|
385
435
|
}, ref) => {
|
|
386
436
|
const eventBus = useEventBus();
|
|
@@ -403,6 +453,19 @@ var init_Box = __esm({
|
|
|
403
453
|
}
|
|
404
454
|
onMouseLeave?.(e);
|
|
405
455
|
}, [hoverEvent, eventBus, onMouseLeave]);
|
|
456
|
+
const { triggerProps } = useTapReveal({
|
|
457
|
+
enabled: tapReveal && !!hoverEvent,
|
|
458
|
+
onReveal: useCallback(() => {
|
|
459
|
+
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
|
|
460
|
+
}, [hoverEvent, eventBus]),
|
|
461
|
+
onDismiss: useCallback(() => {
|
|
462
|
+
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
|
|
463
|
+
}, [hoverEvent, eventBus])
|
|
464
|
+
});
|
|
465
|
+
const handlePointerDown = useCallback((e) => {
|
|
466
|
+
if (hoverEvent && tapReveal) triggerProps.onPointerDown(e);
|
|
467
|
+
onPointerDown?.(e);
|
|
468
|
+
}, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
|
|
406
469
|
const isClickable = action || onClick;
|
|
407
470
|
return React85__default.createElement(
|
|
408
471
|
Component2,
|
|
@@ -430,6 +493,7 @@ var init_Box = __esm({
|
|
|
430
493
|
onClick: isClickable ? handleClick : void 0,
|
|
431
494
|
onMouseEnter: hoverEvent || onMouseEnter ? handleMouseEnter : void 0,
|
|
432
495
|
onMouseLeave: hoverEvent || onMouseLeave ? handleMouseLeave : void 0,
|
|
496
|
+
onPointerDown: hoverEvent && tapReveal || onPointerDown ? handlePointerDown : void 0,
|
|
433
497
|
style: maxWidth ? { maxWidth, ...rest.style } : rest.style,
|
|
434
498
|
...rest
|
|
435
499
|
},
|
|
@@ -4840,6 +4904,11 @@ var init_TextHighlight = __esm({
|
|
|
4840
4904
|
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: false, annotationId });
|
|
4841
4905
|
onMouseLeave?.();
|
|
4842
4906
|
},
|
|
4907
|
+
onPointerDown: (e) => {
|
|
4908
|
+
if (e.pointerType === "mouse") return;
|
|
4909
|
+
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: true, annotationId });
|
|
4910
|
+
onMouseEnter?.();
|
|
4911
|
+
},
|
|
4843
4912
|
role: "button",
|
|
4844
4913
|
tabIndex: 0,
|
|
4845
4914
|
onKeyDown: (e) => {
|
|
@@ -5015,6 +5084,7 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5015
5084
|
init_Typography();
|
|
5016
5085
|
init_Divider();
|
|
5017
5086
|
init_cn();
|
|
5087
|
+
init_useTapReveal();
|
|
5018
5088
|
positionStyles2 = {
|
|
5019
5089
|
top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
|
|
5020
5090
|
bottom: "top-full left-1/2 -translate-x-1/2 mt-2",
|
|
@@ -5036,6 +5106,7 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5036
5106
|
const { t } = useTranslate();
|
|
5037
5107
|
const [isVisible, setIsVisible] = React85__default.useState(false);
|
|
5038
5108
|
const timeoutRef = React85__default.useRef(null);
|
|
5109
|
+
const triggerRef = React85__default.useRef(null);
|
|
5039
5110
|
const handleMouseEnter = () => {
|
|
5040
5111
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
5041
5112
|
timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
|
|
@@ -5044,6 +5115,8 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5044
5115
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
5045
5116
|
setIsVisible(false);
|
|
5046
5117
|
};
|
|
5118
|
+
const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
|
|
5119
|
+
const open = isVisible || revealed;
|
|
5047
5120
|
React85__default.useEffect(() => {
|
|
5048
5121
|
return () => {
|
|
5049
5122
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
@@ -5052,6 +5125,7 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5052
5125
|
return /* @__PURE__ */ jsxs(
|
|
5053
5126
|
Box,
|
|
5054
5127
|
{
|
|
5128
|
+
ref: triggerRef,
|
|
5055
5129
|
as: "span",
|
|
5056
5130
|
position: "relative",
|
|
5057
5131
|
display: "inline-block",
|
|
@@ -5060,9 +5134,10 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5060
5134
|
onMouseLeave: handleMouseLeave,
|
|
5061
5135
|
onFocus: handleMouseEnter,
|
|
5062
5136
|
onBlur: handleMouseLeave,
|
|
5137
|
+
onPointerDown: triggerProps.onPointerDown,
|
|
5063
5138
|
children: [
|
|
5064
5139
|
children,
|
|
5065
|
-
|
|
5140
|
+
open && /* @__PURE__ */ jsxs(
|
|
5066
5141
|
Box,
|
|
5067
5142
|
{
|
|
5068
5143
|
padding: "sm",
|
|
@@ -10822,6 +10897,36 @@ function useCamera() {
|
|
|
10822
10897
|
cameraRef.current.zoom = Math.max(0.5, Math.min(3, cameraRef.current.zoom * zoomDelta));
|
|
10823
10898
|
drawFn?.();
|
|
10824
10899
|
}, []);
|
|
10900
|
+
const handlePointerDown = useCallback((e) => {
|
|
10901
|
+
handleMouseDown(e);
|
|
10902
|
+
}, [handleMouseDown]);
|
|
10903
|
+
const handlePointerUp = useCallback(() => {
|
|
10904
|
+
handleMouseUp();
|
|
10905
|
+
}, [handleMouseUp]);
|
|
10906
|
+
const handlePointerMove = useCallback((e, drawFn) => {
|
|
10907
|
+
return handleMouseMove(e, drawFn);
|
|
10908
|
+
}, [handleMouseMove]);
|
|
10909
|
+
const panBy = useCallback((dx, dy, drawFn) => {
|
|
10910
|
+
cameraRef.current.x -= dx;
|
|
10911
|
+
cameraRef.current.y -= dy;
|
|
10912
|
+
targetCameraRef.current = null;
|
|
10913
|
+
drawFn?.();
|
|
10914
|
+
}, []);
|
|
10915
|
+
const zoomAtPoint = useCallback((factor, centerX, centerY, viewportSize, drawFn) => {
|
|
10916
|
+
const cam = cameraRef.current;
|
|
10917
|
+
const oldZoom = cam.zoom;
|
|
10918
|
+
const newZoom = Math.max(0.5, Math.min(3, oldZoom * factor));
|
|
10919
|
+
if (newZoom === oldZoom) {
|
|
10920
|
+
drawFn?.();
|
|
10921
|
+
return;
|
|
10922
|
+
}
|
|
10923
|
+
const inv = 1 / oldZoom - 1 / newZoom;
|
|
10924
|
+
cam.x += (centerX - viewportSize.width / 2) * inv;
|
|
10925
|
+
cam.y += (centerY - viewportSize.height / 2) * inv;
|
|
10926
|
+
cam.zoom = newZoom;
|
|
10927
|
+
targetCameraRef.current = null;
|
|
10928
|
+
drawFn?.();
|
|
10929
|
+
}, []);
|
|
10825
10930
|
const screenToWorld = useCallback((clientX, clientY, canvas, viewportSize) => {
|
|
10826
10931
|
const rect = canvas.getBoundingClientRect();
|
|
10827
10932
|
const screenX = clientX - rect.left;
|
|
@@ -10853,6 +10958,11 @@ function useCamera() {
|
|
|
10853
10958
|
handleMouseMove,
|
|
10854
10959
|
handleMouseLeave,
|
|
10855
10960
|
handleWheel,
|
|
10961
|
+
handlePointerDown,
|
|
10962
|
+
handlePointerUp,
|
|
10963
|
+
handlePointerMove,
|
|
10964
|
+
panBy,
|
|
10965
|
+
zoomAtPoint,
|
|
10856
10966
|
screenToWorld,
|
|
10857
10967
|
lerpToTarget
|
|
10858
10968
|
};
|
|
@@ -10862,6 +10972,113 @@ var init_useCamera = __esm({
|
|
|
10862
10972
|
"use client";
|
|
10863
10973
|
}
|
|
10864
10974
|
});
|
|
10975
|
+
function localPoint(canvas, clientX, clientY) {
|
|
10976
|
+
if (!canvas) return { x: clientX, y: clientY };
|
|
10977
|
+
const rect = canvas.getBoundingClientRect();
|
|
10978
|
+
return { x: clientX - rect.left, y: clientY - rect.top };
|
|
10979
|
+
}
|
|
10980
|
+
function useCanvasGestures(options) {
|
|
10981
|
+
const {
|
|
10982
|
+
canvasRef,
|
|
10983
|
+
enabled = true,
|
|
10984
|
+
wheelStep = 1.1,
|
|
10985
|
+
onPointerDown,
|
|
10986
|
+
onPointerMove,
|
|
10987
|
+
onPointerUp,
|
|
10988
|
+
onZoom,
|
|
10989
|
+
onPanDelta,
|
|
10990
|
+
onMultiTouchStart
|
|
10991
|
+
} = options;
|
|
10992
|
+
const pointers = useRef(/* @__PURE__ */ new Map());
|
|
10993
|
+
const pinch = useRef(null);
|
|
10994
|
+
const computePinch = useCallback(() => {
|
|
10995
|
+
const pts = [...pointers.current.values()];
|
|
10996
|
+
const dx = pts[1].x - pts[0].x;
|
|
10997
|
+
const dy = pts[1].y - pts[0].y;
|
|
10998
|
+
return {
|
|
10999
|
+
distance: Math.hypot(dx, dy) || 1,
|
|
11000
|
+
centroid: { x: (pts[0].x + pts[1].x) / 2, y: (pts[0].y + pts[1].y) / 2 }
|
|
11001
|
+
};
|
|
11002
|
+
}, []);
|
|
11003
|
+
const handlePointerDown = useCallback(
|
|
11004
|
+
(e) => {
|
|
11005
|
+
if (!enabled) return;
|
|
11006
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
11007
|
+
pointers.current.set(e.pointerId, localPoint(canvasRef.current, e.clientX, e.clientY));
|
|
11008
|
+
if (pointers.current.size === 2) {
|
|
11009
|
+
onMultiTouchStart?.();
|
|
11010
|
+
pinch.current = computePinch();
|
|
11011
|
+
} else if (pointers.current.size === 1) {
|
|
11012
|
+
onPointerDown?.(e);
|
|
11013
|
+
}
|
|
11014
|
+
},
|
|
11015
|
+
[enabled, canvasRef, onMultiTouchStart, computePinch, onPointerDown]
|
|
11016
|
+
);
|
|
11017
|
+
const handlePointerMove = useCallback(
|
|
11018
|
+
(e) => {
|
|
11019
|
+
if (!enabled) return;
|
|
11020
|
+
if (pointers.current.has(e.pointerId)) {
|
|
11021
|
+
pointers.current.set(e.pointerId, localPoint(canvasRef.current, e.clientX, e.clientY));
|
|
11022
|
+
}
|
|
11023
|
+
if (pointers.current.size >= 2 && pinch.current) {
|
|
11024
|
+
const next = computePinch();
|
|
11025
|
+
const prev = pinch.current;
|
|
11026
|
+
if (next.distance !== prev.distance) {
|
|
11027
|
+
onZoom?.(next.distance / prev.distance, next.centroid.x, next.centroid.y);
|
|
11028
|
+
}
|
|
11029
|
+
onPanDelta?.(next.centroid.x - prev.centroid.x, next.centroid.y - prev.centroid.y);
|
|
11030
|
+
pinch.current = next;
|
|
11031
|
+
return;
|
|
11032
|
+
}
|
|
11033
|
+
onPointerMove?.(e);
|
|
11034
|
+
},
|
|
11035
|
+
[enabled, canvasRef, computePinch, onZoom, onPanDelta, onPointerMove]
|
|
11036
|
+
);
|
|
11037
|
+
const endPointer = useCallback(
|
|
11038
|
+
(e, fireUp) => {
|
|
11039
|
+
const wasMulti = pointers.current.size >= 2;
|
|
11040
|
+
pointers.current.delete(e.pointerId);
|
|
11041
|
+
if (pointers.current.size < 2) pinch.current = null;
|
|
11042
|
+
if (wasMulti && pointers.current.size === 1) return;
|
|
11043
|
+
if (pointers.current.size === 0 && fireUp) onPointerUp?.(e);
|
|
11044
|
+
},
|
|
11045
|
+
[onPointerUp]
|
|
11046
|
+
);
|
|
11047
|
+
const handlePointerUp = useCallback(
|
|
11048
|
+
(e) => {
|
|
11049
|
+
if (!enabled) return;
|
|
11050
|
+
endPointer(e, true);
|
|
11051
|
+
},
|
|
11052
|
+
[enabled, endPointer]
|
|
11053
|
+
);
|
|
11054
|
+
const handlePointerCancel = useCallback(
|
|
11055
|
+
(e) => {
|
|
11056
|
+
if (!enabled) return;
|
|
11057
|
+
endPointer(e, false);
|
|
11058
|
+
},
|
|
11059
|
+
[enabled, endPointer]
|
|
11060
|
+
);
|
|
11061
|
+
const handleWheel = useCallback(
|
|
11062
|
+
(e) => {
|
|
11063
|
+
if (!enabled) return;
|
|
11064
|
+
e.preventDefault();
|
|
11065
|
+
const { x, y } = localPoint(canvasRef.current, e.clientX, e.clientY);
|
|
11066
|
+
onZoom?.(e.deltaY < 0 ? wheelStep : 1 / wheelStep, x, y);
|
|
11067
|
+
},
|
|
11068
|
+
[enabled, canvasRef, wheelStep, onZoom]
|
|
11069
|
+
);
|
|
11070
|
+
return {
|
|
11071
|
+
onPointerDown: handlePointerDown,
|
|
11072
|
+
onPointerMove: handlePointerMove,
|
|
11073
|
+
onPointerUp: handlePointerUp,
|
|
11074
|
+
onPointerCancel: handlePointerCancel,
|
|
11075
|
+
onWheel: handleWheel
|
|
11076
|
+
};
|
|
11077
|
+
}
|
|
11078
|
+
var init_useCanvasGestures = __esm({
|
|
11079
|
+
"hooks/useCanvasGestures.ts"() {
|
|
11080
|
+
}
|
|
11081
|
+
});
|
|
10865
11082
|
function unitAtlasUrl(unit) {
|
|
10866
11083
|
if (unit.spriteSheet) return unit.spriteSheet;
|
|
10867
11084
|
const sprite = unit.sprite;
|
|
@@ -11240,11 +11457,12 @@ function IsometricCanvas({
|
|
|
11240
11457
|
cameraRef,
|
|
11241
11458
|
targetCameraRef,
|
|
11242
11459
|
dragDistance,
|
|
11243
|
-
handleMouseDown,
|
|
11244
|
-
handleMouseUp,
|
|
11245
|
-
handleMouseMove,
|
|
11246
11460
|
handleMouseLeave,
|
|
11247
|
-
|
|
11461
|
+
handlePointerDown,
|
|
11462
|
+
handlePointerUp,
|
|
11463
|
+
handlePointerMove,
|
|
11464
|
+
panBy,
|
|
11465
|
+
zoomAtPoint,
|
|
11248
11466
|
screenToWorld,
|
|
11249
11467
|
lerpToTarget
|
|
11250
11468
|
} = useCamera();
|
|
@@ -11679,11 +11897,16 @@ function IsometricCanvas({
|
|
|
11679
11897
|
cancelAnimationFrame(rafIdRef.current);
|
|
11680
11898
|
};
|
|
11681
11899
|
}, [draw, units.length, validMoves.length, attackTargets.length, selectedUnitId, hasActiveEffects2, pendingCount, atlasPending, lerpToTarget, targetCameraRef]);
|
|
11682
|
-
const
|
|
11683
|
-
|
|
11684
|
-
|
|
11685
|
-
|
|
11686
|
-
|
|
11900
|
+
const singlePointerActiveRef = useRef(false);
|
|
11901
|
+
const handleCanvasPointerDown = useCallback((e) => {
|
|
11902
|
+
singlePointerActiveRef.current = true;
|
|
11903
|
+
if (enableCamera) handlePointerDown(e);
|
|
11904
|
+
}, [enableCamera, handlePointerDown]);
|
|
11905
|
+
const handleCanvasPointerMove = useCallback((e) => {
|
|
11906
|
+
if (enableCamera) handlePointerMove(e, () => draw(animTimeRef.current));
|
|
11907
|
+
}, [enableCamera, handlePointerMove, draw]);
|
|
11908
|
+
const handleCanvasHover = useCallback((e) => {
|
|
11909
|
+
if (singlePointerActiveRef.current) return;
|
|
11687
11910
|
if (!onTileHover && !tileHoverEvent || !canvasRef.current) return;
|
|
11688
11911
|
const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
|
|
11689
11912
|
const adjustedX = world.x - scaledTileWidth / 2;
|
|
@@ -11694,26 +11917,10 @@ function IsometricCanvas({
|
|
|
11694
11917
|
if (tileHoverEvent) eventBus.emit(`UI:${tileHoverEvent}`, { x: isoPos.x, y: isoPos.y });
|
|
11695
11918
|
onTileHover?.(isoPos.x, isoPos.y);
|
|
11696
11919
|
}
|
|
11697
|
-
}, [
|
|
11698
|
-
const
|
|
11699
|
-
|
|
11700
|
-
if (
|
|
11701
|
-
onTileLeave?.();
|
|
11702
|
-
}, [handleMouseLeave, onTileLeave, tileLeaveEvent, eventBus]);
|
|
11703
|
-
const handleWheelWithCamera = useCallback((e) => {
|
|
11704
|
-
if (enableCamera) {
|
|
11705
|
-
handleWheel(e, () => draw(animTimeRef.current));
|
|
11706
|
-
}
|
|
11707
|
-
}, [enableCamera, handleWheel, draw]);
|
|
11708
|
-
useEffect(() => {
|
|
11709
|
-
const canvas = canvasRef.current;
|
|
11710
|
-
if (!canvas) return;
|
|
11711
|
-
canvas.addEventListener("wheel", handleWheelWithCamera, { passive: false });
|
|
11712
|
-
return () => {
|
|
11713
|
-
canvas.removeEventListener("wheel", handleWheelWithCamera);
|
|
11714
|
-
};
|
|
11715
|
-
}, [handleWheelWithCamera]);
|
|
11716
|
-
const handleClick = useCallback((e) => {
|
|
11920
|
+
}, [onTileHover, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, tilesProp, tileHoverEvent, eventBus]);
|
|
11921
|
+
const handleCanvasPointerUp = useCallback((e) => {
|
|
11922
|
+
singlePointerActiveRef.current = false;
|
|
11923
|
+
if (enableCamera) handlePointerUp();
|
|
11717
11924
|
if (dragDistance() > 5) return;
|
|
11718
11925
|
if (!canvasRef.current) return;
|
|
11719
11926
|
const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
|
|
@@ -11731,7 +11938,32 @@ function IsometricCanvas({
|
|
|
11731
11938
|
onTileClick?.(isoPos.x, isoPos.y);
|
|
11732
11939
|
}
|
|
11733
11940
|
}
|
|
11734
|
-
}, [dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, units, tilesProp, onUnitClick, onTileClick, unitClickEvent, tileClickEvent, eventBus]);
|
|
11941
|
+
}, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, units, tilesProp, onUnitClick, onTileClick, unitClickEvent, tileClickEvent, eventBus]);
|
|
11942
|
+
const handleCanvasPointerLeave = useCallback(() => {
|
|
11943
|
+
handleMouseLeave();
|
|
11944
|
+
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
11945
|
+
onTileLeave?.();
|
|
11946
|
+
}, [handleMouseLeave, onTileLeave, tileLeaveEvent, eventBus]);
|
|
11947
|
+
const applyZoom = useCallback((factor, centerX, centerY) => {
|
|
11948
|
+
if (enableCamera) zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw(animTimeRef.current));
|
|
11949
|
+
}, [enableCamera, zoomAtPoint, viewportSize, draw]);
|
|
11950
|
+
const applyPanDelta = useCallback((dx, dy) => {
|
|
11951
|
+
if (enableCamera) panBy(dx, dy, () => draw(animTimeRef.current));
|
|
11952
|
+
}, [enableCamera, panBy, draw]);
|
|
11953
|
+
const cancelSinglePointer = useCallback(() => {
|
|
11954
|
+
singlePointerActiveRef.current = false;
|
|
11955
|
+
if (enableCamera) handlePointerUp();
|
|
11956
|
+
}, [enableCamera, handlePointerUp]);
|
|
11957
|
+
const gestureHandlers = useCanvasGestures({
|
|
11958
|
+
canvasRef,
|
|
11959
|
+
enabled: enableCamera || !!onTileHover || !!tileHoverEvent || !!onTileClick || !!tileClickEvent || !!onUnitClick || !!unitClickEvent,
|
|
11960
|
+
onPointerDown: handleCanvasPointerDown,
|
|
11961
|
+
onPointerMove: handleCanvasPointerMove,
|
|
11962
|
+
onPointerUp: handleCanvasPointerUp,
|
|
11963
|
+
onZoom: applyZoom,
|
|
11964
|
+
onPanDelta: applyPanDelta,
|
|
11965
|
+
onMultiTouchStart: cancelSinglePointer
|
|
11966
|
+
});
|
|
11735
11967
|
if (error) {
|
|
11736
11968
|
return /* @__PURE__ */ jsx(ErrorState, { title: t("canvas.errorTitle"), message: error.message, className });
|
|
11737
11969
|
}
|
|
@@ -11763,13 +11995,17 @@ function IsometricCanvas({
|
|
|
11763
11995
|
{
|
|
11764
11996
|
ref: canvasRef,
|
|
11765
11997
|
"data-testid": "game-canvas",
|
|
11766
|
-
|
|
11767
|
-
|
|
11768
|
-
|
|
11769
|
-
|
|
11770
|
-
|
|
11998
|
+
onPointerDown: gestureHandlers.onPointerDown,
|
|
11999
|
+
onPointerMove: (e) => {
|
|
12000
|
+
gestureHandlers.onPointerMove(e);
|
|
12001
|
+
handleCanvasHover(e);
|
|
12002
|
+
},
|
|
12003
|
+
onPointerUp: gestureHandlers.onPointerUp,
|
|
12004
|
+
onPointerCancel: gestureHandlers.onPointerCancel,
|
|
12005
|
+
onPointerLeave: handleCanvasPointerLeave,
|
|
12006
|
+
onWheel: gestureHandlers.onWheel,
|
|
11771
12007
|
onContextMenu: (e) => e.preventDefault(),
|
|
11772
|
-
className: "cursor-pointer",
|
|
12008
|
+
className: "cursor-pointer touch-none",
|
|
11773
12009
|
style: {
|
|
11774
12010
|
width: viewportSize.width,
|
|
11775
12011
|
height: viewportSize.height
|
|
@@ -11823,6 +12059,7 @@ var init_IsometricCanvas = __esm({
|
|
|
11823
12059
|
init_ErrorState();
|
|
11824
12060
|
init_useImageCache();
|
|
11825
12061
|
init_useCamera();
|
|
12062
|
+
init_useCanvasGestures();
|
|
11826
12063
|
init_useUnitSpriteAtlas();
|
|
11827
12064
|
init_verificationRegistry();
|
|
11828
12065
|
init_isometric();
|
|
@@ -14938,6 +15175,10 @@ var init_StateMachineView = __esm({
|
|
|
14938
15175
|
const handleMouseLeave2 = () => {
|
|
14939
15176
|
onHover(null, 0, 0);
|
|
14940
15177
|
};
|
|
15178
|
+
const handlePointerDown2 = (e) => {
|
|
15179
|
+
if (e.pointerType === "mouse") return;
|
|
15180
|
+
handleMouseEnter2();
|
|
15181
|
+
};
|
|
14941
15182
|
return /* @__PURE__ */ jsxs(
|
|
14942
15183
|
"g",
|
|
14943
15184
|
{
|
|
@@ -14947,6 +15188,7 @@ var init_StateMachineView = __esm({
|
|
|
14947
15188
|
onClick: () => onClick?.(bundle),
|
|
14948
15189
|
onMouseEnter: handleMouseEnter2,
|
|
14949
15190
|
onMouseLeave: handleMouseLeave2,
|
|
15191
|
+
onPointerDown: handlePointerDown2,
|
|
14950
15192
|
style: { pointerEvents: "auto" },
|
|
14951
15193
|
children: [
|
|
14952
15194
|
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
@@ -15064,6 +15306,10 @@ var init_StateMachineView = __esm({
|
|
|
15064
15306
|
const handleMouseLeave = useCallback(() => {
|
|
15065
15307
|
onHover(null, 0, 0);
|
|
15066
15308
|
}, [onHover]);
|
|
15309
|
+
const handlePointerDown = useCallback((e) => {
|
|
15310
|
+
if (e.pointerType === "mouse") return;
|
|
15311
|
+
handleMouseEnter();
|
|
15312
|
+
}, [handleMouseEnter]);
|
|
15067
15313
|
const uniqueMarkerId = `arrow-${bundle.id}`;
|
|
15068
15314
|
const hasDetails = bundle.labels.some((l) => l.hasDetails);
|
|
15069
15315
|
return /* @__PURE__ */ jsxs(
|
|
@@ -15075,6 +15321,7 @@ var init_StateMachineView = __esm({
|
|
|
15075
15321
|
onClick: () => onClick?.(bundle),
|
|
15076
15322
|
onMouseEnter: handleMouseEnter,
|
|
15077
15323
|
onMouseLeave: handleMouseLeave,
|
|
15324
|
+
onPointerDown: handlePointerDown,
|
|
15078
15325
|
style: { pointerEvents: "auto" },
|
|
15079
15326
|
children: [
|
|
15080
15327
|
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
@@ -23573,10 +23820,84 @@ function SubMenu({
|
|
|
23573
23820
|
);
|
|
23574
23821
|
return typeof document !== "undefined" ? createPortal(panel, document.body) : panel;
|
|
23575
23822
|
}
|
|
23823
|
+
function MenuItemRow({
|
|
23824
|
+
item,
|
|
23825
|
+
itemId,
|
|
23826
|
+
hasSubMenu,
|
|
23827
|
+
isDanger,
|
|
23828
|
+
direction,
|
|
23829
|
+
isSubMenuOpen,
|
|
23830
|
+
activeSubMenuRef,
|
|
23831
|
+
eventBus,
|
|
23832
|
+
onItemClick,
|
|
23833
|
+
openSubMenu
|
|
23834
|
+
}) {
|
|
23835
|
+
const rowRef = useRef(null);
|
|
23836
|
+
const { triggerProps } = useTapReveal({
|
|
23837
|
+
enabled: hasSubMenu,
|
|
23838
|
+
onReveal: () => openSubMenu(itemId, rowRef.current),
|
|
23839
|
+
refs: [rowRef]
|
|
23840
|
+
});
|
|
23841
|
+
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
23842
|
+
/* @__PURE__ */ jsx(
|
|
23843
|
+
Box,
|
|
23844
|
+
{
|
|
23845
|
+
ref: rowRef,
|
|
23846
|
+
as: "button",
|
|
23847
|
+
onClick: () => onItemClick({ ...item, id: itemId }, itemId),
|
|
23848
|
+
"aria-disabled": item.disabled || void 0,
|
|
23849
|
+
onMouseEnter: (e) => {
|
|
23850
|
+
if (hasSubMenu) openSubMenu(itemId, e.currentTarget);
|
|
23851
|
+
},
|
|
23852
|
+
onPointerDown: hasSubMenu ? triggerProps.onPointerDown : void 0,
|
|
23853
|
+
"data-testid": item.event ? `action-${item.event}` : void 0,
|
|
23854
|
+
className: cn(
|
|
23855
|
+
"w-full flex items-center justify-between gap-3 px-4 py-2 text-start",
|
|
23856
|
+
"text-sm transition-colors",
|
|
23857
|
+
"hover:bg-muted",
|
|
23858
|
+
"focus:outline-none focus:bg-muted",
|
|
23859
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
23860
|
+
item.disabled && "cursor-not-allowed",
|
|
23861
|
+
isDanger && "text-error hover:bg-error/10"
|
|
23862
|
+
),
|
|
23863
|
+
children: /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
23864
|
+
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" })),
|
|
23865
|
+
/* @__PURE__ */ jsx(
|
|
23866
|
+
Typography,
|
|
23867
|
+
{
|
|
23868
|
+
variant: "small",
|
|
23869
|
+
className: cn("flex-1", isDanger && "text-red-600"),
|
|
23870
|
+
children: item.label
|
|
23871
|
+
}
|
|
23872
|
+
),
|
|
23873
|
+
item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: item.badge }),
|
|
23874
|
+
hasSubMenu && /* @__PURE__ */ jsx(
|
|
23875
|
+
Icon,
|
|
23876
|
+
{
|
|
23877
|
+
name: direction === "rtl" ? "chevron-left" : "chevron-right",
|
|
23878
|
+
size: "sm",
|
|
23879
|
+
className: "flex-shrink-0"
|
|
23880
|
+
}
|
|
23881
|
+
)
|
|
23882
|
+
] })
|
|
23883
|
+
}
|
|
23884
|
+
),
|
|
23885
|
+
hasSubMenu && isSubMenuOpen && item.subMenu && /* @__PURE__ */ jsx(
|
|
23886
|
+
SubMenu,
|
|
23887
|
+
{
|
|
23888
|
+
items: item.subMenu,
|
|
23889
|
+
itemRef: activeSubMenuRef,
|
|
23890
|
+
direction,
|
|
23891
|
+
eventBus
|
|
23892
|
+
}
|
|
23893
|
+
)
|
|
23894
|
+
] });
|
|
23895
|
+
}
|
|
23576
23896
|
var MENU_GAP, menuContainerStyles, Menu;
|
|
23577
23897
|
var init_Menu = __esm({
|
|
23578
23898
|
"components/core/molecules/Menu.tsx"() {
|
|
23579
23899
|
"use client";
|
|
23900
|
+
init_useTapReveal();
|
|
23580
23901
|
init_Box();
|
|
23581
23902
|
init_Icon();
|
|
23582
23903
|
init_Divider();
|
|
@@ -23631,6 +23952,10 @@ var init_Menu = __esm({
|
|
|
23631
23952
|
setIsOpen(false);
|
|
23632
23953
|
}
|
|
23633
23954
|
};
|
|
23955
|
+
const openSubMenu = (itemId, el) => {
|
|
23956
|
+
setActiveSubMenu(itemId);
|
|
23957
|
+
setActiveSubMenuRef(el);
|
|
23958
|
+
};
|
|
23634
23959
|
useEffect(() => {
|
|
23635
23960
|
if (isOpen) {
|
|
23636
23961
|
updatePosition();
|
|
@@ -23674,61 +23999,22 @@ var init_Menu = __esm({
|
|
|
23674
23999
|
if (isDivider) {
|
|
23675
24000
|
return /* @__PURE__ */ jsx(Divider, { className: "my-1" }, `divider-${index}`);
|
|
23676
24001
|
}
|
|
23677
|
-
return /* @__PURE__ */
|
|
23678
|
-
|
|
23679
|
-
|
|
23680
|
-
|
|
23681
|
-
|
|
23682
|
-
|
|
23683
|
-
|
|
23684
|
-
|
|
23685
|
-
|
|
23686
|
-
|
|
23687
|
-
|
|
23688
|
-
|
|
23689
|
-
|
|
23690
|
-
|
|
23691
|
-
|
|
23692
|
-
|
|
23693
|
-
"text-sm transition-colors",
|
|
23694
|
-
"hover:bg-muted",
|
|
23695
|
-
"focus:outline-none focus:bg-muted",
|
|
23696
|
-
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
23697
|
-
item.disabled && "cursor-not-allowed",
|
|
23698
|
-
isDanger && "text-error hover:bg-error/10"
|
|
23699
|
-
),
|
|
23700
|
-
children: /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
23701
|
-
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" })),
|
|
23702
|
-
/* @__PURE__ */ jsx(
|
|
23703
|
-
Typography,
|
|
23704
|
-
{
|
|
23705
|
-
variant: "small",
|
|
23706
|
-
className: cn("flex-1", isDanger && "text-red-600"),
|
|
23707
|
-
children: item.label
|
|
23708
|
-
}
|
|
23709
|
-
),
|
|
23710
|
-
item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: item.badge }),
|
|
23711
|
-
hasSubMenu && /* @__PURE__ */ jsx(
|
|
23712
|
-
Icon,
|
|
23713
|
-
{
|
|
23714
|
-
name: direction === "rtl" ? "chevron-left" : "chevron-right",
|
|
23715
|
-
size: "sm",
|
|
23716
|
-
className: "flex-shrink-0"
|
|
23717
|
-
}
|
|
23718
|
-
)
|
|
23719
|
-
] })
|
|
23720
|
-
}
|
|
23721
|
-
),
|
|
23722
|
-
hasSubMenu && activeSubMenu === itemId && item.subMenu && /* @__PURE__ */ jsx(
|
|
23723
|
-
SubMenu,
|
|
23724
|
-
{
|
|
23725
|
-
items: item.subMenu,
|
|
23726
|
-
itemRef: activeSubMenuRef,
|
|
23727
|
-
direction,
|
|
23728
|
-
eventBus
|
|
23729
|
-
}
|
|
23730
|
-
)
|
|
23731
|
-
] }, itemId);
|
|
24002
|
+
return /* @__PURE__ */ jsx(
|
|
24003
|
+
MenuItemRow,
|
|
24004
|
+
{
|
|
24005
|
+
item,
|
|
24006
|
+
itemId,
|
|
24007
|
+
hasSubMenu,
|
|
24008
|
+
isDanger,
|
|
24009
|
+
direction,
|
|
24010
|
+
isSubMenuOpen: activeSubMenu === itemId,
|
|
24011
|
+
activeSubMenuRef,
|
|
24012
|
+
eventBus,
|
|
24013
|
+
onItemClick: handleItemClick,
|
|
24014
|
+
openSubMenu
|
|
24015
|
+
},
|
|
24016
|
+
itemId
|
|
24017
|
+
);
|
|
23732
24018
|
});
|
|
23733
24019
|
const panel = isOpen && triggerRect ? /* @__PURE__ */ jsxs(
|
|
23734
24020
|
"div",
|
|
@@ -26031,6 +26317,7 @@ var init_Popover = __esm({
|
|
|
26031
26317
|
"use client";
|
|
26032
26318
|
init_Typography();
|
|
26033
26319
|
init_cn();
|
|
26320
|
+
init_useTapReveal();
|
|
26034
26321
|
arrowClasses = {
|
|
26035
26322
|
top: "top-full left-1/2 -translate-x-1/2 border-t-white border-l-transparent border-r-transparent border-b-transparent",
|
|
26036
26323
|
bottom: "bottom-full left-1/2 -translate-x-1/2 border-b-white border-l-transparent border-r-transparent border-t-transparent",
|
|
@@ -26101,18 +26388,32 @@ var init_Popover = __esm({
|
|
|
26101
26388
|
document.addEventListener("mousedown", handleClickOutside);
|
|
26102
26389
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
26103
26390
|
}, [isOpen, trigger]);
|
|
26104
|
-
const triggerProps
|
|
26391
|
+
const { triggerProps: tapTriggerProps } = useTapReveal({
|
|
26392
|
+
enabled: trigger === "hover",
|
|
26393
|
+
onReveal: handleOpen,
|
|
26394
|
+
onDismiss: handleClose,
|
|
26395
|
+
refs: [triggerRef, popoverRef]
|
|
26396
|
+
});
|
|
26397
|
+
const handlerProps = trigger === "click" ? {
|
|
26105
26398
|
onClick: handleToggle
|
|
26106
26399
|
} : {
|
|
26107
26400
|
onMouseEnter: handleOpen,
|
|
26108
|
-
onMouseLeave: handleClose
|
|
26401
|
+
onMouseLeave: handleClose,
|
|
26402
|
+
onPointerDown: tapTriggerProps.onPointerDown
|
|
26109
26403
|
};
|
|
26110
26404
|
const childElement = React85__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
26405
|
+
const childPointerDown = childElement.props.onPointerDown;
|
|
26111
26406
|
const triggerElement = React85__default.cloneElement(
|
|
26112
26407
|
childElement,
|
|
26113
26408
|
{
|
|
26114
26409
|
ref: triggerRef,
|
|
26115
|
-
...
|
|
26410
|
+
...handlerProps,
|
|
26411
|
+
...trigger === "hover" ? {
|
|
26412
|
+
onPointerDown: (e) => {
|
|
26413
|
+
tapTriggerProps.onPointerDown(e);
|
|
26414
|
+
childPointerDown?.(e);
|
|
26415
|
+
}
|
|
26416
|
+
} : void 0
|
|
26116
26417
|
}
|
|
26117
26418
|
);
|
|
26118
26419
|
const panel = isOpen && triggerRect ? /* @__PURE__ */ jsxs(
|
|
@@ -26643,6 +26944,7 @@ var init_Tooltip = __esm({
|
|
|
26643
26944
|
"use client";
|
|
26644
26945
|
init_Typography();
|
|
26645
26946
|
init_cn();
|
|
26947
|
+
init_useTapReveal();
|
|
26646
26948
|
TRIGGER_GAP2 = 8;
|
|
26647
26949
|
arrowClasses2 = {
|
|
26648
26950
|
top: "top-full left-1/2 -translate-x-1/2 border-t-primary border-l-transparent border-r-transparent border-b-transparent",
|
|
@@ -26687,6 +26989,11 @@ var init_Tooltip = __esm({
|
|
|
26687
26989
|
setIsVisible(false);
|
|
26688
26990
|
}, hideDelay);
|
|
26689
26991
|
};
|
|
26992
|
+
const { triggerProps } = useTapReveal({
|
|
26993
|
+
onReveal: handleMouseEnter,
|
|
26994
|
+
onDismiss: handleMouseLeave,
|
|
26995
|
+
refs: [triggerRef, tooltipRef]
|
|
26996
|
+
});
|
|
26690
26997
|
useLayoutEffect(() => {
|
|
26691
26998
|
if (isVisible) {
|
|
26692
26999
|
updatePosition();
|
|
@@ -26699,12 +27006,17 @@ var init_Tooltip = __esm({
|
|
|
26699
27006
|
};
|
|
26700
27007
|
}, []);
|
|
26701
27008
|
const triggerElement = React85__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
27009
|
+
const childPointerDown = triggerElement.props.onPointerDown;
|
|
26702
27010
|
const trigger = React85__default.cloneElement(triggerElement, {
|
|
26703
27011
|
ref: triggerRef,
|
|
26704
27012
|
onMouseEnter: handleMouseEnter,
|
|
26705
27013
|
onMouseLeave: handleMouseLeave,
|
|
26706
27014
|
onFocus: handleMouseEnter,
|
|
26707
|
-
onBlur: handleMouseLeave
|
|
27015
|
+
onBlur: handleMouseLeave,
|
|
27016
|
+
onPointerDown: (e) => {
|
|
27017
|
+
triggerProps.onPointerDown(e);
|
|
27018
|
+
childPointerDown?.(e);
|
|
27019
|
+
}
|
|
26708
27020
|
});
|
|
26709
27021
|
const tooltipContent = isVisible && triggerRect ? /* @__PURE__ */ jsxs(
|
|
26710
27022
|
"div",
|
|
@@ -30054,6 +30366,14 @@ var init_GraphView = __esm({
|
|
|
30054
30366
|
},
|
|
30055
30367
|
[onNodeClick]
|
|
30056
30368
|
);
|
|
30369
|
+
const handleNodePointerDown = useCallback(
|
|
30370
|
+
(e, node) => {
|
|
30371
|
+
if (e.pointerType === "mouse") return;
|
|
30372
|
+
handleNodeMouseEnter(node);
|
|
30373
|
+
handleNodeClickInternal(node);
|
|
30374
|
+
},
|
|
30375
|
+
[handleNodeMouseEnter, handleNodeClickInternal]
|
|
30376
|
+
);
|
|
30057
30377
|
if (nodes.length === 0) {
|
|
30058
30378
|
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") }) });
|
|
30059
30379
|
}
|
|
@@ -30113,6 +30433,7 @@ var init_GraphView = __esm({
|
|
|
30113
30433
|
onMouseEnter: () => handleNodeMouseEnter(node),
|
|
30114
30434
|
onMouseLeave: handleNodeMouseLeave,
|
|
30115
30435
|
onClick: () => handleNodeClickInternal(node),
|
|
30436
|
+
onPointerDown: (e) => handleNodePointerDown(e, node),
|
|
30116
30437
|
children: [
|
|
30117
30438
|
/* @__PURE__ */ jsx(
|
|
30118
30439
|
"circle",
|
|
@@ -30193,13 +30514,13 @@ var init_MapView = __esm({
|
|
|
30193
30514
|
shadowSize: [41, 41]
|
|
30194
30515
|
});
|
|
30195
30516
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
30196
|
-
const { useEffect:
|
|
30517
|
+
const { useEffect: useEffect82, useRef: useRef80, useCallback: useCallback125, useState: useState111 } = React85__default;
|
|
30197
30518
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
30198
30519
|
const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
30199
30520
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
30200
30521
|
const map = useMap();
|
|
30201
|
-
const prevRef =
|
|
30202
|
-
|
|
30522
|
+
const prevRef = useRef80({ centerLat, centerLng, zoom });
|
|
30523
|
+
useEffect82(() => {
|
|
30203
30524
|
const prev = prevRef.current;
|
|
30204
30525
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
30205
30526
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -30210,7 +30531,7 @@ var init_MapView = __esm({
|
|
|
30210
30531
|
}
|
|
30211
30532
|
function MapClickHandler({ onMapClick }) {
|
|
30212
30533
|
const map = useMap();
|
|
30213
|
-
|
|
30534
|
+
useEffect82(() => {
|
|
30214
30535
|
if (!onMapClick) return;
|
|
30215
30536
|
const handler = (e) => {
|
|
30216
30537
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -30238,8 +30559,8 @@ var init_MapView = __esm({
|
|
|
30238
30559
|
showAttribution = true
|
|
30239
30560
|
}) {
|
|
30240
30561
|
const eventBus = useEventBus3();
|
|
30241
|
-
const [clickedPosition, setClickedPosition] =
|
|
30242
|
-
const handleMapClick =
|
|
30562
|
+
const [clickedPosition, setClickedPosition] = useState111(null);
|
|
30563
|
+
const handleMapClick = useCallback125((lat, lng) => {
|
|
30243
30564
|
if (showClickedPin) {
|
|
30244
30565
|
setClickedPosition({ lat, lng });
|
|
30245
30566
|
}
|
|
@@ -30248,7 +30569,7 @@ var init_MapView = __esm({
|
|
|
30248
30569
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
30249
30570
|
}
|
|
30250
30571
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
30251
|
-
const handleMarkerClick =
|
|
30572
|
+
const handleMarkerClick = useCallback125((marker) => {
|
|
30252
30573
|
onMarkerClick?.(marker);
|
|
30253
30574
|
if (markerClickEvent) {
|
|
30254
30575
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -30589,7 +30910,7 @@ var init_StarRating = __esm({
|
|
|
30589
30910
|
"aria-valuenow": value,
|
|
30590
30911
|
tabIndex: readOnly ? void 0 : 0,
|
|
30591
30912
|
onKeyDown: handleKeyDown,
|
|
30592
|
-
|
|
30913
|
+
onPointerLeave: () => setHoverValue(null),
|
|
30593
30914
|
children: Array.from({ length: max }, (_, i) => {
|
|
30594
30915
|
const fillLevel = Math.max(0, Math.min(1, displayValue - i));
|
|
30595
30916
|
const isFull = fillLevel >= 1;
|
|
@@ -30599,7 +30920,7 @@ var init_StarRating = __esm({
|
|
|
30599
30920
|
{
|
|
30600
30921
|
className: "relative inline-block",
|
|
30601
30922
|
onClick: () => handleStarClick(i, false),
|
|
30602
|
-
|
|
30923
|
+
onPointerMove: (e) => {
|
|
30603
30924
|
if (readOnly) return;
|
|
30604
30925
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
30605
30926
|
const isLeftHalf = e.clientX - rect.left < rect.width / 2;
|
|
@@ -34489,7 +34810,7 @@ var init_PositionedCanvas = __esm({
|
|
|
34489
34810
|
{
|
|
34490
34811
|
ref: containerRef,
|
|
34491
34812
|
"data-testid": "positioned-canvas",
|
|
34492
|
-
className: "relative bg-background border border-border rounded-container overflow-hidden",
|
|
34813
|
+
className: "relative bg-background border border-border rounded-container overflow-hidden touch-none",
|
|
34493
34814
|
style: { width, height },
|
|
34494
34815
|
onClick: handleContainerClick,
|
|
34495
34816
|
children: items.map((item) => {
|
|
@@ -38658,6 +38979,7 @@ var init_GraphCanvas = __esm({
|
|
|
38658
38979
|
init_ErrorState();
|
|
38659
38980
|
init_EmptyState();
|
|
38660
38981
|
init_useEventBus();
|
|
38982
|
+
init_useCanvasGestures();
|
|
38661
38983
|
GROUP_COLORS2 = [
|
|
38662
38984
|
"var(--color-primary)",
|
|
38663
38985
|
"var(--color-success)",
|
|
@@ -38695,6 +39017,10 @@ var init_GraphCanvas = __esm({
|
|
|
38695
39017
|
const animRef = useRef(0);
|
|
38696
39018
|
const [zoom, setZoom] = useState(1);
|
|
38697
39019
|
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
|
39020
|
+
const zoomRef = useRef(zoom);
|
|
39021
|
+
zoomRef.current = zoom;
|
|
39022
|
+
const offsetRef = useRef(offset);
|
|
39023
|
+
offsetRef.current = offset;
|
|
38698
39024
|
const [hoveredNode, setHoveredNode] = useState(null);
|
|
38699
39025
|
const nodesRef = useRef([]);
|
|
38700
39026
|
const [, forceUpdate] = useState(0);
|
|
@@ -38954,25 +39280,27 @@ var init_GraphCanvas = __esm({
|
|
|
38954
39280
|
setZoom(1);
|
|
38955
39281
|
setOffset({ x: 0, y: 0 });
|
|
38956
39282
|
}, []);
|
|
38957
|
-
const
|
|
38958
|
-
(
|
|
38959
|
-
|
|
38960
|
-
|
|
38961
|
-
|
|
38962
|
-
|
|
38963
|
-
|
|
38964
|
-
|
|
38965
|
-
|
|
38966
|
-
|
|
38967
|
-
|
|
38968
|
-
|
|
38969
|
-
|
|
38970
|
-
|
|
38971
|
-
|
|
38972
|
-
|
|
38973
|
-
|
|
38974
|
-
|
|
38975
|
-
|
|
39283
|
+
const applyZoom = useCallback((factor, cx, cy) => {
|
|
39284
|
+
if (!interactive) return;
|
|
39285
|
+
const oldZoom = zoomRef.current;
|
|
39286
|
+
const newZoom = Math.max(0.3, Math.min(3, oldZoom * factor));
|
|
39287
|
+
if (newZoom === oldZoom) return;
|
|
39288
|
+
const o = offsetRef.current;
|
|
39289
|
+
setOffset({
|
|
39290
|
+
x: cx - (cx - o.x) * (newZoom / oldZoom),
|
|
39291
|
+
y: cy - (cy - o.y) * (newZoom / oldZoom)
|
|
39292
|
+
});
|
|
39293
|
+
setZoom(newZoom);
|
|
39294
|
+
}, [interactive]);
|
|
39295
|
+
const applyPanDelta = useCallback((dx, dy) => {
|
|
39296
|
+
if (!interactive) return;
|
|
39297
|
+
setOffset((o) => ({ x: o.x + dx, y: o.y + dy }));
|
|
39298
|
+
}, [interactive]);
|
|
39299
|
+
const cancelSinglePointer = useCallback(() => {
|
|
39300
|
+
interactionRef.current.mode = "none";
|
|
39301
|
+
interactionRef.current.dragNodeId = null;
|
|
39302
|
+
}, []);
|
|
39303
|
+
const handlePointerDown = useCallback(
|
|
38976
39304
|
(e) => {
|
|
38977
39305
|
const coords = toCoords(e);
|
|
38978
39306
|
if (!coords) return;
|
|
@@ -38994,7 +39322,7 @@ var init_GraphCanvas = __esm({
|
|
|
38994
39322
|
},
|
|
38995
39323
|
[toCoords, nodeAt, draggable, interactive, offset]
|
|
38996
39324
|
);
|
|
38997
|
-
const
|
|
39325
|
+
const handlePointerMove = useCallback(
|
|
38998
39326
|
(e) => {
|
|
38999
39327
|
const state = interactionRef.current;
|
|
39000
39328
|
if (state.mode === "panning") {
|
|
@@ -39023,7 +39351,7 @@ var init_GraphCanvas = __esm({
|
|
|
39023
39351
|
},
|
|
39024
39352
|
[toCoords, nodeAt]
|
|
39025
39353
|
);
|
|
39026
|
-
const
|
|
39354
|
+
const handlePointerUp = useCallback(
|
|
39027
39355
|
(e) => {
|
|
39028
39356
|
const state = interactionRef.current;
|
|
39029
39357
|
const moved = Math.abs(e.clientX - state.downPos.x) + Math.abs(e.clientY - state.downPos.y);
|
|
@@ -39040,11 +39368,19 @@ var init_GraphCanvas = __esm({
|
|
|
39040
39368
|
},
|
|
39041
39369
|
[toCoords, nodeAt, handleNodeClick]
|
|
39042
39370
|
);
|
|
39043
|
-
const
|
|
39044
|
-
interactionRef.current.mode = "none";
|
|
39045
|
-
interactionRef.current.dragNodeId = null;
|
|
39371
|
+
const handlePointerLeave = useCallback(() => {
|
|
39046
39372
|
setHoveredNode(null);
|
|
39047
39373
|
}, []);
|
|
39374
|
+
const gestureHandlers = useCanvasGestures({
|
|
39375
|
+
canvasRef,
|
|
39376
|
+
enabled: interactive || draggable,
|
|
39377
|
+
onPointerDown: handlePointerDown,
|
|
39378
|
+
onPointerMove: handlePointerMove,
|
|
39379
|
+
onPointerUp: handlePointerUp,
|
|
39380
|
+
onZoom: applyZoom,
|
|
39381
|
+
onPanDelta: applyPanDelta,
|
|
39382
|
+
onMultiTouchStart: cancelSinglePointer
|
|
39383
|
+
});
|
|
39048
39384
|
const handleDoubleClick = useCallback(
|
|
39049
39385
|
(e) => {
|
|
39050
39386
|
const coords = toCoords(e);
|
|
@@ -39113,13 +39449,14 @@ var init_GraphCanvas = __esm({
|
|
|
39113
39449
|
ref: canvasRef,
|
|
39114
39450
|
width: Math.round(logicalW * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
|
|
39115
39451
|
height: Math.round(height * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
|
|
39116
|
-
className: "w-full cursor-grab active:cursor-grabbing",
|
|
39452
|
+
className: "w-full cursor-grab active:cursor-grabbing touch-none",
|
|
39117
39453
|
style: { height },
|
|
39118
|
-
|
|
39119
|
-
|
|
39120
|
-
|
|
39121
|
-
|
|
39122
|
-
|
|
39454
|
+
onPointerDown: gestureHandlers.onPointerDown,
|
|
39455
|
+
onPointerMove: gestureHandlers.onPointerMove,
|
|
39456
|
+
onPointerUp: gestureHandlers.onPointerUp,
|
|
39457
|
+
onPointerCancel: gestureHandlers.onPointerCancel,
|
|
39458
|
+
onPointerLeave: handlePointerLeave,
|
|
39459
|
+
onWheel: gestureHandlers.onWheel,
|
|
39123
39460
|
onDoubleClick: handleDoubleClick
|
|
39124
39461
|
}
|
|
39125
39462
|
) }),
|
|
@@ -43591,6 +43928,9 @@ var init_GameCanvas3D2 = __esm({
|
|
|
43591
43928
|
target: cameraTarget,
|
|
43592
43929
|
enableDamping: true,
|
|
43593
43930
|
dampingFactor: 0.05,
|
|
43931
|
+
enableZoom: true,
|
|
43932
|
+
enablePan: true,
|
|
43933
|
+
touches: { ONE: THREE3.TOUCH.ROTATE, TWO: THREE3.TOUCH.DOLLY_PAN },
|
|
43594
43934
|
minDistance: 2,
|
|
43595
43935
|
maxDistance: 100,
|
|
43596
43936
|
maxPolarAngle: Math.PI / 2 - 0.1
|
|
@@ -48902,20 +49242,21 @@ var init_SplitPane = __esm({
|
|
|
48902
49242
|
const [ratio, setRatio] = useState(initialRatio);
|
|
48903
49243
|
const containerRef = useRef(null);
|
|
48904
49244
|
const isDragging = useRef(false);
|
|
48905
|
-
const
|
|
49245
|
+
const handlePointerDown = useCallback(
|
|
48906
49246
|
(e) => {
|
|
48907
49247
|
if (!resizable) return;
|
|
48908
49248
|
e.preventDefault();
|
|
48909
49249
|
isDragging.current = true;
|
|
48910
|
-
|
|
49250
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
49251
|
+
const handlePointerMove = (ev) => {
|
|
48911
49252
|
if (!isDragging.current || !containerRef.current) return;
|
|
48912
49253
|
const rect = containerRef.current.getBoundingClientRect();
|
|
48913
49254
|
let newRatio;
|
|
48914
49255
|
if (direction === "horizontal") {
|
|
48915
|
-
const x =
|
|
49256
|
+
const x = ev.clientX - rect.left;
|
|
48916
49257
|
newRatio = x / rect.width * 100;
|
|
48917
49258
|
} else {
|
|
48918
|
-
const y =
|
|
49259
|
+
const y = ev.clientY - rect.top;
|
|
48919
49260
|
newRatio = y / rect.height * 100;
|
|
48920
49261
|
}
|
|
48921
49262
|
const minRatio = minSize / (direction === "horizontal" ? rect.width : rect.height) * 100;
|
|
@@ -48923,13 +49264,15 @@ var init_SplitPane = __esm({
|
|
|
48923
49264
|
newRatio = Math.max(minRatio, Math.min(maxRatio, newRatio));
|
|
48924
49265
|
setRatio(newRatio);
|
|
48925
49266
|
};
|
|
48926
|
-
const
|
|
49267
|
+
const handlePointerUp = () => {
|
|
48927
49268
|
isDragging.current = false;
|
|
48928
|
-
document.removeEventListener("
|
|
48929
|
-
document.removeEventListener("
|
|
49269
|
+
document.removeEventListener("pointermove", handlePointerMove);
|
|
49270
|
+
document.removeEventListener("pointerup", handlePointerUp);
|
|
49271
|
+
document.removeEventListener("pointercancel", handlePointerUp);
|
|
48930
49272
|
};
|
|
48931
|
-
document.addEventListener("
|
|
48932
|
-
document.addEventListener("
|
|
49273
|
+
document.addEventListener("pointermove", handlePointerMove);
|
|
49274
|
+
document.addEventListener("pointerup", handlePointerUp);
|
|
49275
|
+
document.addEventListener("pointercancel", handlePointerUp);
|
|
48933
49276
|
},
|
|
48934
49277
|
[direction, minSize, resizable]
|
|
48935
49278
|
);
|
|
@@ -48958,9 +49301,9 @@ var init_SplitPane = __esm({
|
|
|
48958
49301
|
resizable && /* @__PURE__ */ jsx(
|
|
48959
49302
|
"div",
|
|
48960
49303
|
{
|
|
48961
|
-
|
|
49304
|
+
onPointerDown: handlePointerDown,
|
|
48962
49305
|
className: cn(
|
|
48963
|
-
"flex-shrink-0 bg-border transition-colors",
|
|
49306
|
+
"flex-shrink-0 bg-border transition-colors touch-none",
|
|
48964
49307
|
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"
|
|
48965
49308
|
)
|
|
48966
49309
|
}
|