@canvas-harness/react 0.0.2 → 0.0.3

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/index.cjs CHANGED
@@ -18,6 +18,54 @@ function useCanvasStore() {
18
18
  }
19
19
  return store;
20
20
  }
21
+ function useInteractionState() {
22
+ const store = useCanvasStore();
23
+ return react.useSyncExternalStore(
24
+ (cb) => store.subscribe("interaction", cb),
25
+ () => store.getInteractionState()
26
+ );
27
+ }
28
+ function useInteractionMode() {
29
+ const store = useCanvasStore();
30
+ return react.useSyncExternalStore(
31
+ (cb) => {
32
+ let lastMode = store.getInteractionState().mode;
33
+ return store.subscribe("interaction", (state) => {
34
+ if (state.mode !== lastMode) {
35
+ lastMode = state.mode;
36
+ cb();
37
+ }
38
+ });
39
+ },
40
+ () => store.getInteractionState().mode
41
+ );
42
+ }
43
+ function useCursor() {
44
+ const store = useCanvasStore();
45
+ return react.useSyncExternalStore(
46
+ (cb) => store.subscribe("interaction", cb),
47
+ () => store.getInteractionState().pointer
48
+ );
49
+ }
50
+ function useIsMoving() {
51
+ const mode = useInteractionMode();
52
+ return mode === "panning" || mode === "zooming" || mode === "dragging" || mode === "resizing" || mode === "rotating";
53
+ }
54
+ var EMPTY_DRAGGED = [];
55
+ function useDraggedIds() {
56
+ const store = useCanvasStore();
57
+ return react.useSyncExternalStore(
58
+ (cb) => store.subscribe("interaction", cb),
59
+ () => {
60
+ const state = store.getInteractionState();
61
+ return state.draggedIds.length === 0 ? EMPTY_DRAGGED : state.draggedIds;
62
+ }
63
+ );
64
+ }
65
+ function useIsPenActive() {
66
+ const cursor = useCursor();
67
+ return cursor?.pointerType === "pen";
68
+ }
21
69
  function EditorMount({
22
70
  store,
23
71
  factory = core.createDefaultTextareaEditor
@@ -713,7 +761,9 @@ var useOverlayHost = () => {
713
761
  }, []);
714
762
  return { mountedIds, setMountedIds };
715
763
  };
716
- var usePanZoom = (ref, store) => {
764
+ var usePanZoom = (ref, store, tool) => {
765
+ const toolRef = react.useRef(tool);
766
+ toolRef.current = tool;
717
767
  react.useEffect(() => {
718
768
  const el = ref.current;
719
769
  if (!el) return;
@@ -851,7 +901,8 @@ var usePanZoom = (ref, store) => {
851
901
  }
852
902
  return;
853
903
  }
854
- if (e.button === 1 || e.button === 0 && panActivatedBySpace) {
904
+ const handToolActive = toolRef.current === "pan";
905
+ if (e.button === 1 || e.button === 0 && (panActivatedBySpace || handToolActive)) {
855
906
  panning = true;
856
907
  lastX = e.clientX;
857
908
  lastY = e.clientY;
@@ -994,8 +1045,9 @@ function CanvasSurface({
994
1045
  const toolRef = react.useRef(tool);
995
1046
  toolRef.current = tool;
996
1047
  const { w, h } = useResizeObserver(wrapRef);
997
- usePanZoom(wrapRef, store);
1048
+ usePanZoom(wrapRef, store, tool);
998
1049
  useInteractionGesture(wrapRef, store, tool);
1050
+ const interactionMode = useInteractionMode();
999
1051
  useArrowTool(wrapRef, store, tool === "arrow", arrowDefaults);
1000
1052
  const { mountedIds, setMountedIds } = useOverlayHost();
1001
1053
  const [camera, setCamera] = react.useState(() => store.getCamera());
@@ -1206,7 +1258,7 @@ function CanvasSurface({
1206
1258
  inset: 0,
1207
1259
  background: "#f8fafc",
1208
1260
  overflow: "hidden",
1209
- cursor: tool === "select" ? "default" : "crosshair",
1261
+ cursor: tool === "pan" ? interactionMode === "panning" ? "grabbing" : "grab" : tool === "select" ? "default" : "crosshair",
1210
1262
  touchAction: "none"
1211
1263
  },
1212
1264
  children: [
@@ -1556,54 +1608,6 @@ function useCamera() {
1556
1608
  () => store.getCamera()
1557
1609
  );
1558
1610
  }
1559
- function useInteractionState() {
1560
- const store = useCanvasStore();
1561
- return react.useSyncExternalStore(
1562
- (cb) => store.subscribe("interaction", cb),
1563
- () => store.getInteractionState()
1564
- );
1565
- }
1566
- function useInteractionMode() {
1567
- const store = useCanvasStore();
1568
- return react.useSyncExternalStore(
1569
- (cb) => {
1570
- let lastMode = store.getInteractionState().mode;
1571
- return store.subscribe("interaction", (state) => {
1572
- if (state.mode !== lastMode) {
1573
- lastMode = state.mode;
1574
- cb();
1575
- }
1576
- });
1577
- },
1578
- () => store.getInteractionState().mode
1579
- );
1580
- }
1581
- function useCursor() {
1582
- const store = useCanvasStore();
1583
- return react.useSyncExternalStore(
1584
- (cb) => store.subscribe("interaction", cb),
1585
- () => store.getInteractionState().pointer
1586
- );
1587
- }
1588
- function useIsMoving() {
1589
- const mode = useInteractionMode();
1590
- return mode === "panning" || mode === "zooming" || mode === "dragging" || mode === "resizing" || mode === "rotating";
1591
- }
1592
- var EMPTY_DRAGGED = [];
1593
- function useDraggedIds() {
1594
- const store = useCanvasStore();
1595
- return react.useSyncExternalStore(
1596
- (cb) => store.subscribe("interaction", cb),
1597
- () => {
1598
- const state = store.getInteractionState();
1599
- return state.draggedIds.length === 0 ? EMPTY_DRAGGED : state.draggedIds;
1600
- }
1601
- );
1602
- }
1603
- function useIsPenActive() {
1604
- const cursor = useCursor();
1605
- return cursor?.pointerType === "pen";
1606
- }
1607
1611
  function useLocalPresence() {
1608
1612
  const store = useCanvasStore();
1609
1613
  return react.useSyncExternalStore(