@octaviaflow/core 3.1.0-beta.94 → 3.1.0-beta.96

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/workflow.js CHANGED
@@ -2736,6 +2736,120 @@ function transformOriginFor(side, align) {
2736
2736
  return align === "start" ? "left top" : align === "end" ? "left bottom" : "left center";
2737
2737
  }
2738
2738
 
2739
+ // src/workflow/components/PresenceCursors/PresenceCursors.tsx
2740
+ import { useEffect as useEffect3, useRef as useRef6 } from "react";
2741
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
2742
+ var IDENTITY_VIEWPORT = { x: 0, y: 0, zoom: 1 };
2743
+ function PresenceCursors({
2744
+ members,
2745
+ onCursorMove,
2746
+ viewport,
2747
+ showLabels = true,
2748
+ className
2749
+ }) {
2750
+ const layerRef = useRef6(null);
2751
+ const liveViewport = useViewportOrNull();
2752
+ const vp = viewport ?? liveViewport ?? IDENTITY_VIEWPORT;
2753
+ const vpRef = useRef6(vp);
2754
+ const reportRef = useRef6(onCursorMove);
2755
+ useEffect3(() => {
2756
+ vpRef.current = vp;
2757
+ reportRef.current = onCursorMove;
2758
+ });
2759
+ const isReporting = Boolean(onCursorMove);
2760
+ useEffect3(() => {
2761
+ const layer = layerRef.current;
2762
+ if (!layer || !isReporting) return;
2763
+ let frameId = 0;
2764
+ let scheduled = false;
2765
+ let disposed = false;
2766
+ let pendingClient = null;
2767
+ const flush = () => {
2768
+ scheduled = false;
2769
+ if (disposed) return;
2770
+ if (!pendingClient) {
2771
+ reportRef.current?.(null);
2772
+ return;
2773
+ }
2774
+ const rect = layer.getBoundingClientRect();
2775
+ const inside = pendingClient.x >= rect.left && pendingClient.x <= rect.right && pendingClient.y >= rect.top && pendingClient.y <= rect.bottom;
2776
+ reportRef.current?.(
2777
+ inside ? screenToFlow(
2778
+ { x: pendingClient.x - rect.left, y: pendingClient.y - rect.top },
2779
+ vpRef.current
2780
+ ) : null
2781
+ );
2782
+ };
2783
+ const schedule = () => {
2784
+ if (scheduled || disposed) return;
2785
+ scheduled = true;
2786
+ frameId = requestAnimationFrame(flush);
2787
+ };
2788
+ const onMove = (e) => {
2789
+ pendingClient = { x: e.clientX, y: e.clientY };
2790
+ schedule();
2791
+ };
2792
+ const onLeave = () => {
2793
+ pendingClient = null;
2794
+ schedule();
2795
+ };
2796
+ const onVisibility = () => {
2797
+ if (document.visibilityState === "hidden") onLeave();
2798
+ };
2799
+ window.addEventListener("pointermove", onMove, { passive: true });
2800
+ window.addEventListener("pointerleave", onLeave);
2801
+ window.addEventListener("blur", onLeave);
2802
+ document.addEventListener("visibilitychange", onVisibility);
2803
+ return () => {
2804
+ disposed = true;
2805
+ window.removeEventListener("pointermove", onMove);
2806
+ window.removeEventListener("pointerleave", onLeave);
2807
+ window.removeEventListener("blur", onLeave);
2808
+ document.removeEventListener("visibilitychange", onVisibility);
2809
+ if (frameId) cancelAnimationFrame(frameId);
2810
+ };
2811
+ }, [isReporting]);
2812
+ return /* @__PURE__ */ jsx6("div", { ref: layerRef, className: cn("ods-presence-cursors", className), "aria-hidden": "true", children: members.map((m) => {
2813
+ if (!m.cursor) return null;
2814
+ const p = flowToScreen(m.cursor, vp);
2815
+ return /* @__PURE__ */ jsxs5(
2816
+ "div",
2817
+ {
2818
+ className: "ods-presence-cursors__pointer",
2819
+ style: {
2820
+ transform: `translate3d(${p.x}px, ${p.y}px, 0)`,
2821
+ color: m.colour
2822
+ },
2823
+ children: [
2824
+ /* @__PURE__ */ jsx6(
2825
+ "svg",
2826
+ {
2827
+ className: "ods-presence-cursors__arrow",
2828
+ width: "18",
2829
+ height: "18",
2830
+ viewBox: "0 0 18 18",
2831
+ fill: "none",
2832
+ "aria-hidden": "true",
2833
+ children: /* @__PURE__ */ jsx6(
2834
+ "path",
2835
+ {
2836
+ d: "M2 1.5 L2 14 L5.6 10.7 L8 15.8 L10.6 14.6 L8.2 9.6 L13 9.3 Z",
2837
+ fill: "currentColor",
2838
+ stroke: "var(--ods-surface-canvas)",
2839
+ strokeWidth: "1.2",
2840
+ strokeLinejoin: "round"
2841
+ }
2842
+ )
2843
+ }
2844
+ ),
2845
+ showLabels && /* @__PURE__ */ jsx6("span", { className: "ods-presence-cursors__label", children: m.name })
2846
+ ]
2847
+ },
2848
+ m.userId
2849
+ );
2850
+ }) });
2851
+ }
2852
+
2739
2853
  // src/workflow/utils/collapse.ts
2740
2854
  function collapseFor(nodes, edges) {
2741
2855
  const collapsedAncestorOf = /* @__PURE__ */ new Map();
@@ -2835,6 +2949,7 @@ export {
2835
2949
  NodeToolbar,
2836
2950
  OutputNode,
2837
2951
  ParallelNode,
2952
+ PresenceCursors,
2838
2953
  StickyNode,
2839
2954
  TriggerNode,
2840
2955
  WaitNode,