@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/components/index.js
CHANGED
|
@@ -3202,12 +3202,60 @@ var init_Avatar = __esm({
|
|
|
3202
3202
|
Avatar.displayName = "Avatar";
|
|
3203
3203
|
}
|
|
3204
3204
|
});
|
|
3205
|
+
function useTapReveal(options = {}) {
|
|
3206
|
+
const { onReveal, onDismiss, refs, enabled = true } = options;
|
|
3207
|
+
const [revealed, setRevealed] = useState(false);
|
|
3208
|
+
const onRevealRef = useRef(onReveal);
|
|
3209
|
+
const onDismissRef = useRef(onDismiss);
|
|
3210
|
+
onRevealRef.current = onReveal;
|
|
3211
|
+
onDismissRef.current = onDismiss;
|
|
3212
|
+
const reveal = useCallback(() => {
|
|
3213
|
+
setRevealed((wasRevealed) => {
|
|
3214
|
+
if (!wasRevealed) onRevealRef.current?.();
|
|
3215
|
+
return true;
|
|
3216
|
+
});
|
|
3217
|
+
}, []);
|
|
3218
|
+
const dismiss = useCallback(() => {
|
|
3219
|
+
setRevealed((wasRevealed) => {
|
|
3220
|
+
if (wasRevealed) onDismissRef.current?.();
|
|
3221
|
+
return false;
|
|
3222
|
+
});
|
|
3223
|
+
}, []);
|
|
3224
|
+
const onPointerDown = useCallback(
|
|
3225
|
+
(e) => {
|
|
3226
|
+
if (!enabled || e.pointerType === "mouse") return;
|
|
3227
|
+
if (revealed) dismiss();
|
|
3228
|
+
else reveal();
|
|
3229
|
+
},
|
|
3230
|
+
[enabled, revealed, reveal, dismiss]
|
|
3231
|
+
);
|
|
3232
|
+
useEffect(() => {
|
|
3233
|
+
if (!revealed || typeof document === "undefined") return;
|
|
3234
|
+
const onDocDown = (ev) => {
|
|
3235
|
+
const target = ev.target;
|
|
3236
|
+
if (!(target instanceof Node)) return;
|
|
3237
|
+
const inside = (refs ?? []).some((r) => r.current?.contains(target));
|
|
3238
|
+
if (!inside) dismiss();
|
|
3239
|
+
};
|
|
3240
|
+
const id = setTimeout(() => document.addEventListener("pointerdown", onDocDown), 0);
|
|
3241
|
+
return () => {
|
|
3242
|
+
clearTimeout(id);
|
|
3243
|
+
document.removeEventListener("pointerdown", onDocDown);
|
|
3244
|
+
};
|
|
3245
|
+
}, [revealed, refs, dismiss]);
|
|
3246
|
+
return { revealed, triggerProps: { onPointerDown }, reveal, dismiss };
|
|
3247
|
+
}
|
|
3248
|
+
var init_useTapReveal = __esm({
|
|
3249
|
+
"hooks/useTapReveal.ts"() {
|
|
3250
|
+
}
|
|
3251
|
+
});
|
|
3205
3252
|
var paddingStyles2, paddingXStyles, paddingYStyles, marginStyles, marginXStyles, marginYStyles, bgStyles, roundedStyles, shadowStyles2, displayStyles, overflowStyles, positionStyles, Box;
|
|
3206
3253
|
var init_Box = __esm({
|
|
3207
3254
|
"components/core/atoms/Box.tsx"() {
|
|
3208
3255
|
"use client";
|
|
3209
3256
|
init_cn();
|
|
3210
3257
|
init_useEventBus();
|
|
3258
|
+
init_useTapReveal();
|
|
3211
3259
|
paddingStyles2 = {
|
|
3212
3260
|
none: "p-0",
|
|
3213
3261
|
xs: "p-1",
|
|
@@ -3333,10 +3381,12 @@ var init_Box = __esm({
|
|
|
3333
3381
|
action,
|
|
3334
3382
|
actionPayload,
|
|
3335
3383
|
hoverEvent,
|
|
3384
|
+
tapReveal = true,
|
|
3336
3385
|
maxWidth,
|
|
3337
3386
|
onClick,
|
|
3338
3387
|
onMouseEnter,
|
|
3339
3388
|
onMouseLeave,
|
|
3389
|
+
onPointerDown,
|
|
3340
3390
|
...rest
|
|
3341
3391
|
}, ref) => {
|
|
3342
3392
|
const eventBus = useEventBus();
|
|
@@ -3359,6 +3409,19 @@ var init_Box = __esm({
|
|
|
3359
3409
|
}
|
|
3360
3410
|
onMouseLeave?.(e);
|
|
3361
3411
|
}, [hoverEvent, eventBus, onMouseLeave]);
|
|
3412
|
+
const { triggerProps } = useTapReveal({
|
|
3413
|
+
enabled: tapReveal && !!hoverEvent,
|
|
3414
|
+
onReveal: useCallback(() => {
|
|
3415
|
+
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
|
|
3416
|
+
}, [hoverEvent, eventBus]),
|
|
3417
|
+
onDismiss: useCallback(() => {
|
|
3418
|
+
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
|
|
3419
|
+
}, [hoverEvent, eventBus])
|
|
3420
|
+
});
|
|
3421
|
+
const handlePointerDown = useCallback((e) => {
|
|
3422
|
+
if (hoverEvent && tapReveal) triggerProps.onPointerDown(e);
|
|
3423
|
+
onPointerDown?.(e);
|
|
3424
|
+
}, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
|
|
3362
3425
|
const isClickable = action || onClick;
|
|
3363
3426
|
return React79__default.createElement(
|
|
3364
3427
|
Component2,
|
|
@@ -3386,6 +3449,7 @@ var init_Box = __esm({
|
|
|
3386
3449
|
onClick: isClickable ? handleClick : void 0,
|
|
3387
3450
|
onMouseEnter: hoverEvent || onMouseEnter ? handleMouseEnter : void 0,
|
|
3388
3451
|
onMouseLeave: hoverEvent || onMouseLeave ? handleMouseLeave : void 0,
|
|
3452
|
+
onPointerDown: hoverEvent && tapReveal || onPointerDown ? handlePointerDown : void 0,
|
|
3389
3453
|
style: maxWidth ? { maxWidth, ...rest.style } : rest.style,
|
|
3390
3454
|
...rest
|
|
3391
3455
|
},
|
|
@@ -4142,6 +4206,11 @@ var init_TextHighlight = __esm({
|
|
|
4142
4206
|
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: false, annotationId });
|
|
4143
4207
|
onMouseLeave?.();
|
|
4144
4208
|
},
|
|
4209
|
+
onPointerDown: (e) => {
|
|
4210
|
+
if (e.pointerType === "mouse") return;
|
|
4211
|
+
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: true, annotationId });
|
|
4212
|
+
onMouseEnter?.();
|
|
4213
|
+
},
|
|
4145
4214
|
role: "button",
|
|
4146
4215
|
tabIndex: 0,
|
|
4147
4216
|
onKeyDown: (e) => {
|
|
@@ -4640,6 +4709,7 @@ var init_LawReferenceTooltip = __esm({
|
|
|
4640
4709
|
init_Typography();
|
|
4641
4710
|
init_Divider();
|
|
4642
4711
|
init_cn();
|
|
4712
|
+
init_useTapReveal();
|
|
4643
4713
|
positionStyles2 = {
|
|
4644
4714
|
top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
|
|
4645
4715
|
bottom: "top-full left-1/2 -translate-x-1/2 mt-2",
|
|
@@ -4661,6 +4731,7 @@ var init_LawReferenceTooltip = __esm({
|
|
|
4661
4731
|
const { t } = useTranslate();
|
|
4662
4732
|
const [isVisible, setIsVisible] = React79__default.useState(false);
|
|
4663
4733
|
const timeoutRef = React79__default.useRef(null);
|
|
4734
|
+
const triggerRef = React79__default.useRef(null);
|
|
4664
4735
|
const handleMouseEnter = () => {
|
|
4665
4736
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
4666
4737
|
timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
|
|
@@ -4669,6 +4740,8 @@ var init_LawReferenceTooltip = __esm({
|
|
|
4669
4740
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
4670
4741
|
setIsVisible(false);
|
|
4671
4742
|
};
|
|
4743
|
+
const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
|
|
4744
|
+
const open = isVisible || revealed;
|
|
4672
4745
|
React79__default.useEffect(() => {
|
|
4673
4746
|
return () => {
|
|
4674
4747
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
@@ -4677,6 +4750,7 @@ var init_LawReferenceTooltip = __esm({
|
|
|
4677
4750
|
return /* @__PURE__ */ jsxs(
|
|
4678
4751
|
Box,
|
|
4679
4752
|
{
|
|
4753
|
+
ref: triggerRef,
|
|
4680
4754
|
as: "span",
|
|
4681
4755
|
position: "relative",
|
|
4682
4756
|
display: "inline-block",
|
|
@@ -4685,9 +4759,10 @@ var init_LawReferenceTooltip = __esm({
|
|
|
4685
4759
|
onMouseLeave: handleMouseLeave,
|
|
4686
4760
|
onFocus: handleMouseEnter,
|
|
4687
4761
|
onBlur: handleMouseLeave,
|
|
4762
|
+
onPointerDown: triggerProps.onPointerDown,
|
|
4688
4763
|
children: [
|
|
4689
4764
|
children,
|
|
4690
|
-
|
|
4765
|
+
open && /* @__PURE__ */ jsxs(
|
|
4691
4766
|
Box,
|
|
4692
4767
|
{
|
|
4693
4768
|
padding: "sm",
|
|
@@ -9332,6 +9407,36 @@ function useCamera() {
|
|
|
9332
9407
|
cameraRef.current.zoom = Math.max(0.5, Math.min(3, cameraRef.current.zoom * zoomDelta));
|
|
9333
9408
|
drawFn?.();
|
|
9334
9409
|
}, []);
|
|
9410
|
+
const handlePointerDown = useCallback((e) => {
|
|
9411
|
+
handleMouseDown(e);
|
|
9412
|
+
}, [handleMouseDown]);
|
|
9413
|
+
const handlePointerUp = useCallback(() => {
|
|
9414
|
+
handleMouseUp();
|
|
9415
|
+
}, [handleMouseUp]);
|
|
9416
|
+
const handlePointerMove = useCallback((e, drawFn) => {
|
|
9417
|
+
return handleMouseMove(e, drawFn);
|
|
9418
|
+
}, [handleMouseMove]);
|
|
9419
|
+
const panBy = useCallback((dx, dy, drawFn) => {
|
|
9420
|
+
cameraRef.current.x -= dx;
|
|
9421
|
+
cameraRef.current.y -= dy;
|
|
9422
|
+
targetCameraRef.current = null;
|
|
9423
|
+
drawFn?.();
|
|
9424
|
+
}, []);
|
|
9425
|
+
const zoomAtPoint = useCallback((factor, centerX, centerY, viewportSize, drawFn) => {
|
|
9426
|
+
const cam = cameraRef.current;
|
|
9427
|
+
const oldZoom = cam.zoom;
|
|
9428
|
+
const newZoom = Math.max(0.5, Math.min(3, oldZoom * factor));
|
|
9429
|
+
if (newZoom === oldZoom) {
|
|
9430
|
+
drawFn?.();
|
|
9431
|
+
return;
|
|
9432
|
+
}
|
|
9433
|
+
const inv = 1 / oldZoom - 1 / newZoom;
|
|
9434
|
+
cam.x += (centerX - viewportSize.width / 2) * inv;
|
|
9435
|
+
cam.y += (centerY - viewportSize.height / 2) * inv;
|
|
9436
|
+
cam.zoom = newZoom;
|
|
9437
|
+
targetCameraRef.current = null;
|
|
9438
|
+
drawFn?.();
|
|
9439
|
+
}, []);
|
|
9335
9440
|
const screenToWorld = useCallback((clientX, clientY, canvas, viewportSize) => {
|
|
9336
9441
|
const rect = canvas.getBoundingClientRect();
|
|
9337
9442
|
const screenX = clientX - rect.left;
|
|
@@ -9363,6 +9468,11 @@ function useCamera() {
|
|
|
9363
9468
|
handleMouseMove,
|
|
9364
9469
|
handleMouseLeave,
|
|
9365
9470
|
handleWheel,
|
|
9471
|
+
handlePointerDown,
|
|
9472
|
+
handlePointerUp,
|
|
9473
|
+
handlePointerMove,
|
|
9474
|
+
panBy,
|
|
9475
|
+
zoomAtPoint,
|
|
9366
9476
|
screenToWorld,
|
|
9367
9477
|
lerpToTarget
|
|
9368
9478
|
};
|
|
@@ -9372,6 +9482,113 @@ var init_useCamera = __esm({
|
|
|
9372
9482
|
"use client";
|
|
9373
9483
|
}
|
|
9374
9484
|
});
|
|
9485
|
+
function localPoint(canvas, clientX, clientY) {
|
|
9486
|
+
if (!canvas) return { x: clientX, y: clientY };
|
|
9487
|
+
const rect = canvas.getBoundingClientRect();
|
|
9488
|
+
return { x: clientX - rect.left, y: clientY - rect.top };
|
|
9489
|
+
}
|
|
9490
|
+
function useCanvasGestures(options) {
|
|
9491
|
+
const {
|
|
9492
|
+
canvasRef,
|
|
9493
|
+
enabled = true,
|
|
9494
|
+
wheelStep = 1.1,
|
|
9495
|
+
onPointerDown,
|
|
9496
|
+
onPointerMove,
|
|
9497
|
+
onPointerUp,
|
|
9498
|
+
onZoom,
|
|
9499
|
+
onPanDelta,
|
|
9500
|
+
onMultiTouchStart
|
|
9501
|
+
} = options;
|
|
9502
|
+
const pointers = useRef(/* @__PURE__ */ new Map());
|
|
9503
|
+
const pinch = useRef(null);
|
|
9504
|
+
const computePinch = useCallback(() => {
|
|
9505
|
+
const pts = [...pointers.current.values()];
|
|
9506
|
+
const dx = pts[1].x - pts[0].x;
|
|
9507
|
+
const dy = pts[1].y - pts[0].y;
|
|
9508
|
+
return {
|
|
9509
|
+
distance: Math.hypot(dx, dy) || 1,
|
|
9510
|
+
centroid: { x: (pts[0].x + pts[1].x) / 2, y: (pts[0].y + pts[1].y) / 2 }
|
|
9511
|
+
};
|
|
9512
|
+
}, []);
|
|
9513
|
+
const handlePointerDown = useCallback(
|
|
9514
|
+
(e) => {
|
|
9515
|
+
if (!enabled) return;
|
|
9516
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
9517
|
+
pointers.current.set(e.pointerId, localPoint(canvasRef.current, e.clientX, e.clientY));
|
|
9518
|
+
if (pointers.current.size === 2) {
|
|
9519
|
+
onMultiTouchStart?.();
|
|
9520
|
+
pinch.current = computePinch();
|
|
9521
|
+
} else if (pointers.current.size === 1) {
|
|
9522
|
+
onPointerDown?.(e);
|
|
9523
|
+
}
|
|
9524
|
+
},
|
|
9525
|
+
[enabled, canvasRef, onMultiTouchStart, computePinch, onPointerDown]
|
|
9526
|
+
);
|
|
9527
|
+
const handlePointerMove = useCallback(
|
|
9528
|
+
(e) => {
|
|
9529
|
+
if (!enabled) return;
|
|
9530
|
+
if (pointers.current.has(e.pointerId)) {
|
|
9531
|
+
pointers.current.set(e.pointerId, localPoint(canvasRef.current, e.clientX, e.clientY));
|
|
9532
|
+
}
|
|
9533
|
+
if (pointers.current.size >= 2 && pinch.current) {
|
|
9534
|
+
const next = computePinch();
|
|
9535
|
+
const prev = pinch.current;
|
|
9536
|
+
if (next.distance !== prev.distance) {
|
|
9537
|
+
onZoom?.(next.distance / prev.distance, next.centroid.x, next.centroid.y);
|
|
9538
|
+
}
|
|
9539
|
+
onPanDelta?.(next.centroid.x - prev.centroid.x, next.centroid.y - prev.centroid.y);
|
|
9540
|
+
pinch.current = next;
|
|
9541
|
+
return;
|
|
9542
|
+
}
|
|
9543
|
+
onPointerMove?.(e);
|
|
9544
|
+
},
|
|
9545
|
+
[enabled, canvasRef, computePinch, onZoom, onPanDelta, onPointerMove]
|
|
9546
|
+
);
|
|
9547
|
+
const endPointer = useCallback(
|
|
9548
|
+
(e, fireUp) => {
|
|
9549
|
+
const wasMulti = pointers.current.size >= 2;
|
|
9550
|
+
pointers.current.delete(e.pointerId);
|
|
9551
|
+
if (pointers.current.size < 2) pinch.current = null;
|
|
9552
|
+
if (wasMulti && pointers.current.size === 1) return;
|
|
9553
|
+
if (pointers.current.size === 0 && fireUp) onPointerUp?.(e);
|
|
9554
|
+
},
|
|
9555
|
+
[onPointerUp]
|
|
9556
|
+
);
|
|
9557
|
+
const handlePointerUp = useCallback(
|
|
9558
|
+
(e) => {
|
|
9559
|
+
if (!enabled) return;
|
|
9560
|
+
endPointer(e, true);
|
|
9561
|
+
},
|
|
9562
|
+
[enabled, endPointer]
|
|
9563
|
+
);
|
|
9564
|
+
const handlePointerCancel = useCallback(
|
|
9565
|
+
(e) => {
|
|
9566
|
+
if (!enabled) return;
|
|
9567
|
+
endPointer(e, false);
|
|
9568
|
+
},
|
|
9569
|
+
[enabled, endPointer]
|
|
9570
|
+
);
|
|
9571
|
+
const handleWheel = useCallback(
|
|
9572
|
+
(e) => {
|
|
9573
|
+
if (!enabled) return;
|
|
9574
|
+
e.preventDefault();
|
|
9575
|
+
const { x, y } = localPoint(canvasRef.current, e.clientX, e.clientY);
|
|
9576
|
+
onZoom?.(e.deltaY < 0 ? wheelStep : 1 / wheelStep, x, y);
|
|
9577
|
+
},
|
|
9578
|
+
[enabled, canvasRef, wheelStep, onZoom]
|
|
9579
|
+
);
|
|
9580
|
+
return {
|
|
9581
|
+
onPointerDown: handlePointerDown,
|
|
9582
|
+
onPointerMove: handlePointerMove,
|
|
9583
|
+
onPointerUp: handlePointerUp,
|
|
9584
|
+
onPointerCancel: handlePointerCancel,
|
|
9585
|
+
onWheel: handleWheel
|
|
9586
|
+
};
|
|
9587
|
+
}
|
|
9588
|
+
var init_useCanvasGestures = __esm({
|
|
9589
|
+
"hooks/useCanvasGestures.ts"() {
|
|
9590
|
+
}
|
|
9591
|
+
});
|
|
9375
9592
|
|
|
9376
9593
|
// components/game/organisms/utils/spriteSheetConstants.ts
|
|
9377
9594
|
var SHEET_COLUMNS, SPRITE_SHEET_LAYOUT;
|
|
@@ -9877,13 +10094,13 @@ function IsometricCanvas({
|
|
|
9877
10094
|
const {
|
|
9878
10095
|
cameraRef,
|
|
9879
10096
|
targetCameraRef,
|
|
9880
|
-
isDragging,
|
|
9881
10097
|
dragDistance,
|
|
9882
|
-
handleMouseDown,
|
|
9883
|
-
handleMouseUp,
|
|
9884
|
-
handleMouseMove,
|
|
9885
10098
|
handleMouseLeave,
|
|
9886
|
-
|
|
10099
|
+
handlePointerDown,
|
|
10100
|
+
handlePointerUp,
|
|
10101
|
+
handlePointerMove,
|
|
10102
|
+
panBy,
|
|
10103
|
+
zoomAtPoint,
|
|
9887
10104
|
screenToWorld,
|
|
9888
10105
|
lerpToTarget
|
|
9889
10106
|
} = useCamera();
|
|
@@ -10318,11 +10535,16 @@ function IsometricCanvas({
|
|
|
10318
10535
|
cancelAnimationFrame(rafIdRef.current);
|
|
10319
10536
|
};
|
|
10320
10537
|
}, [draw, units.length, validMoves.length, attackTargets.length, selectedUnitId, hasActiveEffects2, pendingCount, atlasPending, lerpToTarget, targetCameraRef]);
|
|
10321
|
-
const
|
|
10322
|
-
|
|
10323
|
-
|
|
10324
|
-
|
|
10325
|
-
|
|
10538
|
+
const singlePointerActiveRef = useRef(false);
|
|
10539
|
+
const handleCanvasPointerDown = useCallback((e) => {
|
|
10540
|
+
singlePointerActiveRef.current = true;
|
|
10541
|
+
if (enableCamera) handlePointerDown(e);
|
|
10542
|
+
}, [enableCamera, handlePointerDown]);
|
|
10543
|
+
const handleCanvasPointerMove = useCallback((e) => {
|
|
10544
|
+
if (enableCamera) handlePointerMove(e, () => draw(animTimeRef.current));
|
|
10545
|
+
}, [enableCamera, handlePointerMove, draw]);
|
|
10546
|
+
const handleCanvasHover = useCallback((e) => {
|
|
10547
|
+
if (singlePointerActiveRef.current) return;
|
|
10326
10548
|
if (!onTileHover && !tileHoverEvent || !canvasRef.current) return;
|
|
10327
10549
|
const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
|
|
10328
10550
|
const adjustedX = world.x - scaledTileWidth / 2;
|
|
@@ -10333,26 +10555,10 @@ function IsometricCanvas({
|
|
|
10333
10555
|
if (tileHoverEvent) eventBus.emit(`UI:${tileHoverEvent}`, { x: isoPos.x, y: isoPos.y });
|
|
10334
10556
|
onTileHover?.(isoPos.x, isoPos.y);
|
|
10335
10557
|
}
|
|
10336
|
-
}, [
|
|
10337
|
-
const
|
|
10338
|
-
|
|
10339
|
-
if (
|
|
10340
|
-
onTileLeave?.();
|
|
10341
|
-
}, [handleMouseLeave, onTileLeave, tileLeaveEvent, eventBus]);
|
|
10342
|
-
const handleWheelWithCamera = useCallback((e) => {
|
|
10343
|
-
if (enableCamera) {
|
|
10344
|
-
handleWheel(e, () => draw(animTimeRef.current));
|
|
10345
|
-
}
|
|
10346
|
-
}, [enableCamera, handleWheel, draw]);
|
|
10347
|
-
useEffect(() => {
|
|
10348
|
-
const canvas = canvasRef.current;
|
|
10349
|
-
if (!canvas) return;
|
|
10350
|
-
canvas.addEventListener("wheel", handleWheelWithCamera, { passive: false });
|
|
10351
|
-
return () => {
|
|
10352
|
-
canvas.removeEventListener("wheel", handleWheelWithCamera);
|
|
10353
|
-
};
|
|
10354
|
-
}, [handleWheelWithCamera]);
|
|
10355
|
-
const handleClick = useCallback((e) => {
|
|
10558
|
+
}, [onTileHover, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, tilesProp, tileHoverEvent, eventBus]);
|
|
10559
|
+
const handleCanvasPointerUp = useCallback((e) => {
|
|
10560
|
+
singlePointerActiveRef.current = false;
|
|
10561
|
+
if (enableCamera) handlePointerUp();
|
|
10356
10562
|
if (dragDistance() > 5) return;
|
|
10357
10563
|
if (!canvasRef.current) return;
|
|
10358
10564
|
const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
|
|
@@ -10370,7 +10576,32 @@ function IsometricCanvas({
|
|
|
10370
10576
|
onTileClick?.(isoPos.x, isoPos.y);
|
|
10371
10577
|
}
|
|
10372
10578
|
}
|
|
10373
|
-
}, [dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, units, tilesProp, onUnitClick, onTileClick, unitClickEvent, tileClickEvent, eventBus]);
|
|
10579
|
+
}, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, units, tilesProp, onUnitClick, onTileClick, unitClickEvent, tileClickEvent, eventBus]);
|
|
10580
|
+
const handleCanvasPointerLeave = useCallback(() => {
|
|
10581
|
+
handleMouseLeave();
|
|
10582
|
+
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
10583
|
+
onTileLeave?.();
|
|
10584
|
+
}, [handleMouseLeave, onTileLeave, tileLeaveEvent, eventBus]);
|
|
10585
|
+
const applyZoom = useCallback((factor, centerX, centerY) => {
|
|
10586
|
+
if (enableCamera) zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw(animTimeRef.current));
|
|
10587
|
+
}, [enableCamera, zoomAtPoint, viewportSize, draw]);
|
|
10588
|
+
const applyPanDelta = useCallback((dx, dy) => {
|
|
10589
|
+
if (enableCamera) panBy(dx, dy, () => draw(animTimeRef.current));
|
|
10590
|
+
}, [enableCamera, panBy, draw]);
|
|
10591
|
+
const cancelSinglePointer = useCallback(() => {
|
|
10592
|
+
singlePointerActiveRef.current = false;
|
|
10593
|
+
if (enableCamera) handlePointerUp();
|
|
10594
|
+
}, [enableCamera, handlePointerUp]);
|
|
10595
|
+
const gestureHandlers = useCanvasGestures({
|
|
10596
|
+
canvasRef,
|
|
10597
|
+
enabled: enableCamera || !!onTileHover || !!tileHoverEvent || !!onTileClick || !!tileClickEvent || !!onUnitClick || !!unitClickEvent,
|
|
10598
|
+
onPointerDown: handleCanvasPointerDown,
|
|
10599
|
+
onPointerMove: handleCanvasPointerMove,
|
|
10600
|
+
onPointerUp: handleCanvasPointerUp,
|
|
10601
|
+
onZoom: applyZoom,
|
|
10602
|
+
onPanDelta: applyPanDelta,
|
|
10603
|
+
onMultiTouchStart: cancelSinglePointer
|
|
10604
|
+
});
|
|
10374
10605
|
if (error) {
|
|
10375
10606
|
return /* @__PURE__ */ jsx(ErrorState, { title: t("canvas.errorTitle"), message: error.message, className });
|
|
10376
10607
|
}
|
|
@@ -10402,13 +10633,17 @@ function IsometricCanvas({
|
|
|
10402
10633
|
{
|
|
10403
10634
|
ref: canvasRef,
|
|
10404
10635
|
"data-testid": "game-canvas",
|
|
10405
|
-
|
|
10406
|
-
|
|
10407
|
-
|
|
10408
|
-
|
|
10409
|
-
|
|
10636
|
+
onPointerDown: gestureHandlers.onPointerDown,
|
|
10637
|
+
onPointerMove: (e) => {
|
|
10638
|
+
gestureHandlers.onPointerMove(e);
|
|
10639
|
+
handleCanvasHover(e);
|
|
10640
|
+
},
|
|
10641
|
+
onPointerUp: gestureHandlers.onPointerUp,
|
|
10642
|
+
onPointerCancel: gestureHandlers.onPointerCancel,
|
|
10643
|
+
onPointerLeave: handleCanvasPointerLeave,
|
|
10644
|
+
onWheel: gestureHandlers.onWheel,
|
|
10410
10645
|
onContextMenu: (e) => e.preventDefault(),
|
|
10411
|
-
className: "cursor-pointer",
|
|
10646
|
+
className: "cursor-pointer touch-none",
|
|
10412
10647
|
style: {
|
|
10413
10648
|
width: viewportSize.width,
|
|
10414
10649
|
height: viewportSize.height
|
|
@@ -10462,6 +10697,7 @@ var init_IsometricCanvas = __esm({
|
|
|
10462
10697
|
init_ErrorState();
|
|
10463
10698
|
init_useImageCache();
|
|
10464
10699
|
init_useCamera();
|
|
10700
|
+
init_useCanvasGestures();
|
|
10465
10701
|
init_useUnitSpriteAtlas();
|
|
10466
10702
|
init_verificationRegistry();
|
|
10467
10703
|
init_isometric();
|
|
@@ -13577,6 +13813,10 @@ var init_StateMachineView = __esm({
|
|
|
13577
13813
|
const handleMouseLeave2 = () => {
|
|
13578
13814
|
onHover(null, 0, 0);
|
|
13579
13815
|
};
|
|
13816
|
+
const handlePointerDown2 = (e) => {
|
|
13817
|
+
if (e.pointerType === "mouse") return;
|
|
13818
|
+
handleMouseEnter2();
|
|
13819
|
+
};
|
|
13580
13820
|
return /* @__PURE__ */ jsxs(
|
|
13581
13821
|
"g",
|
|
13582
13822
|
{
|
|
@@ -13586,6 +13826,7 @@ var init_StateMachineView = __esm({
|
|
|
13586
13826
|
onClick: () => onClick?.(bundle),
|
|
13587
13827
|
onMouseEnter: handleMouseEnter2,
|
|
13588
13828
|
onMouseLeave: handleMouseLeave2,
|
|
13829
|
+
onPointerDown: handlePointerDown2,
|
|
13589
13830
|
style: { pointerEvents: "auto" },
|
|
13590
13831
|
children: [
|
|
13591
13832
|
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
@@ -13703,6 +13944,10 @@ var init_StateMachineView = __esm({
|
|
|
13703
13944
|
const handleMouseLeave = useCallback(() => {
|
|
13704
13945
|
onHover(null, 0, 0);
|
|
13705
13946
|
}, [onHover]);
|
|
13947
|
+
const handlePointerDown = useCallback((e) => {
|
|
13948
|
+
if (e.pointerType === "mouse") return;
|
|
13949
|
+
handleMouseEnter();
|
|
13950
|
+
}, [handleMouseEnter]);
|
|
13706
13951
|
const uniqueMarkerId = `arrow-${bundle.id}`;
|
|
13707
13952
|
const hasDetails = bundle.labels.some((l) => l.hasDetails);
|
|
13708
13953
|
return /* @__PURE__ */ jsxs(
|
|
@@ -13714,6 +13959,7 @@ var init_StateMachineView = __esm({
|
|
|
13714
13959
|
onClick: () => onClick?.(bundle),
|
|
13715
13960
|
onMouseEnter: handleMouseEnter,
|
|
13716
13961
|
onMouseLeave: handleMouseLeave,
|
|
13962
|
+
onPointerDown: handlePointerDown,
|
|
13717
13963
|
style: { pointerEvents: "auto" },
|
|
13718
13964
|
children: [
|
|
13719
13965
|
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
@@ -22486,10 +22732,84 @@ function SubMenu({
|
|
|
22486
22732
|
);
|
|
22487
22733
|
return typeof document !== "undefined" ? createPortal(panel, document.body) : panel;
|
|
22488
22734
|
}
|
|
22735
|
+
function MenuItemRow({
|
|
22736
|
+
item,
|
|
22737
|
+
itemId,
|
|
22738
|
+
hasSubMenu,
|
|
22739
|
+
isDanger,
|
|
22740
|
+
direction,
|
|
22741
|
+
isSubMenuOpen,
|
|
22742
|
+
activeSubMenuRef,
|
|
22743
|
+
eventBus,
|
|
22744
|
+
onItemClick,
|
|
22745
|
+
openSubMenu
|
|
22746
|
+
}) {
|
|
22747
|
+
const rowRef = useRef(null);
|
|
22748
|
+
const { triggerProps } = useTapReveal({
|
|
22749
|
+
enabled: hasSubMenu,
|
|
22750
|
+
onReveal: () => openSubMenu(itemId, rowRef.current),
|
|
22751
|
+
refs: [rowRef]
|
|
22752
|
+
});
|
|
22753
|
+
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
22754
|
+
/* @__PURE__ */ jsx(
|
|
22755
|
+
Box,
|
|
22756
|
+
{
|
|
22757
|
+
ref: rowRef,
|
|
22758
|
+
as: "button",
|
|
22759
|
+
onClick: () => onItemClick({ ...item, id: itemId }, itemId),
|
|
22760
|
+
"aria-disabled": item.disabled || void 0,
|
|
22761
|
+
onMouseEnter: (e) => {
|
|
22762
|
+
if (hasSubMenu) openSubMenu(itemId, e.currentTarget);
|
|
22763
|
+
},
|
|
22764
|
+
onPointerDown: hasSubMenu ? triggerProps.onPointerDown : void 0,
|
|
22765
|
+
"data-testid": item.event ? `action-${item.event}` : void 0,
|
|
22766
|
+
className: cn(
|
|
22767
|
+
"w-full flex items-center justify-between gap-3 px-4 py-2 text-start",
|
|
22768
|
+
"text-sm transition-colors",
|
|
22769
|
+
"hover:bg-muted",
|
|
22770
|
+
"focus:outline-none focus:bg-muted",
|
|
22771
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
22772
|
+
item.disabled && "cursor-not-allowed",
|
|
22773
|
+
isDanger && "text-error hover:bg-error/10"
|
|
22774
|
+
),
|
|
22775
|
+
children: /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
22776
|
+
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" })),
|
|
22777
|
+
/* @__PURE__ */ jsx(
|
|
22778
|
+
Typography,
|
|
22779
|
+
{
|
|
22780
|
+
variant: "small",
|
|
22781
|
+
className: cn("flex-1", isDanger && "text-red-600"),
|
|
22782
|
+
children: item.label
|
|
22783
|
+
}
|
|
22784
|
+
),
|
|
22785
|
+
item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: item.badge }),
|
|
22786
|
+
hasSubMenu && /* @__PURE__ */ jsx(
|
|
22787
|
+
Icon,
|
|
22788
|
+
{
|
|
22789
|
+
name: direction === "rtl" ? "chevron-left" : "chevron-right",
|
|
22790
|
+
size: "sm",
|
|
22791
|
+
className: "flex-shrink-0"
|
|
22792
|
+
}
|
|
22793
|
+
)
|
|
22794
|
+
] })
|
|
22795
|
+
}
|
|
22796
|
+
),
|
|
22797
|
+
hasSubMenu && isSubMenuOpen && item.subMenu && /* @__PURE__ */ jsx(
|
|
22798
|
+
SubMenu,
|
|
22799
|
+
{
|
|
22800
|
+
items: item.subMenu,
|
|
22801
|
+
itemRef: activeSubMenuRef,
|
|
22802
|
+
direction,
|
|
22803
|
+
eventBus
|
|
22804
|
+
}
|
|
22805
|
+
)
|
|
22806
|
+
] });
|
|
22807
|
+
}
|
|
22489
22808
|
var MENU_GAP, menuContainerStyles, Menu;
|
|
22490
22809
|
var init_Menu = __esm({
|
|
22491
22810
|
"components/core/molecules/Menu.tsx"() {
|
|
22492
22811
|
"use client";
|
|
22812
|
+
init_useTapReveal();
|
|
22493
22813
|
init_Box();
|
|
22494
22814
|
init_Icon();
|
|
22495
22815
|
init_Divider();
|
|
@@ -22544,6 +22864,10 @@ var init_Menu = __esm({
|
|
|
22544
22864
|
setIsOpen(false);
|
|
22545
22865
|
}
|
|
22546
22866
|
};
|
|
22867
|
+
const openSubMenu = (itemId, el) => {
|
|
22868
|
+
setActiveSubMenu(itemId);
|
|
22869
|
+
setActiveSubMenuRef(el);
|
|
22870
|
+
};
|
|
22547
22871
|
useEffect(() => {
|
|
22548
22872
|
if (isOpen) {
|
|
22549
22873
|
updatePosition();
|
|
@@ -22587,61 +22911,22 @@ var init_Menu = __esm({
|
|
|
22587
22911
|
if (isDivider) {
|
|
22588
22912
|
return /* @__PURE__ */ jsx(Divider, { className: "my-1" }, `divider-${index}`);
|
|
22589
22913
|
}
|
|
22590
|
-
return /* @__PURE__ */
|
|
22591
|
-
|
|
22592
|
-
|
|
22593
|
-
|
|
22594
|
-
|
|
22595
|
-
|
|
22596
|
-
|
|
22597
|
-
|
|
22598
|
-
|
|
22599
|
-
|
|
22600
|
-
|
|
22601
|
-
|
|
22602
|
-
|
|
22603
|
-
|
|
22604
|
-
|
|
22605
|
-
|
|
22606
|
-
"text-sm transition-colors",
|
|
22607
|
-
"hover:bg-muted",
|
|
22608
|
-
"focus:outline-none focus:bg-muted",
|
|
22609
|
-
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
22610
|
-
item.disabled && "cursor-not-allowed",
|
|
22611
|
-
isDanger && "text-error hover:bg-error/10"
|
|
22612
|
-
),
|
|
22613
|
-
children: /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
22614
|
-
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" })),
|
|
22615
|
-
/* @__PURE__ */ jsx(
|
|
22616
|
-
Typography,
|
|
22617
|
-
{
|
|
22618
|
-
variant: "small",
|
|
22619
|
-
className: cn("flex-1", isDanger && "text-red-600"),
|
|
22620
|
-
children: item.label
|
|
22621
|
-
}
|
|
22622
|
-
),
|
|
22623
|
-
item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: item.badge }),
|
|
22624
|
-
hasSubMenu && /* @__PURE__ */ jsx(
|
|
22625
|
-
Icon,
|
|
22626
|
-
{
|
|
22627
|
-
name: direction === "rtl" ? "chevron-left" : "chevron-right",
|
|
22628
|
-
size: "sm",
|
|
22629
|
-
className: "flex-shrink-0"
|
|
22630
|
-
}
|
|
22631
|
-
)
|
|
22632
|
-
] })
|
|
22633
|
-
}
|
|
22634
|
-
),
|
|
22635
|
-
hasSubMenu && activeSubMenu === itemId && item.subMenu && /* @__PURE__ */ jsx(
|
|
22636
|
-
SubMenu,
|
|
22637
|
-
{
|
|
22638
|
-
items: item.subMenu,
|
|
22639
|
-
itemRef: activeSubMenuRef,
|
|
22640
|
-
direction,
|
|
22641
|
-
eventBus
|
|
22642
|
-
}
|
|
22643
|
-
)
|
|
22644
|
-
] }, itemId);
|
|
22914
|
+
return /* @__PURE__ */ jsx(
|
|
22915
|
+
MenuItemRow,
|
|
22916
|
+
{
|
|
22917
|
+
item,
|
|
22918
|
+
itemId,
|
|
22919
|
+
hasSubMenu,
|
|
22920
|
+
isDanger,
|
|
22921
|
+
direction,
|
|
22922
|
+
isSubMenuOpen: activeSubMenu === itemId,
|
|
22923
|
+
activeSubMenuRef,
|
|
22924
|
+
eventBus,
|
|
22925
|
+
onItemClick: handleItemClick,
|
|
22926
|
+
openSubMenu
|
|
22927
|
+
},
|
|
22928
|
+
itemId
|
|
22929
|
+
);
|
|
22645
22930
|
});
|
|
22646
22931
|
const panel = isOpen && triggerRect ? /* @__PURE__ */ jsxs(
|
|
22647
22932
|
"div",
|
|
@@ -25886,6 +26171,7 @@ var init_Popover = __esm({
|
|
|
25886
26171
|
"use client";
|
|
25887
26172
|
init_Typography();
|
|
25888
26173
|
init_cn();
|
|
26174
|
+
init_useTapReveal();
|
|
25889
26175
|
arrowClasses = {
|
|
25890
26176
|
top: "top-full left-1/2 -translate-x-1/2 border-t-white border-l-transparent border-r-transparent border-b-transparent",
|
|
25891
26177
|
bottom: "bottom-full left-1/2 -translate-x-1/2 border-b-white border-l-transparent border-r-transparent border-t-transparent",
|
|
@@ -25956,18 +26242,32 @@ var init_Popover = __esm({
|
|
|
25956
26242
|
document.addEventListener("mousedown", handleClickOutside);
|
|
25957
26243
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
25958
26244
|
}, [isOpen, trigger]);
|
|
25959
|
-
const triggerProps
|
|
26245
|
+
const { triggerProps: tapTriggerProps } = useTapReveal({
|
|
26246
|
+
enabled: trigger === "hover",
|
|
26247
|
+
onReveal: handleOpen,
|
|
26248
|
+
onDismiss: handleClose,
|
|
26249
|
+
refs: [triggerRef, popoverRef]
|
|
26250
|
+
});
|
|
26251
|
+
const handlerProps = trigger === "click" ? {
|
|
25960
26252
|
onClick: handleToggle
|
|
25961
26253
|
} : {
|
|
25962
26254
|
onMouseEnter: handleOpen,
|
|
25963
|
-
onMouseLeave: handleClose
|
|
26255
|
+
onMouseLeave: handleClose,
|
|
26256
|
+
onPointerDown: tapTriggerProps.onPointerDown
|
|
25964
26257
|
};
|
|
25965
26258
|
const childElement = React79__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
26259
|
+
const childPointerDown = childElement.props.onPointerDown;
|
|
25966
26260
|
const triggerElement = React79__default.cloneElement(
|
|
25967
26261
|
childElement,
|
|
25968
26262
|
{
|
|
25969
26263
|
ref: triggerRef,
|
|
25970
|
-
...
|
|
26264
|
+
...handlerProps,
|
|
26265
|
+
...trigger === "hover" ? {
|
|
26266
|
+
onPointerDown: (e) => {
|
|
26267
|
+
tapTriggerProps.onPointerDown(e);
|
|
26268
|
+
childPointerDown?.(e);
|
|
26269
|
+
}
|
|
26270
|
+
} : void 0
|
|
25971
26271
|
}
|
|
25972
26272
|
);
|
|
25973
26273
|
const panel = isOpen && triggerRect ? /* @__PURE__ */ jsxs(
|
|
@@ -26748,6 +27048,7 @@ var init_Tooltip = __esm({
|
|
|
26748
27048
|
"use client";
|
|
26749
27049
|
init_Typography();
|
|
26750
27050
|
init_cn();
|
|
27051
|
+
init_useTapReveal();
|
|
26751
27052
|
TRIGGER_GAP2 = 8;
|
|
26752
27053
|
arrowClasses2 = {
|
|
26753
27054
|
top: "top-full left-1/2 -translate-x-1/2 border-t-primary border-l-transparent border-r-transparent border-b-transparent",
|
|
@@ -26792,6 +27093,11 @@ var init_Tooltip = __esm({
|
|
|
26792
27093
|
setIsVisible(false);
|
|
26793
27094
|
}, hideDelay);
|
|
26794
27095
|
};
|
|
27096
|
+
const { triggerProps } = useTapReveal({
|
|
27097
|
+
onReveal: handleMouseEnter,
|
|
27098
|
+
onDismiss: handleMouseLeave,
|
|
27099
|
+
refs: [triggerRef, tooltipRef]
|
|
27100
|
+
});
|
|
26795
27101
|
useLayoutEffect(() => {
|
|
26796
27102
|
if (isVisible) {
|
|
26797
27103
|
updatePosition();
|
|
@@ -26804,12 +27110,17 @@ var init_Tooltip = __esm({
|
|
|
26804
27110
|
};
|
|
26805
27111
|
}, []);
|
|
26806
27112
|
const triggerElement = React79__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
27113
|
+
const childPointerDown = triggerElement.props.onPointerDown;
|
|
26807
27114
|
const trigger = React79__default.cloneElement(triggerElement, {
|
|
26808
27115
|
ref: triggerRef,
|
|
26809
27116
|
onMouseEnter: handleMouseEnter,
|
|
26810
27117
|
onMouseLeave: handleMouseLeave,
|
|
26811
27118
|
onFocus: handleMouseEnter,
|
|
26812
|
-
onBlur: handleMouseLeave
|
|
27119
|
+
onBlur: handleMouseLeave,
|
|
27120
|
+
onPointerDown: (e) => {
|
|
27121
|
+
triggerProps.onPointerDown(e);
|
|
27122
|
+
childPointerDown?.(e);
|
|
27123
|
+
}
|
|
26813
27124
|
});
|
|
26814
27125
|
const tooltipContent = isVisible && triggerRect ? /* @__PURE__ */ jsxs(
|
|
26815
27126
|
"div",
|
|
@@ -30482,6 +30793,14 @@ var init_GraphView = __esm({
|
|
|
30482
30793
|
},
|
|
30483
30794
|
[onNodeClick]
|
|
30484
30795
|
);
|
|
30796
|
+
const handleNodePointerDown = useCallback(
|
|
30797
|
+
(e, node) => {
|
|
30798
|
+
if (e.pointerType === "mouse") return;
|
|
30799
|
+
handleNodeMouseEnter(node);
|
|
30800
|
+
handleNodeClickInternal(node);
|
|
30801
|
+
},
|
|
30802
|
+
[handleNodeMouseEnter, handleNodeClickInternal]
|
|
30803
|
+
);
|
|
30485
30804
|
if (nodes.length === 0) {
|
|
30486
30805
|
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") }) });
|
|
30487
30806
|
}
|
|
@@ -30541,6 +30860,7 @@ var init_GraphView = __esm({
|
|
|
30541
30860
|
onMouseEnter: () => handleNodeMouseEnter(node),
|
|
30542
30861
|
onMouseLeave: handleNodeMouseLeave,
|
|
30543
30862
|
onClick: () => handleNodeClickInternal(node),
|
|
30863
|
+
onPointerDown: (e) => handleNodePointerDown(e, node),
|
|
30544
30864
|
children: [
|
|
30545
30865
|
/* @__PURE__ */ jsx(
|
|
30546
30866
|
"circle",
|
|
@@ -30621,13 +30941,13 @@ var init_MapView = __esm({
|
|
|
30621
30941
|
shadowSize: [41, 41]
|
|
30622
30942
|
});
|
|
30623
30943
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
30624
|
-
const { useEffect:
|
|
30944
|
+
const { useEffect: useEffect83, useRef: useRef83, useCallback: useCallback127, useState: useState112 } = React79__default;
|
|
30625
30945
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
30626
30946
|
const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
30627
30947
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
30628
30948
|
const map = useMap();
|
|
30629
|
-
const prevRef =
|
|
30630
|
-
|
|
30949
|
+
const prevRef = useRef83({ centerLat, centerLng, zoom });
|
|
30950
|
+
useEffect83(() => {
|
|
30631
30951
|
const prev = prevRef.current;
|
|
30632
30952
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
30633
30953
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -30638,7 +30958,7 @@ var init_MapView = __esm({
|
|
|
30638
30958
|
}
|
|
30639
30959
|
function MapClickHandler({ onMapClick }) {
|
|
30640
30960
|
const map = useMap();
|
|
30641
|
-
|
|
30961
|
+
useEffect83(() => {
|
|
30642
30962
|
if (!onMapClick) return;
|
|
30643
30963
|
const handler = (e) => {
|
|
30644
30964
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -30666,8 +30986,8 @@ var init_MapView = __esm({
|
|
|
30666
30986
|
showAttribution = true
|
|
30667
30987
|
}) {
|
|
30668
30988
|
const eventBus = useEventBus3();
|
|
30669
|
-
const [clickedPosition, setClickedPosition] =
|
|
30670
|
-
const handleMapClick =
|
|
30989
|
+
const [clickedPosition, setClickedPosition] = useState112(null);
|
|
30990
|
+
const handleMapClick = useCallback127((lat, lng) => {
|
|
30671
30991
|
if (showClickedPin) {
|
|
30672
30992
|
setClickedPosition({ lat, lng });
|
|
30673
30993
|
}
|
|
@@ -30676,7 +30996,7 @@ var init_MapView = __esm({
|
|
|
30676
30996
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
30677
30997
|
}
|
|
30678
30998
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
30679
|
-
const handleMarkerClick =
|
|
30999
|
+
const handleMarkerClick = useCallback127((marker) => {
|
|
30680
31000
|
onMarkerClick?.(marker);
|
|
30681
31001
|
if (markerClickEvent) {
|
|
30682
31002
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -31017,7 +31337,7 @@ var init_StarRating = __esm({
|
|
|
31017
31337
|
"aria-valuenow": value,
|
|
31018
31338
|
tabIndex: readOnly ? void 0 : 0,
|
|
31019
31339
|
onKeyDown: handleKeyDown,
|
|
31020
|
-
|
|
31340
|
+
onPointerLeave: () => setHoverValue(null),
|
|
31021
31341
|
children: Array.from({ length: max }, (_, i) => {
|
|
31022
31342
|
const fillLevel = Math.max(0, Math.min(1, displayValue - i));
|
|
31023
31343
|
const isFull = fillLevel >= 1;
|
|
@@ -31027,7 +31347,7 @@ var init_StarRating = __esm({
|
|
|
31027
31347
|
{
|
|
31028
31348
|
className: "relative inline-block",
|
|
31029
31349
|
onClick: () => handleStarClick(i, false),
|
|
31030
|
-
|
|
31350
|
+
onPointerMove: (e) => {
|
|
31031
31351
|
if (readOnly) return;
|
|
31032
31352
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
31033
31353
|
const isLeftHalf = e.clientX - rect.left < rect.width / 2;
|
|
@@ -34917,7 +35237,7 @@ var init_PositionedCanvas = __esm({
|
|
|
34917
35237
|
{
|
|
34918
35238
|
ref: containerRef,
|
|
34919
35239
|
"data-testid": "positioned-canvas",
|
|
34920
|
-
className: "relative bg-background border border-border rounded-container overflow-hidden",
|
|
35240
|
+
className: "relative bg-background border border-border rounded-container overflow-hidden touch-none",
|
|
34921
35241
|
style: { width, height },
|
|
34922
35242
|
onClick: handleContainerClick,
|
|
34923
35243
|
children: items.map((item) => {
|
|
@@ -39064,6 +39384,13 @@ var init_DocumentViewer = __esm({
|
|
|
39064
39384
|
DocumentViewer.displayName = "DocumentViewer";
|
|
39065
39385
|
}
|
|
39066
39386
|
});
|
|
39387
|
+
function measureLabelWidth(text) {
|
|
39388
|
+
if (typeof document === "undefined") return text.length * 6;
|
|
39389
|
+
if (!labelMeasureCtx) labelMeasureCtx = document.createElement("canvas").getContext("2d");
|
|
39390
|
+
if (!labelMeasureCtx) return text.length * 6;
|
|
39391
|
+
labelMeasureCtx.font = "10px system-ui";
|
|
39392
|
+
return labelMeasureCtx.measureText(text).width;
|
|
39393
|
+
}
|
|
39067
39394
|
function getGroupColor(group, groups) {
|
|
39068
39395
|
if (!group) return GROUP_COLORS2[0];
|
|
39069
39396
|
const idx = groups.indexOf(group);
|
|
@@ -39075,7 +39402,7 @@ function resolveColor2(color, el) {
|
|
|
39075
39402
|
const resolved = getComputedStyle(el).getPropertyValue(m[1]).trim();
|
|
39076
39403
|
return resolved || (m[2]?.trim() ?? "#888888");
|
|
39077
39404
|
}
|
|
39078
|
-
var GROUP_COLORS2, GraphCanvas;
|
|
39405
|
+
var GROUP_COLORS2, labelMeasureCtx, GraphCanvas;
|
|
39079
39406
|
var init_GraphCanvas = __esm({
|
|
39080
39407
|
"components/core/molecules/GraphCanvas.tsx"() {
|
|
39081
39408
|
"use client";
|
|
@@ -39086,6 +39413,7 @@ var init_GraphCanvas = __esm({
|
|
|
39086
39413
|
init_ErrorState();
|
|
39087
39414
|
init_EmptyState();
|
|
39088
39415
|
init_useEventBus();
|
|
39416
|
+
init_useCanvasGestures();
|
|
39089
39417
|
GROUP_COLORS2 = [
|
|
39090
39418
|
"var(--color-primary)",
|
|
39091
39419
|
"var(--color-success)",
|
|
@@ -39094,6 +39422,7 @@ var init_GraphCanvas = __esm({
|
|
|
39094
39422
|
"var(--color-info)",
|
|
39095
39423
|
"var(--color-accent)"
|
|
39096
39424
|
];
|
|
39425
|
+
labelMeasureCtx = null;
|
|
39097
39426
|
GraphCanvas = ({
|
|
39098
39427
|
title,
|
|
39099
39428
|
nodes: propNodes = [],
|
|
@@ -39123,6 +39452,10 @@ var init_GraphCanvas = __esm({
|
|
|
39123
39452
|
const animRef = useRef(0);
|
|
39124
39453
|
const [zoom, setZoom] = useState(1);
|
|
39125
39454
|
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
|
39455
|
+
const zoomRef = useRef(zoom);
|
|
39456
|
+
zoomRef.current = zoom;
|
|
39457
|
+
const offsetRef = useRef(offset);
|
|
39458
|
+
offsetRef.current = offset;
|
|
39126
39459
|
const [hoveredNode, setHoveredNode] = useState(null);
|
|
39127
39460
|
const nodesRef = useRef([]);
|
|
39128
39461
|
const [, forceUpdate] = useState(0);
|
|
@@ -39270,22 +39603,36 @@ var init_GraphCanvas = __esm({
|
|
|
39270
39603
|
node.x = Math.max(30, Math.min(w - 30, node.x));
|
|
39271
39604
|
node.y = Math.max(30, Math.min(h - 30, node.y));
|
|
39272
39605
|
}
|
|
39606
|
+
const LABEL_GAP = 12;
|
|
39607
|
+
const LABEL_H = 12;
|
|
39608
|
+
const pad = nodeSpacing / 2;
|
|
39273
39609
|
for (let i = 0; i < nodes.length; i++) {
|
|
39274
39610
|
for (let j = i + 1; j < nodes.length; j++) {
|
|
39275
39611
|
const a = nodes[i];
|
|
39276
39612
|
const b = nodes[j];
|
|
39277
|
-
const
|
|
39278
|
-
const
|
|
39279
|
-
|
|
39280
|
-
|
|
39281
|
-
|
|
39282
|
-
|
|
39283
|
-
|
|
39284
|
-
|
|
39285
|
-
|
|
39286
|
-
|
|
39287
|
-
|
|
39288
|
-
|
|
39613
|
+
const ar = a.size || 8;
|
|
39614
|
+
const br = b.size || 8;
|
|
39615
|
+
if (showLabels) {
|
|
39616
|
+
if (a.labelW === void 0) a.labelW = a.label ? measureLabelWidth(a.label) : 0;
|
|
39617
|
+
if (b.labelW === void 0) b.labelW = b.label ? measureLabelWidth(b.label) : 0;
|
|
39618
|
+
}
|
|
39619
|
+
const labelBelow = showLabels ? LABEL_GAP + LABEL_H : 0;
|
|
39620
|
+
const aHalfW = Math.max(ar, (a.labelW ?? 0) / 2) + pad;
|
|
39621
|
+
const bHalfW = Math.max(br, (b.labelW ?? 0) / 2) + pad;
|
|
39622
|
+
const aTop = a.y - ar - pad, aBot = a.y + ar + labelBelow + pad;
|
|
39623
|
+
const bTop = b.y - br - pad, bBot = b.y + br + labelBelow + pad;
|
|
39624
|
+
const overlapX = Math.min(a.x + aHalfW, b.x + bHalfW) - Math.max(a.x - aHalfW, b.x - bHalfW);
|
|
39625
|
+
const overlapY = Math.min(aBot, bBot) - Math.max(aTop, bTop);
|
|
39626
|
+
if (overlapX > 0 && overlapY > 0) {
|
|
39627
|
+
if (overlapX <= overlapY) {
|
|
39628
|
+
const push = overlapX / 2 * (b.x >= a.x ? 1 : -1);
|
|
39629
|
+
a.x = Math.max(30, Math.min(w - 30, a.x - push));
|
|
39630
|
+
b.x = Math.max(30, Math.min(w - 30, b.x + push));
|
|
39631
|
+
} else {
|
|
39632
|
+
const push = overlapY / 2 * (bTop + bBot >= aTop + aBot ? 1 : -1);
|
|
39633
|
+
a.y = Math.max(30, Math.min(h - 30, a.y - push));
|
|
39634
|
+
b.y = Math.max(30, Math.min(h - 30, b.y + push));
|
|
39635
|
+
}
|
|
39289
39636
|
}
|
|
39290
39637
|
}
|
|
39291
39638
|
}
|
|
@@ -39302,7 +39649,7 @@ var init_GraphCanvas = __esm({
|
|
|
39302
39649
|
return () => {
|
|
39303
39650
|
cancelAnimationFrame(animRef.current);
|
|
39304
39651
|
};
|
|
39305
|
-
}, [propNodes, propEdges, layout, repulsion, linkDistance, nodeSpacing, logicalW, height]);
|
|
39652
|
+
}, [propNodes, propEdges, layout, repulsion, linkDistance, nodeSpacing, showLabels, logicalW, height]);
|
|
39306
39653
|
useEffect(() => {
|
|
39307
39654
|
const canvas = canvasRef.current;
|
|
39308
39655
|
if (!canvas) return;
|
|
@@ -39382,25 +39729,27 @@ var init_GraphCanvas = __esm({
|
|
|
39382
39729
|
setZoom(1);
|
|
39383
39730
|
setOffset({ x: 0, y: 0 });
|
|
39384
39731
|
}, []);
|
|
39385
|
-
const
|
|
39386
|
-
(
|
|
39387
|
-
|
|
39388
|
-
|
|
39389
|
-
|
|
39390
|
-
|
|
39391
|
-
|
|
39392
|
-
|
|
39393
|
-
|
|
39394
|
-
|
|
39395
|
-
|
|
39396
|
-
|
|
39397
|
-
|
|
39398
|
-
|
|
39399
|
-
|
|
39400
|
-
|
|
39401
|
-
|
|
39402
|
-
|
|
39403
|
-
|
|
39732
|
+
const applyZoom = useCallback((factor, cx, cy) => {
|
|
39733
|
+
if (!interactive) return;
|
|
39734
|
+
const oldZoom = zoomRef.current;
|
|
39735
|
+
const newZoom = Math.max(0.3, Math.min(3, oldZoom * factor));
|
|
39736
|
+
if (newZoom === oldZoom) return;
|
|
39737
|
+
const o = offsetRef.current;
|
|
39738
|
+
setOffset({
|
|
39739
|
+
x: cx - (cx - o.x) * (newZoom / oldZoom),
|
|
39740
|
+
y: cy - (cy - o.y) * (newZoom / oldZoom)
|
|
39741
|
+
});
|
|
39742
|
+
setZoom(newZoom);
|
|
39743
|
+
}, [interactive]);
|
|
39744
|
+
const applyPanDelta = useCallback((dx, dy) => {
|
|
39745
|
+
if (!interactive) return;
|
|
39746
|
+
setOffset((o) => ({ x: o.x + dx, y: o.y + dy }));
|
|
39747
|
+
}, [interactive]);
|
|
39748
|
+
const cancelSinglePointer = useCallback(() => {
|
|
39749
|
+
interactionRef.current.mode = "none";
|
|
39750
|
+
interactionRef.current.dragNodeId = null;
|
|
39751
|
+
}, []);
|
|
39752
|
+
const handlePointerDown = useCallback(
|
|
39404
39753
|
(e) => {
|
|
39405
39754
|
const coords = toCoords(e);
|
|
39406
39755
|
if (!coords) return;
|
|
@@ -39422,7 +39771,7 @@ var init_GraphCanvas = __esm({
|
|
|
39422
39771
|
},
|
|
39423
39772
|
[toCoords, nodeAt, draggable, interactive, offset]
|
|
39424
39773
|
);
|
|
39425
|
-
const
|
|
39774
|
+
const handlePointerMove = useCallback(
|
|
39426
39775
|
(e) => {
|
|
39427
39776
|
const state = interactionRef.current;
|
|
39428
39777
|
if (state.mode === "panning") {
|
|
@@ -39451,7 +39800,7 @@ var init_GraphCanvas = __esm({
|
|
|
39451
39800
|
},
|
|
39452
39801
|
[toCoords, nodeAt]
|
|
39453
39802
|
);
|
|
39454
|
-
const
|
|
39803
|
+
const handlePointerUp = useCallback(
|
|
39455
39804
|
(e) => {
|
|
39456
39805
|
const state = interactionRef.current;
|
|
39457
39806
|
const moved = Math.abs(e.clientX - state.downPos.x) + Math.abs(e.clientY - state.downPos.y);
|
|
@@ -39468,11 +39817,19 @@ var init_GraphCanvas = __esm({
|
|
|
39468
39817
|
},
|
|
39469
39818
|
[toCoords, nodeAt, handleNodeClick]
|
|
39470
39819
|
);
|
|
39471
|
-
const
|
|
39472
|
-
interactionRef.current.mode = "none";
|
|
39473
|
-
interactionRef.current.dragNodeId = null;
|
|
39820
|
+
const handlePointerLeave = useCallback(() => {
|
|
39474
39821
|
setHoveredNode(null);
|
|
39475
39822
|
}, []);
|
|
39823
|
+
const gestureHandlers = useCanvasGestures({
|
|
39824
|
+
canvasRef,
|
|
39825
|
+
enabled: interactive || draggable,
|
|
39826
|
+
onPointerDown: handlePointerDown,
|
|
39827
|
+
onPointerMove: handlePointerMove,
|
|
39828
|
+
onPointerUp: handlePointerUp,
|
|
39829
|
+
onZoom: applyZoom,
|
|
39830
|
+
onPanDelta: applyPanDelta,
|
|
39831
|
+
onMultiTouchStart: cancelSinglePointer
|
|
39832
|
+
});
|
|
39476
39833
|
const handleDoubleClick = useCallback(
|
|
39477
39834
|
(e) => {
|
|
39478
39835
|
const coords = toCoords(e);
|
|
@@ -39541,13 +39898,14 @@ var init_GraphCanvas = __esm({
|
|
|
39541
39898
|
ref: canvasRef,
|
|
39542
39899
|
width: Math.round(logicalW * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
|
|
39543
39900
|
height: Math.round(height * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
|
|
39544
|
-
className: "w-full cursor-grab active:cursor-grabbing",
|
|
39901
|
+
className: "w-full cursor-grab active:cursor-grabbing touch-none",
|
|
39545
39902
|
style: { height },
|
|
39546
|
-
|
|
39547
|
-
|
|
39548
|
-
|
|
39549
|
-
|
|
39550
|
-
|
|
39903
|
+
onPointerDown: gestureHandlers.onPointerDown,
|
|
39904
|
+
onPointerMove: gestureHandlers.onPointerMove,
|
|
39905
|
+
onPointerUp: gestureHandlers.onPointerUp,
|
|
39906
|
+
onPointerCancel: gestureHandlers.onPointerCancel,
|
|
39907
|
+
onPointerLeave: handlePointerLeave,
|
|
39908
|
+
onWheel: gestureHandlers.onWheel,
|
|
39551
39909
|
onDoubleClick: handleDoubleClick
|
|
39552
39910
|
}
|
|
39553
39911
|
) }),
|
|
@@ -44346,6 +44704,9 @@ var init_GameCanvas3D2 = __esm({
|
|
|
44346
44704
|
target: cameraTarget,
|
|
44347
44705
|
enableDamping: true,
|
|
44348
44706
|
dampingFactor: 0.05,
|
|
44707
|
+
enableZoom: true,
|
|
44708
|
+
enablePan: true,
|
|
44709
|
+
touches: { ONE: THREE3.TOUCH.ROTATE, TWO: THREE3.TOUCH.DOLLY_PAN },
|
|
44349
44710
|
minDistance: 2,
|
|
44350
44711
|
maxDistance: 100,
|
|
44351
44712
|
maxPolarAngle: Math.PI / 2 - 0.1
|
|
@@ -49831,20 +50192,21 @@ var init_SplitPane = __esm({
|
|
|
49831
50192
|
const [ratio, setRatio] = useState(initialRatio);
|
|
49832
50193
|
const containerRef = useRef(null);
|
|
49833
50194
|
const isDragging = useRef(false);
|
|
49834
|
-
const
|
|
50195
|
+
const handlePointerDown = useCallback(
|
|
49835
50196
|
(e) => {
|
|
49836
50197
|
if (!resizable) return;
|
|
49837
50198
|
e.preventDefault();
|
|
49838
50199
|
isDragging.current = true;
|
|
49839
|
-
|
|
50200
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
50201
|
+
const handlePointerMove = (ev) => {
|
|
49840
50202
|
if (!isDragging.current || !containerRef.current) return;
|
|
49841
50203
|
const rect = containerRef.current.getBoundingClientRect();
|
|
49842
50204
|
let newRatio;
|
|
49843
50205
|
if (direction === "horizontal") {
|
|
49844
|
-
const x =
|
|
50206
|
+
const x = ev.clientX - rect.left;
|
|
49845
50207
|
newRatio = x / rect.width * 100;
|
|
49846
50208
|
} else {
|
|
49847
|
-
const y =
|
|
50209
|
+
const y = ev.clientY - rect.top;
|
|
49848
50210
|
newRatio = y / rect.height * 100;
|
|
49849
50211
|
}
|
|
49850
50212
|
const minRatio = minSize / (direction === "horizontal" ? rect.width : rect.height) * 100;
|
|
@@ -49852,13 +50214,15 @@ var init_SplitPane = __esm({
|
|
|
49852
50214
|
newRatio = Math.max(minRatio, Math.min(maxRatio, newRatio));
|
|
49853
50215
|
setRatio(newRatio);
|
|
49854
50216
|
};
|
|
49855
|
-
const
|
|
50217
|
+
const handlePointerUp = () => {
|
|
49856
50218
|
isDragging.current = false;
|
|
49857
|
-
document.removeEventListener("
|
|
49858
|
-
document.removeEventListener("
|
|
50219
|
+
document.removeEventListener("pointermove", handlePointerMove);
|
|
50220
|
+
document.removeEventListener("pointerup", handlePointerUp);
|
|
50221
|
+
document.removeEventListener("pointercancel", handlePointerUp);
|
|
49859
50222
|
};
|
|
49860
|
-
document.addEventListener("
|
|
49861
|
-
document.addEventListener("
|
|
50223
|
+
document.addEventListener("pointermove", handlePointerMove);
|
|
50224
|
+
document.addEventListener("pointerup", handlePointerUp);
|
|
50225
|
+
document.addEventListener("pointercancel", handlePointerUp);
|
|
49862
50226
|
},
|
|
49863
50227
|
[direction, minSize, resizable]
|
|
49864
50228
|
);
|
|
@@ -49887,9 +50251,9 @@ var init_SplitPane = __esm({
|
|
|
49887
50251
|
resizable && /* @__PURE__ */ jsx(
|
|
49888
50252
|
"div",
|
|
49889
50253
|
{
|
|
49890
|
-
|
|
50254
|
+
onPointerDown: handlePointerDown,
|
|
49891
50255
|
className: cn(
|
|
49892
|
-
"flex-shrink-0 bg-border transition-colors",
|
|
50256
|
+
"flex-shrink-0 bg-border transition-colors touch-none",
|
|
49893
50257
|
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"
|
|
49894
50258
|
)
|
|
49895
50259
|
}
|