refactor(elements): split into nodes and edges

This commit is contained in:
moklick
2021-10-09 11:33:10 +02:00
parent be3b451d1d
commit 32ee964044
23 changed files with 502 additions and 393 deletions
+8 -8
View File
@@ -1,5 +1,6 @@
import React, { useEffect, useState, CSSProperties } from 'react';
import { useStoreState } from '../../store/hooks';
import { getBezierPath } from '../Edges/BezierEdge';
import { getSmoothStepPath } from '../Edges/SmoothStepEdge';
import {
@@ -20,7 +21,6 @@ interface ConnectionLineProps {
connectionPositionX: number;
connectionPositionY: number;
connectionLineType: ConnectionLineType;
nodes: Node[];
transform: Transform;
isConnectable: boolean;
connectionLineStyle?: CSSProperties;
@@ -35,11 +35,11 @@ export default ({
connectionPositionX,
connectionPositionY,
connectionLineType = ConnectionLineType.Bezier,
nodes = [],
transform,
isConnectable,
CustomConnectionLineComponent,
}: ConnectionLineProps) => {
const nodes = useStoreState((state) => state.nodes);
const [sourceNode, setSourceNode] = useState<Node | null>(null);
const nodeId = connectionNodeId;
const handleId = connectionHandleId;
@@ -54,12 +54,12 @@ export default ({
}
const sourceHandle = handleId
? sourceNode.__rf.handleBounds[connectionHandleType].find((d: HandleElement) => d.id === handleId)
: sourceNode.__rf.handleBounds[connectionHandleType][0];
const sourceHandleX = sourceHandle ? sourceHandle.x + sourceHandle.width / 2 : sourceNode.__rf.width / 2;
const sourceHandleY = sourceHandle ? sourceHandle.y + sourceHandle.height / 2 : sourceNode.__rf.height;
const sourceX = sourceNode.__rf.position.x + sourceHandleX;
const sourceY = sourceNode.__rf.position.y + sourceHandleY;
? sourceNode.handleBounds[connectionHandleType].find((d: HandleElement) => d.id === handleId)
: sourceNode.handleBounds[connectionHandleType][0];
const sourceHandleX = sourceHandle ? sourceHandle.x + sourceHandle.width / 2 : sourceNode.width! / 2;
const sourceHandleY = sourceHandle ? sourceHandle.y + sourceHandle.height / 2 : sourceNode.height;
const sourceX = sourceNode.position.x + sourceHandleX;
const sourceY = sourceNode.position.y + sourceHandleY;
const targetX = (connectionPositionX - transform[0]) / transform[2];
const targetY = (connectionPositionY - transform[1]) / transform[2];
+12 -6
View File
@@ -1,18 +1,24 @@
import { useEffect } from 'react';
import { useStoreActions } from '../../store/hooks';
import { Elements } from '../../types';
import { Node, Edge } from '../../types';
interface ElementUpdaterProps {
elements: Elements;
nodes: Node[];
edges: Edge[];
}
const ElementUpdater = ({ elements }: ElementUpdaterProps) => {
const setElements = useStoreActions((actions) => actions.setElements);
const ElementUpdater = ({ nodes, edges }: ElementUpdaterProps) => {
const setNodes = useStoreActions((actions) => actions.setNodes);
const setEdges = useStoreActions((actions) => actions.setEdges);
useEffect(() => {
setElements(elements);
}, [elements]);
setNodes(nodes);
}, [nodes]);
useEffect(() => {
setEdges(edges);
}, [edges]);
return null;
};
+6 -2
View File
@@ -1,6 +1,9 @@
import { MouseEvent as ReactMouseEvent } from 'react';
import { Store } from 'redux';
import { getHostForElement } from '../../utils';
import { ReactFlowState } from '../../types';
import { ReactFlowAction } from '../../store/actions';
import {
ElementId,
@@ -103,7 +106,8 @@ export function onMouseDown(
onEdgeUpdateEnd?: (evt: MouseEvent) => void,
onConnectStart?: OnConnectStartFunc,
onConnectStop?: OnConnectStopFunc,
onConnectEnd?: OnConnectEndFunc
onConnectEnd?: OnConnectEndFunc,
store?: Store<ReactFlowState, ReactFlowAction>
): void {
const reactFlowNode = (event.target as Element).closest('.react-flow');
// when react-flow is used inside a shadow root we can't use document
@@ -177,7 +181,7 @@ export function onMouseDown(
onConnectStop?.(event);
if (isValid) {
onConnect?.(connection);
onConnect?.(connection, store?.getState().nodes || []);
}
onConnectEnd?.(event);
+8 -6
View File
@@ -1,9 +1,9 @@
import React, { memo, useContext, useCallback, HTMLAttributes, forwardRef } from 'react';
import cc from 'classcat';
import { useStoreActions, useStoreState } from '../../store/hooks';
import { useStoreActions, useStoreState, useStore } from '../../store/hooks';
import NodeIdContext from '../../contexts/NodeIdContext';
import { HandleProps, Connection, ElementId, Position } from '../../types';
import { HandleProps, Connection, ElementId, Position, Node } from '../../types';
import { onMouseDown, SetSourceIdFunc, SetPosition } from './handler';
@@ -26,6 +26,7 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
},
ref
) => {
const store = useStore();
const nodeId = useContext(NodeIdContext) as ElementId;
const setPosition = useStoreActions((actions) => actions.setConnectionPosition);
const setConnectionNodeId = useStoreActions((actions) => actions.setConnectionNodeId);
@@ -38,9 +39,9 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
const isTarget = type === 'target';
const onConnectExtended = useCallback(
(params: Connection) => {
onConnectAction?.(params);
onConnect?.(params);
(params: Connection, nodes: Node[]) => {
onConnectAction?.(params, nodes);
onConnect?.(params, nodes);
},
[onConnectAction, onConnect]
);
@@ -61,7 +62,8 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
undefined,
onConnectStart,
onConnectStop,
onConnectEnd
onConnectEnd,
store
);
},
[
+32 -32
View File
@@ -1,18 +1,8 @@
import React, {
useEffect,
useLayoutEffect,
useRef,
memo,
ComponentType,
CSSProperties,
useMemo,
MouseEvent,
useCallback,
} from 'react';
import React, { useEffect, useRef, memo, ComponentType, CSSProperties, useMemo, MouseEvent, useCallback } from 'react';
import { DraggableCore, DraggableData, DraggableEvent } from 'react-draggable';
import cc from 'classcat';
import { useStoreActions } from '../../store/hooks';
import { useStoreActions, useStoreState } from '../../store/hooks';
import { Provider } from '../../contexts/NodeIdContext';
import { NodeComponentProps, WrapNodeProps } from '../../types';
@@ -50,9 +40,9 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
resizeObserver,
dragHandle,
}: WrapNodeProps) => {
const updateNodeDimensions = useStoreActions((actions) => actions.updateNodeDimensions);
// const updateNodeDimensions = useStoreActions((actions) => actions.updateNodeDimensions);
const addSelectedElements = useStoreActions((actions) => actions.addSelectedElements);
const updateNodePosDiff = useStoreActions((actions) => actions.updateNodePosDiff);
const onNodesChange = useStoreState((state) => state.onNodesChange);
const unsetNodesSelection = useStoreActions((actions) => actions.unsetNodesSelection);
const nodeElement = useRef<HTMLDivElement>(null);
@@ -84,6 +74,7 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
onMouseLeave,
]
);
const onMouseEnterHandler = useMemo(() => {
if (!onMouseEnter || isDragging) {
return;
@@ -153,20 +144,25 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
const onDrag = useCallback(
(event: DraggableEvent, draggableData: DraggableData) => {
node.position.x += draggableData.deltaX;
node.position.y += draggableData.deltaY;
if (onNodeDrag) {
node.position.x += draggableData.deltaX;
node.position.y += draggableData.deltaY;
onNodeDrag(event as MouseEvent, node);
}
updateNodePosDiff({
id,
diff: {
x: draggableData.deltaX,
y: draggableData.deltaY,
onNodesChange?.([
{
id,
change: {
position: {
x: node.position.x,
y: node.position.y,
},
isDragging: true,
},
},
isDragging: true,
});
]);
},
[id, node, onNodeDrag]
);
@@ -185,10 +181,14 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
return;
}
updateNodePosDiff({
id: node.id,
isDragging: false,
});
onNodesChange?.([
{
id: node.id,
change: {
isDragging: true,
},
},
]);
onNodeDragStop?.(event as MouseEvent, node);
},
@@ -202,11 +202,11 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
[node, onNodeDoubleClick]
);
useLayoutEffect(() => {
if (nodeElement.current && !isHidden) {
updateNodeDimensions([{ id, nodeElement: nodeElement.current, forceUpdate: true }]);
}
}, [id, isHidden, sourcePosition, targetPosition]);
// useEffect(() => {
// if (nodeElement.current && !isHidden) {
// updateNodeDimensions([{ id, nodeElement: nodeElement.current, forceUpdate: true }]);
// }
// }, [id, isHidden, sourcePosition, targetPosition]);
useEffect(() => {
if (nodeElement.current) {
+1 -1
View File
@@ -45,7 +45,7 @@ export default ({
return {
...matchingNode,
position: matchingNode?.__rf.position,
position: matchingNode?.position,
} as Node;
})
: [],