@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 +56 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +57 -53
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -464,7 +464,7 @@ declare function useCanRedo(): boolean;
|
|
|
464
464
|
* zoom; this hook handles primary-button gestures only.
|
|
465
465
|
*/
|
|
466
466
|
|
|
467
|
-
type InteractionTool = 'select' | 'rect' | 'ellipse' | 'diamond' | 'capsule' | 'arrow' | 'text';
|
|
467
|
+
type InteractionTool = 'select' | 'pan' | 'rect' | 'ellipse' | 'diamond' | 'capsule' | 'arrow' | 'text';
|
|
468
468
|
|
|
469
469
|
/**
|
|
470
470
|
* @canvas-harness/react
|
package/dist/index.d.ts
CHANGED
|
@@ -464,7 +464,7 @@ declare function useCanRedo(): boolean;
|
|
|
464
464
|
* zoom; this hook handles primary-button gestures only.
|
|
465
465
|
*/
|
|
466
466
|
|
|
467
|
-
type InteractionTool = 'select' | 'rect' | 'ellipse' | 'diamond' | 'capsule' | 'arrow' | 'text';
|
|
467
|
+
type InteractionTool = 'select' | 'pan' | 'rect' | 'ellipse' | 'diamond' | 'capsule' | 'arrow' | 'text';
|
|
468
468
|
|
|
469
469
|
/**
|
|
470
470
|
* @canvas-harness/react
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRenderer, DEFAULT_MINIMAP_MAX_NODES, renderMinimapContent, sceneBounds, drawMinimapViewport, worldViewportFromCamera, screenToWorld, hitTestAny, copy, cut, paste, createPalmRejectionState, createDefaultTextareaEditor, minimapScreenToWorld, notePenActive, shouldRejectTouch, notePenInactive, asEdgeId, midpointToCubicControls, projectToNodeBoundary, marqueeNodes, shouldAutoFit, computeAutoFitHeight, hitTestPoint, worldToNodeLocal, edgeLabelBoundsWorld, asNodeId, zoomAtScreenPoint, clampZoom, panByScreen } from '@canvas-harness/core';
|
|
2
|
-
import { createContext, useContext, useRef, useState, useEffect
|
|
2
|
+
import { createContext, useContext, useSyncExternalStore, useRef, useState, useEffect } from 'react';
|
|
3
3
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
// src/Canvas.tsx
|
|
@@ -16,6 +16,54 @@ function useCanvasStore() {
|
|
|
16
16
|
}
|
|
17
17
|
return store;
|
|
18
18
|
}
|
|
19
|
+
function useInteractionState() {
|
|
20
|
+
const store = useCanvasStore();
|
|
21
|
+
return useSyncExternalStore(
|
|
22
|
+
(cb) => store.subscribe("interaction", cb),
|
|
23
|
+
() => store.getInteractionState()
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
function useInteractionMode() {
|
|
27
|
+
const store = useCanvasStore();
|
|
28
|
+
return useSyncExternalStore(
|
|
29
|
+
(cb) => {
|
|
30
|
+
let lastMode = store.getInteractionState().mode;
|
|
31
|
+
return store.subscribe("interaction", (state) => {
|
|
32
|
+
if (state.mode !== lastMode) {
|
|
33
|
+
lastMode = state.mode;
|
|
34
|
+
cb();
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
() => store.getInteractionState().mode
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
function useCursor() {
|
|
42
|
+
const store = useCanvasStore();
|
|
43
|
+
return useSyncExternalStore(
|
|
44
|
+
(cb) => store.subscribe("interaction", cb),
|
|
45
|
+
() => store.getInteractionState().pointer
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
function useIsMoving() {
|
|
49
|
+
const mode = useInteractionMode();
|
|
50
|
+
return mode === "panning" || mode === "zooming" || mode === "dragging" || mode === "resizing" || mode === "rotating";
|
|
51
|
+
}
|
|
52
|
+
var EMPTY_DRAGGED = [];
|
|
53
|
+
function useDraggedIds() {
|
|
54
|
+
const store = useCanvasStore();
|
|
55
|
+
return useSyncExternalStore(
|
|
56
|
+
(cb) => store.subscribe("interaction", cb),
|
|
57
|
+
() => {
|
|
58
|
+
const state = store.getInteractionState();
|
|
59
|
+
return state.draggedIds.length === 0 ? EMPTY_DRAGGED : state.draggedIds;
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
function useIsPenActive() {
|
|
64
|
+
const cursor = useCursor();
|
|
65
|
+
return cursor?.pointerType === "pen";
|
|
66
|
+
}
|
|
19
67
|
function EditorMount({
|
|
20
68
|
store,
|
|
21
69
|
factory = createDefaultTextareaEditor
|
|
@@ -711,7 +759,9 @@ var useOverlayHost = () => {
|
|
|
711
759
|
}, []);
|
|
712
760
|
return { mountedIds, setMountedIds };
|
|
713
761
|
};
|
|
714
|
-
var usePanZoom = (ref, store) => {
|
|
762
|
+
var usePanZoom = (ref, store, tool) => {
|
|
763
|
+
const toolRef = useRef(tool);
|
|
764
|
+
toolRef.current = tool;
|
|
715
765
|
useEffect(() => {
|
|
716
766
|
const el = ref.current;
|
|
717
767
|
if (!el) return;
|
|
@@ -849,7 +899,8 @@ var usePanZoom = (ref, store) => {
|
|
|
849
899
|
}
|
|
850
900
|
return;
|
|
851
901
|
}
|
|
852
|
-
|
|
902
|
+
const handToolActive = toolRef.current === "pan";
|
|
903
|
+
if (e.button === 1 || e.button === 0 && (panActivatedBySpace || handToolActive)) {
|
|
853
904
|
panning = true;
|
|
854
905
|
lastX = e.clientX;
|
|
855
906
|
lastY = e.clientY;
|
|
@@ -992,8 +1043,9 @@ function CanvasSurface({
|
|
|
992
1043
|
const toolRef = useRef(tool);
|
|
993
1044
|
toolRef.current = tool;
|
|
994
1045
|
const { w, h } = useResizeObserver(wrapRef);
|
|
995
|
-
usePanZoom(wrapRef, store);
|
|
1046
|
+
usePanZoom(wrapRef, store, tool);
|
|
996
1047
|
useInteractionGesture(wrapRef, store, tool);
|
|
1048
|
+
const interactionMode = useInteractionMode();
|
|
997
1049
|
useArrowTool(wrapRef, store, tool === "arrow", arrowDefaults);
|
|
998
1050
|
const { mountedIds, setMountedIds } = useOverlayHost();
|
|
999
1051
|
const [camera, setCamera] = useState(() => store.getCamera());
|
|
@@ -1204,7 +1256,7 @@ function CanvasSurface({
|
|
|
1204
1256
|
inset: 0,
|
|
1205
1257
|
background: "#f8fafc",
|
|
1206
1258
|
overflow: "hidden",
|
|
1207
|
-
cursor: tool === "select" ? "default" : "crosshair",
|
|
1259
|
+
cursor: tool === "pan" ? interactionMode === "panning" ? "grabbing" : "grab" : tool === "select" ? "default" : "crosshair",
|
|
1208
1260
|
touchAction: "none"
|
|
1209
1261
|
},
|
|
1210
1262
|
children: [
|
|
@@ -1554,54 +1606,6 @@ function useCamera() {
|
|
|
1554
1606
|
() => store.getCamera()
|
|
1555
1607
|
);
|
|
1556
1608
|
}
|
|
1557
|
-
function useInteractionState() {
|
|
1558
|
-
const store = useCanvasStore();
|
|
1559
|
-
return useSyncExternalStore(
|
|
1560
|
-
(cb) => store.subscribe("interaction", cb),
|
|
1561
|
-
() => store.getInteractionState()
|
|
1562
|
-
);
|
|
1563
|
-
}
|
|
1564
|
-
function useInteractionMode() {
|
|
1565
|
-
const store = useCanvasStore();
|
|
1566
|
-
return useSyncExternalStore(
|
|
1567
|
-
(cb) => {
|
|
1568
|
-
let lastMode = store.getInteractionState().mode;
|
|
1569
|
-
return store.subscribe("interaction", (state) => {
|
|
1570
|
-
if (state.mode !== lastMode) {
|
|
1571
|
-
lastMode = state.mode;
|
|
1572
|
-
cb();
|
|
1573
|
-
}
|
|
1574
|
-
});
|
|
1575
|
-
},
|
|
1576
|
-
() => store.getInteractionState().mode
|
|
1577
|
-
);
|
|
1578
|
-
}
|
|
1579
|
-
function useCursor() {
|
|
1580
|
-
const store = useCanvasStore();
|
|
1581
|
-
return useSyncExternalStore(
|
|
1582
|
-
(cb) => store.subscribe("interaction", cb),
|
|
1583
|
-
() => store.getInteractionState().pointer
|
|
1584
|
-
);
|
|
1585
|
-
}
|
|
1586
|
-
function useIsMoving() {
|
|
1587
|
-
const mode = useInteractionMode();
|
|
1588
|
-
return mode === "panning" || mode === "zooming" || mode === "dragging" || mode === "resizing" || mode === "rotating";
|
|
1589
|
-
}
|
|
1590
|
-
var EMPTY_DRAGGED = [];
|
|
1591
|
-
function useDraggedIds() {
|
|
1592
|
-
const store = useCanvasStore();
|
|
1593
|
-
return useSyncExternalStore(
|
|
1594
|
-
(cb) => store.subscribe("interaction", cb),
|
|
1595
|
-
() => {
|
|
1596
|
-
const state = store.getInteractionState();
|
|
1597
|
-
return state.draggedIds.length === 0 ? EMPTY_DRAGGED : state.draggedIds;
|
|
1598
|
-
}
|
|
1599
|
-
);
|
|
1600
|
-
}
|
|
1601
|
-
function useIsPenActive() {
|
|
1602
|
-
const cursor = useCursor();
|
|
1603
|
-
return cursor?.pointerType === "pen";
|
|
1604
|
-
}
|
|
1605
1609
|
function useLocalPresence() {
|
|
1606
1610
|
const store = useCanvasStore();
|
|
1607
1611
|
return useSyncExternalStore(
|