refactor(elements): split into nodes and edges
This commit is contained in:
@@ -4,7 +4,7 @@ import { useStoreState } from '../../store/hooks';
|
||||
import ConnectionLine from '../../components/ConnectionLine/index';
|
||||
import { isEdge } from '../../utils/graph';
|
||||
import MarkerDefinitions from './MarkerDefinitions';
|
||||
import { getEdgePositions, getHandle, isEdgeVisible, getSourceTargetNodes } from './utils';
|
||||
import { getEdgePositions, getHandle } from './utils';
|
||||
import {
|
||||
Position,
|
||||
Edge,
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
ConnectionLineType,
|
||||
ConnectionLineComponent,
|
||||
ConnectionMode,
|
||||
Transform,
|
||||
OnEdgeUpdateFunc,
|
||||
} from '../../types';
|
||||
|
||||
@@ -41,151 +40,167 @@ interface EdgeRendererProps {
|
||||
|
||||
interface EdgeWrapperProps {
|
||||
edge: Edge;
|
||||
props: EdgeRendererProps;
|
||||
nodes: Node[];
|
||||
edgeTypes: any;
|
||||
markerEndId?: string;
|
||||
onElementClick?: (event: React.MouseEvent, element: Node | Edge) => void;
|
||||
onEdgeContextMenu?: (event: React.MouseEvent, edge: Edge) => void;
|
||||
onEdgeMouseEnter?: (event: React.MouseEvent, edge: Edge) => void;
|
||||
onEdgeMouseMove?: (event: React.MouseEvent, edge: Edge) => void;
|
||||
onEdgeMouseLeave?: (event: React.MouseEvent, edge: Edge) => void;
|
||||
edgeUpdaterRadius?: number;
|
||||
onEdgeDoubleClick?: (event: React.MouseEvent, edge: Edge) => void;
|
||||
onEdgeUpdateStart?: (event: React.MouseEvent, edge: Edge) => void;
|
||||
onEdgeUpdateEnd?: (event: MouseEvent, edge: Edge) => void;
|
||||
onEdgeUpdate?: OnEdgeUpdateFunc;
|
||||
targetNode?: Node;
|
||||
sourceNode?: Node;
|
||||
selectedElements: Elements | null;
|
||||
elementsSelectable: boolean;
|
||||
transform: Transform;
|
||||
width: number;
|
||||
height: number;
|
||||
onlyRenderVisibleElements: boolean;
|
||||
connectionMode?: ConnectionMode;
|
||||
}
|
||||
|
||||
const Edge = ({
|
||||
edge,
|
||||
props,
|
||||
nodes,
|
||||
selectedElements,
|
||||
elementsSelectable,
|
||||
transform,
|
||||
width,
|
||||
height,
|
||||
onlyRenderVisibleElements,
|
||||
connectionMode,
|
||||
}: EdgeWrapperProps) => {
|
||||
const sourceHandleId = edge.sourceHandle || null;
|
||||
const targetHandleId = edge.targetHandle || null;
|
||||
const { sourceNode, targetNode } = getSourceTargetNodes(edge, nodes);
|
||||
|
||||
const onConnectEdge = useCallback(
|
||||
(connection: Connection) => {
|
||||
props.onEdgeUpdate?.(edge, connection);
|
||||
},
|
||||
[edge, props.onEdgeUpdate]
|
||||
);
|
||||
|
||||
if (!sourceNode) {
|
||||
console.warn(`couldn't create edge for source id: ${edge.source}; edge id: ${edge.id}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!targetNode) {
|
||||
console.warn(`couldn't create edge for target id: ${edge.target}; edge id: ${edge.id}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
// source and target node need to be initialized
|
||||
if (!sourceNode.__rf.width || !targetNode.__rf.width) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const edgeType = edge.type || 'default';
|
||||
const EdgeComponent = props.edgeTypes[edgeType] || props.edgeTypes.default;
|
||||
const targetNodeBounds = targetNode.__rf.handleBounds;
|
||||
// when connection type is loose we can define all handles as sources
|
||||
const targetNodeHandles =
|
||||
connectionMode === ConnectionMode.Strict
|
||||
? targetNodeBounds.target
|
||||
: targetNodeBounds.target || targetNodeBounds.source;
|
||||
const sourceHandle = getHandle(sourceNode.__rf.handleBounds.source, sourceHandleId);
|
||||
const targetHandle = getHandle(targetNodeHandles, targetHandleId);
|
||||
const sourcePosition = sourceHandle ? sourceHandle.position : Position.Bottom;
|
||||
const targetPosition = targetHandle ? targetHandle.position : Position.Top;
|
||||
|
||||
if (!sourceHandle) {
|
||||
console.warn(`couldn't create edge for source handle id: ${sourceHandleId}; edge id: ${edge.id}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!targetHandle) {
|
||||
console.warn(`couldn't create edge for target handle id: ${targetHandleId}; edge id: ${edge.id}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const { sourceX, sourceY, targetX, targetY } = getEdgePositions(
|
||||
sourceNode,
|
||||
sourceHandle,
|
||||
sourcePosition,
|
||||
const Edge = memo(
|
||||
({
|
||||
edge,
|
||||
edgeTypes,
|
||||
markerEndId,
|
||||
onElementClick,
|
||||
onEdgeContextMenu,
|
||||
onEdgeMouseEnter,
|
||||
onEdgeMouseMove,
|
||||
onEdgeMouseLeave,
|
||||
edgeUpdaterRadius,
|
||||
onEdgeDoubleClick,
|
||||
onEdgeUpdateStart,
|
||||
onEdgeUpdateEnd,
|
||||
onEdgeUpdate,
|
||||
targetNode,
|
||||
targetHandle,
|
||||
targetPosition
|
||||
);
|
||||
sourceNode,
|
||||
selectedElements,
|
||||
elementsSelectable,
|
||||
connectionMode,
|
||||
}: EdgeWrapperProps) => {
|
||||
const sourceHandleId = edge.sourceHandle || null;
|
||||
const targetHandleId = edge.targetHandle || null;
|
||||
|
||||
const isVisible = onlyRenderVisibleElements
|
||||
? isEdgeVisible({
|
||||
sourcePos: { x: sourceX, y: sourceY },
|
||||
targetPos: { x: targetX, y: targetY },
|
||||
width,
|
||||
height,
|
||||
transform,
|
||||
})
|
||||
: true;
|
||||
const onConnectEdge = useCallback(
|
||||
(connection: Connection) => {
|
||||
onEdgeUpdate?.(edge, connection);
|
||||
},
|
||||
[edge, onEdgeUpdate]
|
||||
);
|
||||
|
||||
if (!isVisible) {
|
||||
return null;
|
||||
if (!sourceNode) {
|
||||
console.warn(`couldn't create edge for source id: ${edge.source}; edge id: ${edge.id}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!targetNode) {
|
||||
console.warn(`couldn't create edge for target id: ${edge.target}; edge id: ${edge.id}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
// source and target node need to be initialized
|
||||
if (!sourceNode.width || !targetNode.width) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const edgeType = edge.type || 'default';
|
||||
const EdgeComponent = edgeTypes[edgeType] || edgeTypes.default;
|
||||
const targetNodeBounds = targetNode.handleBounds;
|
||||
// when connection type is loose we can define all handles as sources
|
||||
const targetNodeHandles =
|
||||
connectionMode === ConnectionMode.Strict
|
||||
? targetNodeBounds.target
|
||||
: targetNodeBounds.target || targetNodeBounds.source;
|
||||
const sourceHandle = getHandle(sourceNode.handleBounds.source, sourceHandleId);
|
||||
const targetHandle = getHandle(targetNodeHandles, targetHandleId);
|
||||
const sourcePosition = sourceHandle ? sourceHandle.position : Position.Bottom;
|
||||
const targetPosition = targetHandle ? targetHandle.position : Position.Top;
|
||||
|
||||
if (!sourceHandle) {
|
||||
console.warn(`couldn't create edge for source handle id: ${sourceHandleId}; edge id: ${edge.id}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!targetHandle) {
|
||||
console.warn(`couldn't create edge for target handle id: ${targetHandleId}; edge id: ${edge.id}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const { sourceX, sourceY, targetX, targetY } = getEdgePositions(
|
||||
sourceNode,
|
||||
sourceHandle,
|
||||
sourcePosition,
|
||||
targetNode,
|
||||
targetHandle,
|
||||
targetPosition
|
||||
);
|
||||
|
||||
// const isVisible = onlyRenderVisibleElements
|
||||
// ? isEdgeVisible({
|
||||
// sourcePos: { x: sourceX, y: sourceY },
|
||||
// targetPos: { x: targetX, y: targetY },
|
||||
// width,
|
||||
// height,
|
||||
// transform,
|
||||
// })
|
||||
// : true;
|
||||
|
||||
// if (!isVisible) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
const isSelected = selectedElements?.some((elm) => isEdge(elm) && elm.id === edge.id) || false;
|
||||
|
||||
return (
|
||||
<EdgeComponent
|
||||
key={edge.id}
|
||||
id={edge.id}
|
||||
className={edge.className}
|
||||
type={edge.type}
|
||||
data={edge.data}
|
||||
onClick={onElementClick}
|
||||
selected={isSelected}
|
||||
animated={edge.animated}
|
||||
label={edge.label}
|
||||
labelStyle={edge.labelStyle}
|
||||
labelShowBg={edge.labelShowBg}
|
||||
labelBgStyle={edge.labelBgStyle}
|
||||
labelBgPadding={edge.labelBgPadding}
|
||||
labelBgBorderRadius={edge.labelBgBorderRadius}
|
||||
style={edge.style}
|
||||
arrowHeadType={edge.arrowHeadType}
|
||||
source={edge.source}
|
||||
target={edge.target}
|
||||
sourceHandleId={sourceHandleId}
|
||||
targetHandleId={targetHandleId}
|
||||
sourceX={sourceX}
|
||||
sourceY={sourceY}
|
||||
targetX={targetX}
|
||||
targetY={targetY}
|
||||
sourcePosition={sourcePosition}
|
||||
targetPosition={targetPosition}
|
||||
elementsSelectable={elementsSelectable}
|
||||
markerEndId={markerEndId}
|
||||
isHidden={edge.isHidden}
|
||||
onConnectEdge={onConnectEdge}
|
||||
handleEdgeUpdate={typeof onEdgeUpdate !== 'undefined'}
|
||||
onContextMenu={onEdgeContextMenu}
|
||||
onMouseEnter={onEdgeMouseEnter}
|
||||
onMouseMove={onEdgeMouseMove}
|
||||
onMouseLeave={onEdgeMouseLeave}
|
||||
edgeUpdaterRadius={edgeUpdaterRadius}
|
||||
onEdgeDoubleClick={onEdgeDoubleClick}
|
||||
onEdgeUpdateStart={onEdgeUpdateStart}
|
||||
onEdgeUpdateEnd={onEdgeUpdateEnd}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const isSelected = selectedElements?.some((elm) => isEdge(elm) && elm.id === edge.id) || false;
|
||||
|
||||
return (
|
||||
<EdgeComponent
|
||||
key={edge.id}
|
||||
id={edge.id}
|
||||
className={edge.className}
|
||||
type={edge.type}
|
||||
data={edge.data}
|
||||
onClick={props.onElementClick}
|
||||
selected={isSelected}
|
||||
animated={edge.animated}
|
||||
label={edge.label}
|
||||
labelStyle={edge.labelStyle}
|
||||
labelShowBg={edge.labelShowBg}
|
||||
labelBgStyle={edge.labelBgStyle}
|
||||
labelBgPadding={edge.labelBgPadding}
|
||||
labelBgBorderRadius={edge.labelBgBorderRadius}
|
||||
style={edge.style}
|
||||
arrowHeadType={edge.arrowHeadType}
|
||||
source={edge.source}
|
||||
target={edge.target}
|
||||
sourceHandleId={sourceHandleId}
|
||||
targetHandleId={targetHandleId}
|
||||
sourceX={sourceX}
|
||||
sourceY={sourceY}
|
||||
targetX={targetX}
|
||||
targetY={targetY}
|
||||
sourcePosition={sourcePosition}
|
||||
targetPosition={targetPosition}
|
||||
elementsSelectable={elementsSelectable}
|
||||
markerEndId={props.markerEndId}
|
||||
isHidden={edge.isHidden}
|
||||
onConnectEdge={onConnectEdge}
|
||||
handleEdgeUpdate={typeof props.onEdgeUpdate !== 'undefined'}
|
||||
onContextMenu={props.onEdgeContextMenu}
|
||||
onMouseEnter={props.onEdgeMouseEnter}
|
||||
onMouseMove={props.onEdgeMouseMove}
|
||||
onMouseLeave={props.onEdgeMouseLeave}
|
||||
edgeUpdaterRadius={props.edgeUpdaterRadius}
|
||||
onEdgeDoubleClick={props.onEdgeDoubleClick}
|
||||
onEdgeUpdateStart={props.onEdgeUpdateStart}
|
||||
onEdgeUpdateEnd={props.onEdgeUpdateEnd}
|
||||
/>
|
||||
);
|
||||
};
|
||||
);
|
||||
|
||||
const EdgeRenderer = (props: EdgeRendererProps) => {
|
||||
const transform = useStoreState((state) => state.transform);
|
||||
const nodes = useStoreState((state) => state.nodes);
|
||||
const edges = useStoreState((state) => state.edges);
|
||||
const connectionNodeId = useStoreState((state) => state.connectionNodeId);
|
||||
const connectionHandleId = useStoreState((state) => state.connectionHandleId);
|
||||
@@ -201,13 +216,7 @@ const EdgeRenderer = (props: EdgeRendererProps) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
connectionLineType,
|
||||
arrowHeadColor,
|
||||
connectionLineStyle,
|
||||
connectionLineComponent,
|
||||
onlyRenderVisibleElements,
|
||||
} = props;
|
||||
const { connectionLineType, arrowHeadColor, connectionLineStyle, connectionLineComponent } = props;
|
||||
const transformStyle = `translate(${transform[0]},${transform[1]}) scale(${transform[2]})`;
|
||||
const renderConnectionLine = connectionNodeId && connectionHandleType;
|
||||
|
||||
@@ -219,19 +228,25 @@ const EdgeRenderer = (props: EdgeRendererProps) => {
|
||||
<Edge
|
||||
key={edge.id}
|
||||
edge={edge}
|
||||
props={props}
|
||||
nodes={nodes}
|
||||
sourceNode={edge.sourceNode}
|
||||
targetNode={edge.targetNode}
|
||||
selectedElements={selectedElements}
|
||||
elementsSelectable={elementsSelectable}
|
||||
transform={transform}
|
||||
width={width}
|
||||
height={height}
|
||||
onlyRenderVisibleElements={onlyRenderVisibleElements}
|
||||
markerEndId={props.markerEndId}
|
||||
onEdgeContextMenu={props.onEdgeContextMenu}
|
||||
onEdgeMouseEnter={props.onEdgeMouseEnter}
|
||||
onEdgeMouseMove={props.onEdgeMouseMove}
|
||||
onEdgeMouseLeave={props.onEdgeMouseLeave}
|
||||
edgeUpdaterRadius={props.edgeUpdaterRadius}
|
||||
onEdgeDoubleClick={props.onEdgeDoubleClick}
|
||||
onEdgeUpdateStart={props.onEdgeUpdateStart}
|
||||
onEdgeUpdateEnd={props.onEdgeUpdateEnd}
|
||||
onEdgeUpdate={props.onEdgeUpdate}
|
||||
edgeTypes={props.edgeTypes}
|
||||
/>
|
||||
))}
|
||||
{renderConnectionLine && (
|
||||
<ConnectionLine
|
||||
nodes={nodes}
|
||||
connectionNodeId={connectionNodeId!}
|
||||
connectionHandleId={connectionHandleId}
|
||||
connectionHandleType={connectionHandleType!}
|
||||
|
||||
@@ -40,8 +40,8 @@ export function createEdgeTypes(edgeTypes: EdgeTypesType): EdgeTypesType {
|
||||
}
|
||||
|
||||
export function getHandlePosition(position: Position, node: Node, handle: any | null = null): XYPosition {
|
||||
const x = (handle?.x || 0) + node.__rf.position.x;
|
||||
const y = (handle?.y || 0) + node.__rf.position.y;
|
||||
const x = (handle?.x || 0) + node.position.x;
|
||||
const y = (handle?.y || 0) + node.position.y;
|
||||
const width = handle?.width || node.__rf.width;
|
||||
const height = handle?.height || node.__rf.height;
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ const FlowRenderer = ({
|
||||
onPaneClick,
|
||||
onPaneContextMenu,
|
||||
onPaneScroll,
|
||||
onElementsRemove,
|
||||
deleteKeyCode,
|
||||
onMove,
|
||||
onMoveStart,
|
||||
@@ -61,7 +60,7 @@ const FlowRenderer = ({
|
||||
|
||||
const selectionKeyPressed = useKeyPress(selectionKeyCode);
|
||||
|
||||
useGlobalKeyHandler({ onElementsRemove, deleteKeyCode, multiSelectionKeyCode });
|
||||
useGlobalKeyHandler({ deleteKeyCode, multiSelectionKeyCode });
|
||||
|
||||
const onClick = useCallback(
|
||||
(event: MouseEvent) => {
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ReactFlowProps } from '../ReactFlow';
|
||||
|
||||
import { NodeTypesType, EdgeTypesType, ConnectionLineType, KeyCode } from '../../types';
|
||||
|
||||
export interface GraphViewProps extends Omit<ReactFlowProps, 'onSelectionChange' | 'elements'> {
|
||||
export interface GraphViewProps extends Omit<ReactFlowProps, 'onSelectionChange' | 'nodes' | 'edges'> {
|
||||
nodeTypes: NodeTypesType;
|
||||
edgeTypes: EdgeTypesType;
|
||||
selectionKeyCode: KeyCode;
|
||||
@@ -55,7 +55,6 @@ const GraphView = ({
|
||||
selectionKeyCode,
|
||||
multiSelectionKeyCode,
|
||||
zoomActivationKeyCode,
|
||||
onElementsRemove,
|
||||
deleteKeyCode,
|
||||
onConnect,
|
||||
onConnectStart,
|
||||
@@ -95,6 +94,8 @@ const GraphView = ({
|
||||
edgeUpdaterRadius,
|
||||
onEdgeUpdateStart,
|
||||
onEdgeUpdateEnd,
|
||||
onNodesChange,
|
||||
onEdgesChange,
|
||||
}: GraphViewProps) => {
|
||||
const isInitialized = useRef<boolean>(false);
|
||||
const setOnConnect = useStoreActions((actions) => actions.setOnConnect);
|
||||
@@ -111,6 +112,9 @@ const GraphView = ({
|
||||
const setTranslateExtent = useStoreActions((actions) => actions.setTranslateExtent);
|
||||
const setNodeExtent = useStoreActions((actions) => actions.setNodeExtent);
|
||||
const setConnectionMode = useStoreActions((actions) => actions.setConnectionMode);
|
||||
const setOnNodesChange = useStoreActions((actions) => actions.setOnNodesChange);
|
||||
const setOnEdgesChange = useStoreActions((actions) => actions.setOnEdgesChange);
|
||||
|
||||
const currentStore = useStore();
|
||||
const { zoomIn, zoomOut, zoomTo, transform, fitView, initialized } = useZoomPanHelper();
|
||||
|
||||
@@ -217,12 +221,23 @@ const GraphView = ({
|
||||
}
|
||||
}, [connectionMode]);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof onNodesChange !== 'undefined') {
|
||||
setOnNodesChange(onNodesChange);
|
||||
}
|
||||
}, [onNodesChange]);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof onEdgesChange !== 'undefined') {
|
||||
setOnEdgesChange(onEdgesChange);
|
||||
}
|
||||
}, [onEdgesChange]);
|
||||
|
||||
return (
|
||||
<FlowRenderer
|
||||
onPaneClick={onPaneClick}
|
||||
onPaneContextMenu={onPaneContextMenu}
|
||||
onPaneScroll={onPaneScroll}
|
||||
onElementsRemove={onElementsRemove}
|
||||
deleteKeyCode={deleteKeyCode}
|
||||
selectionKeyCode={selectionKeyCode}
|
||||
multiSelectionKeyCode={multiSelectionKeyCode}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React, { memo, useMemo, ComponentType, MouseEvent } from 'react';
|
||||
|
||||
import { getNodesInside } from '../../utils/graph';
|
||||
import { useStoreState, useStoreActions } from '../../store/hooks';
|
||||
import { Node, NodeTypesType, WrapNodeProps, Edge } from '../../types';
|
||||
interface NodeRendererProps {
|
||||
@@ -26,14 +25,12 @@ const NodeRenderer = (props: NodeRendererProps) => {
|
||||
const nodesDraggable = useStoreState((state) => state.nodesDraggable);
|
||||
const nodesConnectable = useStoreState((state) => state.nodesConnectable);
|
||||
const elementsSelectable = useStoreState((state) => state.elementsSelectable);
|
||||
const width = useStoreState((state) => state.width);
|
||||
const height = useStoreState((state) => state.height);
|
||||
const nodes = useStoreState((state) => state.nodes);
|
||||
const updateNodeDimensions = useStoreActions((actions) => actions.updateNodeDimensions);
|
||||
|
||||
const visibleNodes = props.onlyRenderVisibleElements
|
||||
? getNodesInside(nodes, { x: 0, y: 0, width, height }, transform, true)
|
||||
: nodes;
|
||||
// const visibleNodes = props.onlyRenderVisibleElements
|
||||
// ? getNodesInside(nodes, { x: 0, y: 0, width, height }, transform, true)
|
||||
// : nodes;
|
||||
|
||||
const transformStyle = useMemo(
|
||||
() => ({
|
||||
@@ -59,7 +56,7 @@ const NodeRenderer = (props: NodeRendererProps) => {
|
||||
|
||||
return (
|
||||
<div className="react-flow__nodes" style={transformStyle}>
|
||||
{visibleNodes.map((node) => {
|
||||
{nodes.map((node) => {
|
||||
const nodeType = node.type || 'default';
|
||||
const NodeComponent = (props.nodeTypes[nodeType] || props.nodeTypes.default) as ComponentType<WrapNodeProps>;
|
||||
|
||||
@@ -82,10 +79,10 @@ const NodeRenderer = (props: NodeRendererProps) => {
|
||||
sourcePosition={node.sourcePosition}
|
||||
targetPosition={node.targetPosition}
|
||||
isHidden={node.isHidden}
|
||||
xPos={node.__rf.position.x}
|
||||
yPos={node.__rf.position.y}
|
||||
isDragging={node.__rf.isDragging}
|
||||
isInitialized={node.__rf.width !== null && node.__rf.height !== null}
|
||||
xPos={node.position.x}
|
||||
yPos={node.position.y}
|
||||
isDragging={node.isDragging}
|
||||
isInitialized={node.width !== null && node.height !== null}
|
||||
snapGrid={props.snapGrid}
|
||||
snapToGrid={props.snapToGrid}
|
||||
selectNodesOnDrag={props.selectNodesOnDrag}
|
||||
|
||||
@@ -25,7 +25,6 @@ import {
|
||||
OnLoadFunc,
|
||||
Node,
|
||||
Edge,
|
||||
Connection,
|
||||
ConnectionMode,
|
||||
ConnectionLineType,
|
||||
ConnectionLineComponent,
|
||||
@@ -33,11 +32,13 @@ import {
|
||||
OnConnectStartFunc,
|
||||
OnConnectStopFunc,
|
||||
OnConnectEndFunc,
|
||||
OnConnectFunc,
|
||||
TranslateExtent,
|
||||
KeyCode,
|
||||
PanOnScrollMode,
|
||||
OnEdgeUpdateFunc,
|
||||
NodeExtent,
|
||||
ElementChange,
|
||||
} from '../../types';
|
||||
|
||||
import '../../style.css';
|
||||
@@ -57,9 +58,11 @@ const defaultEdgeTypes = {
|
||||
};
|
||||
|
||||
export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onLoad'> {
|
||||
elements: Elements;
|
||||
nodes: Node[];
|
||||
edges: Edge[];
|
||||
onNodesChange?: (nodeChanges: ElementChange[]) => void;
|
||||
onEdgesChange?: (edgeChanges: ElementChange[]) => void;
|
||||
onElementClick?: (event: ReactMouseEvent, element: Node | Edge) => void;
|
||||
onElementsRemove?: (elements: Elements) => void;
|
||||
onNodeDoubleClick?: (event: ReactMouseEvent, node: Node) => void;
|
||||
onNodeMouseEnter?: (event: ReactMouseEvent, node: Node) => void;
|
||||
onNodeMouseMove?: (event: ReactMouseEvent, node: Node) => void;
|
||||
@@ -68,7 +71,7 @@ export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'on
|
||||
onNodeDragStart?: (event: ReactMouseEvent, node: Node) => void;
|
||||
onNodeDrag?: (event: ReactMouseEvent, node: Node) => void;
|
||||
onNodeDragStop?: (event: ReactMouseEvent, node: Node) => void;
|
||||
onConnect?: (connection: Edge | Connection) => void;
|
||||
onConnect?: OnConnectFunc;
|
||||
onConnectStart?: OnConnectStartFunc;
|
||||
onConnectStop?: OnConnectStopFunc;
|
||||
onConnectEnd?: OnConnectEndFunc;
|
||||
@@ -132,10 +135,14 @@ export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'on
|
||||
|
||||
export type ReactFlowRefType = HTMLDivElement;
|
||||
|
||||
const initSnapGrid: [number, number] = [15, 15];
|
||||
const initDefaultPosition: [number, number] = [0, 0];
|
||||
|
||||
const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
|
||||
(
|
||||
{
|
||||
elements = [],
|
||||
nodes = [],
|
||||
edges = [],
|
||||
className,
|
||||
nodeTypes = defaultNodeTypes,
|
||||
edgeTypes = defaultEdgeTypes,
|
||||
@@ -144,7 +151,6 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
|
||||
onMove,
|
||||
onMoveStart,
|
||||
onMoveEnd,
|
||||
onElementsRemove,
|
||||
onConnect,
|
||||
onConnectStart,
|
||||
onConnectStop,
|
||||
@@ -171,7 +177,7 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
|
||||
multiSelectionKeyCode = 'Meta',
|
||||
zoomActivationKeyCode = 'Meta',
|
||||
snapToGrid = false,
|
||||
snapGrid = [15, 15],
|
||||
snapGrid = initSnapGrid,
|
||||
onlyRenderVisibleElements = false,
|
||||
selectNodesOnDrag = true,
|
||||
nodesDraggable,
|
||||
@@ -180,7 +186,7 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
|
||||
minZoom,
|
||||
maxZoom,
|
||||
defaultZoom = 1,
|
||||
defaultPosition = [0, 0],
|
||||
defaultPosition = initDefaultPosition,
|
||||
translateExtent,
|
||||
preventScrolling = true,
|
||||
nodeExtent,
|
||||
@@ -208,6 +214,8 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
|
||||
edgeUpdaterRadius = 10,
|
||||
nodeTypesId = '1',
|
||||
edgeTypesId = '1',
|
||||
onNodesChange,
|
||||
onEdgesChange,
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
@@ -240,7 +248,6 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
|
||||
connectionLineStyle={connectionLineStyle}
|
||||
connectionLineComponent={connectionLineComponent}
|
||||
selectionKeyCode={selectionKeyCode}
|
||||
onElementsRemove={onElementsRemove}
|
||||
deleteKeyCode={deleteKeyCode}
|
||||
multiSelectionKeyCode={multiSelectionKeyCode}
|
||||
zoomActivationKeyCode={zoomActivationKeyCode}
|
||||
@@ -287,8 +294,10 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
|
||||
onEdgeUpdateStart={onEdgeUpdateStart}
|
||||
onEdgeUpdateEnd={onEdgeUpdateEnd}
|
||||
edgeUpdaterRadius={edgeUpdaterRadius}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
/>
|
||||
<ElementUpdater elements={elements} />
|
||||
<ElementUpdater nodes={nodes} edges={edges} />
|
||||
{onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />}
|
||||
{children}
|
||||
</Wrapper>
|
||||
|
||||
Reference in New Issue
Block a user