@xyflow/react 12.0.0-next.24 → 12.0.0-next.26
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/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/additional-components/NodeToolbar/NodeToolbar.d.ts.map +1 -1
- package/dist/esm/components/ConnectionLine/index.d.ts.map +1 -1
- package/dist/esm/components/Handle/index.d.ts.map +1 -1
- package/dist/esm/components/NodeWrapper/index.d.ts +1 -1
- package/dist/esm/components/NodeWrapper/index.d.ts.map +1 -1
- package/dist/esm/components/NodesSelection/index.d.ts.map +1 -1
- package/dist/esm/components/ReactFlowProvider/index.d.ts +3 -1
- package/dist/esm/components/ReactFlowProvider/index.d.ts.map +1 -1
- package/dist/esm/components/StoreUpdater/index.d.ts +1 -1
- package/dist/esm/components/StoreUpdater/index.d.ts.map +1 -1
- package/dist/esm/container/FlowRenderer/index.d.ts +1 -1
- package/dist/esm/container/FlowRenderer/index.d.ts.map +1 -1
- package/dist/esm/container/GraphView/index.d.ts +2 -2
- package/dist/esm/container/GraphView/index.d.ts.map +1 -1
- package/dist/esm/container/NodeRenderer/index.d.ts +1 -1
- package/dist/esm/container/NodeRenderer/index.d.ts.map +1 -1
- package/dist/esm/container/Pane/index.d.ts.map +1 -1
- package/dist/esm/container/ReactFlow/Wrapper.d.ts +3 -1
- package/dist/esm/container/ReactFlow/Wrapper.d.ts.map +1 -1
- package/dist/esm/container/ReactFlow/index.d.ts.map +1 -1
- package/dist/esm/contexts/RFStoreContext.d.ts +5 -0
- package/dist/esm/contexts/RFStoreContext.d.ts.map +1 -0
- package/dist/esm/hooks/useConnection.d.ts +4 -15
- package/dist/esm/hooks/useConnection.d.ts.map +1 -1
- package/dist/esm/hooks/useViewportHelper.d.ts.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +201 -238
- package/dist/esm/index.mjs +201 -238
- package/dist/esm/store/index.d.ts +3 -1
- package/dist/esm/store/index.d.ts.map +1 -1
- package/dist/esm/store/initialState.d.ts +3 -1
- package/dist/esm/store/initialState.d.ts.map +1 -1
- package/dist/esm/store/utils.d.ts +12 -0
- package/dist/esm/store/utils.d.ts.map +1 -0
- package/dist/esm/types/changes.d.ts +51 -0
- package/dist/esm/types/changes.d.ts.map +1 -0
- package/dist/esm/types/component-props.d.ts +4 -0
- package/dist/esm/types/component-props.d.ts.map +1 -1
- package/dist/esm/types/edges.d.ts +6 -4
- package/dist/esm/types/edges.d.ts.map +1 -1
- package/dist/esm/types/nodes.d.ts +1 -2
- package/dist/esm/types/nodes.d.ts.map +1 -1
- package/dist/esm/types/store.d.ts +5 -7
- package/dist/esm/types/store.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/additional-components/NodeToolbar/NodeToolbar.d.ts.map +1 -1
- package/dist/umd/components/ConnectionLine/index.d.ts.map +1 -1
- package/dist/umd/components/Handle/index.d.ts.map +1 -1
- package/dist/umd/components/NodeWrapper/index.d.ts +1 -1
- package/dist/umd/components/NodeWrapper/index.d.ts.map +1 -1
- package/dist/umd/components/NodesSelection/index.d.ts.map +1 -1
- package/dist/umd/components/ReactFlowProvider/index.d.ts +3 -1
- package/dist/umd/components/ReactFlowProvider/index.d.ts.map +1 -1
- package/dist/umd/components/StoreUpdater/index.d.ts +1 -1
- package/dist/umd/components/StoreUpdater/index.d.ts.map +1 -1
- package/dist/umd/container/FlowRenderer/index.d.ts +1 -1
- package/dist/umd/container/FlowRenderer/index.d.ts.map +1 -1
- package/dist/umd/container/GraphView/index.d.ts +2 -2
- package/dist/umd/container/GraphView/index.d.ts.map +1 -1
- package/dist/umd/container/NodeRenderer/index.d.ts +1 -1
- package/dist/umd/container/NodeRenderer/index.d.ts.map +1 -1
- package/dist/umd/container/Pane/index.d.ts.map +1 -1
- package/dist/umd/container/ReactFlow/Wrapper.d.ts +3 -1
- package/dist/umd/container/ReactFlow/Wrapper.d.ts.map +1 -1
- package/dist/umd/container/ReactFlow/index.d.ts.map +1 -1
- package/dist/umd/hooks/useConnection.d.ts +4 -15
- package/dist/umd/hooks/useConnection.d.ts.map +1 -1
- package/dist/umd/hooks/useViewportHelper.d.ts.map +1 -1
- package/dist/umd/index.d.ts +1 -1
- package/dist/umd/index.d.ts.map +1 -1
- package/dist/umd/index.js +2 -2
- package/dist/umd/store/index.d.ts +3 -1
- package/dist/umd/store/index.d.ts.map +1 -1
- package/dist/umd/store/initialState.d.ts +3 -1
- package/dist/umd/store/initialState.d.ts.map +1 -1
- package/dist/umd/types/component-props.d.ts +4 -0
- package/dist/umd/types/component-props.d.ts.map +1 -1
- package/dist/umd/types/edges.d.ts +6 -4
- package/dist/umd/types/edges.d.ts.map +1 -1
- package/dist/umd/types/nodes.d.ts +1 -2
- package/dist/umd/types/nodes.d.ts.map +1 -1
- package/dist/umd/types/store.d.ts +5 -7
- package/dist/umd/types/store.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/esm/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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, isRectObject, nodeToRect, getOverlappingArea, evaluateAbsolutePosition, getDimensions, XYPanZoom, PanOnScrollMode, SelectionMode, getEventPosition, getNodesInside, XYDrag, snapPosition, calculateNodePosition, Position, ConnectionMode, isMouseEvent, XYHandle, getHostForElement, addEdge, getInternalNodesBounds, isNumeric, nodeHasDimensions, getNodeDimensions, clampPosition,
|
|
4
|
+
import { errorMessages, infiniteExtent, isInputDOMNode, fitView, getViewportForBounds, pointToRendererPoint, rendererPointToPoint, isNodeBase, isEdgeBase, getElementsToRemove, isRectObject, nodeToRect, getOverlappingArea, evaluateAbsolutePosition, getDimensions, XYPanZoom, PanOnScrollMode, SelectionMode, getEventPosition, getNodesInside, XYDrag, snapPosition, calculateNodePosition, Position, ConnectionMode, isMouseEvent, XYHandle, getHostForElement, addEdge, getInternalNodesBounds, isNumeric, nodeHasDimensions, getNodeDimensions, clampPosition, elementSelectionKeys, isEdgeVisible, MarkerType, createMarkerIds, getBezierEdgeCenter, getSmoothStepPath, getStraightPath, getBezierPath, getEdgePosition, getElevatedEdgeZIndex, getMarkerId, getConnectionStatus, ConnectionLineType, updateConnectionLookup, adoptUserNodes, initialConnection, devWarn, updateNodeInternals, updateAbsolutePositions, handleExpandParent, panBy, isMacOs, areConnectionMapsEqual, handleConnectionChange, shallowNodeData, XYMinimap, getBoundsOfRects, ResizeControlVariant, XYResizer, XY_RESIZER_LINE_POSITIONS, XY_RESIZER_HANDLE_POSITIONS, getNodeToolbarTransform } from '@xyflow/system';
|
|
5
5
|
export { ConnectionLineType, ConnectionMode, MarkerType, PanOnScrollMode, Position, SelectionMode, addEdge, getBezierEdgeCenter, getBezierPath, getConnectedEdges, getEdgeCenter, getIncomers, getNodesBounds, getOutgoers, getSmoothStepPath, getStraightPath, getViewportForBounds, reconnectEdge } 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';
|
|
@@ -58,18 +58,18 @@ const ariaLiveStyle = {
|
|
|
58
58
|
const ARIA_NODE_DESC_KEY = 'react-flow__node-desc';
|
|
59
59
|
const ARIA_EDGE_DESC_KEY = 'react-flow__edge-desc';
|
|
60
60
|
const ARIA_LIVE_MESSAGE = 'react-flow__aria-live';
|
|
61
|
-
const selector$
|
|
61
|
+
const selector$p = (s) => s.ariaLiveMessage;
|
|
62
62
|
function AriaLiveMessage({ rfId }) {
|
|
63
|
-
const ariaLiveMessage = useStore(selector$
|
|
63
|
+
const ariaLiveMessage = useStore(selector$p);
|
|
64
64
|
return (jsx("div", { id: `${ARIA_LIVE_MESSAGE}-${rfId}`, "aria-live": "assertive", "aria-atomic": "true", style: ariaLiveStyle, children: ariaLiveMessage }));
|
|
65
65
|
}
|
|
66
66
|
function A11yDescriptions({ rfId, disableKeyboardA11y }) {
|
|
67
67
|
return (jsxs(Fragment, { children: [jsxs("div", { id: `${ARIA_NODE_DESC_KEY}-${rfId}`, style: style, children: ["Press enter or space to select a node.", !disableKeyboardA11y && 'You can then use the arrow keys to move the node around.', " Press delete to remove it and escape to cancel.", ' '] }), jsx("div", { id: `${ARIA_EDGE_DESC_KEY}-${rfId}`, style: style, children: "Press enter or space to select an edge. You can then press delete to remove it or escape to cancel." }), !disableKeyboardA11y && jsx(AriaLiveMessage, { rfId: rfId })] }));
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
const selector$
|
|
70
|
+
const selector$o = (s) => (s.userSelectionActive ? 'none' : 'all');
|
|
71
71
|
function Panel({ position = 'top-left', children, className, style, ...rest }) {
|
|
72
|
-
const pointerEvents = useStore(selector$
|
|
72
|
+
const pointerEvents = useStore(selector$o);
|
|
73
73
|
const positionClasses = `${position}`.split('-');
|
|
74
74
|
return (jsx("div", { className: cc(['react-flow__panel', className, ...positionClasses]), style: { ...style, pointerEvents }, ...rest, children: children }));
|
|
75
75
|
}
|
|
@@ -81,7 +81,7 @@ function Attribution({ proOptions, position = 'bottom-right' }) {
|
|
|
81
81
|
return (jsx(Panel, { position: position, className: "react-flow__attribution", "data-message": "Please only hide this attribution when you are subscribed to React Flow Pro: https://pro.reactflow.dev", children: jsx("a", { href: "https://reactflow.dev", target: "_blank", rel: "noopener noreferrer", "aria-label": "React Flow attribution", children: "React Flow" }) }));
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
const selector$
|
|
84
|
+
const selector$n = (s) => {
|
|
85
85
|
const selectedNodes = [];
|
|
86
86
|
const selectedEdges = [];
|
|
87
87
|
for (const [, node] of s.nodeLookup) {
|
|
@@ -103,7 +103,7 @@ function areEqual(a, b) {
|
|
|
103
103
|
}
|
|
104
104
|
function SelectionListenerInner({ onSelectionChange }) {
|
|
105
105
|
const store = useStoreApi();
|
|
106
|
-
const { selectedNodes, selectedEdges } = useStore(selector$
|
|
106
|
+
const { selectedNodes, selectedEdges } = useStore(selector$n, areEqual);
|
|
107
107
|
useEffect(() => {
|
|
108
108
|
const params = { nodes: selectedNodes, edges: selectedEdges };
|
|
109
109
|
onSelectionChange?.(params);
|
|
@@ -183,10 +183,11 @@ const reactFlowFieldsToTrack = [
|
|
|
183
183
|
'nodeDragThreshold',
|
|
184
184
|
'onBeforeDelete',
|
|
185
185
|
'debug',
|
|
186
|
+
'autoPanSpeed',
|
|
186
187
|
];
|
|
187
188
|
// rfId doesn't exist in ReactFlowProps, but it's one of the fields we want to update
|
|
188
189
|
const fieldsToTrack = [...reactFlowFieldsToTrack, 'rfId'];
|
|
189
|
-
const selector$
|
|
190
|
+
const selector$m = (s) => ({
|
|
190
191
|
setNodes: s.setNodes,
|
|
191
192
|
setEdges: s.setEdges,
|
|
192
193
|
setMinZoom: s.setMinZoom,
|
|
@@ -209,7 +210,7 @@ const initPrevValues = {
|
|
|
209
210
|
rfId: '1',
|
|
210
211
|
};
|
|
211
212
|
function StoreUpdater(props) {
|
|
212
|
-
const { setNodes, setEdges, setMinZoom, setMaxZoom, setTranslateExtent, setNodeExtent, reset, setDefaultNodesAndEdges, } = useStore(selector$
|
|
213
|
+
const { setNodes, setEdges, setMinZoom, setMaxZoom, setTranslateExtent, setNodeExtent, reset, setDefaultNodesAndEdges, } = useStore(selector$m, shallow);
|
|
213
214
|
const store = useStoreApi();
|
|
214
215
|
useEffect(() => {
|
|
215
216
|
setDefaultNodesAndEdges(props.defaultNodes, props.defaultEdges);
|
|
@@ -419,18 +420,18 @@ const useViewportHelper = () => {
|
|
|
419
420
|
return { x, y, zoom };
|
|
420
421
|
},
|
|
421
422
|
fitView: (options) => {
|
|
422
|
-
const { nodeLookup, width, height,
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
423
|
+
const { nodeLookup, width, height, minZoom, maxZoom, panZoom } = store.getState();
|
|
424
|
+
if (!panZoom) {
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
return fitView({
|
|
428
|
+
nodeLookup,
|
|
429
|
+
width,
|
|
430
|
+
height,
|
|
431
|
+
minZoom,
|
|
432
|
+
maxZoom,
|
|
433
|
+
panZoom,
|
|
434
|
+
}, options);
|
|
434
435
|
},
|
|
435
436
|
setCenter: (x, y, options) => {
|
|
436
437
|
const { width, height, maxZoom, panZoom } = store.getState();
|
|
@@ -800,7 +801,7 @@ function useBatchContext() {
|
|
|
800
801
|
return batchContext;
|
|
801
802
|
}
|
|
802
803
|
|
|
803
|
-
const selector$
|
|
804
|
+
const selector$l = (s) => !!s.panZoom;
|
|
804
805
|
/**
|
|
805
806
|
* Hook for accessing the ReactFlow instance.
|
|
806
807
|
*
|
|
@@ -811,7 +812,7 @@ function useReactFlow() {
|
|
|
811
812
|
const viewportHelper = useViewportHelper();
|
|
812
813
|
const store = useStoreApi();
|
|
813
814
|
const batchContext = useBatchContext();
|
|
814
|
-
const viewportInitialized = useStore(selector$
|
|
815
|
+
const viewportInitialized = useStore(selector$l);
|
|
815
816
|
const generalHelper = useMemo(() => {
|
|
816
817
|
const getInternalNode = (id) => store.getState().nodeLookup.get(id);
|
|
817
818
|
const setNodes = (payload) => {
|
|
@@ -824,7 +825,7 @@ function useReactFlow() {
|
|
|
824
825
|
const { nodeLookup, nodeOrigin } = store.getState();
|
|
825
826
|
const nodeToUse = isNode(node) ? node : nodeLookup.get(node.id);
|
|
826
827
|
const position = nodeToUse.parentId
|
|
827
|
-
? evaluateAbsolutePosition(nodeToUse.position, nodeToUse.parentId, nodeLookup, nodeOrigin)
|
|
828
|
+
? evaluateAbsolutePosition(nodeToUse.position, nodeToUse.measured, nodeToUse.parentId, nodeLookup, nodeOrigin)
|
|
828
829
|
: nodeToUse.position;
|
|
829
830
|
const nodeWithPosition = {
|
|
830
831
|
id: nodeToUse.id,
|
|
@@ -1030,14 +1031,14 @@ const containerStyle = {
|
|
|
1030
1031
|
left: 0,
|
|
1031
1032
|
};
|
|
1032
1033
|
|
|
1033
|
-
const selector$
|
|
1034
|
+
const selector$k = (s) => ({
|
|
1034
1035
|
userSelectionActive: s.userSelectionActive,
|
|
1035
1036
|
lib: s.lib,
|
|
1036
1037
|
});
|
|
1037
1038
|
function ZoomPane({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true, panOnScroll = false, panOnScrollSpeed = 0.5, panOnScrollMode = PanOnScrollMode.Free, zoomOnDoubleClick = true, panOnDrag = true, defaultViewport, translateExtent, minZoom, maxZoom, zoomActivationKeyCode, preventScrolling = true, children, noWheelClassName, noPanClassName, onViewportChange, isControlledViewport, }) {
|
|
1038
1039
|
const store = useStoreApi();
|
|
1039
1040
|
const zoomPane = useRef(null);
|
|
1040
|
-
const { userSelectionActive, lib } = useStore(selector$
|
|
1041
|
+
const { userSelectionActive, lib } = useStore(selector$k, shallow);
|
|
1041
1042
|
const zoomActivationKeyPressed = useKeyPress(zoomActivationKeyCode);
|
|
1042
1043
|
const panZoom = useRef();
|
|
1043
1044
|
useResizeHandler(zoomPane);
|
|
@@ -1119,12 +1120,12 @@ function ZoomPane({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true,
|
|
|
1119
1120
|
return (jsx("div", { className: "react-flow__renderer", ref: zoomPane, style: containerStyle, children: children }));
|
|
1120
1121
|
}
|
|
1121
1122
|
|
|
1122
|
-
const selector$
|
|
1123
|
+
const selector$j = (s) => ({
|
|
1123
1124
|
userSelectionActive: s.userSelectionActive,
|
|
1124
1125
|
userSelectionRect: s.userSelectionRect,
|
|
1125
1126
|
});
|
|
1126
1127
|
function UserSelection() {
|
|
1127
|
-
const { userSelectionActive, userSelectionRect } = useStore(selector$
|
|
1128
|
+
const { userSelectionActive, userSelectionRect } = useStore(selector$j, shallow);
|
|
1128
1129
|
const isActive = userSelectionActive && userSelectionRect;
|
|
1129
1130
|
if (!isActive) {
|
|
1130
1131
|
return null;
|
|
@@ -1144,7 +1145,7 @@ const wrapHandler = (handler, containerRef) => {
|
|
|
1144
1145
|
handler?.(event);
|
|
1145
1146
|
};
|
|
1146
1147
|
};
|
|
1147
|
-
const selector$
|
|
1148
|
+
const selector$i = (s) => ({
|
|
1148
1149
|
userSelectionActive: s.userSelectionActive,
|
|
1149
1150
|
elementsSelectable: s.elementsSelectable,
|
|
1150
1151
|
dragging: s.paneDragging,
|
|
@@ -1156,7 +1157,7 @@ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.
|
|
|
1156
1157
|
const prevSelectedEdgesCount = useRef(0);
|
|
1157
1158
|
const containerBounds = useRef();
|
|
1158
1159
|
const edgeIdLookup = useRef(new Map());
|
|
1159
|
-
const { userSelectionActive, elementsSelectable, dragging } = useStore(selector$
|
|
1160
|
+
const { userSelectionActive, elementsSelectable, dragging } = useStore(selector$i, shallow);
|
|
1160
1161
|
const hasActiveSelection = elementsSelectable && (isSelecting || userSelectionActive);
|
|
1161
1162
|
// Used to prevent click events when the user lets go of the selectionKey during a selection
|
|
1162
1163
|
const selectionInProgress = useRef(false);
|
|
@@ -1214,7 +1215,7 @@ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.
|
|
|
1214
1215
|
onSelectionStart?.(event);
|
|
1215
1216
|
};
|
|
1216
1217
|
const onPointerMove = (event) => {
|
|
1217
|
-
const { userSelectionRect, edgeLookup, transform,
|
|
1218
|
+
const { userSelectionRect, edgeLookup, transform, nodeLookup, triggerNodeChanges, triggerEdgeChanges } = store.getState();
|
|
1218
1219
|
if (!containerBounds.current || !userSelectionRect) {
|
|
1219
1220
|
return;
|
|
1220
1221
|
}
|
|
@@ -1229,7 +1230,7 @@ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.
|
|
|
1229
1230
|
width: Math.abs(mouseX - startX),
|
|
1230
1231
|
height: Math.abs(mouseY - startY),
|
|
1231
1232
|
};
|
|
1232
|
-
const selectedNodes = getNodesInside(nodeLookup, nextUserSelectRect, transform, selectionMode === SelectionMode.Partial, true
|
|
1233
|
+
const selectedNodes = getNodesInside(nodeLookup, nextUserSelectRect, transform, selectionMode === SelectionMode.Partial, true);
|
|
1233
1234
|
const selectedEdgeIds = new Set();
|
|
1234
1235
|
const selectedNodeIds = new Set();
|
|
1235
1236
|
for (const selectedNode of selectedNodes) {
|
|
@@ -1403,23 +1404,24 @@ const useNodeId = () => {
|
|
|
1403
1404
|
return nodeId;
|
|
1404
1405
|
};
|
|
1405
1406
|
|
|
1406
|
-
const selector$
|
|
1407
|
+
const selector$h = (s) => ({
|
|
1407
1408
|
connectOnClick: s.connectOnClick,
|
|
1408
1409
|
noPanClassName: s.noPanClassName,
|
|
1409
1410
|
rfId: s.rfId,
|
|
1410
1411
|
});
|
|
1411
1412
|
const connectingSelector = (nodeId, handleId, type) => (state) => {
|
|
1412
|
-
const {
|
|
1413
|
-
const
|
|
1413
|
+
const { connectionClickStartHandle: clickHandle, connectionMode, connection } = state;
|
|
1414
|
+
const { fromHandle, toHandle, isValid } = connection;
|
|
1415
|
+
const connectingTo = toHandle?.nodeId === nodeId && toHandle?.id === handleId && toHandle?.type === type;
|
|
1414
1416
|
return {
|
|
1415
|
-
connectingFrom:
|
|
1417
|
+
connectingFrom: fromHandle?.nodeId === nodeId && fromHandle?.id === handleId && fromHandle?.type === type,
|
|
1416
1418
|
connectingTo,
|
|
1417
|
-
clickConnecting: clickHandle?.nodeId === nodeId && clickHandle?.
|
|
1419
|
+
clickConnecting: clickHandle?.nodeId === nodeId && clickHandle?.id === handleId && clickHandle?.type === type,
|
|
1418
1420
|
isPossibleEndHandle: connectionMode === ConnectionMode.Strict
|
|
1419
|
-
?
|
|
1420
|
-
: nodeId !==
|
|
1421
|
-
connectionInProcess: !!
|
|
1422
|
-
valid: connectingTo &&
|
|
1421
|
+
? fromHandle?.type !== type
|
|
1422
|
+
: nodeId !== fromHandle?.nodeId || handleId !== fromHandle?.id,
|
|
1423
|
+
connectionInProcess: !!fromHandle,
|
|
1424
|
+
valid: connectingTo && isValid,
|
|
1423
1425
|
};
|
|
1424
1426
|
};
|
|
1425
1427
|
function HandleComponent({ type = 'source', position = Position.Top, isValidConnection, isConnectable = true, isConnectableStart = true, isConnectableEnd = true, id, onConnect, children, className, onMouseDown, onTouchStart, ...rest }, ref) {
|
|
@@ -1427,7 +1429,7 @@ function HandleComponent({ type = 'source', position = Position.Top, isValidConn
|
|
|
1427
1429
|
const isTarget = type === 'target';
|
|
1428
1430
|
const store = useStoreApi();
|
|
1429
1431
|
const nodeId = useNodeId();
|
|
1430
|
-
const { connectOnClick, noPanClassName, rfId } = useStore(selector$
|
|
1432
|
+
const { connectOnClick, noPanClassName, rfId } = useStore(selector$h, shallow);
|
|
1431
1433
|
const { connectingFrom, connectingTo, clickConnecting, isPossibleEndHandle, connectionInProcess, valid } = useStore(connectingSelector(nodeId, handleId, type), shallow);
|
|
1432
1434
|
if (!nodeId) {
|
|
1433
1435
|
store.getState().onError?.('010', errorMessages['error010']());
|
|
@@ -1472,7 +1474,8 @@ function HandleComponent({ type = 'source', position = Position.Top, isValidConn
|
|
|
1472
1474
|
onConnect: onConnectExtended,
|
|
1473
1475
|
isValidConnection: isValidConnection || currentStore.isValidConnection,
|
|
1474
1476
|
getTransform: () => store.getState().transform,
|
|
1475
|
-
|
|
1477
|
+
getFromHandle: () => store.getState().connection.fromHandle,
|
|
1478
|
+
autoPanSpeed: currentStore.autoPanSpeed,
|
|
1476
1479
|
});
|
|
1477
1480
|
}
|
|
1478
1481
|
if (isMouseTriggered) {
|
|
@@ -1489,7 +1492,7 @@ function HandleComponent({ type = 'source', position = Position.Top, isValidConn
|
|
|
1489
1492
|
}
|
|
1490
1493
|
if (!connectionClickStartHandle) {
|
|
1491
1494
|
onClickConnectStart?.(event.nativeEvent, { nodeId, handleId, handleType: type });
|
|
1492
|
-
store.setState({ connectionClickStartHandle: { nodeId, type, handleId } });
|
|
1495
|
+
store.setState({ connectionClickStartHandle: { nodeId, type, id: handleId } });
|
|
1493
1496
|
return;
|
|
1494
1497
|
}
|
|
1495
1498
|
const doc = getHostForElement(event.target);
|
|
@@ -1502,7 +1505,7 @@ function HandleComponent({ type = 'source', position = Position.Top, isValidConn
|
|
|
1502
1505
|
},
|
|
1503
1506
|
connectionMode,
|
|
1504
1507
|
fromNodeId: connectionClickStartHandle.nodeId,
|
|
1505
|
-
fromHandleId: connectionClickStartHandle.
|
|
1508
|
+
fromHandleId: connectionClickStartHandle.id || null,
|
|
1506
1509
|
fromType: connectionClickStartHandle.type,
|
|
1507
1510
|
isValidConnection: isValidConnectionHandler,
|
|
1508
1511
|
flowId,
|
|
@@ -1585,9 +1588,8 @@ function getNodeInlineStyleDimensions(node) {
|
|
|
1585
1588
|
};
|
|
1586
1589
|
}
|
|
1587
1590
|
|
|
1588
|
-
const selector$
|
|
1591
|
+
const selector$g = (s) => {
|
|
1589
1592
|
const { width, height, x, y } = getInternalNodesBounds(s.nodeLookup, {
|
|
1590
|
-
nodeOrigin: s.nodeOrigin,
|
|
1591
1593
|
filter: (node) => !!node.selected,
|
|
1592
1594
|
});
|
|
1593
1595
|
return {
|
|
@@ -1599,7 +1601,7 @@ const selector$h = (s) => {
|
|
|
1599
1601
|
};
|
|
1600
1602
|
function NodesSelection({ onSelectionContextMenu, noPanClassName, disableKeyboardA11y, }) {
|
|
1601
1603
|
const store = useStoreApi();
|
|
1602
|
-
const { width, height, transformString, userSelectionActive } = useStore(selector$
|
|
1604
|
+
const { width, height, transformString, userSelectionActive } = useStore(selector$g, shallow);
|
|
1603
1605
|
const moveSelectedNodes = useMoveSelectedNodes();
|
|
1604
1606
|
const nodeRef = useRef(null);
|
|
1605
1607
|
useEffect(() => {
|
|
@@ -1638,11 +1640,11 @@ function NodesSelection({ onSelectionContextMenu, noPanClassName, disableKeyboar
|
|
|
1638
1640
|
}
|
|
1639
1641
|
|
|
1640
1642
|
const win = typeof window !== 'undefined' ? window : undefined;
|
|
1641
|
-
const selector$
|
|
1643
|
+
const selector$f = (s) => {
|
|
1642
1644
|
return { nodesSelectionActive: s.nodesSelectionActive, userSelectionActive: s.userSelectionActive };
|
|
1643
1645
|
};
|
|
1644
1646
|
function FlowRendererComponent({ children, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneContextMenu, onPaneScroll, deleteKeyCode, selectionKeyCode, selectionOnDrag, selectionMode, onSelectionStart, onSelectionEnd, multiSelectionKeyCode, panActivationKeyCode, zoomActivationKeyCode, elementsSelectable, zoomOnScroll, zoomOnPinch, panOnScroll: _panOnScroll, panOnScrollSpeed, panOnScrollMode, zoomOnDoubleClick, panOnDrag: _panOnDrag, defaultViewport, translateExtent, minZoom, maxZoom, preventScrolling, onSelectionContextMenu, noWheelClassName, noPanClassName, disableKeyboardA11y, onViewportChange, isControlledViewport, }) {
|
|
1645
|
-
const { nodesSelectionActive, userSelectionActive } = useStore(selector$
|
|
1647
|
+
const { nodesSelectionActive, userSelectionActive } = useStore(selector$f);
|
|
1646
1648
|
const selectionKeyPressed = useKeyPress(selectionKeyCode, { target: win });
|
|
1647
1649
|
const panActivationKeyPressed = useKeyPress(panActivationKeyCode, { target: win });
|
|
1648
1650
|
const panOnDrag = panActivationKeyPressed || _panOnDrag;
|
|
@@ -1654,7 +1656,7 @@ function FlowRendererComponent({ children, onPaneClick, onPaneMouseEnter, onPane
|
|
|
1654
1656
|
FlowRendererComponent.displayName = 'FlowRenderer';
|
|
1655
1657
|
const FlowRenderer = memo(FlowRendererComponent);
|
|
1656
1658
|
|
|
1657
|
-
const selector$
|
|
1659
|
+
const selector$e = (onlyRenderVisible) => (s) => {
|
|
1658
1660
|
return onlyRenderVisible
|
|
1659
1661
|
? getNodesInside(s.nodeLookup, { x: 0, y: 0, width: s.width, height: s.height }, s.transform, true).map((node) => node.id)
|
|
1660
1662
|
: Array.from(s.nodeLookup.keys());
|
|
@@ -1667,13 +1669,13 @@ const selector$f = (onlyRenderVisible) => (s) => {
|
|
|
1667
1669
|
* @returns array with visible node ids
|
|
1668
1670
|
*/
|
|
1669
1671
|
function useVisibleNodeIds(onlyRenderVisible) {
|
|
1670
|
-
const nodeIds = useStore(useCallback(selector$
|
|
1672
|
+
const nodeIds = useStore(useCallback(selector$e(onlyRenderVisible), [onlyRenderVisible]), shallow);
|
|
1671
1673
|
return nodeIds;
|
|
1672
1674
|
}
|
|
1673
1675
|
|
|
1674
|
-
const selector$
|
|
1676
|
+
const selector$d = (s) => s.updateNodeInternals;
|
|
1675
1677
|
function useResizeObserver() {
|
|
1676
|
-
const updateNodeInternals = useStore(selector$
|
|
1678
|
+
const updateNodeInternals = useStore(selector$d);
|
|
1677
1679
|
const [resizeObserver] = useState(() => {
|
|
1678
1680
|
if (typeof ResizeObserver === 'undefined') {
|
|
1679
1681
|
return null;
|
|
@@ -1750,7 +1752,7 @@ function useNodeObserver({ node, nodeType, hasDimensions, resizeObserver, }) {
|
|
|
1750
1752
|
return nodeRef;
|
|
1751
1753
|
}
|
|
1752
1754
|
|
|
1753
|
-
function NodeWrapper({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onContextMenu, onDoubleClick, nodesDraggable, elementsSelectable, nodesConnectable, nodesFocusable, resizeObserver, noDragClassName, noPanClassName, disableKeyboardA11y, rfId, nodeTypes, nodeExtent,
|
|
1755
|
+
function NodeWrapper({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onContextMenu, onDoubleClick, nodesDraggable, elementsSelectable, nodesConnectable, nodesFocusable, resizeObserver, noDragClassName, noPanClassName, disableKeyboardA11y, rfId, nodeTypes, nodeExtent, onError, }) {
|
|
1754
1756
|
const { node, internals, isParent } = useStore((s) => {
|
|
1755
1757
|
const node = s.nodeLookup.get(id);
|
|
1756
1758
|
const isParent = s.parentLookup.has(id);
|
|
@@ -1788,14 +1790,10 @@ function NodeWrapper({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onC
|
|
|
1788
1790
|
}
|
|
1789
1791
|
const nodeDimensions = getNodeDimensions(node);
|
|
1790
1792
|
const inlineDimensions = getNodeInlineStyleDimensions(node);
|
|
1793
|
+
// TODO: clamping should happen earlier
|
|
1791
1794
|
const clampedPosition = nodeExtent
|
|
1792
1795
|
? clampPosition(internals.positionAbsolute, nodeExtent)
|
|
1793
1796
|
: internals.positionAbsolute;
|
|
1794
|
-
const positionWithOrigin = getPositionWithOrigin({
|
|
1795
|
-
...clampedPosition,
|
|
1796
|
-
...nodeDimensions,
|
|
1797
|
-
origin: node.origin || nodeOrigin,
|
|
1798
|
-
});
|
|
1799
1797
|
const hasPointerEvents = isSelectable || isDraggable || onClick || onMouseEnter || onMouseMove || onMouseLeave;
|
|
1800
1798
|
const onMouseEnterHandler = onMouseEnter
|
|
1801
1799
|
? (event) => onMouseEnter(event, { ...internals.userNode })
|
|
@@ -1869,7 +1867,7 @@ function NodeWrapper({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onC
|
|
|
1869
1867
|
},
|
|
1870
1868
|
]), ref: nodeRef, style: {
|
|
1871
1869
|
zIndex: internals.z,
|
|
1872
|
-
transform: `translate(${
|
|
1870
|
+
transform: `translate(${clampedPosition.x}px,${clampedPosition.y}px)`,
|
|
1873
1871
|
pointerEvents: hasPointerEvents ? 'all' : 'none',
|
|
1874
1872
|
visibility: hasDimensions ? 'visible' : 'hidden',
|
|
1875
1873
|
...node.style,
|
|
@@ -1877,7 +1875,7 @@ function NodeWrapper({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onC
|
|
|
1877
1875
|
}, "data-id": id, "data-testid": `rf__node-${id}`, onMouseEnter: onMouseEnterHandler, onMouseMove: onMouseMoveHandler, onMouseLeave: onMouseLeaveHandler, onContextMenu: onContextMenuHandler, onClick: onSelectNodeHandler, onDoubleClick: onDoubleClickHandler, onKeyDown: isFocusable ? onKeyDown : undefined, tabIndex: isFocusable ? 0 : undefined, role: isFocusable ? 'button' : undefined, "aria-describedby": disableKeyboardA11y ? undefined : `${ARIA_NODE_DESC_KEY}-${rfId}`, "aria-label": node.ariaLabel, children: jsx(Provider, { value: id, children: jsx(NodeComponent, { id: id, data: node.data, type: nodeType, positionAbsoluteX: clampedPosition.x, positionAbsoluteY: clampedPosition.y, selected: node.selected, selectable: isSelectable, draggable: isDraggable, deletable: node.deletable ?? true, isConnectable: isConnectable, sourcePosition: node.sourcePosition, targetPosition: node.targetPosition, dragging: dragging, dragHandle: node.dragHandle, zIndex: internals.z, parentId: node.parentId, ...nodeDimensions }) }) }));
|
|
1878
1876
|
}
|
|
1879
1877
|
|
|
1880
|
-
const selector$
|
|
1878
|
+
const selector$c = (s) => ({
|
|
1881
1879
|
nodesDraggable: s.nodesDraggable,
|
|
1882
1880
|
nodesConnectable: s.nodesConnectable,
|
|
1883
1881
|
nodesFocusable: s.nodesFocusable,
|
|
@@ -1885,7 +1883,7 @@ const selector$d = (s) => ({
|
|
|
1885
1883
|
onError: s.onError,
|
|
1886
1884
|
});
|
|
1887
1885
|
function NodeRendererComponent(props) {
|
|
1888
|
-
const { nodesDraggable, nodesConnectable, nodesFocusable, elementsSelectable, onError } = useStore(selector$
|
|
1886
|
+
const { nodesDraggable, nodesConnectable, nodesFocusable, elementsSelectable, onError } = useStore(selector$c, shallow);
|
|
1889
1887
|
const nodeIds = useVisibleNodeIds(props.onlyRenderVisibleElements);
|
|
1890
1888
|
const resizeObserver = useResizeObserver();
|
|
1891
1889
|
return (jsx("div", { className: "react-flow__nodes", style: containerStyle, children: nodeIds.map((nodeId) => {
|
|
@@ -1913,7 +1911,7 @@ function NodeRendererComponent(props) {
|
|
|
1913
1911
|
// moved into `NodeComponentWrapper`. This ensures they are
|
|
1914
1912
|
// memorized – so if `NodeRenderer` *has* to rerender, it only
|
|
1915
1913
|
// needs to regenerate the list of nodes, nothing else.
|
|
1916
|
-
jsx(NodeWrapper, { id: nodeId, nodeTypes: props.nodeTypes, nodeExtent: props.nodeExtent,
|
|
1914
|
+
jsx(NodeWrapper, { id: nodeId, nodeTypes: props.nodeTypes, nodeExtent: props.nodeExtent, onClick: props.onNodeClick, onMouseEnter: props.onNodeMouseEnter, onMouseMove: props.onNodeMouseMove, onMouseLeave: props.onNodeMouseLeave, onContextMenu: props.onNodeContextMenu, onDoubleClick: props.onNodeDoubleClick, noDragClassName: props.noDragClassName, noPanClassName: props.noPanClassName, rfId: props.rfId, disableKeyboardA11y: props.disableKeyboardA11y, resizeObserver: resizeObserver, nodesDraggable: nodesDraggable, nodesConnectable: nodesConnectable, nodesFocusable: nodesFocusable, elementsSelectable: elementsSelectable, onError: onError }, nodeId));
|
|
1917
1915
|
}) }));
|
|
1918
1916
|
}
|
|
1919
1917
|
NodeRendererComponent.displayName = 'NodeRenderer';
|
|
@@ -2243,7 +2241,7 @@ function EdgeUpdateAnchors({ isReconnectable, reconnectRadius, edge, targetHandl
|
|
|
2243
2241
|
onReconnectEnd: _onReconnectEnd,
|
|
2244
2242
|
updateConnection,
|
|
2245
2243
|
getTransform: () => store.getState().transform,
|
|
2246
|
-
|
|
2244
|
+
getFromHandle: () => store.getState().connection.fromHandle,
|
|
2247
2245
|
});
|
|
2248
2246
|
};
|
|
2249
2247
|
const onReconnectSourceMouseDown = (event) => handleEdgeUpdater(event, true);
|
|
@@ -2376,7 +2374,7 @@ function EdgeWrapper({ id, edgesFocusable, edgesReconnectable, elementsSelectabl
|
|
|
2376
2374
|
]), onClick: onEdgeClick, onDoubleClick: onEdgeDoubleClick, onContextMenu: onEdgeContextMenu, onMouseEnter: onEdgeMouseEnter, onMouseMove: onEdgeMouseMove, onMouseLeave: onEdgeMouseLeave, onKeyDown: isFocusable ? onKeyDown : undefined, tabIndex: isFocusable ? 0 : undefined, role: isFocusable ? 'button' : 'img', "data-id": id, "data-testid": `rf__edge-${id}`, "aria-label": edge.ariaLabel === null ? undefined : edge.ariaLabel || `Edge from ${edge.source} to ${edge.target}`, "aria-describedby": isFocusable ? `${ARIA_EDGE_DESC_KEY}-${rfId}` : undefined, ref: edgeRef, children: [!reconnecting && (jsx(EdgeComponent, { id: id, source: edge.source, target: edge.target, type: edge.type, selected: edge.selected, animated: edge.animated, selectable: isSelectable, deletable: edge.deletable ?? true, label: edge.label, labelStyle: edge.labelStyle, labelShowBg: edge.labelShowBg, labelBgStyle: edge.labelBgStyle, labelBgPadding: edge.labelBgPadding, labelBgBorderRadius: edge.labelBgBorderRadius, sourceX: sourceX, sourceY: sourceY, targetX: targetX, targetY: targetY, sourcePosition: sourcePosition, targetPosition: targetPosition, data: edge.data, style: edge.style, sourceHandleId: edge.sourceHandle, targetHandleId: edge.targetHandle, markerStart: markerStartUrl, markerEnd: markerEndUrl, pathOptions: 'pathOptions' in edge ? edge.pathOptions : undefined, interactionWidth: edge.interactionWidth })), isReconnectable && (jsx(EdgeUpdateAnchors, { edge: edge, isReconnectable: isReconnectable, reconnectRadius: reconnectRadius, onReconnect: onReconnect, onReconnectStart: onReconnectStart, onReconnectEnd: onReconnectEnd, sourceX: sourceX, sourceY: sourceY, targetX: targetX, targetY: targetY, sourcePosition: sourcePosition, targetPosition: targetPosition, setUpdateHover: setUpdateHover, setReconnecting: setReconnecting, sourceHandleId: edge.sourceHandle, targetHandleId: edge.targetHandle }))] }) }));
|
|
2377
2375
|
}
|
|
2378
2376
|
|
|
2379
|
-
const selector$
|
|
2377
|
+
const selector$b = (s) => ({
|
|
2380
2378
|
width: s.width,
|
|
2381
2379
|
height: s.height,
|
|
2382
2380
|
edgesFocusable: s.edgesFocusable,
|
|
@@ -2386,7 +2384,7 @@ const selector$c = (s) => ({
|
|
|
2386
2384
|
onError: s.onError,
|
|
2387
2385
|
});
|
|
2388
2386
|
function EdgeRendererComponent({ defaultMarkerColor, onlyRenderVisibleElements, rfId, edgeTypes, noPanClassName, onReconnect, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeClick, reconnectRadius, onEdgeDoubleClick, onReconnectStart, onReconnectEnd, disableKeyboardA11y, }) {
|
|
2389
|
-
const { edgesFocusable, edgesReconnectable, elementsSelectable, onError } = useStore(selector$
|
|
2387
|
+
const { edgesFocusable, edgesReconnectable, elementsSelectable, onError } = useStore(selector$b, shallow);
|
|
2390
2388
|
const edgeIds = useVisibleEdgeIds(onlyRenderVisibleElements);
|
|
2391
2389
|
return (jsxs("div", { className: "react-flow__edges", children: [jsx(MarkerDefinitions$1, { defaultColor: defaultMarkerColor, rfId: rfId }), edgeIds.map((id) => {
|
|
2392
2390
|
return (jsx(EdgeWrapper, { id: id, edgesFocusable: edgesFocusable, edgesReconnectable: edgesReconnectable, elementsSelectable: elementsSelectable, noPanClassName: noPanClassName, onReconnect: onReconnect, onContextMenu: onEdgeContextMenu, onMouseEnter: onEdgeMouseEnter, onMouseMove: onEdgeMouseMove, onMouseLeave: onEdgeMouseLeave, onClick: onEdgeClick, reconnectRadius: reconnectRadius, onDoubleClick: onEdgeDoubleClick, onReconnectStart: onReconnectStart, onReconnectEnd: onReconnectEnd, rfId: rfId, onError: onError, edgeTypes: edgeTypes, disableKeyboardA11y: disableKeyboardA11y }, id));
|
|
@@ -2395,9 +2393,9 @@ function EdgeRendererComponent({ defaultMarkerColor, onlyRenderVisibleElements,
|
|
|
2395
2393
|
EdgeRendererComponent.displayName = 'EdgeRenderer';
|
|
2396
2394
|
const EdgeRenderer = memo(EdgeRendererComponent);
|
|
2397
2395
|
|
|
2398
|
-
const selector$
|
|
2396
|
+
const selector$a = (s) => `translate(${s.transform[0]}px,${s.transform[1]}px) scale(${s.transform[2]})`;
|
|
2399
2397
|
function Viewport({ children }) {
|
|
2400
|
-
const transform = useStore(selector$
|
|
2398
|
+
const transform = useStore(selector$a);
|
|
2401
2399
|
return (jsx("div", { className: "react-flow__viewport xyflow__viewport react-flow__container", style: { transform }, children: children }));
|
|
2402
2400
|
}
|
|
2403
2401
|
|
|
@@ -2417,7 +2415,7 @@ function useOnInitHandler(onInit) {
|
|
|
2417
2415
|
}, [onInit, rfInstance.viewportInitialized]);
|
|
2418
2416
|
}
|
|
2419
2417
|
|
|
2420
|
-
const selector$
|
|
2418
|
+
const selector$9 = (state) => state.panZoom?.syncViewport;
|
|
2421
2419
|
/**
|
|
2422
2420
|
* Hook for syncing the viewport with the panzoom instance.
|
|
2423
2421
|
*
|
|
@@ -2425,7 +2423,7 @@ const selector$a = (state) => state.panZoom?.syncViewport;
|
|
|
2425
2423
|
* @param viewport
|
|
2426
2424
|
*/
|
|
2427
2425
|
function useViewportSync(viewport) {
|
|
2428
|
-
const syncViewport = useStore(selector$
|
|
2426
|
+
const syncViewport = useStore(selector$9);
|
|
2429
2427
|
const store = useStoreApi();
|
|
2430
2428
|
useEffect(() => {
|
|
2431
2429
|
if (viewport) {
|
|
@@ -2436,90 +2434,75 @@ function useViewportSync(viewport) {
|
|
|
2436
2434
|
return null;
|
|
2437
2435
|
}
|
|
2438
2436
|
|
|
2439
|
-
const
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
[Position.Bottom]: Position.Top,
|
|
2437
|
+
const selector$8 = (s) => {
|
|
2438
|
+
return s.connection.inProgress
|
|
2439
|
+
? { ...s.connection, to: pointToRendererPoint(s.connection.to, s.transform) }
|
|
2440
|
+
: { ...s.connection };
|
|
2444
2441
|
};
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2442
|
+
/**
|
|
2443
|
+
* Hook for accessing the connection state.
|
|
2444
|
+
*
|
|
2445
|
+
* @public
|
|
2446
|
+
* @returns ConnectionState
|
|
2447
|
+
*/
|
|
2448
|
+
function useConnection() {
|
|
2449
|
+
return useStore(selector$8, shallow);
|
|
2450
|
+
}
|
|
2451
|
+
|
|
2452
|
+
const selector$7 = (s) => ({
|
|
2453
|
+
nodesConnectable: s.nodesConnectable,
|
|
2454
|
+
isValid: s.connection.isValid,
|
|
2455
|
+
inProgress: s.connection.inProgress,
|
|
2456
|
+
width: s.width,
|
|
2457
|
+
height: s.height,
|
|
2458
|
+
});
|
|
2459
|
+
function ConnectionLineWrapper({ containerStyle, style, type, component }) {
|
|
2460
|
+
const { nodesConnectable, width, height, isValid, inProgress } = useStore(selector$7, shallow);
|
|
2461
|
+
const renderConnection = !!(width && nodesConnectable && inProgress);
|
|
2462
|
+
if (!renderConnection) {
|
|
2461
2463
|
return null;
|
|
2462
2464
|
}
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
const
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
const toPosition = isValid && endPosition ? endPosition : fromPosition ? oppositePosition[fromPosition] : null;
|
|
2470
|
-
if (!fromPosition || !toPosition) {
|
|
2471
|
-
return null;
|
|
2465
|
+
return (jsx("svg", { style: containerStyle, width: width, height: height, className: "react-flow__connectionline react-flow__container", children: jsx("g", { className: cc(['react-flow__connection', getConnectionStatus(isValid)]), children: jsx(ConnectionLine, { style: style, type: type, CustomComponent: component, isValid: isValid }) }) }));
|
|
2466
|
+
}
|
|
2467
|
+
const ConnectionLine = ({ style, type = ConnectionLineType.Bezier, CustomComponent, isValid }) => {
|
|
2468
|
+
const { inProgress, from, fromNode, fromHandle, fromPosition, to, toNode, toHandle, toPosition } = useConnection();
|
|
2469
|
+
if (!inProgress) {
|
|
2470
|
+
return;
|
|
2472
2471
|
}
|
|
2473
2472
|
if (CustomComponent) {
|
|
2474
|
-
return (jsx(CustomComponent, { connectionLineType: type, connectionLineStyle: style, fromNode: fromNode, fromHandle: fromHandle, fromX:
|
|
2473
|
+
return (jsx(CustomComponent, { connectionLineType: type, connectionLineStyle: style, fromNode: fromNode, fromHandle: fromHandle, fromX: from.x, fromY: from.y, toX: to.x, toY: to.y, fromPosition: fromPosition, toPosition: toPosition, connectionStatus: getConnectionStatus(isValid), toNode: toNode, toHandle: toHandle }));
|
|
2475
2474
|
}
|
|
2476
|
-
let
|
|
2475
|
+
let path = '';
|
|
2477
2476
|
const pathParams = {
|
|
2478
|
-
sourceX:
|
|
2479
|
-
sourceY:
|
|
2477
|
+
sourceX: from.x,
|
|
2478
|
+
sourceY: from.y,
|
|
2480
2479
|
sourcePosition: fromPosition,
|
|
2481
|
-
targetX:
|
|
2482
|
-
targetY:
|
|
2480
|
+
targetX: to.x,
|
|
2481
|
+
targetY: to.y,
|
|
2483
2482
|
targetPosition: toPosition,
|
|
2484
2483
|
};
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2484
|
+
switch (type) {
|
|
2485
|
+
case ConnectionLineType.Bezier:
|
|
2486
|
+
[path] = getBezierPath(pathParams);
|
|
2487
|
+
break;
|
|
2488
|
+
case ConnectionLineType.SimpleBezier:
|
|
2489
|
+
[path] = getSimpleBezierPath(pathParams);
|
|
2490
|
+
break;
|
|
2491
|
+
case ConnectionLineType.Step:
|
|
2492
|
+
[path] = getSmoothStepPath({
|
|
2493
|
+
...pathParams,
|
|
2494
|
+
borderRadius: 0,
|
|
2495
|
+
});
|
|
2496
|
+
break;
|
|
2497
|
+
case ConnectionLineType.SmoothStep:
|
|
2498
|
+
[path] = getSmoothStepPath(pathParams);
|
|
2499
|
+
break;
|
|
2500
|
+
default:
|
|
2501
|
+
[path] = getStraightPath(pathParams);
|
|
2503
2502
|
}
|
|
2504
|
-
return jsx("path", { d:
|
|
2503
|
+
return jsx("path", { d: path, fill: "none", className: "react-flow__connection-path", style: style });
|
|
2505
2504
|
};
|
|
2506
2505
|
ConnectionLine.displayName = 'ConnectionLine';
|
|
2507
|
-
const selector$9 = (s) => ({
|
|
2508
|
-
nodeId: s.connectionStartHandle?.nodeId,
|
|
2509
|
-
handleType: s.connectionStartHandle?.type,
|
|
2510
|
-
nodesConnectable: s.nodesConnectable,
|
|
2511
|
-
connectionStatus: s.connectionStatus,
|
|
2512
|
-
width: s.width,
|
|
2513
|
-
height: s.height,
|
|
2514
|
-
});
|
|
2515
|
-
function ConnectionLineWrapper({ containerStyle, style, type, component }) {
|
|
2516
|
-
const { nodeId, handleType, nodesConnectable, width, height, connectionStatus } = useStore(selector$9, shallow);
|
|
2517
|
-
const isValid = !!(nodeId && handleType && width && nodesConnectable);
|
|
2518
|
-
if (!isValid) {
|
|
2519
|
-
return null;
|
|
2520
|
-
}
|
|
2521
|
-
return (jsx("svg", { style: containerStyle, width: width, height: height, className: "react-flow__connectionline react-flow__container", children: jsx("g", { className: cc(['react-flow__connection', connectionStatus]), children: jsx(ConnectionLine, { nodeId: nodeId, handleType: handleType, style: style, type: type, CustomComponent: component, connectionStatus: connectionStatus }) }) }));
|
|
2522
|
-
}
|
|
2523
2506
|
|
|
2524
2507
|
const emptyTypes = {};
|
|
2525
2508
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -2556,34 +2539,33 @@ function useStylesLoadedWarning() {
|
|
|
2556
2539
|
}, []);
|
|
2557
2540
|
}
|
|
2558
2541
|
|
|
2559
|
-
function GraphViewComponent({ nodeTypes, edgeTypes, onInit, onNodeClick, onEdgeClick, onNodeDoubleClick, onEdgeDoubleClick, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onSelectionContextMenu, onSelectionStart, onSelectionEnd, connectionLineType, connectionLineStyle, connectionLineComponent, connectionLineContainerStyle, selectionKeyCode, selectionOnDrag, selectionMode, multiSelectionKeyCode, panActivationKeyCode, zoomActivationKeyCode, deleteKeyCode, onlyRenderVisibleElements, elementsSelectable, defaultViewport, translateExtent, minZoom, maxZoom, preventScrolling, defaultMarkerColor, zoomOnScroll, zoomOnPinch, panOnScroll, panOnScrollSpeed, panOnScrollMode, zoomOnDoubleClick, panOnDrag, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneScroll, onPaneContextMenu, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, reconnectRadius, onReconnect, onReconnectStart, onReconnectEnd, noDragClassName, noWheelClassName, noPanClassName, disableKeyboardA11y,
|
|
2542
|
+
function GraphViewComponent({ nodeTypes, edgeTypes, onInit, onNodeClick, onEdgeClick, onNodeDoubleClick, onEdgeDoubleClick, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onSelectionContextMenu, onSelectionStart, onSelectionEnd, connectionLineType, connectionLineStyle, connectionLineComponent, connectionLineContainerStyle, selectionKeyCode, selectionOnDrag, selectionMode, multiSelectionKeyCode, panActivationKeyCode, zoomActivationKeyCode, deleteKeyCode, onlyRenderVisibleElements, elementsSelectable, defaultViewport, translateExtent, minZoom, maxZoom, preventScrolling, defaultMarkerColor, zoomOnScroll, zoomOnPinch, panOnScroll, panOnScrollSpeed, panOnScrollMode, zoomOnDoubleClick, panOnDrag, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneScroll, onPaneContextMenu, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, reconnectRadius, onReconnect, onReconnectStart, onReconnectEnd, noDragClassName, noWheelClassName, noPanClassName, disableKeyboardA11y, nodeExtent, rfId, viewport, onViewportChange, }) {
|
|
2560
2543
|
useNodeOrEdgeTypesWarning(nodeTypes);
|
|
2561
2544
|
useNodeOrEdgeTypesWarning(edgeTypes);
|
|
2562
2545
|
useStylesLoadedWarning();
|
|
2563
2546
|
useOnInitHandler(onInit);
|
|
2564
2547
|
useViewportSync(viewport);
|
|
2565
|
-
return (jsx(FlowRenderer, { onPaneClick: onPaneClick, onPaneMouseEnter: onPaneMouseEnter, onPaneMouseMove: onPaneMouseMove, onPaneMouseLeave: onPaneMouseLeave, onPaneContextMenu: onPaneContextMenu, onPaneScroll: onPaneScroll, deleteKeyCode: deleteKeyCode, selectionKeyCode: selectionKeyCode, selectionOnDrag: selectionOnDrag, selectionMode: selectionMode, onSelectionStart: onSelectionStart, onSelectionEnd: onSelectionEnd, multiSelectionKeyCode: multiSelectionKeyCode, panActivationKeyCode: panActivationKeyCode, zoomActivationKeyCode: zoomActivationKeyCode, elementsSelectable: elementsSelectable, zoomOnScroll: zoomOnScroll, zoomOnPinch: zoomOnPinch, zoomOnDoubleClick: zoomOnDoubleClick, panOnScroll: panOnScroll, panOnScrollSpeed: panOnScrollSpeed, panOnScrollMode: panOnScrollMode, panOnDrag: panOnDrag, defaultViewport: defaultViewport, translateExtent: translateExtent, minZoom: minZoom, maxZoom: maxZoom, onSelectionContextMenu: onSelectionContextMenu, preventScrolling: preventScrolling, noDragClassName: noDragClassName, noWheelClassName: noWheelClassName, noPanClassName: noPanClassName, disableKeyboardA11y: disableKeyboardA11y, onViewportChange: onViewportChange, isControlledViewport: !!viewport, children: jsxs(Viewport, { children: [jsx(EdgeRenderer, { edgeTypes: edgeTypes, onEdgeClick: onEdgeClick, onEdgeDoubleClick: onEdgeDoubleClick, onReconnect: onReconnect, onReconnectStart: onReconnectStart, onReconnectEnd: onReconnectEnd, onlyRenderVisibleElements: onlyRenderVisibleElements, onEdgeContextMenu: onEdgeContextMenu, onEdgeMouseEnter: onEdgeMouseEnter, onEdgeMouseMove: onEdgeMouseMove, onEdgeMouseLeave: onEdgeMouseLeave, reconnectRadius: reconnectRadius, defaultMarkerColor: defaultMarkerColor, noPanClassName: noPanClassName, disableKeyboardA11y: disableKeyboardA11y, rfId: rfId }), jsx(ConnectionLineWrapper, { style: connectionLineStyle, type: connectionLineType, component: connectionLineComponent, containerStyle: connectionLineContainerStyle }), jsx("div", { className: "react-flow__edgelabel-renderer" }), jsx(NodeRenderer, { nodeTypes: nodeTypes, onNodeClick: onNodeClick, onNodeDoubleClick: onNodeDoubleClick, onNodeMouseEnter: onNodeMouseEnter, onNodeMouseMove: onNodeMouseMove, onNodeMouseLeave: onNodeMouseLeave, onNodeContextMenu: onNodeContextMenu, onlyRenderVisibleElements: onlyRenderVisibleElements, noPanClassName: noPanClassName, noDragClassName: noDragClassName, disableKeyboardA11y: disableKeyboardA11y,
|
|
2548
|
+
return (jsx(FlowRenderer, { onPaneClick: onPaneClick, onPaneMouseEnter: onPaneMouseEnter, onPaneMouseMove: onPaneMouseMove, onPaneMouseLeave: onPaneMouseLeave, onPaneContextMenu: onPaneContextMenu, onPaneScroll: onPaneScroll, deleteKeyCode: deleteKeyCode, selectionKeyCode: selectionKeyCode, selectionOnDrag: selectionOnDrag, selectionMode: selectionMode, onSelectionStart: onSelectionStart, onSelectionEnd: onSelectionEnd, multiSelectionKeyCode: multiSelectionKeyCode, panActivationKeyCode: panActivationKeyCode, zoomActivationKeyCode: zoomActivationKeyCode, elementsSelectable: elementsSelectable, zoomOnScroll: zoomOnScroll, zoomOnPinch: zoomOnPinch, zoomOnDoubleClick: zoomOnDoubleClick, panOnScroll: panOnScroll, panOnScrollSpeed: panOnScrollSpeed, panOnScrollMode: panOnScrollMode, panOnDrag: panOnDrag, defaultViewport: defaultViewport, translateExtent: translateExtent, minZoom: minZoom, maxZoom: maxZoom, onSelectionContextMenu: onSelectionContextMenu, preventScrolling: preventScrolling, noDragClassName: noDragClassName, noWheelClassName: noWheelClassName, noPanClassName: noPanClassName, disableKeyboardA11y: disableKeyboardA11y, onViewportChange: onViewportChange, isControlledViewport: !!viewport, children: jsxs(Viewport, { children: [jsx(EdgeRenderer, { edgeTypes: edgeTypes, onEdgeClick: onEdgeClick, onEdgeDoubleClick: onEdgeDoubleClick, onReconnect: onReconnect, onReconnectStart: onReconnectStart, onReconnectEnd: onReconnectEnd, onlyRenderVisibleElements: onlyRenderVisibleElements, onEdgeContextMenu: onEdgeContextMenu, onEdgeMouseEnter: onEdgeMouseEnter, onEdgeMouseMove: onEdgeMouseMove, onEdgeMouseLeave: onEdgeMouseLeave, reconnectRadius: reconnectRadius, defaultMarkerColor: defaultMarkerColor, noPanClassName: noPanClassName, disableKeyboardA11y: disableKeyboardA11y, rfId: rfId }), jsx(ConnectionLineWrapper, { style: connectionLineStyle, type: connectionLineType, component: connectionLineComponent, containerStyle: connectionLineContainerStyle }), jsx("div", { className: "react-flow__edgelabel-renderer" }), jsx(NodeRenderer, { nodeTypes: nodeTypes, onNodeClick: onNodeClick, onNodeDoubleClick: onNodeDoubleClick, onNodeMouseEnter: onNodeMouseEnter, onNodeMouseMove: onNodeMouseMove, onNodeMouseLeave: onNodeMouseLeave, onNodeContextMenu: onNodeContextMenu, onlyRenderVisibleElements: onlyRenderVisibleElements, noPanClassName: noPanClassName, noDragClassName: noDragClassName, disableKeyboardA11y: disableKeyboardA11y, nodeExtent: nodeExtent, rfId: rfId }), jsx("div", { className: "react-flow__viewport-portal" })] }) }));
|
|
2566
2549
|
}
|
|
2567
2550
|
GraphViewComponent.displayName = 'GraphView';
|
|
2568
2551
|
const GraphView = memo(GraphViewComponent);
|
|
2569
2552
|
|
|
2570
|
-
const getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, height, fitView, } = {}) => {
|
|
2553
|
+
const getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, height, fitView, nodeOrigin, } = {}) => {
|
|
2571
2554
|
const nodeLookup = new Map();
|
|
2572
2555
|
const parentLookup = new Map();
|
|
2573
2556
|
const connectionLookup = new Map();
|
|
2574
2557
|
const edgeLookup = new Map();
|
|
2575
2558
|
const storeEdges = defaultEdges ?? edges ?? [];
|
|
2576
2559
|
const storeNodes = defaultNodes ?? nodes ?? [];
|
|
2560
|
+
const storeNodeOrigin = nodeOrigin ?? [0, 0];
|
|
2577
2561
|
updateConnectionLookup(connectionLookup, edgeLookup, storeEdges);
|
|
2578
2562
|
adoptUserNodes(storeNodes, nodeLookup, parentLookup, {
|
|
2579
|
-
nodeOrigin:
|
|
2563
|
+
nodeOrigin: storeNodeOrigin,
|
|
2580
2564
|
elevateNodesOnSelect: false,
|
|
2581
2565
|
});
|
|
2582
2566
|
let transform = [0, 0, 1];
|
|
2583
2567
|
if (fitView && width && height) {
|
|
2584
|
-
// @todo users nodeOrigin should be used here
|
|
2585
2568
|
const bounds = getInternalNodesBounds(nodeLookup, {
|
|
2586
|
-
nodeOrigin: [0, 0],
|
|
2587
2569
|
filter: (node) => !!((node.width || node.initialWidth) && (node.height || node.initialHeight)),
|
|
2588
2570
|
});
|
|
2589
2571
|
const { x, y, zoom } = getViewportForBounds(bounds, width, height, 0.5, 2, 0.1);
|
|
@@ -2612,13 +2594,11 @@ const getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, heig
|
|
|
2612
2594
|
nodesSelectionActive: false,
|
|
2613
2595
|
userSelectionActive: false,
|
|
2614
2596
|
userSelectionRect: null,
|
|
2615
|
-
connectionPosition: { x: 0, y: 0 },
|
|
2616
|
-
connectionStatus: null,
|
|
2617
2597
|
connectionMode: ConnectionMode.Strict,
|
|
2618
2598
|
domNode: null,
|
|
2619
2599
|
paneDragging: false,
|
|
2620
2600
|
noPanClassName: 'nopan',
|
|
2621
|
-
nodeOrigin:
|
|
2601
|
+
nodeOrigin: storeNodeOrigin,
|
|
2622
2602
|
nodeDragThreshold: 1,
|
|
2623
2603
|
snapGrid: [15, 15],
|
|
2624
2604
|
snapToGrid: false,
|
|
@@ -2635,13 +2615,13 @@ const getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, heig
|
|
|
2635
2615
|
fitViewOnInitOptions: undefined,
|
|
2636
2616
|
selectNodesOnDrag: true,
|
|
2637
2617
|
multiSelectionActive: false,
|
|
2638
|
-
|
|
2639
|
-
connectionEndHandle: null,
|
|
2618
|
+
connection: { ...initialConnection },
|
|
2640
2619
|
connectionClickStartHandle: null,
|
|
2641
2620
|
connectOnClick: true,
|
|
2642
2621
|
ariaLiveMessage: '',
|
|
2643
2622
|
autoPanOnConnect: true,
|
|
2644
2623
|
autoPanOnNodeDrag: true,
|
|
2624
|
+
autoPanSpeed: 15,
|
|
2645
2625
|
connectionRadius: 20,
|
|
2646
2626
|
onError: devWarn,
|
|
2647
2627
|
isValidConnection: undefined,
|
|
@@ -2651,8 +2631,8 @@ const getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, heig
|
|
|
2651
2631
|
};
|
|
2652
2632
|
};
|
|
2653
2633
|
|
|
2654
|
-
const createStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height, fitView: fitView$1, }) => createWithEqualityFn((set, get) => ({
|
|
2655
|
-
...getInitialState({ nodes, edges, width, height, fitView: fitView$1, defaultNodes, defaultEdges }),
|
|
2634
|
+
const createStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height, fitView: fitView$1, nodeOrigin, }) => createWithEqualityFn((set, get) => ({
|
|
2635
|
+
...getInitialState({ nodes, edges, width, height, fitView: fitView$1, nodeOrigin, defaultNodes, defaultEdges }),
|
|
2656
2636
|
setNodes: (nodes) => {
|
|
2657
2637
|
const { nodeLookup, parentLookup, nodeOrigin, elevateNodesOnSelect } = get();
|
|
2658
2638
|
// setNodes() is called exclusively in response to user actions:
|
|
@@ -2690,7 +2670,7 @@ const createStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height,
|
|
|
2690
2670
|
if (!updatedInternals) {
|
|
2691
2671
|
return;
|
|
2692
2672
|
}
|
|
2693
|
-
updateAbsolutePositions(nodeLookup, { nodeOrigin });
|
|
2673
|
+
updateAbsolutePositions(nodeLookup, parentLookup, { nodeOrigin });
|
|
2694
2674
|
// we call fitView once initially after all dimensions are set
|
|
2695
2675
|
let nextFitViewDone = fitViewDone;
|
|
2696
2676
|
if (!fitViewDone && fitViewOnInit) {
|
|
@@ -2739,8 +2719,8 @@ const createStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height,
|
|
|
2739
2719
|
changes.push(change);
|
|
2740
2720
|
}
|
|
2741
2721
|
if (parentExpandChildren.length > 0) {
|
|
2742
|
-
const { nodeLookup, parentLookup } = get();
|
|
2743
|
-
const parentExpandChanges = handleExpandParent(parentExpandChildren, nodeLookup, parentLookup);
|
|
2722
|
+
const { nodeLookup, parentLookup, nodeOrigin } = get();
|
|
2723
|
+
const parentExpandChanges = handleExpandParent(parentExpandChildren, nodeLookup, parentLookup, nodeOrigin);
|
|
2744
2724
|
changes.push(...parentExpandChanges);
|
|
2745
2725
|
}
|
|
2746
2726
|
get().triggerNodeChanges(changes);
|
|
@@ -2845,7 +2825,7 @@ const createStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height,
|
|
|
2845
2825
|
return panBy({ delta, panZoom, transform, translateExtent, width, height });
|
|
2846
2826
|
},
|
|
2847
2827
|
fitView: (options) => {
|
|
2848
|
-
const { panZoom, width, height, minZoom, maxZoom,
|
|
2828
|
+
const { panZoom, width, height, minZoom, maxZoom, nodeLookup } = get();
|
|
2849
2829
|
if (!panZoom) {
|
|
2850
2830
|
return false;
|
|
2851
2831
|
}
|
|
@@ -2856,26 +2836,20 @@ const createStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height,
|
|
|
2856
2836
|
panZoom,
|
|
2857
2837
|
minZoom,
|
|
2858
2838
|
maxZoom,
|
|
2859
|
-
nodeOrigin,
|
|
2860
2839
|
}, options);
|
|
2861
2840
|
},
|
|
2862
|
-
cancelConnection: () =>
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
}
|
|
2867
|
-
updateConnection: (
|
|
2868
|
-
|
|
2869
|
-
const currentConnection = {
|
|
2870
|
-
...params,
|
|
2871
|
-
connectionPosition: params.connectionPosition ?? connectionPosition,
|
|
2872
|
-
};
|
|
2873
|
-
set(currentConnection);
|
|
2841
|
+
cancelConnection: () => {
|
|
2842
|
+
set({
|
|
2843
|
+
connection: { ...initialConnection },
|
|
2844
|
+
});
|
|
2845
|
+
},
|
|
2846
|
+
updateConnection: (connection) => {
|
|
2847
|
+
set({ connection });
|
|
2874
2848
|
},
|
|
2875
2849
|
reset: () => set({ ...getInitialState() }),
|
|
2876
2850
|
}), Object.is);
|
|
2877
2851
|
|
|
2878
|
-
function ReactFlowProvider({ initialNodes: nodes, initialEdges: edges, defaultNodes, defaultEdges, initialWidth: width, initialHeight: height, fitView, children, }) {
|
|
2852
|
+
function ReactFlowProvider({ initialNodes: nodes, initialEdges: edges, defaultNodes, defaultEdges, initialWidth: width, initialHeight: height, fitView, nodeOrigin, children, }) {
|
|
2879
2853
|
const [store] = useState(() => createStore({
|
|
2880
2854
|
nodes,
|
|
2881
2855
|
edges,
|
|
@@ -2884,18 +2858,19 @@ function ReactFlowProvider({ initialNodes: nodes, initialEdges: edges, defaultNo
|
|
|
2884
2858
|
width,
|
|
2885
2859
|
height,
|
|
2886
2860
|
fitView,
|
|
2861
|
+
nodeOrigin,
|
|
2887
2862
|
}));
|
|
2888
2863
|
return (jsx(Provider$1, { value: store, children: jsx(BatchProvider, { children: children }) }));
|
|
2889
2864
|
}
|
|
2890
2865
|
|
|
2891
|
-
function Wrapper({ children, nodes, edges, defaultNodes, defaultEdges, width, height, fitView, }) {
|
|
2866
|
+
function Wrapper({ children, nodes, edges, defaultNodes, defaultEdges, width, height, fitView, nodeOrigin, }) {
|
|
2892
2867
|
const isWrapped = useContext(StoreContext);
|
|
2893
2868
|
if (isWrapped) {
|
|
2894
2869
|
// we need to wrap it with a fragment because it's not allowed for children to be a ReactNode
|
|
2895
2870
|
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18051
|
|
2896
2871
|
return jsx(Fragment, { children: children });
|
|
2897
2872
|
}
|
|
2898
|
-
return (jsx(ReactFlowProvider, { initialNodes: nodes, initialEdges: edges, defaultNodes: defaultNodes, defaultEdges: defaultEdges, initialWidth: width, initialHeight: height, fitView: fitView, children: children }));
|
|
2873
|
+
return (jsx(ReactFlowProvider, { initialNodes: nodes, initialEdges: edges, defaultNodes: defaultNodes, defaultEdges: defaultEdges, initialWidth: width, initialHeight: height, fitView: fitView, nodeOrigin: nodeOrigin, children: children }));
|
|
2899
2874
|
}
|
|
2900
2875
|
|
|
2901
2876
|
const wrapperStyle = {
|
|
@@ -2905,25 +2880,25 @@ const wrapperStyle = {
|
|
|
2905
2880
|
position: 'relative',
|
|
2906
2881
|
zIndex: 0,
|
|
2907
2882
|
};
|
|
2908
|
-
function ReactFlow({ nodes, edges, defaultNodes, defaultEdges, className, nodeTypes, edgeTypes, onNodeClick, onEdgeClick, onInit, onMove, onMoveStart, onMoveEnd, onConnect, onConnectStart, onConnectEnd, onClickConnectStart, onClickConnectEnd, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onNodeDoubleClick, onNodeDragStart, onNodeDrag, onNodeDragStop, onNodesDelete, onEdgesDelete, onDelete, onSelectionChange, onSelectionDragStart, onSelectionDrag, onSelectionDragStop, onSelectionContextMenu, onSelectionStart, onSelectionEnd, onBeforeDelete, connectionMode, connectionLineType = ConnectionLineType.Bezier, connectionLineStyle, connectionLineComponent, connectionLineContainerStyle, deleteKeyCode = 'Backspace', selectionKeyCode = 'Shift', selectionOnDrag = false, selectionMode = SelectionMode.Full, panActivationKeyCode = 'Space', multiSelectionKeyCode = isMacOs() ? 'Meta' : 'Control', zoomActivationKeyCode = isMacOs() ? 'Meta' : 'Control', snapToGrid, snapGrid, onlyRenderVisibleElements = false, selectNodesOnDrag, nodesDraggable, nodesConnectable, nodesFocusable, nodeOrigin = defaultNodeOrigin, edgesFocusable, edgesReconnectable, elementsSelectable = true, defaultViewport: defaultViewport$1 = defaultViewport, minZoom = 0.5, maxZoom = 2, translateExtent = infiniteExtent, preventScrolling = true, nodeExtent, defaultMarkerColor = '#b1b1b7', zoomOnScroll = true, zoomOnPinch = true, panOnScroll = false, panOnScrollSpeed = 0.5, panOnScrollMode = PanOnScrollMode.Free, zoomOnDoubleClick = true, panOnDrag = true, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneScroll, onPaneContextMenu, children, onReconnect, onReconnectStart, onReconnectEnd, onEdgeContextMenu, onEdgeDoubleClick, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, reconnectRadius = 10, onNodesChange, onEdgesChange, noDragClassName = 'nodrag', noWheelClassName = 'nowheel', noPanClassName = 'nopan', fitView, fitViewOptions, connectOnClick, attributionPosition, proOptions, defaultEdgeOptions, elevateNodesOnSelect, elevateEdgesOnSelect, disableKeyboardA11y = false, autoPanOnConnect, autoPanOnNodeDrag, connectionRadius, isValidConnection, onError, style, id, nodeDragThreshold, viewport, onViewportChange, width, height, colorMode = 'light', debug, ...rest }, ref) {
|
|
2883
|
+
function ReactFlow({ nodes, edges, defaultNodes, defaultEdges, className, nodeTypes, edgeTypes, onNodeClick, onEdgeClick, onInit, onMove, onMoveStart, onMoveEnd, onConnect, onConnectStart, onConnectEnd, onClickConnectStart, onClickConnectEnd, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onNodeDoubleClick, onNodeDragStart, onNodeDrag, onNodeDragStop, onNodesDelete, onEdgesDelete, onDelete, onSelectionChange, onSelectionDragStart, onSelectionDrag, onSelectionDragStop, onSelectionContextMenu, onSelectionStart, onSelectionEnd, onBeforeDelete, connectionMode, connectionLineType = ConnectionLineType.Bezier, connectionLineStyle, connectionLineComponent, connectionLineContainerStyle, deleteKeyCode = 'Backspace', selectionKeyCode = 'Shift', selectionOnDrag = false, selectionMode = SelectionMode.Full, panActivationKeyCode = 'Space', multiSelectionKeyCode = isMacOs() ? 'Meta' : 'Control', zoomActivationKeyCode = isMacOs() ? 'Meta' : 'Control', snapToGrid, snapGrid, onlyRenderVisibleElements = false, selectNodesOnDrag, nodesDraggable, nodesConnectable, nodesFocusable, nodeOrigin = defaultNodeOrigin, edgesFocusable, edgesReconnectable, elementsSelectable = true, defaultViewport: defaultViewport$1 = defaultViewport, minZoom = 0.5, maxZoom = 2, translateExtent = infiniteExtent, preventScrolling = true, nodeExtent, defaultMarkerColor = '#b1b1b7', zoomOnScroll = true, zoomOnPinch = true, panOnScroll = false, panOnScrollSpeed = 0.5, panOnScrollMode = PanOnScrollMode.Free, zoomOnDoubleClick = true, panOnDrag = true, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneScroll, onPaneContextMenu, children, onReconnect, onReconnectStart, onReconnectEnd, onEdgeContextMenu, onEdgeDoubleClick, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, reconnectRadius = 10, onNodesChange, onEdgesChange, noDragClassName = 'nodrag', noWheelClassName = 'nowheel', noPanClassName = 'nopan', fitView, fitViewOptions, connectOnClick, attributionPosition, proOptions, defaultEdgeOptions, elevateNodesOnSelect, elevateEdgesOnSelect, disableKeyboardA11y = false, autoPanOnConnect, autoPanOnNodeDrag, autoPanSpeed, connectionRadius, isValidConnection, onError, style, id, nodeDragThreshold, viewport, onViewportChange, width, height, colorMode = 'light', debug, ...rest }, ref) {
|
|
2909
2884
|
const rfId = id || '1';
|
|
2910
2885
|
const colorModeClassName = useColorModeClass(colorMode);
|
|
2911
|
-
return (jsx("div", { ...rest, style: { ...style, ...wrapperStyle }, ref: ref, className: cc(['react-flow', className, colorModeClassName]), "data-testid": "rf__wrapper", id: id, children: jsxs(Wrapper, { nodes: nodes, edges: edges, width: width, height: height, fitView: fitView, children: [jsx(GraphView, { onInit: onInit, onNodeClick: onNodeClick, onEdgeClick: onEdgeClick, onNodeMouseEnter: onNodeMouseEnter, onNodeMouseMove: onNodeMouseMove, onNodeMouseLeave: onNodeMouseLeave, onNodeContextMenu: onNodeContextMenu, onNodeDoubleClick: onNodeDoubleClick, nodeTypes: nodeTypes, edgeTypes: edgeTypes, connectionLineType: connectionLineType, connectionLineStyle: connectionLineStyle, connectionLineComponent: connectionLineComponent, connectionLineContainerStyle: connectionLineContainerStyle, selectionKeyCode: selectionKeyCode, selectionOnDrag: selectionOnDrag, selectionMode: selectionMode, deleteKeyCode: deleteKeyCode, multiSelectionKeyCode: multiSelectionKeyCode, panActivationKeyCode: panActivationKeyCode, zoomActivationKeyCode: zoomActivationKeyCode, onlyRenderVisibleElements: onlyRenderVisibleElements, defaultViewport: defaultViewport$1, translateExtent: translateExtent, minZoom: minZoom, maxZoom: maxZoom, preventScrolling: preventScrolling, zoomOnScroll: zoomOnScroll, zoomOnPinch: zoomOnPinch, zoomOnDoubleClick: zoomOnDoubleClick, panOnScroll: panOnScroll, panOnScrollSpeed: panOnScrollSpeed, panOnScrollMode: panOnScrollMode, panOnDrag: panOnDrag, onPaneClick: onPaneClick, onPaneMouseEnter: onPaneMouseEnter, onPaneMouseMove: onPaneMouseMove, onPaneMouseLeave: onPaneMouseLeave, onPaneScroll: onPaneScroll, onPaneContextMenu: onPaneContextMenu, onSelectionContextMenu: onSelectionContextMenu, onSelectionStart: onSelectionStart, onSelectionEnd: onSelectionEnd, onReconnect: onReconnect, onReconnectStart: onReconnectStart, onReconnectEnd: onReconnectEnd, onEdgeContextMenu: onEdgeContextMenu, onEdgeDoubleClick: onEdgeDoubleClick, onEdgeMouseEnter: onEdgeMouseEnter, onEdgeMouseMove: onEdgeMouseMove, onEdgeMouseLeave: onEdgeMouseLeave, reconnectRadius: reconnectRadius, defaultMarkerColor: defaultMarkerColor, noDragClassName: noDragClassName, noWheelClassName: noWheelClassName, noPanClassName: noPanClassName, rfId: rfId, disableKeyboardA11y: disableKeyboardA11y,
|
|
2886
|
+
return (jsx("div", { ...rest, style: { ...style, ...wrapperStyle }, ref: ref, className: cc(['react-flow', className, colorModeClassName]), "data-testid": "rf__wrapper", id: id, children: jsxs(Wrapper, { nodes: nodes, edges: edges, width: width, height: height, fitView: fitView, nodeOrigin: nodeOrigin, children: [jsx(GraphView, { onInit: onInit, onNodeClick: onNodeClick, onEdgeClick: onEdgeClick, onNodeMouseEnter: onNodeMouseEnter, onNodeMouseMove: onNodeMouseMove, onNodeMouseLeave: onNodeMouseLeave, onNodeContextMenu: onNodeContextMenu, onNodeDoubleClick: onNodeDoubleClick, nodeTypes: nodeTypes, edgeTypes: edgeTypes, connectionLineType: connectionLineType, connectionLineStyle: connectionLineStyle, connectionLineComponent: connectionLineComponent, connectionLineContainerStyle: connectionLineContainerStyle, selectionKeyCode: selectionKeyCode, selectionOnDrag: selectionOnDrag, selectionMode: selectionMode, deleteKeyCode: deleteKeyCode, multiSelectionKeyCode: multiSelectionKeyCode, panActivationKeyCode: panActivationKeyCode, zoomActivationKeyCode: zoomActivationKeyCode, onlyRenderVisibleElements: onlyRenderVisibleElements, defaultViewport: defaultViewport$1, translateExtent: translateExtent, minZoom: minZoom, maxZoom: maxZoom, preventScrolling: preventScrolling, zoomOnScroll: zoomOnScroll, zoomOnPinch: zoomOnPinch, zoomOnDoubleClick: zoomOnDoubleClick, panOnScroll: panOnScroll, panOnScrollSpeed: panOnScrollSpeed, panOnScrollMode: panOnScrollMode, panOnDrag: panOnDrag, onPaneClick: onPaneClick, onPaneMouseEnter: onPaneMouseEnter, onPaneMouseMove: onPaneMouseMove, onPaneMouseLeave: onPaneMouseLeave, onPaneScroll: onPaneScroll, onPaneContextMenu: onPaneContextMenu, onSelectionContextMenu: onSelectionContextMenu, onSelectionStart: onSelectionStart, onSelectionEnd: onSelectionEnd, onReconnect: onReconnect, onReconnectStart: onReconnectStart, onReconnectEnd: onReconnectEnd, onEdgeContextMenu: onEdgeContextMenu, onEdgeDoubleClick: onEdgeDoubleClick, onEdgeMouseEnter: onEdgeMouseEnter, onEdgeMouseMove: onEdgeMouseMove, onEdgeMouseLeave: onEdgeMouseLeave, reconnectRadius: reconnectRadius, defaultMarkerColor: defaultMarkerColor, noDragClassName: noDragClassName, noWheelClassName: noWheelClassName, noPanClassName: noPanClassName, rfId: rfId, disableKeyboardA11y: disableKeyboardA11y, nodeExtent: nodeExtent, viewport: viewport, onViewportChange: onViewportChange }), jsx(StoreUpdater, { nodes: nodes, edges: edges, defaultNodes: defaultNodes, defaultEdges: defaultEdges, onConnect: onConnect, onConnectStart: onConnectStart, onConnectEnd: onConnectEnd, onClickConnectStart: onClickConnectStart, onClickConnectEnd: onClickConnectEnd, nodesDraggable: nodesDraggable, nodesConnectable: nodesConnectable, nodesFocusable: nodesFocusable, edgesFocusable: edgesFocusable, edgesReconnectable: edgesReconnectable, elementsSelectable: elementsSelectable, elevateNodesOnSelect: elevateNodesOnSelect, elevateEdgesOnSelect: elevateEdgesOnSelect, minZoom: minZoom, maxZoom: maxZoom, nodeExtent: nodeExtent, onNodesChange: onNodesChange, onEdgesChange: onEdgesChange, snapToGrid: snapToGrid, snapGrid: snapGrid, connectionMode: connectionMode, translateExtent: translateExtent, connectOnClick: connectOnClick, defaultEdgeOptions: defaultEdgeOptions, fitView: fitView, fitViewOptions: fitViewOptions, onNodesDelete: onNodesDelete, onEdgesDelete: onEdgesDelete, onDelete: onDelete, onNodeDragStart: onNodeDragStart, onNodeDrag: onNodeDrag, onNodeDragStop: onNodeDragStop, onSelectionDrag: onSelectionDrag, onSelectionDragStart: onSelectionDragStart, onSelectionDragStop: onSelectionDragStop, onMove: onMove, onMoveStart: onMoveStart, onMoveEnd: onMoveEnd, noPanClassName: noPanClassName, nodeOrigin: nodeOrigin, rfId: rfId, autoPanOnConnect: autoPanOnConnect, autoPanOnNodeDrag: autoPanOnNodeDrag, autoPanSpeed: autoPanSpeed, onError: onError, connectionRadius: connectionRadius, isValidConnection: isValidConnection, selectNodesOnDrag: selectNodesOnDrag, nodeDragThreshold: nodeDragThreshold, onBeforeDelete: onBeforeDelete, debug: debug }), jsx(SelectionListener, { onSelectionChange: onSelectionChange }), children, jsx(Attribution, { proOptions: proOptions, position: attributionPosition }), jsx(A11yDescriptions, { rfId: rfId, disableKeyboardA11y: disableKeyboardA11y })] }) }));
|
|
2912
2887
|
}
|
|
2913
2888
|
var index = fixedForwardRef(ReactFlow);
|
|
2914
2889
|
|
|
2915
|
-
const selector$
|
|
2890
|
+
const selector$6 = (s) => s.domNode?.querySelector('.react-flow__edgelabel-renderer');
|
|
2916
2891
|
function EdgeLabelRenderer({ children }) {
|
|
2917
|
-
const edgeLabelRenderer = useStore(selector$
|
|
2892
|
+
const edgeLabelRenderer = useStore(selector$6);
|
|
2918
2893
|
if (!edgeLabelRenderer) {
|
|
2919
2894
|
return null;
|
|
2920
2895
|
}
|
|
2921
2896
|
return createPortal(children, edgeLabelRenderer);
|
|
2922
2897
|
}
|
|
2923
2898
|
|
|
2924
|
-
const selector$
|
|
2899
|
+
const selector$5 = (s) => s.domNode?.querySelector('.react-flow__viewport-portal');
|
|
2925
2900
|
function ViewportPortal({ children }) {
|
|
2926
|
-
const viewPortalDiv = useStore(selector$
|
|
2901
|
+
const viewPortalDiv = useStore(selector$5);
|
|
2927
2902
|
if (!viewPortalDiv) {
|
|
2928
2903
|
return null;
|
|
2929
2904
|
}
|
|
@@ -3056,7 +3031,7 @@ function useOnSelectionChange({ onChange }) {
|
|
|
3056
3031
|
}, [onChange]);
|
|
3057
3032
|
}
|
|
3058
3033
|
|
|
3059
|
-
const selector$
|
|
3034
|
+
const selector$4 = (options) => (s) => {
|
|
3060
3035
|
if (s.nodeLookup.size === 0) {
|
|
3061
3036
|
return false;
|
|
3062
3037
|
}
|
|
@@ -3080,7 +3055,7 @@ const defaultOptions = {
|
|
|
3080
3055
|
* @returns boolean indicating whether all nodes are initialized
|
|
3081
3056
|
*/
|
|
3082
3057
|
function useNodesInitialized(options = defaultOptions) {
|
|
3083
|
-
const initialized = useStore(selector$
|
|
3058
|
+
const initialized = useStore(selector$4(options));
|
|
3084
3059
|
return initialized;
|
|
3085
3060
|
}
|
|
3086
3061
|
|
|
@@ -3133,23 +3108,6 @@ function useNodesData(nodeIds) {
|
|
|
3133
3108
|
return nodesData;
|
|
3134
3109
|
}
|
|
3135
3110
|
|
|
3136
|
-
const selector$5 = (s) => ({
|
|
3137
|
-
startHandle: s.connectionStartHandle,
|
|
3138
|
-
endHandle: s.connectionEndHandle,
|
|
3139
|
-
status: s.connectionStatus,
|
|
3140
|
-
position: s.connectionStartHandle ? s.connectionPosition : null,
|
|
3141
|
-
});
|
|
3142
|
-
/**
|
|
3143
|
-
* Hook for accessing the ongoing connection.
|
|
3144
|
-
*
|
|
3145
|
-
* @public
|
|
3146
|
-
* @returns ongoing connection
|
|
3147
|
-
*/
|
|
3148
|
-
function useConnection() {
|
|
3149
|
-
const ongoingConnection = useStore(selector$5, shallow);
|
|
3150
|
-
return ongoingConnection;
|
|
3151
|
-
}
|
|
3152
|
-
|
|
3153
3111
|
/**
|
|
3154
3112
|
* Hook for getting an internal node by id
|
|
3155
3113
|
*
|
|
@@ -3181,14 +3139,14 @@ const defaultSize = {
|
|
|
3181
3139
|
[BackgroundVariant.Lines]: 1,
|
|
3182
3140
|
[BackgroundVariant.Cross]: 6,
|
|
3183
3141
|
};
|
|
3184
|
-
const selector$
|
|
3142
|
+
const selector$3 = (s) => ({ transform: s.transform, patternId: `pattern-${s.rfId}` });
|
|
3185
3143
|
function BackgroundComponent({ id, variant = BackgroundVariant.Dots,
|
|
3186
3144
|
// only used for dots and cross
|
|
3187
3145
|
gap = 20,
|
|
3188
3146
|
// only used for lines and cross
|
|
3189
3147
|
size, lineWidth = 1, offset = 2, color, bgColor, style, className, patternClassName, }) {
|
|
3190
3148
|
const ref = useRef(null);
|
|
3191
|
-
const { transform, patternId } = useStore(selector$
|
|
3149
|
+
const { transform, patternId } = useStore(selector$3, shallow);
|
|
3192
3150
|
const patternSize = size || defaultSize[variant];
|
|
3193
3151
|
const isDots = variant === BackgroundVariant.Dots;
|
|
3194
3152
|
const isCross = variant === BackgroundVariant.Cross;
|
|
@@ -3234,14 +3192,14 @@ function ControlButton({ children, className, ...rest }) {
|
|
|
3234
3192
|
return (jsx("button", { type: "button", className: cc(['react-flow__controls-button', className]), ...rest, children: children }));
|
|
3235
3193
|
}
|
|
3236
3194
|
|
|
3237
|
-
const selector$
|
|
3195
|
+
const selector$2 = (s) => ({
|
|
3238
3196
|
isInteractive: s.nodesDraggable || s.nodesConnectable || s.elementsSelectable,
|
|
3239
3197
|
minZoomReached: s.transform[2] <= s.minZoom,
|
|
3240
3198
|
maxZoomReached: s.transform[2] >= s.maxZoom,
|
|
3241
3199
|
});
|
|
3242
3200
|
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', }) {
|
|
3243
3201
|
const store = useStoreApi();
|
|
3244
|
-
const { isInteractive, minZoomReached, maxZoomReached } = useStore(selector$
|
|
3202
|
+
const { isInteractive, minZoomReached, maxZoomReached } = useStore(selector$2, shallow);
|
|
3245
3203
|
const { zoomIn, zoomOut, fitView } = useReactFlow();
|
|
3246
3204
|
const onZoomInHandler = () => {
|
|
3247
3205
|
zoomIn();
|
|
@@ -3280,7 +3238,6 @@ function MiniMapNodeComponent({ id, x, y, width, height, style, color, strokeCol
|
|
|
3280
3238
|
}
|
|
3281
3239
|
const MiniMapNode = memo(MiniMapNodeComponent);
|
|
3282
3240
|
|
|
3283
|
-
const selector$2 = (s) => s.nodeOrigin;
|
|
3284
3241
|
const selectorNodeIds = (s) => s.nodes.map((node) => node.id);
|
|
3285
3242
|
const getAttrFunction = (func) => func instanceof Function ? func : () => func;
|
|
3286
3243
|
function MiniMapNodes({ nodeStrokeColor, nodeColor, nodeClassName = '', nodeBorderRadius = 5, nodeStrokeWidth,
|
|
@@ -3288,7 +3245,6 @@ function MiniMapNodes({ nodeStrokeColor, nodeColor, nodeClassName = '', nodeBord
|
|
|
3288
3245
|
// a component properly.
|
|
3289
3246
|
nodeComponent: NodeComponent = MiniMapNode, onClick, }) {
|
|
3290
3247
|
const nodeIds = useStore(selectorNodeIds, shallow);
|
|
3291
|
-
const nodeOrigin = useStore(selector$2);
|
|
3292
3248
|
const nodeColorFunc = getAttrFunction(nodeColor);
|
|
3293
3249
|
const nodeStrokeColorFunc = getAttrFunction(nodeStrokeColor);
|
|
3294
3250
|
const nodeClassNameFunc = getAttrFunction(nodeClassName);
|
|
@@ -3299,12 +3255,12 @@ nodeComponent: NodeComponent = MiniMapNode, onClick, }) {
|
|
|
3299
3255
|
// minimize the cost of updates when individual nodes change.
|
|
3300
3256
|
//
|
|
3301
3257
|
// For more details, see a similar commit in `NodeRenderer/index.tsx`.
|
|
3302
|
-
jsx(NodeComponentWrapper, { id: nodeId,
|
|
3258
|
+
jsx(NodeComponentWrapper, { id: nodeId, nodeColorFunc: nodeColorFunc, nodeStrokeColorFunc: nodeStrokeColorFunc, nodeClassNameFunc: nodeClassNameFunc, nodeBorderRadius: nodeBorderRadius, nodeStrokeWidth: nodeStrokeWidth, NodeComponent: NodeComponent, onClick: onClick, shapeRendering: shapeRendering }, nodeId))) }));
|
|
3303
3259
|
}
|
|
3304
|
-
function NodeComponentWrapperInner({ id,
|
|
3260
|
+
function NodeComponentWrapperInner({ id, nodeColorFunc, nodeStrokeColorFunc, nodeClassNameFunc, nodeBorderRadius, nodeStrokeWidth, shapeRendering, NodeComponent, onClick, }) {
|
|
3305
3261
|
const { node, x, y } = useStore((s) => {
|
|
3306
3262
|
const node = s.nodeLookup.get(id);
|
|
3307
|
-
const { x, y } =
|
|
3263
|
+
const { x, y } = node.internals.positionAbsolute;
|
|
3308
3264
|
return {
|
|
3309
3265
|
node,
|
|
3310
3266
|
x,
|
|
@@ -3331,11 +3287,8 @@ const selector$1 = (s) => {
|
|
|
3331
3287
|
};
|
|
3332
3288
|
return {
|
|
3333
3289
|
viewBB,
|
|
3334
|
-
boundingRect: s.nodeLookup.size > 0
|
|
3335
|
-
? getBoundsOfRects(getInternalNodesBounds(s.nodeLookup, { nodeOrigin: s.nodeOrigin }), viewBB)
|
|
3336
|
-
: viewBB,
|
|
3290
|
+
boundingRect: s.nodeLookup.size > 0 ? getBoundsOfRects(getInternalNodesBounds(s.nodeLookup), viewBB) : viewBB,
|
|
3337
3291
|
rfId: s.rfId,
|
|
3338
|
-
nodeOrigin: s.nodeOrigin,
|
|
3339
3292
|
panZoom: s.panZoom,
|
|
3340
3293
|
translateExtent: s.translateExtent,
|
|
3341
3294
|
flowWidth: s.width,
|
|
@@ -3449,23 +3402,27 @@ function ResizeControl({ nodeId, position, variant = ResizeControlVariant.Handle
|
|
|
3449
3402
|
const nextPosition = { x: change.x, y: change.y };
|
|
3450
3403
|
const node = nodeLookup.get(id);
|
|
3451
3404
|
if (node && node.expandParent && node.parentId) {
|
|
3405
|
+
const origin = node.origin ?? nodeOrigin;
|
|
3406
|
+
const width = change.width ?? node.measured.width;
|
|
3407
|
+
const height = change.height ?? node.measured.height;
|
|
3452
3408
|
const child = {
|
|
3453
3409
|
id: node.id,
|
|
3454
3410
|
parentId: node.parentId,
|
|
3455
3411
|
rect: {
|
|
3456
|
-
width
|
|
3457
|
-
height
|
|
3412
|
+
width,
|
|
3413
|
+
height,
|
|
3458
3414
|
...evaluateAbsolutePosition({
|
|
3459
3415
|
x: change.x ?? node.position.x,
|
|
3460
3416
|
y: change.y ?? node.position.y,
|
|
3461
|
-
}, node.parentId, nodeLookup,
|
|
3417
|
+
}, { width, height }, node.parentId, nodeLookup, origin),
|
|
3462
3418
|
},
|
|
3463
3419
|
};
|
|
3464
3420
|
const parentExpandChanges = handleExpandParent([child], nodeLookup, parentLookup, nodeOrigin);
|
|
3465
3421
|
changes.push(...parentExpandChanges);
|
|
3466
|
-
// when the parent was expanded by the child node, its position will be clamped at
|
|
3467
|
-
|
|
3468
|
-
nextPosition.
|
|
3422
|
+
// when the parent was expanded by the child node, its position will be clamped at
|
|
3423
|
+
// 0,0 when node origin is 0,0 and to width, height if it's 1,1
|
|
3424
|
+
nextPosition.x = change.x ? Math.max(origin[0] * width, change.x) : undefined;
|
|
3425
|
+
nextPosition.y = change.y ? Math.max(origin[1] * height, change.y) : undefined;
|
|
3469
3426
|
}
|
|
3470
3427
|
if (nextPosition.x !== undefined && nextPosition.y !== undefined) {
|
|
3471
3428
|
const positionChange = {
|
|
@@ -3566,48 +3523,54 @@ const nodeEqualityFn = (a, b) => a?.internals.positionAbsolute.x !== b?.internal
|
|
|
3566
3523
|
a?.selected !== b?.selected ||
|
|
3567
3524
|
a?.internals.z !== b?.internals.z;
|
|
3568
3525
|
const nodesEqualityFn = (a, b) => {
|
|
3569
|
-
if (a.
|
|
3526
|
+
if (a.size !== b.size) {
|
|
3570
3527
|
return false;
|
|
3571
3528
|
}
|
|
3572
|
-
|
|
3529
|
+
for (const [key, node] of a) {
|
|
3530
|
+
if (nodeEqualityFn(node, b.get(key))) {
|
|
3531
|
+
return false;
|
|
3532
|
+
}
|
|
3533
|
+
}
|
|
3534
|
+
return true;
|
|
3573
3535
|
};
|
|
3574
3536
|
const storeSelector = (state) => ({
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
zoom: state.transform[2],
|
|
3579
|
-
},
|
|
3580
|
-
nodeOrigin: state.nodeOrigin,
|
|
3537
|
+
x: state.transform[0],
|
|
3538
|
+
y: state.transform[1],
|
|
3539
|
+
zoom: state.transform[2],
|
|
3581
3540
|
selectedNodesCount: state.nodes.filter((node) => node.selected).length,
|
|
3582
3541
|
});
|
|
3583
3542
|
function NodeToolbar({ nodeId, children, className, style, isVisible, position = Position.Top, offset = 10, align = 'center', ...rest }) {
|
|
3584
3543
|
const contextNodeId = useNodeId();
|
|
3585
3544
|
const nodesSelector = useCallback((state) => {
|
|
3586
3545
|
const nodeIds = Array.isArray(nodeId) ? nodeId : [nodeId || contextNodeId || ''];
|
|
3587
|
-
|
|
3546
|
+
const internalNodes = nodeIds.reduce((res, id) => {
|
|
3588
3547
|
const node = state.nodeLookup.get(id);
|
|
3589
3548
|
if (node) {
|
|
3590
|
-
|
|
3549
|
+
res.set(node.id, node);
|
|
3591
3550
|
}
|
|
3592
|
-
return
|
|
3593
|
-
},
|
|
3551
|
+
return res;
|
|
3552
|
+
}, new Map());
|
|
3553
|
+
return internalNodes;
|
|
3594
3554
|
}, [nodeId, contextNodeId]);
|
|
3595
3555
|
const nodes = useStore(nodesSelector, nodesEqualityFn);
|
|
3596
|
-
const {
|
|
3556
|
+
const { x, y, zoom, selectedNodesCount } = useStore(storeSelector, shallow);
|
|
3597
3557
|
// if isVisible is not set, we show the toolbar only if its node is selected and no other node is selected
|
|
3598
|
-
const isActive = typeof isVisible === 'boolean'
|
|
3599
|
-
|
|
3558
|
+
const isActive = typeof isVisible === 'boolean'
|
|
3559
|
+
? isVisible
|
|
3560
|
+
: nodes.size === 1 && nodes.values().next().value.selected && selectedNodesCount === 1;
|
|
3561
|
+
if (!isActive || !nodes.size) {
|
|
3600
3562
|
return null;
|
|
3601
3563
|
}
|
|
3602
|
-
const nodeRect =
|
|
3603
|
-
const
|
|
3564
|
+
const nodeRect = getInternalNodesBounds(nodes);
|
|
3565
|
+
const nodesArray = Array.from(nodes.values());
|
|
3566
|
+
const zIndex = Math.max(...nodesArray.map((node) => node.internals.z + 1));
|
|
3604
3567
|
const wrapperStyle = {
|
|
3605
3568
|
position: 'absolute',
|
|
3606
|
-
transform: getNodeToolbarTransform(nodeRect,
|
|
3569
|
+
transform: getNodeToolbarTransform(nodeRect, { x, y, zoom }, position, offset, align),
|
|
3607
3570
|
zIndex,
|
|
3608
3571
|
...style,
|
|
3609
3572
|
};
|
|
3610
|
-
return (jsx(NodeToolbarPortal, { children: jsx("div", { style: wrapperStyle, className: cc(['react-flow__node-toolbar', className]), ...rest, "data-id":
|
|
3573
|
+
return (jsx(NodeToolbarPortal, { children: jsx("div", { style: wrapperStyle, className: cc(['react-flow__node-toolbar', className]), ...rest, "data-id": nodesArray.reduce((acc, node) => `${acc}${node.id} `, '').trim(), children: children }) }));
|
|
3611
3574
|
}
|
|
3612
3575
|
|
|
3613
3576
|
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 };
|