import React, { useMemo, CSSProperties, HTMLAttributes, MouseEvent, WheelEvent } from 'react'; import cc from 'classcat'; const nodeEnv: string = process.env.NODE_ENV as string; if (nodeEnv !== 'production') { const whyDidYouRender = require('@welldone-software/why-did-you-render'); whyDidYouRender(React); } import GraphView from '../GraphView'; import DefaultNode from '../../components/Nodes/DefaultNode'; import InputNode from '../../components/Nodes/InputNode'; import OutputNode from '../../components/Nodes/OutputNode'; import { createNodeTypes } from '../NodeRenderer/utils'; import SelectionListener from '../../components/SelectionListener'; import { BezierEdge, StepEdge, SmoothStepEdge, StraightEdge } from '../../components/Edges'; import { createEdgeTypes } from '../EdgeRenderer/utils'; import Wrapper from './Wrapper'; import { Elements, NodeTypesType, EdgeTypesType, OnLoadFunc, Node, Edge, Connection, ConnectionLineType, FlowTransform, OnConnectStartFunc, OnConnectStopFunc, OnConnectEndFunc, TranslateExtent, } from '../../types'; import '../../style.css'; export interface ReactFlowProps extends Omit, 'onLoad'> { elements: Elements; onElementClick?: (event: MouseEvent, element: Node | Edge) => void; onElementsRemove?: (elements: Elements) => void; onNodeMouseEnter?: (event: MouseEvent, node: Node) => void; onNodeMouseMove?: (event: MouseEvent, node: Node) => void; onNodeMouseLeave?: (event: MouseEvent, node: Node) => void; onNodeContextMenu?: (event: MouseEvent, node: Node) => void; onNodeDragStart?: (event: MouseEvent, node: Node) => void; onNodeDragStop?: (event: MouseEvent, node: Node) => void; onConnect?: (connection: Edge | Connection) => void; onConnectStart?: OnConnectStartFunc; onConnectStop?: OnConnectStopFunc; onConnectEnd?: OnConnectEndFunc; onLoad?: OnLoadFunc; onMove?: (flowTransform?: FlowTransform) => void; onMoveStart?: (flowTransform?: FlowTransform) => void; onMoveEnd?: (flowTransform?: FlowTransform) => void; onSelectionChange?: (elements: Elements | null) => void; onSelectionDragStart?: (event: MouseEvent, nodes: Node[]) => void; onSelectionDrag?: (event: MouseEvent, nodes: Node[]) => void; onSelectionDragStop?: (event: MouseEvent, nodes: Node[]) => void; onPaneScroll?: (event?: WheelEvent) => void; onPaneClick?: (event: MouseEvent) => void; onPaneContextMenu?: (event: MouseEvent) => void; nodeTypes: NodeTypesType; edgeTypes: EdgeTypesType; connectionLineType: ConnectionLineType; connectionLineStyle?: CSSProperties; deleteKeyCode: number; selectionKeyCode: number; snapToGrid: boolean; snapGrid: [number, number]; onlyRenderVisibleNodes: boolean; nodesDraggable: boolean; nodesConnectable: boolean; elementsSelectable: boolean; selectNodesOnDrag: boolean; paneMoveable: boolean; minZoom: number; maxZoom: number; defaultZoom: number; defaultPosition: [number, number]; translateExtent?: TranslateExtent; arrowHeadColor: string; markerEndId?: string; zoomOnScroll: boolean; zoomOnDoubleClick: boolean; } const ReactFlow = ({ style, onElementClick, elements = [], className, children, nodeTypes, edgeTypes, onLoad, onMove, onMoveStart, onMoveEnd, onElementsRemove, onConnect, onConnectStart, onConnectStop, onConnectEnd, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onNodeDragStart, onNodeDragStop, onSelectionChange, onSelectionDragStart, onSelectionDrag, onSelectionDragStop, connectionLineType, connectionLineStyle, deleteKeyCode, selectionKeyCode, snapToGrid, snapGrid, onlyRenderVisibleNodes, nodesDraggable, nodesConnectable, elementsSelectable, selectNodesOnDrag, minZoom, maxZoom, defaultZoom, defaultPosition, translateExtent, arrowHeadColor, markerEndId, zoomOnScroll, zoomOnDoubleClick, paneMoveable, onPaneClick, onPaneScroll, onPaneContextMenu, }: ReactFlowProps) => { const nodeTypesParsed = useMemo(() => createNodeTypes(nodeTypes), []); const edgeTypesParsed = useMemo(() => createEdgeTypes(edgeTypes), []); const reactFlowClasses = cc(['react-flow', className]); return (
{onSelectionChange && } {children}
); }; ReactFlow.displayName = 'ReactFlow'; ReactFlow.defaultProps = { nodeTypes: { input: InputNode, default: DefaultNode, output: OutputNode, }, edgeTypes: { default: BezierEdge, straight: StraightEdge, step: StepEdge, smoothstep: SmoothStepEdge, }, connectionLineType: ConnectionLineType.Bezier, deleteKeyCode: 8, selectionKeyCode: 16, snapToGrid: false, snapGrid: [16, 16], onlyRenderVisibleNodes: true, nodesDraggable: true, nodesConnectable: true, elementsSelectable: true, selectNodesOnDrag: true, paneMoveable: true, minZoom: 0.5, maxZoom: 2, defaultZoom: 1, defaultPosition: [0, 0], arrowHeadColor: '#bbb', zoomOnScroll: true, zoomOnDoubleClick: true, }; export default ReactFlow;