@canvas-harness/react 0.0.1 → 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 +62 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +63 -54
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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
|
-
|
|
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;
|
|
@@ -981,6 +1032,7 @@ function CanvasSurface({
|
|
|
981
1032
|
onCreateDrag,
|
|
982
1033
|
arrowDefaults,
|
|
983
1034
|
background,
|
|
1035
|
+
selectionColor,
|
|
984
1036
|
renderCustomNodeView,
|
|
985
1037
|
children
|
|
986
1038
|
}) {
|
|
@@ -993,8 +1045,9 @@ function CanvasSurface({
|
|
|
993
1045
|
const toolRef = react.useRef(tool);
|
|
994
1046
|
toolRef.current = tool;
|
|
995
1047
|
const { w, h } = useResizeObserver(wrapRef);
|
|
996
|
-
usePanZoom(wrapRef, store);
|
|
1048
|
+
usePanZoom(wrapRef, store, tool);
|
|
997
1049
|
useInteractionGesture(wrapRef, store, tool);
|
|
1050
|
+
const interactionMode = useInteractionMode();
|
|
998
1051
|
useArrowTool(wrapRef, store, tool === "arrow", arrowDefaults);
|
|
999
1052
|
const { mountedIds, setMountedIds } = useOverlayHost();
|
|
1000
1053
|
const [camera, setCamera] = react.useState(() => store.getCamera());
|
|
@@ -1013,6 +1066,7 @@ function CanvasSurface({
|
|
|
1013
1066
|
width: w,
|
|
1014
1067
|
height: h,
|
|
1015
1068
|
background,
|
|
1069
|
+
selectionColor,
|
|
1016
1070
|
onOverlayChange: (ids) => setMountedIds(ids)
|
|
1017
1071
|
});
|
|
1018
1072
|
r.start();
|
|
@@ -1026,6 +1080,9 @@ function CanvasSurface({
|
|
|
1026
1080
|
react.useEffect(() => {
|
|
1027
1081
|
rendererRef.current?.setBackground(background);
|
|
1028
1082
|
}, [background]);
|
|
1083
|
+
react.useEffect(() => {
|
|
1084
|
+
if (selectionColor !== void 0) rendererRef.current?.setSelectionColor(selectionColor);
|
|
1085
|
+
}, [selectionColor]);
|
|
1029
1086
|
react.useEffect(() => {
|
|
1030
1087
|
const el = wrapRef.current;
|
|
1031
1088
|
if (!el) return;
|
|
@@ -1063,6 +1120,7 @@ function CanvasSurface({
|
|
|
1063
1120
|
el.removeEventListener("dblclick", onDoubleClickHandler);
|
|
1064
1121
|
};
|
|
1065
1122
|
}, [store, onClick, onDoubleClick]);
|
|
1123
|
+
const justCommittedRef = react.useRef(false);
|
|
1066
1124
|
react.useEffect(() => {
|
|
1067
1125
|
const el = wrapRef.current;
|
|
1068
1126
|
if (!el || !onCreateDrag) return;
|
|
@@ -1070,7 +1128,6 @@ function CanvasSurface({
|
|
|
1070
1128
|
let startScreen = null;
|
|
1071
1129
|
let activePointerId = null;
|
|
1072
1130
|
let committed = false;
|
|
1073
|
-
const justCommittedRef = { current: false };
|
|
1074
1131
|
const screenFromEvent = (e) => {
|
|
1075
1132
|
const rect = el.getBoundingClientRect();
|
|
1076
1133
|
return { x: e.clientX - rect.left, y: e.clientY - rect.top };
|
|
@@ -1201,7 +1258,7 @@ function CanvasSurface({
|
|
|
1201
1258
|
inset: 0,
|
|
1202
1259
|
background: "#f8fafc",
|
|
1203
1260
|
overflow: "hidden",
|
|
1204
|
-
cursor: tool === "select" ? "default" : "crosshair",
|
|
1261
|
+
cursor: tool === "pan" ? interactionMode === "panning" ? "grabbing" : "grab" : tool === "select" ? "default" : "crosshair",
|
|
1205
1262
|
touchAction: "none"
|
|
1206
1263
|
},
|
|
1207
1264
|
children: [
|
|
@@ -1551,54 +1608,6 @@ function useCamera() {
|
|
|
1551
1608
|
() => store.getCamera()
|
|
1552
1609
|
);
|
|
1553
1610
|
}
|
|
1554
|
-
function useInteractionState() {
|
|
1555
|
-
const store = useCanvasStore();
|
|
1556
|
-
return react.useSyncExternalStore(
|
|
1557
|
-
(cb) => store.subscribe("interaction", cb),
|
|
1558
|
-
() => store.getInteractionState()
|
|
1559
|
-
);
|
|
1560
|
-
}
|
|
1561
|
-
function useInteractionMode() {
|
|
1562
|
-
const store = useCanvasStore();
|
|
1563
|
-
return react.useSyncExternalStore(
|
|
1564
|
-
(cb) => {
|
|
1565
|
-
let lastMode = store.getInteractionState().mode;
|
|
1566
|
-
return store.subscribe("interaction", (state) => {
|
|
1567
|
-
if (state.mode !== lastMode) {
|
|
1568
|
-
lastMode = state.mode;
|
|
1569
|
-
cb();
|
|
1570
|
-
}
|
|
1571
|
-
});
|
|
1572
|
-
},
|
|
1573
|
-
() => store.getInteractionState().mode
|
|
1574
|
-
);
|
|
1575
|
-
}
|
|
1576
|
-
function useCursor() {
|
|
1577
|
-
const store = useCanvasStore();
|
|
1578
|
-
return react.useSyncExternalStore(
|
|
1579
|
-
(cb) => store.subscribe("interaction", cb),
|
|
1580
|
-
() => store.getInteractionState().pointer
|
|
1581
|
-
);
|
|
1582
|
-
}
|
|
1583
|
-
function useIsMoving() {
|
|
1584
|
-
const mode = useInteractionMode();
|
|
1585
|
-
return mode === "panning" || mode === "zooming" || mode === "dragging" || mode === "resizing" || mode === "rotating";
|
|
1586
|
-
}
|
|
1587
|
-
var EMPTY_DRAGGED = [];
|
|
1588
|
-
function useDraggedIds() {
|
|
1589
|
-
const store = useCanvasStore();
|
|
1590
|
-
return react.useSyncExternalStore(
|
|
1591
|
-
(cb) => store.subscribe("interaction", cb),
|
|
1592
|
-
() => {
|
|
1593
|
-
const state = store.getInteractionState();
|
|
1594
|
-
return state.draggedIds.length === 0 ? EMPTY_DRAGGED : state.draggedIds;
|
|
1595
|
-
}
|
|
1596
|
-
);
|
|
1597
|
-
}
|
|
1598
|
-
function useIsPenActive() {
|
|
1599
|
-
const cursor = useCursor();
|
|
1600
|
-
return cursor?.pointerType === "pen";
|
|
1601
|
-
}
|
|
1602
1611
|
function useLocalPresence() {
|
|
1603
1612
|
const store = useCanvasStore();
|
|
1604
1613
|
return react.useSyncExternalStore(
|