@xyflow/react 12.0.0-next.24 → 12.0.0-next.25
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/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 +197 -237
- package/dist/esm/index.mjs +197 -237
- 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/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 +4 -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/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/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 +4 -7
- package/dist/umd/types/store.d.ts.map +1 -1
- package/package.json +3 -3
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);
|
|
@@ -186,7 +186,7 @@ const reactFlowFieldsToTrack = [
|
|
|
186
186
|
];
|
|
187
187
|
// rfId doesn't exist in ReactFlowProps, but it's one of the fields we want to update
|
|
188
188
|
const fieldsToTrack = [...reactFlowFieldsToTrack, 'rfId'];
|
|
189
|
-
const selector$
|
|
189
|
+
const selector$m = (s) => ({
|
|
190
190
|
setNodes: s.setNodes,
|
|
191
191
|
setEdges: s.setEdges,
|
|
192
192
|
setMinZoom: s.setMinZoom,
|
|
@@ -209,7 +209,7 @@ const initPrevValues = {
|
|
|
209
209
|
rfId: '1',
|
|
210
210
|
};
|
|
211
211
|
function StoreUpdater(props) {
|
|
212
|
-
const { setNodes, setEdges, setMinZoom, setMaxZoom, setTranslateExtent, setNodeExtent, reset, setDefaultNodesAndEdges, } = useStore(selector$
|
|
212
|
+
const { setNodes, setEdges, setMinZoom, setMaxZoom, setTranslateExtent, setNodeExtent, reset, setDefaultNodesAndEdges, } = useStore(selector$m, shallow);
|
|
213
213
|
const store = useStoreApi();
|
|
214
214
|
useEffect(() => {
|
|
215
215
|
setDefaultNodesAndEdges(props.defaultNodes, props.defaultEdges);
|
|
@@ -419,18 +419,18 @@ const useViewportHelper = () => {
|
|
|
419
419
|
return { x, y, zoom };
|
|
420
420
|
},
|
|
421
421
|
fitView: (options) => {
|
|
422
|
-
const { nodeLookup, width, height,
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
422
|
+
const { nodeLookup, width, height, minZoom, maxZoom, panZoom } = store.getState();
|
|
423
|
+
if (!panZoom) {
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
return fitView({
|
|
427
|
+
nodeLookup,
|
|
428
|
+
width,
|
|
429
|
+
height,
|
|
430
|
+
minZoom,
|
|
431
|
+
maxZoom,
|
|
432
|
+
panZoom,
|
|
433
|
+
}, options);
|
|
434
434
|
},
|
|
435
435
|
setCenter: (x, y, options) => {
|
|
436
436
|
const { width, height, maxZoom, panZoom } = store.getState();
|
|
@@ -800,7 +800,7 @@ function useBatchContext() {
|
|
|
800
800
|
return batchContext;
|
|
801
801
|
}
|
|
802
802
|
|
|
803
|
-
const selector$
|
|
803
|
+
const selector$l = (s) => !!s.panZoom;
|
|
804
804
|
/**
|
|
805
805
|
* Hook for accessing the ReactFlow instance.
|
|
806
806
|
*
|
|
@@ -811,7 +811,7 @@ function useReactFlow() {
|
|
|
811
811
|
const viewportHelper = useViewportHelper();
|
|
812
812
|
const store = useStoreApi();
|
|
813
813
|
const batchContext = useBatchContext();
|
|
814
|
-
const viewportInitialized = useStore(selector$
|
|
814
|
+
const viewportInitialized = useStore(selector$l);
|
|
815
815
|
const generalHelper = useMemo(() => {
|
|
816
816
|
const getInternalNode = (id) => store.getState().nodeLookup.get(id);
|
|
817
817
|
const setNodes = (payload) => {
|
|
@@ -824,7 +824,7 @@ function useReactFlow() {
|
|
|
824
824
|
const { nodeLookup, nodeOrigin } = store.getState();
|
|
825
825
|
const nodeToUse = isNode(node) ? node : nodeLookup.get(node.id);
|
|
826
826
|
const position = nodeToUse.parentId
|
|
827
|
-
? evaluateAbsolutePosition(nodeToUse.position, nodeToUse.parentId, nodeLookup, nodeOrigin)
|
|
827
|
+
? evaluateAbsolutePosition(nodeToUse.position, nodeToUse.measured, nodeToUse.parentId, nodeLookup, nodeOrigin)
|
|
828
828
|
: nodeToUse.position;
|
|
829
829
|
const nodeWithPosition = {
|
|
830
830
|
id: nodeToUse.id,
|
|
@@ -1030,14 +1030,14 @@ const containerStyle = {
|
|
|
1030
1030
|
left: 0,
|
|
1031
1031
|
};
|
|
1032
1032
|
|
|
1033
|
-
const selector$
|
|
1033
|
+
const selector$k = (s) => ({
|
|
1034
1034
|
userSelectionActive: s.userSelectionActive,
|
|
1035
1035
|
lib: s.lib,
|
|
1036
1036
|
});
|
|
1037
1037
|
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
1038
|
const store = useStoreApi();
|
|
1039
1039
|
const zoomPane = useRef(null);
|
|
1040
|
-
const { userSelectionActive, lib } = useStore(selector$
|
|
1040
|
+
const { userSelectionActive, lib } = useStore(selector$k, shallow);
|
|
1041
1041
|
const zoomActivationKeyPressed = useKeyPress(zoomActivationKeyCode);
|
|
1042
1042
|
const panZoom = useRef();
|
|
1043
1043
|
useResizeHandler(zoomPane);
|
|
@@ -1119,12 +1119,12 @@ function ZoomPane({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true,
|
|
|
1119
1119
|
return (jsx("div", { className: "react-flow__renderer", ref: zoomPane, style: containerStyle, children: children }));
|
|
1120
1120
|
}
|
|
1121
1121
|
|
|
1122
|
-
const selector$
|
|
1122
|
+
const selector$j = (s) => ({
|
|
1123
1123
|
userSelectionActive: s.userSelectionActive,
|
|
1124
1124
|
userSelectionRect: s.userSelectionRect,
|
|
1125
1125
|
});
|
|
1126
1126
|
function UserSelection() {
|
|
1127
|
-
const { userSelectionActive, userSelectionRect } = useStore(selector$
|
|
1127
|
+
const { userSelectionActive, userSelectionRect } = useStore(selector$j, shallow);
|
|
1128
1128
|
const isActive = userSelectionActive && userSelectionRect;
|
|
1129
1129
|
if (!isActive) {
|
|
1130
1130
|
return null;
|
|
@@ -1144,7 +1144,7 @@ const wrapHandler = (handler, containerRef) => {
|
|
|
1144
1144
|
handler?.(event);
|
|
1145
1145
|
};
|
|
1146
1146
|
};
|
|
1147
|
-
const selector$
|
|
1147
|
+
const selector$i = (s) => ({
|
|
1148
1148
|
userSelectionActive: s.userSelectionActive,
|
|
1149
1149
|
elementsSelectable: s.elementsSelectable,
|
|
1150
1150
|
dragging: s.paneDragging,
|
|
@@ -1156,7 +1156,7 @@ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.
|
|
|
1156
1156
|
const prevSelectedEdgesCount = useRef(0);
|
|
1157
1157
|
const containerBounds = useRef();
|
|
1158
1158
|
const edgeIdLookup = useRef(new Map());
|
|
1159
|
-
const { userSelectionActive, elementsSelectable, dragging } = useStore(selector$
|
|
1159
|
+
const { userSelectionActive, elementsSelectable, dragging } = useStore(selector$i, shallow);
|
|
1160
1160
|
const hasActiveSelection = elementsSelectable && (isSelecting || userSelectionActive);
|
|
1161
1161
|
// Used to prevent click events when the user lets go of the selectionKey during a selection
|
|
1162
1162
|
const selectionInProgress = useRef(false);
|
|
@@ -1214,7 +1214,7 @@ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.
|
|
|
1214
1214
|
onSelectionStart?.(event);
|
|
1215
1215
|
};
|
|
1216
1216
|
const onPointerMove = (event) => {
|
|
1217
|
-
const { userSelectionRect, edgeLookup, transform,
|
|
1217
|
+
const { userSelectionRect, edgeLookup, transform, nodeLookup, triggerNodeChanges, triggerEdgeChanges } = store.getState();
|
|
1218
1218
|
if (!containerBounds.current || !userSelectionRect) {
|
|
1219
1219
|
return;
|
|
1220
1220
|
}
|
|
@@ -1229,7 +1229,7 @@ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.
|
|
|
1229
1229
|
width: Math.abs(mouseX - startX),
|
|
1230
1230
|
height: Math.abs(mouseY - startY),
|
|
1231
1231
|
};
|
|
1232
|
-
const selectedNodes = getNodesInside(nodeLookup, nextUserSelectRect, transform, selectionMode === SelectionMode.Partial, true
|
|
1232
|
+
const selectedNodes = getNodesInside(nodeLookup, nextUserSelectRect, transform, selectionMode === SelectionMode.Partial, true);
|
|
1233
1233
|
const selectedEdgeIds = new Set();
|
|
1234
1234
|
const selectedNodeIds = new Set();
|
|
1235
1235
|
for (const selectedNode of selectedNodes) {
|
|
@@ -1403,23 +1403,24 @@ const useNodeId = () => {
|
|
|
1403
1403
|
return nodeId;
|
|
1404
1404
|
};
|
|
1405
1405
|
|
|
1406
|
-
const selector$
|
|
1406
|
+
const selector$h = (s) => ({
|
|
1407
1407
|
connectOnClick: s.connectOnClick,
|
|
1408
1408
|
noPanClassName: s.noPanClassName,
|
|
1409
1409
|
rfId: s.rfId,
|
|
1410
1410
|
});
|
|
1411
1411
|
const connectingSelector = (nodeId, handleId, type) => (state) => {
|
|
1412
|
-
const {
|
|
1413
|
-
const
|
|
1412
|
+
const { connectionClickStartHandle: clickHandle, connectionMode, connection } = state;
|
|
1413
|
+
const { fromHandle, toHandle, isValid } = connection;
|
|
1414
|
+
const connectingTo = toHandle?.nodeId === nodeId && toHandle?.id === handleId && toHandle?.type === type;
|
|
1414
1415
|
return {
|
|
1415
|
-
connectingFrom:
|
|
1416
|
+
connectingFrom: fromHandle?.nodeId === nodeId && fromHandle?.id === handleId && fromHandle?.type === type,
|
|
1416
1417
|
connectingTo,
|
|
1417
|
-
clickConnecting: clickHandle?.nodeId === nodeId && clickHandle?.
|
|
1418
|
+
clickConnecting: clickHandle?.nodeId === nodeId && clickHandle?.id === handleId && clickHandle?.type === type,
|
|
1418
1419
|
isPossibleEndHandle: connectionMode === ConnectionMode.Strict
|
|
1419
|
-
?
|
|
1420
|
-
: nodeId !==
|
|
1421
|
-
connectionInProcess: !!
|
|
1422
|
-
valid: connectingTo &&
|
|
1420
|
+
? fromHandle?.type !== type
|
|
1421
|
+
: nodeId !== fromHandle?.nodeId || handleId !== fromHandle?.id,
|
|
1422
|
+
connectionInProcess: !!fromHandle,
|
|
1423
|
+
valid: connectingTo && isValid,
|
|
1423
1424
|
};
|
|
1424
1425
|
};
|
|
1425
1426
|
function HandleComponent({ type = 'source', position = Position.Top, isValidConnection, isConnectable = true, isConnectableStart = true, isConnectableEnd = true, id, onConnect, children, className, onMouseDown, onTouchStart, ...rest }, ref) {
|
|
@@ -1427,7 +1428,7 @@ function HandleComponent({ type = 'source', position = Position.Top, isValidConn
|
|
|
1427
1428
|
const isTarget = type === 'target';
|
|
1428
1429
|
const store = useStoreApi();
|
|
1429
1430
|
const nodeId = useNodeId();
|
|
1430
|
-
const { connectOnClick, noPanClassName, rfId } = useStore(selector$
|
|
1431
|
+
const { connectOnClick, noPanClassName, rfId } = useStore(selector$h, shallow);
|
|
1431
1432
|
const { connectingFrom, connectingTo, clickConnecting, isPossibleEndHandle, connectionInProcess, valid } = useStore(connectingSelector(nodeId, handleId, type), shallow);
|
|
1432
1433
|
if (!nodeId) {
|
|
1433
1434
|
store.getState().onError?.('010', errorMessages['error010']());
|
|
@@ -1472,7 +1473,7 @@ function HandleComponent({ type = 'source', position = Position.Top, isValidConn
|
|
|
1472
1473
|
onConnect: onConnectExtended,
|
|
1473
1474
|
isValidConnection: isValidConnection || currentStore.isValidConnection,
|
|
1474
1475
|
getTransform: () => store.getState().transform,
|
|
1475
|
-
|
|
1476
|
+
getFromHandle: () => store.getState().connection.fromHandle,
|
|
1476
1477
|
});
|
|
1477
1478
|
}
|
|
1478
1479
|
if (isMouseTriggered) {
|
|
@@ -1489,7 +1490,7 @@ function HandleComponent({ type = 'source', position = Position.Top, isValidConn
|
|
|
1489
1490
|
}
|
|
1490
1491
|
if (!connectionClickStartHandle) {
|
|
1491
1492
|
onClickConnectStart?.(event.nativeEvent, { nodeId, handleId, handleType: type });
|
|
1492
|
-
store.setState({ connectionClickStartHandle: { nodeId, type, handleId } });
|
|
1493
|
+
store.setState({ connectionClickStartHandle: { nodeId, type, id: handleId } });
|
|
1493
1494
|
return;
|
|
1494
1495
|
}
|
|
1495
1496
|
const doc = getHostForElement(event.target);
|
|
@@ -1502,7 +1503,7 @@ function HandleComponent({ type = 'source', position = Position.Top, isValidConn
|
|
|
1502
1503
|
},
|
|
1503
1504
|
connectionMode,
|
|
1504
1505
|
fromNodeId: connectionClickStartHandle.nodeId,
|
|
1505
|
-
fromHandleId: connectionClickStartHandle.
|
|
1506
|
+
fromHandleId: connectionClickStartHandle.id || null,
|
|
1506
1507
|
fromType: connectionClickStartHandle.type,
|
|
1507
1508
|
isValidConnection: isValidConnectionHandler,
|
|
1508
1509
|
flowId,
|
|
@@ -1585,9 +1586,8 @@ function getNodeInlineStyleDimensions(node) {
|
|
|
1585
1586
|
};
|
|
1586
1587
|
}
|
|
1587
1588
|
|
|
1588
|
-
const selector$
|
|
1589
|
+
const selector$g = (s) => {
|
|
1589
1590
|
const { width, height, x, y } = getInternalNodesBounds(s.nodeLookup, {
|
|
1590
|
-
nodeOrigin: s.nodeOrigin,
|
|
1591
1591
|
filter: (node) => !!node.selected,
|
|
1592
1592
|
});
|
|
1593
1593
|
return {
|
|
@@ -1599,7 +1599,7 @@ const selector$h = (s) => {
|
|
|
1599
1599
|
};
|
|
1600
1600
|
function NodesSelection({ onSelectionContextMenu, noPanClassName, disableKeyboardA11y, }) {
|
|
1601
1601
|
const store = useStoreApi();
|
|
1602
|
-
const { width, height, transformString, userSelectionActive } = useStore(selector$
|
|
1602
|
+
const { width, height, transformString, userSelectionActive } = useStore(selector$g, shallow);
|
|
1603
1603
|
const moveSelectedNodes = useMoveSelectedNodes();
|
|
1604
1604
|
const nodeRef = useRef(null);
|
|
1605
1605
|
useEffect(() => {
|
|
@@ -1638,11 +1638,11 @@ function NodesSelection({ onSelectionContextMenu, noPanClassName, disableKeyboar
|
|
|
1638
1638
|
}
|
|
1639
1639
|
|
|
1640
1640
|
const win = typeof window !== 'undefined' ? window : undefined;
|
|
1641
|
-
const selector$
|
|
1641
|
+
const selector$f = (s) => {
|
|
1642
1642
|
return { nodesSelectionActive: s.nodesSelectionActive, userSelectionActive: s.userSelectionActive };
|
|
1643
1643
|
};
|
|
1644
1644
|
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$
|
|
1645
|
+
const { nodesSelectionActive, userSelectionActive } = useStore(selector$f);
|
|
1646
1646
|
const selectionKeyPressed = useKeyPress(selectionKeyCode, { target: win });
|
|
1647
1647
|
const panActivationKeyPressed = useKeyPress(panActivationKeyCode, { target: win });
|
|
1648
1648
|
const panOnDrag = panActivationKeyPressed || _panOnDrag;
|
|
@@ -1654,7 +1654,7 @@ function FlowRendererComponent({ children, onPaneClick, onPaneMouseEnter, onPane
|
|
|
1654
1654
|
FlowRendererComponent.displayName = 'FlowRenderer';
|
|
1655
1655
|
const FlowRenderer = memo(FlowRendererComponent);
|
|
1656
1656
|
|
|
1657
|
-
const selector$
|
|
1657
|
+
const selector$e = (onlyRenderVisible) => (s) => {
|
|
1658
1658
|
return onlyRenderVisible
|
|
1659
1659
|
? getNodesInside(s.nodeLookup, { x: 0, y: 0, width: s.width, height: s.height }, s.transform, true).map((node) => node.id)
|
|
1660
1660
|
: Array.from(s.nodeLookup.keys());
|
|
@@ -1667,13 +1667,13 @@ const selector$f = (onlyRenderVisible) => (s) => {
|
|
|
1667
1667
|
* @returns array with visible node ids
|
|
1668
1668
|
*/
|
|
1669
1669
|
function useVisibleNodeIds(onlyRenderVisible) {
|
|
1670
|
-
const nodeIds = useStore(useCallback(selector$
|
|
1670
|
+
const nodeIds = useStore(useCallback(selector$e(onlyRenderVisible), [onlyRenderVisible]), shallow);
|
|
1671
1671
|
return nodeIds;
|
|
1672
1672
|
}
|
|
1673
1673
|
|
|
1674
|
-
const selector$
|
|
1674
|
+
const selector$d = (s) => s.updateNodeInternals;
|
|
1675
1675
|
function useResizeObserver() {
|
|
1676
|
-
const updateNodeInternals = useStore(selector$
|
|
1676
|
+
const updateNodeInternals = useStore(selector$d);
|
|
1677
1677
|
const [resizeObserver] = useState(() => {
|
|
1678
1678
|
if (typeof ResizeObserver === 'undefined') {
|
|
1679
1679
|
return null;
|
|
@@ -1750,7 +1750,7 @@ function useNodeObserver({ node, nodeType, hasDimensions, resizeObserver, }) {
|
|
|
1750
1750
|
return nodeRef;
|
|
1751
1751
|
}
|
|
1752
1752
|
|
|
1753
|
-
function NodeWrapper({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onContextMenu, onDoubleClick, nodesDraggable, elementsSelectable, nodesConnectable, nodesFocusable, resizeObserver, noDragClassName, noPanClassName, disableKeyboardA11y, rfId, nodeTypes, nodeExtent,
|
|
1753
|
+
function NodeWrapper({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onContextMenu, onDoubleClick, nodesDraggable, elementsSelectable, nodesConnectable, nodesFocusable, resizeObserver, noDragClassName, noPanClassName, disableKeyboardA11y, rfId, nodeTypes, nodeExtent, onError, }) {
|
|
1754
1754
|
const { node, internals, isParent } = useStore((s) => {
|
|
1755
1755
|
const node = s.nodeLookup.get(id);
|
|
1756
1756
|
const isParent = s.parentLookup.has(id);
|
|
@@ -1788,14 +1788,10 @@ function NodeWrapper({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onC
|
|
|
1788
1788
|
}
|
|
1789
1789
|
const nodeDimensions = getNodeDimensions(node);
|
|
1790
1790
|
const inlineDimensions = getNodeInlineStyleDimensions(node);
|
|
1791
|
+
// TODO: clamping should happen earlier
|
|
1791
1792
|
const clampedPosition = nodeExtent
|
|
1792
1793
|
? clampPosition(internals.positionAbsolute, nodeExtent)
|
|
1793
1794
|
: internals.positionAbsolute;
|
|
1794
|
-
const positionWithOrigin = getPositionWithOrigin({
|
|
1795
|
-
...clampedPosition,
|
|
1796
|
-
...nodeDimensions,
|
|
1797
|
-
origin: node.origin || nodeOrigin,
|
|
1798
|
-
});
|
|
1799
1795
|
const hasPointerEvents = isSelectable || isDraggable || onClick || onMouseEnter || onMouseMove || onMouseLeave;
|
|
1800
1796
|
const onMouseEnterHandler = onMouseEnter
|
|
1801
1797
|
? (event) => onMouseEnter(event, { ...internals.userNode })
|
|
@@ -1869,7 +1865,7 @@ function NodeWrapper({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onC
|
|
|
1869
1865
|
},
|
|
1870
1866
|
]), ref: nodeRef, style: {
|
|
1871
1867
|
zIndex: internals.z,
|
|
1872
|
-
transform: `translate(${
|
|
1868
|
+
transform: `translate(${clampedPosition.x}px,${clampedPosition.y}px)`,
|
|
1873
1869
|
pointerEvents: hasPointerEvents ? 'all' : 'none',
|
|
1874
1870
|
visibility: hasDimensions ? 'visible' : 'hidden',
|
|
1875
1871
|
...node.style,
|
|
@@ -1877,7 +1873,7 @@ function NodeWrapper({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onC
|
|
|
1877
1873
|
}, "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
1874
|
}
|
|
1879
1875
|
|
|
1880
|
-
const selector$
|
|
1876
|
+
const selector$c = (s) => ({
|
|
1881
1877
|
nodesDraggable: s.nodesDraggable,
|
|
1882
1878
|
nodesConnectable: s.nodesConnectable,
|
|
1883
1879
|
nodesFocusable: s.nodesFocusable,
|
|
@@ -1885,7 +1881,7 @@ const selector$d = (s) => ({
|
|
|
1885
1881
|
onError: s.onError,
|
|
1886
1882
|
});
|
|
1887
1883
|
function NodeRendererComponent(props) {
|
|
1888
|
-
const { nodesDraggable, nodesConnectable, nodesFocusable, elementsSelectable, onError } = useStore(selector$
|
|
1884
|
+
const { nodesDraggable, nodesConnectable, nodesFocusable, elementsSelectable, onError } = useStore(selector$c, shallow);
|
|
1889
1885
|
const nodeIds = useVisibleNodeIds(props.onlyRenderVisibleElements);
|
|
1890
1886
|
const resizeObserver = useResizeObserver();
|
|
1891
1887
|
return (jsx("div", { className: "react-flow__nodes", style: containerStyle, children: nodeIds.map((nodeId) => {
|
|
@@ -1913,7 +1909,7 @@ function NodeRendererComponent(props) {
|
|
|
1913
1909
|
// moved into `NodeComponentWrapper`. This ensures they are
|
|
1914
1910
|
// memorized – so if `NodeRenderer` *has* to rerender, it only
|
|
1915
1911
|
// needs to regenerate the list of nodes, nothing else.
|
|
1916
|
-
jsx(NodeWrapper, { id: nodeId, nodeTypes: props.nodeTypes, nodeExtent: props.nodeExtent,
|
|
1912
|
+
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
1913
|
}) }));
|
|
1918
1914
|
}
|
|
1919
1915
|
NodeRendererComponent.displayName = 'NodeRenderer';
|
|
@@ -2243,7 +2239,7 @@ function EdgeUpdateAnchors({ isReconnectable, reconnectRadius, edge, targetHandl
|
|
|
2243
2239
|
onReconnectEnd: _onReconnectEnd,
|
|
2244
2240
|
updateConnection,
|
|
2245
2241
|
getTransform: () => store.getState().transform,
|
|
2246
|
-
|
|
2242
|
+
getFromHandle: () => store.getState().connection.fromHandle,
|
|
2247
2243
|
});
|
|
2248
2244
|
};
|
|
2249
2245
|
const onReconnectSourceMouseDown = (event) => handleEdgeUpdater(event, true);
|
|
@@ -2376,7 +2372,7 @@ function EdgeWrapper({ id, edgesFocusable, edgesReconnectable, elementsSelectabl
|
|
|
2376
2372
|
]), 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
2373
|
}
|
|
2378
2374
|
|
|
2379
|
-
const selector$
|
|
2375
|
+
const selector$b = (s) => ({
|
|
2380
2376
|
width: s.width,
|
|
2381
2377
|
height: s.height,
|
|
2382
2378
|
edgesFocusable: s.edgesFocusable,
|
|
@@ -2386,7 +2382,7 @@ const selector$c = (s) => ({
|
|
|
2386
2382
|
onError: s.onError,
|
|
2387
2383
|
});
|
|
2388
2384
|
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$
|
|
2385
|
+
const { edgesFocusable, edgesReconnectable, elementsSelectable, onError } = useStore(selector$b, shallow);
|
|
2390
2386
|
const edgeIds = useVisibleEdgeIds(onlyRenderVisibleElements);
|
|
2391
2387
|
return (jsxs("div", { className: "react-flow__edges", children: [jsx(MarkerDefinitions$1, { defaultColor: defaultMarkerColor, rfId: rfId }), edgeIds.map((id) => {
|
|
2392
2388
|
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 +2391,9 @@ function EdgeRendererComponent({ defaultMarkerColor, onlyRenderVisibleElements,
|
|
|
2395
2391
|
EdgeRendererComponent.displayName = 'EdgeRenderer';
|
|
2396
2392
|
const EdgeRenderer = memo(EdgeRendererComponent);
|
|
2397
2393
|
|
|
2398
|
-
const selector$
|
|
2394
|
+
const selector$a = (s) => `translate(${s.transform[0]}px,${s.transform[1]}px) scale(${s.transform[2]})`;
|
|
2399
2395
|
function Viewport({ children }) {
|
|
2400
|
-
const transform = useStore(selector$
|
|
2396
|
+
const transform = useStore(selector$a);
|
|
2401
2397
|
return (jsx("div", { className: "react-flow__viewport xyflow__viewport react-flow__container", style: { transform }, children: children }));
|
|
2402
2398
|
}
|
|
2403
2399
|
|
|
@@ -2417,7 +2413,7 @@ function useOnInitHandler(onInit) {
|
|
|
2417
2413
|
}, [onInit, rfInstance.viewportInitialized]);
|
|
2418
2414
|
}
|
|
2419
2415
|
|
|
2420
|
-
const selector$
|
|
2416
|
+
const selector$9 = (state) => state.panZoom?.syncViewport;
|
|
2421
2417
|
/**
|
|
2422
2418
|
* Hook for syncing the viewport with the panzoom instance.
|
|
2423
2419
|
*
|
|
@@ -2425,7 +2421,7 @@ const selector$a = (state) => state.panZoom?.syncViewport;
|
|
|
2425
2421
|
* @param viewport
|
|
2426
2422
|
*/
|
|
2427
2423
|
function useViewportSync(viewport) {
|
|
2428
|
-
const syncViewport = useStore(selector$
|
|
2424
|
+
const syncViewport = useStore(selector$9);
|
|
2429
2425
|
const store = useStoreApi();
|
|
2430
2426
|
useEffect(() => {
|
|
2431
2427
|
if (viewport) {
|
|
@@ -2436,90 +2432,75 @@ function useViewportSync(viewport) {
|
|
|
2436
2432
|
return null;
|
|
2437
2433
|
}
|
|
2438
2434
|
|
|
2439
|
-
const
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
[Position.Bottom]: Position.Top,
|
|
2435
|
+
const selector$8 = (s) => {
|
|
2436
|
+
return s.connection.inProgress
|
|
2437
|
+
? { ...s.connection, to: pointToRendererPoint(s.connection.to, s.transform) }
|
|
2438
|
+
: { ...s.connection };
|
|
2444
2439
|
};
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2440
|
+
/**
|
|
2441
|
+
* Hook for accessing the connection state.
|
|
2442
|
+
*
|
|
2443
|
+
* @public
|
|
2444
|
+
* @returns ConnectionState
|
|
2445
|
+
*/
|
|
2446
|
+
function useConnection() {
|
|
2447
|
+
return useStore(selector$8, shallow);
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
const selector$7 = (s) => ({
|
|
2451
|
+
nodesConnectable: s.nodesConnectable,
|
|
2452
|
+
isValid: s.connection.isValid,
|
|
2453
|
+
inProgress: s.connection.inProgress,
|
|
2454
|
+
width: s.width,
|
|
2455
|
+
height: s.height,
|
|
2456
|
+
});
|
|
2457
|
+
function ConnectionLineWrapper({ containerStyle, style, type, component }) {
|
|
2458
|
+
const { nodesConnectable, width, height, isValid, inProgress } = useStore(selector$7, shallow);
|
|
2459
|
+
const renderConnection = !!(width && nodesConnectable && inProgress);
|
|
2460
|
+
if (!renderConnection) {
|
|
2461
2461
|
return null;
|
|
2462
2462
|
}
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
const
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
const toPosition = isValid && endPosition ? endPosition : fromPosition ? oppositePosition[fromPosition] : null;
|
|
2470
|
-
if (!fromPosition || !toPosition) {
|
|
2471
|
-
return null;
|
|
2463
|
+
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 }) }) }));
|
|
2464
|
+
}
|
|
2465
|
+
const ConnectionLine = ({ style, type = ConnectionLineType.Bezier, CustomComponent, isValid }) => {
|
|
2466
|
+
const { inProgress, from, fromNode, fromHandle, fromPosition, to, toNode, toHandle, toPosition } = useConnection();
|
|
2467
|
+
if (!inProgress) {
|
|
2468
|
+
return;
|
|
2472
2469
|
}
|
|
2473
2470
|
if (CustomComponent) {
|
|
2474
|
-
return (jsx(CustomComponent, { connectionLineType: type, connectionLineStyle: style, fromNode: fromNode, fromHandle: fromHandle, fromX:
|
|
2471
|
+
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
2472
|
}
|
|
2476
|
-
let
|
|
2473
|
+
let path = '';
|
|
2477
2474
|
const pathParams = {
|
|
2478
|
-
sourceX:
|
|
2479
|
-
sourceY:
|
|
2475
|
+
sourceX: from.x,
|
|
2476
|
+
sourceY: from.y,
|
|
2480
2477
|
sourcePosition: fromPosition,
|
|
2481
|
-
targetX:
|
|
2482
|
-
targetY:
|
|
2478
|
+
targetX: to.x,
|
|
2479
|
+
targetY: to.y,
|
|
2483
2480
|
targetPosition: toPosition,
|
|
2484
2481
|
};
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2482
|
+
switch (type) {
|
|
2483
|
+
case ConnectionLineType.Bezier:
|
|
2484
|
+
[path] = getBezierPath(pathParams);
|
|
2485
|
+
break;
|
|
2486
|
+
case ConnectionLineType.SimpleBezier:
|
|
2487
|
+
[path] = getSimpleBezierPath(pathParams);
|
|
2488
|
+
break;
|
|
2489
|
+
case ConnectionLineType.Step:
|
|
2490
|
+
[path] = getSmoothStepPath({
|
|
2491
|
+
...pathParams,
|
|
2492
|
+
borderRadius: 0,
|
|
2493
|
+
});
|
|
2494
|
+
break;
|
|
2495
|
+
case ConnectionLineType.SmoothStep:
|
|
2496
|
+
[path] = getSmoothStepPath(pathParams);
|
|
2497
|
+
break;
|
|
2498
|
+
default:
|
|
2499
|
+
[path] = getStraightPath(pathParams);
|
|
2503
2500
|
}
|
|
2504
|
-
return jsx("path", { d:
|
|
2501
|
+
return jsx("path", { d: path, fill: "none", className: "react-flow__connection-path", style: style });
|
|
2505
2502
|
};
|
|
2506
2503
|
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
2504
|
|
|
2524
2505
|
const emptyTypes = {};
|
|
2525
2506
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -2556,34 +2537,33 @@ function useStylesLoadedWarning() {
|
|
|
2556
2537
|
}, []);
|
|
2557
2538
|
}
|
|
2558
2539
|
|
|
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,
|
|
2540
|
+
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
2541
|
useNodeOrEdgeTypesWarning(nodeTypes);
|
|
2561
2542
|
useNodeOrEdgeTypesWarning(edgeTypes);
|
|
2562
2543
|
useStylesLoadedWarning();
|
|
2563
2544
|
useOnInitHandler(onInit);
|
|
2564
2545
|
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,
|
|
2546
|
+
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
2547
|
}
|
|
2567
2548
|
GraphViewComponent.displayName = 'GraphView';
|
|
2568
2549
|
const GraphView = memo(GraphViewComponent);
|
|
2569
2550
|
|
|
2570
|
-
const getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, height, fitView, } = {}) => {
|
|
2551
|
+
const getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, height, fitView, nodeOrigin, } = {}) => {
|
|
2571
2552
|
const nodeLookup = new Map();
|
|
2572
2553
|
const parentLookup = new Map();
|
|
2573
2554
|
const connectionLookup = new Map();
|
|
2574
2555
|
const edgeLookup = new Map();
|
|
2575
2556
|
const storeEdges = defaultEdges ?? edges ?? [];
|
|
2576
2557
|
const storeNodes = defaultNodes ?? nodes ?? [];
|
|
2558
|
+
const storeNodeOrigin = nodeOrigin ?? [0, 0];
|
|
2577
2559
|
updateConnectionLookup(connectionLookup, edgeLookup, storeEdges);
|
|
2578
2560
|
adoptUserNodes(storeNodes, nodeLookup, parentLookup, {
|
|
2579
|
-
nodeOrigin:
|
|
2561
|
+
nodeOrigin: storeNodeOrigin,
|
|
2580
2562
|
elevateNodesOnSelect: false,
|
|
2581
2563
|
});
|
|
2582
2564
|
let transform = [0, 0, 1];
|
|
2583
2565
|
if (fitView && width && height) {
|
|
2584
|
-
// @todo users nodeOrigin should be used here
|
|
2585
2566
|
const bounds = getInternalNodesBounds(nodeLookup, {
|
|
2586
|
-
nodeOrigin: [0, 0],
|
|
2587
2567
|
filter: (node) => !!((node.width || node.initialWidth) && (node.height || node.initialHeight)),
|
|
2588
2568
|
});
|
|
2589
2569
|
const { x, y, zoom } = getViewportForBounds(bounds, width, height, 0.5, 2, 0.1);
|
|
@@ -2612,13 +2592,11 @@ const getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, heig
|
|
|
2612
2592
|
nodesSelectionActive: false,
|
|
2613
2593
|
userSelectionActive: false,
|
|
2614
2594
|
userSelectionRect: null,
|
|
2615
|
-
connectionPosition: { x: 0, y: 0 },
|
|
2616
|
-
connectionStatus: null,
|
|
2617
2595
|
connectionMode: ConnectionMode.Strict,
|
|
2618
2596
|
domNode: null,
|
|
2619
2597
|
paneDragging: false,
|
|
2620
2598
|
noPanClassName: 'nopan',
|
|
2621
|
-
nodeOrigin:
|
|
2599
|
+
nodeOrigin: storeNodeOrigin,
|
|
2622
2600
|
nodeDragThreshold: 1,
|
|
2623
2601
|
snapGrid: [15, 15],
|
|
2624
2602
|
snapToGrid: false,
|
|
@@ -2635,8 +2613,7 @@ const getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, heig
|
|
|
2635
2613
|
fitViewOnInitOptions: undefined,
|
|
2636
2614
|
selectNodesOnDrag: true,
|
|
2637
2615
|
multiSelectionActive: false,
|
|
2638
|
-
|
|
2639
|
-
connectionEndHandle: null,
|
|
2616
|
+
connection: { ...initialConnection },
|
|
2640
2617
|
connectionClickStartHandle: null,
|
|
2641
2618
|
connectOnClick: true,
|
|
2642
2619
|
ariaLiveMessage: '',
|
|
@@ -2651,8 +2628,8 @@ const getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, heig
|
|
|
2651
2628
|
};
|
|
2652
2629
|
};
|
|
2653
2630
|
|
|
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 }),
|
|
2631
|
+
const createStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height, fitView: fitView$1, nodeOrigin, }) => createWithEqualityFn((set, get) => ({
|
|
2632
|
+
...getInitialState({ nodes, edges, width, height, fitView: fitView$1, nodeOrigin, defaultNodes, defaultEdges }),
|
|
2656
2633
|
setNodes: (nodes) => {
|
|
2657
2634
|
const { nodeLookup, parentLookup, nodeOrigin, elevateNodesOnSelect } = get();
|
|
2658
2635
|
// setNodes() is called exclusively in response to user actions:
|
|
@@ -2690,7 +2667,7 @@ const createStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height,
|
|
|
2690
2667
|
if (!updatedInternals) {
|
|
2691
2668
|
return;
|
|
2692
2669
|
}
|
|
2693
|
-
updateAbsolutePositions(nodeLookup, { nodeOrigin });
|
|
2670
|
+
updateAbsolutePositions(nodeLookup, parentLookup, { nodeOrigin });
|
|
2694
2671
|
// we call fitView once initially after all dimensions are set
|
|
2695
2672
|
let nextFitViewDone = fitViewDone;
|
|
2696
2673
|
if (!fitViewDone && fitViewOnInit) {
|
|
@@ -2739,8 +2716,8 @@ const createStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height,
|
|
|
2739
2716
|
changes.push(change);
|
|
2740
2717
|
}
|
|
2741
2718
|
if (parentExpandChildren.length > 0) {
|
|
2742
|
-
const { nodeLookup, parentLookup } = get();
|
|
2743
|
-
const parentExpandChanges = handleExpandParent(parentExpandChildren, nodeLookup, parentLookup);
|
|
2719
|
+
const { nodeLookup, parentLookup, nodeOrigin } = get();
|
|
2720
|
+
const parentExpandChanges = handleExpandParent(parentExpandChildren, nodeLookup, parentLookup, nodeOrigin);
|
|
2744
2721
|
changes.push(...parentExpandChanges);
|
|
2745
2722
|
}
|
|
2746
2723
|
get().triggerNodeChanges(changes);
|
|
@@ -2845,7 +2822,7 @@ const createStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height,
|
|
|
2845
2822
|
return panBy({ delta, panZoom, transform, translateExtent, width, height });
|
|
2846
2823
|
},
|
|
2847
2824
|
fitView: (options) => {
|
|
2848
|
-
const { panZoom, width, height, minZoom, maxZoom,
|
|
2825
|
+
const { panZoom, width, height, minZoom, maxZoom, nodeLookup } = get();
|
|
2849
2826
|
if (!panZoom) {
|
|
2850
2827
|
return false;
|
|
2851
2828
|
}
|
|
@@ -2856,26 +2833,20 @@ const createStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height,
|
|
|
2856
2833
|
panZoom,
|
|
2857
2834
|
minZoom,
|
|
2858
2835
|
maxZoom,
|
|
2859
|
-
nodeOrigin,
|
|
2860
2836
|
}, options);
|
|
2861
2837
|
},
|
|
2862
|
-
cancelConnection: () =>
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
}
|
|
2867
|
-
updateConnection: (
|
|
2868
|
-
|
|
2869
|
-
const currentConnection = {
|
|
2870
|
-
...params,
|
|
2871
|
-
connectionPosition: params.connectionPosition ?? connectionPosition,
|
|
2872
|
-
};
|
|
2873
|
-
set(currentConnection);
|
|
2838
|
+
cancelConnection: () => {
|
|
2839
|
+
set({
|
|
2840
|
+
connection: { ...initialConnection },
|
|
2841
|
+
});
|
|
2842
|
+
},
|
|
2843
|
+
updateConnection: (connection) => {
|
|
2844
|
+
set({ connection });
|
|
2874
2845
|
},
|
|
2875
2846
|
reset: () => set({ ...getInitialState() }),
|
|
2876
2847
|
}), Object.is);
|
|
2877
2848
|
|
|
2878
|
-
function ReactFlowProvider({ initialNodes: nodes, initialEdges: edges, defaultNodes, defaultEdges, initialWidth: width, initialHeight: height, fitView, children, }) {
|
|
2849
|
+
function ReactFlowProvider({ initialNodes: nodes, initialEdges: edges, defaultNodes, defaultEdges, initialWidth: width, initialHeight: height, fitView, nodeOrigin, children, }) {
|
|
2879
2850
|
const [store] = useState(() => createStore({
|
|
2880
2851
|
nodes,
|
|
2881
2852
|
edges,
|
|
@@ -2884,18 +2855,19 @@ function ReactFlowProvider({ initialNodes: nodes, initialEdges: edges, defaultNo
|
|
|
2884
2855
|
width,
|
|
2885
2856
|
height,
|
|
2886
2857
|
fitView,
|
|
2858
|
+
nodeOrigin,
|
|
2887
2859
|
}));
|
|
2888
2860
|
return (jsx(Provider$1, { value: store, children: jsx(BatchProvider, { children: children }) }));
|
|
2889
2861
|
}
|
|
2890
2862
|
|
|
2891
|
-
function Wrapper({ children, nodes, edges, defaultNodes, defaultEdges, width, height, fitView, }) {
|
|
2863
|
+
function Wrapper({ children, nodes, edges, defaultNodes, defaultEdges, width, height, fitView, nodeOrigin, }) {
|
|
2892
2864
|
const isWrapped = useContext(StoreContext);
|
|
2893
2865
|
if (isWrapped) {
|
|
2894
2866
|
// we need to wrap it with a fragment because it's not allowed for children to be a ReactNode
|
|
2895
2867
|
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18051
|
|
2896
2868
|
return jsx(Fragment, { children: children });
|
|
2897
2869
|
}
|
|
2898
|
-
return (jsx(ReactFlowProvider, { initialNodes: nodes, initialEdges: edges, defaultNodes: defaultNodes, defaultEdges: defaultEdges, initialWidth: width, initialHeight: height, fitView: fitView, children: children }));
|
|
2870
|
+
return (jsx(ReactFlowProvider, { initialNodes: nodes, initialEdges: edges, defaultNodes: defaultNodes, defaultEdges: defaultEdges, initialWidth: width, initialHeight: height, fitView: fitView, nodeOrigin: nodeOrigin, children: children }));
|
|
2899
2871
|
}
|
|
2900
2872
|
|
|
2901
2873
|
const wrapperStyle = {
|
|
@@ -2908,22 +2880,22 @@ const wrapperStyle = {
|
|
|
2908
2880
|
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) {
|
|
2909
2881
|
const rfId = id || '1';
|
|
2910
2882
|
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,
|
|
2883
|
+
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, 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
2884
|
}
|
|
2913
2885
|
var index = fixedForwardRef(ReactFlow);
|
|
2914
2886
|
|
|
2915
|
-
const selector$
|
|
2887
|
+
const selector$6 = (s) => s.domNode?.querySelector('.react-flow__edgelabel-renderer');
|
|
2916
2888
|
function EdgeLabelRenderer({ children }) {
|
|
2917
|
-
const edgeLabelRenderer = useStore(selector$
|
|
2889
|
+
const edgeLabelRenderer = useStore(selector$6);
|
|
2918
2890
|
if (!edgeLabelRenderer) {
|
|
2919
2891
|
return null;
|
|
2920
2892
|
}
|
|
2921
2893
|
return createPortal(children, edgeLabelRenderer);
|
|
2922
2894
|
}
|
|
2923
2895
|
|
|
2924
|
-
const selector$
|
|
2896
|
+
const selector$5 = (s) => s.domNode?.querySelector('.react-flow__viewport-portal');
|
|
2925
2897
|
function ViewportPortal({ children }) {
|
|
2926
|
-
const viewPortalDiv = useStore(selector$
|
|
2898
|
+
const viewPortalDiv = useStore(selector$5);
|
|
2927
2899
|
if (!viewPortalDiv) {
|
|
2928
2900
|
return null;
|
|
2929
2901
|
}
|
|
@@ -3056,7 +3028,7 @@ function useOnSelectionChange({ onChange }) {
|
|
|
3056
3028
|
}, [onChange]);
|
|
3057
3029
|
}
|
|
3058
3030
|
|
|
3059
|
-
const selector$
|
|
3031
|
+
const selector$4 = (options) => (s) => {
|
|
3060
3032
|
if (s.nodeLookup.size === 0) {
|
|
3061
3033
|
return false;
|
|
3062
3034
|
}
|
|
@@ -3080,7 +3052,7 @@ const defaultOptions = {
|
|
|
3080
3052
|
* @returns boolean indicating whether all nodes are initialized
|
|
3081
3053
|
*/
|
|
3082
3054
|
function useNodesInitialized(options = defaultOptions) {
|
|
3083
|
-
const initialized = useStore(selector$
|
|
3055
|
+
const initialized = useStore(selector$4(options));
|
|
3084
3056
|
return initialized;
|
|
3085
3057
|
}
|
|
3086
3058
|
|
|
@@ -3133,23 +3105,6 @@ function useNodesData(nodeIds) {
|
|
|
3133
3105
|
return nodesData;
|
|
3134
3106
|
}
|
|
3135
3107
|
|
|
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
3108
|
/**
|
|
3154
3109
|
* Hook for getting an internal node by id
|
|
3155
3110
|
*
|
|
@@ -3181,14 +3136,14 @@ const defaultSize = {
|
|
|
3181
3136
|
[BackgroundVariant.Lines]: 1,
|
|
3182
3137
|
[BackgroundVariant.Cross]: 6,
|
|
3183
3138
|
};
|
|
3184
|
-
const selector$
|
|
3139
|
+
const selector$3 = (s) => ({ transform: s.transform, patternId: `pattern-${s.rfId}` });
|
|
3185
3140
|
function BackgroundComponent({ id, variant = BackgroundVariant.Dots,
|
|
3186
3141
|
// only used for dots and cross
|
|
3187
3142
|
gap = 20,
|
|
3188
3143
|
// only used for lines and cross
|
|
3189
3144
|
size, lineWidth = 1, offset = 2, color, bgColor, style, className, patternClassName, }) {
|
|
3190
3145
|
const ref = useRef(null);
|
|
3191
|
-
const { transform, patternId } = useStore(selector$
|
|
3146
|
+
const { transform, patternId } = useStore(selector$3, shallow);
|
|
3192
3147
|
const patternSize = size || defaultSize[variant];
|
|
3193
3148
|
const isDots = variant === BackgroundVariant.Dots;
|
|
3194
3149
|
const isCross = variant === BackgroundVariant.Cross;
|
|
@@ -3234,14 +3189,14 @@ function ControlButton({ children, className, ...rest }) {
|
|
|
3234
3189
|
return (jsx("button", { type: "button", className: cc(['react-flow__controls-button', className]), ...rest, children: children }));
|
|
3235
3190
|
}
|
|
3236
3191
|
|
|
3237
|
-
const selector$
|
|
3192
|
+
const selector$2 = (s) => ({
|
|
3238
3193
|
isInteractive: s.nodesDraggable || s.nodesConnectable || s.elementsSelectable,
|
|
3239
3194
|
minZoomReached: s.transform[2] <= s.minZoom,
|
|
3240
3195
|
maxZoomReached: s.transform[2] >= s.maxZoom,
|
|
3241
3196
|
});
|
|
3242
3197
|
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
3198
|
const store = useStoreApi();
|
|
3244
|
-
const { isInteractive, minZoomReached, maxZoomReached } = useStore(selector$
|
|
3199
|
+
const { isInteractive, minZoomReached, maxZoomReached } = useStore(selector$2, shallow);
|
|
3245
3200
|
const { zoomIn, zoomOut, fitView } = useReactFlow();
|
|
3246
3201
|
const onZoomInHandler = () => {
|
|
3247
3202
|
zoomIn();
|
|
@@ -3280,7 +3235,6 @@ function MiniMapNodeComponent({ id, x, y, width, height, style, color, strokeCol
|
|
|
3280
3235
|
}
|
|
3281
3236
|
const MiniMapNode = memo(MiniMapNodeComponent);
|
|
3282
3237
|
|
|
3283
|
-
const selector$2 = (s) => s.nodeOrigin;
|
|
3284
3238
|
const selectorNodeIds = (s) => s.nodes.map((node) => node.id);
|
|
3285
3239
|
const getAttrFunction = (func) => func instanceof Function ? func : () => func;
|
|
3286
3240
|
function MiniMapNodes({ nodeStrokeColor, nodeColor, nodeClassName = '', nodeBorderRadius = 5, nodeStrokeWidth,
|
|
@@ -3288,7 +3242,6 @@ function MiniMapNodes({ nodeStrokeColor, nodeColor, nodeClassName = '', nodeBord
|
|
|
3288
3242
|
// a component properly.
|
|
3289
3243
|
nodeComponent: NodeComponent = MiniMapNode, onClick, }) {
|
|
3290
3244
|
const nodeIds = useStore(selectorNodeIds, shallow);
|
|
3291
|
-
const nodeOrigin = useStore(selector$2);
|
|
3292
3245
|
const nodeColorFunc = getAttrFunction(nodeColor);
|
|
3293
3246
|
const nodeStrokeColorFunc = getAttrFunction(nodeStrokeColor);
|
|
3294
3247
|
const nodeClassNameFunc = getAttrFunction(nodeClassName);
|
|
@@ -3299,12 +3252,12 @@ nodeComponent: NodeComponent = MiniMapNode, onClick, }) {
|
|
|
3299
3252
|
// minimize the cost of updates when individual nodes change.
|
|
3300
3253
|
//
|
|
3301
3254
|
// For more details, see a similar commit in `NodeRenderer/index.tsx`.
|
|
3302
|
-
jsx(NodeComponentWrapper, { id: nodeId,
|
|
3255
|
+
jsx(NodeComponentWrapper, { id: nodeId, nodeColorFunc: nodeColorFunc, nodeStrokeColorFunc: nodeStrokeColorFunc, nodeClassNameFunc: nodeClassNameFunc, nodeBorderRadius: nodeBorderRadius, nodeStrokeWidth: nodeStrokeWidth, NodeComponent: NodeComponent, onClick: onClick, shapeRendering: shapeRendering }, nodeId))) }));
|
|
3303
3256
|
}
|
|
3304
|
-
function NodeComponentWrapperInner({ id,
|
|
3257
|
+
function NodeComponentWrapperInner({ id, nodeColorFunc, nodeStrokeColorFunc, nodeClassNameFunc, nodeBorderRadius, nodeStrokeWidth, shapeRendering, NodeComponent, onClick, }) {
|
|
3305
3258
|
const { node, x, y } = useStore((s) => {
|
|
3306
3259
|
const node = s.nodeLookup.get(id);
|
|
3307
|
-
const { x, y } =
|
|
3260
|
+
const { x, y } = node.internals.positionAbsolute;
|
|
3308
3261
|
return {
|
|
3309
3262
|
node,
|
|
3310
3263
|
x,
|
|
@@ -3331,11 +3284,8 @@ const selector$1 = (s) => {
|
|
|
3331
3284
|
};
|
|
3332
3285
|
return {
|
|
3333
3286
|
viewBB,
|
|
3334
|
-
boundingRect: s.nodeLookup.size > 0
|
|
3335
|
-
? getBoundsOfRects(getInternalNodesBounds(s.nodeLookup, { nodeOrigin: s.nodeOrigin }), viewBB)
|
|
3336
|
-
: viewBB,
|
|
3287
|
+
boundingRect: s.nodeLookup.size > 0 ? getBoundsOfRects(getInternalNodesBounds(s.nodeLookup), viewBB) : viewBB,
|
|
3337
3288
|
rfId: s.rfId,
|
|
3338
|
-
nodeOrigin: s.nodeOrigin,
|
|
3339
3289
|
panZoom: s.panZoom,
|
|
3340
3290
|
translateExtent: s.translateExtent,
|
|
3341
3291
|
flowWidth: s.width,
|
|
@@ -3449,23 +3399,27 @@ function ResizeControl({ nodeId, position, variant = ResizeControlVariant.Handle
|
|
|
3449
3399
|
const nextPosition = { x: change.x, y: change.y };
|
|
3450
3400
|
const node = nodeLookup.get(id);
|
|
3451
3401
|
if (node && node.expandParent && node.parentId) {
|
|
3402
|
+
const origin = node.origin ?? nodeOrigin;
|
|
3403
|
+
const width = change.width ?? node.measured.width;
|
|
3404
|
+
const height = change.height ?? node.measured.height;
|
|
3452
3405
|
const child = {
|
|
3453
3406
|
id: node.id,
|
|
3454
3407
|
parentId: node.parentId,
|
|
3455
3408
|
rect: {
|
|
3456
|
-
width
|
|
3457
|
-
height
|
|
3409
|
+
width,
|
|
3410
|
+
height,
|
|
3458
3411
|
...evaluateAbsolutePosition({
|
|
3459
3412
|
x: change.x ?? node.position.x,
|
|
3460
3413
|
y: change.y ?? node.position.y,
|
|
3461
|
-
}, node.parentId, nodeLookup,
|
|
3414
|
+
}, { width, height }, node.parentId, nodeLookup, origin),
|
|
3462
3415
|
},
|
|
3463
3416
|
};
|
|
3464
3417
|
const parentExpandChanges = handleExpandParent([child], nodeLookup, parentLookup, nodeOrigin);
|
|
3465
3418
|
changes.push(...parentExpandChanges);
|
|
3466
|
-
// when the parent was expanded by the child node, its position will be clamped at
|
|
3467
|
-
|
|
3468
|
-
nextPosition.
|
|
3419
|
+
// when the parent was expanded by the child node, its position will be clamped at
|
|
3420
|
+
// 0,0 when node origin is 0,0 and to width, height if it's 1,1
|
|
3421
|
+
nextPosition.x = change.x ? Math.max(origin[0] * width, change.x) : undefined;
|
|
3422
|
+
nextPosition.y = change.y ? Math.max(origin[1] * height, change.y) : undefined;
|
|
3469
3423
|
}
|
|
3470
3424
|
if (nextPosition.x !== undefined && nextPosition.y !== undefined) {
|
|
3471
3425
|
const positionChange = {
|
|
@@ -3566,48 +3520,54 @@ const nodeEqualityFn = (a, b) => a?.internals.positionAbsolute.x !== b?.internal
|
|
|
3566
3520
|
a?.selected !== b?.selected ||
|
|
3567
3521
|
a?.internals.z !== b?.internals.z;
|
|
3568
3522
|
const nodesEqualityFn = (a, b) => {
|
|
3569
|
-
if (a.
|
|
3523
|
+
if (a.size !== b.size) {
|
|
3570
3524
|
return false;
|
|
3571
3525
|
}
|
|
3572
|
-
|
|
3526
|
+
for (const [key, node] of a) {
|
|
3527
|
+
if (nodeEqualityFn(node, b.get(key))) {
|
|
3528
|
+
return false;
|
|
3529
|
+
}
|
|
3530
|
+
}
|
|
3531
|
+
return true;
|
|
3573
3532
|
};
|
|
3574
3533
|
const storeSelector = (state) => ({
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
zoom: state.transform[2],
|
|
3579
|
-
},
|
|
3580
|
-
nodeOrigin: state.nodeOrigin,
|
|
3534
|
+
x: state.transform[0],
|
|
3535
|
+
y: state.transform[1],
|
|
3536
|
+
zoom: state.transform[2],
|
|
3581
3537
|
selectedNodesCount: state.nodes.filter((node) => node.selected).length,
|
|
3582
3538
|
});
|
|
3583
3539
|
function NodeToolbar({ nodeId, children, className, style, isVisible, position = Position.Top, offset = 10, align = 'center', ...rest }) {
|
|
3584
3540
|
const contextNodeId = useNodeId();
|
|
3585
3541
|
const nodesSelector = useCallback((state) => {
|
|
3586
3542
|
const nodeIds = Array.isArray(nodeId) ? nodeId : [nodeId || contextNodeId || ''];
|
|
3587
|
-
|
|
3543
|
+
const internalNodes = nodeIds.reduce((res, id) => {
|
|
3588
3544
|
const node = state.nodeLookup.get(id);
|
|
3589
3545
|
if (node) {
|
|
3590
|
-
|
|
3546
|
+
res.set(node.id, node);
|
|
3591
3547
|
}
|
|
3592
|
-
return
|
|
3593
|
-
},
|
|
3548
|
+
return res;
|
|
3549
|
+
}, new Map());
|
|
3550
|
+
return internalNodes;
|
|
3594
3551
|
}, [nodeId, contextNodeId]);
|
|
3595
3552
|
const nodes = useStore(nodesSelector, nodesEqualityFn);
|
|
3596
|
-
const {
|
|
3553
|
+
const { x, y, zoom, selectedNodesCount } = useStore(storeSelector, shallow);
|
|
3597
3554
|
// 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
|
-
|
|
3555
|
+
const isActive = typeof isVisible === 'boolean'
|
|
3556
|
+
? isVisible
|
|
3557
|
+
: nodes.size === 1 && nodes.values().next().value.selected && selectedNodesCount === 1;
|
|
3558
|
+
if (!isActive || !nodes.size) {
|
|
3600
3559
|
return null;
|
|
3601
3560
|
}
|
|
3602
|
-
const nodeRect =
|
|
3603
|
-
const
|
|
3561
|
+
const nodeRect = getInternalNodesBounds(nodes);
|
|
3562
|
+
const nodesArray = Array.from(nodes.values());
|
|
3563
|
+
const zIndex = Math.max(...nodesArray.map((node) => node.internals.z + 1));
|
|
3604
3564
|
const wrapperStyle = {
|
|
3605
3565
|
position: 'absolute',
|
|
3606
|
-
transform: getNodeToolbarTransform(nodeRect,
|
|
3566
|
+
transform: getNodeToolbarTransform(nodeRect, { x, y, zoom }, position, offset, align),
|
|
3607
3567
|
zIndex,
|
|
3608
3568
|
...style,
|
|
3609
3569
|
};
|
|
3610
|
-
return (jsx(NodeToolbarPortal, { children: jsx("div", { style: wrapperStyle, className: cc(['react-flow__node-toolbar', className]), ...rest, "data-id":
|
|
3570
|
+
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
3571
|
}
|
|
3612
3572
|
|
|
3613
3573
|
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 };
|