@xyflow/react 12.0.0-next.12 → 12.0.0-next.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base.css +7 -0
- package/dist/esm/additional-components/Controls/Controls.d.ts +1 -1
- package/dist/esm/additional-components/Controls/Controls.d.ts.map +1 -1
- package/dist/esm/additional-components/Controls/types.d.ts +1 -0
- package/dist/esm/additional-components/Controls/types.d.ts.map +1 -1
- package/dist/esm/additional-components/MiniMap/MiniMap.d.ts.map +1 -1
- package/dist/esm/additional-components/MiniMap/MiniMapNodes.d.ts.map +1 -1
- package/dist/esm/additional-components/NodeResizer/NodeResizeControl.d.ts.map +1 -1
- package/dist/esm/components/ConnectionLine/index.d.ts.map +1 -1
- package/dist/esm/components/NodeWrapper/index.d.ts.map +1 -1
- package/dist/esm/components/NodeWrapper/utils.d.ts +2 -2
- package/dist/esm/components/NodeWrapper/utils.d.ts.map +1 -1
- package/dist/esm/components/NodesSelection/index.d.ts.map +1 -1
- package/dist/esm/components/StoreUpdater/index.d.ts.map +1 -1
- package/dist/esm/container/NodeRenderer/useResizeObserver.d.ts.map +1 -1
- package/dist/esm/container/Pane/index.d.ts.map +1 -1
- package/dist/esm/hooks/useInternalNode.d.ts +10 -0
- package/dist/esm/hooks/useInternalNode.d.ts.map +1 -0
- package/dist/esm/hooks/useKeyPress.d.ts.map +1 -1
- package/dist/esm/hooks/useMoveSelectedNodes.d.ts.map +1 -1
- package/dist/esm/hooks/useNodesInitialized.d.ts.map +1 -1
- package/dist/esm/hooks/useReactFlow.d.ts.map +1 -1
- package/dist/esm/index.d.ts +3 -2
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +160 -172
- package/dist/esm/index.mjs +160 -172
- package/dist/esm/store/index.d.ts.map +1 -1
- package/dist/esm/types/general.d.ts +2 -2
- package/dist/esm/types/general.d.ts.map +1 -1
- package/dist/esm/types/index.d.ts +0 -1
- package/dist/esm/types/index.d.ts.map +1 -1
- package/dist/esm/types/instance.d.ts +9 -1
- package/dist/esm/types/instance.d.ts.map +1 -1
- package/dist/esm/types/nodes.d.ts +2 -1
- package/dist/esm/types/nodes.d.ts.map +1 -1
- package/dist/esm/types/store.d.ts +4 -4
- package/dist/esm/types/store.d.ts.map +1 -1
- package/dist/esm/utils/changes.d.ts +4 -5
- package/dist/esm/utils/changes.d.ts.map +1 -1
- package/dist/style.css +8 -3
- package/dist/umd/additional-components/Controls/Controls.d.ts +1 -1
- package/dist/umd/additional-components/Controls/Controls.d.ts.map +1 -1
- package/dist/umd/additional-components/Controls/types.d.ts +1 -0
- package/dist/umd/additional-components/Controls/types.d.ts.map +1 -1
- package/dist/umd/additional-components/MiniMap/MiniMap.d.ts.map +1 -1
- package/dist/umd/additional-components/MiniMap/MiniMapNodes.d.ts.map +1 -1
- package/dist/umd/additional-components/NodeResizer/NodeResizeControl.d.ts.map +1 -1
- package/dist/umd/components/ConnectionLine/index.d.ts.map +1 -1
- package/dist/umd/components/NodeWrapper/index.d.ts.map +1 -1
- package/dist/umd/components/NodeWrapper/utils.d.ts +2 -2
- package/dist/umd/components/NodeWrapper/utils.d.ts.map +1 -1
- package/dist/umd/components/NodesSelection/index.d.ts.map +1 -1
- package/dist/umd/components/StoreUpdater/index.d.ts.map +1 -1
- package/dist/umd/container/NodeRenderer/useResizeObserver.d.ts.map +1 -1
- package/dist/umd/container/Pane/index.d.ts.map +1 -1
- package/dist/umd/hooks/useInternalNode.d.ts +10 -0
- package/dist/umd/hooks/useInternalNode.d.ts.map +1 -0
- package/dist/umd/hooks/useKeyPress.d.ts.map +1 -1
- package/dist/umd/hooks/useMoveSelectedNodes.d.ts.map +1 -1
- package/dist/umd/hooks/useNodesInitialized.d.ts.map +1 -1
- package/dist/umd/hooks/useReactFlow.d.ts.map +1 -1
- package/dist/umd/index.d.ts +3 -2
- package/dist/umd/index.d.ts.map +1 -1
- package/dist/umd/index.js +2 -2
- package/dist/umd/store/index.d.ts.map +1 -1
- package/dist/umd/types/general.d.ts +2 -2
- package/dist/umd/types/general.d.ts.map +1 -1
- package/dist/umd/types/index.d.ts +0 -1
- package/dist/umd/types/index.d.ts.map +1 -1
- package/dist/umd/types/instance.d.ts +9 -1
- package/dist/umd/types/instance.d.ts.map +1 -1
- package/dist/umd/types/nodes.d.ts +2 -1
- package/dist/umd/types/nodes.d.ts.map +1 -1
- package/dist/umd/types/store.d.ts +4 -4
- package/dist/umd/types/store.d.ts.map +1 -1
- package/dist/umd/utils/changes.d.ts +4 -5
- package/dist/umd/utils/changes.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/esm/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import cc from 'classcat';
|
|
4
|
-
import { errorMessages, infiniteExtent, isInputDOMNode, fitView, getViewportForBounds, pointToRendererPoint, rendererPointToPoint, isNodeBase, isEdgeBase, getElementsToRemove,
|
|
5
|
-
export { ConnectionLineType, ConnectionMode, MarkerType, PanOnScrollMode, Position, SelectionMode, addEdge, getBezierEdgeCenter, getBezierPath, getConnectedEdges, getEdgeCenter, getIncomers, getNodesBounds, getOutgoers, getSmoothStepPath, getStraightPath, getViewportForBounds,
|
|
4
|
+
import { errorMessages, infiniteExtent, isInputDOMNode, fitView, getViewportForBounds, pointToRendererPoint, rendererPointToPoint, isNodeBase, isEdgeBase, getElementsToRemove, nodeToRect, isRectObject, getOverlappingArea, getDimensions, XYPanZoom, PanOnScrollMode, SelectionMode, getEventPosition, getNodesInside, XYDrag, snapPosition, calculateNodePosition, Position, ConnectionMode, isMouseEvent, XYHandle, getHostForElement, addEdge, getNodesBounds, clampPosition, getNodeDimensions, nodeHasDimensions, getPositionWithOrigin, elementSelectionKeys, isEdgeVisible, MarkerType, createMarkerIds, isNumeric, getBezierEdgeCenter, getSmoothStepPath, getStraightPath, getBezierPath, getEdgePosition, getElevatedEdgeZIndex, getMarkerId, ConnectionLineType, updateConnectionLookup, adoptUserNodes, devWarn, updateNodeDimensions, updateAbsolutePositions, handleParentExpand, panBy, isMacOs, areConnectionMapsEqual, handleConnectionChange, shallowNodeData, getNodePositionWithOrigin, XYMinimap, getBoundsOfRects, getInternalNodesBounds, ResizeControlVariant, XYResizer, XY_RESIZER_LINE_POSITIONS, XY_RESIZER_HANDLE_POSITIONS, getNodeToolbarTransform } from '@xyflow/system';
|
|
5
|
+
export { ConnectionLineType, ConnectionMode, MarkerType, PanOnScrollMode, Position, SelectionMode, addEdge, getBezierEdgeCenter, getBezierPath, getConnectedEdges, getEdgeCenter, getIncomers, getNodesBounds, getOutgoers, getSmoothStepPath, getStraightPath, getViewportForBounds, updateEdge } from '@xyflow/system';
|
|
6
6
|
import { createContext, useContext, useMemo, useEffect, useRef, useState, forwardRef, useLayoutEffect, useCallback, memo } from 'react';
|
|
7
7
|
import { useStoreWithEqualityFn, createWithEqualityFn } from 'zustand/traditional';
|
|
8
8
|
import { shallow } from 'zustand/shallow';
|
|
@@ -83,7 +83,7 @@ function Attribution({ proOptions, position = 'bottom-right' }) {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
const selector$o = (s) => ({
|
|
86
|
-
selectedNodes: s.
|
|
86
|
+
selectedNodes: Array.from(s.nodeLookup.values()).filter((n) => n.selected),
|
|
87
87
|
selectedEdges: s.edges.filter((e) => e.selected),
|
|
88
88
|
});
|
|
89
89
|
const selectId = (obj) => obj.id;
|
|
@@ -356,10 +356,12 @@ keyCode = null, options = { target: defaultDoc, actInsideInputWithModifier: true
|
|
|
356
356
|
target?.addEventListener('keydown', downHandler);
|
|
357
357
|
target?.addEventListener('keyup', upHandler);
|
|
358
358
|
window.addEventListener('blur', resetHandler);
|
|
359
|
+
window.addEventListener('contextmenu', resetHandler);
|
|
359
360
|
return () => {
|
|
360
361
|
target?.removeEventListener('keydown', downHandler);
|
|
361
362
|
target?.removeEventListener('keyup', upHandler);
|
|
362
363
|
window.removeEventListener('blur', resetHandler);
|
|
364
|
+
window.removeEventListener('contextmenu', resetHandler);
|
|
363
365
|
};
|
|
364
366
|
}
|
|
365
367
|
}, [keyCode, setKeyPressed]);
|
|
@@ -409,10 +411,10 @@ const useViewportHelper = () => {
|
|
|
409
411
|
return { x, y, zoom };
|
|
410
412
|
},
|
|
411
413
|
fitView: (options) => {
|
|
412
|
-
const {
|
|
414
|
+
const { nodeLookup, width, height, nodeOrigin, minZoom, maxZoom, panZoom } = store.getState();
|
|
413
415
|
return panZoom
|
|
414
416
|
? fitView({
|
|
415
|
-
|
|
417
|
+
nodeLookup,
|
|
416
418
|
width,
|
|
417
419
|
height,
|
|
418
420
|
nodeOrigin,
|
|
@@ -468,42 +470,6 @@ const useViewportHelper = () => {
|
|
|
468
470
|
return viewportHelperFunctions;
|
|
469
471
|
};
|
|
470
472
|
|
|
471
|
-
function handleParentExpand(updatedElements, updateItem) {
|
|
472
|
-
for (const [index, item] of updatedElements.entries()) {
|
|
473
|
-
if (item.id === updateItem.parentNode) {
|
|
474
|
-
const parent = { ...item };
|
|
475
|
-
parent.computed ??= {};
|
|
476
|
-
const extendWidth = updateItem.position.x + updateItem.computed.width - parent.computed.width;
|
|
477
|
-
const extendHeight = updateItem.position.y + updateItem.computed.height - parent.computed.height;
|
|
478
|
-
if (extendWidth > 0 || extendHeight > 0 || updateItem.position.x < 0 || updateItem.position.y < 0) {
|
|
479
|
-
parent.width = parent.width ?? parent.computed.width;
|
|
480
|
-
parent.height = parent.height ?? parent.computed.height;
|
|
481
|
-
if (extendWidth > 0) {
|
|
482
|
-
parent.width += extendWidth;
|
|
483
|
-
}
|
|
484
|
-
if (extendHeight > 0) {
|
|
485
|
-
parent.height += extendHeight;
|
|
486
|
-
}
|
|
487
|
-
if (updateItem.position.x < 0) {
|
|
488
|
-
const xDiff = Math.abs(updateItem.position.x);
|
|
489
|
-
parent.position.x = parent.position.x - xDiff;
|
|
490
|
-
parent.width += xDiff;
|
|
491
|
-
updateItem.position.x = 0;
|
|
492
|
-
}
|
|
493
|
-
if (updateItem.position.y < 0) {
|
|
494
|
-
const yDiff = Math.abs(updateItem.position.y);
|
|
495
|
-
parent.position.y = parent.position.y - yDiff;
|
|
496
|
-
parent.height += yDiff;
|
|
497
|
-
updateItem.position.y = 0;
|
|
498
|
-
}
|
|
499
|
-
parent.computed.width = parent.width;
|
|
500
|
-
parent.computed.height = parent.height;
|
|
501
|
-
updatedElements[index] = parent;
|
|
502
|
-
}
|
|
503
|
-
break;
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
473
|
// This function applies changes to nodes or edges that are triggered by React Flow internally.
|
|
508
474
|
// When you drag a node for example, React Flow will send a position change update.
|
|
509
475
|
// This function then applies the changes and returns the updated elements.
|
|
@@ -555,14 +521,14 @@ function applyChanges(changes, elements) {
|
|
|
555
521
|
/// each _mutate_ this object, so there's only ever one copy.
|
|
556
522
|
const updatedElement = { ...element };
|
|
557
523
|
for (const change of changes) {
|
|
558
|
-
applyChange(change, updatedElement
|
|
524
|
+
applyChange(change, updatedElement);
|
|
559
525
|
}
|
|
560
526
|
updatedElements.push(updatedElement);
|
|
561
527
|
}
|
|
562
528
|
return updatedElements;
|
|
563
529
|
}
|
|
564
530
|
// Applies a single change to an element. This is a *mutable* update.
|
|
565
|
-
function applyChange(change, element
|
|
531
|
+
function applyChange(change, element) {
|
|
566
532
|
switch (change.type) {
|
|
567
533
|
case 'select': {
|
|
568
534
|
element.selected = change.selected;
|
|
@@ -572,23 +538,16 @@ function applyChange(change, element, elements = []) {
|
|
|
572
538
|
if (typeof change.position !== 'undefined') {
|
|
573
539
|
element.position = change.position;
|
|
574
540
|
}
|
|
575
|
-
if (typeof change.positionAbsolute !== 'undefined') {
|
|
576
|
-
element.computed ??= {};
|
|
577
|
-
element.computed.positionAbsolute = change.positionAbsolute;
|
|
578
|
-
}
|
|
579
541
|
if (typeof change.dragging !== 'undefined') {
|
|
580
542
|
element.dragging = change.dragging;
|
|
581
543
|
}
|
|
582
|
-
if (element.expandParent) {
|
|
583
|
-
handleParentExpand(elements, element);
|
|
584
|
-
}
|
|
585
544
|
break;
|
|
586
545
|
}
|
|
587
546
|
case 'dimensions': {
|
|
588
547
|
if (typeof change.dimensions !== 'undefined') {
|
|
589
|
-
element.
|
|
590
|
-
element.
|
|
591
|
-
element.
|
|
548
|
+
element.measured ??= {};
|
|
549
|
+
element.measured.width = change.dimensions.width;
|
|
550
|
+
element.measured.height = change.dimensions.height;
|
|
592
551
|
if (change.resizing) {
|
|
593
552
|
element.width = change.dimensions.width;
|
|
594
553
|
element.height = change.dimensions.height;
|
|
@@ -597,9 +556,6 @@ function applyChange(change, element, elements = []) {
|
|
|
597
556
|
if (typeof change.resizing === 'boolean') {
|
|
598
557
|
element.resizing = change.resizing;
|
|
599
558
|
}
|
|
600
|
-
if (element.expandParent) {
|
|
601
|
-
handleParentExpand(elements, element);
|
|
602
|
-
}
|
|
603
559
|
break;
|
|
604
560
|
}
|
|
605
561
|
}
|
|
@@ -659,7 +615,7 @@ function createSelectionChange(id, selected) {
|
|
|
659
615
|
}
|
|
660
616
|
function getSelectionChanges(items, selectedIds = new Set(), mutateItem = false) {
|
|
661
617
|
const changes = [];
|
|
662
|
-
for (const item of items) {
|
|
618
|
+
for (const [, item] of items) {
|
|
663
619
|
const willBeSelected = selectedIds.has(item.id);
|
|
664
620
|
// we don't want to set all items to selected=false on the first selection
|
|
665
621
|
if (!(item.selected === undefined && !willBeSelected) && item.selected !== willBeSelected) {
|
|
@@ -729,12 +685,9 @@ const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffec
|
|
|
729
685
|
function useReactFlow() {
|
|
730
686
|
const viewportHelper = useViewportHelper();
|
|
731
687
|
const store = useStoreApi();
|
|
732
|
-
const getNodes = useCallback(() => {
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
const getNode = useCallback((id) => {
|
|
736
|
-
return store.getState().nodeLookup.get(id);
|
|
737
|
-
}, []);
|
|
688
|
+
const getNodes = useCallback(() => store.getState().nodes.map((n) => ({ ...n })), []);
|
|
689
|
+
const getInternalNode = useCallback((id) => store.getState().nodeLookup.get(id), []);
|
|
690
|
+
const getNode = useCallback((id) => getInternalNode(id)?.internals.userNode, [getInternalNode]);
|
|
738
691
|
const getEdges = useCallback(() => {
|
|
739
692
|
const { edges = [] } = store.getState();
|
|
740
693
|
return edges.map((e) => ({ ...e }));
|
|
@@ -872,11 +825,9 @@ function useReactFlow() {
|
|
|
872
825
|
}
|
|
873
826
|
return { deletedNodes: matchingNodes, deletedEdges: matchingEdges };
|
|
874
827
|
}, []);
|
|
875
|
-
const getNodeRect = useCallback((
|
|
876
|
-
const
|
|
877
|
-
|
|
878
|
-
: store.getState().nodeLookup.get(nodeOrRect.id);
|
|
879
|
-
return node ? nodeToRect(node) : null;
|
|
828
|
+
const getNodeRect = useCallback(({ id }) => {
|
|
829
|
+
const internalNode = store.getState().nodeLookup.get(id);
|
|
830
|
+
return internalNode ? nodeToRect(internalNode) : null;
|
|
880
831
|
}, []);
|
|
881
832
|
const getIntersectingNodes = useCallback((nodeOrRect, partially = true, nodes) => {
|
|
882
833
|
const isRect = isRectObject(nodeOrRect);
|
|
@@ -885,7 +836,8 @@ function useReactFlow() {
|
|
|
885
836
|
return [];
|
|
886
837
|
}
|
|
887
838
|
return (nodes || store.getState().nodes).filter((n) => {
|
|
888
|
-
|
|
839
|
+
const internalNode = store.getState().nodeLookup.get(n.id);
|
|
840
|
+
if (internalNode && !isRect && (n.id === nodeOrRect.id || !internalNode.internals.positionAbsolute)) {
|
|
889
841
|
return false;
|
|
890
842
|
}
|
|
891
843
|
const currNodeRect = nodeToRect(n);
|
|
@@ -924,6 +876,7 @@ function useReactFlow() {
|
|
|
924
876
|
...viewportHelper,
|
|
925
877
|
getNodes,
|
|
926
878
|
getNode,
|
|
879
|
+
getInternalNode,
|
|
927
880
|
getEdges,
|
|
928
881
|
getEdge,
|
|
929
882
|
setNodes,
|
|
@@ -941,6 +894,7 @@ function useReactFlow() {
|
|
|
941
894
|
viewportHelper,
|
|
942
895
|
getNodes,
|
|
943
896
|
getNode,
|
|
897
|
+
getInternalNode,
|
|
944
898
|
getEdges,
|
|
945
899
|
getEdge,
|
|
946
900
|
setNodes,
|
|
@@ -1190,7 +1144,7 @@ function Pane({ isSelecting, selectionMode = SelectionMode.Full, panOnDrag, onSe
|
|
|
1190
1144
|
onSelectionStart?.(event);
|
|
1191
1145
|
};
|
|
1192
1146
|
const onMouseMove = (event) => {
|
|
1193
|
-
const { userSelectionRect,
|
|
1147
|
+
const { userSelectionRect, edgeLookup, transform, nodeOrigin, nodeLookup, triggerNodeChanges, triggerEdgeChanges } = store.getState();
|
|
1194
1148
|
if (!isSelecting || !containerBounds.current || !userSelectionRect) {
|
|
1195
1149
|
return;
|
|
1196
1150
|
}
|
|
@@ -1205,25 +1159,25 @@ function Pane({ isSelecting, selectionMode = SelectionMode.Full, panOnDrag, onSe
|
|
|
1205
1159
|
width: Math.abs(mousePos.x - startX),
|
|
1206
1160
|
height: Math.abs(mousePos.y - startY),
|
|
1207
1161
|
};
|
|
1208
|
-
const selectedNodes = getNodesInside(
|
|
1162
|
+
const selectedNodes = getNodesInside(nodeLookup, nextUserSelectRect, transform, selectionMode === SelectionMode.Partial, true, nodeOrigin);
|
|
1209
1163
|
const selectedEdgeIds = new Set();
|
|
1210
1164
|
const selectedNodeIds = new Set();
|
|
1211
1165
|
for (const selectedNode of selectedNodes) {
|
|
1212
1166
|
selectedNodeIds.add(selectedNode.id);
|
|
1213
|
-
for (const edge of
|
|
1167
|
+
for (const [edgeId, edge] of edgeLookup) {
|
|
1214
1168
|
if (edge.source === selectedNode.id || edge.target === selectedNode.id) {
|
|
1215
|
-
selectedEdgeIds.add(
|
|
1169
|
+
selectedEdgeIds.add(edgeId);
|
|
1216
1170
|
}
|
|
1217
1171
|
}
|
|
1218
1172
|
}
|
|
1219
1173
|
if (prevSelectedNodesCount.current !== selectedNodeIds.size) {
|
|
1220
1174
|
prevSelectedNodesCount.current = selectedNodeIds.size;
|
|
1221
|
-
const changes = getSelectionChanges(
|
|
1175
|
+
const changes = getSelectionChanges(nodeLookup, selectedNodeIds, true);
|
|
1222
1176
|
triggerNodeChanges(changes);
|
|
1223
1177
|
}
|
|
1224
1178
|
if (prevSelectedEdgesCount.current !== selectedEdgeIds.size) {
|
|
1225
1179
|
prevSelectedEdgesCount.current = selectedEdgeIds.size;
|
|
1226
|
-
const changes = getSelectionChanges(
|
|
1180
|
+
const changes = getSelectionChanges(edgeLookup, selectedEdgeIds);
|
|
1227
1181
|
triggerEdgeChanges(changes);
|
|
1228
1182
|
}
|
|
1229
1183
|
store.setState({
|
|
@@ -1333,36 +1287,38 @@ const selectedAndDraggable = (nodesDraggable) => (n) => n.selected && (n.draggab
|
|
|
1333
1287
|
function useMoveSelectedNodes() {
|
|
1334
1288
|
const store = useStoreApi();
|
|
1335
1289
|
const moveSelectedNodes = useCallback((params) => {
|
|
1336
|
-
const { nodeExtent,
|
|
1337
|
-
const
|
|
1290
|
+
const { nodeExtent, snapToGrid, snapGrid, nodesDraggable, onError, updateNodePositions, nodeLookup, nodeOrigin } = store.getState();
|
|
1291
|
+
const nodeUpdates = [];
|
|
1292
|
+
const isSelected = selectedAndDraggable(nodesDraggable);
|
|
1338
1293
|
// by default a node moves 5px on each key press
|
|
1339
1294
|
// if snap grid is enabled, we use that for the velocity
|
|
1340
1295
|
const xVelo = snapToGrid ? snapGrid[0] : 5;
|
|
1341
1296
|
const yVelo = snapToGrid ? snapGrid[1] : 5;
|
|
1342
1297
|
const xDiff = params.direction.x * xVelo * params.factor;
|
|
1343
1298
|
const yDiff = params.direction.y * yVelo * params.factor;
|
|
1344
|
-
const
|
|
1345
|
-
if (node
|
|
1346
|
-
|
|
1347
|
-
x: node.computed.positionAbsolute.x + xDiff,
|
|
1348
|
-
y: node.computed.positionAbsolute.y + yDiff,
|
|
1349
|
-
};
|
|
1350
|
-
if (snapToGrid) {
|
|
1351
|
-
nextPosition = snapPosition(nextPosition, snapGrid);
|
|
1352
|
-
}
|
|
1353
|
-
const { position, positionAbsolute } = calculateNodePosition({
|
|
1354
|
-
nodeId: node.id,
|
|
1355
|
-
nextPosition,
|
|
1356
|
-
nodeLookup,
|
|
1357
|
-
nodeExtent,
|
|
1358
|
-
nodeOrigin,
|
|
1359
|
-
onError,
|
|
1360
|
-
});
|
|
1361
|
-
node.position = position;
|
|
1362
|
-
node.computed.positionAbsolute = positionAbsolute;
|
|
1299
|
+
for (const [, node] of nodeLookup) {
|
|
1300
|
+
if (!isSelected(node)) {
|
|
1301
|
+
continue;
|
|
1363
1302
|
}
|
|
1364
|
-
|
|
1365
|
-
|
|
1303
|
+
let nextPosition = {
|
|
1304
|
+
x: node.internals.positionAbsolute.x + xDiff,
|
|
1305
|
+
y: node.internals.positionAbsolute.y + yDiff,
|
|
1306
|
+
};
|
|
1307
|
+
if (snapToGrid) {
|
|
1308
|
+
nextPosition = snapPosition(nextPosition, snapGrid);
|
|
1309
|
+
}
|
|
1310
|
+
const { position, positionAbsolute } = calculateNodePosition({
|
|
1311
|
+
nodeId: node.id,
|
|
1312
|
+
nextPosition,
|
|
1313
|
+
nodeLookup,
|
|
1314
|
+
nodeExtent,
|
|
1315
|
+
nodeOrigin,
|
|
1316
|
+
onError,
|
|
1317
|
+
});
|
|
1318
|
+
node.position = position;
|
|
1319
|
+
node.internals.positionAbsolute = positionAbsolute;
|
|
1320
|
+
nodeUpdates.push(node);
|
|
1321
|
+
}
|
|
1366
1322
|
updateNodePositions(nodeUpdates);
|
|
1367
1323
|
}, []);
|
|
1368
1324
|
return moveSelectedNodes;
|
|
@@ -1431,7 +1387,7 @@ function HandleComponent({ type = 'source', position = Position.Top, isValidConn
|
|
|
1431
1387
|
connectionMode: currentStore.connectionMode,
|
|
1432
1388
|
connectionRadius: currentStore.connectionRadius,
|
|
1433
1389
|
domNode: currentStore.domNode,
|
|
1434
|
-
|
|
1390
|
+
nodeLookup: currentStore.nodeLookup,
|
|
1435
1391
|
lib: currentStore.lib,
|
|
1436
1392
|
isTarget,
|
|
1437
1393
|
handleId,
|
|
@@ -1546,7 +1502,7 @@ const builtinNodeTypes = {
|
|
|
1546
1502
|
group: GroupNode,
|
|
1547
1503
|
};
|
|
1548
1504
|
function getNodeInlineStyleDimensions(node) {
|
|
1549
|
-
if (
|
|
1505
|
+
if (node.internals.handleBounds === undefined) {
|
|
1550
1506
|
return {
|
|
1551
1507
|
width: node.width ?? node.initialWidth ?? node.style?.width,
|
|
1552
1508
|
height: node.height ?? node.initialHeight ?? node.style?.height,
|
|
@@ -1559,7 +1515,12 @@ function getNodeInlineStyleDimensions(node) {
|
|
|
1559
1515
|
}
|
|
1560
1516
|
|
|
1561
1517
|
const selector$h = (s) => {
|
|
1562
|
-
const selectedNodes =
|
|
1518
|
+
const selectedNodes = [];
|
|
1519
|
+
for (const [, node] of s.nodeLookup) {
|
|
1520
|
+
if (node.selected) {
|
|
1521
|
+
selectedNodes.push(node);
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1563
1524
|
const { width, height, x, y } = getNodesBounds(selectedNodes, { nodeOrigin: s.nodeOrigin });
|
|
1564
1525
|
return {
|
|
1565
1526
|
width,
|
|
@@ -1626,7 +1587,7 @@ const FlowRenderer = memo(FlowRendererComponent);
|
|
|
1626
1587
|
|
|
1627
1588
|
const selector$f = (onlyRenderVisible) => (s) => {
|
|
1628
1589
|
return onlyRenderVisible
|
|
1629
|
-
? getNodesInside(s.
|
|
1590
|
+
? getNodesInside(s.nodeLookup, { x: 0, y: 0, width: s.width, height: s.height }, s.transform, true).map((node) => node.id)
|
|
1630
1591
|
: Array.from(s.nodeLookup.keys());
|
|
1631
1592
|
};
|
|
1632
1593
|
/**
|
|
@@ -1656,7 +1617,6 @@ function useResizeObserver() {
|
|
|
1656
1617
|
updates.set(id, {
|
|
1657
1618
|
id,
|
|
1658
1619
|
nodeElement: entry.target,
|
|
1659
|
-
forceUpdate: true,
|
|
1660
1620
|
});
|
|
1661
1621
|
});
|
|
1662
1622
|
updateNodeDimensions(updates);
|
|
@@ -1676,16 +1636,16 @@ function NodeWrapper({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onC
|
|
|
1676
1636
|
const { node, positionAbsoluteX, positionAbsoluteY, zIndex, isParent } = useStore((s) => {
|
|
1677
1637
|
const node = s.nodeLookup.get(id);
|
|
1678
1638
|
const positionAbsolute = nodeExtent
|
|
1679
|
-
? clampPosition(node.
|
|
1680
|
-
: node.
|
|
1639
|
+
? clampPosition(node.internals.positionAbsolute, nodeExtent)
|
|
1640
|
+
: node.internals.positionAbsolute || { x: 0, y: 0 };
|
|
1681
1641
|
return {
|
|
1682
1642
|
node,
|
|
1683
1643
|
// we are mutating positionAbsolute, z and isParent attributes for sub flows
|
|
1684
1644
|
// so we we need to force a re-render when some change
|
|
1685
1645
|
positionAbsoluteX: positionAbsolute.x,
|
|
1686
1646
|
positionAbsoluteY: positionAbsolute.y,
|
|
1687
|
-
zIndex: node
|
|
1688
|
-
isParent:
|
|
1647
|
+
zIndex: node.internals.z,
|
|
1648
|
+
isParent: node.internals.isParent,
|
|
1689
1649
|
};
|
|
1690
1650
|
}, shallow);
|
|
1691
1651
|
let nodeType = node.type || 'default';
|
|
@@ -1707,12 +1667,13 @@ function NodeWrapper({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onC
|
|
|
1707
1667
|
const nodeDimensions = getNodeDimensions(node);
|
|
1708
1668
|
const inlineDimensions = getNodeInlineStyleDimensions(node);
|
|
1709
1669
|
const initialized = nodeHasDimensions(node);
|
|
1710
|
-
const hasHandleBounds = !!node
|
|
1670
|
+
const hasHandleBounds = !!node.internals.handleBounds;
|
|
1711
1671
|
const moveSelectedNodes = useMoveSelectedNodes();
|
|
1712
1672
|
useEffect(() => {
|
|
1673
|
+
const currNode = nodeRef.current;
|
|
1713
1674
|
return () => {
|
|
1714
|
-
if (
|
|
1715
|
-
resizeObserver?.unobserve(
|
|
1675
|
+
if (currNode) {
|
|
1676
|
+
resizeObserver?.unobserve(currNode);
|
|
1716
1677
|
}
|
|
1717
1678
|
};
|
|
1718
1679
|
}, []);
|
|
@@ -1740,7 +1701,7 @@ function NodeWrapper({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onC
|
|
|
1740
1701
|
if (targetPosChanged) {
|
|
1741
1702
|
prevTargetPosition.current = node.targetPosition;
|
|
1742
1703
|
}
|
|
1743
|
-
store.getState().updateNodeDimensions(new Map([[id, { id, nodeElement: nodeRef.current,
|
|
1704
|
+
store.getState().updateNodeDimensions(new Map([[id, { id, nodeElement: nodeRef.current, force: true }]]));
|
|
1744
1705
|
}
|
|
1745
1706
|
}, [id, nodeType, node.sourcePosition, node.targetPosition]);
|
|
1746
1707
|
const dragging = useDrag({
|
|
@@ -2163,7 +2124,7 @@ function EdgeUpdateAnchors({ isUpdatable, edgeUpdaterRadius, edge, targetHandleI
|
|
|
2163
2124
|
if (event.button !== 0) {
|
|
2164
2125
|
return;
|
|
2165
2126
|
}
|
|
2166
|
-
const { autoPanOnConnect, domNode, isValidConnection, connectionMode, connectionRadius, lib, onConnectStart, onConnectEnd, cancelConnection,
|
|
2127
|
+
const { autoPanOnConnect, domNode, isValidConnection, connectionMode, connectionRadius, lib, onConnectStart, onConnectEnd, cancelConnection, nodeLookup, rfId: flowId, panBy, updateConnection, } = store.getState();
|
|
2167
2128
|
const nodeId = isSourceHandle ? edge.target : edge.source;
|
|
2168
2129
|
const handleId = (isSourceHandle ? targetHandleId : sourceHandleId) || null;
|
|
2169
2130
|
const handleType = isSourceHandle ? 'target' : 'source';
|
|
@@ -2182,7 +2143,7 @@ function EdgeUpdateAnchors({ isUpdatable, edgeUpdaterRadius, edge, targetHandleI
|
|
|
2182
2143
|
domNode,
|
|
2183
2144
|
handleId,
|
|
2184
2145
|
nodeId,
|
|
2185
|
-
|
|
2146
|
+
nodeLookup,
|
|
2186
2147
|
isTarget,
|
|
2187
2148
|
edgeUpdaterType: handleType,
|
|
2188
2149
|
lib,
|
|
@@ -2403,7 +2364,7 @@ const ConnectionLine = ({ nodeId, handleType, style, type = ConnectionLineType.B
|
|
|
2403
2364
|
toY: (s.connectionPosition.y - s.transform[1]) / s.transform[2],
|
|
2404
2365
|
connectionMode: s.connectionMode,
|
|
2405
2366
|
}), [nodeId]), shallow);
|
|
2406
|
-
const fromHandleBounds = fromNode?.
|
|
2367
|
+
const fromHandleBounds = fromNode?.internals?.handleBounds;
|
|
2407
2368
|
let handleBounds = fromHandleBounds?.[handleType];
|
|
2408
2369
|
if (connectionMode === ConnectionMode.Loose) {
|
|
2409
2370
|
handleBounds = handleBounds ? handleBounds : fromHandleBounds?.[handleType === 'source' ? 'target' : 'source'];
|
|
@@ -2412,10 +2373,10 @@ const ConnectionLine = ({ nodeId, handleType, style, type = ConnectionLineType.B
|
|
|
2412
2373
|
return null;
|
|
2413
2374
|
}
|
|
2414
2375
|
const fromHandle = handleId ? handleBounds.find((d) => d.id === handleId) : handleBounds[0];
|
|
2415
|
-
const fromHandleX = fromHandle ? fromHandle.x + fromHandle.width / 2 : (fromNode.
|
|
2416
|
-
const fromHandleY = fromHandle ? fromHandle.y + fromHandle.height / 2 : fromNode.
|
|
2417
|
-
const fromX = (fromNode.
|
|
2418
|
-
const fromY = (fromNode.
|
|
2376
|
+
const fromHandleX = fromHandle ? fromHandle.x + fromHandle.width / 2 : (fromNode.measured.width ?? 0) / 2;
|
|
2377
|
+
const fromHandleY = fromHandle ? fromHandle.y + fromHandle.height / 2 : fromNode.measured.height ?? 0;
|
|
2378
|
+
const fromX = (fromNode.internals.positionAbsolute.x ?? 0) + fromHandleX;
|
|
2379
|
+
const fromY = (fromNode.internals.positionAbsolute.y ?? 0) + fromHandleY;
|
|
2419
2380
|
const fromPosition = fromHandle?.position;
|
|
2420
2381
|
const toPosition = fromPosition ? oppositePosition[fromPosition] : null;
|
|
2421
2382
|
if (!fromPosition || !toPosition) {
|
|
@@ -2504,13 +2465,13 @@ const getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, heig
|
|
|
2504
2465
|
const storeEdges = defaultEdges ?? edges ?? [];
|
|
2505
2466
|
const storeNodes = defaultNodes ?? nodes ?? [];
|
|
2506
2467
|
updateConnectionLookup(connectionLookup, edgeLookup, storeEdges);
|
|
2507
|
-
|
|
2468
|
+
adoptUserNodes(storeNodes, nodeLookup, {
|
|
2508
2469
|
nodeOrigin: [0, 0],
|
|
2509
2470
|
elevateNodesOnSelect: false,
|
|
2510
2471
|
});
|
|
2511
2472
|
let transform = [0, 0, 1];
|
|
2512
2473
|
if (fitView && width && height) {
|
|
2513
|
-
const nodesWithDimensions =
|
|
2474
|
+
const nodesWithDimensions = storeNodes.filter((node) => (node.width || node.initialWidth) && (node.height || node.initialHeight));
|
|
2514
2475
|
// @todo users nodeOrigin should be used here
|
|
2515
2476
|
const bounds = getNodesBounds(nodesWithDimensions, { nodeOrigin: [0, 0] });
|
|
2516
2477
|
const { x, y, zoom } = getViewportForBounds(bounds, width, height, 0.5, 2, 0.1);
|
|
@@ -2521,7 +2482,7 @@ const getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, heig
|
|
|
2521
2482
|
width: 0,
|
|
2522
2483
|
height: 0,
|
|
2523
2484
|
transform,
|
|
2524
|
-
nodes:
|
|
2485
|
+
nodes: storeNodes,
|
|
2525
2486
|
nodeLookup,
|
|
2526
2487
|
edges: storeEdges,
|
|
2527
2488
|
edgeLookup,
|
|
@@ -2587,8 +2548,8 @@ const createRFStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height
|
|
|
2587
2548
|
//
|
|
2588
2549
|
// When this happens, we take the note objects passed by the user and extend them with fields
|
|
2589
2550
|
// relevant for internal React Flow operations.
|
|
2590
|
-
|
|
2591
|
-
set({ nodes
|
|
2551
|
+
adoptUserNodes(nodes, nodeLookup, { nodeOrigin, elevateNodesOnSelect });
|
|
2552
|
+
set({ nodes });
|
|
2592
2553
|
},
|
|
2593
2554
|
setEdges: (edges) => {
|
|
2594
2555
|
const { connectionLookup, edgeLookup } = get();
|
|
@@ -2611,25 +2572,18 @@ const createRFStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height
|
|
|
2611
2572
|
// changes its dimensions, this function is called to measure the
|
|
2612
2573
|
// new dimensions and update the nodes.
|
|
2613
2574
|
updateNodeDimensions: (updates) => {
|
|
2614
|
-
const { onNodesChange, fitView,
|
|
2615
|
-
const changes =
|
|
2616
|
-
|
|
2617
|
-
changes.push({
|
|
2618
|
-
id: id,
|
|
2619
|
-
type: 'dimensions',
|
|
2620
|
-
dimensions,
|
|
2621
|
-
});
|
|
2622
|
-
});
|
|
2623
|
-
if (!updatedNodes) {
|
|
2575
|
+
const { onNodesChange, fitView, nodeLookup, fitViewOnInit, fitViewDone, fitViewOnInitOptions, domNode, nodeOrigin, debug, } = get();
|
|
2576
|
+
const changes = updateNodeDimensions(updates, nodeLookup, domNode, nodeOrigin);
|
|
2577
|
+
if (changes.length === 0) {
|
|
2624
2578
|
return;
|
|
2625
2579
|
}
|
|
2626
|
-
|
|
2580
|
+
updateAbsolutePositions(nodeLookup, { nodeOrigin });
|
|
2627
2581
|
// we call fitView once initially after all dimensions are set
|
|
2628
2582
|
let nextFitViewDone = fitViewDone;
|
|
2629
2583
|
if (!fitViewDone && fitViewOnInit) {
|
|
2630
|
-
nextFitViewDone = fitView(
|
|
2584
|
+
nextFitViewDone = fitView({
|
|
2631
2585
|
...fitViewOnInitOptions,
|
|
2632
|
-
nodes: fitViewOnInitOptions?.nodes
|
|
2586
|
+
nodes: fitViewOnInitOptions?.nodes,
|
|
2633
2587
|
});
|
|
2634
2588
|
}
|
|
2635
2589
|
// here we are cirmumventing the onNodesChange handler
|
|
@@ -2637,7 +2591,7 @@ const createRFStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height
|
|
|
2637
2591
|
// has not provided an onNodesChange handler.
|
|
2638
2592
|
// Nodes are only rendered if they have a width and height
|
|
2639
2593
|
// attribute which they get from this handler.
|
|
2640
|
-
set({
|
|
2594
|
+
set({ fitViewDone: nextFitViewDone });
|
|
2641
2595
|
if (changes?.length > 0) {
|
|
2642
2596
|
if (debug) {
|
|
2643
2597
|
console.log('React Flow: trigger node changes', changes);
|
|
@@ -2646,16 +2600,35 @@ const createRFStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height
|
|
|
2646
2600
|
}
|
|
2647
2601
|
},
|
|
2648
2602
|
updateNodePositions: (nodeDragItems, dragging = false) => {
|
|
2603
|
+
const { nodeLookup } = get();
|
|
2604
|
+
const triggerChangeNodes = [];
|
|
2649
2605
|
const changes = nodeDragItems.map((node) => {
|
|
2606
|
+
// @todo add expandParent to drag item so that we can get rid of the look up here
|
|
2607
|
+
const internalNode = nodeLookup.get(node.id);
|
|
2650
2608
|
const change = {
|
|
2651
2609
|
id: node.id,
|
|
2652
2610
|
type: 'position',
|
|
2653
2611
|
position: node.position,
|
|
2654
|
-
positionAbsolute: node.computed?.positionAbsolute,
|
|
2655
2612
|
dragging,
|
|
2656
2613
|
};
|
|
2614
|
+
if (internalNode?.expandParent && change.position) {
|
|
2615
|
+
triggerChangeNodes.push({
|
|
2616
|
+
...internalNode,
|
|
2617
|
+
position: change.position,
|
|
2618
|
+
internals: {
|
|
2619
|
+
...internalNode.internals,
|
|
2620
|
+
positionAbsolute: node.internals.positionAbsolute,
|
|
2621
|
+
},
|
|
2622
|
+
});
|
|
2623
|
+
change.position.x = Math.max(0, change.position.x);
|
|
2624
|
+
change.position.y = Math.max(0, change.position.y);
|
|
2625
|
+
}
|
|
2657
2626
|
return change;
|
|
2658
2627
|
});
|
|
2628
|
+
if (triggerChangeNodes.length > 0) {
|
|
2629
|
+
const parentExpandChanges = handleParentExpand(triggerChangeNodes, nodeLookup);
|
|
2630
|
+
changes.push(...parentExpandChanges);
|
|
2631
|
+
}
|
|
2659
2632
|
get().triggerNodeChanges(changes);
|
|
2660
2633
|
},
|
|
2661
2634
|
triggerNodeChanges: (changes) => {
|
|
@@ -2685,24 +2658,24 @@ const createRFStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height
|
|
|
2685
2658
|
}
|
|
2686
2659
|
},
|
|
2687
2660
|
addSelectedNodes: (selectedNodeIds) => {
|
|
2688
|
-
const { multiSelectionActive,
|
|
2661
|
+
const { multiSelectionActive, edgeLookup, nodeLookup, triggerNodeChanges, triggerEdgeChanges } = get();
|
|
2689
2662
|
if (multiSelectionActive) {
|
|
2690
2663
|
const nodeChanges = selectedNodeIds.map((nodeId) => createSelectionChange(nodeId, true));
|
|
2691
2664
|
triggerNodeChanges(nodeChanges);
|
|
2692
2665
|
return;
|
|
2693
2666
|
}
|
|
2694
|
-
triggerNodeChanges(getSelectionChanges(
|
|
2695
|
-
triggerEdgeChanges(getSelectionChanges(
|
|
2667
|
+
triggerNodeChanges(getSelectionChanges(nodeLookup, new Set([...selectedNodeIds]), true));
|
|
2668
|
+
triggerEdgeChanges(getSelectionChanges(edgeLookup));
|
|
2696
2669
|
},
|
|
2697
2670
|
addSelectedEdges: (selectedEdgeIds) => {
|
|
2698
|
-
const { multiSelectionActive,
|
|
2671
|
+
const { multiSelectionActive, edgeLookup, nodeLookup, triggerNodeChanges, triggerEdgeChanges } = get();
|
|
2699
2672
|
if (multiSelectionActive) {
|
|
2700
2673
|
const changedEdges = selectedEdgeIds.map((edgeId) => createSelectionChange(edgeId, true));
|
|
2701
2674
|
triggerEdgeChanges(changedEdges);
|
|
2702
2675
|
return;
|
|
2703
2676
|
}
|
|
2704
|
-
triggerEdgeChanges(getSelectionChanges(
|
|
2705
|
-
triggerNodeChanges(getSelectionChanges(
|
|
2677
|
+
triggerEdgeChanges(getSelectionChanges(edgeLookup, new Set([...selectedEdgeIds])));
|
|
2678
|
+
triggerNodeChanges(getSelectionChanges(nodeLookup, new Set(), true));
|
|
2706
2679
|
},
|
|
2707
2680
|
unselectNodesAndEdges: ({ nodes, edges } = {}) => {
|
|
2708
2681
|
const { edges: storeEdges, nodes: storeNodes, triggerNodeChanges, triggerEdgeChanges } = get();
|
|
@@ -2738,32 +2711,32 @@ const createRFStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height
|
|
|
2738
2711
|
triggerEdgeChanges(edgeChanges);
|
|
2739
2712
|
},
|
|
2740
2713
|
setNodeExtent: (nodeExtent) => {
|
|
2741
|
-
const {
|
|
2714
|
+
const { nodeLookup } = get();
|
|
2715
|
+
for (const [, node] of nodeLookup) {
|
|
2716
|
+
const positionAbsolute = clampPosition(node.position, nodeExtent);
|
|
2717
|
+
nodeLookup.set(node.id, {
|
|
2718
|
+
...node,
|
|
2719
|
+
internals: {
|
|
2720
|
+
...node.internals,
|
|
2721
|
+
positionAbsolute,
|
|
2722
|
+
},
|
|
2723
|
+
});
|
|
2724
|
+
}
|
|
2742
2725
|
set({
|
|
2743
2726
|
nodeExtent,
|
|
2744
|
-
nodes: nodes.map((node) => {
|
|
2745
|
-
const positionAbsolute = clampPosition(node.position, nodeExtent);
|
|
2746
|
-
return {
|
|
2747
|
-
...node,
|
|
2748
|
-
computed: {
|
|
2749
|
-
...node.computed,
|
|
2750
|
-
positionAbsolute,
|
|
2751
|
-
},
|
|
2752
|
-
};
|
|
2753
|
-
}),
|
|
2754
2727
|
});
|
|
2755
2728
|
},
|
|
2756
2729
|
panBy: (delta) => {
|
|
2757
2730
|
const { transform, width, height, panZoom, translateExtent } = get();
|
|
2758
2731
|
return panBy({ delta, panZoom, transform, translateExtent, width, height });
|
|
2759
2732
|
},
|
|
2760
|
-
fitView: (
|
|
2761
|
-
const { panZoom, width, height, minZoom, maxZoom, nodeOrigin } = get();
|
|
2733
|
+
fitView: (options) => {
|
|
2734
|
+
const { panZoom, width, height, minZoom, maxZoom, nodeOrigin, nodeLookup } = get();
|
|
2762
2735
|
if (!panZoom) {
|
|
2763
2736
|
return false;
|
|
2764
2737
|
}
|
|
2765
2738
|
return fitView({
|
|
2766
|
-
|
|
2739
|
+
nodeLookup,
|
|
2767
2740
|
width,
|
|
2768
2741
|
height,
|
|
2769
2742
|
panZoom,
|
|
@@ -2861,7 +2834,7 @@ function useUpdateNodeInternals() {
|
|
|
2861
2834
|
updateIds.forEach((updateId) => {
|
|
2862
2835
|
const nodeElement = domNode?.querySelector(`.react-flow__node[data-id="${updateId}"]`);
|
|
2863
2836
|
if (nodeElement) {
|
|
2864
|
-
updates.set(updateId, { id: updateId, nodeElement,
|
|
2837
|
+
updates.set(updateId, { id: updateId, nodeElement, force: true });
|
|
2865
2838
|
}
|
|
2866
2839
|
});
|
|
2867
2840
|
requestAnimationFrame(() => updateNodeDimensions(updates));
|
|
@@ -2973,12 +2946,12 @@ function useOnSelectionChange({ onChange }) {
|
|
|
2973
2946
|
}
|
|
2974
2947
|
|
|
2975
2948
|
const selector$6 = (options) => (s) => {
|
|
2976
|
-
if (s.
|
|
2949
|
+
if (s.nodeLookup.size === 0) {
|
|
2977
2950
|
return false;
|
|
2978
2951
|
}
|
|
2979
|
-
for (const node of s.
|
|
2952
|
+
for (const [, node] of s.nodeLookup) {
|
|
2980
2953
|
if (options.includeHiddenNodes || !node.hidden) {
|
|
2981
|
-
if (node
|
|
2954
|
+
if (node.internals.handleBounds === undefined) {
|
|
2982
2955
|
return false;
|
|
2983
2956
|
}
|
|
2984
2957
|
}
|
|
@@ -3066,6 +3039,18 @@ function useConnection() {
|
|
|
3066
3039
|
return ongoingConnection;
|
|
3067
3040
|
}
|
|
3068
3041
|
|
|
3042
|
+
/**
|
|
3043
|
+
* Hook for getting an internal node by id
|
|
3044
|
+
*
|
|
3045
|
+
* @public
|
|
3046
|
+
* @param id - id of the node
|
|
3047
|
+
* @returns array with visible node ids
|
|
3048
|
+
*/
|
|
3049
|
+
function useInternalNode(id) {
|
|
3050
|
+
const node = useStore(useCallback((s) => s.nodeLookup.get(id), [id]), shallow);
|
|
3051
|
+
return node;
|
|
3052
|
+
}
|
|
3053
|
+
|
|
3069
3054
|
function LinePattern({ dimensions, lineWidth, variant, className }) {
|
|
3070
3055
|
return (jsx("path", { strokeWidth: lineWidth, d: `M${dimensions[0] / 2} 0 V${dimensions[1]} M0 ${dimensions[1] / 2} H${dimensions[0]}`, className: cc(['react-flow__background-pattern', variant, className]) }));
|
|
3071
3056
|
}
|
|
@@ -3143,7 +3128,7 @@ const selector$3 = (s) => ({
|
|
|
3143
3128
|
minZoomReached: s.transform[2] <= s.minZoom,
|
|
3144
3129
|
maxZoomReached: s.transform[2] >= s.maxZoom,
|
|
3145
3130
|
});
|
|
3146
|
-
function ControlsComponent({ style, showZoom = true, showFitView = true, showInteractive = true, fitViewOptions, onZoomIn, onZoomOut, onFitView, onInteractiveChange, className, children, position = 'bottom-left', 'aria-label': ariaLabel = 'React Flow controls', }) {
|
|
3131
|
+
function ControlsComponent({ style, showZoom = true, showFitView = true, showInteractive = true, fitViewOptions, onZoomIn, onZoomOut, onFitView, onInteractiveChange, className, children, position = 'bottom-left', orientation = 'vertical', 'aria-label': ariaLabel = 'React Flow controls', }) {
|
|
3147
3132
|
const store = useStoreApi();
|
|
3148
3133
|
const { isInteractive, minZoomReached, maxZoomReached } = useStore(selector$3, shallow);
|
|
3149
3134
|
const { zoomIn, zoomOut, fitView } = useReactFlow();
|
|
@@ -3167,7 +3152,8 @@ function ControlsComponent({ style, showZoom = true, showFitView = true, showInt
|
|
|
3167
3152
|
});
|
|
3168
3153
|
onInteractiveChange?.(!isInteractive);
|
|
3169
3154
|
};
|
|
3170
|
-
|
|
3155
|
+
const orientationClass = orientation === 'horizontal' ? 'horizontal' : 'vertical';
|
|
3156
|
+
return (jsxs(Panel, { className: cc(['react-flow__controls', orientationClass, className]), position: position, style: style, "data-testid": "rf__controls", "aria-label": ariaLabel, children: [showZoom && (jsxs(Fragment, { children: [jsx(ControlButton, { onClick: onZoomInHandler, className: "react-flow__controls-zoomin", title: "zoom in", "aria-label": "zoom in", disabled: maxZoomReached, children: jsx(PlusIcon, {}) }), jsx(ControlButton, { onClick: onZoomOutHandler, className: "react-flow__controls-zoomout", title: "zoom out", "aria-label": "zoom out", disabled: minZoomReached, children: jsx(MinusIcon, {}) })] })), showFitView && (jsx(ControlButton, { className: "react-flow__controls-fitview", onClick: onFitViewHandler, title: "fit view", "aria-label": "fit view", children: jsx(FitViewIcon, {}) })), showInteractive && (jsx(ControlButton, { className: "react-flow__controls-interactive", onClick: onToggleInteractivity, title: "toggle interactivity", "aria-label": "toggle interactivity", children: isInteractive ? jsx(UnlockIcon, {}) : jsx(LockIcon, {}) })), children] }));
|
|
3171
3157
|
}
|
|
3172
3158
|
ControlsComponent.displayName = 'Controls';
|
|
3173
3159
|
const Controls = memo(ControlsComponent);
|
|
@@ -3234,7 +3220,9 @@ const selector$1 = (s) => {
|
|
|
3234
3220
|
};
|
|
3235
3221
|
return {
|
|
3236
3222
|
viewBB,
|
|
3237
|
-
boundingRect: s.
|
|
3223
|
+
boundingRect: s.nodeLookup.size > 0
|
|
3224
|
+
? getBoundsOfRects(getInternalNodesBounds(s.nodeLookup, { nodeOrigin: s.nodeOrigin }), viewBB)
|
|
3225
|
+
: viewBB,
|
|
3238
3226
|
rfId: s.rfId,
|
|
3239
3227
|
nodeOrigin: s.nodeOrigin,
|
|
3240
3228
|
panZoom: s.panZoom,
|
|
@@ -3441,12 +3429,12 @@ function NodeToolbarPortal({ children }) {
|
|
|
3441
3429
|
return createPortal(children, wrapperRef);
|
|
3442
3430
|
}
|
|
3443
3431
|
|
|
3444
|
-
const nodeEqualityFn = (a, b) => a?.
|
|
3445
|
-
a?.
|
|
3446
|
-
a?.
|
|
3447
|
-
a?.
|
|
3432
|
+
const nodeEqualityFn = (a, b) => a?.internals.positionAbsolute.x !== b?.internals.positionAbsolute.x ||
|
|
3433
|
+
a?.internals.positionAbsolute.y !== b?.internals.positionAbsolute.y ||
|
|
3434
|
+
a?.measured.width !== b?.measured.width ||
|
|
3435
|
+
a?.measured.height !== b?.measured.height ||
|
|
3448
3436
|
a?.selected !== b?.selected ||
|
|
3449
|
-
a?.
|
|
3437
|
+
a?.internals.z !== b?.internals.z;
|
|
3450
3438
|
const nodesEqualityFn = (a, b) => {
|
|
3451
3439
|
if (a.length !== b.length) {
|
|
3452
3440
|
return false;
|
|
@@ -3482,7 +3470,7 @@ function NodeToolbar({ nodeId, children, className, style, isVisible, position =
|
|
|
3482
3470
|
return null;
|
|
3483
3471
|
}
|
|
3484
3472
|
const nodeRect = getNodesBounds(nodes, { nodeOrigin });
|
|
3485
|
-
const zIndex = Math.max(...nodes.map((node) => (node
|
|
3473
|
+
const zIndex = Math.max(...nodes.map((node) => (node.internals?.z || 1) + 1));
|
|
3486
3474
|
const wrapperStyle = {
|
|
3487
3475
|
position: 'absolute',
|
|
3488
3476
|
transform: getNodeToolbarTransform(nodeRect, viewport, position, offset, align),
|
|
@@ -3492,4 +3480,4 @@ function NodeToolbar({ nodeId, children, className, style, isVisible, position =
|
|
|
3492
3480
|
return (jsx(NodeToolbarPortal, { children: jsx("div", { style: wrapperStyle, className: cc(['react-flow__node-toolbar', className]), ...rest, "data-id": nodes.reduce((acc, node) => `${acc}${node.id} `, '').trim(), children: children }) }));
|
|
3493
3481
|
}
|
|
3494
3482
|
|
|
3495
|
-
export { Background, BackgroundVariant, BaseEdge, BezierEdge, ControlButton, Controls, EdgeLabelRenderer, EdgeText, Handle, MiniMap, NodeResizeControl, NodeResizer, NodeToolbar, Panel, index as ReactFlow, ReactFlowProvider, SimpleBezierEdge, SmoothStepEdge, StepEdge, StraightEdge, ViewportPortal, applyEdgeChanges, applyNodeChanges, getSimpleBezierPath,
|
|
3483
|
+
export { Background, BackgroundVariant, BaseEdge, BezierEdge, ControlButton, Controls, EdgeLabelRenderer, EdgeText, Handle, MiniMap, NodeResizeControl, NodeResizer, NodeToolbar, Panel, index as ReactFlow, ReactFlowProvider, SimpleBezierEdge, SmoothStepEdge, StepEdge, StraightEdge, ViewportPortal, applyEdgeChanges, applyNodeChanges, getSimpleBezierPath, isEdge, isNode, useConnection, useEdges, useEdgesState, useHandleConnections, useInternalNode, useKeyPress, useNodeId, useNodes, useNodesData, useNodesInitialized, useNodesState, useOnSelectionChange, useOnViewportChange, useReactFlow, useStore, useStoreApi, useUpdateNodeInternals, useViewport };
|