) => {
return null;
}
- const nodeClasses = cc([
- 'react-flow__node',
- `react-flow__node-${type}`,
- noPanClassName,
- className,
- {
- selected,
- selectable: isSelectable,
- parent: isParent,
- },
- ]);
-
return (
;
export type UseDragData = { dx: number; dy: number };
@@ -76,30 +77,23 @@ function useDrag({
} else {
const dragHandler = drag()
.on('start', (event: UseDragEvent) => {
- const { nodeInternals, addSelectedNodes, unselectNodesAndEdges, multiSelectionActive } = store.getState();
+ const { nodeInternals, multiSelectionActive, unselectNodesAndEdges } = store.getState();
parentPos.current = getParentNodePosition(nodeInternals, nodeId);
- // this part is the regular drag handler for a single node
- // it selects the dragged node and deselects all other nodes if multiSelectionActive = false
- if (nodeId && isSelectable) {
- const node = nodeInternals.get(nodeId)!;
-
- if (selectNodesOnDrag) {
- store.setState({ nodesSelectionActive: false });
-
- if (!node.selected) {
- addSelectedNodes([nodeId]);
- }
- } else if (!selectNodesOnDrag && !node.selected) {
- if (multiSelectionActive) {
- addSelectedNodes([nodeId]);
- } else {
- unselectNodesAndEdges();
- store.setState({ nodesSelectionActive: false });
- }
+ if (!selectNodesOnDrag && !multiSelectionActive && nodeId) {
+ if (!nodeInternals.get(nodeId)?.selected) {
+ // we need to reset selected nodes when selectNodesOnDrag=false
+ unselectNodesAndEdges();
}
}
+ if (nodeId && isSelectable && selectNodesOnDrag) {
+ handleNodeClick({
+ id: nodeId,
+ store,
+ });
+ }
+
const mousePos = getMousePosition(event);
dragItems.current = getDragItems(nodeInternals, mousePos, nodeId);
diff --git a/src/store/index.ts b/src/store/index.ts
index 419ecbab..727a6515 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -14,6 +14,7 @@ import {
NodeSelectionChange,
NodePositionChange,
NodeDragItem,
+ UnselectNodesAndEdgesParams,
} from '../types';
import { getHandleBounds } from '../components/Nodes/utils';
import { createSelectionChange, getSelectionChanges } from '../utils/changes';
@@ -152,19 +153,22 @@ const createStore = () =>
set,
});
},
- unselectNodesAndEdges: () => {
- const { nodeInternals, edges } = get();
- const nodes = Array.from(nodeInternals.values());
+ unselectNodesAndEdges: ({ nodes, edges }: UnselectNodesAndEdgesParams = {}) => {
+ const { nodeInternals, edges: storeEdges } = get();
+ const nodesToUnselect = nodes ? nodes : Array.from(nodeInternals.values());
+ const edgesToUnselect = edges ? edges : storeEdges;
- const nodesToUnselect = nodes.map((n) => {
+ const changedNodes = nodesToUnselect.map((n) => {
n.selected = false;
return createSelectionChange(n.id, false);
}) as NodeSelectionChange[];
- const edgesToUnselect = edges.map((edge) => createSelectionChange(edge.id, false)) as EdgeSelectionChange[];
+ const changedEdges = edgesToUnselect.map((edge) =>
+ createSelectionChange(edge.id, false)
+ ) as EdgeSelectionChange[];
updateNodesAndEdgesSelections({
- changedNodes: nodesToUnselect,
- changedEdges: edgesToUnselect,
+ changedNodes,
+ changedEdges,
get,
set,
});
diff --git a/src/types/general.ts b/src/types/general.ts
index 978de52a..1a36991f 100644
--- a/src/types/general.ts
+++ b/src/types/general.ts
@@ -105,6 +105,11 @@ export type FitBoundsOptions = ViewportHelperFunctionOptions & {
padding?: number;
};
+export type UnselectNodesAndEdgesParams = {
+ nodes?: Node[];
+ edges?: Edge[];
+};
+
export interface ViewportHelperFunctions {
zoomIn: ZoomInOut;
zoomOut: ZoomInOut;
@@ -187,7 +192,7 @@ export type ReactFlowActions = {
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => void;
updateNodePositions: (nodeDragItems: NodeDragItem[]) => void;
resetSelectedElements: () => void;
- unselectNodesAndEdges: () => void;
+ unselectNodesAndEdges: (params?: UnselectNodesAndEdgesParams) => void;
addSelectedNodes: (nodeIds: string[]) => void;
addSelectedEdges: (edgeIds: string[]) => void;
setMinZoom: (minZoom: number) => void;
diff --git a/src/types/nodes.ts b/src/types/nodes.ts
index 6c416ef5..7a5db412 100644
--- a/src/types/nodes.ts
+++ b/src/types/nodes.ts
@@ -71,9 +71,9 @@ export interface WrapNodeProps {
onMouseMove?: NodeMouseHandler;
onMouseLeave?: NodeMouseHandler;
onContextMenu?: NodeMouseHandler;
- onNodeDragStart?: NodeDragHandler;
- onNodeDrag?: NodeDragHandler;
- onNodeDragStop?: NodeDragHandler;
+ onDragStart?: NodeDragHandler;
+ onDrag?: NodeDragHandler;
+ onDragStop?: NodeDragHandler;
style?: CSSProperties;
className?: string;
sourcePosition: Position;
diff --git a/src/utils/changes.ts b/src/utils/changes.ts
index 9279a3f0..2e6a1cf0 100644
--- a/src/utils/changes.ts
+++ b/src/utils/changes.ts
@@ -45,8 +45,7 @@ function handleParentExpand(res: any[], updateItem: any) {
}
function applyChanges(changes: any[], elements: any[]): any[] {
- // unfortunately we need this hack to handle the setNodes and setEdges function of the
- // useReactFlow hook.
+ // we need this hack to handle the setNodes and setEdges function of the useReactFlow hook for controlled flows
if (changes.some((c) => c.type === 'reset')) {
return changes.filter((c) => c.type === 'reset').map((c) => c.item);
}