chore(examples): use new api
This commit is contained in:
@@ -4,7 +4,6 @@ import ReactFlow, {
|
||||
addEdge,
|
||||
Background,
|
||||
BackgroundVariant,
|
||||
FlowElement,
|
||||
Node,
|
||||
Edge,
|
||||
Connection,
|
||||
@@ -14,7 +13,7 @@ import ReactFlow, {
|
||||
} from 'react-flow-renderer';
|
||||
|
||||
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[] = [
|
||||
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, className: 'light' },
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import React, { DragEvent } from 'react';
|
||||
|
||||
const onDragStart = (event: DragEvent, nodeType: string) => {
|
||||
event.dataTransfer.setData('application/reactflow', nodeType);
|
||||
event.dataTransfer.effectAllowed = 'move';
|
||||
};
|
||||
|
||||
const Sidebar = () => {
|
||||
return (
|
||||
<aside>
|
||||
<div className="description">You can drag these nodes to the pane on the left.</div>
|
||||
<div className="react-flow__node-input" onDragStart={(event: DragEvent) => onDragStart(event, 'input')} draggable>
|
||||
Input Node
|
||||
</div>
|
||||
<div className="react-flow__node-default" onDragStart={(event: DragEvent) => onDragStart(event, 'default')} draggable>
|
||||
Default Node
|
||||
</div>
|
||||
<div className="react-flow__node-output" onDragStart={(event: DragEvent) => onDragStart(event, 'output')} draggable>
|
||||
Output Node
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
};
|
||||
|
||||
export default Sidebar;
|
||||
@@ -0,0 +1,37 @@
|
||||
.dndflow {
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.dndflow aside {
|
||||
border-right: 1px solid #eee;
|
||||
padding: 15px 10px;
|
||||
font-size: 12px;
|
||||
background: #fcfcfc;
|
||||
}
|
||||
|
||||
.dndflow aside > * {
|
||||
margin-bottom: 10px;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.dndflow aside .description {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.dndflow .reactflow-wrapper {
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.dndflow {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.dndflow aside {
|
||||
width: 20%;
|
||||
max-width: 180px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import { useState, DragEvent } from 'react';
|
||||
import ReactFlow, {
|
||||
ReactFlowProvider,
|
||||
addEdge,
|
||||
Controls,
|
||||
ReactFlowInstance,
|
||||
Connection,
|
||||
Edge,
|
||||
Node,
|
||||
useNodesState,
|
||||
useEdgesState,
|
||||
} from 'react-flow-renderer';
|
||||
|
||||
import Sidebar from './Sidebar';
|
||||
|
||||
import './dnd.css';
|
||||
|
||||
const initialNodes: Node[] = [{ id: '1', type: 'input', data: { label: 'input node' }, position: { x: 250, y: 5 } }];
|
||||
|
||||
const onDragOver = (event: DragEvent) => {
|
||||
event.preventDefault();
|
||||
event.dataTransfer.dropEffect = 'move';
|
||||
};
|
||||
|
||||
let id = 0;
|
||||
const getId = () => `dndnode_${id++}`;
|
||||
|
||||
const DnDFlow = () => {
|
||||
const [reactFlowInstance, setReactFlowInstance] = useState<ReactFlowInstance>();
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
||||
|
||||
const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds));
|
||||
const onPaneReady = (rfi: ReactFlowInstance) => setReactFlowInstance(rfi);
|
||||
|
||||
const onDrop = (event: DragEvent) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (reactFlowInstance) {
|
||||
const type = event.dataTransfer.getData('application/reactflow');
|
||||
const position = reactFlowInstance.project({ x: event.clientX, y: event.clientY - 40 });
|
||||
const newNode: Node = {
|
||||
id: getId(),
|
||||
type,
|
||||
position,
|
||||
data: { label: `${type} node` },
|
||||
};
|
||||
|
||||
setNodes((nds) => nds.concat(newNode));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="dndflow">
|
||||
<ReactFlowProvider>
|
||||
<div className="reactflow-wrapper">
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onEdgesChange={onEdgesChange}
|
||||
onNodesChange={onNodesChange}
|
||||
onConnect={onConnect}
|
||||
onPaneReady={onPaneReady}
|
||||
onDrop={onDrop}
|
||||
onDragOver={onDragOver}
|
||||
>
|
||||
<Controls />
|
||||
</ReactFlow>
|
||||
</div>
|
||||
<Sidebar />
|
||||
</ReactFlowProvider>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DnDFlow;
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Example for checking the different edge types and source and target positions
|
||||
*/
|
||||
|
||||
import ReactFlow, {
|
||||
addEdge,
|
||||
MiniMap,
|
||||
Controls,
|
||||
Background,
|
||||
ReactFlowInstance,
|
||||
Connection,
|
||||
Edge,
|
||||
useNodesState,
|
||||
useEdgesState,
|
||||
} from 'react-flow-renderer';
|
||||
import { getElements } from './utils';
|
||||
|
||||
const onPaneReady = (reactFlowInstance: ReactFlowInstance) => {
|
||||
reactFlowInstance.fitView();
|
||||
console.log(reactFlowInstance.getNodes());
|
||||
};
|
||||
|
||||
const { nodes: initialNodes, edges: initialEdges } = getElements();
|
||||
|
||||
const multiSelectionKeyCode = ['ShiftLeft', 'ShiftRight'];
|
||||
const deleteKeyCode = ['AltLeft+KeyD', 'Backspace'];
|
||||
|
||||
const EdgeTypesFlow = () => {
|
||||
const [nodes, , onNodesChange] = useNodesState(initialNodes);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||
const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds));
|
||||
|
||||
return (
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
onPaneReady={onPaneReady}
|
||||
onConnect={onConnect}
|
||||
minZoom={0.2}
|
||||
zoomOnScroll={false}
|
||||
selectionKeyCode="a+s"
|
||||
multiSelectionKeyCode={multiSelectionKeyCode}
|
||||
deleteKeyCode={deleteKeyCode}
|
||||
zoomActivationKeyCode="z"
|
||||
>
|
||||
<MiniMap />
|
||||
<Controls />
|
||||
<Background />
|
||||
</ReactFlow>
|
||||
);
|
||||
};
|
||||
|
||||
export default EdgeTypesFlow;
|
||||
@@ -0,0 +1,111 @@
|
||||
import { Node, Edge, Position } from 'react-flow-renderer';
|
||||
|
||||
const nodeWidth = 80;
|
||||
const nodeGapWidth = nodeWidth * 2;
|
||||
const nodeStyle = { width: nodeWidth, fontSize: 11, color: 'white' };
|
||||
|
||||
const sourceTargetPositions = [
|
||||
{ source: Position.Bottom, target: Position.Top },
|
||||
{ source: Position.Right, target: Position.Left },
|
||||
];
|
||||
const nodeColors = [
|
||||
['#1e9e99', '#4cb3ac', '#6ec9c0', '#8ddfd4'],
|
||||
['#0f4c75', '#1b5d8b', '#276fa1', '#3282b8'],
|
||||
];
|
||||
const edgeTypes = ['default', 'step', 'smoothstep', 'straight'];
|
||||
const offsets = [
|
||||
{
|
||||
x: 0,
|
||||
y: -nodeGapWidth,
|
||||
},
|
||||
{
|
||||
x: nodeGapWidth,
|
||||
y: -nodeGapWidth,
|
||||
},
|
||||
{
|
||||
x: nodeGapWidth,
|
||||
y: 0,
|
||||
},
|
||||
{
|
||||
x: nodeGapWidth,
|
||||
y: nodeGapWidth,
|
||||
},
|
||||
{
|
||||
x: 0,
|
||||
y: nodeGapWidth,
|
||||
},
|
||||
{
|
||||
x: -nodeGapWidth,
|
||||
y: nodeGapWidth,
|
||||
},
|
||||
{
|
||||
x: -nodeGapWidth,
|
||||
y: 0,
|
||||
},
|
||||
{
|
||||
x: -nodeGapWidth,
|
||||
y: -nodeGapWidth,
|
||||
},
|
||||
];
|
||||
|
||||
let id = 0;
|
||||
const getNodeId = (): string => (id++).toString();
|
||||
|
||||
export function getElements(): { nodes: Node[]; edges: Edge[] } {
|
||||
const initialElements = { nodes: [] as Node[], edges: [] as Edge[] };
|
||||
|
||||
for (let sourceTargetIndex = 0; sourceTargetIndex < sourceTargetPositions.length; sourceTargetIndex++) {
|
||||
const currSourceTargetPos = sourceTargetPositions[sourceTargetIndex];
|
||||
|
||||
for (let edgeTypeIndex = 0; edgeTypeIndex < edgeTypes.length; edgeTypeIndex++) {
|
||||
const currEdgeType = edgeTypes[edgeTypeIndex];
|
||||
|
||||
for (let offsetIndex = 0; offsetIndex < offsets.length; offsetIndex++) {
|
||||
const currOffset = offsets[offsetIndex];
|
||||
|
||||
const style = { ...nodeStyle, background: nodeColors[sourceTargetIndex][edgeTypeIndex] };
|
||||
const sourcePosition = {
|
||||
x: offsetIndex * nodeWidth * 4,
|
||||
y: edgeTypeIndex * 300 + sourceTargetIndex * edgeTypes.length * 300,
|
||||
};
|
||||
const sourceId = getNodeId();
|
||||
const sourceData = { label: `Source ${sourceId}` };
|
||||
const sourceNode: Node = {
|
||||
id: sourceId,
|
||||
style,
|
||||
data: sourceData,
|
||||
position: sourcePosition,
|
||||
sourcePosition: currSourceTargetPos.source,
|
||||
targetPosition: currSourceTargetPos.target,
|
||||
};
|
||||
|
||||
const targetId = getNodeId();
|
||||
const targetData = { label: `Target ${targetId}` };
|
||||
const targetPosition = {
|
||||
x: sourcePosition.x + currOffset.x,
|
||||
y: sourcePosition.y + currOffset.y,
|
||||
};
|
||||
const targetNode: Node = {
|
||||
id: targetId,
|
||||
style,
|
||||
data: targetData,
|
||||
position: targetPosition,
|
||||
sourcePosition: currSourceTargetPos.source,
|
||||
targetPosition: currSourceTargetPos.target,
|
||||
};
|
||||
|
||||
initialElements.nodes.push(sourceNode);
|
||||
initialElements.nodes.push(targetNode);
|
||||
|
||||
initialElements.edges.push({
|
||||
id: `${sourceId}-${targetId}`,
|
||||
source: sourceId,
|
||||
target: targetId,
|
||||
type: currEdgeType,
|
||||
} as Edge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return initialElements;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { FC } from 'react';
|
||||
import { EdgeProps, getBezierPath } from 'react-flow-renderer';
|
||||
|
||||
const CustomEdge: FC<EdgeProps> = ({
|
||||
id,
|
||||
sourceX,
|
||||
sourceY,
|
||||
targetX,
|
||||
targetY,
|
||||
sourcePosition,
|
||||
targetPosition,
|
||||
data,
|
||||
}) => {
|
||||
const edgePath = getBezierPath({ sourceX, sourceY, sourcePosition, targetX, targetY, targetPosition });
|
||||
|
||||
return (
|
||||
<>
|
||||
<path id={id} className="react-flow__edge-path" d={edgePath} />
|
||||
<text>
|
||||
<textPath href={`#${id}`} style={{ fontSize: '12px' }} startOffset="50%" textAnchor="middle">
|
||||
{data.text}
|
||||
</textPath>
|
||||
</text>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomEdge;
|
||||
@@ -0,0 +1,41 @@
|
||||
import { FC } from 'react';
|
||||
import { EdgeProps, getBezierPath, EdgeText, getEdgeCenter } from 'react-flow-renderer';
|
||||
|
||||
const CustomEdge: FC<EdgeProps> = ({
|
||||
id,
|
||||
sourceX,
|
||||
sourceY,
|
||||
targetX,
|
||||
targetY,
|
||||
sourcePosition,
|
||||
targetPosition,
|
||||
data,
|
||||
}) => {
|
||||
const edgePath = getBezierPath({ sourceX, sourceY, sourcePosition, targetX, targetY, targetPosition });
|
||||
const [centerX, centerY] = getEdgeCenter({
|
||||
sourceX,
|
||||
sourceY,
|
||||
targetX,
|
||||
targetY,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<path id={id} className="react-flow__edge-path" d={edgePath} />
|
||||
<EdgeText
|
||||
x={centerX}
|
||||
y={centerY}
|
||||
label={data.text}
|
||||
labelStyle={{ fill: 'white' }}
|
||||
labelShowBg
|
||||
labelBgStyle={{ fill: 'red' }}
|
||||
labelBgPadding={[2, 4]}
|
||||
labelBgBorderRadius={2}
|
||||
onClick={() => console.log(data)}
|
||||
/>
|
||||
;
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomEdge;
|
||||
@@ -0,0 +1,135 @@
|
||||
import { MouseEvent } from 'react';
|
||||
|
||||
import ReactFlow, {
|
||||
addEdge,
|
||||
MiniMap,
|
||||
Controls,
|
||||
Background,
|
||||
ReactFlowInstance,
|
||||
EdgeTypesType,
|
||||
Connection,
|
||||
Edge,
|
||||
MarkerType,
|
||||
Node,
|
||||
useNodesState,
|
||||
useEdgesState,
|
||||
} from 'react-flow-renderer';
|
||||
|
||||
import CustomEdge from './CustomEdge';
|
||||
import CustomEdge2 from './CustomEdge2';
|
||||
|
||||
const onPaneReady = (reactFlowInstance: ReactFlowInstance) => reactFlowInstance.fitView();
|
||||
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
|
||||
const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node);
|
||||
|
||||
const initialNodes: Node[] = [
|
||||
{ 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: '2a', data: { label: 'Node 2a' }, position: { x: 0, y: 180 } },
|
||||
{ id: '3', data: { label: 'Node 3' }, position: { x: 250, y: 200 } },
|
||||
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 300 } },
|
||||
{ id: '3a', data: { label: 'Node 3a' }, position: { x: 150, y: 300 } },
|
||||
{ id: '5', data: { label: 'Node 5' }, position: { x: 250, y: 400 } },
|
||||
{ id: '6', type: 'output', data: { label: 'Output 6' }, position: { x: 50, 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: '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: 'e2-2a', source: '2', target: '2a', type: 'smoothstep', label: 'smoothstep edge' },
|
||||
{ id: 'e2-3', source: '2', target: '3', type: 'step', label: 'step edge' },
|
||||
{ id: 'e3-4', source: '3', target: '4', type: 'straight', label: 'straight edge' },
|
||||
{ id: 'e3-3a', source: '3', target: '3a', type: 'straight', label: 'label only edge', style: { stroke: 'none' } },
|
||||
{ id: 'e3-5', source: '4', target: '5', animated: true, label: 'animated styled edge', style: { stroke: 'red' } },
|
||||
{
|
||||
id: 'e5-7',
|
||||
source: '5',
|
||||
target: '7',
|
||||
label: 'label with styled bg',
|
||||
labelBgPadding: [8, 4],
|
||||
labelBgBorderRadius: 4,
|
||||
labelBgStyle: { fill: '#FFCC00', color: '#fff', fillOpacity: 0.7 },
|
||||
markerEnd: {
|
||||
type: MarkerType.ArrowClosed,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'e5-8',
|
||||
source: '5',
|
||||
target: '8',
|
||||
type: 'custom',
|
||||
data: { text: 'custom edge' },
|
||||
},
|
||||
{
|
||||
id: 'e5-9',
|
||||
source: '5',
|
||||
target: '9',
|
||||
type: 'custom2',
|
||||
data: { text: 'custom edge 2' },
|
||||
},
|
||||
{
|
||||
id: 'e5-6',
|
||||
source: '5',
|
||||
target: '6',
|
||||
label: (
|
||||
<>
|
||||
<tspan>i am using</tspan>
|
||||
<tspan dy={10} x={0}>
|
||||
{'<tspan>'}
|
||||
</tspan>
|
||||
</>
|
||||
),
|
||||
labelStyle: { fill: 'red', fontWeight: 700 },
|
||||
style: { stroke: '#ffcc00' },
|
||||
markerEnd: {
|
||||
type: MarkerType.Arrow,
|
||||
color: '#FFCC00',
|
||||
markerUnits: 'userSpaceOnUse',
|
||||
width: 20,
|
||||
height: 20,
|
||||
strokeWidth: 2,
|
||||
},
|
||||
markerStart: {
|
||||
type: MarkerType.ArrowClosed,
|
||||
color: '#FFCC00',
|
||||
orient: 'auto-start-reverse',
|
||||
markerUnits: 'userSpaceOnUse',
|
||||
width: 20,
|
||||
height: 20,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const edgeTypes: EdgeTypesType = {
|
||||
custom: CustomEdge,
|
||||
custom2: CustomEdge2,
|
||||
};
|
||||
|
||||
const EdgesFlow = () => {
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||
const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds));
|
||||
|
||||
return (
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
onNodeClick={onNodeClick}
|
||||
onConnect={onConnect}
|
||||
onNodeDragStop={onNodeDragStop}
|
||||
onPaneReady={onPaneReady}
|
||||
snapToGrid={true}
|
||||
edgeTypes={edgeTypes}
|
||||
>
|
||||
<MiniMap />
|
||||
<Controls />
|
||||
<Background />
|
||||
</ReactFlow>
|
||||
);
|
||||
};
|
||||
|
||||
export default EdgesFlow;
|
||||
@@ -0,0 +1,56 @@
|
||||
import { FC } from 'react';
|
||||
|
||||
import ReactFlow, {
|
||||
addEdge,
|
||||
Background,
|
||||
Node,
|
||||
Edge,
|
||||
Connection,
|
||||
ReactFlowProvider,
|
||||
useNodesState,
|
||||
useEdgesState,
|
||||
} from 'react-flow-renderer';
|
||||
|
||||
import './multiflows.css';
|
||||
|
||||
const initialNodes: Node[] = [
|
||||
{ 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: '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' },
|
||||
];
|
||||
|
||||
const initialEdges: Edge[] = [
|
||||
{ id: 'e1-2', source: '1', target: '2', animated: true },
|
||||
{ id: 'e1-3', source: '1', target: '3' },
|
||||
];
|
||||
|
||||
const Flow: FC = () => {
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||
|
||||
const onConnect = (params: Edge | Connection) => setEdges((eds) => addEdge(params, eds));
|
||||
|
||||
return (
|
||||
<ReactFlowProvider>
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
onConnect={onConnect}
|
||||
>
|
||||
<Background />
|
||||
</ReactFlow>
|
||||
</ReactFlowProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const MultiFlows: FC = () => (
|
||||
<div className="react-flow__example-multiflows">
|
||||
<Flow />
|
||||
<Flow />
|
||||
</div>
|
||||
);
|
||||
|
||||
export default MultiFlows;
|
||||
@@ -0,0 +1,13 @@
|
||||
.react-flow__example-multiflows {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.react-flow__example-multiflows .react-flow {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.react-flow__example-multiflows .react-flow:first-child {
|
||||
border-right: 2px solid #333;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -0,0 +1,81 @@
|
||||
import { useState, CSSProperties, FC } from 'react';
|
||||
|
||||
import ReactFlow, {
|
||||
addEdge,
|
||||
Node,
|
||||
Position,
|
||||
Connection,
|
||||
Edge,
|
||||
NodeProps,
|
||||
NodeTypesType,
|
||||
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: 'a',
|
||||
sourcePosition: Position.Right,
|
||||
targetPosition: Position.Left,
|
||||
data: { label: 'A Node' },
|
||||
position: { x: 250, y: 0 },
|
||||
},
|
||||
];
|
||||
|
||||
const buttonStyle: CSSProperties = { position: 'absolute', right: 10, top: 30, zIndex: 4 };
|
||||
|
||||
const nodeStyles: CSSProperties = { padding: '10px 15px', border: '1px solid #ddd' };
|
||||
|
||||
const NodeA: FC<NodeProps> = () => {
|
||||
return <div style={nodeStyles}>A</div>;
|
||||
};
|
||||
|
||||
const NodeB: FC<NodeProps> = () => {
|
||||
return <div style={nodeStyles}>B</div>;
|
||||
};
|
||||
|
||||
type NodeTypesObject = {
|
||||
[key: string]: NodeTypesType;
|
||||
};
|
||||
|
||||
const nodeTypesObjects: NodeTypesObject = {
|
||||
a: {
|
||||
a: NodeA,
|
||||
},
|
||||
b: {
|
||||
b: NodeB,
|
||||
},
|
||||
};
|
||||
|
||||
const NodeTypeChangeFlow = () => {
|
||||
const [nodeTypesId, setNodeTypesId] = useState<string>('a');
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
||||
const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds));
|
||||
const changeType = () => setNodeTypesId((nt) => (nt === 'a' ? 'b' : 'a'));
|
||||
|
||||
return (
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
onConnect={onConnect}
|
||||
nodeTypes={nodeTypesObjects[nodeTypesId]}
|
||||
>
|
||||
<button onClick={changeType} style={buttonStyle}>
|
||||
change type
|
||||
</button>
|
||||
</ReactFlow>
|
||||
);
|
||||
};
|
||||
|
||||
export default NodeTypeChangeFlow;
|
||||
@@ -0,0 +1,63 @@
|
||||
import React, { memo, useCallback, Dispatch, FC } from 'react';
|
||||
import { useZoomPanHelper, ReactFlowInstance, Edge, Node, FlowExportObject } from 'react-flow-renderer';
|
||||
import localforage from 'localforage';
|
||||
|
||||
localforage.config({
|
||||
name: 'react-flow',
|
||||
storeName: 'flows',
|
||||
});
|
||||
|
||||
const flowKey = 'example-flow';
|
||||
|
||||
const getNodeId = () => `randomnode_${+new Date()}`;
|
||||
|
||||
type ControlsProps = {
|
||||
rfInstance?: ReactFlowInstance;
|
||||
setNodes: Dispatch<React.SetStateAction<Node<any>[]>>;
|
||||
setEdges: Dispatch<React.SetStateAction<Edge<any>[]>>;
|
||||
};
|
||||
|
||||
const Controls: FC<ControlsProps> = ({ rfInstance, setNodes, setEdges }) => {
|
||||
const { setTransform } = useZoomPanHelper();
|
||||
|
||||
const onSave = useCallback(() => {
|
||||
if (rfInstance) {
|
||||
const flow = rfInstance.toObject();
|
||||
localforage.setItem(flowKey, flow);
|
||||
}
|
||||
}, [rfInstance]);
|
||||
|
||||
const onRestore = useCallback(() => {
|
||||
const restoreFlow = async () => {
|
||||
const flow: FlowExportObject | null = await localforage.getItem(flowKey);
|
||||
|
||||
if (flow) {
|
||||
const [x = 0, y = 0] = flow.position;
|
||||
setNodes(flow.nodes || []);
|
||||
setEdges(flow.edges || []);
|
||||
setTransform({ x, y, zoom: flow.zoom || 0 });
|
||||
}
|
||||
};
|
||||
|
||||
restoreFlow();
|
||||
}, [setNodes, setEdges, setTransform]);
|
||||
|
||||
const onAdd = useCallback(() => {
|
||||
const newNode = {
|
||||
id: `random_node-${getNodeId()}`,
|
||||
data: { label: 'Added node' },
|
||||
position: { x: Math.random() * window.innerWidth - 100, y: Math.random() * window.innerHeight },
|
||||
};
|
||||
setNodes((nds) => nds.concat(newNode));
|
||||
}, [setNodes]);
|
||||
|
||||
return (
|
||||
<div className="save__controls">
|
||||
<button onClick={onSave}>save</button>
|
||||
<button onClick={onRestore}>restore</button>
|
||||
<button onClick={onAdd}>add node</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(Controls);
|
||||
@@ -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;
|
||||
@@ -0,0 +1,11 @@
|
||||
.save__controls {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
z-index: 4;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.save__controls button {
|
||||
margin-left: 5px;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import { MouseEvent } from 'react';
|
||||
import ReactFlow, { addEdge, Node, Connection, Edge, useNodesState, useEdgesState } from 'react-flow-renderer';
|
||||
|
||||
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
|
||||
const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node);
|
||||
|
||||
const nodesA: Node[] = [
|
||||
{ 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: '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' },
|
||||
];
|
||||
|
||||
const edgesA: Edge[] = [
|
||||
{ id: 'e1-2', source: '1a', target: '2a' },
|
||||
{ id: 'e1-3', source: '1a', target: '3a' },
|
||||
];
|
||||
|
||||
const nodesB: Node[] = [
|
||||
{ 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: '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: '4b', data: { label: 'Node 4' }, position: { x: 600, y: 100 }, className: 'light' },
|
||||
];
|
||||
|
||||
const edgesB: Edge[] = [
|
||||
{ id: 'e1b', source: 'inputb', target: '1b' },
|
||||
{ id: 'e2b', source: 'inputb', target: '2b' },
|
||||
{ id: 'e3b', source: 'inputb', target: '3b' },
|
||||
{ id: 'e4b', source: 'inputb', target: '4b' },
|
||||
];
|
||||
|
||||
const BasicFlow = () => {
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(nodesA);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(edgesA);
|
||||
|
||||
const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds));
|
||||
|
||||
return (
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
onNodeClick={onNodeClick}
|
||||
onConnect={onConnect}
|
||||
onNodeDragStop={onNodeDragStop}
|
||||
>
|
||||
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
|
||||
<button
|
||||
onClick={() => {
|
||||
setNodes(nodesA);
|
||||
setEdges(edgesA);
|
||||
}}
|
||||
style={{ marginRight: 5 }}
|
||||
>
|
||||
flow a
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
setNodes(nodesB);
|
||||
setEdges(edgesB);
|
||||
}}
|
||||
>
|
||||
flow b
|
||||
</button>
|
||||
</div>
|
||||
</ReactFlow>
|
||||
);
|
||||
};
|
||||
|
||||
export default BasicFlow;
|
||||
@@ -31,7 +31,7 @@ const initialNodes: Node[] = [
|
||||
const initialEdges: Edge[] = [];
|
||||
|
||||
const TouchDeviceFlow = () => {
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
||||
const [nodes, , onNodesChange] = useNodesState(initialNodes);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||
const onConnect = useCallback((connection: Connection) => setEdges((eds) => addEdge(connection, eds)), []);
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import React, { memo, FC, useMemo, CSSProperties } from 'react';
|
||||
import { Handle, Position, NodeProps } from 'react-flow-renderer';
|
||||
|
||||
const nodeStyles: CSSProperties = { padding: 10, border: '1px solid #ddd' };
|
||||
|
||||
const CustomNode: FC<NodeProps> = ({ data }) => {
|
||||
const handles = useMemo(
|
||||
() =>
|
||||
Array.from({ length: data.handleCount }, (x, i) => {
|
||||
const handleId = `handle-${i}`;
|
||||
return (
|
||||
<Handle
|
||||
key={handleId}
|
||||
type="source"
|
||||
position={Position.Right}
|
||||
id={handleId}
|
||||
style={{ top: 10 * i + data.handlePosition * 10 }}
|
||||
/>
|
||||
);
|
||||
}),
|
||||
[data.handleCount, data.handlePosition]
|
||||
);
|
||||
|
||||
return (
|
||||
<div style={nodeStyles}>
|
||||
<Handle type="target" position={Position.Left} />
|
||||
<div>output handle count: {data.handleCount}</div>
|
||||
{handles}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(CustomNode);
|
||||
@@ -0,0 +1,103 @@
|
||||
import { useCallback, CSSProperties } from 'react';
|
||||
|
||||
import ReactFlow, {
|
||||
NodeTypesType,
|
||||
addEdge,
|
||||
useZoomPanHelper,
|
||||
ReactFlowProvider,
|
||||
Node,
|
||||
Connection,
|
||||
Edge,
|
||||
useUpdateNodeInternals,
|
||||
Position,
|
||||
useNodesState,
|
||||
useEdgesState,
|
||||
} from 'react-flow-renderer';
|
||||
import CustomNode from './CustomNode';
|
||||
|
||||
const initialHandleCount = 1;
|
||||
|
||||
const initialNodes: Node[] = [
|
||||
{
|
||||
id: '1',
|
||||
type: 'custom',
|
||||
data: { label: 'Node 1', handleCount: initialHandleCount, handlePosition: 0 },
|
||||
position: { x: 250, y: 5 },
|
||||
},
|
||||
];
|
||||
|
||||
const buttonWrapperStyles: CSSProperties = { position: 'absolute', right: 10, top: 10, zIndex: 10 };
|
||||
|
||||
const nodeTypes: NodeTypesType = {
|
||||
custom: CustomNode,
|
||||
};
|
||||
|
||||
let id = 5;
|
||||
const getId = (): string => `${id++}`;
|
||||
|
||||
const UpdateNodeInternalsFlow = () => {
|
||||
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 { project } = useZoomPanHelper();
|
||||
|
||||
const onPaneClick = useCallback(
|
||||
(evt) =>
|
||||
setNodes((nds) =>
|
||||
nds.concat({
|
||||
id: getId(),
|
||||
position: project({ x: evt.clientX, y: evt.clientY - 40 }),
|
||||
data: { label: 'new node' },
|
||||
targetPosition: Position.Left,
|
||||
sourcePosition: Position.Right,
|
||||
})
|
||||
),
|
||||
[project]
|
||||
);
|
||||
|
||||
const toggleHandleCount = useCallback(() => {
|
||||
setNodes((nds) =>
|
||||
nds.map((node) => {
|
||||
return { ...node, data: { ...node.data, handleCount: node.data?.handleCount === 1 ? 2 : 1 } };
|
||||
})
|
||||
);
|
||||
}, []);
|
||||
|
||||
const toggleHandlePosition = useCallback(() => {
|
||||
setNodes((nds) =>
|
||||
nds.map((node) => {
|
||||
return { ...node, data: { ...node.data, handlePosition: node.data?.handlePosition === 0 ? 1 : 0 } };
|
||||
})
|
||||
);
|
||||
}, []);
|
||||
|
||||
const updateNode = useCallback(() => updateNodeInternals('1'), [updateNodeInternals]);
|
||||
|
||||
return (
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
nodeTypes={nodeTypes}
|
||||
onConnect={onConnect}
|
||||
onPaneClick={onPaneClick}
|
||||
>
|
||||
<div style={buttonWrapperStyles}>
|
||||
<button onClick={toggleHandleCount}>toggle handle count</button>
|
||||
<button onClick={toggleHandlePosition}>toggle handle position</button>
|
||||
<button onClick={updateNode}>update node internals</button>
|
||||
</div>
|
||||
</ReactFlow>
|
||||
);
|
||||
};
|
||||
|
||||
const WrappedFlow = () => (
|
||||
<ReactFlowProvider>
|
||||
<UpdateNodeInternalsFlow />
|
||||
</ReactFlowProvider>
|
||||
);
|
||||
|
||||
export default WrappedFlow;
|
||||
@@ -0,0 +1,78 @@
|
||||
import { MouseEvent as ReactMouseEvent, FC } from 'react';
|
||||
import ReactFlow, {
|
||||
addEdge,
|
||||
Handle,
|
||||
Connection,
|
||||
Position,
|
||||
Node,
|
||||
Edge,
|
||||
OnConnectStartParams,
|
||||
NodeProps,
|
||||
NodeTypesType,
|
||||
useNodesState,
|
||||
useEdgesState,
|
||||
} from 'react-flow-renderer';
|
||||
|
||||
import './validation.css';
|
||||
|
||||
const initialNodes: Node[] = [
|
||||
{ id: '0', type: 'custominput', position: { x: 0, y: 150 }, data: null },
|
||||
{ id: 'A', type: 'customnode', position: { x: 250, y: 0 }, data: null },
|
||||
{ id: 'B', type: 'customnode', position: { x: 250, y: 150 }, data: null },
|
||||
{ id: 'C', type: 'customnode', position: { x: 250, y: 300 }, data: null },
|
||||
];
|
||||
|
||||
const isValidConnection = (connection: Connection) => connection.target === 'B';
|
||||
const onConnectStart = (_: ReactMouseEvent, { nodeId, handleType }: OnConnectStartParams) =>
|
||||
console.log('on connect start', { nodeId, handleType });
|
||||
const onConnectStop = (event: MouseEvent) => console.log('on connect stop', event);
|
||||
const onConnectEnd = (event: MouseEvent) => console.log('on connect end', event);
|
||||
|
||||
const CustomInput: FC<NodeProps> = () => (
|
||||
<>
|
||||
<div>Only connectable with B</div>
|
||||
<Handle type="source" position={Position.Right} isValidConnection={isValidConnection} />
|
||||
</>
|
||||
);
|
||||
|
||||
const CustomNode: FC<NodeProps> = ({ id }) => (
|
||||
<>
|
||||
<Handle type="target" position={Position.Left} isValidConnection={isValidConnection} />
|
||||
<div>{id}</div>
|
||||
<Handle type="source" position={Position.Right} isValidConnection={isValidConnection} />
|
||||
</>
|
||||
);
|
||||
|
||||
const nodeTypes: NodeTypesType = {
|
||||
custominput: CustomInput,
|
||||
customnode: CustomNode,
|
||||
};
|
||||
|
||||
const ValidationFlow = () => {
|
||||
const [nodes, , onNodesChange] = useNodesState(initialNodes);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
||||
|
||||
const onConnect = (params: Connection | Edge) => {
|
||||
console.log('on connect', params);
|
||||
setEdges((eds) => addEdge(params, eds));
|
||||
};
|
||||
|
||||
return (
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
onConnect={onConnect}
|
||||
selectNodesOnDrag={false}
|
||||
className="validationflow"
|
||||
nodeTypes={nodeTypes}
|
||||
onConnectStart={onConnectStart}
|
||||
onConnectStop={onConnectStop}
|
||||
onConnectEnd={onConnectEnd}
|
||||
fitViewOnInit
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ValidationFlow;
|
||||
@@ -0,0 +1,31 @@
|
||||
.validationflow .react-flow__node {
|
||||
width: 150px;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
color: #555;
|
||||
border: 1px solid #ddd;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.validationflow .react-flow__node-customnode {
|
||||
background: #e6e6e9;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.react-flow__node-custominput .react-flow__handle {
|
||||
background: #e6e6e9;
|
||||
}
|
||||
|
||||
.validationflow .react-flow__node-custominput {
|
||||
background: #fff;
|
||||
|
||||
}
|
||||
|
||||
.validationflow .react-flow__handle-connecting {
|
||||
background: #ff6060;
|
||||
}
|
||||
|
||||
.validationflow .react-flow__handle-valid {
|
||||
background: #55dd99;
|
||||
}
|
||||
+86
-36
@@ -21,6 +21,16 @@ import Undirectional from './Undirectional';
|
||||
import Provider from './Provider';
|
||||
import CustomConnectionLine from './CustomConnectionLine';
|
||||
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';
|
||||
|
||||
@@ -34,73 +44,113 @@ const routes = [
|
||||
component: Basic,
|
||||
},
|
||||
{
|
||||
path: '/update-node',
|
||||
component: UpdateNode,
|
||||
},
|
||||
{
|
||||
path: '/stress',
|
||||
component: Stress,
|
||||
path: '/custom-connectionline',
|
||||
component: CustomConnectionLine,
|
||||
},
|
||||
{
|
||||
path: '/custom-node',
|
||||
component: CustomNode,
|
||||
},
|
||||
{
|
||||
path: '/floating-edges',
|
||||
component: FloatingEdges,
|
||||
path: '/draghandle',
|
||||
component: DragHandle,
|
||||
},
|
||||
{
|
||||
path: '/layouting',
|
||||
component: Layouting,
|
||||
path: '/dragndrop',
|
||||
component: DragNDrop,
|
||||
},
|
||||
{
|
||||
path: '/nested-nodes',
|
||||
component: NestedNodes,
|
||||
path: '/edges',
|
||||
component: Edges,
|
||||
},
|
||||
{
|
||||
path: '/hidden',
|
||||
component: Hidden,
|
||||
},
|
||||
{
|
||||
path: '/updatable-edge',
|
||||
component: UpdatableEdge,
|
||||
},
|
||||
{
|
||||
path: '/touch-device',
|
||||
component: TouchDevice,
|
||||
},
|
||||
{
|
||||
path: '/subflow',
|
||||
component: Subflow,
|
||||
},
|
||||
{
|
||||
path: '/interaction',
|
||||
component: Interaction,
|
||||
path: '/edge-types',
|
||||
component: EdgeTypes,
|
||||
},
|
||||
{
|
||||
path: '/empty',
|
||||
component: Empty,
|
||||
},
|
||||
{
|
||||
path: '/draghandle',
|
||||
component: DragHandle,
|
||||
path: '/floating-edges',
|
||||
component: FloatingEdges,
|
||||
},
|
||||
{
|
||||
path: '/undirectional',
|
||||
component: Undirectional,
|
||||
path: '/hidden',
|
||||
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',
|
||||
component: Provider,
|
||||
},
|
||||
{
|
||||
path: '/custom-connectionline',
|
||||
component: CustomConnectionLine,
|
||||
path: '/save-restore',
|
||||
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',
|
||||
component: UseZoomPanHelper,
|
||||
},
|
||||
{
|
||||
path: '/useupdatenodeinternals',
|
||||
component: UseUpdateNodeInternals,
|
||||
},
|
||||
{
|
||||
path: '/validation',
|
||||
component: Validation,
|
||||
},
|
||||
];
|
||||
|
||||
const Header = withRouter(({ history, location }) => {
|
||||
|
||||
Reference in New Issue
Block a user