refactor(actions): addSelectedElements => addSelectedNodes, addSelectedEdges

This commit is contained in:
moklick
2021-11-26 15:18:27 +01:00
parent a032306408
commit d260abec75
9 changed files with 46 additions and 39 deletions
+13 -9
View File
@@ -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 -1
View File
@@ -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';
+3 -3
View File
@@ -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);
+5 -5
View File
@@ -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);
+1 -7
View File
@@ -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;
}
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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,
});
+2 -1
View File
@@ -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;