@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.
Files changed (35) hide show
  1. package/dist/avl/index.cjs +526 -161
  2. package/dist/avl/index.js +526 -161
  3. package/dist/components/core/atoms/Box.d.ts +2 -0
  4. package/dist/components/core/molecules/CalendarGrid.d.ts +9 -1
  5. package/dist/components/core/molecules/PositionedCanvas.d.ts +14 -1
  6. package/dist/components/core/molecules/ReplyTree.d.ts +13 -1
  7. package/dist/components/game/molecules/three/index.cjs +64 -0
  8. package/dist/components/game/molecules/three/index.js +64 -0
  9. package/dist/components/game/organisms/hooks/useCamera.d.ts +16 -0
  10. package/dist/components/index.cjs +526 -162
  11. package/dist/components/index.js +526 -162
  12. package/dist/components/marketing/organisms/CaseStudyOrganism.d.ts +10 -1
  13. package/dist/components/marketing/organisms/FeatureGridOrganism.d.ts +10 -1
  14. package/dist/components/marketing/organisms/HeroOrganism.d.ts +24 -1
  15. package/dist/components/marketing/organisms/PricingOrganism.d.ts +14 -1
  16. package/dist/components/marketing/organisms/ShowcaseOrganism.d.ts +14 -1
  17. package/dist/components/marketing/organisms/StatsOrganism.d.ts +6 -1
  18. package/dist/components/marketing/organisms/StepFlowOrganism.d.ts +9 -1
  19. package/dist/components/marketing/organisms/TeamOrganism.d.ts +10 -1
  20. package/dist/docs/index.cjs +64 -0
  21. package/dist/docs/index.d.cts +2 -0
  22. package/dist/docs/index.js +64 -0
  23. package/dist/hooks/index.cjs +148 -0
  24. package/dist/hooks/index.d.ts +2 -0
  25. package/dist/hooks/index.js +147 -1
  26. package/dist/hooks/useCanvasGestures.d.ts +44 -0
  27. package/dist/hooks/useTapReveal.d.ts +32 -0
  28. package/dist/marketing/index.cjs +59 -0
  29. package/dist/marketing/index.d.cts +2 -0
  30. package/dist/marketing/index.js +59 -0
  31. package/dist/providers/index.cjs +526 -161
  32. package/dist/providers/index.js +526 -161
  33. package/dist/runtime/index.cjs +526 -161
  34. package/dist/runtime/index.js +526 -161
  35. package/package.json +2 -2
@@ -2514,6 +2514,152 @@ function usePinchZoom(options = {}) {
2514
2514
  resetZoom
2515
2515
  };
2516
2516
  }
2517
+ function localPoint(canvas, clientX, clientY) {
2518
+ if (!canvas) return { x: clientX, y: clientY };
2519
+ const rect = canvas.getBoundingClientRect();
2520
+ return { x: clientX - rect.left, y: clientY - rect.top };
2521
+ }
2522
+ function useCanvasGestures(options) {
2523
+ const {
2524
+ canvasRef,
2525
+ enabled = true,
2526
+ wheelStep = 1.1,
2527
+ onPointerDown,
2528
+ onPointerMove,
2529
+ onPointerUp,
2530
+ onZoom,
2531
+ onPanDelta,
2532
+ onMultiTouchStart
2533
+ } = options;
2534
+ const pointers = useRef(/* @__PURE__ */ new Map());
2535
+ const pinch = useRef(null);
2536
+ const computePinch = useCallback(() => {
2537
+ const pts = [...pointers.current.values()];
2538
+ const dx = pts[1].x - pts[0].x;
2539
+ const dy = pts[1].y - pts[0].y;
2540
+ return {
2541
+ distance: Math.hypot(dx, dy) || 1,
2542
+ centroid: { x: (pts[0].x + pts[1].x) / 2, y: (pts[0].y + pts[1].y) / 2 }
2543
+ };
2544
+ }, []);
2545
+ const handlePointerDown = useCallback(
2546
+ (e) => {
2547
+ if (!enabled) return;
2548
+ e.currentTarget.setPointerCapture(e.pointerId);
2549
+ pointers.current.set(e.pointerId, localPoint(canvasRef.current, e.clientX, e.clientY));
2550
+ if (pointers.current.size === 2) {
2551
+ onMultiTouchStart?.();
2552
+ pinch.current = computePinch();
2553
+ } else if (pointers.current.size === 1) {
2554
+ onPointerDown?.(e);
2555
+ }
2556
+ },
2557
+ [enabled, canvasRef, onMultiTouchStart, computePinch, onPointerDown]
2558
+ );
2559
+ const handlePointerMove = useCallback(
2560
+ (e) => {
2561
+ if (!enabled) return;
2562
+ if (pointers.current.has(e.pointerId)) {
2563
+ pointers.current.set(e.pointerId, localPoint(canvasRef.current, e.clientX, e.clientY));
2564
+ }
2565
+ if (pointers.current.size >= 2 && pinch.current) {
2566
+ const next = computePinch();
2567
+ const prev = pinch.current;
2568
+ if (next.distance !== prev.distance) {
2569
+ onZoom?.(next.distance / prev.distance, next.centroid.x, next.centroid.y);
2570
+ }
2571
+ onPanDelta?.(next.centroid.x - prev.centroid.x, next.centroid.y - prev.centroid.y);
2572
+ pinch.current = next;
2573
+ return;
2574
+ }
2575
+ onPointerMove?.(e);
2576
+ },
2577
+ [enabled, canvasRef, computePinch, onZoom, onPanDelta, onPointerMove]
2578
+ );
2579
+ const endPointer = useCallback(
2580
+ (e, fireUp) => {
2581
+ const wasMulti = pointers.current.size >= 2;
2582
+ pointers.current.delete(e.pointerId);
2583
+ if (pointers.current.size < 2) pinch.current = null;
2584
+ if (wasMulti && pointers.current.size === 1) return;
2585
+ if (pointers.current.size === 0 && fireUp) onPointerUp?.(e);
2586
+ },
2587
+ [onPointerUp]
2588
+ );
2589
+ const handlePointerUp = useCallback(
2590
+ (e) => {
2591
+ if (!enabled) return;
2592
+ endPointer(e, true);
2593
+ },
2594
+ [enabled, endPointer]
2595
+ );
2596
+ const handlePointerCancel = useCallback(
2597
+ (e) => {
2598
+ if (!enabled) return;
2599
+ endPointer(e, false);
2600
+ },
2601
+ [enabled, endPointer]
2602
+ );
2603
+ const handleWheel = useCallback(
2604
+ (e) => {
2605
+ if (!enabled) return;
2606
+ e.preventDefault();
2607
+ const { x, y } = localPoint(canvasRef.current, e.clientX, e.clientY);
2608
+ onZoom?.(e.deltaY < 0 ? wheelStep : 1 / wheelStep, x, y);
2609
+ },
2610
+ [enabled, canvasRef, wheelStep, onZoom]
2611
+ );
2612
+ return {
2613
+ onPointerDown: handlePointerDown,
2614
+ onPointerMove: handlePointerMove,
2615
+ onPointerUp: handlePointerUp,
2616
+ onPointerCancel: handlePointerCancel,
2617
+ onWheel: handleWheel
2618
+ };
2619
+ }
2620
+ function useTapReveal(options = {}) {
2621
+ const { onReveal, onDismiss, refs, enabled = true } = options;
2622
+ const [revealed, setRevealed] = useState(false);
2623
+ const onRevealRef = useRef(onReveal);
2624
+ const onDismissRef = useRef(onDismiss);
2625
+ onRevealRef.current = onReveal;
2626
+ onDismissRef.current = onDismiss;
2627
+ const reveal = useCallback(() => {
2628
+ setRevealed((wasRevealed) => {
2629
+ if (!wasRevealed) onRevealRef.current?.();
2630
+ return true;
2631
+ });
2632
+ }, []);
2633
+ const dismiss = useCallback(() => {
2634
+ setRevealed((wasRevealed) => {
2635
+ if (wasRevealed) onDismissRef.current?.();
2636
+ return false;
2637
+ });
2638
+ }, []);
2639
+ const onPointerDown = useCallback(
2640
+ (e) => {
2641
+ if (!enabled || e.pointerType === "mouse") return;
2642
+ if (revealed) dismiss();
2643
+ else reveal();
2644
+ },
2645
+ [enabled, revealed, reveal, dismiss]
2646
+ );
2647
+ useEffect(() => {
2648
+ if (!revealed || typeof document === "undefined") return;
2649
+ const onDocDown = (ev) => {
2650
+ const target = ev.target;
2651
+ if (!(target instanceof Node)) return;
2652
+ const inside = (refs ?? []).some((r) => r.current?.contains(target));
2653
+ if (!inside) dismiss();
2654
+ };
2655
+ const id = setTimeout(() => document.addEventListener("pointerdown", onDocDown), 0);
2656
+ return () => {
2657
+ clearTimeout(id);
2658
+ document.removeEventListener("pointerdown", onDocDown);
2659
+ };
2660
+ }, [revealed, refs, dismiss]);
2661
+ return { revealed, triggerProps: { onPointerDown }, reveal, dismiss };
2662
+ }
2517
2663
  var ALMADAR_DND_MIME = "application/x-almadar-dnd";
2518
2664
  function useDraggable({ payload, disabled = false }) {
2519
2665
  const [isDragging, setIsDragging] = useState(false);
@@ -2749,4 +2895,4 @@ function useGitHubBranches(owner, repo, enabled = true) {
2749
2895
  });
2750
2896
  }
2751
2897
 
2752
- export { ALMADAR_DND_MIME, DEFAULT_SLOTS, I18nProvider, clearEntities, createTranslate, getAllEntities, getByType, getEntity, getSingleton, parseQueryBinding, removeEntity, spawnEntity, updateEntity, updateSingleton, useAgentChat, useAuthContext, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEntities, useEntitiesByType, useEntity as useEntityById, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useInfiniteScroll, useInput, useLongPress, useOrbitalHistory, usePhysics, usePinchZoom, usePlayer, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSingletonEntity, useSwipeGesture, useTraitListens, useTranslate, useUIEvents, useUISlotManager, useValidation };
2898
+ export { ALMADAR_DND_MIME, DEFAULT_SLOTS, I18nProvider, clearEntities, createTranslate, getAllEntities, getByType, getEntity, getSingleton, parseQueryBinding, removeEntity, spawnEntity, updateEntity, updateSingleton, useAgentChat, useAuthContext, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEntities, useEntitiesByType, useEntity as useEntityById, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useInfiniteScroll, useInput, useLongPress, useOrbitalHistory, usePhysics, usePinchZoom, usePlayer, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSingletonEntity, useSwipeGesture, useTapReveal, useTraitListens, useTranslate, useUIEvents, useUISlotManager, useValidation };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Unified pointer/touch gesture detection for canvas surfaces (graph, isometric, etc.).
3
+ *
4
+ * It owns the hard part — pointer tracking + two-finger pinch (scale factor + centroid) —
5
+ * and DELEGATES application to the consumer via callbacks, so each canvas applies pan/zoom
6
+ * in its own coordinate convention (screen-offset vs world-camera). A single pointer is
7
+ * passed straight through to the consumer's domain handlers (pan / node-drag / tile-select);
8
+ * a second pointer takes over as a pinch and cancels any in-flight single-pointer action.
9
+ *
10
+ * Pointer Events cover mouse, touch and pen, so this REPLACES mouse handlers — no dual paths.
11
+ */
12
+ export interface CanvasGestureCallbacks {
13
+ /** Single-pointer down — start the consumer's pan / drag / select (domain-specific). */
14
+ onPointerDown?: (e: React.PointerEvent<HTMLCanvasElement>) => void;
15
+ /** Single-pointer move. */
16
+ onPointerMove?: (e: React.PointerEvent<HTMLCanvasElement>) => void;
17
+ /** Single-pointer up. */
18
+ onPointerUp?: (e: React.PointerEvent<HTMLCanvasElement>) => void;
19
+ /**
20
+ * Multiplicative zoom around a canvas-local point. Fired by wheel and by pinch.
21
+ * Consumer applies `newZoom = clamp(oldZoom * factor)` keeping (centerX,centerY) fixed.
22
+ */
23
+ onZoom?: (factor: number, centerX: number, centerY: number) => void;
24
+ /** Two-finger pan delta in canvas-local px (fired alongside pinch). */
25
+ onPanDelta?: (dx: number, dy: number) => void;
26
+ /** A second pointer arrived — cancel any single-pointer pan/drag the consumer started. */
27
+ onMultiTouchStart?: () => void;
28
+ }
29
+ export interface UseCanvasGesturesOptions extends CanvasGestureCallbacks {
30
+ /** The canvas being gestured on (for coordinate translation). */
31
+ canvasRef: React.RefObject<HTMLCanvasElement | null>;
32
+ /** When false, all gestures are inert. Default true. */
33
+ enabled?: boolean;
34
+ /** Wheel zoom step per notch (>1). Default 1.1. */
35
+ wheelStep?: number;
36
+ }
37
+ export interface CanvasGestureHandlers {
38
+ onPointerDown: (e: React.PointerEvent<HTMLCanvasElement>) => void;
39
+ onPointerMove: (e: React.PointerEvent<HTMLCanvasElement>) => void;
40
+ onPointerUp: (e: React.PointerEvent<HTMLCanvasElement>) => void;
41
+ onPointerCancel: (e: React.PointerEvent<HTMLCanvasElement>) => void;
42
+ onWheel: (e: React.WheelEvent<HTMLCanvasElement>) => void;
43
+ }
44
+ export declare function useCanvasGestures(options: UseCanvasGesturesOptions): CanvasGestureHandlers;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Hover-only reveals (tooltips, hover-popovers, submenus, `Box.hoverEvent`) have no hover on
3
+ * touch, so they're invisible/unreachable. This adds the tap-to-reveal fallback: on a touch/pen
4
+ * tap the surface reveals and fires the SAME event the hover path fires; a tap outside dismisses.
5
+ * Mouse is left to the component's existing hover handlers (`pointerType === 'mouse'` is ignored),
6
+ * so this is purely additive — no behavior change on desktop.
7
+ */
8
+ export interface TapRevealOptions {
9
+ /** Fired when a tap reveals — reuse to emit the component's existing hover event. */
10
+ onReveal?: () => void;
11
+ /** Fired when an outside tap (or a second trigger tap) dismisses. */
12
+ onDismiss?: () => void;
13
+ /**
14
+ * Elements considered "inside" for outside-tap detection. Pass the trigger and the surface
15
+ * (the surface may be portaled, so it isn't a DOM descendant of the trigger). A tap whose
16
+ * target is inside none of these dismisses.
17
+ */
18
+ refs?: ReadonlyArray<React.RefObject<HTMLElement | null>>;
19
+ /** When false, taps are ignored (hover-only). Default true. */
20
+ enabled?: boolean;
21
+ }
22
+ export interface TapRevealResult {
23
+ /** Whether the surface is currently revealed via a tap. OR this with the hover state. */
24
+ revealed: boolean;
25
+ /** Spread on the trigger; toggles reveal on a touch/pen tap (ignores mouse). */
26
+ triggerProps: {
27
+ onPointerDown: (e: React.PointerEvent) => void;
28
+ };
29
+ reveal: () => void;
30
+ dismiss: () => void;
31
+ }
32
+ export declare function useTapReveal(options?: TapRevealOptions): TapRevealResult;
@@ -2625,6 +2625,49 @@ function useEventBus() {
2625
2625
  };
2626
2626
  }, [baseBus, scope]);
2627
2627
  }
2628
+ function useTapReveal(options = {}) {
2629
+ const { onReveal, onDismiss, refs, enabled = true } = options;
2630
+ const [revealed, setRevealed] = React9.useState(false);
2631
+ const onRevealRef = React9.useRef(onReveal);
2632
+ const onDismissRef = React9.useRef(onDismiss);
2633
+ onRevealRef.current = onReveal;
2634
+ onDismissRef.current = onDismiss;
2635
+ const reveal = React9.useCallback(() => {
2636
+ setRevealed((wasRevealed) => {
2637
+ if (!wasRevealed) onRevealRef.current?.();
2638
+ return true;
2639
+ });
2640
+ }, []);
2641
+ const dismiss = React9.useCallback(() => {
2642
+ setRevealed((wasRevealed) => {
2643
+ if (wasRevealed) onDismissRef.current?.();
2644
+ return false;
2645
+ });
2646
+ }, []);
2647
+ const onPointerDown = React9.useCallback(
2648
+ (e) => {
2649
+ if (!enabled || e.pointerType === "mouse") return;
2650
+ if (revealed) dismiss();
2651
+ else reveal();
2652
+ },
2653
+ [enabled, revealed, reveal, dismiss]
2654
+ );
2655
+ React9.useEffect(() => {
2656
+ if (!revealed || typeof document === "undefined") return;
2657
+ const onDocDown = (ev) => {
2658
+ const target = ev.target;
2659
+ if (!(target instanceof Node)) return;
2660
+ const inside = (refs ?? []).some((r2) => r2.current?.contains(target));
2661
+ if (!inside) dismiss();
2662
+ };
2663
+ const id = setTimeout(() => document.addEventListener("pointerdown", onDocDown), 0);
2664
+ return () => {
2665
+ clearTimeout(id);
2666
+ document.removeEventListener("pointerdown", onDocDown);
2667
+ };
2668
+ }, [revealed, refs, dismiss]);
2669
+ return { revealed, triggerProps: { onPointerDown }, reveal, dismiss };
2670
+ }
2628
2671
 
2629
2672
  // components/core/atoms/Box.tsx
2630
2673
  var paddingStyles = {
@@ -2752,10 +2795,12 @@ var Box = React9__default.default.forwardRef(
2752
2795
  action,
2753
2796
  actionPayload,
2754
2797
  hoverEvent,
2798
+ tapReveal = true,
2755
2799
  maxWidth,
2756
2800
  onClick,
2757
2801
  onMouseEnter,
2758
2802
  onMouseLeave,
2803
+ onPointerDown,
2759
2804
  ...rest
2760
2805
  }, ref) => {
2761
2806
  const eventBus = useEventBus();
@@ -2778,6 +2823,19 @@ var Box = React9__default.default.forwardRef(
2778
2823
  }
2779
2824
  onMouseLeave?.(e);
2780
2825
  }, [hoverEvent, eventBus, onMouseLeave]);
2826
+ const { triggerProps } = useTapReveal({
2827
+ enabled: tapReveal && !!hoverEvent,
2828
+ onReveal: React9.useCallback(() => {
2829
+ if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
2830
+ }, [hoverEvent, eventBus]),
2831
+ onDismiss: React9.useCallback(() => {
2832
+ if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
2833
+ }, [hoverEvent, eventBus])
2834
+ });
2835
+ const handlePointerDown = React9.useCallback((e) => {
2836
+ if (hoverEvent && tapReveal) triggerProps.onPointerDown(e);
2837
+ onPointerDown?.(e);
2838
+ }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
2781
2839
  const isClickable = action || onClick;
2782
2840
  return React9__default.default.createElement(
2783
2841
  Component,
@@ -2805,6 +2863,7 @@ var Box = React9__default.default.forwardRef(
2805
2863
  onClick: isClickable ? handleClick : void 0,
2806
2864
  onMouseEnter: hoverEvent || onMouseEnter ? handleMouseEnter : void 0,
2807
2865
  onMouseLeave: hoverEvent || onMouseLeave ? handleMouseLeave : void 0,
2866
+ onPointerDown: hoverEvent && tapReveal || onPointerDown ? handlePointerDown : void 0,
2808
2867
  style: maxWidth ? { maxWidth, ...rest.style } : rest.style,
2809
2868
  ...rest
2810
2869
  },
@@ -55,6 +55,8 @@ interface BoxProps extends React.HTMLAttributes<HTMLDivElement> {
55
55
  actionPayload?: EventPayload;
56
56
  /** Declarative hover event — emits UI:{hoverEvent} with { hovered: true/false } on mouseEnter/mouseLeave */
57
57
  hoverEvent?: EventKey;
58
+ /** When true (default), a touch/pen tap also fires `hoverEvent` (toggling hovered) so hover-only reveals work on touch. */
59
+ tapReveal?: boolean;
58
60
  /** Maximum width (CSS value, e.g., "550px", "80rem") */
59
61
  maxWidth?: string;
60
62
  /** Children elements */
@@ -2601,6 +2601,49 @@ function useEventBus() {
2601
2601
  };
2602
2602
  }, [baseBus, scope]);
2603
2603
  }
2604
+ function useTapReveal(options = {}) {
2605
+ const { onReveal, onDismiss, refs, enabled = true } = options;
2606
+ const [revealed, setRevealed] = useState(false);
2607
+ const onRevealRef = useRef(onReveal);
2608
+ const onDismissRef = useRef(onDismiss);
2609
+ onRevealRef.current = onReveal;
2610
+ onDismissRef.current = onDismiss;
2611
+ const reveal = useCallback(() => {
2612
+ setRevealed((wasRevealed) => {
2613
+ if (!wasRevealed) onRevealRef.current?.();
2614
+ return true;
2615
+ });
2616
+ }, []);
2617
+ const dismiss = useCallback(() => {
2618
+ setRevealed((wasRevealed) => {
2619
+ if (wasRevealed) onDismissRef.current?.();
2620
+ return false;
2621
+ });
2622
+ }, []);
2623
+ const onPointerDown = useCallback(
2624
+ (e) => {
2625
+ if (!enabled || e.pointerType === "mouse") return;
2626
+ if (revealed) dismiss();
2627
+ else reveal();
2628
+ },
2629
+ [enabled, revealed, reveal, dismiss]
2630
+ );
2631
+ useEffect(() => {
2632
+ if (!revealed || typeof document === "undefined") return;
2633
+ const onDocDown = (ev) => {
2634
+ const target = ev.target;
2635
+ if (!(target instanceof Node)) return;
2636
+ const inside = (refs ?? []).some((r2) => r2.current?.contains(target));
2637
+ if (!inside) dismiss();
2638
+ };
2639
+ const id = setTimeout(() => document.addEventListener("pointerdown", onDocDown), 0);
2640
+ return () => {
2641
+ clearTimeout(id);
2642
+ document.removeEventListener("pointerdown", onDocDown);
2643
+ };
2644
+ }, [revealed, refs, dismiss]);
2645
+ return { revealed, triggerProps: { onPointerDown }, reveal, dismiss };
2646
+ }
2604
2647
 
2605
2648
  // components/core/atoms/Box.tsx
2606
2649
  var paddingStyles = {
@@ -2728,10 +2771,12 @@ var Box = React9.forwardRef(
2728
2771
  action,
2729
2772
  actionPayload,
2730
2773
  hoverEvent,
2774
+ tapReveal = true,
2731
2775
  maxWidth,
2732
2776
  onClick,
2733
2777
  onMouseEnter,
2734
2778
  onMouseLeave,
2779
+ onPointerDown,
2735
2780
  ...rest
2736
2781
  }, ref) => {
2737
2782
  const eventBus = useEventBus();
@@ -2754,6 +2799,19 @@ var Box = React9.forwardRef(
2754
2799
  }
2755
2800
  onMouseLeave?.(e);
2756
2801
  }, [hoverEvent, eventBus, onMouseLeave]);
2802
+ const { triggerProps } = useTapReveal({
2803
+ enabled: tapReveal && !!hoverEvent,
2804
+ onReveal: useCallback(() => {
2805
+ if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
2806
+ }, [hoverEvent, eventBus]),
2807
+ onDismiss: useCallback(() => {
2808
+ if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
2809
+ }, [hoverEvent, eventBus])
2810
+ });
2811
+ const handlePointerDown = useCallback((e) => {
2812
+ if (hoverEvent && tapReveal) triggerProps.onPointerDown(e);
2813
+ onPointerDown?.(e);
2814
+ }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
2757
2815
  const isClickable = action || onClick;
2758
2816
  return React9.createElement(
2759
2817
  Component,
@@ -2781,6 +2839,7 @@ var Box = React9.forwardRef(
2781
2839
  onClick: isClickable ? handleClick : void 0,
2782
2840
  onMouseEnter: hoverEvent || onMouseEnter ? handleMouseEnter : void 0,
2783
2841
  onMouseLeave: hoverEvent || onMouseLeave ? handleMouseLeave : void 0,
2842
+ onPointerDown: hoverEvent && tapReveal || onPointerDown ? handlePointerDown : void 0,
2784
2843
  style: maxWidth ? { maxWidth, ...rest.style } : rest.style,
2785
2844
  ...rest
2786
2845
  },