chore(examples): add examples

This commit is contained in:
moklick
2021-12-22 23:53:05 +01:00
parent c1e5f90c7c
commit 7a85bb9666
13 changed files with 141 additions and 187 deletions
@@ -0,0 +1,36 @@
import ReactFlow, {
Node,
addEdge,
Background,
BackgroundVariant,
Connection,
Edge,
useNodesState,
useEdgesState,
} from 'react-flow-renderer';
import ConnectionLine from './ConnectionLine';
const initialNodes: Node[] = [{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } }];
const initialEdges: Edge[] = [];
const ConnectionLineFlow = () => {
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}
connectionLineComponent={ConnectionLine}
onConnect={onConnect}
>
<Background variant={BackgroundVariant.Lines} />
</ReactFlow>
);
};
export default ConnectionLineFlow;
+3 -3
View File
@@ -33,8 +33,7 @@ const onNodeClick = (_: MouseEvent, node: Node) => console.log('node click:', no
const onSelectionChange = ({ nodes, edges }: OnSelectionChangeParams) => console.log('selection change', nodes, edges);
const onPaneReady = (reactFlowInstance: ReactFlowInstance) => {
console.log('flow loaded:', reactFlowInstance);
reactFlowInstance.fitView();
console.log('pane ready:', reactFlowInstance);
};
const onMoveStart = (transform?: FlowTransform) => console.log('zoom/move start', transform);
@@ -158,7 +157,7 @@ const nodeColor = (n: Node): string => {
};
const OverviewFlow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [nodes, , onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds));
@@ -193,6 +192,7 @@ const OverviewFlow = () => {
onEdgeMouseMove={onEdgeMouseMove}
onEdgeMouseLeave={onEdgeMouseLeave}
onEdgeDoubleClick={onEdgeDoubleClick}
fitViewOnInit
>
<MiniMap nodeStrokeColor={nodeStrokeColor} nodeColor={nodeColor} nodeBorderRadius={2} />
<Controls />
@@ -1,13 +1,13 @@
import React from 'react';
import { useStoreState, useStoreActions } from 'react-flow-renderer';
import { useStore, useStoreApi } from 'react-flow-renderer';
const Sidebar = () => {
const nodes = useStoreState((store) => store.nodes);
const transform = useStoreState((store) => store.transform);
const setSelectedElements = useStoreActions((actions) => actions.setSelectedElements);
const store = useStoreApi();
const nodeInternals = useStore((store) => store.nodeInternals);
const transform = useStore((store) => store.transform);
const selectAll = () => {
setSelectedElements(nodes.map((node) => ({ id: node.id, type: node.type })));
nodeInternals.forEach((node) => (node.selected = true));
store.setState({ nodeInternals: new Map(nodeInternals) });
};
return (
@@ -20,9 +20,9 @@ const Sidebar = () => {
[{transform[0].toFixed(2)}, {transform[1].toFixed(2)}, {transform[2].toFixed(2)}]
</div>
<div className="title">Nodes</div>
{nodes.map((node) => (
{Array.from(nodeInternals).map(([, node]) => (
<div key={node.id}>
Node {node.id} - x: {node.__rf.position.x.toFixed(2)}, y: {node.__rf.position.y.toFixed(2)}
Node {node.id} - x: {node.position.x.toFixed(2)}, y: {node.position.y.toFixed(2)}
</div>
))}
@@ -1,37 +1,40 @@
import React, { useState, MouseEvent } from 'react';
import { MouseEvent } from 'react';
import ReactFlow, {
ReactFlowProvider,
addEdge,
removeElements,
Node,
Controls,
OnLoadParams,
FlowElement,
Connection,
Edge,
Elements,
ConnectionMode,
useNodesState,
useEdgesState,
ReactFlowInstance,
} from 'react-flow-renderer';
import Sidebar from './Sidebar';
import './provider.css';
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element);
const onLoad = (reactFlowInstance: OnLoadParams) => console.log('flow loaded:', reactFlowInstance);
const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node);
const onPaneReady = (reactFlowInstance: ReactFlowInstance) => console.log('pane ready:', reactFlowInstance);
const initialElements: Elements = [
const initialNodes: Node[] = [
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } },
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 } },
{ id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 } },
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 } },
];
const initialEdges: Edge[] = [
{ id: 'e1-2', source: '1', target: '2', animated: true },
{ id: 'e1-3', source: '1', target: '3' },
];
const ProviderFlow = () => {
const [elements, setElements] = useState<Elements>(initialElements);
const onConnect = (params: Connection | Edge) => setElements((els) => addEdge(params, els));
const onElementsRemove = (elementsToRemove: Elements) => setElements((els) => removeElements(elementsToRemove, els));
const [nodes, , onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = (params: Edge | Connection) => setEdges((els) => addEdge(params, els));
return (
<div className="providerflow">
@@ -39,11 +42,13 @@ const ProviderFlow = () => {
<Sidebar />
<div className="reactflow-wrapper">
<ReactFlow
elements={elements}
onElementClick={onElementClick}
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onNodeClick={onNodeClick}
onConnect={onConnect}
onElementsRemove={onElementsRemove}
onLoad={onLoad}
onPaneReady={onPaneReady}
connectionMode={ConnectionMode.Loose}
>
<Controls />
@@ -1,66 +1,79 @@
import React, { useState, useCallback } from 'react';
import { useCallback } from 'react';
import ReactFlow, {
NodeTypesType,
addEdge,
useZoomPanHelper,
ReactFlowProvider,
Elements,
Node,
Connection,
Edge,
ElementId,
ConnectionLineType,
ConnectionMode,
updateEdge,
useNodesState,
useEdgesState,
} from 'react-flow-renderer';
import CustomNode from './CustomNode';
const initialElements: Elements = [
const initialNodes: Node[] = [
{
id: '00',
type: 'custom',
position: { x: 300, y: 250 },
data: null,
},
{
id: '01',
type: 'custom',
position: { x: 100, y: 50 },
data: null,
},
{
id: '02',
type: 'custom',
position: { x: 500, y: 50 },
data: null,
},
{
id: '03',
type: 'custom',
position: { x: 500, y: 500 },
data: null,
},
{
id: '04',
type: 'custom',
position: { x: 100, y: 500 },
data: null,
},
{
id: '10',
type: 'custom',
position: { x: 300, y: 5 },
data: null,
},
{
id: '20',
type: 'custom',
position: { x: 600, y: 250 },
data: null,
},
{
id: '30',
type: 'custom',
position: { x: 300, y: 600 },
data: null,
},
{
id: '40',
type: 'custom',
position: { x: 5, y: 250 },
data: null,
},
];
const initialEdges: Edge[] = [
{
id: 'e0-1a',
source: '00',
@@ -164,22 +177,25 @@ const nodeTypes: NodeTypesType = {
};
let id = 4;
const getId = (): ElementId => `${id++}`;
const getId = () => `${id++}`;
const UpdateNodeInternalsFlow = () => {
const [elements, setElements] = useState<Elements>(initialElements);
const onConnect = (params: Connection | Edge) => setElements((els) => addEdge({ ...params, type: 'default' }, els));
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = (params: Edge | Connection) => setEdges((els) => addEdge(params, els));
const { project } = useZoomPanHelper();
const onEdgeUpdate = (oldEdge: Edge, newConnection: Connection) =>
setElements((els) => updateEdge(oldEdge, newConnection, els));
setEdges((els) => updateEdge(oldEdge, newConnection, els));
const onPaneClick = useCallback(
(evt) =>
setElements((els) =>
els.concat({
setNodes((nds) =>
nds.concat({
id: getId(),
position: project({ x: evt.clientX, y: evt.clientY - 40 }),
type: 'custom',
data: null,
})
),
[project]
@@ -187,7 +203,10 @@ const UpdateNodeInternalsFlow = () => {
return (
<ReactFlow
elements={elements}
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
nodeTypes={nodeTypes}
onConnect={onConnect}
onPaneClick={onPaneClick}
@@ -1,42 +1,46 @@
import React, { useState, useCallback } from 'react';
import { useCallback } from 'react';
import ReactFlow, {
removeElements,
Node,
addEdge,
Background,
MiniMap,
useZoomPanHelper,
ReactFlowProvider,
Elements,
ElementId,
Connection,
Edge,
useNodesState,
useEdgesState,
} from 'react-flow-renderer';
const initialElements: Elements = [
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' },
];
let id = 5;
const getId = (): ElementId => `${id++}`;
const getId = () => `${id++}`;
const UseZoomPanHelperFlow = () => {
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));
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds));
const { project, setCenter, zoomIn, zoomOut } = useZoomPanHelper();
const onPaneClick = useCallback(
(evt) => {
const projectedPosition = project({ x: evt.clientX, y: evt.clientY - 40 });
setElements((els) =>
els.concat({
setNodes((nds) =>
nds.concat({
id: getId(),
position: projectedPosition,
data: {
@@ -48,25 +52,27 @@ const UseZoomPanHelperFlow = () => {
[project]
);
const onElementClick = useCallback(
const onNodeClick = useCallback(
(_, element) => {
const { x, y } = element.position;
setCenter(x, y, 1);
setCenter(x, y, { zoom: 1 });
},
[setCenter]
);
return (
<ReactFlow
elements={elements}
onElementClick={onElementClick}
onElementsRemove={onElementsRemove}
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onNodeClick={onNodeClick}
onConnect={onConnect}
onPaneClick={onPaneClick}
>
<div style={{ position: 'absolute', left: 0, top: 0, zIndex: 100 }}>
<button onClick={() => zoomIn(1200)}>zoomIn</button>
<button onClick={() => zoomOut(0)}>zoomOut</button>
<button onClick={() => zoomIn({ duration: 1200 })}>zoomIn</button>
<button onClick={() => zoomOut({ duration: 0 })}>zoomOut</button>
</div>
<Background />
<MiniMap />
+20
View File
@@ -17,6 +17,10 @@ import Subflow from './Subflow';
import Interaction from './Interaction';
import Empty from './Empty';
import DragHandle from './DragHandle';
import Undirectional from './Undirectional';
import Provider from './Provider';
import CustomConnectionLine from './CustomConnectionLine';
import UseZoomPanHelper from './UseZoomPanHelper';
import './index.css';
@@ -81,6 +85,22 @@ const routes = [
path: '/draghandle',
component: DragHandle,
},
{
path: '/undirectional',
component: Undirectional,
},
{
path: '/provider',
component: Provider,
},
{
path: '/custom-connectionline',
component: CustomConnectionLine,
},
{
path: '/usezoompanhelper',
component: UseZoomPanHelper,
},
];
const Header = withRouter(({ history, location }) => {
@@ -1,33 +0,0 @@
import React, { useState } from 'react';
import ReactFlow, {
removeElements,
addEdge,
Background,
BackgroundVariant,
Elements,
Connection,
Edge,
} from 'react-flow-renderer';
import ConnectionLine from './ConnectionLine';
const initialElements: Elements = [{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } }];
const ConnectionLineFlow = () => {
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 (
<ReactFlow
elements={elements}
connectionLineComponent={ConnectionLine}
onElementsRemove={onElementsRemove}
onConnect={onConnect}
>
<Background variant={BackgroundVariant.Lines} />
</ReactFlow>
);
};
export default ConnectionLineFlow;
-78
View File
@@ -1,78 +0,0 @@
import React, { useEffect, useState } from 'react';
import ReactFlow, { Elements } from 'react-flow-renderer';
import './updatenode.css';
const initialElements: Elements = [
{ id: '1', data: { label: '-' }, position: { x: 100, y: 100 } },
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 200 } },
{ id: 'e1-2', source: '1', target: '2' },
];
const UpdateNode = () => {
const [elements, setElements] = useState<Elements>(initialElements);
const [nodeName, setNodeName] = useState<string>('Node 1');
const [nodeBg, setNodeBg] = useState<string>('#eee');
const [nodeHidden, setNodeHidden] = useState<boolean>(false);
useEffect(() => {
setElements((els) =>
els.map((el) => {
if (el.id === '1') {
// it's important that you create a new object here in order to notify react flow about the change
el.data = {
...el.data,
label: nodeName,
};
}
return el;
})
);
}, [nodeName, setElements]);
useEffect(() => {
setElements((els) =>
els.map((el) => {
if (el.id === '1') {
// it's important that you create a new object here in order to notify react flow about the change
el.style = { ...el.style, backgroundColor: nodeBg };
}
return el;
})
);
}, [nodeBg, setElements]);
useEffect(() => {
setElements((els) =>
els.map((el) => {
if (el.id === '1' || el.id === 'e1-2') {
// when you update a simple type you can just update the value
el.isHidden = nodeHidden;
}
return el;
})
);
}, [nodeHidden, setElements]);
return (
<ReactFlow elements={elements} defaultZoom={1.5} minZoom={0.2} maxZoom={4}>
<div className="updatenode__controls">
<label>label:</label>
<input value={nodeName} onChange={(evt) => setNodeName(evt.target.value)} />
<label className="updatenode__bglabel">background:</label>
<input value={nodeBg} onChange={(evt) => setNodeBg(evt.target.value)} />
<div className="updatenode__checkboxwrapper">
<label>hidden:</label>
<input type="checkbox" checked={nodeHidden} onChange={(evt) => setNodeHidden(evt.target.checked)} />
</div>
</div>
</ReactFlow>
);
};
export default UpdateNode;
@@ -1,21 +0,0 @@
.updatenode__controls {
position: absolute;
right: 10px;
top: 10px;
z-index: 4;
font-size: 12px;
}
.updatenode__controls label {
display: block;
}
.updatenode__bglabel {
margin-top: 10px;
}
.updatenode__checkboxwrapper {
margin-top: 10px;
display: flex;
align-items: center;
}