refactor(actions): addSelectedElements => addSelectedNodes, addSelectedEdges
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
import ReactFlow, { Node, Edge, applyNodeChanges, NodeChange } from 'react-flow-renderer';
|
||||
import { useEffect, useState } from 'react';
|
||||
import ReactFlow, { Node, Edge, useNodesState, useEdgesState } from 'react-flow-renderer';
|
||||
|
||||
import './updatenode.css';
|
||||
|
||||
@@ -11,8 +11,8 @@ const initialNodes: Node[] = [
|
||||
const initialEdges: Edge[] = [{ id: 'e1-2', source: '1', target: '2' }];
|
||||
|
||||
const UpdateNode = () => {
|
||||
const [nodes, setNodes] = useState<Node[]>(initialNodes);
|
||||
const [edges, setEdges] = useState<Edge[]>(initialEdges);
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||
|
||||
const [nodeName, setNodeName] = useState<string>('Node 1');
|
||||
const [nodeBg, setNodeBg] = useState<string>('#eee');
|
||||
@@ -60,12 +60,16 @@ const UpdateNode = () => {
|
||||
);
|
||||
}, [nodeHidden]);
|
||||
|
||||
const onNodesChange = useCallback((changes: NodeChange[]) => {
|
||||
setNodes((ns) => applyNodeChanges(changes, ns));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ReactFlow nodes={nodes} edges={edges} defaultZoom={1.5} minZoom={0.2} maxZoom={4} onNodesChange={onNodesChange}>
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
defaultZoom={1.5}
|
||||
minZoom={0.2}
|
||||
maxZoom={4}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
>
|
||||
<div className="updatenode__controls">
|
||||
<label>label:</label>
|
||||
<input value={nodeName} onChange={(evt) => setNodeName(evt.target.value)} />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// These components are not used by React Flow directly
|
||||
// but the user can add them as children of a React Flow component
|
||||
// They can be added as children of a React Flow component
|
||||
|
||||
export { default as MiniMap } from './MiniMap';
|
||||
export { default as Controls, ControlButton } from './Controls';
|
||||
|
||||
@@ -9,7 +9,7 @@ import { EdgeAnchor } from './EdgeAnchor';
|
||||
import { getMarkerId } from '../../utils/graph';
|
||||
|
||||
const selector = (s: ReactFlowState) => ({
|
||||
addSelectedElements: s.addSelectedElements,
|
||||
addSelectedEdges: s.addSelectedEdges,
|
||||
setConnectionNodeId: s.setConnectionNodeId,
|
||||
unsetNodesSelection: s.unsetNodesSelection,
|
||||
setPosition: s.setConnectionPosition,
|
||||
@@ -57,7 +57,7 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
markerStart,
|
||||
}: WrapEdgeProps): JSX.Element | null => {
|
||||
const store = useStoreApi();
|
||||
const { addSelectedElements, setConnectionNodeId, unsetNodesSelection, setPosition, connectionMode } = useStore(
|
||||
const { addSelectedEdges, setConnectionNodeId, unsetNodesSelection, setPosition, connectionMode } = useStore(
|
||||
selector,
|
||||
shallow
|
||||
);
|
||||
@@ -100,7 +100,7 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
(event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
||||
if (elementsSelectable) {
|
||||
unsetNodesSelection();
|
||||
addSelectedElements([edgeElement]);
|
||||
addSelectedEdges([edgeElement.id]);
|
||||
}
|
||||
|
||||
onClick?.(event, edgeElement);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Provider } from '../../contexts/NodeIdContext';
|
||||
import { NodeProps, WrapNodeProps, ReactFlowState } from '../../types';
|
||||
|
||||
const selector = (s: ReactFlowState) => ({
|
||||
addSelectedElements: s.addSelectedElements,
|
||||
addSelectedNodes: s.addSelectedNodes,
|
||||
unsetNodesSelection: s.unsetNodesSelection,
|
||||
updateNodePosition: s.updateNodePosition,
|
||||
updateNodeDimensions: s.updateNodeDimensions,
|
||||
@@ -54,7 +54,7 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
|
||||
noDragClassName,
|
||||
}: WrapNodeProps) => {
|
||||
const {
|
||||
addSelectedElements,
|
||||
addSelectedNodes,
|
||||
unselectNodesAndEdges,
|
||||
unsetNodesSelection,
|
||||
updateNodePosition,
|
||||
@@ -130,7 +130,7 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
|
||||
unsetNodesSelection();
|
||||
|
||||
if (!selected) {
|
||||
addSelectedElements([node]);
|
||||
addSelectedNodes([node.id]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
|
||||
unsetNodesSelection();
|
||||
|
||||
if (!selected) {
|
||||
addSelectedElements([node]);
|
||||
addSelectedNodes([node.id]);
|
||||
}
|
||||
} else if (!selectNodesOnDrag && !selected && isSelectable) {
|
||||
unselectNodesAndEdges();
|
||||
@@ -178,7 +178,7 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
|
||||
// Because of that we set dragging to true inside the onDrag handler and handle the click here
|
||||
if (!dragging) {
|
||||
if (isSelectable && !selectNodesOnDrag && !selected) {
|
||||
addSelectedElements([node]);
|
||||
addSelectedNodes([node.id]);
|
||||
}
|
||||
|
||||
onClick?.(event as MouseEvent, node);
|
||||
|
||||
@@ -88,13 +88,7 @@ const EdgeRenderer = (props: EdgeRendererProps) => {
|
||||
const [sourceNodeRect, sourceHandleBounds, sourceIsValid] = getNodeData(nodeInternals, edge.source);
|
||||
const [targetNodeRect, targetHandleBounds, targetIsValid] = getNodeData(nodeInternals, edge.target);
|
||||
|
||||
if (!sourceIsValid) {
|
||||
console.warn(`couldn't create edge for source id: ${edge.source}; edge id: ${edge.id}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!targetIsValid) {
|
||||
console.warn(`couldn't create edge for target id: ${edge.target}; edge id: ${edge.id}`);
|
||||
if (!sourceIsValid || !targetIsValid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { ReactFlowState } from '../types';
|
||||
|
||||
const updateSizeSelector = (state: ReactFlowState) => state.updateSize;
|
||||
|
||||
function useResizeHandler(rendererNode: MutableRefObject<HTMLDivElement | null>) {
|
||||
function useResizeHandler(rendererNode: MutableRefObject<HTMLDivElement | null>): void {
|
||||
const updateSize = useStore(updateSizeSelector);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
+18
-10
@@ -27,7 +27,7 @@ import {
|
||||
XYPosition,
|
||||
ReactFlowStore,
|
||||
} from '../types';
|
||||
import { isNode, isEdge, getRectOfNodes, getNodesInside, getConnectedEdges } from '../utils/graph';
|
||||
import { getRectOfNodes, getNodesInside, getConnectedEdges } from '../utils/graph';
|
||||
import { getHandleBounds } from '../components/Nodes/utils';
|
||||
import { createNodeInternals, createNodeOrEdgeSelectionChange } from './utils';
|
||||
|
||||
@@ -249,28 +249,36 @@ const createStore = () =>
|
||||
|
||||
set(stateUpdate);
|
||||
},
|
||||
addSelectedElements: (selectedElementsArr: Array<Node | Edge>) => {
|
||||
const { multiSelectionActive, onNodesChange, onEdgesChange, nodeInternals, edges } = get();
|
||||
addSelectedNodes: (selectedNodeIds: string[]) => {
|
||||
const { multiSelectionActive, onNodesChange, nodeInternals } = get();
|
||||
// @TODO: work with nodeInternals instead of converting it to an array
|
||||
const nodes = Array.from(nodeInternals).map(([_, node]) => node);
|
||||
let changedNodes;
|
||||
let changedEdges;
|
||||
|
||||
if (multiSelectionActive) {
|
||||
changedNodes = selectedElementsArr.filter(isNode).map(createNodeOrEdgeSelectionChange(true));
|
||||
changedEdges = selectedElementsArr.filter(isEdge).map(createNodeOrEdgeSelectionChange(true));
|
||||
changedNodes = selectedNodeIds.map(createNodeOrEdgeSelectionChange(true));
|
||||
} else {
|
||||
changedNodes = nodes.map((node) =>
|
||||
createNodeOrEdgeSelectionChange(selectedElementsArr.some((e) => e.id === node.id))(node)
|
||||
);
|
||||
changedEdges = edges.map((edge) =>
|
||||
createNodeOrEdgeSelectionChange(selectedElementsArr.some((e) => e.id === edge.id))(edge)
|
||||
createNodeOrEdgeSelectionChange(selectedNodeIds.some((nodeId) => nodeId === node.id))(node.id)
|
||||
);
|
||||
}
|
||||
|
||||
if (changedNodes.length) {
|
||||
onNodesChange?.(changedNodes as NodeChange[]);
|
||||
}
|
||||
},
|
||||
addSelectedEdges: (selectedEdgeIds: string[]) => {
|
||||
const { multiSelectionActive, onEdgesChange, edges } = get();
|
||||
|
||||
let changedEdges;
|
||||
|
||||
if (multiSelectionActive) {
|
||||
changedEdges = selectedEdgeIds.map(createNodeOrEdgeSelectionChange(true));
|
||||
} else {
|
||||
changedEdges = edges.map((edge) =>
|
||||
createNodeOrEdgeSelectionChange(selectedEdgeIds.some((edgeId) => edgeId === edge.id))(edge.id)
|
||||
);
|
||||
}
|
||||
|
||||
if (changedEdges.length) {
|
||||
onEdgesChange?.(changedEdges as EdgeChange[]);
|
||||
|
||||
+2
-2
@@ -105,8 +105,8 @@ export function createNodeInternals(nodes: Node[], nodeInternals: NodeInternals)
|
||||
return nextNodeInternals;
|
||||
}
|
||||
|
||||
export const createNodeOrEdgeSelectionChange = (selected: boolean) => (item: Node | Edge) => ({
|
||||
id: item.id,
|
||||
export const createNodeOrEdgeSelectionChange = (selected: boolean) => (item: Node | Edge | string) => ({
|
||||
id: typeof item === 'string' ? item : item.id,
|
||||
type: 'select',
|
||||
selected,
|
||||
});
|
||||
|
||||
@@ -182,7 +182,8 @@ export type ReactFlowActions = {
|
||||
unsetNodesSelection: () => void;
|
||||
resetSelectedElements: () => void;
|
||||
unselectNodesAndEdges: () => void;
|
||||
addSelectedElements: (elements: Elements) => void;
|
||||
addSelectedNodes: (nodeIds: string[]) => void;
|
||||
addSelectedEdges: (edgeIds: string[]) => void;
|
||||
updateTransform: (transform: Transform) => void;
|
||||
updateSize: (size: Dimensions) => void;
|
||||
initD3Zoom: (payload: InitD3ZoomPayload) => void;
|
||||
|
||||
Reference in New Issue
Block a user