react-cosmos-diagram 0.3.0 → 0.5.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 (100) hide show
  1. package/dist/esm/components/Background/LinePath.d.ts +8 -0
  2. package/dist/esm/components/Background/LinePath.d.ts.map +1 -0
  3. package/dist/esm/components/Background/index.d.ts +9 -0
  4. package/dist/esm/components/Background/index.d.ts.map +1 -0
  5. package/dist/esm/components/Background/type.d.ts +6 -0
  6. package/dist/esm/components/Background/type.d.ts.map +1 -0
  7. package/dist/esm/components/Node/NodeWrapper/index.d.ts +1 -1
  8. package/dist/esm/components/Node/NodeWrapper/index.d.ts.map +1 -1
  9. package/dist/esm/components/Node/NodeWrapper/type.d.ts +1 -1
  10. package/dist/esm/components/Node/NodeWrapper/type.d.ts.map +1 -1
  11. package/dist/esm/components/Node/type.d.ts +1 -0
  12. package/dist/esm/components/Node/type.d.ts.map +1 -1
  13. package/dist/esm/components/ReactDiagramProvider/type.d.ts +4 -2
  14. package/dist/esm/components/ReactDiagramProvider/type.d.ts.map +1 -1
  15. package/dist/esm/components/SelectionBox/index.d.ts.map +1 -1
  16. package/dist/esm/components/StoreUpdater/index.d.ts +2 -2
  17. package/dist/esm/components/StoreUpdater/index.d.ts.map +1 -1
  18. package/dist/esm/container/DragSelection/index.d.ts +0 -3
  19. package/dist/esm/container/DragSelection/index.d.ts.map +1 -1
  20. package/dist/esm/container/NodeRenderer/index.d.ts.map +1 -1
  21. package/dist/esm/container/Pane/index.d.ts.map +1 -1
  22. package/dist/esm/container/ReactDiagram/index.d.ts +2 -0
  23. package/dist/esm/container/ReactDiagram/index.d.ts.map +1 -1
  24. package/dist/esm/hooks/useDrag/index.d.ts.map +1 -1
  25. package/dist/esm/hooks/useDrag/type.d.ts +3 -10
  26. package/dist/esm/hooks/useDrag/type.d.ts.map +1 -1
  27. package/dist/esm/hooks/useDrag/utils.d.ts +7 -6
  28. package/dist/esm/hooks/useDrag/utils.d.ts.map +1 -1
  29. package/dist/esm/hooks/useGetPointerPosition.d.ts +14 -2
  30. package/dist/esm/hooks/useGetPointerPosition.d.ts.map +1 -1
  31. package/dist/esm/hooks/useNodesEdgesState/type.d.ts +6 -1
  32. package/dist/esm/hooks/useNodesEdgesState/type.d.ts.map +1 -1
  33. package/dist/esm/hooks/useUpdateIntersectionNodes/index.d.ts +6 -0
  34. package/dist/esm/hooks/useUpdateIntersectionNodes/index.d.ts.map +1 -0
  35. package/dist/esm/index.d.ts +1 -0
  36. package/dist/esm/index.d.ts.map +1 -1
  37. package/dist/esm/index.js +821 -620
  38. package/dist/esm/store/index.d.ts.map +1 -1
  39. package/dist/esm/store/initialState.d.ts.map +1 -1
  40. package/dist/esm/store/utils.d.ts +0 -12
  41. package/dist/esm/store/utils.d.ts.map +1 -1
  42. package/dist/esm/types/core.d.ts +2 -0
  43. package/dist/esm/types/core.d.ts.map +1 -1
  44. package/dist/esm/types/index.d.ts +1 -0
  45. package/dist/esm/types/index.d.ts.map +1 -1
  46. package/dist/esm/utils/changes.d.ts.map +1 -1
  47. package/dist/esm/utils/deepEqual.d.ts +2 -0
  48. package/dist/esm/utils/deepEqual.d.ts.map +1 -0
  49. package/dist/esm/utils/graph.d.ts.map +1 -1
  50. package/dist/style.css +5 -0
  51. package/dist/umd/components/Background/LinePath.d.ts +8 -0
  52. package/dist/umd/components/Background/LinePath.d.ts.map +1 -0
  53. package/dist/umd/components/Background/index.d.ts +9 -0
  54. package/dist/umd/components/Background/index.d.ts.map +1 -0
  55. package/dist/umd/components/Background/type.d.ts +6 -0
  56. package/dist/umd/components/Background/type.d.ts.map +1 -0
  57. package/dist/umd/components/Node/NodeWrapper/index.d.ts +1 -1
  58. package/dist/umd/components/Node/NodeWrapper/index.d.ts.map +1 -1
  59. package/dist/umd/components/Node/NodeWrapper/type.d.ts +1 -1
  60. package/dist/umd/components/Node/NodeWrapper/type.d.ts.map +1 -1
  61. package/dist/umd/components/Node/type.d.ts +1 -0
  62. package/dist/umd/components/Node/type.d.ts.map +1 -1
  63. package/dist/umd/components/ReactDiagramProvider/type.d.ts +4 -2
  64. package/dist/umd/components/ReactDiagramProvider/type.d.ts.map +1 -1
  65. package/dist/umd/components/SelectionBox/index.d.ts.map +1 -1
  66. package/dist/umd/components/StoreUpdater/index.d.ts +2 -2
  67. package/dist/umd/components/StoreUpdater/index.d.ts.map +1 -1
  68. package/dist/umd/container/DragSelection/index.d.ts +0 -3
  69. package/dist/umd/container/DragSelection/index.d.ts.map +1 -1
  70. package/dist/umd/container/NodeRenderer/index.d.ts.map +1 -1
  71. package/dist/umd/container/Pane/index.d.ts.map +1 -1
  72. package/dist/umd/container/ReactDiagram/index.d.ts +2 -0
  73. package/dist/umd/container/ReactDiagram/index.d.ts.map +1 -1
  74. package/dist/umd/hooks/useDrag/index.d.ts.map +1 -1
  75. package/dist/umd/hooks/useDrag/type.d.ts +3 -10
  76. package/dist/umd/hooks/useDrag/type.d.ts.map +1 -1
  77. package/dist/umd/hooks/useDrag/utils.d.ts +7 -6
  78. package/dist/umd/hooks/useDrag/utils.d.ts.map +1 -1
  79. package/dist/umd/hooks/useGetPointerPosition.d.ts +14 -2
  80. package/dist/umd/hooks/useGetPointerPosition.d.ts.map +1 -1
  81. package/dist/umd/hooks/useNodesEdgesState/type.d.ts +6 -1
  82. package/dist/umd/hooks/useNodesEdgesState/type.d.ts.map +1 -1
  83. package/dist/umd/hooks/useUpdateIntersectionNodes/index.d.ts +6 -0
  84. package/dist/umd/hooks/useUpdateIntersectionNodes/index.d.ts.map +1 -0
  85. package/dist/umd/index.d.ts +1 -0
  86. package/dist/umd/index.d.ts.map +1 -1
  87. package/dist/umd/index.js +1 -1
  88. package/dist/umd/store/index.d.ts.map +1 -1
  89. package/dist/umd/store/initialState.d.ts.map +1 -1
  90. package/dist/umd/store/utils.d.ts +0 -12
  91. package/dist/umd/store/utils.d.ts.map +1 -1
  92. package/dist/umd/types/core.d.ts +2 -0
  93. package/dist/umd/types/core.d.ts.map +1 -1
  94. package/dist/umd/types/index.d.ts +1 -0
  95. package/dist/umd/types/index.d.ts.map +1 -1
  96. package/dist/umd/utils/changes.d.ts.map +1 -1
  97. package/dist/umd/utils/deepEqual.d.ts +2 -0
  98. package/dist/umd/utils/deepEqual.d.ts.map +1 -0
  99. package/dist/umd/utils/graph.d.ts.map +1 -1
  100. package/package.json +7 -7
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { createContext, useContext, useMemo, useState, useEffect, useRef, memo, useCallback, forwardRef } from 'react';
2
+ import { createContext, useContext, useMemo, useState, useEffect, useRef, useCallback, memo, forwardRef } from 'react';
3
3
  import { useStore as useStore$1, createStore } from 'zustand';
4
4
  import { zoom, zoomIdentity } from 'd3-zoom';
5
5
  import { select } from 'd3-selection';
@@ -112,11 +112,11 @@ const getBoundsOfBoxes = (box1, box2) => ({
112
112
  const isMouseEvent = (event) => 'clientX' in event;
113
113
  const getEventPosition = (event, bounds) => {
114
114
  const isMouseTriggered = isMouseEvent(event);
115
- const evtX = isMouseTriggered ? event.clientX : event.touches?.[0].clientX;
116
- const evtY = isMouseTriggered ? event.clientY : event.touches?.[0].clientY;
115
+ const eventX = isMouseTriggered ? event.clientX : event.touches?.[0].clientX;
116
+ const eventY = isMouseTriggered ? event.clientY : event.touches?.[0].clientY;
117
117
  return {
118
- x: evtX - (bounds?.left ?? 0),
119
- y: evtY - (bounds?.top ?? 0),
118
+ x: eventX - (bounds?.left ?? 0),
119
+ y: eventY - (bounds?.top ?? 0),
120
120
  };
121
121
  };
122
122
  const calcAutoPanVelocity = (value, bound, radius, velocity) => {
@@ -149,10 +149,9 @@ const isViewChanged = (prevViewport, eventViewport) => {
149
149
  const { x, y, k } = eventViewport;
150
150
  return prevX !== x || prevY !== y || prevZoom !== k;
151
151
  };
152
- const selector$7 = (s) => ({
152
+ const selector$8 = (s) => ({
153
153
  d3Zoom: s.d3Zoom,
154
154
  d3Selection: s.d3Selection,
155
- elementsSelectable: s.elementsSelectable,
156
155
  });
157
156
  function Pane({ noPanClassName, panning, minZoom, maxZoom, defaultViewport, translateExtent, children, onMove, onMoveStart, onMoveEnd, }) {
158
157
  const store = useStoreApi();
@@ -161,7 +160,7 @@ function Pane({ noPanClassName, panning, minZoom, maxZoom, defaultViewport, tran
161
160
  const d3ZoomHandler = useRef();
162
161
  const prevTransform = useRef({ x: 0, y: 0, zoom: 0 });
163
162
  const timerId = useRef();
164
- const { d3Zoom, d3Selection } = useStore(selector$7, shallow);
163
+ const { d3Zoom, d3Selection } = useStore(selector$8, shallow);
165
164
  useEffect(() => {
166
165
  if (Pane.current) {
167
166
  const bbox = Pane.current.getBoundingClientRect();
@@ -269,9 +268,9 @@ function Pane({ noPanClassName, panning, minZoom, maxZoom, defaultViewport, tran
269
268
  return (jsx("div", { className: "react-diagram__pane react-diagram__container", ref: Pane, children: children }));
270
269
  }
271
270
 
272
- const selector$6 = (s) => `translate(${s.transform[0]}px,${s.transform[1]}px) scale(${s.transform[2]})`;
271
+ const selector$7 = (s) => `translate(${s.transform[0]}px,${s.transform[1]}px) scale(${s.transform[2]})`;
273
272
  function Viewport({ children }) {
274
- const transform = useStore(selector$6);
273
+ const transform = useStore(selector$7);
275
274
  return (jsx("div", { className: "react-diagram__viewport react-diagram__container", style: { transform }, children: children }));
276
275
  }
277
276
 
@@ -286,22 +285,92 @@ function DragBox({ rect }) {
286
285
  } }));
287
286
  }
288
287
 
289
- function SelectionBox({ rect, transform }) {
290
- const nodeRef = useRef(null);
291
- const { width, height, x, y } = rect;
292
- return (jsx("div", { className: cc([
293
- 'react-diagram__selection-box',
294
- 'react-diagram__container',
295
- ]), style: {
296
- transform,
297
- }, children: jsx("div", { ref: nodeRef, className: "react-diagram__selection-box-rect", tabIndex: -1, style: {
298
- width,
299
- height,
300
- top: y,
301
- left: x,
302
- } }) }));
288
+ function useGetPointerPosition() {
289
+ const store = useStoreApi();
290
+ const getPointerPosition = useCallback(({ sourceEvent }) => {
291
+ const { transform, gridStep, centerStep } = store.getState();
292
+ const x = sourceEvent.changedTouches
293
+ ? sourceEvent.changedTouches[0].clientX
294
+ : sourceEvent.clientX;
295
+ const y = sourceEvent.changedTouches
296
+ ? sourceEvent.changedTouches[0].clientY
297
+ : sourceEvent.clientY;
298
+ const pointerPos = {
299
+ x: (x - transform[0]) / transform[2],
300
+ y: (y - transform[1]) / transform[2],
301
+ };
302
+ const getStepPosition = (params = {
303
+ position: pointerPos,
304
+ }) => {
305
+ const { position, nodeSize } = params;
306
+ if (!gridStep)
307
+ return position;
308
+ let x = gridStep[0] * Math.round(position.x / gridStep[0]), y = gridStep[1] * Math.round(position.y / gridStep[1]);
309
+ if (centerStep && nodeSize) {
310
+ const centerX = (gridStep[0] - nodeSize.width) / 2;
311
+ const centerY = (gridStep[1] - nodeSize.height) / 2;
312
+ const positionX = position.x - centerX;
313
+ const positionY = position.y - centerY;
314
+ x = gridStep[0] * Math.round(positionX / gridStep[0]) + centerX;
315
+ y = gridStep[1] * Math.round(positionY / gridStep[1]) + centerY;
316
+ }
317
+ return {
318
+ x,
319
+ y,
320
+ };
321
+ };
322
+ return {
323
+ getStepPosition,
324
+ ...pointerPos,
325
+ };
326
+ }, []);
327
+ return getPointerPosition;
328
+ }
329
+
330
+ const getPortBounds = (selector, nodeElement, zoom, nodeOrigin) => {
331
+ const ports = nodeElement.querySelectorAll(selector);
332
+ if (!ports || !ports.length) {
333
+ return null;
334
+ }
335
+ const portsArray = Array.from(ports);
336
+ const nodeBounds = nodeElement.getBoundingClientRect();
337
+ const nodeOffset = {
338
+ x: nodeBounds.width * nodeOrigin[0],
339
+ y: nodeBounds.height * nodeOrigin[1],
340
+ };
341
+ return portsArray.map((port) => {
342
+ const portBounds = port.getBoundingClientRect();
343
+ return {
344
+ id: port.getAttribute('data-portid'),
345
+ position: port.dataset.portPosition,
346
+ x: (portBounds.left - nodeBounds.left - nodeOffset.x) / zoom,
347
+ y: (portBounds.top - nodeBounds.top - nodeOffset.y) / zoom,
348
+ ...getDimensions(port),
349
+ };
350
+ });
351
+ };
352
+ function getMouseHandler$1(id, getState, handler) {
353
+ return handler === undefined
354
+ ? handler
355
+ : (event) => {
356
+ const node = getState().nodeInternals.get(id);
357
+ handler(event, { ...node });
358
+ };
359
+ }
360
+ function handleNodeClick({ id, store, isSelectable, unselect = false, nodeRef, }) {
361
+ if (!isSelectable)
362
+ return;
363
+ const { addSelectedNodes, unselectNodes, multiSelectionActive, nodeInternals, } = store.getState();
364
+ const node = nodeInternals.get(id);
365
+ store.setState({ selectionBoxActive: false });
366
+ if (!node.selected) {
367
+ addSelectedNodes([id]);
368
+ }
369
+ else if (unselect || (node.selected && multiSelectionActive)) {
370
+ unselectNodes({ nodes: [node] });
371
+ requestAnimationFrame(() => nodeRef?.current?.blur());
372
+ }
303
373
  }
304
- var SelectionBox$1 = memo(SelectionBox);
305
374
 
306
375
  const isNode = (element) => 'id' in element && !('source' in element) && !('target' in element);
307
376
  const isEdge = (element) => 'source' in element && 'target' in element;
@@ -332,9 +401,7 @@ const getNodePositionWithOrigin = (node, nodeOrigin = [0, 0]) => {
332
401
  : position,
333
402
  };
334
403
  };
335
- const getNodesInside = (nodeInternals, rect, [tx, ty, tScale] = [0, 0, 1], partially = false,
336
- // set excludeNonSelectableNodes if you want to pay attention to the nodes "selectable" attribute
337
- excludeNonSelectableNodes = false, nodeOrigin = [0, 0]) => {
404
+ const getNodesInside = (nodeInternals, rect, [tx, ty, tScale] = [0, 0, 1], partially = false, excludeNonSelectableNodes = false, nodeOrigin = [0, 0]) => {
338
405
  const paneRect = {
339
406
  x: (rect.x - tx) / tScale,
340
407
  y: (rect.y - ty) / tScale,
@@ -433,64 +500,477 @@ const getRectOfNodes = (nodes, nodeOrigin = [0, 0]) => {
433
500
  return boxToRect(box);
434
501
  };
435
502
 
436
- const handleParentExpand = (res, updateItem) => {
437
- const parent = res.find((e) => e.id === updateItem.parentNode);
438
- if (parent) {
439
- const extendWidth = updateItem.position.x + updateItem.width - parent.width;
440
- const extendHeight = updateItem.position.y + updateItem.height - parent.height;
441
- if (extendWidth > 0 ||
442
- extendHeight > 0 ||
443
- updateItem.position.x < 0 ||
444
- updateItem.position.y < 0) {
445
- parent.style = { ...parent.style } || {};
446
- parent.style.width = parent.style.width ?? parent.width;
447
- parent.style.height = parent.style.height ?? parent.height;
448
- if (extendWidth > 0) {
449
- parent.style.width += extendWidth;
450
- }
451
- if (extendHeight > 0) {
452
- parent.style.height += extendHeight;
453
- }
454
- if (updateItem.position.x < 0) {
455
- const xDiff = Math.abs(updateItem.position.x);
456
- parent.position.x = parent.position.x - xDiff;
457
- parent.style.width += xDiff;
458
- updateItem.position.x = 0;
503
+ function isParentSelected(node, nodeInternals) {
504
+ if (!node.parentNode) {
505
+ return false;
506
+ }
507
+ const parentNode = nodeInternals.get(node.parentNode);
508
+ if (!parentNode) {
509
+ return false;
510
+ }
511
+ if (parentNode.selected) {
512
+ return true;
513
+ }
514
+ return isParentSelected(parentNode, nodeInternals);
515
+ }
516
+ const getDragItems = (nodeInternals, nodesDraggable, mousePosition, nodeId) => {
517
+ const filteredNode = Array.from(nodeInternals.values()).filter((n) => {
518
+ const hasSize = n.width && n.height;
519
+ const isSelected = n.selected || n.id === nodeId;
520
+ const hasNoParent = !n.parentNode || !isParentSelected(n, nodeInternals);
521
+ const isDraggable = n.draggable || (nodesDraggable && typeof n.draggable === 'undefined');
522
+ return hasSize && isSelected && hasNoParent && isDraggable;
523
+ });
524
+ return filteredNode.map((n) => ({
525
+ id: n.id,
526
+ position: n.position || { x: 0, y: 0 },
527
+ positionAbsolute: n.positionAbsolute || { x: 0, y: 0 },
528
+ distance: {
529
+ x: mousePosition.x - (n.positionAbsolute?.x ?? 0),
530
+ y: mousePosition.y - (n.positionAbsolute?.y ?? 0),
531
+ },
532
+ extent: n.extent,
533
+ parentNode: n.parentNode,
534
+ width: n.width,
535
+ height: n.height,
536
+ }));
537
+ };
538
+ const calcNextPosition = (node, nextPosition, nodeInternals, nodeExtent, nodeOrigin = [0, 0], onError) => {
539
+ let currentExtent = node.extent || nodeExtent;
540
+ if (node.extent === 'parent') {
541
+ if (node.parentNode && node.width && node.height) {
542
+ const parent = nodeInternals.get(node.parentNode);
543
+ const { x: parentX, y: parentY } = getNodePositionWithOrigin(parent, nodeOrigin).positionAbsolute;
544
+ currentExtent =
545
+ parent &&
546
+ isNumeric(parentX) &&
547
+ isNumeric(parentY) &&
548
+ isNumeric(parent.width) &&
549
+ isNumeric(parent.height)
550
+ ? [
551
+ [
552
+ parentX + node.width * nodeOrigin[0],
553
+ parentY + node.height * nodeOrigin[1],
554
+ ],
555
+ [
556
+ parentX +
557
+ parent.width -
558
+ node.width +
559
+ node.width * nodeOrigin[0],
560
+ parentY +
561
+ parent.height -
562
+ node.height +
563
+ node.height * nodeOrigin[1],
564
+ ],
565
+ ]
566
+ : currentExtent;
567
+ }
568
+ else {
569
+ onError?.('011');
570
+ currentExtent = nodeExtent;
571
+ }
572
+ }
573
+ else if (node.extent && node.parentNode) {
574
+ const parent = nodeInternals.get(node.parentNode);
575
+ const { x: parentX, y: parentY } = getNodePositionWithOrigin(parent, nodeOrigin).positionAbsolute;
576
+ currentExtent = [
577
+ [node.extent[0][0] + parentX, node.extent[0][1] + parentY],
578
+ [node.extent[1][0] + parentX, node.extent[1][1] + parentY],
579
+ ];
580
+ }
581
+ let parentPosition = { x: 0, y: 0 };
582
+ if (node.parentNode) {
583
+ const parentNode = nodeInternals.get(node.parentNode);
584
+ parentPosition = getNodePositionWithOrigin(parentNode, nodeOrigin).positionAbsolute;
585
+ }
586
+ const positionAbsolute = currentExtent
587
+ ? clampPosition(nextPosition, currentExtent)
588
+ : nextPosition;
589
+ return {
590
+ position: {
591
+ x: positionAbsolute.x - parentPosition.x,
592
+ y: positionAbsolute.y - parentPosition.y,
593
+ },
594
+ positionAbsolute,
595
+ };
596
+ };
597
+ const getEventHandlerParams = ({ nodeId, dragItems, nodeInternals, }) => {
598
+ const extentedDragItems = dragItems.map((n) => {
599
+ const node = nodeInternals.get(n.id);
600
+ return {
601
+ ...node,
602
+ position: n.position,
603
+ positionAbsolute: n.positionAbsolute,
604
+ };
605
+ });
606
+ return [
607
+ nodeId
608
+ ? extentedDragItems.find((n) => n.id === nodeId)
609
+ : extentedDragItems[0],
610
+ extentedDragItems,
611
+ ];
612
+ };
613
+ const hasSelector = (target, selector, nodeRef) => {
614
+ let current = target;
615
+ do {
616
+ if (current?.matches(selector))
617
+ return true;
618
+ if (current === nodeRef.current)
619
+ return false;
620
+ current = current.parentElement;
621
+ } while (current);
622
+ return false;
623
+ };
624
+ const hasChangedPosition = (beforePositions, currentPosition) => beforePositions.x !== currentPosition.x ||
625
+ beforePositions.y !== currentPosition.y;
626
+
627
+ const has = Object.prototype.hasOwnProperty;
628
+ const deepEqual = (foo, bar) => {
629
+ let constructor;
630
+ let length;
631
+ if (foo === bar)
632
+ return true;
633
+ if (foo && bar && foo.constructor === bar.constructor) {
634
+ constructor = foo.constructor;
635
+ if (constructor === Date)
636
+ return foo.getTime() === bar.getTime();
637
+ if (constructor === RegExp)
638
+ return foo.toString() === bar.toString();
639
+ if (constructor === Array) {
640
+ if ((length = foo.length) === bar.length) {
641
+ while (length-- && deepEqual(foo[length], bar[length]))
642
+ ;
459
643
  }
460
- if (updateItem.position.y < 0) {
461
- const yDiff = Math.abs(updateItem.position.y);
462
- parent.position.y = parent.position.y - yDiff;
463
- parent.style.height += yDiff;
464
- updateItem.position.y = 0;
644
+ return length === -1;
645
+ }
646
+ if (!constructor || typeof foo === 'object') {
647
+ length = 0;
648
+ for (constructor in foo) {
649
+ if (has.call(foo, constructor) &&
650
+ ++length &&
651
+ !has.call(bar, constructor))
652
+ return false;
653
+ if (!(constructor in bar) ||
654
+ !deepEqual(foo[constructor], bar[constructor]))
655
+ return false;
465
656
  }
466
- parent.width = parent.style.width;
467
- parent.height = parent.style.height;
657
+ return Object.keys(bar).length === length;
468
658
  }
469
659
  }
660
+ return foo !== foo && bar !== bar;
470
661
  };
471
- const applyChanges = (changes, elements) => {
472
- // we need this hack to handle the setNodes and setEdges function of the useReactDiagram hook for controlled flows
473
- if (changes.some((c) => c.type === 'reset')) {
474
- return changes.filter((c) => c.type === 'reset').map((c) => c.item);
475
- }
476
- const initElements = changes
477
- .filter((c) => c.type === 'add')
478
- .map((c) => c.item);
479
- return elements.reduce((res, item) => {
480
- const currentChanges = changes.filter((c) => c.id === item.id);
481
- if (currentChanges.length === 0) {
482
- res.push(item);
483
- return res;
662
+
663
+ function useUpdateIntersectionNodes() {
664
+ const store = useStoreApi();
665
+ const intersectionChanges = useRef([]);
666
+ const resetIntersectedNodes = useCallback((intersectedNodes) => {
667
+ const hasIntersectedNodes = intersectedNodes.length;
668
+ let beforeChanges;
669
+ if (hasIntersectedNodes) {
670
+ beforeChanges = intersectionChanges.current
671
+ .filter((beforeChange) => {
672
+ return !intersectedNodes.some((intersectedNode) => beforeChange.id === intersectedNode.id);
673
+ })
674
+ .map((beforeChange) => ({
675
+ ...beforeChange,
676
+ intersected: false,
677
+ }));
484
678
  }
485
- const updateItem = { ...item };
486
- for (const currentChange of currentChanges) {
487
- if (currentChange) {
488
- switch (currentChange.type) {
489
- case 'select': {
490
- updateItem.selected = currentChange.selected;
491
- break;
679
+ else {
680
+ beforeChanges = intersectionChanges.current.map((beforeChange) => ({
681
+ ...beforeChange,
682
+ intersected: false,
683
+ }));
684
+ }
685
+ return beforeChanges;
686
+ }, []);
687
+ const updateNodesIntersection = useCallback((dragItems) => {
688
+ const { getNodes, triggerNodeChanges } = store.getState();
689
+ const intersectedDraggingNodeIds = [];
690
+ const intersectedNodes = getNodes()
691
+ .filter((node) => {
692
+ const { width, height, position, parentNode } = node;
693
+ if (parentNode)
694
+ return;
695
+ if (width && height) {
696
+ return dragItems.current?.some((dragItem) => {
697
+ const { position: dPosition, width: dWidth, height: dHeight, } = dragItem;
698
+ if (node.id === dragItem.id)
699
+ return;
700
+ if (dragItem.parentNode)
701
+ return;
702
+ if (!dWidth || !dHeight)
703
+ return;
704
+ const leftIn = dPosition.x + dWidth >= position.x, rightIn = position.x + width >= dPosition.x, topIn = dPosition.y + dHeight >= position.y, bottomIn = position.y + height >= dPosition.y;
705
+ const isIn = leftIn && rightIn && topIn && bottomIn;
706
+ if (isIn) {
707
+ if (!intersectedDraggingNodeIds.includes(dragItem.id)) {
708
+ intersectedDraggingNodeIds.push(dragItem.id);
709
+ }
492
710
  }
493
- case 'position': {
711
+ return isIn;
712
+ });
713
+ }
714
+ })
715
+ .map((node) => {
716
+ return {
717
+ id: node.id,
718
+ type: 'intersect',
719
+ intersected: true,
720
+ };
721
+ });
722
+ const intersectedDraggingNodes = intersectedDraggingNodeIds.map((id) => {
723
+ return {
724
+ id,
725
+ type: 'intersect',
726
+ intersected: true,
727
+ };
728
+ });
729
+ const changes = [...intersectedNodes, ...intersectedDraggingNodes];
730
+ if (!deepEqual(changes, intersectionChanges.current)) {
731
+ const beforeChanges = resetIntersectedNodes(changes);
732
+ intersectionChanges.current = changes;
733
+ triggerNodeChanges([...changes, ...beforeChanges]);
734
+ }
735
+ }, []);
736
+ return updateNodesIntersection;
737
+ }
738
+
739
+ const isDragItem = (node) => 'distance' in node;
740
+ function useDrag({ nodeRef, nodeId, isSelectable, noDragClassName, }) {
741
+ const store = useStoreApi();
742
+ const dragItems = useRef([]);
743
+ const containerBounds = useRef(null);
744
+ const mousePosition = useRef({ x: 0, y: 0 });
745
+ const lastPosition = useRef({ x: 0, y: 0 });
746
+ const dragEvent = useRef(null);
747
+ const autoPanStarted = useRef(false);
748
+ const autoPanId = useRef(0);
749
+ const [dragging, setDragging] = useState(false);
750
+ const getPointerPosition = useGetPointerPosition();
751
+ const updateNodesIntersection = useUpdateIntersectionNodes();
752
+ const updateNodePosition = (pointerPositions, dragEnd = false) => (dragItem) => {
753
+ if (!isDragItem(dragItem))
754
+ return;
755
+ const { nodeInternals, nodeExtent, nodeOrigin, smoothStep, gridStep, onError, } = store.getState();
756
+ const { distance, width, height } = dragItem;
757
+ const { x, y, getStepPosition } = pointerPositions;
758
+ let nextPosition = {
759
+ x: x - distance.x,
760
+ y: y - distance.y,
761
+ };
762
+ if (gridStep && getStepPosition) {
763
+ const nodeSize = { width, height };
764
+ const stepPosition = getStepPosition({
765
+ position: nextPosition,
766
+ nodeSize,
767
+ });
768
+ if (!smoothStep || (smoothStep && dragEnd)) {
769
+ nextPosition = stepPosition;
770
+ }
771
+ }
772
+ const updatedPosition = calcNextPosition(dragItem, nextPosition, nodeInternals, nodeExtent, nodeOrigin, onError);
773
+ const hasChange = hasChangedPosition(dragItem.position, updatedPosition.position);
774
+ if (!hasChange)
775
+ return;
776
+ dragItem.position = updatedPosition.position;
777
+ dragItem.positionAbsolute = updatedPosition.positionAbsolute;
778
+ };
779
+ useEffect(() => {
780
+ if (nodeRef?.current) {
781
+ const selection = select(nodeRef.current);
782
+ const updateNodes = (pointerPosition) => {
783
+ const { nodeInternals, onNodeDrag, updateNodesPosition } = store.getState();
784
+ const { x, y } = pointerPosition;
785
+ lastPosition.current = { x, y };
786
+ updateNodesPosition(dragItems.current, true, updateNodePosition(pointerPosition));
787
+ setDragging(true);
788
+ if (onNodeDrag && dragEvent.current) {
789
+ const [currentNode, nodes] = getEventHandlerParams({
790
+ nodeId,
791
+ dragItems: dragItems.current,
792
+ nodeInternals,
793
+ });
794
+ onNodeDrag(dragEvent.current, currentNode, nodes);
795
+ }
796
+ };
797
+ const autoPan = () => {
798
+ if (!containerBounds.current) {
799
+ return;
800
+ }
801
+ const [xMovement, yMovement] = calcAutoPanPosition(mousePosition.current, containerBounds.current);
802
+ if (xMovement !== 0 || yMovement !== 0) {
803
+ const { transform, panBy } = store.getState();
804
+ lastPosition.current.x -= xMovement / transform[2];
805
+ lastPosition.current.y -= yMovement / transform[2];
806
+ updateNodes(lastPosition.current);
807
+ panBy({ x: xMovement, y: yMovement });
808
+ }
809
+ autoPanId.current = requestAnimationFrame(autoPan);
810
+ };
811
+ const dragHandle = drag()
812
+ .on('start', (e) => {
813
+ const { nodeInternals, nodesDraggable, domNode, onNodeDragStart, } = store.getState();
814
+ if (nodeId) {
815
+ handleNodeClick({
816
+ id: nodeId,
817
+ store,
818
+ nodeRef: nodeRef,
819
+ isSelectable,
820
+ });
821
+ }
822
+ const pointerPosition = getPointerPosition(e);
823
+ dragItems.current = getDragItems(nodeInternals, nodesDraggable, pointerPosition, nodeId);
824
+ if (onNodeDragStart && dragItems.current) {
825
+ const [currentNode, nodes] = getEventHandlerParams({
826
+ nodeId,
827
+ dragItems: dragItems.current,
828
+ nodeInternals,
829
+ });
830
+ onNodeDragStart(e.sourceEvent, currentNode, nodes);
831
+ }
832
+ containerBounds.current =
833
+ domNode?.getBoundingClientRect() || null;
834
+ mousePosition.current = getEventPosition(e.sourceEvent, containerBounds.current);
835
+ })
836
+ .on('drag', (e) => {
837
+ const pointerPosition = getPointerPosition(e);
838
+ const { autoPanOnNodeDrag } = store.getState();
839
+ if (!autoPanStarted.current && autoPanOnNodeDrag) {
840
+ autoPanStarted.current = true;
841
+ autoPan();
842
+ }
843
+ const isChanged = hasChangedPosition(lastPosition.current, pointerPosition.getStepPosition());
844
+ if (isChanged && dragItems.current) {
845
+ dragEvent.current = e.sourceEvent;
846
+ mousePosition.current = getEventPosition(e.sourceEvent, containerBounds.current);
847
+ updateNodes(pointerPosition);
848
+ updateNodesIntersection(dragItems);
849
+ }
850
+ })
851
+ .on('end', (event) => {
852
+ setDragging(false);
853
+ autoPanStarted.current = false;
854
+ cancelAnimationFrame(autoPanId.current);
855
+ if (dragItems.current) {
856
+ const { nodeInternals, smoothStep, gridStep, updateNodesPosition, onNodeDragEnd, } = store.getState();
857
+ const isSmoothStep = !!gridStep && smoothStep;
858
+ if (isSmoothStep) {
859
+ const pointerPosition = getPointerPosition(event);
860
+ updateNodesPosition(dragItems.current, false, updateNodePosition(pointerPosition, true));
861
+ }
862
+ else {
863
+ updateNodesPosition(dragItems.current, false);
864
+ }
865
+ if (onNodeDragEnd) {
866
+ const [currentNode, nodes] = getEventHandlerParams({
867
+ nodeId,
868
+ dragItems: dragItems.current,
869
+ nodeInternals,
870
+ });
871
+ onNodeDragEnd(event.sourceEvent, currentNode, nodes);
872
+ }
873
+ }
874
+ })
875
+ .filter((event) => {
876
+ const target = event.target;
877
+ const isDraggable = !event.button &&
878
+ (!noDragClassName ||
879
+ !hasSelector(target, `.${noDragClassName}`, nodeRef));
880
+ return isDraggable;
881
+ });
882
+ selection.call(dragHandle);
883
+ return () => {
884
+ selection.on('.drag', null);
885
+ };
886
+ }
887
+ }, [
888
+ store,
889
+ nodeRef,
890
+ nodeId,
891
+ isSelectable,
892
+ noDragClassName,
893
+ getPointerPosition,
894
+ ]);
895
+ return dragging;
896
+ }
897
+
898
+ function SelectionBox({ rect, transform }) {
899
+ const nodeRef = useRef(null);
900
+ useDrag({ nodeRef });
901
+ const { width, height, x, y } = rect;
902
+ return (jsx("div", { className: cc([
903
+ 'react-diagram__selection-box',
904
+ 'react-diagram__container',
905
+ ]), style: {
906
+ transform,
907
+ }, children: jsx("div", { ref: nodeRef, className: "react-diagram__selection-box-rect", tabIndex: -1, style: {
908
+ width,
909
+ height,
910
+ top: y,
911
+ left: x,
912
+ } }) }));
913
+ }
914
+ var SelectionBox$1 = memo(SelectionBox);
915
+
916
+ const handleParentExpand = (res, updateItem) => {
917
+ const parent = res.find((e) => e.id === updateItem.parentNode);
918
+ if (parent) {
919
+ const extendWidth = updateItem.position.x + updateItem.width - parent.width;
920
+ const extendHeight = updateItem.position.y + updateItem.height - parent.height;
921
+ if (extendWidth > 0 ||
922
+ extendHeight > 0 ||
923
+ updateItem.position.x < 0 ||
924
+ updateItem.position.y < 0) {
925
+ parent.style = { ...parent.style } || {};
926
+ parent.style.width = parent.style.width ?? parent.width;
927
+ parent.style.height = parent.style.height ?? parent.height;
928
+ if (extendWidth > 0) {
929
+ parent.style.width += extendWidth;
930
+ }
931
+ if (extendHeight > 0) {
932
+ parent.style.height += extendHeight;
933
+ }
934
+ if (updateItem.position.x < 0) {
935
+ const xDiff = Math.abs(updateItem.position.x);
936
+ parent.position.x = parent.position.x - xDiff;
937
+ parent.style.width += xDiff;
938
+ updateItem.position.x = 0;
939
+ }
940
+ if (updateItem.position.y < 0) {
941
+ const yDiff = Math.abs(updateItem.position.y);
942
+ parent.position.y = parent.position.y - yDiff;
943
+ parent.style.height += yDiff;
944
+ updateItem.position.y = 0;
945
+ }
946
+ parent.width = parent.style.width;
947
+ parent.height = parent.style.height;
948
+ }
949
+ }
950
+ };
951
+ const applyChanges = (changes, elements) => {
952
+ // we need this hack to handle the setNodes and setEdges function of the useReactDiagram hook for controlled flows
953
+ if (changes.some((c) => c.type === 'reset')) {
954
+ return changes.filter((c) => c.type === 'reset').map((c) => c.item);
955
+ }
956
+ const initElements = changes
957
+ .filter((c) => c.type === 'add')
958
+ .map((c) => c.item);
959
+ return elements.reduce((res, item) => {
960
+ const currentChanges = changes.filter((c) => c.id === item.id);
961
+ if (currentChanges.length === 0) {
962
+ res.push(item);
963
+ return res;
964
+ }
965
+ const updateItem = { ...item };
966
+ for (const currentChange of currentChanges) {
967
+ if (currentChange) {
968
+ switch (currentChange.type) {
969
+ case 'select': {
970
+ updateItem.selected = currentChange.selected;
971
+ break;
972
+ }
973
+ case 'position': {
494
974
  if (typeof currentChange.position !== 'undefined') {
495
975
  updateItem.position = currentChange.position;
496
976
  }
@@ -525,6 +1005,10 @@ const applyChanges = (changes, elements) => {
525
1005
  }
526
1006
  break;
527
1007
  }
1008
+ case 'intersect': {
1009
+ updateItem.intersected = currentChange.intersected;
1010
+ break;
1011
+ }
528
1012
  case 'remove': {
529
1013
  return res;
530
1014
  }
@@ -561,10 +1045,14 @@ function getSelectionChanges(items, selectedIds) {
561
1045
  }, []);
562
1046
  }
563
1047
 
564
- const selector$5 = (s) => {
1048
+ const selector$6 = (s) => {
1049
+ const { elementsSelectable, transform, selectionBoxActive, getNodes } = s;
1050
+ const selectedNodes = getNodes().filter((n) => n.selected);
565
1051
  return {
566
- elementsSelectable: s.elementsSelectable,
567
- transform: `translate(${s.transform[0]}px,${s.transform[1]}px) scale(${s.transform[2]})`,
1052
+ elementsSelectable,
1053
+ selectionBoxRect: getRectOfNodes(selectedNodes, s.nodeOrigin),
1054
+ transformString: `translate(${transform[0]}px,${transform[1]}px) scale(${transform[2]})`,
1055
+ selectionBoxActive,
568
1056
  };
569
1057
  };
570
1058
  function DragSelection({ children, dragSelectionKeyPressed, }) {
@@ -572,7 +1060,7 @@ function DragSelection({ children, dragSelectionKeyPressed, }) {
572
1060
  const dragSelection = useRef(null);
573
1061
  const prevSelectedNodesCount = useRef(0);
574
1062
  const containerBounds = useRef();
575
- const { elementsSelectable, transform } = useStore(selector$5, shallow);
1063
+ const { elementsSelectable, selectionBoxRect, transformString, selectionBoxActive, } = useStore(selector$6, shallow);
576
1064
  const [dragBoxStartPosition, setDragBoxStartPosition] = useState({
577
1065
  x: 0,
578
1066
  y: 0,
@@ -583,14 +1071,7 @@ function DragSelection({ children, dragSelectionKeyPressed, }) {
583
1071
  x: 0,
584
1072
  y: 0,
585
1073
  });
586
- const [selectionBoxRect, setSelectionBoxRect] = useState({
587
- width: 0,
588
- height: 0,
589
- x: 0,
590
- y: 0,
591
- });
592
1074
  const [dragBoxActive, setDragBoxActive] = useState(false);
593
- const [selectionBoxActive, setSelectionBoxActive] = useState(false);
594
1075
  const resetDragBox = () => {
595
1076
  setDragBoxStartPosition({
596
1077
  x: 0,
@@ -607,8 +1088,10 @@ function DragSelection({ children, dragSelectionKeyPressed, }) {
607
1088
  const onClick = (e) => {
608
1089
  if (e.target === dragSelection.current) {
609
1090
  store.getState().resetSelectedElements();
1091
+ store.setState({
1092
+ selectionBoxActive: false,
1093
+ });
610
1094
  setDragBoxActive(false);
611
- setSelectionBoxActive(false);
612
1095
  }
613
1096
  };
614
1097
  const onMouseDown = (event) => {
@@ -636,7 +1119,6 @@ function DragSelection({ children, dragSelectionKeyPressed, }) {
636
1119
  };
637
1120
  const onMouseMove = (event) => {
638
1121
  const { nodeInternals, transform, nodeOrigin, getNodes, onNodesChange } = store.getState();
639
- // const hasDragBoxPosition = dragBoxRect.x > 0 && dragBoxRect.y > 0;
640
1122
  const hasDragBoxStartPosition = dragBoxStartPosition.x > 0 && dragBoxStartPosition.y > 0;
641
1123
  if (
642
1124
  // !hasDragBoxPosition ||
@@ -645,8 +1127,10 @@ function DragSelection({ children, dragSelectionKeyPressed, }) {
645
1127
  !dragSelectionKeyPressed) {
646
1128
  return;
647
1129
  }
1130
+ store.setState({
1131
+ selectionBoxActive: false,
1132
+ });
648
1133
  setDragBoxActive(true);
649
- setSelectionBoxActive(false);
650
1134
  const mousePos = getEventPosition(event, containerBounds.current);
651
1135
  const startX = dragBoxStartPosition.x ?? 0;
652
1136
  const startY = dragBoxStartPosition.y ?? 0;
@@ -659,8 +1143,6 @@ function DragSelection({ children, dragSelectionKeyPressed, }) {
659
1143
  const nodes = getNodes();
660
1144
  const selectedNodes = getNodesInside(nodeInternals, rect, transform, false, true, nodeOrigin);
661
1145
  const selectedNodeIds = selectedNodes.map((n) => n.id);
662
- const selectionBoxRect = getRectOfNodes(selectedNodes, nodeOrigin);
663
- setSelectionBoxRect(selectionBoxRect);
664
1146
  if (prevSelectedNodesCount.current !== selectedNodeIds.length) {
665
1147
  prevSelectedNodesCount.current = selectedNodeIds.length;
666
1148
  const changes = getSelectionChanges(nodes, selectedNodeIds);
@@ -674,19 +1156,22 @@ function DragSelection({ children, dragSelectionKeyPressed, }) {
674
1156
  if (event.button !== 0) {
675
1157
  return;
676
1158
  }
677
- setSelectionBoxActive(prevSelectedNodesCount.current > 0);
1159
+ store.setState({
1160
+ selectionBoxActive: prevSelectedNodesCount.current > 0,
1161
+ });
678
1162
  resetDragBox();
679
1163
  };
680
1164
  const onMouseLeave = () => {
681
- setSelectionBoxActive(prevSelectedNodesCount.current > 0);
1165
+ store.setState({
1166
+ selectionBoxActive: prevSelectedNodesCount.current > 0,
1167
+ });
682
1168
  resetDragBox();
683
1169
  };
684
1170
  const isPossibleDragSelection = elementsSelectable && dragSelectionKeyPressed;
685
- return (jsxs("div", { ref: dragSelection, className: "react-diagram__container react-diagram__drag-selection", onClick: onClick, onMouseDown: isPossibleDragSelection ? onMouseDown : undefined, onMouseMove: isPossibleDragSelection ? onMouseMove : undefined, onMouseUp: elementsSelectable && dragBoxRect ? onMouseUp : undefined, onMouseLeave: isPossibleDragSelection ? onMouseLeave : undefined, children: [children, dragBoxActive && jsx(DragBox, { rect: dragBoxRect }), selectionBoxActive && (jsx(SelectionBox$1, { rect: selectionBoxRect, transform: transform }))] }));
1171
+ return (jsxs("div", { ref: dragSelection, className: "react-diagram__container react-diagram__drag-selection", onClick: onClick, onMouseDown: isPossibleDragSelection ? onMouseDown : undefined, onMouseMove: isPossibleDragSelection ? onMouseMove : undefined, onMouseUp: elementsSelectable && dragBoxRect ? onMouseUp : undefined, onMouseLeave: isPossibleDragSelection ? onMouseLeave : undefined, children: [children, dragBoxActive && jsx(DragBox, { rect: dragBoxRect }), selectionBoxActive && (jsx(SelectionBox$1, { rect: selectionBoxRect, transform: transformString }))] }));
686
1172
  }
687
- DragSelection.displayName = 'DragSelection';
688
1173
 
689
- const selector$4 = (s) => {
1174
+ const selector$5 = (s) => {
690
1175
  const { minZoom, maxZoom, translateExtent } = s;
691
1176
  return {
692
1177
  minZoom,
@@ -695,7 +1180,7 @@ const selector$4 = (s) => {
695
1180
  };
696
1181
  };
697
1182
  function DiagramRenderer({ children, multiSelectionKeyCode, noPanClassName, panning, defaultViewport, onMove, onMoveStart, onMoveEnd, }) {
698
- const { minZoom, maxZoom, translateExtent } = useStore(selector$4);
1183
+ const { minZoom, maxZoom, translateExtent } = useStore(selector$5);
699
1184
  const [dragSelectionKeyPressed, setDragSelectionKeyPressed] = useState(false);
700
1185
  useGlobalKeyHandler(multiSelectionKeyCode);
701
1186
  const handleKeyDown = (e) => {
@@ -737,14 +1222,14 @@ var MarkerType;
737
1222
  MarkerType["Arrow"] = "arrow";
738
1223
  })(MarkerType || (MarkerType = {}));
739
1224
 
740
- const selector$3 = (s) => ({
1225
+ const selector$4 = (s) => ({
741
1226
  nodesDraggable: s.nodesDraggable,
742
1227
  elementsSelectable: s.elementsSelectable,
743
1228
  updateNodeDimensions: s.updateNodeDimensions,
744
1229
  onError: s.onError,
745
1230
  });
746
1231
  function NodeRenderer({ nodeTypes, onNodeClick, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onNodeDoubleClick, ...props }) {
747
- const { nodesDraggable, elementsSelectable, updateNodeDimensions, onError } = useStore(selector$3, shallow);
1232
+ const { nodesDraggable, elementsSelectable, updateNodeDimensions, onError } = useStore(selector$4, shallow);
748
1233
  const nodes = useVisibleNodes();
749
1234
  const resizeObserverRef = useRef();
750
1235
  const resizeObserver = useMemo(() => {
@@ -768,7 +1253,7 @@ function NodeRenderer({ nodeTypes, onNodeClick, onNodeMouseEnter, onNodeMouseMov
768
1253
  return (jsx("div", { className: "react-diagram__nodes react-diagram__container", children: nodes.map((node) => {
769
1254
  const { data, type,
770
1255
  // elProps
771
- id, className, style, ariaLabel, positionAbsolute, hidden, selected, selectable, draggable, } = node;
1256
+ id, className, style, width, height, ariaLabel, positionAbsolute, hidden, selected, selectable, draggable, intersected, } = node;
772
1257
  let nodeType = type || 'default';
773
1258
  if (!nodeTypes[nodeType]) {
774
1259
  onError?.('010', nodeType);
@@ -783,11 +1268,9 @@ function NodeRenderer({ nodeTypes, onNodeClick, onNodeMouseEnter, onNodeMouseMov
783
1268
  const elProps = {
784
1269
  id,
785
1270
  className,
786
- style: {
787
- ...style,
788
- width: node.width,
789
- height: node.height,
790
- },
1271
+ style,
1272
+ width,
1273
+ height,
791
1274
  ariaLabel,
792
1275
  };
793
1276
  const events = {
@@ -806,6 +1289,7 @@ function NodeRenderer({ nodeTypes, onNodeClick, onNodeMouseEnter, onNodeMouseMov
806
1289
  };
807
1290
  const booleanProps = {
808
1291
  selected: !!selected,
1292
+ intersected,
809
1293
  isSelectable,
810
1294
  isDraggable,
811
1295
  hidden,
@@ -1333,7 +1817,7 @@ type, }) {
1333
1817
  ]), cx: portPositionX(centerX, radius, position), cy: portPositionY(centerY, radius, position), r: radius, stroke: "transparent", fill: "transparent", onMouseDown: onMouseDown }));
1334
1818
  }
1335
1819
 
1336
- function getMouseHandler$1(id, getState, handler) {
1820
+ function getMouseHandler(id, getState, handler) {
1337
1821
  return handler === undefined
1338
1822
  ? handler
1339
1823
  : (event) => {
@@ -1417,11 +1901,11 @@ const wrapEdge = (EdgeComponent) => {
1417
1901
  onClick(event, edge);
1418
1902
  }
1419
1903
  };
1420
- const onEdgeDoubleClick = getMouseHandler$1(id, store.getState, onDoubleClick);
1421
- const onEdgeContextMenu = getMouseHandler$1(id, store.getState, onContextMenu);
1422
- const onEdgeMouseEnter = getMouseHandler$1(id, store.getState, onMouseEnter);
1423
- const onEdgeMouseMove = getMouseHandler$1(id, store.getState, onMouseMove);
1424
- const onEdgeMouseLeave = getMouseHandler$1(id, store.getState, onMouseLeave);
1904
+ const onEdgeDoubleClick = getMouseHandler(id, store.getState, onDoubleClick);
1905
+ const onEdgeContextMenu = getMouseHandler(id, store.getState, onContextMenu);
1906
+ const onEdgeMouseEnter = getMouseHandler(id, store.getState, onMouseEnter);
1907
+ const onEdgeMouseMove = getMouseHandler(id, store.getState, onMouseMove);
1908
+ const onEdgeMouseLeave = getMouseHandler(id, store.getState, onMouseLeave);
1425
1909
  const inactive = !elementsSelectable;
1426
1910
  const wrapperClassName = cc([
1427
1911
  'react-diagram__edge',
@@ -1549,7 +2033,7 @@ function getNodeData(node) {
1549
2033
  ];
1550
2034
  }
1551
2035
 
1552
- const selector$2 = (s) => ({
2036
+ const selector$3 = (s) => ({
1553
2037
  edges: s.edges,
1554
2038
  width: s.width,
1555
2039
  height: s.height,
@@ -1557,7 +2041,7 @@ const selector$2 = (s) => ({
1557
2041
  onError: s.onError,
1558
2042
  });
1559
2043
  function EdgeRenderer({ rfId, edgeTypes, noPanClassName, edgeUpdaterRadius, onEdgeClick, onEdgeDoubleClick, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeUpdate, onEdgeUpdateStart, onEdgeUpdateEnd, }) {
1560
- const { edges, width, height, nodeInternals } = useStore(selector$2, shallow);
2044
+ const { edges, width, height, nodeInternals } = useStore(selector$3, shallow);
1561
2045
  return (jsxs("svg", { width: width || '100vw', height: height || '100vh', className: "react-diagram__edges react-diagram__container", children: [jsx(MarkerComponent$1, { defaultColor: "#000000", rfId: rfId }), jsx("g", { children: edges.map((edge) => {
1562
2046
  const { data, type,
1563
2047
  // elProps
@@ -1669,13 +2153,13 @@ function ConnectionPath({ nodeId, portType, edge, Component, EdgeWrapper, }) {
1669
2153
  }
1670
2154
  ConnectionPath.displayName = 'ConnectionPath';
1671
2155
 
1672
- const selector$1 = (s) => ({
2156
+ const selector$2 = (s) => ({
1673
2157
  edges: s.edges,
1674
2158
  nodeId: s.connectionNodeId,
1675
2159
  portType: s.connectionPortType,
1676
2160
  });
1677
2161
  function ConnectionLineRenderer({ containerStyle, edgeTypes, component, }) {
1678
- const { nodeId, portType, edges } = useStore(selector$1, shallow);
2162
+ const { nodeId, portType, edges } = useStore(selector$2, shallow);
1679
2163
  const isValid = !!(nodeId && portType);
1680
2164
  if (!isValid) {
1681
2165
  return null;
@@ -1687,480 +2171,137 @@ function ConnectionLineRenderer({ containerStyle, edgeTypes, component, }) {
1687
2171
  ? edgeTypes[selectedEdge.type]
1688
2172
  : edgeTypes.default;
1689
2173
  return (jsx("svg", { style: containerStyle, className: "react-diagram__container react-diagram__connection-line", children: jsx("g", { className: "react-diagram__connection", children: jsx(ConnectionPath, { nodeId: nodeId, portType: portType, edge: selectedEdge, Component: component, EdgeWrapper: EdgeWrapper }) }) }));
1690
- }
1691
-
1692
- function DiagramView({ rfId,
1693
- // DiagramRenderer props
1694
- noPanClassName, panning, defaultViewport, multiSelectionKeyCode, onMove, onMoveStart, onMoveEnd,
1695
- // NodeRenderer props
1696
- onlyRenderVisibleElements, disableKeyboardA11y, noDragClassName, nodeOrigin, nodeTypes, onNodeClick, onNodeDoubleClick, onNodeContextMenu, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave,
1697
- // EdgeRenderer props
1698
- edgeTypes, edgeUpdaterRadius, onEdgeClick, onEdgeDoubleClick, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeUpdate, onEdgeUpdateStart, onEdgeUpdateEnd,
1699
- // ConnectionLineWrapper
1700
- ConnectionLineContainerStyle, ConnectionLineComponent, }) {
1701
- return (jsxs(DiagramRenderer$1, { multiSelectionKeyCode: multiSelectionKeyCode, noPanClassName: noPanClassName, panning: panning, defaultViewport: defaultViewport, onMove: onMove, onMoveStart: onMoveStart, onMoveEnd: onMoveEnd, children: [jsx(NodeRenderer$1, { rfId: rfId, nodeTypes: nodeTypes, onlyRenderVisibleElements: onlyRenderVisibleElements, disableKeyboardA11y: disableKeyboardA11y, nodeOrigin: nodeOrigin, noDragClassName: noDragClassName, noPanClassName: noPanClassName, onNodeClick: onNodeClick, onNodeDoubleClick: onNodeDoubleClick, onNodeContextMenu: onNodeContextMenu, onNodeMouseEnter: onNodeMouseEnter, onNodeMouseMove: onNodeMouseMove, onNodeMouseLeave: onNodeMouseLeave }), jsx(EdgeRenderer$1, { rfId: rfId, edgeTypes: edgeTypes, noPanClassName: noPanClassName, edgeUpdaterRadius: edgeUpdaterRadius, onEdgeClick: onEdgeClick, onEdgeDoubleClick: onEdgeDoubleClick, onEdgeContextMenu: onEdgeContextMenu, onEdgeMouseEnter: onEdgeMouseEnter, onEdgeMouseMove: onEdgeMouseMove, onEdgeMouseLeave: onEdgeMouseLeave, onEdgeUpdate: onEdgeUpdate, onEdgeUpdateStart: onEdgeUpdateStart, onEdgeUpdateEnd: onEdgeUpdateEnd }), jsx(ConnectionLineRenderer, { edgeTypes: edgeTypes, containerStyle: ConnectionLineContainerStyle, component: ConnectionLineComponent })] }));
1702
- }
1703
- DiagramView.displayName = 'DiagramView';
1704
- var DiagramView$1 = memo(DiagramView);
1705
-
1706
- const selector = (s) => {
1707
- const { setNodes, setEdges, setNodeExtent, setTranslateExtent, setMinZoom, setMaxZoom, } = s;
1708
- return {
1709
- setNodes,
1710
- setEdges,
1711
- setNodeExtent,
1712
- setTranslateExtent,
1713
- setMinZoom,
1714
- setMaxZoom,
1715
- };
1716
- };
1717
- function useStoreUpdater(value, setStoreState) {
1718
- useEffect(() => {
1719
- if (typeof value !== 'undefined') {
1720
- setStoreState(value);
1721
- }
1722
- }, [value]);
1723
- }
1724
- // updates with values in store that don't have a dedicated setter function
1725
- function useDirectStoreUpdater(key, value, setState) {
1726
- useEffect(() => {
1727
- if (typeof value !== 'undefined') {
1728
- setState({ [key]: value });
1729
- }
1730
- }, [value]);
1731
- }
1732
- const StoreUpdater = ({ nodes, onNodesChange, onNodeDrag, onNodeDragStart, onNodeDragEnd, edges, onEdgesChange, gridStep, elevateNodesOnSelect, nodesDraggable, autoPanOnNodeDrag, autoPanOnConnect, connectionRadius, onConnect, onConnectStart, onConnectEnd, onError, nodeExtent, translateExtent, minZoom, maxZoom, }) => {
1733
- const { setNodes, setEdges, setNodeExtent, setTranslateExtent, setMinZoom, setMaxZoom, } = useStore(selector, shallow);
1734
- const store = useStoreApi();
1735
- useDirectStoreUpdater('gridStep', gridStep, store.setState);
1736
- useStoreUpdater(nodes, setNodes);
1737
- useStoreUpdater(edges, setEdges);
1738
- useStoreUpdater(nodeExtent, setNodeExtent);
1739
- useStoreUpdater(translateExtent, setTranslateExtent);
1740
- useStoreUpdater(minZoom, setMinZoom);
1741
- useStoreUpdater(maxZoom, setMaxZoom);
1742
- useDirectStoreUpdater('elevateNodesOnSelect', elevateNodesOnSelect, store.setState);
1743
- useDirectStoreUpdater('nodesDraggable', nodesDraggable, store.setState);
1744
- useDirectStoreUpdater('autoPanOnNodeDrag', autoPanOnNodeDrag, store.setState);
1745
- useDirectStoreUpdater('autoPanOnConnect', autoPanOnConnect, store.setState);
1746
- useDirectStoreUpdater('connectionRadius', connectionRadius, store.setState);
1747
- useDirectStoreUpdater('onNodesChange', onNodesChange, store.setState);
1748
- useDirectStoreUpdater('onNodeDrag', onNodeDrag, store.setState);
1749
- useDirectStoreUpdater('onNodeDragStart', onNodeDragStart, store.setState);
1750
- useDirectStoreUpdater('onNodeDragEnd', onNodeDragEnd, store.setState);
1751
- useDirectStoreUpdater('onEdgesChange', onEdgesChange, store.setState);
1752
- useDirectStoreUpdater('onConnect', onConnect, store.setState);
1753
- useDirectStoreUpdater('onConnectStart', onConnectStart, store.setState);
1754
- useDirectStoreUpdater('onConnectEnd', onConnectEnd, store.setState);
1755
- useDirectStoreUpdater('onError', onErrorWrapper(onError), store.setState);
1756
- return null;
1757
- };
1758
-
1759
- function useNodeOrEdgeTypes(nodeOrEdgeTypes, createTypes) {
1760
- const typesKeysRef = useRef(null);
1761
- const typesParsed = useMemo(() => {
1762
- if (process.env.NODE_ENV === 'development') {
1763
- const typeKeys = Object.keys(nodeOrEdgeTypes);
1764
- if (shallow(typesKeysRef.current, typeKeys)) {
1765
- devWarn('002');
1766
- }
1767
- typesKeysRef.current = typeKeys;
1768
- }
1769
- return createTypes(nodeOrEdgeTypes);
1770
- }, [nodeOrEdgeTypes]);
1771
- return typesParsed;
1772
- }
1773
-
1774
- const NodeIdContext = createContext(null);
1775
- const Provider = NodeIdContext.Provider;
1776
- NodeIdContext.Consumer;
1777
- const useNodeId = () => {
1778
- const nodeId = useContext(NodeIdContext);
1779
- return nodeId;
1780
- };
1781
-
1782
- function Port({ type, position }) {
1783
- const store = useStoreApi();
1784
- const nodeId = useNodeId();
1785
- if (!nodeId)
1786
- return null;
1787
- const handleOnConnect = (connection) => {
1788
- const { defaultEdgeOptions, onConnect } = store.getState();
1789
- const edgeParams = {
1790
- ...defaultEdgeOptions,
1791
- ...connection,
1792
- };
1793
- onConnect?.(edgeParams);
1794
- };
1795
- const onPointerDown = (event) => {
1796
- const isMouseTriggered = isMouseEvent(event);
1797
- if ((isMouseTriggered && event.button === 0) || !isMouseTriggered) {
1798
- handlePointerDown({
1799
- event,
1800
- nodeId,
1801
- portType: type,
1802
- getState: store.getState,
1803
- setState: store.setState,
1804
- onConnect: handleOnConnect,
1805
- });
1806
- }
1807
- };
1808
- return (jsx("div", { "data-nodeid": nodeId, "data-id": `${nodeId}-${type}`, "data-port-position": position, className: `react-diagram__port react-diagram__port-${position} ${type} nodrag`, onMouseDown: onPointerDown, onTouchStart: onPointerDown }));
1809
- }
1810
- Port.displayName = 'Port';
1811
- var Port$1 = memo(Port);
1812
-
1813
- function Nodes({ data }) {
1814
- return (jsxs(Fragment, { children: [jsx(Port$1, { type: "target", position: Position.Top }), data.label, jsx(Port$1, { type: "source", position: Position.Bottom })] }));
1815
- }
1816
-
1817
- function useGetPointerPosition() {
1818
- const store = useStoreApi();
1819
- // returns the pointer position projected to the RF coordinate system
1820
- const getPointerPosition = useCallback(({ sourceEvent }) => {
1821
- const { transform, gridStep } = store.getState();
1822
- const x = sourceEvent.touches
1823
- ? sourceEvent.touches[0].clientX
1824
- : sourceEvent.clientX;
1825
- const y = sourceEvent.touches
1826
- ? sourceEvent.touches[0].clientY
1827
- : sourceEvent.clientY;
1828
- const pointerPos = {
1829
- x: (x - transform[0]) / transform[2],
1830
- y: (y - transform[1]) / transform[2],
1831
- };
1832
- // we need the snapped position in order to be able to skip unnecessary drag events
1833
- return {
1834
- xSnapped: gridStep
1835
- ? gridStep[0] * Math.round(pointerPos.x / gridStep[0])
1836
- : pointerPos.x,
1837
- ySnapped: gridStep
1838
- ? gridStep[1] * Math.round(pointerPos.y / gridStep[1])
1839
- : pointerPos.y,
1840
- ...pointerPos,
1841
- };
1842
- }, []);
1843
- return getPointerPosition;
1844
- }
1845
-
1846
- const getPortBounds = (selector, nodeElement, zoom, nodeOrigin) => {
1847
- const ports = nodeElement.querySelectorAll(selector);
1848
- if (!ports || !ports.length) {
1849
- return null;
1850
- }
1851
- const portsArray = Array.from(ports);
1852
- const nodeBounds = nodeElement.getBoundingClientRect();
1853
- const nodeOffset = {
1854
- x: nodeBounds.width * nodeOrigin[0],
1855
- y: nodeBounds.height * nodeOrigin[1],
1856
- };
1857
- return portsArray.map((port) => {
1858
- const portBounds = port.getBoundingClientRect();
1859
- return {
1860
- id: port.getAttribute('data-portid'),
1861
- position: port.dataset.portPosition,
1862
- x: (portBounds.left - nodeBounds.left - nodeOffset.x) / zoom,
1863
- y: (portBounds.top - nodeBounds.top - nodeOffset.y) / zoom,
1864
- ...getDimensions(port),
1865
- };
1866
- });
1867
- };
1868
- function getMouseHandler(id, getState, handler) {
1869
- return handler === undefined
1870
- ? handler
1871
- : (event) => {
1872
- const node = getState().nodeInternals.get(id);
1873
- handler(event, { ...node });
1874
- };
1875
- }
1876
- function handleNodeClick({ id, store, isSelectable, unselect = false, nodeRef, }) {
1877
- if (!isSelectable)
1878
- return;
1879
- const { addSelectedNodes, unselectNodes, multiSelectionActive, nodeInternals, } = store.getState();
1880
- const node = nodeInternals.get(id);
1881
- store.setState({ nodesSelectionActive: false });
1882
- if (!node.selected) {
1883
- addSelectedNodes([id]);
1884
- }
1885
- else if (unselect || (node.selected && multiSelectionActive)) {
1886
- unselectNodes({ nodes: [node] });
1887
- requestAnimationFrame(() => nodeRef?.current?.blur());
1888
- }
1889
- }
1890
-
1891
- function isParentSelected(node, nodeInternals) {
1892
- if (!node.parentNode) {
1893
- return false;
1894
- }
1895
- const parentNode = nodeInternals.get(node.parentNode);
1896
- if (!parentNode) {
1897
- return false;
1898
- }
1899
- if (parentNode.selected) {
1900
- return true;
1901
- }
1902
- return isParentSelected(parentNode, nodeInternals);
1903
- }
1904
- function getDragItems(nodeInternals, nodesDraggable, mousePosition, nodeId) {
1905
- return Array.from(nodeInternals.values())
1906
- .filter((n) => (n.selected || n.id === nodeId) &&
1907
- (!n.parentNode || !isParentSelected(n, nodeInternals)) &&
1908
- (n.draggable ||
1909
- (nodesDraggable && typeof n.draggable === 'undefined')))
1910
- .map((n) => ({
1911
- id: n.id,
1912
- position: n.position || { x: 0, y: 0 },
1913
- positionAbsolute: n.positionAbsolute || { x: 0, y: 0 },
1914
- distance: {
1915
- x: mousePosition.x - (n.positionAbsolute?.x ?? 0),
1916
- y: mousePosition.y - (n.positionAbsolute?.y ?? 0),
1917
- },
1918
- delta: {
1919
- x: 0,
1920
- y: 0,
1921
- },
1922
- extent: n.extent,
1923
- parentNode: n.parentNode,
1924
- width: n.width,
1925
- height: n.height,
1926
- }));
1927
- }
1928
- function calcNextPosition(node, nextPosition, nodeInternals, nodeExtent, nodeOrigin = [0, 0], onError) {
1929
- let currentExtent = node.extent || nodeExtent;
1930
- if (node.extent === 'parent') {
1931
- if (node.parentNode && node.width && node.height) {
1932
- const parent = nodeInternals.get(node.parentNode);
1933
- const { x: parentX, y: parentY } = getNodePositionWithOrigin(parent, nodeOrigin).positionAbsolute;
1934
- currentExtent =
1935
- parent &&
1936
- isNumeric(parentX) &&
1937
- isNumeric(parentY) &&
1938
- isNumeric(parent.width) &&
1939
- isNumeric(parent.height)
1940
- ? [
1941
- [
1942
- parentX + node.width * nodeOrigin[0],
1943
- parentY + node.height * nodeOrigin[1],
1944
- ],
1945
- [
1946
- parentX +
1947
- parent.width -
1948
- node.width +
1949
- node.width * nodeOrigin[0],
1950
- parentY +
1951
- parent.height -
1952
- node.height +
1953
- node.height * nodeOrigin[1],
1954
- ],
1955
- ]
1956
- : currentExtent;
1957
- }
1958
- else {
1959
- onError?.('011');
1960
- currentExtent = nodeExtent;
1961
- }
1962
- }
1963
- else if (node.extent && node.parentNode) {
1964
- const parent = nodeInternals.get(node.parentNode);
1965
- const { x: parentX, y: parentY } = getNodePositionWithOrigin(parent, nodeOrigin).positionAbsolute;
1966
- currentExtent = [
1967
- [node.extent[0][0] + parentX, node.extent[0][1] + parentY],
1968
- [node.extent[1][0] + parentX, node.extent[1][1] + parentY],
1969
- ];
1970
- }
1971
- let parentPosition = { x: 0, y: 0 };
1972
- if (node.parentNode) {
1973
- const parentNode = nodeInternals.get(node.parentNode);
1974
- parentPosition = getNodePositionWithOrigin(parentNode, nodeOrigin).positionAbsolute;
1975
- }
1976
- const positionAbsolute = currentExtent
1977
- ? clampPosition(nextPosition, currentExtent)
1978
- : nextPosition;
2174
+ }
2175
+
2176
+ function DiagramView({ rfId,
2177
+ // DiagramRenderer props
2178
+ noPanClassName, panning, defaultViewport, multiSelectionKeyCode, onMove, onMoveStart, onMoveEnd,
2179
+ // NodeRenderer props
2180
+ onlyRenderVisibleElements, disableKeyboardA11y, noDragClassName, nodeOrigin, nodeTypes, onNodeClick, onNodeDoubleClick, onNodeContextMenu, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave,
2181
+ // EdgeRenderer props
2182
+ edgeTypes, edgeUpdaterRadius, onEdgeClick, onEdgeDoubleClick, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeUpdate, onEdgeUpdateStart, onEdgeUpdateEnd,
2183
+ // ConnectionLineWrapper
2184
+ ConnectionLineContainerStyle, ConnectionLineComponent, }) {
2185
+ return (jsxs(DiagramRenderer$1, { multiSelectionKeyCode: multiSelectionKeyCode, noPanClassName: noPanClassName, panning: panning, defaultViewport: defaultViewport, onMove: onMove, onMoveStart: onMoveStart, onMoveEnd: onMoveEnd, children: [jsx(NodeRenderer$1, { rfId: rfId, nodeTypes: nodeTypes, onlyRenderVisibleElements: onlyRenderVisibleElements, disableKeyboardA11y: disableKeyboardA11y, nodeOrigin: nodeOrigin, noDragClassName: noDragClassName, noPanClassName: noPanClassName, onNodeClick: onNodeClick, onNodeDoubleClick: onNodeDoubleClick, onNodeContextMenu: onNodeContextMenu, onNodeMouseEnter: onNodeMouseEnter, onNodeMouseMove: onNodeMouseMove, onNodeMouseLeave: onNodeMouseLeave }), jsx(EdgeRenderer$1, { rfId: rfId, edgeTypes: edgeTypes, noPanClassName: noPanClassName, edgeUpdaterRadius: edgeUpdaterRadius, onEdgeClick: onEdgeClick, onEdgeDoubleClick: onEdgeDoubleClick, onEdgeContextMenu: onEdgeContextMenu, onEdgeMouseEnter: onEdgeMouseEnter, onEdgeMouseMove: onEdgeMouseMove, onEdgeMouseLeave: onEdgeMouseLeave, onEdgeUpdate: onEdgeUpdate, onEdgeUpdateStart: onEdgeUpdateStart, onEdgeUpdateEnd: onEdgeUpdateEnd }), jsx(ConnectionLineRenderer, { edgeTypes: edgeTypes, containerStyle: ConnectionLineContainerStyle, component: ConnectionLineComponent })] }));
2186
+ }
2187
+ DiagramView.displayName = 'DiagramView';
2188
+ var DiagramView$1 = memo(DiagramView);
2189
+
2190
+ const selector$1 = (s) => {
2191
+ const { setNodes, setEdges, setNodeExtent, setTranslateExtent, setMinZoom, setMaxZoom, } = s;
1979
2192
  return {
1980
- position: {
1981
- x: positionAbsolute.x - parentPosition.x,
1982
- y: positionAbsolute.y - parentPosition.y,
1983
- },
1984
- positionAbsolute,
2193
+ setNodes,
2194
+ setEdges,
2195
+ setNodeExtent,
2196
+ setTranslateExtent,
2197
+ setMinZoom,
2198
+ setMaxZoom,
1985
2199
  };
2200
+ };
2201
+ function useStoreUpdater(value, setStoreState) {
2202
+ useEffect(() => {
2203
+ if (typeof value !== 'undefined') {
2204
+ setStoreState(value);
2205
+ }
2206
+ }, [value]);
1986
2207
  }
1987
- function getEventHandlerParams({ nodeId, dragItems, nodeInternals, }) {
1988
- const extentedDragItems = dragItems.map((n) => {
1989
- const node = nodeInternals.get(n.id);
1990
- return {
1991
- ...node,
1992
- position: n.position,
1993
- positionAbsolute: n.positionAbsolute,
1994
- };
1995
- });
1996
- return [
1997
- nodeId
1998
- ? extentedDragItems.find((n) => n.id === nodeId)
1999
- : extentedDragItems[0],
2000
- extentedDragItems,
2001
- ];
2208
+ // updates with values in store that don't have a dedicated setter function
2209
+ function useDirectStoreUpdater(key, value, setState) {
2210
+ useEffect(() => {
2211
+ if (typeof value !== 'undefined') {
2212
+ setState({ [key]: value });
2213
+ }
2214
+ }, [value]);
2002
2215
  }
2003
- function hasSelector(target, selector, nodeRef) {
2004
- let current = target;
2005
- do {
2006
- if (current?.matches(selector))
2007
- return true;
2008
- if (current === nodeRef.current)
2009
- return false;
2010
- current = current.parentElement;
2011
- } while (current);
2012
- return false;
2216
+ const StoreUpdater = ({ nodes, onNodesChange, onNodeDrag, onNodeDragStart, onNodeDragEnd, edges, onEdgesChange, smoothStep, centerStep, gridStep, elevateNodesOnSelect, nodesDraggable, autoPanOnNodeDrag, autoPanOnConnect, connectionRadius, onConnect, onConnectStart, onConnectEnd, onError, nodeExtent, translateExtent, minZoom, maxZoom, }) => {
2217
+ const { setNodes, setEdges, setNodeExtent, setTranslateExtent, setMinZoom, setMaxZoom, } = useStore(selector$1, shallow);
2218
+ const store = useStoreApi();
2219
+ useStoreUpdater(nodes, setNodes);
2220
+ useStoreUpdater(edges, setEdges);
2221
+ useStoreUpdater(nodeExtent, setNodeExtent);
2222
+ useStoreUpdater(translateExtent, setTranslateExtent);
2223
+ useStoreUpdater(minZoom, setMinZoom);
2224
+ useStoreUpdater(maxZoom, setMaxZoom);
2225
+ useDirectStoreUpdater('smoothStep', smoothStep, store.setState);
2226
+ useDirectStoreUpdater('centerStep', centerStep, store.setState);
2227
+ useDirectStoreUpdater('gridStep', gridStep, store.setState);
2228
+ useDirectStoreUpdater('elevateNodesOnSelect', elevateNodesOnSelect, store.setState);
2229
+ useDirectStoreUpdater('nodesDraggable', nodesDraggable, store.setState);
2230
+ useDirectStoreUpdater('autoPanOnNodeDrag', autoPanOnNodeDrag, store.setState);
2231
+ useDirectStoreUpdater('autoPanOnConnect', autoPanOnConnect, store.setState);
2232
+ useDirectStoreUpdater('connectionRadius', connectionRadius, store.setState);
2233
+ useDirectStoreUpdater('onNodesChange', onNodesChange, store.setState);
2234
+ useDirectStoreUpdater('onNodeDrag', onNodeDrag, store.setState);
2235
+ useDirectStoreUpdater('onNodeDragStart', onNodeDragStart, store.setState);
2236
+ useDirectStoreUpdater('onNodeDragEnd', onNodeDragEnd, store.setState);
2237
+ useDirectStoreUpdater('onEdgesChange', onEdgesChange, store.setState);
2238
+ useDirectStoreUpdater('onConnect', onConnect, store.setState);
2239
+ useDirectStoreUpdater('onConnectStart', onConnectStart, store.setState);
2240
+ useDirectStoreUpdater('onConnectEnd', onConnectEnd, store.setState);
2241
+ useDirectStoreUpdater('onError', onErrorWrapper(onError), store.setState);
2242
+ return null;
2243
+ };
2244
+
2245
+ function useNodeOrEdgeTypes(nodeOrEdgeTypes, createTypes) {
2246
+ const typesKeysRef = useRef(null);
2247
+ const typesParsed = useMemo(() => {
2248
+ if (process.env.NODE_ENV === 'development') {
2249
+ const typeKeys = Object.keys(nodeOrEdgeTypes);
2250
+ if (shallow(typesKeysRef.current, typeKeys)) {
2251
+ devWarn('002');
2252
+ }
2253
+ typesKeysRef.current = typeKeys;
2254
+ }
2255
+ return createTypes(nodeOrEdgeTypes);
2256
+ }, [nodeOrEdgeTypes]);
2257
+ return typesParsed;
2013
2258
  }
2014
2259
 
2015
- function useDrag({ nodeRef, nodeId, isSelectable, noDragClassName, }) {
2260
+ const NodeIdContext = createContext(null);
2261
+ const Provider = NodeIdContext.Provider;
2262
+ NodeIdContext.Consumer;
2263
+ const useNodeId = () => {
2264
+ const nodeId = useContext(NodeIdContext);
2265
+ return nodeId;
2266
+ };
2267
+
2268
+ function Port({ type, position }) {
2016
2269
  const store = useStoreApi();
2017
- const dragItems = useRef([]);
2018
- const containerBounds = useRef(null);
2019
- const mousePosition = useRef({ x: 0, y: 0 });
2020
- const lastPosition = useRef({
2021
- x: null,
2022
- y: null,
2023
- });
2024
- const dragEvent = useRef(null);
2025
- const autoPanStarted = useRef(false);
2026
- const autoPanId = useRef(0);
2027
- const [dragging, setDragging] = useState(false);
2028
- const getPointerPosition = useGetPointerPosition();
2029
- useEffect(() => {
2030
- if (nodeRef?.current) {
2031
- const selection = select(nodeRef.current);
2032
- const updateNodes = ({ x, y }) => {
2033
- const { nodeInternals, onNodeDrag, updateNodePositions, nodeExtent, nodeOrigin, gridStep, onError, } = store.getState();
2034
- lastPosition.current = { x, y };
2035
- let hasChange = false;
2036
- dragItems.current = dragItems.current.map((n) => {
2037
- const nextPosition = {
2038
- x: x - n.distance.x,
2039
- y: y - n.distance.y,
2040
- };
2041
- if (gridStep) {
2042
- nextPosition.x =
2043
- gridStep[0] * Math.round(nextPosition.x / gridStep[0]);
2044
- nextPosition.y =
2045
- gridStep[1] * Math.round(nextPosition.y / gridStep[1]);
2046
- }
2047
- const updatedPos = calcNextPosition(n, nextPosition, nodeInternals, nodeExtent, nodeOrigin, onError);
2048
- // we want to make sure that we only fire a change event when there is a changes
2049
- hasChange =
2050
- hasChange ||
2051
- n.position.x !== updatedPos.position.x ||
2052
- n.position.y !== updatedPos.position.y;
2053
- n.position = updatedPos.position;
2054
- n.positionAbsolute = updatedPos.positionAbsolute;
2055
- return n;
2056
- });
2057
- if (!hasChange) {
2058
- return;
2059
- }
2060
- updateNodePositions(dragItems.current, true, true);
2061
- setDragging(true);
2062
- if (onNodeDrag && dragEvent.current) {
2063
- const [currentNode, nodes] = getEventHandlerParams({
2064
- nodeId,
2065
- dragItems: dragItems.current,
2066
- nodeInternals,
2067
- });
2068
- onNodeDrag(dragEvent.current, currentNode, nodes);
2069
- }
2070
- };
2071
- const autoPan = () => {
2072
- if (!containerBounds.current) {
2073
- return;
2074
- }
2075
- const [xMovement, yMovement] = calcAutoPanPosition(mousePosition.current, containerBounds.current);
2076
- if (xMovement !== 0 || yMovement !== 0) {
2077
- const { transform, panBy } = store.getState();
2078
- lastPosition.current.x =
2079
- (lastPosition.current.x ?? 0) - xMovement / transform[2];
2080
- lastPosition.current.y =
2081
- (lastPosition.current.y ?? 0) - yMovement / transform[2];
2082
- updateNodes(lastPosition.current);
2083
- panBy({ x: xMovement, y: yMovement });
2084
- }
2085
- autoPanId.current = requestAnimationFrame(autoPan);
2086
- };
2087
- const dragHandle = drag()
2088
- .on('start', (e) => {
2089
- // only allow left click
2090
- if (e.sourceEvent.which !== 1)
2091
- return;
2092
- const { nodeInternals, nodesDraggable, domNode, onNodeDragStart, } = store.getState();
2093
- if (nodeId) {
2094
- handleNodeClick({
2095
- id: nodeId,
2096
- store,
2097
- nodeRef: nodeRef,
2098
- isSelectable,
2099
- });
2100
- }
2101
- const pointerPosition = getPointerPosition(e);
2102
- dragItems.current = getDragItems(nodeInternals, nodesDraggable, pointerPosition, nodeId);
2103
- if (onNodeDragStart && dragItems.current) {
2104
- const [currentNode, nodes] = getEventHandlerParams({
2105
- nodeId,
2106
- dragItems: dragItems.current,
2107
- nodeInternals,
2108
- });
2109
- onNodeDragStart(e.sourceEvent, currentNode, nodes);
2110
- }
2111
- containerBounds.current =
2112
- domNode?.getBoundingClientRect() || null;
2113
- mousePosition.current = getEventPosition(e.sourceEvent, containerBounds.current);
2114
- })
2115
- .on('drag', (e) => {
2116
- const pointerPosition = getPointerPosition(e);
2117
- const { autoPanOnNodeDrag } = store.getState();
2118
- if (!autoPanStarted.current && autoPanOnNodeDrag) {
2119
- autoPanStarted.current = true;
2120
- autoPan();
2121
- }
2122
- if ((lastPosition.current.x !== pointerPosition.xSnapped ||
2123
- lastPosition.current.y !== pointerPosition.ySnapped) &&
2124
- dragItems.current) {
2125
- dragEvent.current = e.sourceEvent;
2126
- mousePosition.current = getEventPosition(e.sourceEvent, containerBounds.current);
2127
- updateNodes(pointerPosition);
2128
- }
2129
- })
2130
- .on('end', (event) => {
2131
- setDragging(false);
2132
- autoPanStarted.current = false;
2133
- cancelAnimationFrame(autoPanId.current);
2134
- if (dragItems.current) {
2135
- const { nodeInternals, updateNodePositions, onNodeDragEnd } = store.getState();
2136
- updateNodePositions(dragItems.current, false, false);
2137
- if (onNodeDragEnd) {
2138
- const [currentNode, nodes] = getEventHandlerParams({
2139
- nodeId,
2140
- dragItems: dragItems.current,
2141
- nodeInternals,
2142
- });
2143
- onNodeDragEnd(event.sourceEvent, currentNode, nodes);
2144
- }
2145
- }
2146
- })
2147
- .filter((event) => {
2148
- const target = event.target;
2149
- const isDraggable = (!event.button && !noDragClassName) ||
2150
- !hasSelector(target, `.${noDragClassName}`, nodeRef);
2151
- return isDraggable;
2270
+ const nodeId = useNodeId();
2271
+ if (!nodeId)
2272
+ return null;
2273
+ const handleOnConnect = (connection) => {
2274
+ const { defaultEdgeOptions, onConnect } = store.getState();
2275
+ const edgeParams = {
2276
+ ...defaultEdgeOptions,
2277
+ ...connection,
2278
+ };
2279
+ onConnect?.(edgeParams);
2280
+ };
2281
+ const onPointerDown = (event) => {
2282
+ const isMouseTriggered = isMouseEvent(event);
2283
+ if ((isMouseTriggered && event.button === 0) || !isMouseTriggered) {
2284
+ handlePointerDown({
2285
+ event,
2286
+ nodeId,
2287
+ portType: type,
2288
+ getState: store.getState,
2289
+ setState: store.setState,
2290
+ onConnect: handleOnConnect,
2152
2291
  });
2153
- selection.call(dragHandle);
2154
- return () => {
2155
- selection.on('.drag', null);
2156
- };
2157
2292
  }
2158
- }, [store, nodeRef, nodeId, isSelectable, noDragClassName]);
2159
- return dragging;
2293
+ };
2294
+ return (jsx("div", { "data-nodeid": nodeId, "data-id": `${nodeId}-${type}`, "data-port-position": position, className: `react-diagram__port react-diagram__port-${position} ${type} nodrag`, onMouseDown: onPointerDown, onTouchStart: onPointerDown }));
2295
+ }
2296
+ Port.displayName = 'Port';
2297
+ var Port$1 = memo(Port);
2298
+
2299
+ function Nodes({ data }) {
2300
+ return (jsxs(Fragment, { children: [jsx(Port$1, { type: "target", position: Position.Top }), data.label, jsx(Port$1, { type: "source", position: Position.Bottom })] }));
2160
2301
  }
2161
2302
 
2162
2303
  const wrapNode = (NodeComponent) => {
2163
- function NodeWrapper({ id, type, data, positionX, positionY, sourcePosition, targetPosition, onClick, onMouseEnter, onMouseMove, onMouseLeave, onContextMenu, onDoubleClick, style, className, selected, isSelectable, isDraggable, hidden, resizeObserver, dragHandle, zIndex, isParent, initialized, disableKeyboardA11y, ariaLabel, rfId, noDragClassName, noPanClassName, }) {
2304
+ function NodeWrapper({ id, type, data, positionX, positionY, sourcePosition, targetPosition, onClick, onMouseEnter, onMouseMove, onMouseLeave, onContextMenu, onDoubleClick, style, width, height, className, selected, isSelectable, isDraggable, intersected, hidden, resizeObserver, dragHandle, zIndex, isParent, initialized, disableKeyboardA11y, ariaLabel, rfId, noDragClassName, noPanClassName, }) {
2164
2305
  const store = useStoreApi();
2165
2306
  const nodeRef = useRef(null);
2166
2307
  const prevSourcePosition = useRef(sourcePosition);
@@ -2228,6 +2369,7 @@ const wrapNode = (NodeComponent) => {
2228
2369
  className,
2229
2370
  {
2230
2371
  selected,
2372
+ intersected,
2231
2373
  parent: isParent,
2232
2374
  dragging,
2233
2375
  },
@@ -2237,15 +2379,17 @@ const wrapNode = (NodeComponent) => {
2237
2379
  transform: `translate(${positionX}px,${positionY}px)`,
2238
2380
  pointerEvents: hasPointerEvents ? 'all' : 'none',
2239
2381
  visibility: initialized ? 'visible' : 'hidden',
2382
+ width,
2383
+ height,
2240
2384
  ...style,
2241
2385
  };
2242
2386
  const events = {
2243
2387
  onClick: onSelectNodeHandler,
2244
- onDoubleClick: getMouseHandler(id, store.getState, onDoubleClick),
2245
- onContextMenu: getMouseHandler(id, store.getState, onContextMenu),
2246
- onMouseEnter: getMouseHandler(id, store.getState, onMouseEnter),
2247
- onMouseMove: getMouseHandler(id, store.getState, onMouseMove),
2248
- onMouseLeave: getMouseHandler(id, store.getState, onMouseLeave),
2388
+ onDoubleClick: getMouseHandler$1(id, store.getState, onDoubleClick),
2389
+ onContextMenu: getMouseHandler$1(id, store.getState, onContextMenu),
2390
+ onMouseEnter: getMouseHandler$1(id, store.getState, onMouseEnter),
2391
+ onMouseMove: getMouseHandler$1(id, store.getState, onMouseMove),
2392
+ onMouseLeave: getMouseHandler$1(id, store.getState, onMouseLeave),
2249
2393
  };
2250
2394
  const position = {
2251
2395
  positionX,
@@ -2339,17 +2483,49 @@ function createNodeInternals(nodes, nodeInternals, nodeOrigin, elevateNodesOnSel
2339
2483
  z,
2340
2484
  },
2341
2485
  });
2486
+ // console.log('create', currInternals, node);
2342
2487
  nextNodeInternals.set(node.id, internals);
2343
2488
  });
2344
2489
  updateAbsoluteNodePositions(nextNodeInternals, nodeOrigin, parentNodes);
2345
2490
  return nextNodeInternals;
2346
2491
  }
2347
- function updateNodesSelections({ changedNodes, get, }) {
2348
- const { onNodesChange } = get();
2349
- if (changedNodes?.length) {
2350
- onNodesChange?.(changedNodes);
2351
- }
2352
- }
2492
+ // export function handleControlledNodeSelectionChange(
2493
+ // nodeChanges: NodeSelectionChange[],
2494
+ // nodeInternals: NodeInternals,
2495
+ // ) {
2496
+ // nodeChanges.forEach((change) => {
2497
+ // const node = nodeInternals.get(change.id);
2498
+ // if (node) {
2499
+ // nodeInternals.set(node.id, {
2500
+ // ...node,
2501
+ // [internalsSymbol]: node[internalsSymbol],
2502
+ // selected: change.selected,
2503
+ // });
2504
+ // }
2505
+ // });
2506
+ // return new Map(nodeInternals);
2507
+ // }
2508
+ // export function handleControlledEdgeSelectionChange(
2509
+ // edgeChanges: EdgeSelectionChange[],
2510
+ // edges: Edge[],
2511
+ // ) {
2512
+ // return edges.map((e) => {
2513
+ // const change = edgeChanges.find((change) => change.id === e.id);
2514
+ // if (change) {
2515
+ // e.selected = change.selected;
2516
+ // }
2517
+ // return e;
2518
+ // });
2519
+ // }
2520
+ // export function updateNodesSelections({
2521
+ // changedNodes,
2522
+ // get,
2523
+ // }: UpdateNodesParams) {
2524
+ // const { onNodesChange } = get();
2525
+ // if (changedNodes?.length) {
2526
+ // onNodesChange?.(changedNodes);
2527
+ // }
2528
+ // }
2353
2529
 
2354
2530
  const infiniteExtent = [
2355
2531
  [Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY],
@@ -2366,11 +2542,13 @@ const initialState = {
2366
2542
  onNodesChange: null,
2367
2543
  domNode: null,
2368
2544
  nodeOrigin: [0, 0],
2545
+ smoothStep: false,
2546
+ centerStep: false,
2369
2547
  gridStep: undefined,
2370
- nodesSelectionActive: false,
2371
2548
  elevateNodesOnSelect: true,
2372
2549
  nodesDraggable: true,
2373
2550
  multiSelectionActive: false,
2551
+ selectionBoxActive: false,
2374
2552
  d3Zoom: null,
2375
2553
  d3Selection: null,
2376
2554
  minZoom: 0.5,
@@ -2445,17 +2623,21 @@ const createRFStore = () => createStore((set, get) => ({
2445
2623
  onNodesChange?.(changes);
2446
2624
  }
2447
2625
  },
2448
- updateNodePositions: (nodeDragItems, positionChanged = true, dragging = false) => {
2626
+ updateNodesPosition: (nodes, dragging = false, updateFunc) => {
2449
2627
  const { triggerNodeChanges } = get();
2450
- const changes = nodeDragItems.map((node) => {
2628
+ const changes = nodes.map((node) => {
2451
2629
  const change = {
2452
2630
  id: node.id,
2453
2631
  type: 'position',
2454
2632
  dragging,
2455
2633
  };
2456
- if (positionChanged) {
2457
- change.positionAbsolute = node.positionAbsolute;
2458
- change.position = node.position;
2634
+ if (updateFunc) {
2635
+ updateFunc(node);
2636
+ return {
2637
+ ...change,
2638
+ position: node.position,
2639
+ positionAbsolute: node.positionAbsolute,
2640
+ };
2459
2641
  }
2460
2642
  return change;
2461
2643
  });
@@ -2468,7 +2650,7 @@ const createRFStore = () => createStore((set, get) => ({
2468
2650
  }
2469
2651
  },
2470
2652
  addSelectedNodes: (selectedNodeIds) => {
2471
- const { multiSelectionActive, getNodes } = get();
2653
+ const { multiSelectionActive, getNodes, triggerNodeChanges } = get();
2472
2654
  let changedNodes;
2473
2655
  if (multiSelectionActive) {
2474
2656
  changedNodes = selectedNodeIds.map((nodeId) => createSelectionChange(nodeId, true));
@@ -2476,36 +2658,24 @@ const createRFStore = () => createStore((set, get) => ({
2476
2658
  else {
2477
2659
  changedNodes = getSelectionChanges(getNodes(), selectedNodeIds);
2478
2660
  }
2479
- updateNodesSelections({
2480
- changedNodes,
2481
- get,
2482
- set,
2483
- });
2661
+ triggerNodeChanges(changedNodes);
2484
2662
  },
2485
2663
  unselectNodes: ({ nodes } = {}) => {
2486
- const { getNodes } = get();
2664
+ const { getNodes, triggerNodeChanges } = get();
2487
2665
  const nodesToUnselect = nodes ? nodes : getNodes();
2488
2666
  const changedNodes = nodesToUnselect.map((n) => {
2489
2667
  n.selected = false;
2490
2668
  return createSelectionChange(n.id, false);
2491
2669
  });
2492
- updateNodesSelections({
2493
- changedNodes,
2494
- get,
2495
- set,
2496
- });
2670
+ triggerNodeChanges(changedNodes);
2497
2671
  },
2498
2672
  resetSelectedElements: () => {
2499
- const { getNodes } = get();
2673
+ const { getNodes, triggerNodeChanges } = get();
2500
2674
  const nodes = getNodes();
2501
2675
  const nodesToUnselect = nodes
2502
2676
  .filter((e) => e.selected)
2503
2677
  .map((n) => createSelectionChange(n.id, false));
2504
- updateNodesSelections({
2505
- changedNodes: nodesToUnselect,
2506
- get,
2507
- set,
2508
- });
2678
+ triggerNodeChanges(nodesToUnselect);
2509
2679
  },
2510
2680
  cancelConnection: () => set({
2511
2681
  connectionNodeId: initialState.connectionNodeId,
@@ -2578,15 +2748,15 @@ const defaultNodeTypes = {
2578
2748
  const defaultEdgeTypes = {
2579
2749
  step: StepEdge,
2580
2750
  };
2581
- const ReactDiagram = forwardRef(({ id,
2751
+ const ReactDiagram = forwardRef(({ children, id,
2582
2752
  // DiagramView props
2583
2753
  panning = true, minZoom, maxZoom, translateExtent, nodeExtent, defaultViewport = initViewport, multiSelectionKeyCode, onlyRenderVisibleElements = false, disableKeyboardA11y = false, noDragClassName = 'nodrag', noPanClassName = 'nopan', nodeOrigin = initNodeOrigin, nodeTypes = defaultNodeTypes, onNodeClick, onNodeDoubleClick, onNodeContextMenu, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, edgeTypes = defaultEdgeTypes, edgeUpdaterRadius, onEdgeClick, onEdgeDoubleClick, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeUpdate, onEdgeUpdateStart, onEdgeUpdateEnd, onMove, onMoveStart, onMoveEnd, ConnectionLineContainerStyle, ConnectionLineComponent,
2584
2754
  // StoreUpdater props
2585
- nodes, edges, nodesDraggable, elevateNodesOnSelect, autoPanOnNodeDrag, autoPanOnConnect, connectionRadius, onNodesChange, onNodeDrag, onNodeDragStart, onNodeDragEnd, onEdgesChange, onConnect, onConnectStart, onConnectEnd, onError, }, ref) => {
2755
+ nodes, edges, nodesDraggable, elevateNodesOnSelect, autoPanOnNodeDrag, autoPanOnConnect, connectionRadius, smoothStep, centerStep, gridStep, onNodesChange, onNodeDrag, onNodeDragStart, onNodeDragEnd, onEdgesChange, onConnect, onConnectStart, onConnectEnd, onError, }, ref) => {
2586
2756
  const rfId = id || '1';
2587
2757
  const nodeTypesWrapped = useNodeOrEdgeTypes(nodeTypes, createNodeTypes);
2588
2758
  const edgeTypesWrapped = useNodeOrEdgeTypes(edgeTypes, createEdgeTypes);
2589
- return (jsx("div", { ref: ref, className: "react-diagram", children: jsxs(Wrapper, { children: [jsx(DiagramView$1, { rfId: rfId, panning: panning, defaultViewport: defaultViewport, multiSelectionKeyCode: multiSelectionKeyCode, onlyRenderVisibleElements: onlyRenderVisibleElements, disableKeyboardA11y: disableKeyboardA11y, noDragClassName: noDragClassName, noPanClassName: noPanClassName, nodeOrigin: nodeOrigin, nodeTypes: nodeTypesWrapped, edgeTypes: edgeTypesWrapped, edgeUpdaterRadius: edgeUpdaterRadius, ConnectionLineContainerStyle: ConnectionLineContainerStyle, ConnectionLineComponent: ConnectionLineComponent, onNodeClick: onNodeClick, onNodeDoubleClick: onNodeDoubleClick, onNodeContextMenu: onNodeContextMenu, onNodeMouseEnter: onNodeMouseEnter, onNodeMouseMove: onNodeMouseMove, onNodeMouseLeave: onNodeMouseLeave, onEdgeClick: onEdgeClick, onEdgeDoubleClick: onEdgeDoubleClick, onEdgeContextMenu: onEdgeContextMenu, onEdgeMouseEnter: onEdgeMouseEnter, onEdgeMouseMove: onEdgeMouseMove, onEdgeMouseLeave: onEdgeMouseLeave, onEdgeUpdate: onEdgeUpdate, onEdgeUpdateStart: onEdgeUpdateStart, onEdgeUpdateEnd: onEdgeUpdateEnd, onMove: onMove, onMoveStart: onMoveStart, onMoveEnd: onMoveEnd }), jsx(StoreUpdater, { rfId: rfId, nodes: nodes, edges: edges, nodesDraggable: nodesDraggable, elevateNodesOnSelect: elevateNodesOnSelect, autoPanOnNodeDrag: autoPanOnNodeDrag, autoPanOnConnect: autoPanOnConnect, connectionRadius: connectionRadius, nodeExtent: nodeExtent, translateExtent: translateExtent, minZoom: minZoom, maxZoom: maxZoom, onNodesChange: onNodesChange, onNodeDrag: onNodeDrag, onNodeDragStart: onNodeDragStart, onNodeDragEnd: onNodeDragEnd, onEdgesChange: onEdgesChange, onConnect: onConnect, onConnectStart: onConnectStart, onConnectEnd: onConnectEnd, onError: onError })] }) }));
2759
+ return (jsx("div", { ref: ref, className: "react-diagram", children: jsxs(Wrapper, { children: [jsx(DiagramView$1, { rfId: rfId, panning: panning, defaultViewport: defaultViewport, multiSelectionKeyCode: multiSelectionKeyCode, onlyRenderVisibleElements: onlyRenderVisibleElements, disableKeyboardA11y: disableKeyboardA11y, noDragClassName: noDragClassName, noPanClassName: noPanClassName, nodeOrigin: nodeOrigin, nodeTypes: nodeTypesWrapped, edgeTypes: edgeTypesWrapped, edgeUpdaterRadius: edgeUpdaterRadius, ConnectionLineContainerStyle: ConnectionLineContainerStyle, ConnectionLineComponent: ConnectionLineComponent, onNodeClick: onNodeClick, onNodeDoubleClick: onNodeDoubleClick, onNodeContextMenu: onNodeContextMenu, onNodeMouseEnter: onNodeMouseEnter, onNodeMouseMove: onNodeMouseMove, onNodeMouseLeave: onNodeMouseLeave, onEdgeClick: onEdgeClick, onEdgeDoubleClick: onEdgeDoubleClick, onEdgeContextMenu: onEdgeContextMenu, onEdgeMouseEnter: onEdgeMouseEnter, onEdgeMouseMove: onEdgeMouseMove, onEdgeMouseLeave: onEdgeMouseLeave, onEdgeUpdate: onEdgeUpdate, onEdgeUpdateStart: onEdgeUpdateStart, onEdgeUpdateEnd: onEdgeUpdateEnd, onMove: onMove, onMoveStart: onMoveStart, onMoveEnd: onMoveEnd }), jsx(StoreUpdater, { rfId: rfId, nodes: nodes, edges: edges, nodesDraggable: nodesDraggable, elevateNodesOnSelect: elevateNodesOnSelect, autoPanOnNodeDrag: autoPanOnNodeDrag, autoPanOnConnect: autoPanOnConnect, connectionRadius: connectionRadius, nodeExtent: nodeExtent, translateExtent: translateExtent, minZoom: minZoom, maxZoom: maxZoom, smoothStep: smoothStep, centerStep: centerStep, gridStep: gridStep, onNodesChange: onNodesChange, onNodeDrag: onNodeDrag, onNodeDragStart: onNodeDragStart, onNodeDragEnd: onNodeDragEnd, onEdgesChange: onEdgesChange, onConnect: onConnect, onConnectStart: onConnectStart, onConnectEnd: onConnectEnd, onError: onError }), children] }) }));
2590
2760
  });
2591
2761
  ReactDiagram.displayName = 'ReactDiagram';
2592
2762
 
@@ -2600,4 +2770,35 @@ function createUseItemsState(applyChanges) {
2600
2770
  const useNodesState = createUseItemsState(applyNodeChanges);
2601
2771
  const useEdgesState = createUseItemsState(applyEdgeChanges);
2602
2772
 
2603
- export { BaseEdge, BezierEdge, MarkerType, Port$1 as Port, Position, ReactDiagramProvider, StepEdge, addEdge, boxToRect, clamp, ReactDiagram as default, getBezierPath, getStepPath, internalsSymbol, isEdge, isNode, rectToBox, updateEdge, useEdgesState, useNodesState };
2773
+ function LinePath({ color, scaledGap, lineWidth }) {
2774
+ const m1 = `M${scaledGap[0] / 2} 0`;
2775
+ const v = `V${scaledGap[1]}`;
2776
+ const m2 = `M0 ${scaledGap[1] / 2}`;
2777
+ const h = `H${scaledGap[0]}`;
2778
+ const path = `${m1} ${v} ${m2} ${h}`;
2779
+ return jsx("path", { stroke: color, strokeWidth: lineWidth, d: path });
2780
+ }
2781
+
2782
+ const selector = (s) => ({
2783
+ transform: s.transform,
2784
+ rfId: s.rfId,
2785
+ gridStepGap: s.gridStep,
2786
+ });
2787
+ function Background({ gap, lineWidth = 1, color = '#000000', }) {
2788
+ const ref = useRef(null);
2789
+ const { transform, rfId, gridStepGap } = useStore(selector, shallow);
2790
+ const defaultGap = gap ? gap : gridStepGap ? gridStepGap : 50;
2791
+ const gapXY = Array.isArray(defaultGap)
2792
+ ? defaultGap
2793
+ : [defaultGap, defaultGap];
2794
+ const scaledGap = [
2795
+ gapXY[0] * transform[2] || 1,
2796
+ gapXY[1] * transform[2] || 1,
2797
+ ];
2798
+ const patternOffset = [scaledGap[0] / 2, scaledGap[1] / 2];
2799
+ return (jsxs("svg", { className: "react-diagram__container react-diagram__background", ref: ref, children: [jsx("pattern", { id: `background-${rfId}`, x: transform[0] % scaledGap[0], y: transform[1] % scaledGap[1], width: scaledGap[0], height: scaledGap[1], patternUnits: "userSpaceOnUse", patternTransform: `translate(-${patternOffset[0]},-${patternOffset[1]})`, children: jsx(LinePath, { scaledGap: scaledGap, color: color, lineWidth: lineWidth }) }), jsx("rect", { x: "0", y: "0", width: "100%", height: "100%", fill: `url(#${`background-${rfId}`})` })] }));
2800
+ }
2801
+ Background.displayName = 'Background';
2802
+ var index = memo(Background);
2803
+
2804
+ export { index as Background, BaseEdge, BezierEdge, MarkerType, Port$1 as Port, Position, ReactDiagramProvider, StepEdge, addEdge, boxToRect, clamp, ReactDiagram as default, getBezierPath, getStepPath, internalsSymbol, isEdge, isNode, rectToBox, updateEdge, useEdgesState, useNodesState };