chore(examples): use new api

This commit is contained in:
moklick
2021-12-25 13:30:13 +01:00
parent 7a85bb9666
commit a969c63400
29 changed files with 398 additions and 523 deletions
+1 -2
View File
@@ -4,7 +4,6 @@ import ReactFlow, {
addEdge, addEdge,
Background, Background,
BackgroundVariant, BackgroundVariant,
FlowElement,
Node, Node,
Edge, Edge,
Connection, Connection,
@@ -14,7 +13,7 @@ import ReactFlow, {
} from 'react-flow-renderer'; } from 'react-flow-renderer';
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node); const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
const onNodeClick = (_: MouseEvent, element: FlowElement) => console.log('click', element); const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node);
const initialNodes: Node[] = [ const initialNodes: Node[] = [
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, className: 'light' }, { id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, className: 'light' },
@@ -1,22 +1,21 @@
import React, { useState, DragEvent } from 'react'; import { useState, DragEvent } from 'react';
import ReactFlow, { import ReactFlow, {
ReactFlowProvider, ReactFlowProvider,
addEdge, addEdge,
removeElements,
Controls, Controls,
OnLoadParams, ReactFlowInstance,
Elements,
Connection, Connection,
Edge, Edge,
ElementId,
Node, Node,
useNodesState,
useEdgesState,
} from 'react-flow-renderer'; } from 'react-flow-renderer';
import Sidebar from './Sidebar'; import Sidebar from './Sidebar';
import './dnd.css'; import './dnd.css';
const initialElements = [{ id: '1', type: 'input', data: { label: 'input node' }, position: { x: 250, y: 5 } }]; const initialNodes: Node[] = [{ id: '1', type: 'input', data: { label: 'input node' }, position: { x: 250, y: 5 } }];
const onDragOver = (event: DragEvent) => { const onDragOver = (event: DragEvent) => {
event.preventDefault(); event.preventDefault();
@@ -24,15 +23,15 @@ const onDragOver = (event: DragEvent) => {
}; };
let id = 0; let id = 0;
const getId = (): ElementId => `dndnode_${id++}`; const getId = () => `dndnode_${id++}`;
const DnDFlow = () => { const DnDFlow = () => {
const [reactFlowInstance, setReactFlowInstance] = useState<OnLoadParams>(); const [reactFlowInstance, setReactFlowInstance] = useState<ReactFlowInstance>();
const [elements, setElements] = useState<Elements>(initialElements); const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
const onConnect = (params: Connection | Edge) => setElements((els) => addEdge(params, els)); const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds));
const onElementsRemove = (elementsToRemove: Elements) => setElements((els) => removeElements(elementsToRemove, els)); const onPaneReady = (rfi: ReactFlowInstance) => setReactFlowInstance(rfi);
const onLoad = (_reactFlowInstance: OnLoadParams) => setReactFlowInstance(_reactFlowInstance);
const onDrop = (event: DragEvent) => { const onDrop = (event: DragEvent) => {
event.preventDefault(); event.preventDefault();
@@ -47,7 +46,7 @@ const DnDFlow = () => {
data: { label: `${type} node` }, data: { label: `${type} node` },
}; };
setElements((es) => es.concat(newNode)); setNodes((nds) => nds.concat(newNode));
} }
}; };
@@ -56,10 +55,12 @@ const DnDFlow = () => {
<ReactFlowProvider> <ReactFlowProvider>
<div className="reactflow-wrapper"> <div className="reactflow-wrapper">
<ReactFlow <ReactFlow
elements={elements} nodes={nodes}
edges={edges}
onEdgesChange={onEdgesChange}
onNodesChange={onNodesChange}
onConnect={onConnect} onConnect={onConnect}
onElementsRemove={onElementsRemove} onPaneReady={onPaneReady}
onLoad={onLoad}
onDrop={onDrop} onDrop={onDrop}
onDragOver={onDragOver} onDragOver={onDragOver}
> >
@@ -1,41 +1,42 @@
/** /**
* Example for checking the different edge types and source and target positions * Example for checking the different edge types and source and target positions
*/ */
import React, { useState } from 'react';
import ReactFlow, { import ReactFlow, {
removeElements,
addEdge, addEdge,
MiniMap, MiniMap,
Controls, Controls,
Background, Background,
OnLoadParams, ReactFlowInstance,
Connection, Connection,
Edge, Edge,
Elements, useNodesState,
useEdgesState,
} from 'react-flow-renderer'; } from 'react-flow-renderer';
import { getElements } from './utils'; import { getElements } from './utils';
const onLoad = (reactFlowInstance: OnLoadParams) => { const onPaneReady = (reactFlowInstance: ReactFlowInstance) => {
reactFlowInstance.fitView(); reactFlowInstance.fitView();
console.log(reactFlowInstance.getElements()); console.log(reactFlowInstance.getNodes());
}; };
const initialElements = getElements(); const { nodes: initialNodes, edges: initialEdges } = getElements();
const multiSelectionKeyCode = ['ShiftLeft', 'ShiftRight']; const multiSelectionKeyCode = ['ShiftLeft', 'ShiftRight'];
const deleteKeyCode = ['AltLeft+KeyD', 'Backspace']; const deleteKeyCode = ['AltLeft+KeyD', 'Backspace'];
const EdgeTypesFlow = () => { const EdgeTypesFlow = () => {
const [elements, setElements] = useState<Elements>(initialElements); const [nodes, , onNodesChange] = useNodesState(initialNodes);
const onElementsRemove = (elementsToRemove: Elements) => setElements((els) => removeElements(elementsToRemove, els)); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = (params: Connection | Edge) => setElements((els) => addEdge(params, els)); const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds));
return ( return (
<ReactFlow <ReactFlow
elements={elements} nodes={nodes}
onLoad={onLoad} edges={edges}
onElementsRemove={onElementsRemove} onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onPaneReady={onPaneReady}
onConnect={onConnect} onConnect={onConnect}
minZoom={0.2} minZoom={0.2}
zoomOnScroll={false} zoomOnScroll={false}
@@ -1,4 +1,4 @@
import { ElementId, Elements, Position } from 'react-flow-renderer'; import { Node, Edge, Position } from 'react-flow-renderer';
const nodeWidth = 80; const nodeWidth = 80;
const nodeGapWidth = nodeWidth * 2; const nodeGapWidth = nodeWidth * 2;
@@ -49,10 +49,10 @@ const offsets = [
]; ];
let id = 0; let id = 0;
const getNodeId = (): ElementId => (id++).toString(); const getNodeId = (): string => (id++).toString();
export function getElements(): Elements { export function getElements(): { nodes: Node[]; edges: Edge[] } {
const initialElements = []; const initialElements = { nodes: [] as Node[], edges: [] as Edge[] };
for (let sourceTargetIndex = 0; sourceTargetIndex < sourceTargetPositions.length; sourceTargetIndex++) { for (let sourceTargetIndex = 0; sourceTargetIndex < sourceTargetPositions.length; sourceTargetIndex++) {
const currSourceTargetPos = sourceTargetPositions[sourceTargetIndex]; const currSourceTargetPos = sourceTargetPositions[sourceTargetIndex];
@@ -70,7 +70,7 @@ export function getElements(): Elements {
}; };
const sourceId = getNodeId(); const sourceId = getNodeId();
const sourceData = { label: `Source ${sourceId}` }; const sourceData = { label: `Source ${sourceId}` };
const sourceNode = { const sourceNode: Node = {
id: sourceId, id: sourceId,
style, style,
data: sourceData, data: sourceData,
@@ -85,7 +85,7 @@ export function getElements(): Elements {
x: sourcePosition.x + currOffset.x, x: sourcePosition.x + currOffset.x,
y: sourcePosition.y + currOffset.y, y: sourcePosition.y + currOffset.y,
}; };
const targetNode = { const targetNode: Node = {
id: targetId, id: targetId,
style, style,
data: targetData, data: targetData,
@@ -94,10 +94,15 @@ export function getElements(): Elements {
targetPosition: currSourceTargetPos.target, targetPosition: currSourceTargetPos.target,
}; };
initialElements.push(sourceNode); initialElements.nodes.push(sourceNode);
initialElements.push(targetNode); initialElements.nodes.push(targetNode);
initialElements.push({ id: `${sourceId}-${targetId}`, source: sourceId, target: targetId, type: currEdgeType }); initialElements.edges.push({
id: `${sourceId}-${targetId}`,
source: sourceId,
target: targetId,
type: currEdgeType,
} as Edge);
} }
} }
} }
@@ -1,29 +1,28 @@
import React, { useState, MouseEvent } from 'react'; import { MouseEvent } from 'react';
import ReactFlow, { import ReactFlow, {
removeElements,
addEdge, addEdge,
MiniMap, MiniMap,
Controls, Controls,
Background, Background,
OnLoadParams, ReactFlowInstance,
FlowElement,
EdgeTypesType, EdgeTypesType,
Elements,
Connection, Connection,
Edge, Edge,
ArrowHeadType, MarkerType,
Node, Node,
useNodesState,
useEdgesState,
} from 'react-flow-renderer'; } from 'react-flow-renderer';
import CustomEdge from './CustomEdge'; import CustomEdge from './CustomEdge';
import CustomEdge2 from './CustomEdge2'; import CustomEdge2 from './CustomEdge2';
const onLoad = (reactFlowInstance: OnLoadParams) => reactFlowInstance.fitView(); const onPaneReady = (reactFlowInstance: ReactFlowInstance) => reactFlowInstance.fitView();
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node); const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element); const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node);
const initialElements: Elements = [ const initialNodes: Node[] = [
{ id: '1', type: 'input', data: { label: 'Input 1' }, position: { x: 250, y: 0 } }, { id: '1', type: 'input', data: { label: 'Input 1' }, position: { x: 250, y: 0 } },
{ id: '2', data: { label: 'Node 2' }, position: { x: 150, y: 100 } }, { id: '2', data: { label: 'Node 2' }, position: { x: 150, y: 100 } },
{ id: '2a', data: { label: 'Node 2a' }, position: { x: 0, y: 180 } }, { id: '2a', data: { label: 'Node 2a' }, position: { x: 0, y: 180 } },
@@ -35,6 +34,9 @@ const initialElements: Elements = [
{ id: '7', type: 'output', data: { label: 'Output 7' }, position: { x: 250, y: 550 } }, { id: '7', type: 'output', data: { label: 'Output 7' }, position: { x: 250, y: 550 } },
{ id: '8', type: 'output', data: { label: 'Output 8' }, position: { x: 525, y: 600 } }, { id: '8', type: 'output', data: { label: 'Output 8' }, position: { x: 525, y: 600 } },
{ id: '9', type: 'output', data: { label: 'Output 9' }, position: { x: 675, y: 500 } }, { id: '9', type: 'output', data: { label: 'Output 9' }, position: { x: 675, y: 500 } },
];
const initialEdges: Edge[] = [
{ id: 'e1-2', source: '1', target: '2', label: 'bezier edge (default)', className: 'normal-edge' }, { id: 'e1-2', source: '1', target: '2', label: 'bezier edge (default)', className: 'normal-edge' },
{ id: 'e2-2a', source: '2', target: '2a', type: 'smoothstep', label: 'smoothstep edge' }, { id: 'e2-2a', source: '2', target: '2a', type: 'smoothstep', label: 'smoothstep edge' },
{ id: 'e2-3', source: '2', target: '3', type: 'step', label: 'step edge' }, { id: 'e2-3', source: '2', target: '3', type: 'step', label: 'step edge' },
@@ -50,7 +52,7 @@ const initialElements: Elements = [
labelBgBorderRadius: 4, labelBgBorderRadius: 4,
labelBgStyle: { fill: '#FFCC00', color: '#fff', fillOpacity: 0.7 }, labelBgStyle: { fill: '#FFCC00', color: '#fff', fillOpacity: 0.7 },
markerEnd: { markerEnd: {
type: ArrowHeadType.ArrowClosed, type: MarkerType.ArrowClosed,
}, },
}, },
{ {
@@ -82,18 +84,18 @@ const initialElements: Elements = [
labelStyle: { fill: 'red', fontWeight: 700 }, labelStyle: { fill: 'red', fontWeight: 700 },
style: { stroke: '#ffcc00' }, style: { stroke: '#ffcc00' },
markerEnd: { markerEnd: {
type: ArrowHeadType.Arrow, type: MarkerType.Arrow,
color: '#FFCC00', color: '#FFCC00',
units: 'userSpaceOnUse', markerUnits: 'userSpaceOnUse',
width: 20, width: 20,
height: 20, height: 20,
strokeWidth: 2, strokeWidth: 2,
}, },
markerStart: { markerStart: {
type: ArrowHeadType.ArrowClosed, type: MarkerType.ArrowClosed,
color: '#FFCC00', color: '#FFCC00',
orient: 'auto-start-reverse', orient: 'auto-start-reverse',
units: 'userSpaceOnUse', markerUnits: 'userSpaceOnUse',
width: 20, width: 20,
height: 20, height: 20,
}, },
@@ -106,19 +108,20 @@ const edgeTypes: EdgeTypesType = {
}; };
const EdgesFlow = () => { const EdgesFlow = () => {
const [elements, setElements] = useState<Elements>(initialElements); const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onElementsRemove = (elementsToRemove: Elements) => setElements((els) => removeElements(elementsToRemove, els)); const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds));
const onConnect = (params: Connection | Edge) => setElements((els) => addEdge(params, els));
return ( return (
<ReactFlow <ReactFlow
elements={elements} nodes={nodes}
onElementClick={onElementClick} edges={edges}
onElementsRemove={onElementsRemove} onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onNodeClick={onNodeClick}
onConnect={onConnect} onConnect={onConnect}
onNodeDragStop={onNodeDragStop} onNodeDragStop={onNodeDragStop}
onLoad={onLoad} onPaneReady={onPaneReady}
snapToGrid={true} snapToGrid={true}
edgeTypes={edgeTypes} edgeTypes={edgeTypes}
> >
@@ -1,34 +1,45 @@
import React, { useState, FC } from 'react'; import { FC } from 'react';
import ReactFlow, { import ReactFlow, {
removeElements,
addEdge, addEdge,
Background, Background,
Elements, Node,
Edge, Edge,
Connection, Connection,
ReactFlowProvider, ReactFlowProvider,
useNodesState,
useEdgesState,
} from 'react-flow-renderer'; } from 'react-flow-renderer';
import './multiflows.css'; import './multiflows.css';
const initialElements: Elements = [ const initialNodes: Node[] = [
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, className: 'light' }, { id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, className: 'light' },
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 }, className: 'light' }, { id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 }, className: 'light' },
{ id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, className: 'light' }, { id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, className: 'light' },
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 }, className: 'light' }, { id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 }, className: 'light' },
];
const initialEdges: Edge[] = [
{ id: 'e1-2', source: '1', target: '2', animated: true }, { id: 'e1-2', source: '1', target: '2', animated: true },
{ id: 'e1-3', source: '1', target: '3' }, { id: 'e1-3', source: '1', target: '3' },
]; ];
const Flow: FC = () => { const Flow: FC = () => {
const [elements, setElements] = useState<Elements>(initialElements); const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const onElementsRemove = (elementsToRemove: Elements) => setElements((els) => removeElements(elementsToRemove, els)); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = (params: Edge | Connection) => setElements((els) => addEdge(params, els));
const onConnect = (params: Edge | Connection) => setEdges((eds) => addEdge(params, eds));
return ( return (
<ReactFlowProvider> <ReactFlowProvider>
<ReactFlow elements={elements} onElementsRemove={onElementsRemove} onConnect={onConnect}> <ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
>
<Background /> <Background />
</ReactFlow> </ReactFlow>
</ReactFlowProvider> </ReactFlowProvider>
+70
View File
@@ -0,0 +1,70 @@
import { CSSProperties } from 'react';
import ReactFlow, {
addEdge,
Node,
Position,
Connection,
Edge,
useNodesState,
useEdgesState,
} from 'react-flow-renderer';
const initialNodes: Node[] = [
{
id: '1',
sourcePosition: Position.Right,
type: 'input',
data: { label: 'Input' },
position: { x: 0, y: 80 },
},
{
id: '2',
type: 'output',
sourcePosition: Position.Right,
targetPosition: Position.Left,
data: { label: 'A Node' },
position: { x: 250, y: 0 },
},
];
const initialEdges: Edge[] = [{ id: 'e1-2', source: '1', type: 'smoothstep', target: '2', animated: true }];
const buttonStyle: CSSProperties = { position: 'absolute', right: 10, top: 30, zIndex: 4 };
const NodeTypeChangeFlow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds));
const changeType = () => {
setNodes((nds) =>
nds.map((node) => {
if (node.type === 'input') {
return node;
}
return {
...node,
type: node.type === 'default' ? 'output' : 'default',
};
})
);
};
return (
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
fitViewOnInit
>
<button onClick={changeType} style={buttonStyle}>
change type
</button>
</ReactFlow>
);
};
export default NodeTypeChangeFlow;
@@ -1,16 +1,18 @@
import React, { useState, CSSProperties, FC } from 'react'; import { useState, CSSProperties, FC } from 'react';
import ReactFlow, { import ReactFlow, {
addEdge, addEdge,
Elements, Node,
Position, Position,
Connection, Connection,
Edge, Edge,
NodeProps, NodeProps,
NodeTypesType, NodeTypesType,
useNodesState,
useEdgesState,
} from 'react-flow-renderer'; } from 'react-flow-renderer';
const initialElements: Elements = [ const initialNodes: Node[] = [
{ {
id: '1', id: '1',
sourcePosition: Position.Right, sourcePosition: Position.Right,
@@ -55,16 +57,19 @@ const nodeTypesObjects: NodeTypesObject = {
const NodeTypeChangeFlow = () => { const NodeTypeChangeFlow = () => {
const [nodeTypesId, setNodeTypesId] = useState<string>('a'); const [nodeTypesId, setNodeTypesId] = useState<string>('a');
const [elements, setElements] = useState<Elements>(initialElements); const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const onConnect = (params: Connection | Edge) => setElements((els) => addEdge(params, els)); const [edges, setEdges, onEdgesChange] = useEdgesState([]);
const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds));
const changeType = () => setNodeTypesId((nt) => (nt === 'a' ? 'b' : 'a')); const changeType = () => setNodeTypesId((nt) => (nt === 'a' ? 'b' : 'a'));
return ( return (
<ReactFlow <ReactFlow
elements={elements} nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect} onConnect={onConnect}
nodeTypes={nodeTypesObjects[nodeTypesId]} nodeTypes={nodeTypesObjects[nodeTypesId]}
nodeTypesId={nodeTypesId}
> >
<button onClick={changeType} style={buttonStyle}> <button onClick={changeType} style={buttonStyle}>
change type change type
@@ -1,5 +1,5 @@
import React, { memo, useCallback, Dispatch, FC } from 'react'; import React, { memo, useCallback, Dispatch, FC } from 'react';
import { useZoomPanHelper, OnLoadParams, Elements, FlowExportObject } from 'react-flow-renderer'; import { useZoomPanHelper, ReactFlowInstance, Edge, Node, FlowExportObject } from 'react-flow-renderer';
import localforage from 'localforage'; import localforage from 'localforage';
localforage.config({ localforage.config({
@@ -12,12 +12,13 @@ const flowKey = 'example-flow';
const getNodeId = () => `randomnode_${+new Date()}`; const getNodeId = () => `randomnode_${+new Date()}`;
type ControlsProps = { type ControlsProps = {
rfInstance?: OnLoadParams; rfInstance?: ReactFlowInstance;
setElements: Dispatch<React.SetStateAction<Elements<any>>>; setNodes: Dispatch<React.SetStateAction<Node<any>[]>>;
setEdges: Dispatch<React.SetStateAction<Edge<any>[]>>;
}; };
const Controls: FC<ControlsProps> = ({ rfInstance, setElements }) => { const Controls: FC<ControlsProps> = ({ rfInstance, setNodes, setEdges }) => {
const { transform } = useZoomPanHelper(); const { setTransform } = useZoomPanHelper();
const onSave = useCallback(() => { const onSave = useCallback(() => {
if (rfInstance) { if (rfInstance) {
@@ -32,13 +33,14 @@ const Controls: FC<ControlsProps> = ({ rfInstance, setElements }) => {
if (flow) { if (flow) {
const [x = 0, y = 0] = flow.position; const [x = 0, y = 0] = flow.position;
setElements(flow.elements || []); setNodes(flow.nodes || []);
transform({ x, y, zoom: flow.zoom || 0 }); setEdges(flow.edges || []);
setTransform({ x, y, zoom: flow.zoom || 0 });
} }
}; };
restoreFlow(); restoreFlow();
}, [setElements, transform]); }, [setNodes, setEdges, setTransform]);
const onAdd = useCallback(() => { const onAdd = useCallback(() => {
const newNode = { const newNode = {
@@ -46,8 +48,8 @@ const Controls: FC<ControlsProps> = ({ rfInstance, setElements }) => {
data: { label: 'Added node' }, data: { label: 'Added node' },
position: { x: Math.random() * window.innerWidth - 100, y: Math.random() * window.innerHeight }, position: { x: Math.random() * window.innerWidth - 100, y: Math.random() * window.innerHeight },
}; };
setElements((els) => els.concat(newNode)); setNodes((nds) => nds.concat(newNode));
}, [setElements]); }, [setNodes]);
return ( return (
<div className="save__controls"> <div className="save__controls">
+46
View File
@@ -0,0 +1,46 @@
import { useState } from 'react';
import ReactFlow, {
ReactFlowProvider,
Node,
addEdge,
Connection,
Edge,
ReactFlowInstance,
useNodesState,
useEdgesState,
} from 'react-flow-renderer';
import Controls from './Controls';
import './save.css';
const initialNodes: Node[] = [
{ id: '1', data: { label: 'Node 1' }, position: { x: 100, y: 100 } },
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 200 } },
];
const initialEdges: Edge[] = [{ id: 'e1-2', source: '1', target: '2' }];
const SaveRestore = () => {
const [rfInstance, setRfInstance] = useState<ReactFlowInstance>();
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds));
return (
<ReactFlowProvider>
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
onPaneReady={setRfInstance}
>
<Controls rfInstance={rfInstance} setNodes={setNodes} setEdges={setEdges} />
</ReactFlow>
</ReactFlowProvider>
);
};
export default SaveRestore;
@@ -1,26 +1,30 @@
import React, { useState, MouseEvent } from 'react'; import { MouseEvent } from 'react';
import ReactFlow, { addEdge, Node, Connection, Edge, useNodesState, useEdgesState } from 'react-flow-renderer';
import ReactFlow, { removeElements, addEdge, Node, FlowElement, Elements, Connection, Edge } from 'react-flow-renderer';
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node); const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element); const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node);
const elementsA: Elements = [ const nodesA: Node[] = [
{ id: '1a', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, className: 'light' }, { id: '1a', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, className: 'light' },
{ id: '2a', data: { label: 'Node 2' }, position: { x: 100, y: 100 }, className: 'light' }, { id: '2a', data: { label: 'Node 2' }, position: { x: 100, y: 100 }, className: 'light' },
{ id: '3a', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, className: 'light' }, { id: '3a', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, className: 'light' },
{ id: '4a', data: { label: 'Node 4' }, position: { x: 400, y: 200 }, className: 'light' }, { id: '4a', data: { label: 'Node 4' }, position: { x: 400, y: 200 }, className: 'light' },
];
const edgesA: Edge[] = [
{ id: 'e1-2', source: '1a', target: '2a' }, { id: 'e1-2', source: '1a', target: '2a' },
{ id: 'e1-3', source: '1a', target: '3a' }, { id: 'e1-3', source: '1a', target: '3a' },
]; ];
const elementsB: Elements = [ const nodesB: Node[] = [
{ id: 'inputb', type: 'input', data: { label: 'Input' }, position: { x: 300, y: 5 }, className: 'light' }, { id: 'inputb', type: 'input', data: { label: 'Input' }, position: { x: 300, y: 5 }, className: 'light' },
{ id: '1b', data: { label: 'Node 1' }, position: { x: 0, y: 100 }, className: 'light' }, { id: '1b', data: { label: 'Node 1' }, position: { x: 0, y: 100 }, className: 'light' },
{ id: '2b', data: { label: 'Node 2' }, position: { x: 200, y: 100 }, className: 'light' }, { id: '2b', data: { label: 'Node 2' }, position: { x: 200, y: 100 }, className: 'light' },
{ id: '3b', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, className: 'light' }, { id: '3b', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, className: 'light' },
{ id: '4b', data: { label: 'Node 4' }, position: { x: 600, y: 100 }, className: 'light' }, { id: '4b', data: { label: 'Node 4' }, position: { x: 600, y: 100 }, className: 'light' },
];
const edgesB: Edge[] = [
{ id: 'e1b', source: 'inputb', target: '1b' }, { id: 'e1b', source: 'inputb', target: '1b' },
{ id: 'e2b', source: 'inputb', target: '2b' }, { id: 'e2b', source: 'inputb', target: '2b' },
{ id: 'e3b', source: 'inputb', target: '3b' }, { id: 'e3b', source: 'inputb', target: '3b' },
@@ -28,23 +32,39 @@ const elementsB: Elements = [
]; ];
const BasicFlow = () => { const BasicFlow = () => {
const [elements, setElements] = useState<Elements>(elementsA); const [nodes, setNodes, onNodesChange] = useNodesState(nodesA);
const onElementsRemove = (elementsToRemove: Elements) => setElements((els) => removeElements(elementsToRemove, els)); const [edges, setEdges, onEdgesChange] = useEdgesState(edgesA);
const onConnect = (params: Connection | Edge) => setElements((els) => addEdge(params, els));
const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds));
return ( return (
<ReactFlow <ReactFlow
elements={elements} nodes={nodes}
onElementClick={onElementClick} edges={edges}
onElementsRemove={onElementsRemove} onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onNodeClick={onNodeClick}
onConnect={onConnect} onConnect={onConnect}
onNodeDragStop={onNodeDragStop} onNodeDragStop={onNodeDragStop}
> >
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}> <div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
<button onClick={() => setElements(elementsA)} style={{ marginRight: 5 }}> <button
onClick={() => {
setNodes(nodesA);
setEdges(edgesA);
}}
style={{ marginRight: 5 }}
>
flow a flow a
</button> </button>
<button onClick={() => setElements(elementsB)}>flow b</button> <button
onClick={() => {
setNodes(nodesB);
setEdges(edgesB);
}}
>
flow b
</button>
</div> </div>
</ReactFlow> </ReactFlow>
); );
+1 -1
View File
@@ -31,7 +31,7 @@ const initialNodes: Node[] = [
const initialEdges: Edge[] = []; const initialEdges: Edge[] = [];
const TouchDeviceFlow = () => { const TouchDeviceFlow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const [nodes, , onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = useCallback((connection: Connection) => setEdges((eds) => addEdge(connection, eds)), []); const onConnect = useCallback((connection: Connection) => setEdges((eds) => addEdge(connection, eds)), []);
@@ -1,5 +1,4 @@
import React, { memo, FC, useMemo, CSSProperties } from 'react'; import React, { memo, FC, useMemo, CSSProperties } from 'react';
import { Handle, Position, NodeProps } from 'react-flow-renderer'; import { Handle, Position, NodeProps } from 'react-flow-renderer';
const nodeStyles: CSSProperties = { padding: 10, border: '1px solid #ddd' }; const nodeStyles: CSSProperties = { padding: 10, border: '1px solid #ddd' };
@@ -1,23 +1,23 @@
import React, { useState, useCallback, CSSProperties } from 'react'; import { useCallback, CSSProperties } from 'react';
import ReactFlow, { import ReactFlow, {
NodeTypesType, NodeTypesType,
addEdge, addEdge,
useZoomPanHelper, useZoomPanHelper,
ReactFlowProvider, ReactFlowProvider,
Elements, Node,
Connection, Connection,
Edge, Edge,
ElementId,
useUpdateNodeInternals, useUpdateNodeInternals,
Position, Position,
isEdge, useNodesState,
useEdgesState,
} from 'react-flow-renderer'; } from 'react-flow-renderer';
import CustomNode from './CustomNode'; import CustomNode from './CustomNode';
const initialHandleCount = 1; const initialHandleCount = 1;
const initialElements: Elements = [ const initialNodes: Node[] = [
{ {
id: '1', id: '1',
type: 'custom', type: 'custom',
@@ -33,18 +33,20 @@ const nodeTypes: NodeTypesType = {
}; };
let id = 5; let id = 5;
const getId = (): ElementId => `${id++}`; const getId = (): string => `${id++}`;
const UpdateNodeInternalsFlow = () => { const UpdateNodeInternalsFlow = () => {
const [elements, setElements] = useState<Elements>(initialElements); const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
const onConnect = (params: Edge | Connection) => setEdges((els) => addEdge(params, els));
const updateNodeInternals = useUpdateNodeInternals(); const updateNodeInternals = useUpdateNodeInternals();
const onConnect = (params: Connection | Edge) => setElements((els) => addEdge(params, els));
const { project } = useZoomPanHelper(); const { project } = useZoomPanHelper();
const onPaneClick = useCallback( const onPaneClick = useCallback(
(evt) => (evt) =>
setElements((els) => setNodes((nds) =>
els.concat({ nds.concat({
id: getId(), id: getId(),
position: project({ x: evt.clientX, y: evt.clientY - 40 }), position: project({ x: evt.clientX, y: evt.clientY - 40 }),
data: { label: 'new node' }, data: { label: 'new node' },
@@ -56,25 +58,17 @@ const UpdateNodeInternalsFlow = () => {
); );
const toggleHandleCount = useCallback(() => { const toggleHandleCount = useCallback(() => {
setElements((els) => setNodes((nds) =>
els.map((el) => { nds.map((node) => {
if (isEdge(el)) { return { ...node, data: { ...node.data, handleCount: node.data?.handleCount === 1 ? 2 : 1 } };
return el;
}
return { ...el, data: { ...el.data, handleCount: el.data?.handleCount === 1 ? 2 : 1 } };
}) })
); );
}, []); }, []);
const toggleHandlePosition = useCallback(() => { const toggleHandlePosition = useCallback(() => {
setElements((els) => setNodes((nds) =>
els.map((el) => { nds.map((node) => {
if (isEdge(el)) { return { ...node, data: { ...node.data, handlePosition: node.data?.handlePosition === 0 ? 1 : 0 } };
return el;
}
return { ...el, data: { ...el.data, handlePosition: el.data?.handlePosition === 0 ? 1 : 0 } };
}) })
); );
}, []); }, []);
@@ -82,7 +76,15 @@ const UpdateNodeInternalsFlow = () => {
const updateNode = useCallback(() => updateNodeInternals('1'), [updateNodeInternals]); const updateNode = useCallback(() => updateNodeInternals('1'), [updateNodeInternals]);
return ( return (
<ReactFlow elements={elements} nodeTypes={nodeTypes} onConnect={onConnect} onPaneClick={onPaneClick}> <ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
nodeTypes={nodeTypes}
onConnect={onConnect}
onPaneClick={onPaneClick}
>
<div style={buttonWrapperStyles}> <div style={buttonWrapperStyles}>
<button onClick={toggleHandleCount}>toggle handle count</button> <button onClick={toggleHandleCount}>toggle handle count</button>
<button onClick={toggleHandlePosition}>toggle handle position</button> <button onClick={toggleHandlePosition}>toggle handle position</button>
@@ -1,27 +1,27 @@
import React, { useState, MouseEvent as ReactMouseEvent, FC } from 'react'; import { MouseEvent as ReactMouseEvent, FC } from 'react';
import ReactFlow, { import ReactFlow, {
addEdge, addEdge,
Handle, Handle,
OnLoadParams,
Connection, Connection,
Position, Position,
Elements, Node,
Edge, Edge,
OnConnectStartParams, OnConnectStartParams,
NodeProps, NodeProps,
NodeTypesType, NodeTypesType,
useNodesState,
useEdgesState,
} from 'react-flow-renderer'; } from 'react-flow-renderer';
import './validation.css'; import './validation.css';
const initialElements: Elements = [ const initialNodes: Node[] = [
{ id: '0', type: 'custominput', position: { x: 0, y: 150 } }, { id: '0', type: 'custominput', position: { x: 0, y: 150 }, data: null },
{ id: 'A', type: 'customnode', position: { x: 250, y: 0 } }, { id: 'A', type: 'customnode', position: { x: 250, y: 0 }, data: null },
{ id: 'B', type: 'customnode', position: { x: 250, y: 150 } }, { id: 'B', type: 'customnode', position: { x: 250, y: 150 }, data: null },
{ id: 'C', type: 'customnode', position: { x: 250, y: 300 } }, { id: 'C', type: 'customnode', position: { x: 250, y: 300 }, data: null },
]; ];
const onLoad = (reactFlowInstance: OnLoadParams) => reactFlowInstance.fitView();
const isValidConnection = (connection: Connection) => connection.target === 'B'; const isValidConnection = (connection: Connection) => connection.target === 'B';
const onConnectStart = (_: ReactMouseEvent, { nodeId, handleType }: OnConnectStartParams) => const onConnectStart = (_: ReactMouseEvent, { nodeId, handleType }: OnConnectStartParams) =>
console.log('on connect start', { nodeId, handleType }); console.log('on connect start', { nodeId, handleType });
@@ -48,26 +48,31 @@ const nodeTypes: NodeTypesType = {
customnode: CustomNode, customnode: CustomNode,
}; };
const HorizontalFlow = () => { const ValidationFlow = () => {
const [elements, setElements] = useState<Elements>(initialElements); const [nodes, , onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
const onConnect = (params: Connection | Edge) => { const onConnect = (params: Connection | Edge) => {
console.log('on connect', params); console.log('on connect', params);
setElements((els) => addEdge(params, els)); setEdges((eds) => addEdge(params, eds));
}; };
return ( return (
<ReactFlow <ReactFlow
elements={elements} nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect} onConnect={onConnect}
selectNodesOnDrag={false} selectNodesOnDrag={false}
onLoad={onLoad}
className="validationflow" className="validationflow"
nodeTypes={nodeTypes} nodeTypes={nodeTypes}
onConnectStart={onConnectStart} onConnectStart={onConnectStart}
onConnectStop={onConnectStop} onConnectStop={onConnectStop}
onConnectEnd={onConnectEnd} onConnectEnd={onConnectEnd}
fitViewOnInit
/> />
); );
}; };
export default HorizontalFlow; export default ValidationFlow;
+86 -36
View File
@@ -21,6 +21,16 @@ import Undirectional from './Undirectional';
import Provider from './Provider'; import Provider from './Provider';
import CustomConnectionLine from './CustomConnectionLine'; import CustomConnectionLine from './CustomConnectionLine';
import UseZoomPanHelper from './UseZoomPanHelper'; import UseZoomPanHelper from './UseZoomPanHelper';
import DragNDrop from './DragNDrop';
import UseUpdateNodeInternals from './UseUpdateNodeInternals';
import Edges from './Edges';
import EdgeTypes from './EdgeTypes';
import MultiFlows from './MultiFlows';
import NodeTypeChange from './NodeTypeChange';
import NodeTypesObjectChange from './NodeTypesObjectChange';
import SaveRestore from './SaveRestore';
import SwitchFlow from './Switch';
import Validation from './Validation';
import './index.css'; import './index.css';
@@ -34,73 +44,113 @@ const routes = [
component: Basic, component: Basic,
}, },
{ {
path: '/update-node', path: '/custom-connectionline',
component: UpdateNode, component: CustomConnectionLine,
},
{
path: '/stress',
component: Stress,
}, },
{ {
path: '/custom-node', path: '/custom-node',
component: CustomNode, component: CustomNode,
}, },
{ {
path: '/floating-edges', path: '/draghandle',
component: FloatingEdges, component: DragHandle,
}, },
{ {
path: '/layouting', path: '/dragndrop',
component: Layouting, component: DragNDrop,
}, },
{ {
path: '/nested-nodes', path: '/edges',
component: NestedNodes, component: Edges,
}, },
{ {
path: '/hidden', path: '/edge-types',
component: Hidden, component: EdgeTypes,
},
{
path: '/updatable-edge',
component: UpdatableEdge,
},
{
path: '/touch-device',
component: TouchDevice,
},
{
path: '/subflow',
component: Subflow,
},
{
path: '/interaction',
component: Interaction,
}, },
{ {
path: '/empty', path: '/empty',
component: Empty, component: Empty,
}, },
{ {
path: '/draghandle', path: '/floating-edges',
component: DragHandle, component: FloatingEdges,
}, },
{ {
path: '/undirectional', path: '/hidden',
component: Undirectional, component: Hidden,
},
{
path: '/interaction',
component: Interaction,
},
{
path: '/layouting',
component: Layouting,
},
{
path: '/multiflows',
component: MultiFlows,
},
{
path: '/nested-nodes',
component: NestedNodes,
},
{
path: '/nodetype-change',
component: NodeTypeChange,
},
{
path: '/nodetypesobject-change',
component: NodeTypesObjectChange,
}, },
{ {
path: '/provider', path: '/provider',
component: Provider, component: Provider,
}, },
{ {
path: '/custom-connectionline', path: '/save-restore',
component: CustomConnectionLine, component: SaveRestore,
},
{
path: '/stress',
component: Stress,
},
{
path: '/subflow',
component: Subflow,
},
{
path: '/switch',
component: SwitchFlow,
},
{
path: '/touch-device',
component: TouchDevice,
},
{
path: '/undirectional',
component: Undirectional,
},
{
path: '/updatable-edge',
component: UpdatableEdge,
},
{
path: '/update-node',
component: UpdateNode,
}, },
{ {
path: '/usezoompanhelper', path: '/usezoompanhelper',
component: UseZoomPanHelper, component: UseZoomPanHelper,
}, },
{
path: '/useupdatenodeinternals',
component: UseUpdateNodeInternals,
},
{
path: '/validation',
component: Validation,
},
]; ];
const Header = withRouter(({ history, location }) => { const Header = withRouter(({ history, location }) => {
@@ -1,55 +0,0 @@
import React, { useState, CSSProperties } from 'react';
import ReactFlow, { addEdge, isEdge, OnLoadParams, Elements, Position, Connection, Edge } from 'react-flow-renderer';
const onLoad = (reactFlowInstance: OnLoadParams) => reactFlowInstance.fitView();
const initialElements: Elements = [
{
id: '1',
sourcePosition: Position.Right,
type: 'input',
data: { label: 'Input' },
position: { x: 0, y: 80 },
},
{
id: '2',
type: 'output',
sourcePosition: Position.Right,
targetPosition: Position.Left,
data: { label: 'A Node' },
position: { x: 250, y: 0 },
},
{ id: 'e1-2', source: '1', type: 'smoothstep', target: '2', animated: true },
];
const buttonStyle: CSSProperties = { position: 'absolute', right: 10, top: 30, zIndex: 4 };
const NodeTypeChangeFlow = () => {
const [elements, setElements] = useState<Elements>(initialElements);
const onConnect = (params: Connection | Edge) => setElements((els) => addEdge(params, els));
const changeType = () => {
setElements((elms) =>
elms.map((el) => {
if (isEdge(el) || el.type === 'input') {
return el;
}
return {
...el,
type: el.type === 'default' ? 'output' : 'default',
};
})
);
};
return (
<ReactFlow elements={elements} onConnect={onConnect} onLoad={onLoad}>
<button onClick={changeType} style={buttonStyle}>
change type
</button>
</ReactFlow>
);
};
export default NodeTypeChangeFlow;
-37
View File
@@ -1,37 +0,0 @@
import React, { useState } from 'react';
import ReactFlow, {
ReactFlowProvider,
removeElements,
addEdge,
Elements,
Connection,
Edge,
OnLoadParams,
} from 'react-flow-renderer';
import Controls from './Controls';
import './save.css';
const initialElements: Elements = [
{ id: '1', data: { label: 'Node 1' }, position: { x: 100, y: 100 } },
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 200 } },
{ id: 'e1-2', source: '1', target: '2' },
];
const SaveRestore = () => {
const [rfInstance, setRfInstance] = useState<OnLoadParams>();
const [elements, setElements] = useState<Elements>(initialElements);
const onElementsRemove = (elementsToRemove: Elements) => setElements((els) => removeElements(elementsToRemove, els));
const onConnect = (params: Connection | Edge) => setElements((els) => addEdge(params, els));
return (
<ReactFlowProvider>
<ReactFlow elements={elements} onElementsRemove={onElementsRemove} onConnect={onConnect} onLoad={setRfInstance}>
<Controls rfInstance={rfInstance} setElements={setElements} />
</ReactFlow>
</ReactFlowProvider>
);
};
export default SaveRestore;
-82
View File
@@ -1,82 +0,0 @@
body {
font-family: sans-serif;
color: #111;
}
html,
body,
#root {
margin: 0;
height: 100%;
}
#root {
display: flex;
flex-direction: column;
}
header {
padding: 10px;
border-bottom: 1px solid #eee;
display: flex;
font-weight: 700;
align-items: center;
}
.logo {
text-decoration: none;
display: block;
line-height: 1;
}
header a,
header a:focus,
header a:active,
header a:visited {
color: #111;
}
header a:hover {
color: #333;
}
header select {
margin-left: 1em;
}
.overview-example__add {
display: none;
}
.react-flow__node a {
font-weight: 700;
color: #111;
}
.react-flow__node.dark-node {
background: #0041d0;
color: #f8f8f8;
}
.react-flow__node.dark {
background: #557;
color: #f8f8f8;
}
.react-flow__node-selectorNode {
font-size: 12px;
background: #f0f2f3;
border: 1px solid 555;
border-radius: 5px;
text-align: center;
}
.react-flow__node-selectorNode .react-flow__handle {
border-color: #f0f2f3;
}
@media screen and (min-width: 768px) {
.overview-example__add {
display: block;
}
}
-165
View File
@@ -1,165 +0,0 @@
import React, { ChangeEvent } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, Switch, withRouter } from 'react-router-dom';
import Overview from './Overview';
import Basic from './Basic';
import CustomNode from './CustomNode';
import Stress from './Stress';
import Interaction from './Interaction';
import Empty from './Empty';
import Edges from './Edges';
import Validation from './Validation';
import Provider from './Provider';
import Hidden from './Hidden';
import EdgeTypes from './EdgeTypes';
import CustomConnectionLine from './CustomConnectionLine';
import NodeTypeChange from './NodeTypeChange';
import NodeTypesObjectChange from './NodeTypesObjectChange';
import UpdatableEdge from './UpdatableEdge';
import UpdateNode from './UpdateNode';
import SaveRestore from './SaveRestore';
import DragNDrop from './DragNDrop';
import Layout from './Layouting';
import SwitchFlows from './Switch';
import UseZoomPanHelper from './UseZoomPanHelper';
import UseUpdateNodeInternals from './UseUpdateNodeInternals';
import Undirectional from './Undirectional';
import MultiFlows from './MultiFlows';
import DragHandle from './DragHandle';
import './index.css';
const routes = [
{
path: '/',
component: Overview,
},
{
path: '/edges',
component: Edges,
},
{
path: '/custom-node',
component: CustomNode,
},
{
path: '/validation',
component: Validation,
},
{
path: '/provider',
component: Provider,
},
{
path: '/stress',
component: Stress,
},
{
path: '/interaction',
component: Interaction,
},
{
path: '/basic',
component: Basic,
},
{
path: '/empty',
component: Empty,
},
{
path: '/hidden',
component: Hidden,
},
{
path: '/edge-types',
component: EdgeTypes,
},
{
path: '/custom-connectionline',
component: CustomConnectionLine,
},
{
path: '/nodetype-change',
component: NodeTypeChange,
},
{
path: '/nodetypesobject-change',
component: NodeTypesObjectChange,
},
{
path: '/updatable-edge',
component: UpdatableEdge,
},
{
path: '/update-node',
component: UpdateNode,
},
{
path: '/save-restore',
component: SaveRestore,
},
{
path: '/drag-and-drop',
component: DragNDrop,
},
{
path: '/layouting',
component: Layout,
},
{
path: '/switch',
component: SwitchFlows,
},
{
path: '/usezoompanhelper',
component: UseZoomPanHelper,
},
{
path: '/useupdatenodeinternals',
component: UseUpdateNodeInternals,
},
{
path: '/undirectional',
component: Undirectional,
},
{
path: '/multiflows',
component: MultiFlows,
},
{
path: '/draghandle',
component: DragHandle,
},
];
const Header = withRouter(({ history, location }) => {
const onChange = (event: ChangeEvent<HTMLSelectElement>) => history.push(event.target.value);
return (
<header>
<a className="logo" href="https://github.com/wbkd/react-flow">
React Flow Dev
</a>
<select defaultValue={location.pathname} onChange={onChange}>
{routes.map((route) => (
<option value={route.path} key={route.path}>
{route.path === '/' ? 'overview' : route.path.substr(1, route.path.length)}
</option>
))}
</select>
</header>
);
});
ReactDOM.render(
<Router forceRefresh={true}>
<Header />
<Switch>
{routes.map((route) => (
<Route exact path={route.path} render={() => <route.component />} key={route.path} />
))}
</Switch>
</Router>,
document.getElementById('root')
);
-1
View File
@@ -1 +0,0 @@
/// <reference types="react-scripts" />
-4
View File
@@ -7,10 +7,6 @@ import { Node, NodeInternals, NodeDimensionUpdate, NodeDiffUpdate } from './node
import { Edge } from './edges'; import { Edge } from './edges';
import { HandleType, StartHandle } from './handles'; import { HandleType, StartHandle } from './handles';
export type FlowElement<T = any> = Node<T> | Edge<T>;
export type Elements<T = any> = Array<FlowElement<T>>;
export type NodeTypesType = { [key: string]: ReactNode }; export type NodeTypesType = { [key: string]: ReactNode };
export type EdgeTypesType = NodeTypesType; export type EdgeTypesType = NodeTypesType;