@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/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) => {
|
|
@@ -38636,6 +38957,13 @@ var init_DocumentViewer = __esm({
|
|
|
38636
38957
|
DocumentViewer.displayName = "DocumentViewer";
|
|
38637
38958
|
}
|
|
38638
38959
|
});
|
|
38960
|
+
function measureLabelWidth(text) {
|
|
38961
|
+
if (typeof document === "undefined") return text.length * 6;
|
|
38962
|
+
if (!labelMeasureCtx) labelMeasureCtx = document.createElement("canvas").getContext("2d");
|
|
38963
|
+
if (!labelMeasureCtx) return text.length * 6;
|
|
38964
|
+
labelMeasureCtx.font = "10px system-ui";
|
|
38965
|
+
return labelMeasureCtx.measureText(text).width;
|
|
38966
|
+
}
|
|
38639
38967
|
function getGroupColor(group, groups) {
|
|
38640
38968
|
if (!group) return GROUP_COLORS2[0];
|
|
38641
38969
|
const idx = groups.indexOf(group);
|
|
@@ -38647,7 +38975,7 @@ function resolveColor2(color, el) {
|
|
|
38647
38975
|
const resolved = getComputedStyle(el).getPropertyValue(m[1]).trim();
|
|
38648
38976
|
return resolved || (m[2]?.trim() ?? "#888888");
|
|
38649
38977
|
}
|
|
38650
|
-
var GROUP_COLORS2, GraphCanvas;
|
|
38978
|
+
var GROUP_COLORS2, labelMeasureCtx, GraphCanvas;
|
|
38651
38979
|
var init_GraphCanvas = __esm({
|
|
38652
38980
|
"components/core/molecules/GraphCanvas.tsx"() {
|
|
38653
38981
|
"use client";
|
|
@@ -38658,6 +38986,7 @@ var init_GraphCanvas = __esm({
|
|
|
38658
38986
|
init_ErrorState();
|
|
38659
38987
|
init_EmptyState();
|
|
38660
38988
|
init_useEventBus();
|
|
38989
|
+
init_useCanvasGestures();
|
|
38661
38990
|
GROUP_COLORS2 = [
|
|
38662
38991
|
"var(--color-primary)",
|
|
38663
38992
|
"var(--color-success)",
|
|
@@ -38666,6 +38995,7 @@ var init_GraphCanvas = __esm({
|
|
|
38666
38995
|
"var(--color-info)",
|
|
38667
38996
|
"var(--color-accent)"
|
|
38668
38997
|
];
|
|
38998
|
+
labelMeasureCtx = null;
|
|
38669
38999
|
GraphCanvas = ({
|
|
38670
39000
|
title,
|
|
38671
39001
|
nodes: propNodes = [],
|
|
@@ -38695,6 +39025,10 @@ var init_GraphCanvas = __esm({
|
|
|
38695
39025
|
const animRef = useRef(0);
|
|
38696
39026
|
const [zoom, setZoom] = useState(1);
|
|
38697
39027
|
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
|
39028
|
+
const zoomRef = useRef(zoom);
|
|
39029
|
+
zoomRef.current = zoom;
|
|
39030
|
+
const offsetRef = useRef(offset);
|
|
39031
|
+
offsetRef.current = offset;
|
|
38698
39032
|
const [hoveredNode, setHoveredNode] = useState(null);
|
|
38699
39033
|
const nodesRef = useRef([]);
|
|
38700
39034
|
const [, forceUpdate] = useState(0);
|
|
@@ -38842,22 +39176,36 @@ var init_GraphCanvas = __esm({
|
|
|
38842
39176
|
node.x = Math.max(30, Math.min(w - 30, node.x));
|
|
38843
39177
|
node.y = Math.max(30, Math.min(h - 30, node.y));
|
|
38844
39178
|
}
|
|
39179
|
+
const LABEL_GAP = 12;
|
|
39180
|
+
const LABEL_H = 12;
|
|
39181
|
+
const pad = nodeSpacing / 2;
|
|
38845
39182
|
for (let i = 0; i < nodes.length; i++) {
|
|
38846
39183
|
for (let j = i + 1; j < nodes.length; j++) {
|
|
38847
39184
|
const a = nodes[i];
|
|
38848
39185
|
const b = nodes[j];
|
|
38849
|
-
const
|
|
38850
|
-
const
|
|
38851
|
-
|
|
38852
|
-
|
|
38853
|
-
|
|
38854
|
-
|
|
38855
|
-
|
|
38856
|
-
|
|
38857
|
-
|
|
38858
|
-
|
|
38859
|
-
|
|
38860
|
-
|
|
39186
|
+
const ar = a.size || 8;
|
|
39187
|
+
const br = b.size || 8;
|
|
39188
|
+
if (showLabels) {
|
|
39189
|
+
if (a.labelW === void 0) a.labelW = a.label ? measureLabelWidth(a.label) : 0;
|
|
39190
|
+
if (b.labelW === void 0) b.labelW = b.label ? measureLabelWidth(b.label) : 0;
|
|
39191
|
+
}
|
|
39192
|
+
const labelBelow = showLabels ? LABEL_GAP + LABEL_H : 0;
|
|
39193
|
+
const aHalfW = Math.max(ar, (a.labelW ?? 0) / 2) + pad;
|
|
39194
|
+
const bHalfW = Math.max(br, (b.labelW ?? 0) / 2) + pad;
|
|
39195
|
+
const aTop = a.y - ar - pad, aBot = a.y + ar + labelBelow + pad;
|
|
39196
|
+
const bTop = b.y - br - pad, bBot = b.y + br + labelBelow + pad;
|
|
39197
|
+
const overlapX = Math.min(a.x + aHalfW, b.x + bHalfW) - Math.max(a.x - aHalfW, b.x - bHalfW);
|
|
39198
|
+
const overlapY = Math.min(aBot, bBot) - Math.max(aTop, bTop);
|
|
39199
|
+
if (overlapX > 0 && overlapY > 0) {
|
|
39200
|
+
if (overlapX <= overlapY) {
|
|
39201
|
+
const push = overlapX / 2 * (b.x >= a.x ? 1 : -1);
|
|
39202
|
+
a.x = Math.max(30, Math.min(w - 30, a.x - push));
|
|
39203
|
+
b.x = Math.max(30, Math.min(w - 30, b.x + push));
|
|
39204
|
+
} else {
|
|
39205
|
+
const push = overlapY / 2 * (bTop + bBot >= aTop + aBot ? 1 : -1);
|
|
39206
|
+
a.y = Math.max(30, Math.min(h - 30, a.y - push));
|
|
39207
|
+
b.y = Math.max(30, Math.min(h - 30, b.y + push));
|
|
39208
|
+
}
|
|
38861
39209
|
}
|
|
38862
39210
|
}
|
|
38863
39211
|
}
|
|
@@ -38874,7 +39222,7 @@ var init_GraphCanvas = __esm({
|
|
|
38874
39222
|
return () => {
|
|
38875
39223
|
cancelAnimationFrame(animRef.current);
|
|
38876
39224
|
};
|
|
38877
|
-
}, [propNodes, propEdges, layout, repulsion, linkDistance, nodeSpacing, logicalW, height]);
|
|
39225
|
+
}, [propNodes, propEdges, layout, repulsion, linkDistance, nodeSpacing, showLabels, logicalW, height]);
|
|
38878
39226
|
useEffect(() => {
|
|
38879
39227
|
const canvas = canvasRef.current;
|
|
38880
39228
|
if (!canvas) return;
|
|
@@ -38954,25 +39302,27 @@ var init_GraphCanvas = __esm({
|
|
|
38954
39302
|
setZoom(1);
|
|
38955
39303
|
setOffset({ x: 0, y: 0 });
|
|
38956
39304
|
}, []);
|
|
38957
|
-
const
|
|
38958
|
-
(
|
|
38959
|
-
|
|
38960
|
-
|
|
38961
|
-
|
|
38962
|
-
|
|
38963
|
-
|
|
38964
|
-
|
|
38965
|
-
|
|
38966
|
-
|
|
38967
|
-
|
|
38968
|
-
|
|
38969
|
-
|
|
38970
|
-
|
|
38971
|
-
|
|
38972
|
-
|
|
38973
|
-
|
|
38974
|
-
|
|
38975
|
-
|
|
39305
|
+
const applyZoom = useCallback((factor, cx, cy) => {
|
|
39306
|
+
if (!interactive) return;
|
|
39307
|
+
const oldZoom = zoomRef.current;
|
|
39308
|
+
const newZoom = Math.max(0.3, Math.min(3, oldZoom * factor));
|
|
39309
|
+
if (newZoom === oldZoom) return;
|
|
39310
|
+
const o = offsetRef.current;
|
|
39311
|
+
setOffset({
|
|
39312
|
+
x: cx - (cx - o.x) * (newZoom / oldZoom),
|
|
39313
|
+
y: cy - (cy - o.y) * (newZoom / oldZoom)
|
|
39314
|
+
});
|
|
39315
|
+
setZoom(newZoom);
|
|
39316
|
+
}, [interactive]);
|
|
39317
|
+
const applyPanDelta = useCallback((dx, dy) => {
|
|
39318
|
+
if (!interactive) return;
|
|
39319
|
+
setOffset((o) => ({ x: o.x + dx, y: o.y + dy }));
|
|
39320
|
+
}, [interactive]);
|
|
39321
|
+
const cancelSinglePointer = useCallback(() => {
|
|
39322
|
+
interactionRef.current.mode = "none";
|
|
39323
|
+
interactionRef.current.dragNodeId = null;
|
|
39324
|
+
}, []);
|
|
39325
|
+
const handlePointerDown = useCallback(
|
|
38976
39326
|
(e) => {
|
|
38977
39327
|
const coords = toCoords(e);
|
|
38978
39328
|
if (!coords) return;
|
|
@@ -38994,7 +39344,7 @@ var init_GraphCanvas = __esm({
|
|
|
38994
39344
|
},
|
|
38995
39345
|
[toCoords, nodeAt, draggable, interactive, offset]
|
|
38996
39346
|
);
|
|
38997
|
-
const
|
|
39347
|
+
const handlePointerMove = useCallback(
|
|
38998
39348
|
(e) => {
|
|
38999
39349
|
const state = interactionRef.current;
|
|
39000
39350
|
if (state.mode === "panning") {
|
|
@@ -39023,7 +39373,7 @@ var init_GraphCanvas = __esm({
|
|
|
39023
39373
|
},
|
|
39024
39374
|
[toCoords, nodeAt]
|
|
39025
39375
|
);
|
|
39026
|
-
const
|
|
39376
|
+
const handlePointerUp = useCallback(
|
|
39027
39377
|
(e) => {
|
|
39028
39378
|
const state = interactionRef.current;
|
|
39029
39379
|
const moved = Math.abs(e.clientX - state.downPos.x) + Math.abs(e.clientY - state.downPos.y);
|
|
@@ -39040,11 +39390,19 @@ var init_GraphCanvas = __esm({
|
|
|
39040
39390
|
},
|
|
39041
39391
|
[toCoords, nodeAt, handleNodeClick]
|
|
39042
39392
|
);
|
|
39043
|
-
const
|
|
39044
|
-
interactionRef.current.mode = "none";
|
|
39045
|
-
interactionRef.current.dragNodeId = null;
|
|
39393
|
+
const handlePointerLeave = useCallback(() => {
|
|
39046
39394
|
setHoveredNode(null);
|
|
39047
39395
|
}, []);
|
|
39396
|
+
const gestureHandlers = useCanvasGestures({
|
|
39397
|
+
canvasRef,
|
|
39398
|
+
enabled: interactive || draggable,
|
|
39399
|
+
onPointerDown: handlePointerDown,
|
|
39400
|
+
onPointerMove: handlePointerMove,
|
|
39401
|
+
onPointerUp: handlePointerUp,
|
|
39402
|
+
onZoom: applyZoom,
|
|
39403
|
+
onPanDelta: applyPanDelta,
|
|
39404
|
+
onMultiTouchStart: cancelSinglePointer
|
|
39405
|
+
});
|
|
39048
39406
|
const handleDoubleClick = useCallback(
|
|
39049
39407
|
(e) => {
|
|
39050
39408
|
const coords = toCoords(e);
|
|
@@ -39113,13 +39471,14 @@ var init_GraphCanvas = __esm({
|
|
|
39113
39471
|
ref: canvasRef,
|
|
39114
39472
|
width: Math.round(logicalW * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
|
|
39115
39473
|
height: Math.round(height * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
|
|
39116
|
-
className: "w-full cursor-grab active:cursor-grabbing",
|
|
39474
|
+
className: "w-full cursor-grab active:cursor-grabbing touch-none",
|
|
39117
39475
|
style: { height },
|
|
39118
|
-
|
|
39119
|
-
|
|
39120
|
-
|
|
39121
|
-
|
|
39122
|
-
|
|
39476
|
+
onPointerDown: gestureHandlers.onPointerDown,
|
|
39477
|
+
onPointerMove: gestureHandlers.onPointerMove,
|
|
39478
|
+
onPointerUp: gestureHandlers.onPointerUp,
|
|
39479
|
+
onPointerCancel: gestureHandlers.onPointerCancel,
|
|
39480
|
+
onPointerLeave: handlePointerLeave,
|
|
39481
|
+
onWheel: gestureHandlers.onWheel,
|
|
39123
39482
|
onDoubleClick: handleDoubleClick
|
|
39124
39483
|
}
|
|
39125
39484
|
) }),
|
|
@@ -43591,6 +43950,9 @@ var init_GameCanvas3D2 = __esm({
|
|
|
43591
43950
|
target: cameraTarget,
|
|
43592
43951
|
enableDamping: true,
|
|
43593
43952
|
dampingFactor: 0.05,
|
|
43953
|
+
enableZoom: true,
|
|
43954
|
+
enablePan: true,
|
|
43955
|
+
touches: { ONE: THREE3.TOUCH.ROTATE, TWO: THREE3.TOUCH.DOLLY_PAN },
|
|
43594
43956
|
minDistance: 2,
|
|
43595
43957
|
maxDistance: 100,
|
|
43596
43958
|
maxPolarAngle: Math.PI / 2 - 0.1
|
|
@@ -48902,20 +49264,21 @@ var init_SplitPane = __esm({
|
|
|
48902
49264
|
const [ratio, setRatio] = useState(initialRatio);
|
|
48903
49265
|
const containerRef = useRef(null);
|
|
48904
49266
|
const isDragging = useRef(false);
|
|
48905
|
-
const
|
|
49267
|
+
const handlePointerDown = useCallback(
|
|
48906
49268
|
(e) => {
|
|
48907
49269
|
if (!resizable) return;
|
|
48908
49270
|
e.preventDefault();
|
|
48909
49271
|
isDragging.current = true;
|
|
48910
|
-
|
|
49272
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
49273
|
+
const handlePointerMove = (ev) => {
|
|
48911
49274
|
if (!isDragging.current || !containerRef.current) return;
|
|
48912
49275
|
const rect = containerRef.current.getBoundingClientRect();
|
|
48913
49276
|
let newRatio;
|
|
48914
49277
|
if (direction === "horizontal") {
|
|
48915
|
-
const x =
|
|
49278
|
+
const x = ev.clientX - rect.left;
|
|
48916
49279
|
newRatio = x / rect.width * 100;
|
|
48917
49280
|
} else {
|
|
48918
|
-
const y =
|
|
49281
|
+
const y = ev.clientY - rect.top;
|
|
48919
49282
|
newRatio = y / rect.height * 100;
|
|
48920
49283
|
}
|
|
48921
49284
|
const minRatio = minSize / (direction === "horizontal" ? rect.width : rect.height) * 100;
|
|
@@ -48923,13 +49286,15 @@ var init_SplitPane = __esm({
|
|
|
48923
49286
|
newRatio = Math.max(minRatio, Math.min(maxRatio, newRatio));
|
|
48924
49287
|
setRatio(newRatio);
|
|
48925
49288
|
};
|
|
48926
|
-
const
|
|
49289
|
+
const handlePointerUp = () => {
|
|
48927
49290
|
isDragging.current = false;
|
|
48928
|
-
document.removeEventListener("
|
|
48929
|
-
document.removeEventListener("
|
|
49291
|
+
document.removeEventListener("pointermove", handlePointerMove);
|
|
49292
|
+
document.removeEventListener("pointerup", handlePointerUp);
|
|
49293
|
+
document.removeEventListener("pointercancel", handlePointerUp);
|
|
48930
49294
|
};
|
|
48931
|
-
document.addEventListener("
|
|
48932
|
-
document.addEventListener("
|
|
49295
|
+
document.addEventListener("pointermove", handlePointerMove);
|
|
49296
|
+
document.addEventListener("pointerup", handlePointerUp);
|
|
49297
|
+
document.addEventListener("pointercancel", handlePointerUp);
|
|
48933
49298
|
},
|
|
48934
49299
|
[direction, minSize, resizable]
|
|
48935
49300
|
);
|
|
@@ -48958,9 +49323,9 @@ var init_SplitPane = __esm({
|
|
|
48958
49323
|
resizable && /* @__PURE__ */ jsx(
|
|
48959
49324
|
"div",
|
|
48960
49325
|
{
|
|
48961
|
-
|
|
49326
|
+
onPointerDown: handlePointerDown,
|
|
48962
49327
|
className: cn(
|
|
48963
|
-
"flex-shrink-0 bg-border transition-colors",
|
|
49328
|
+
"flex-shrink-0 bg-border transition-colors touch-none",
|
|
48964
49329
|
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
49330
|
)
|
|
48966
49331
|
}
|