@uipath/apollo-react 6.24.0 → 6.26.0

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 (46) hide show
  1. package/dist/canvas/components/BaseCanvas/BaseCanvas.cjs +18 -2
  2. package/dist/canvas/components/BaseCanvas/BaseCanvas.d.ts.map +1 -1
  3. package/dist/canvas/components/BaseCanvas/BaseCanvas.hooks.cjs +33 -1
  4. package/dist/canvas/components/BaseCanvas/BaseCanvas.hooks.d.ts +2 -1
  5. package/dist/canvas/components/BaseCanvas/BaseCanvas.hooks.d.ts.map +1 -1
  6. package/dist/canvas/components/BaseCanvas/BaseCanvas.hooks.js +31 -2
  7. package/dist/canvas/components/BaseCanvas/BaseCanvas.js +19 -3
  8. package/dist/canvas/components/BaseCanvas/BaseCanvas.types.d.ts +1 -0
  9. package/dist/canvas/components/BaseCanvas/BaseCanvas.types.d.ts.map +1 -1
  10. package/dist/canvas/components/BaseCanvas/CanvasProviders.cjs +10 -6
  11. package/dist/canvas/components/BaseCanvas/CanvasProviders.d.ts +2 -1
  12. package/dist/canvas/components/BaseCanvas/CanvasProviders.d.ts.map +1 -1
  13. package/dist/canvas/components/BaseCanvas/CanvasProviders.js +10 -6
  14. package/dist/canvas/components/BaseCanvas/ConnectedHandlesContext.cjs +4 -11
  15. package/dist/canvas/components/BaseCanvas/ConnectedHandlesContext.d.ts.map +1 -1
  16. package/dist/canvas/components/BaseCanvas/ConnectedHandlesContext.js +1 -8
  17. package/dist/canvas/components/BaseCanvas/ReadOnlyNodesContext.cjs +111 -0
  18. package/dist/canvas/components/BaseCanvas/ReadOnlyNodesContext.d.ts +7 -0
  19. package/dist/canvas/components/BaseCanvas/ReadOnlyNodesContext.d.ts.map +1 -0
  20. package/dist/canvas/components/BaseCanvas/ReadOnlyNodesContext.js +71 -0
  21. package/dist/canvas/components/BaseCanvas/index.cjs +72 -19
  22. package/dist/canvas/components/BaseCanvas/index.d.ts +2 -1
  23. package/dist/canvas/components/BaseCanvas/index.d.ts.map +1 -1
  24. package/dist/canvas/components/BaseCanvas/index.js +3 -2
  25. package/dist/canvas/components/BaseCanvas/set-utils.cjs +46 -0
  26. package/dist/canvas/components/BaseCanvas/set-utils.d.ts +3 -0
  27. package/dist/canvas/components/BaseCanvas/set-utils.d.ts.map +1 -0
  28. package/dist/canvas/components/BaseCanvas/set-utils.js +9 -0
  29. package/dist/canvas/components/BaseNode/BaseNode.cjs +32 -10
  30. package/dist/canvas/components/BaseNode/BaseNode.d.ts.map +1 -1
  31. package/dist/canvas/components/BaseNode/BaseNode.js +32 -10
  32. package/dist/canvas/components/BaseNode/NodeLabel.cjs +17 -11
  33. package/dist/canvas/components/BaseNode/NodeLabel.d.ts +2 -1
  34. package/dist/canvas/components/BaseNode/NodeLabel.d.ts.map +1 -1
  35. package/dist/canvas/components/BaseNode/NodeLabel.js +17 -11
  36. package/dist/canvas/components/Toolbar/shared/ToolbarButton.cjs +28 -23
  37. package/dist/canvas/components/Toolbar/shared/ToolbarButton.d.ts.map +1 -1
  38. package/dist/canvas/components/Toolbar/shared/ToolbarButton.js +28 -23
  39. package/dist/canvas/hooks/useIsomorphicLayoutEffect.cjs +37 -0
  40. package/dist/canvas/hooks/useIsomorphicLayoutEffect.d.ts +3 -0
  41. package/dist/canvas/hooks/useIsomorphicLayoutEffect.d.ts.map +1 -0
  42. package/dist/canvas/hooks/useIsomorphicLayoutEffect.js +3 -0
  43. package/dist/canvas/hooks/useLatestRef.cjs +2 -2
  44. package/dist/canvas/hooks/useLatestRef.d.ts.map +1 -1
  45. package/dist/canvas/hooks/useLatestRef.js +2 -2
  46. package/package.json +3 -3
@@ -35,12 +35,26 @@ const external_BaseCanvas_hooks_cjs_namespaceObject = require("./BaseCanvas.hook
35
35
  const external_CanvasBackground_cjs_namespaceObject = require("./CanvasBackground.cjs");
36
36
  const external_CanvasProviders_cjs_namespaceObject = require("./CanvasProviders.cjs");
37
37
  const external_PanShortcutTeachingUI_cjs_namespaceObject = require("./PanShortcutTeachingUI.cjs");
38
+ const external_ReadOnlyNodesContext_cjs_namespaceObject = require("./ReadOnlyNodesContext.cjs");
38
39
  const BaseCanvasInnerComponent = (props)=>{
39
40
  const { innerRef, fitViewOptions: fitViewOptionsProps, ...canvasProps } = props;
40
41
  const fitViewOptions = fitViewOptionsProps ?? external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.fitViewOptions;
41
- const { nodes = [], edges = [], nodeTypes, edgeTypes, children, mode = 'view', showBackground = true, backgroundColor = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.background.color, backgroundSecondaryColor = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.background.bgColor, backgroundVariant = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.background.variant, backgroundGap = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.background.gap, backgroundSize = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.background.size, isDarkMode, locale, minZoom = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.zoom.min, maxZoom = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.zoom.max, defaultViewport = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.defaultViewport, defaultEdgeOptions = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.edge, stickyNoteOptions, onNodesChange, onEdgesChange, onConnect, onConnectStart, onConnectEnd, onNodeClick, onNodeDragStart, onNodeDrag, onNodeDragStop, onPaneClick, onInit, onSelectionChange, proOptions = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.pro, connectionMode = react_cjs_namespaceObject.ConnectionMode.Loose, connectionLineComponent, connectionLineStyle, deleteKeyCode = null, selectNodesOnDrag = true, nodesDraggable = true, nodesConnectable = true, elementsSelectable = true, onlyRenderVisibleElements = true, zoomOnDoubleClick = true, snapToGrid = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.snapToGrid, snapGrid = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.snapGrid, initialAutoLayout, maintainNodesInView, onToolbarAction, breakpoints, panShortcutTeachingUIMessage = 'Hold Space and drag to pan around the canvas!', ...reactFlowProps } = canvasProps;
42
+ const { nodes = [], edges = [], nodeTypes, edgeTypes, children, mode = 'view', readOnlyNodeIds, showBackground = true, backgroundColor = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.background.color, backgroundSecondaryColor = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.background.bgColor, backgroundVariant = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.background.variant, backgroundGap = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.background.gap, backgroundSize = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.background.size, isDarkMode, locale, minZoom = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.zoom.min, maxZoom = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.zoom.max, defaultViewport = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.defaultViewport, defaultEdgeOptions = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.edge, stickyNoteOptions, onNodesChange, onEdgesChange, onConnect, onConnectStart, onConnectEnd, onNodeClick, onNodeDragStart, onNodeDrag, onNodeDragStop, onPaneClick, onInit, onSelectionChange, onBeforeDelete, proOptions = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.pro, connectionMode = react_cjs_namespaceObject.ConnectionMode.Loose, connectionLineComponent, connectionLineStyle, deleteKeyCode = null, selectNodesOnDrag = true, nodesDraggable = true, nodesConnectable = true, elementsSelectable = true, onlyRenderVisibleElements = true, zoomOnDoubleClick = true, snapToGrid = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.snapToGrid, snapGrid = external_BaseCanvas_constants_cjs_namespaceObject.BASE_CANVAS_DEFAULTS.snapGrid, initialAutoLayout, maintainNodesInView, onToolbarAction, breakpoints, panShortcutTeachingUIMessage = 'Hold Space and drag to pan around the canvas!', ...reactFlowProps } = canvasProps;
42
43
  const isInteractive = 'readonly' !== mode;
43
44
  const isDesignMode = 'design' === mode;
45
+ const stableReadOnlyNodeIds = (0, external_ReadOnlyNodesContext_cjs_namespaceObject.useStableNodeIdSet)(readOnlyNodeIds);
46
+ const guardedBeforeDelete = (0, external_BaseCanvas_hooks_cjs_namespaceObject.useReadOnlyBeforeDelete)(stableReadOnlyNodeIds, onBeforeDelete);
47
+ const handleNodesChange = (0, external_react_namespaceObject.useMemo)(()=>{
48
+ if (!onNodesChange || 0 === stableReadOnlyNodeIds.size) return onNodesChange;
49
+ const guarded = (changes)=>{
50
+ const allowed = changes.filter((change)=>!('remove' === change.type && stableReadOnlyNodeIds.has(change.id)));
51
+ if (allowed.length > 0) onNodesChange(allowed);
52
+ };
53
+ return guarded;
54
+ }, [
55
+ onNodesChange,
56
+ stableReadOnlyNodeIds
57
+ ]);
44
58
  const [reactFlowInstance, setReactFlowInstance] = (0, external_react_namespaceObject.useState)();
45
59
  const { isReady } = (0, external_BaseCanvas_hooks_cjs_namespaceObject.useAutoLayout)(nodes, initialAutoLayout, fitViewOptions);
46
60
  const { ensureNodesInView, ensureAllNodesInView, centerNode } = (0, external_BaseCanvas_hooks_cjs_namespaceObject.useEnsureNodesInView)();
@@ -76,6 +90,7 @@ const BaseCanvasInnerComponent = (props)=>{
76
90
  isDarkMode: isDarkMode,
77
91
  locale: locale,
78
92
  stickyNoteOptions: stickyNoteOptions,
93
+ readOnlyNodeIds: stableReadOnlyNodeIds,
79
94
  children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(react_cjs_namespaceObject.ReactFlow, {
80
95
  ...reactFlowProps,
81
96
  colorMode: '',
@@ -105,8 +120,9 @@ const BaseCanvasInnerComponent = (props)=>{
105
120
  zoomOnDoubleClick: isInteractive && zoomOnDoubleClick,
106
121
  panOnDrag: isInteractive ? external_BaseCanvas_constants_cjs_namespaceObject.PAN_ON_DRAG : false,
107
122
  onInit: handleInit,
108
- onNodesChange: isInteractive ? onNodesChange : void 0,
123
+ onNodesChange: isInteractive ? handleNodesChange : void 0,
109
124
  onEdgesChange: isInteractive ? onEdgesChange : void 0,
125
+ onBeforeDelete: guardedBeforeDelete,
110
126
  onConnect: isDesignMode ? onConnect : void 0,
111
127
  onConnectStart: isDesignMode ? onConnectStart : void 0,
112
128
  onConnectEnd: isDesignMode ? onConnectEnd : void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"BaseCanvas.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/BaseCanvas/BaseCanvas.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,IAAI,EACJ,IAAI,EAEL,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAIL,KAAK,YAAY,EAKlB,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAgNzE,eAAO,MAAM,UAAU,EAKjB,CAAC,QAAQ,SAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,SAAS,IAAI,GAAG,IAAI,EAC/D,KAAK,EAAE,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG;IAC3C,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;CACpD,KACE,YAAY,CAAC"}
1
+ {"version":3,"file":"BaseCanvas.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/BaseCanvas/BaseCanvas.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,IAAI,EACJ,IAAI,EAEL,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAIL,KAAK,YAAY,EAKlB,MAAM,OAAO,CAAC;AASf,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAqOzE,eAAO,MAAM,UAAU,EAKjB,CAAC,QAAQ,SAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,SAAS,IAAI,GAAG,IAAI,EAC/D,KAAK,EAAE,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG;IAC3C,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;CACpD,KACE,YAAY,CAAC"}
@@ -27,6 +27,7 @@ __webpack_require__.d(__webpack_exports__, {
27
27
  useAutoLayout: ()=>useAutoLayout,
28
28
  useMaintainNodesInView: ()=>useMaintainNodesInView,
29
29
  useEnsureNodesInView: ()=>useEnsureNodesInView,
30
+ useReadOnlyBeforeDelete: ()=>useReadOnlyBeforeDelete,
30
31
  useFitView: ()=>useFitView
31
32
  });
32
33
  const react_cjs_namespaceObject = require("../../xyflow/react.cjs");
@@ -237,15 +238,46 @@ const useMaintainNodesInView = (nodeIds, fitViewOptions)=>{
237
238
  fitViewOptions
238
239
  ]);
239
240
  };
241
+ function useReadOnlyBeforeDelete(readOnlyNodeIds, onBeforeDelete) {
242
+ return (0, external_react_namespaceObject.useMemo)(()=>{
243
+ if (0 === readOnlyNodeIds.size) return onBeforeDelete;
244
+ return async ({ nodes, edges })=>{
245
+ const upstream = onBeforeDelete ? await onBeforeDelete({
246
+ nodes,
247
+ edges
248
+ }) : true;
249
+ if (false === upstream) return false;
250
+ const candidate = true === upstream ? {
251
+ nodes,
252
+ edges
253
+ } : upstream;
254
+ const vetoedNodeIds = new Set();
255
+ const deletedNodeIds = new Set();
256
+ for (const node of candidate.nodes)(readOnlyNodeIds.has(node.id) ? vetoedNodeIds : deletedNodeIds).add(node.id);
257
+ if (0 === vetoedNodeIds.size) return candidate;
258
+ const touchesVetoedNode = (edge)=>vetoedNodeIds.has(edge.source) || vetoedNodeIds.has(edge.target);
259
+ const touchesDeletedNode = (edge)=>deletedNodeIds.has(edge.source) || deletedNodeIds.has(edge.target);
260
+ return {
261
+ nodes: candidate.nodes.filter((node)=>!vetoedNodeIds.has(node.id)),
262
+ edges: candidate.edges.filter((edge)=>!touchesVetoedNode(edge) || touchesDeletedNode(edge))
263
+ };
264
+ };
265
+ }, [
266
+ readOnlyNodeIds,
267
+ onBeforeDelete
268
+ ]);
269
+ }
240
270
  exports.useAutoLayout = __webpack_exports__.useAutoLayout;
241
271
  exports.useEnsureNodesInView = __webpack_exports__.useEnsureNodesInView;
242
272
  exports.useFitView = __webpack_exports__.useFitView;
243
273
  exports.useMaintainNodesInView = __webpack_exports__.useMaintainNodesInView;
274
+ exports.useReadOnlyBeforeDelete = __webpack_exports__.useReadOnlyBeforeDelete;
244
275
  for(var __rspack_i in __webpack_exports__)if (-1 === [
245
276
  "useAutoLayout",
246
277
  "useEnsureNodesInView",
247
278
  "useFitView",
248
- "useMaintainNodesInView"
279
+ "useMaintainNodesInView",
280
+ "useReadOnlyBeforeDelete"
249
281
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
250
282
  Object.defineProperty(exports, '__esModule', {
251
283
  value: true
@@ -1,4 +1,4 @@
1
- import type { Node } from '../../xyflow/react.ts';
1
+ import type { Edge, Node, OnBeforeDelete } from '../../xyflow/react.ts';
2
2
  import type { BaseCanvasFitViewOptions, EnsureNodesInViewOptions } from './BaseCanvas.types';
3
3
  export declare const useAutoLayout: (nodes: Node[] | undefined, initialAutoLayout?: () => Promise<void> | void, fitViewOptions?: BaseCanvasFitViewOptions) => {
4
4
  isReady: boolean;
@@ -12,4 +12,5 @@ export declare const useEnsureNodesInView: () => {
12
12
  centerNode: (nodeId: string, options?: EnsureNodesInViewOptions) => void;
13
13
  };
14
14
  export declare const useMaintainNodesInView: (nodeIds?: string[], fitViewOptions?: BaseCanvasFitViewOptions) => void;
15
+ export declare function useReadOnlyBeforeDelete<NodeType extends Node, EdgeType extends Edge>(readOnlyNodeIds: ReadonlySet<string>, onBeforeDelete: OnBeforeDelete<NodeType, EdgeType> | undefined): OnBeforeDelete<NodeType, EdgeType> | undefined;
15
16
  //# sourceMappingURL=BaseCanvas.hooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BaseCanvas.hooks.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/BaseCanvas/BaseCanvas.hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0CAA0C,CAAC;AAIrE,OAAO,KAAK,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAqB7F,eAAO,MAAM,aAAa,GACxB,OAAO,IAAI,EAAE,GAAG,SAAS,EACzB,oBAAoB,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,EAC9C,iBAAiB,wBAAwB;;CA+E1C,CAAC;AAEF,eAAO,MAAM,UAAU,GACrB,QAAQ,IAAI,EAAE,EACd,QAAQ,MAAM,EACd,iBAAiB,wBAAwB;;CAgC1C,CAAC;AAEF,eAAO,MAAM,oBAAoB;iCAInB,MAAM,EAAE,YAAY,wBAAwB;qCA4B3C,wBAAwB;yBAqB1B,MAAM,YAAY,wBAAwB;CAgCtD,CAAC;AAqCF,eAAO,MAAM,sBAAsB,GACjC,UAAU,MAAM,EAAE,EAClB,iBAAiB,wBAAwB,SAuE1C,CAAC"}
1
+ {"version":3,"file":"BaseCanvas.hooks.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/BaseCanvas/BaseCanvas.hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAI3F,OAAO,KAAK,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAqB7F,eAAO,MAAM,aAAa,GACxB,OAAO,IAAI,EAAE,GAAG,SAAS,EACzB,oBAAoB,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,EAC9C,iBAAiB,wBAAwB;;CA+E1C,CAAC;AAEF,eAAO,MAAM,UAAU,GACrB,QAAQ,IAAI,EAAE,EACd,QAAQ,MAAM,EACd,iBAAiB,wBAAwB;;CAgC1C,CAAC;AAEF,eAAO,MAAM,oBAAoB;iCAInB,MAAM,EAAE,YAAY,wBAAwB;qCA4B3C,wBAAwB;yBAqB1B,MAAM,YAAY,wBAAwB;CAgCtD,CAAC;AAqCF,eAAO,MAAM,sBAAsB,GACjC,UAAU,MAAM,EAAE,EAClB,iBAAiB,wBAAwB,SAuE1C,CAAC;AAiBF,wBAAgB,uBAAuB,CAAC,QAAQ,SAAS,IAAI,EAAE,QAAQ,SAAS,IAAI,EAClF,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,EACpC,cAAc,EAAE,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,SAAS,GAC7D,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,SAAS,CA+BhD"}
@@ -1,5 +1,5 @@
1
1
  import { useReactFlow, useStoreApi } from "../../xyflow/react.js";
2
- import { useCallback, useEffect, useRef, useState } from "react";
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
3
3
  import { BASE_CANVAS_DEFAULTS, FIT_VIEW_DELAY_MS } from "./BaseCanvas.constants.js";
4
4
  const waitForNodeMeasurements = (getNodes)=>new Promise((resolve)=>{
5
5
  const startTime = Date.now();
@@ -206,4 +206,33 @@ const useMaintainNodesInView = (nodeIds, fitViewOptions)=>{
206
206
  fitViewOptions
207
207
  ]);
208
208
  };
209
- export { useAutoLayout, useEnsureNodesInView, useFitView, useMaintainNodesInView };
209
+ function useReadOnlyBeforeDelete(readOnlyNodeIds, onBeforeDelete) {
210
+ return useMemo(()=>{
211
+ if (0 === readOnlyNodeIds.size) return onBeforeDelete;
212
+ return async ({ nodes, edges })=>{
213
+ const upstream = onBeforeDelete ? await onBeforeDelete({
214
+ nodes,
215
+ edges
216
+ }) : true;
217
+ if (false === upstream) return false;
218
+ const candidate = true === upstream ? {
219
+ nodes,
220
+ edges
221
+ } : upstream;
222
+ const vetoedNodeIds = new Set();
223
+ const deletedNodeIds = new Set();
224
+ for (const node of candidate.nodes)(readOnlyNodeIds.has(node.id) ? vetoedNodeIds : deletedNodeIds).add(node.id);
225
+ if (0 === vetoedNodeIds.size) return candidate;
226
+ const touchesVetoedNode = (edge)=>vetoedNodeIds.has(edge.source) || vetoedNodeIds.has(edge.target);
227
+ const touchesDeletedNode = (edge)=>deletedNodeIds.has(edge.source) || deletedNodeIds.has(edge.target);
228
+ return {
229
+ nodes: candidate.nodes.filter((node)=>!vetoedNodeIds.has(node.id)),
230
+ edges: candidate.edges.filter((edge)=>!touchesVetoedNode(edge) || touchesDeletedNode(edge))
231
+ };
232
+ };
233
+ }, [
234
+ readOnlyNodeIds,
235
+ onBeforeDelete
236
+ ]);
237
+ }
238
+ export { useAutoLayout, useEnsureNodesInView, useFitView, useMaintainNodesInView, useReadOnlyBeforeDelete };
@@ -3,16 +3,30 @@ import { ConnectionMode, ReactFlow } from "../../xyflow/react.js";
3
3
  import { forwardRef, memo, useCallback, useImperativeHandle, useMemo, useState } from "react";
4
4
  import { useToolbarActionStore } from "../../hooks/ToolbarActionContext.js";
5
5
  import { BASE_CANVAS_DEFAULTS, PAN_ON_DRAG } from "./BaseCanvas.constants.js";
6
- import { useAutoLayout, useEnsureNodesInView, useMaintainNodesInView } from "./BaseCanvas.hooks.js";
6
+ import { useAutoLayout, useEnsureNodesInView, useMaintainNodesInView, useReadOnlyBeforeDelete } from "./BaseCanvas.hooks.js";
7
7
  import { CanvasBackground } from "./CanvasBackground.js";
8
8
  import { CanvasProviders } from "./CanvasProviders.js";
9
9
  import { PanShortcutTeachingUI } from "./PanShortcutTeachingUI.js";
10
+ import { useStableNodeIdSet } from "./ReadOnlyNodesContext.js";
10
11
  const BaseCanvasInnerComponent = (props)=>{
11
12
  const { innerRef, fitViewOptions: fitViewOptionsProps, ...canvasProps } = props;
12
13
  const fitViewOptions = fitViewOptionsProps ?? BASE_CANVAS_DEFAULTS.fitViewOptions;
13
- const { nodes = [], edges = [], nodeTypes, edgeTypes, children, mode = 'view', showBackground = true, backgroundColor = BASE_CANVAS_DEFAULTS.background.color, backgroundSecondaryColor = BASE_CANVAS_DEFAULTS.background.bgColor, backgroundVariant = BASE_CANVAS_DEFAULTS.background.variant, backgroundGap = BASE_CANVAS_DEFAULTS.background.gap, backgroundSize = BASE_CANVAS_DEFAULTS.background.size, isDarkMode, locale, minZoom = BASE_CANVAS_DEFAULTS.zoom.min, maxZoom = BASE_CANVAS_DEFAULTS.zoom.max, defaultViewport = BASE_CANVAS_DEFAULTS.defaultViewport, defaultEdgeOptions = BASE_CANVAS_DEFAULTS.edge, stickyNoteOptions, onNodesChange, onEdgesChange, onConnect, onConnectStart, onConnectEnd, onNodeClick, onNodeDragStart, onNodeDrag, onNodeDragStop, onPaneClick, onInit, onSelectionChange, proOptions = BASE_CANVAS_DEFAULTS.pro, connectionMode = ConnectionMode.Loose, connectionLineComponent, connectionLineStyle, deleteKeyCode = null, selectNodesOnDrag = true, nodesDraggable = true, nodesConnectable = true, elementsSelectable = true, onlyRenderVisibleElements = true, zoomOnDoubleClick = true, snapToGrid = BASE_CANVAS_DEFAULTS.snapToGrid, snapGrid = BASE_CANVAS_DEFAULTS.snapGrid, initialAutoLayout, maintainNodesInView, onToolbarAction, breakpoints, panShortcutTeachingUIMessage = 'Hold Space and drag to pan around the canvas!', ...reactFlowProps } = canvasProps;
14
+ const { nodes = [], edges = [], nodeTypes, edgeTypes, children, mode = 'view', readOnlyNodeIds, showBackground = true, backgroundColor = BASE_CANVAS_DEFAULTS.background.color, backgroundSecondaryColor = BASE_CANVAS_DEFAULTS.background.bgColor, backgroundVariant = BASE_CANVAS_DEFAULTS.background.variant, backgroundGap = BASE_CANVAS_DEFAULTS.background.gap, backgroundSize = BASE_CANVAS_DEFAULTS.background.size, isDarkMode, locale, minZoom = BASE_CANVAS_DEFAULTS.zoom.min, maxZoom = BASE_CANVAS_DEFAULTS.zoom.max, defaultViewport = BASE_CANVAS_DEFAULTS.defaultViewport, defaultEdgeOptions = BASE_CANVAS_DEFAULTS.edge, stickyNoteOptions, onNodesChange, onEdgesChange, onConnect, onConnectStart, onConnectEnd, onNodeClick, onNodeDragStart, onNodeDrag, onNodeDragStop, onPaneClick, onInit, onSelectionChange, onBeforeDelete, proOptions = BASE_CANVAS_DEFAULTS.pro, connectionMode = ConnectionMode.Loose, connectionLineComponent, connectionLineStyle, deleteKeyCode = null, selectNodesOnDrag = true, nodesDraggable = true, nodesConnectable = true, elementsSelectable = true, onlyRenderVisibleElements = true, zoomOnDoubleClick = true, snapToGrid = BASE_CANVAS_DEFAULTS.snapToGrid, snapGrid = BASE_CANVAS_DEFAULTS.snapGrid, initialAutoLayout, maintainNodesInView, onToolbarAction, breakpoints, panShortcutTeachingUIMessage = 'Hold Space and drag to pan around the canvas!', ...reactFlowProps } = canvasProps;
14
15
  const isInteractive = 'readonly' !== mode;
15
16
  const isDesignMode = 'design' === mode;
17
+ const stableReadOnlyNodeIds = useStableNodeIdSet(readOnlyNodeIds);
18
+ const guardedBeforeDelete = useReadOnlyBeforeDelete(stableReadOnlyNodeIds, onBeforeDelete);
19
+ const handleNodesChange = useMemo(()=>{
20
+ if (!onNodesChange || 0 === stableReadOnlyNodeIds.size) return onNodesChange;
21
+ const guarded = (changes)=>{
22
+ const allowed = changes.filter((change)=>!('remove' === change.type && stableReadOnlyNodeIds.has(change.id)));
23
+ if (allowed.length > 0) onNodesChange(allowed);
24
+ };
25
+ return guarded;
26
+ }, [
27
+ onNodesChange,
28
+ stableReadOnlyNodeIds
29
+ ]);
16
30
  const [reactFlowInstance, setReactFlowInstance] = useState();
17
31
  const { isReady } = useAutoLayout(nodes, initialAutoLayout, fitViewOptions);
18
32
  const { ensureNodesInView, ensureAllNodesInView, centerNode } = useEnsureNodesInView();
@@ -48,6 +62,7 @@ const BaseCanvasInnerComponent = (props)=>{
48
62
  isDarkMode: isDarkMode,
49
63
  locale: locale,
50
64
  stickyNoteOptions: stickyNoteOptions,
65
+ readOnlyNodeIds: stableReadOnlyNodeIds,
51
66
  children: /*#__PURE__*/ jsxs(ReactFlow, {
52
67
  ...reactFlowProps,
53
68
  colorMode: '',
@@ -77,8 +92,9 @@ const BaseCanvasInnerComponent = (props)=>{
77
92
  zoomOnDoubleClick: isInteractive && zoomOnDoubleClick,
78
93
  panOnDrag: isInteractive ? PAN_ON_DRAG : false,
79
94
  onInit: handleInit,
80
- onNodesChange: isInteractive ? onNodesChange : void 0,
95
+ onNodesChange: isInteractive ? handleNodesChange : void 0,
81
96
  onEdgesChange: isInteractive ? onEdgesChange : void 0,
97
+ onBeforeDelete: guardedBeforeDelete,
82
98
  onConnect: isDesignMode ? onConnect : void 0,
83
99
  onConnectStart: isDesignMode ? onConnectStart : void 0,
84
100
  onConnectEnd: isDesignMode ? onConnectEnd : void 0,
@@ -16,6 +16,7 @@ export interface BaseCanvasFitViewOptions {
16
16
  }
17
17
  export interface BaseCanvasProps<NodeType extends Node = Node, EdgeType extends Edge = Edge> extends ReactFlowProps<NodeType, EdgeType> {
18
18
  mode?: 'design' | 'readonly' | 'view';
19
+ readOnlyNodeIds?: ReadonlySet<string> | readonly string[];
19
20
  stickyNoteOptions?: StickyNoteCanvasOptions;
20
21
  children?: ReactNode;
21
22
  showBackground?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"BaseCanvas.types.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/BaseCanvas/BaseCanvas.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,IAAI,EACJ,IAAI,EACJ,iBAAiB,EACjB,cAAc,EACf,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAMtF,MAAM,WAAW,wBAAwB;IAOvC,OAAO,CAAC,EACJ,MAAM,GACN;QACE,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IAON,QAAQ,CAAC,EAAE,MAAM,CAAC;IAMlB,OAAO,CAAC,EAAE,MAAM,CAAC;IAMjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AASD,MAAM,WAAW,eAAe,CAAC,QAAQ,SAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,SAAS,IAAI,GAAG,IAAI,CACzF,SAAQ,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAe1C,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;IAMtC,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;IAO5C,QAAQ,CAAC,EAAE,SAAS,CAAC;IAOrB,cAAc,CAAC,EAAE,OAAO,CAAC;IAKzB,eAAe,CAAC,EAAE,MAAM,CAAC;IAKzB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAOlC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IAOtC,aAAa,CAAC,EAAE,MAAM,CAAC;IAOvB,cAAc,CAAC,EAAE,MAAM,CAAC;IAcxB,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAkB/C,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAM/B,4BAA4B,CAAC,EAAE,MAAM,CAAC;IAUtC,cAAc,CAAC,EAAE,wBAAwB,CAAC;IAK1C,eAAe,CAAC,EAAE,oBAAoB,CAAC;IAMvC,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAW1B,UAAU,CAAC,EAAE,OAAO,CAAC;IAOrB,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAMD,MAAM,WAAW,wBAAwB;IAKvC,OAAO,CAAC,EAAE,MAAM,CAAC;IAMjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAMlB,OAAO,CAAC,EAAE,MAAM,CAAC;IAMjB,OAAO,CAAC,EAAE,MAAM,CAAC;IAOjB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AASD,MAAM,WAAW,aAAa,CAAC,QAAQ,SAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,SAAS,IAAI,GAAG,IAAI;IAgBvF,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAa/E,oBAAoB,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAiB/D,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAyBrE,SAAS,EAAE,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,SAAS,CAAC;CAC9D"}
1
+ {"version":3,"file":"BaseCanvas.types.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/BaseCanvas/BaseCanvas.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,IAAI,EACJ,IAAI,EACJ,iBAAiB,EACjB,cAAc,EACf,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAMtF,MAAM,WAAW,wBAAwB;IAOvC,OAAO,CAAC,EACJ,MAAM,GACN;QACE,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IAON,QAAQ,CAAC,EAAE,MAAM,CAAC;IAMlB,OAAO,CAAC,EAAE,MAAM,CAAC;IAMjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AASD,MAAM,WAAW,eAAe,CAAC,QAAQ,SAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,SAAS,IAAI,GAAG,IAAI,CACzF,SAAQ,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAe1C,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;IAmBtC,eAAe,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,SAAS,MAAM,EAAE,CAAC;IAM1D,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;IAO5C,QAAQ,CAAC,EAAE,SAAS,CAAC;IAOrB,cAAc,CAAC,EAAE,OAAO,CAAC;IAKzB,eAAe,CAAC,EAAE,MAAM,CAAC;IAKzB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAOlC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IAOtC,aAAa,CAAC,EAAE,MAAM,CAAC;IAOvB,cAAc,CAAC,EAAE,MAAM,CAAC;IAcxB,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAkB/C,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAM/B,4BAA4B,CAAC,EAAE,MAAM,CAAC;IAUtC,cAAc,CAAC,EAAE,wBAAwB,CAAC;IAK1C,eAAe,CAAC,EAAE,oBAAoB,CAAC;IAMvC,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAW1B,UAAU,CAAC,EAAE,OAAO,CAAC;IAOrB,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAMD,MAAM,WAAW,wBAAwB;IAKvC,OAAO,CAAC,EAAE,MAAM,CAAC;IAMjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAMlB,OAAO,CAAC,EAAE,MAAM,CAAC;IAMjB,OAAO,CAAC,EAAE,MAAM,CAAC;IAOjB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AASD,MAAM,WAAW,aAAa,CAAC,QAAQ,SAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,SAAS,IAAI,GAAG,IAAI;IAgBvF,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAa/E,oBAAoB,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAiB/D,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAyBrE,SAAS,EAAE,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,SAAS,CAAC;CAC9D"}
@@ -35,8 +35,9 @@ const StickyNoteCanvasOptionsContext_cjs_namespaceObject = require("../StickyNot
35
35
  const external_BaseCanvasModeProvider_cjs_namespaceObject = require("./BaseCanvasModeProvider.cjs");
36
36
  const external_CanvasThemeContext_cjs_namespaceObject = require("./CanvasThemeContext.cjs");
37
37
  const external_ConnectedHandlesContext_cjs_namespaceObject = require("./ConnectedHandlesContext.cjs");
38
+ const external_ReadOnlyNodesContext_cjs_namespaceObject = require("./ReadOnlyNodesContext.cjs");
38
39
  const external_SelectionStateContext_cjs_namespaceObject = require("./SelectionStateContext.cjs");
39
- function CanvasProviders({ nodes, edges, mode, isDarkMode, locale, stickyNoteOptions, children }) {
40
+ function CanvasProviders({ nodes, edges, mode, isDarkMode, locale, stickyNoteOptions, readOnlyNodeIds, children }) {
40
41
  return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(index_cjs_namespaceObject.ApI18nProvider, {
41
42
  component: "canvas",
42
43
  locale: locale,
@@ -51,11 +52,14 @@ function CanvasProviders({ nodes, edges, mode, isDarkMode, locale, stickyNoteOpt
51
52
  children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(crossings_index_cjs_namespaceObject.EdgeCrossingsProvider, {
52
53
  children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_BaseCanvasModeProvider_cjs_namespaceObject.BaseCanvasModeProvider, {
53
54
  mode: mode,
54
- children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(StickyNoteCanvasOptionsContext_cjs_namespaceObject.StickyNoteCanvasOptionsProvider, {
55
- options: stickyNoteOptions,
56
- children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_SelectionStateContext_cjs_namespaceObject.SelectionStateProvider, {
57
- nodes: nodes,
58
- children: children
55
+ children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_ReadOnlyNodesContext_cjs_namespaceObject.ReadOnlyNodesProvider, {
56
+ readOnlyNodeIds: readOnlyNodeIds,
57
+ children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(StickyNoteCanvasOptionsContext_cjs_namespaceObject.StickyNoteCanvasOptionsProvider, {
58
+ options: stickyNoteOptions,
59
+ children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_SelectionStateContext_cjs_namespaceObject.SelectionStateProvider, {
60
+ nodes: nodes,
61
+ children: children
62
+ })
59
63
  })
60
64
  })
61
65
  })
@@ -10,7 +10,8 @@ interface CanvasProvidersProps {
10
10
  isDarkMode?: boolean;
11
11
  locale?: BaseCanvasProps['locale'];
12
12
  stickyNoteOptions?: StickyNoteCanvasOptions;
13
+ readOnlyNodeIds?: ReadonlySet<string>;
13
14
  }
14
- export declare function CanvasProviders({ nodes, edges, mode, isDarkMode, locale, stickyNoteOptions, children, }: CanvasProvidersProps): import("react/jsx-runtime").JSX.Element;
15
+ export declare function CanvasProviders({ nodes, edges, mode, isDarkMode, locale, stickyNoteOptions, readOnlyNodeIds, children, }: CanvasProvidersProps): import("react/jsx-runtime").JSX.Element;
15
16
  export {};
16
17
  //# sourceMappingURL=CanvasProviders.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CanvasProviders.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/BaseCanvas/CanvasProviders.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,0CAA0C,CAAC;AAE3E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACtF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAM1D,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;IACnC,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;CAC7C;AAQD,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,KAAK,EACL,IAAI,EACJ,UAAU,EACV,MAAM,EACN,iBAAiB,EACjB,QAAQ,GACT,EAAE,oBAAoB,2CAoBtB"}
1
+ {"version":3,"file":"CanvasProviders.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/BaseCanvas/CanvasProviders.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,0CAA0C,CAAC;AAE3E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACtF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAO1D,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;IACnC,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;IAC5C,eAAe,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACvC;AAQD,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,KAAK,EACL,IAAI,EACJ,UAAU,EACV,MAAM,EACN,iBAAiB,EACjB,eAAe,EACf,QAAQ,GACT,EAAE,oBAAoB,2CAsBtB"}
@@ -7,8 +7,9 @@ import { StickyNoteCanvasOptionsProvider } from "../StickyNoteNode/StickyNoteCan
7
7
  import { BaseCanvasModeProvider } from "./BaseCanvasModeProvider.js";
8
8
  import { CanvasThemeProvider } from "./CanvasThemeContext.js";
9
9
  import { ConnectedHandlesProvider } from "./ConnectedHandlesContext.js";
10
+ import { ReadOnlyNodesProvider } from "./ReadOnlyNodesContext.js";
10
11
  import { SelectionStateProvider } from "./SelectionStateContext.js";
11
- function CanvasProviders({ nodes, edges, mode, isDarkMode, locale, stickyNoteOptions, children }) {
12
+ function CanvasProviders({ nodes, edges, mode, isDarkMode, locale, stickyNoteOptions, readOnlyNodeIds, children }) {
12
13
  return /*#__PURE__*/ jsx(ApI18nProvider, {
13
14
  component: "canvas",
14
15
  locale: locale,
@@ -23,11 +24,14 @@ function CanvasProviders({ nodes, edges, mode, isDarkMode, locale, stickyNoteOpt
23
24
  children: /*#__PURE__*/ jsx(EdgeCrossingsProvider, {
24
25
  children: /*#__PURE__*/ jsx(BaseCanvasModeProvider, {
25
26
  mode: mode,
26
- children: /*#__PURE__*/ jsx(StickyNoteCanvasOptionsProvider, {
27
- options: stickyNoteOptions,
28
- children: /*#__PURE__*/ jsx(SelectionStateProvider, {
29
- nodes: nodes,
30
- children: children
27
+ children: /*#__PURE__*/ jsx(ReadOnlyNodesProvider, {
28
+ readOnlyNodeIds: readOnlyNodeIds,
29
+ children: /*#__PURE__*/ jsx(StickyNoteCanvasOptionsProvider, {
30
+ options: stickyNoteOptions,
31
+ children: /*#__PURE__*/ jsx(SelectionStateProvider, {
32
+ nodes: nodes,
33
+ children: children
34
+ })
31
35
  })
32
36
  })
33
37
  })
@@ -29,7 +29,7 @@ __webpack_require__.d(__webpack_exports__, {
29
29
  });
30
30
  const jsx_runtime_namespaceObject = require("react/jsx-runtime");
31
31
  const external_react_namespaceObject = require("react");
32
- const EMPTY_SET = Object.freeze(new Set());
32
+ const external_set_utils_cjs_namespaceObject = require("./set-utils.cjs");
33
33
  class ConnectedHandlesStore {
34
34
  map = new Map();
35
35
  listeners = new Map();
@@ -46,7 +46,7 @@ class ConnectedHandlesStore {
46
46
  };
47
47
  }
48
48
  getSnapshot(nodeId) {
49
- return this.map.get(nodeId) ?? EMPTY_SET;
49
+ return this.map.get(nodeId) ?? external_set_utils_cjs_namespaceObject.EMPTY_SET;
50
50
  }
51
51
  update(edges) {
52
52
  const nextMap = buildConnectedHandlesMap(edges);
@@ -55,7 +55,7 @@ class ConnectedHandlesStore {
55
55
  const changedNodeIds = new Set();
56
56
  for (const [nodeId, nextSet] of nextMap){
57
57
  const prevSet = prevMap.get(nodeId);
58
- if (setsEqual(prevSet, nextSet)) finalMap.set(nodeId, prevSet);
58
+ if ((0, external_set_utils_cjs_namespaceObject.setsEqual)(prevSet, nextSet)) finalMap.set(nodeId, prevSet);
59
59
  else {
60
60
  finalMap.set(nodeId, nextSet);
61
61
  changedNodeIds.add(nodeId);
@@ -70,13 +70,6 @@ class ConnectedHandlesStore {
70
70
  }
71
71
  }
72
72
  }
73
- function setsEqual(a, b) {
74
- if (a === b) return true;
75
- if (!a || !b) return false;
76
- if (a.size !== b.size) return false;
77
- for (const value of a)if (!b.has(value)) return false;
78
- return true;
79
- }
80
73
  function buildConnectedHandlesMap(edges) {
81
74
  const map = new Map();
82
75
  for (const edge of edges){
@@ -122,7 +115,7 @@ function useConnectedHandles(nodeId) {
122
115
  store,
123
116
  nodeId
124
117
  ]);
125
- const getSnapshot = (0, external_react_namespaceObject.useCallback)(()=>store?.getSnapshot(nodeId) ?? EMPTY_SET, [
118
+ const getSnapshot = (0, external_react_namespaceObject.useCallback)(()=>store?.getSnapshot(nodeId) ?? external_set_utils_cjs_namespaceObject.EMPTY_SET, [
126
119
  store,
127
120
  nodeId
128
121
  ]);
@@ -1 +1 @@
1
- {"version":3,"file":"ConnectedHandlesContext.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/BaseCanvas/ConnectedHandlesContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0CAA0C,CAAC;AACrE,OAAO,EAEL,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AA6If,wBAAgB,wBAAwB,CAAC,EACvC,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;CACrB,2CAgBA;AAMD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAgBvE"}
1
+ {"version":3,"file":"ConnectedHandlesContext.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/BaseCanvas/ConnectedHandlesContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0CAA0C,CAAC;AACrE,OAAO,EAEL,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AA8Hf,wBAAgB,wBAAwB,CAAC,EACvC,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;CACrB,2CAgBA;AAMD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAgBvE"}
@@ -1,6 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { createContext, useCallback, useContext, useEffect, useRef, useSyncExternalStore } from "react";
3
- const EMPTY_SET = Object.freeze(new Set());
3
+ import { EMPTY_SET, setsEqual } from "./set-utils.js";
4
4
  class ConnectedHandlesStore {
5
5
  map = new Map();
6
6
  listeners = new Map();
@@ -41,13 +41,6 @@ class ConnectedHandlesStore {
41
41
  }
42
42
  }
43
43
  }
44
- function setsEqual(a, b) {
45
- if (a === b) return true;
46
- if (!a || !b) return false;
47
- if (a.size !== b.size) return false;
48
- for (const value of a)if (!b.has(value)) return false;
49
- return true;
50
- }
51
44
  function buildConnectedHandlesMap(edges) {
52
45
  const map = new Map();
53
46
  for (const edge of edges){
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ useIsNodeReadOnly: ()=>useIsNodeReadOnly,
28
+ ReadOnlyNodesProvider: ()=>ReadOnlyNodesProvider,
29
+ useStableNodeIdSet: ()=>useStableNodeIdSet
30
+ });
31
+ const jsx_runtime_namespaceObject = require("react/jsx-runtime");
32
+ const external_react_namespaceObject = require("react");
33
+ const useIsomorphicLayoutEffect_cjs_namespaceObject = require("../../hooks/useIsomorphicLayoutEffect.cjs");
34
+ const external_set_utils_cjs_namespaceObject = require("./set-utils.cjs");
35
+ class ReadOnlyNodesStore {
36
+ ids;
37
+ listeners = new Map();
38
+ constructor(initial = external_set_utils_cjs_namespaceObject.EMPTY_SET){
39
+ this.ids = 0 === initial.size ? external_set_utils_cjs_namespaceObject.EMPTY_SET : new Set(initial);
40
+ }
41
+ subscribe(nodeId, listener) {
42
+ let nodeListeners = this.listeners.get(nodeId);
43
+ if (!nodeListeners) {
44
+ nodeListeners = new Set();
45
+ this.listeners.set(nodeId, nodeListeners);
46
+ }
47
+ nodeListeners.add(listener);
48
+ return ()=>{
49
+ nodeListeners.delete(listener);
50
+ if (0 === nodeListeners.size) this.listeners.delete(nodeId);
51
+ };
52
+ }
53
+ isReadOnly(nodeId) {
54
+ return this.ids.has(nodeId);
55
+ }
56
+ update(next) {
57
+ const prev = this.ids;
58
+ if ((0, external_set_utils_cjs_namespaceObject.setsEqual)(prev, next)) return;
59
+ const changedNodeIds = new Set();
60
+ for (const id of next)if (!prev.has(id)) changedNodeIds.add(id);
61
+ for (const id of prev)if (!next.has(id)) changedNodeIds.add(id);
62
+ this.ids = 0 === next.size ? external_set_utils_cjs_namespaceObject.EMPTY_SET : new Set(next);
63
+ for (const nodeId of changedNodeIds){
64
+ const nodeListeners = this.listeners.get(nodeId);
65
+ if (nodeListeners) for (const listener of nodeListeners)listener();
66
+ }
67
+ }
68
+ }
69
+ const ReadOnlyNodesContext = /*#__PURE__*/ (0, external_react_namespaceObject.createContext)(null);
70
+ function useStableNodeIdSet(ids) {
71
+ const ref = (0, external_react_namespaceObject.useRef)(external_set_utils_cjs_namespaceObject.EMPTY_SET);
72
+ const next = void 0 === ids ? external_set_utils_cjs_namespaceObject.EMPTY_SET : ids instanceof Set ? ids : new Set(ids);
73
+ if (!(0, external_set_utils_cjs_namespaceObject.setsEqual)(ref.current, next)) ref.current = 0 === next.size ? external_set_utils_cjs_namespaceObject.EMPTY_SET : new Set(next);
74
+ return ref.current;
75
+ }
76
+ const ReadOnlyNodesProvider = ({ children, readOnlyNodeIds })=>{
77
+ const storeRef = (0, external_react_namespaceObject.useRef)(void 0);
78
+ if (!storeRef.current) storeRef.current = new ReadOnlyNodesStore(readOnlyNodeIds);
79
+ (0, useIsomorphicLayoutEffect_cjs_namespaceObject.useIsomorphicLayoutEffect)(()=>{
80
+ storeRef.current?.update(readOnlyNodeIds ?? external_set_utils_cjs_namespaceObject.EMPTY_SET);
81
+ }, [
82
+ readOnlyNodeIds
83
+ ]);
84
+ return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(ReadOnlyNodesContext.Provider, {
85
+ value: storeRef.current,
86
+ children: children
87
+ });
88
+ };
89
+ function useIsNodeReadOnly(nodeId) {
90
+ const store = (0, external_react_namespaceObject.useContext)(ReadOnlyNodesContext);
91
+ const subscribe = (0, external_react_namespaceObject.useCallback)((onStoreChange)=>store?.subscribe(nodeId, onStoreChange) ?? (()=>{}), [
92
+ store,
93
+ nodeId
94
+ ]);
95
+ const getSnapshot = (0, external_react_namespaceObject.useCallback)(()=>store?.isReadOnly(nodeId) ?? false, [
96
+ store,
97
+ nodeId
98
+ ]);
99
+ return (0, external_react_namespaceObject.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
100
+ }
101
+ exports.ReadOnlyNodesProvider = __webpack_exports__.ReadOnlyNodesProvider;
102
+ exports.useIsNodeReadOnly = __webpack_exports__.useIsNodeReadOnly;
103
+ exports.useStableNodeIdSet = __webpack_exports__.useStableNodeIdSet;
104
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
105
+ "ReadOnlyNodesProvider",
106
+ "useIsNodeReadOnly",
107
+ "useStableNodeIdSet"
108
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
109
+ Object.defineProperty(exports, '__esModule', {
110
+ value: true
111
+ });
@@ -0,0 +1,7 @@
1
+ import type React from 'react';
2
+ export declare function useStableNodeIdSet(ids: ReadonlySet<string> | readonly string[] | undefined): ReadonlySet<string>;
3
+ export declare const ReadOnlyNodesProvider: React.FC<React.PropsWithChildren<{
4
+ readOnlyNodeIds?: ReadonlySet<string>;
5
+ }>>;
6
+ export declare function useIsNodeReadOnly(nodeId: string): boolean;
7
+ //# sourceMappingURL=ReadOnlyNodesContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReadOnlyNodesContext.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/BaseCanvas/ReadOnlyNodesContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAuF/B,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,GACvD,WAAW,CAAC,MAAM,CAAC,CASrB;AAMD,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAC1C,KAAK,CAAC,iBAAiB,CAAC;IAAE,eAAe,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CAoBnE,CAAC;AAOF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAUzD"}
@@ -0,0 +1,71 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { createContext, useCallback, useContext, useRef, useSyncExternalStore } from "react";
3
+ import { useIsomorphicLayoutEffect } from "../../hooks/useIsomorphicLayoutEffect.js";
4
+ import { EMPTY_SET, setsEqual } from "./set-utils.js";
5
+ class ReadOnlyNodesStore {
6
+ ids;
7
+ listeners = new Map();
8
+ constructor(initial = EMPTY_SET){
9
+ this.ids = 0 === initial.size ? EMPTY_SET : new Set(initial);
10
+ }
11
+ subscribe(nodeId, listener) {
12
+ let nodeListeners = this.listeners.get(nodeId);
13
+ if (!nodeListeners) {
14
+ nodeListeners = new Set();
15
+ this.listeners.set(nodeId, nodeListeners);
16
+ }
17
+ nodeListeners.add(listener);
18
+ return ()=>{
19
+ nodeListeners.delete(listener);
20
+ if (0 === nodeListeners.size) this.listeners.delete(nodeId);
21
+ };
22
+ }
23
+ isReadOnly(nodeId) {
24
+ return this.ids.has(nodeId);
25
+ }
26
+ update(next) {
27
+ const prev = this.ids;
28
+ if (setsEqual(prev, next)) return;
29
+ const changedNodeIds = new Set();
30
+ for (const id of next)if (!prev.has(id)) changedNodeIds.add(id);
31
+ for (const id of prev)if (!next.has(id)) changedNodeIds.add(id);
32
+ this.ids = 0 === next.size ? EMPTY_SET : new Set(next);
33
+ for (const nodeId of changedNodeIds){
34
+ const nodeListeners = this.listeners.get(nodeId);
35
+ if (nodeListeners) for (const listener of nodeListeners)listener();
36
+ }
37
+ }
38
+ }
39
+ const ReadOnlyNodesContext = /*#__PURE__*/ createContext(null);
40
+ function useStableNodeIdSet(ids) {
41
+ const ref = useRef(EMPTY_SET);
42
+ const next = void 0 === ids ? EMPTY_SET : ids instanceof Set ? ids : new Set(ids);
43
+ if (!setsEqual(ref.current, next)) ref.current = 0 === next.size ? EMPTY_SET : new Set(next);
44
+ return ref.current;
45
+ }
46
+ const ReadOnlyNodesProvider = ({ children, readOnlyNodeIds })=>{
47
+ const storeRef = useRef(void 0);
48
+ if (!storeRef.current) storeRef.current = new ReadOnlyNodesStore(readOnlyNodeIds);
49
+ useIsomorphicLayoutEffect(()=>{
50
+ storeRef.current?.update(readOnlyNodeIds ?? EMPTY_SET);
51
+ }, [
52
+ readOnlyNodeIds
53
+ ]);
54
+ return /*#__PURE__*/ jsx(ReadOnlyNodesContext.Provider, {
55
+ value: storeRef.current,
56
+ children: children
57
+ });
58
+ };
59
+ function useIsNodeReadOnly(nodeId) {
60
+ const store = useContext(ReadOnlyNodesContext);
61
+ const subscribe = useCallback((onStoreChange)=>store?.subscribe(nodeId, onStoreChange) ?? (()=>{}), [
62
+ store,
63
+ nodeId
64
+ ]);
65
+ const getSnapshot = useCallback(()=>store?.isReadOnly(nodeId) ?? false, [
66
+ store,
67
+ nodeId
68
+ ]);
69
+ return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
70
+ }
71
+ export { ReadOnlyNodesProvider, useIsNodeReadOnly, useStableNodeIdSet };