From 7a85bb96661ef0a2da8577ff9b94108ce7c221d0 Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 22 Dec 2021 23:53:05 +0100 Subject: [PATCH] chore(examples): add examples --- .../CustomConnectionLine/ConnectionLine.tsx | 0 example/src/CustomConnectionLine/index.tsx | 36 +++++++++ example/src/Overview/index.tsx | 6 +- .../{src_oldapi => src}/Provider/Sidebar.tsx | 16 ++-- .../{src_oldapi => src}/Provider/index.tsx | 35 +++++---- .../{src_oldapi => src}/Provider/provider.css | 0 .../Undirectional/CustomNode.tsx | 0 .../Undirectional/index.tsx | 41 +++++++--- .../UseZoomPanHelper/index.tsx | 42 +++++----- example/src/index.tsx | 20 +++++ .../src_oldapi/CustomConnectionLine/index.tsx | 33 -------- example/src_oldapi/UpdateNode/index.tsx | 78 ------------------- example/src_oldapi/UpdateNode/updatenode.css | 21 ----- 13 files changed, 141 insertions(+), 187 deletions(-) rename example/{src_oldapi => src}/CustomConnectionLine/ConnectionLine.tsx (100%) create mode 100644 example/src/CustomConnectionLine/index.tsx rename example/{src_oldapi => src}/Provider/Sidebar.tsx (56%) rename example/{src_oldapi => src}/Provider/index.tsx (56%) rename example/{src_oldapi => src}/Provider/provider.css (100%) rename example/{src_oldapi => src}/Undirectional/CustomNode.tsx (100%) rename example/{src_oldapi => src}/Undirectional/index.tsx (80%) rename example/{src_oldapi => src}/UseZoomPanHelper/index.tsx (65%) delete mode 100644 example/src_oldapi/CustomConnectionLine/index.tsx delete mode 100644 example/src_oldapi/UpdateNode/index.tsx delete mode 100644 example/src_oldapi/UpdateNode/updatenode.css diff --git a/example/src_oldapi/CustomConnectionLine/ConnectionLine.tsx b/example/src/CustomConnectionLine/ConnectionLine.tsx similarity index 100% rename from example/src_oldapi/CustomConnectionLine/ConnectionLine.tsx rename to example/src/CustomConnectionLine/ConnectionLine.tsx diff --git a/example/src/CustomConnectionLine/index.tsx b/example/src/CustomConnectionLine/index.tsx new file mode 100644 index 00000000..cca1e821 --- /dev/null +++ b/example/src/CustomConnectionLine/index.tsx @@ -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 ( + + + + ); +}; + +export default ConnectionLineFlow; diff --git a/example/src/Overview/index.tsx b/example/src/Overview/index.tsx index 4cb1e045..9219fe38 100644 --- a/example/src/Overview/index.tsx +++ b/example/src/Overview/index.tsx @@ -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 > diff --git a/example/src_oldapi/Provider/Sidebar.tsx b/example/src/Provider/Sidebar.tsx similarity index 56% rename from example/src_oldapi/Provider/Sidebar.tsx rename to example/src/Provider/Sidebar.tsx index 0b2c5f24..ecd0665b 100644 --- a/example/src_oldapi/Provider/Sidebar.tsx +++ b/example/src/Provider/Sidebar.tsx @@ -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)}]
Nodes
- {nodes.map((node) => ( + {Array.from(nodeInternals).map(([, node]) => (
- 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)}
))} diff --git a/example/src_oldapi/Provider/index.tsx b/example/src/Provider/index.tsx similarity index 56% rename from example/src_oldapi/Provider/index.tsx rename to example/src/Provider/index.tsx index a7a78b7c..342900e1 100644 --- a/example/src_oldapi/Provider/index.tsx +++ b/example/src/Provider/index.tsx @@ -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(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 (
@@ -39,11 +42,13 @@ const ProviderFlow = () => {
diff --git a/example/src_oldapi/Provider/provider.css b/example/src/Provider/provider.css similarity index 100% rename from example/src_oldapi/Provider/provider.css rename to example/src/Provider/provider.css diff --git a/example/src_oldapi/Undirectional/CustomNode.tsx b/example/src/Undirectional/CustomNode.tsx similarity index 100% rename from example/src_oldapi/Undirectional/CustomNode.tsx rename to example/src/Undirectional/CustomNode.tsx diff --git a/example/src_oldapi/Undirectional/index.tsx b/example/src/Undirectional/index.tsx similarity index 80% rename from example/src_oldapi/Undirectional/index.tsx rename to example/src/Undirectional/index.tsx index de6bc11f..79b5615a 100644 --- a/example/src_oldapi/Undirectional/index.tsx +++ b/example/src/Undirectional/index.tsx @@ -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(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 ( `${id++}`; + +const getId = () => `${id++}`; const UseZoomPanHelperFlow = () => { - const [elements, setElements] = useState(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 (
- - + +
diff --git a/example/src/index.tsx b/example/src/index.tsx index d81cad1f..967a7087 100644 --- a/example/src/index.tsx +++ b/example/src/index.tsx @@ -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 }) => { diff --git a/example/src_oldapi/CustomConnectionLine/index.tsx b/example/src_oldapi/CustomConnectionLine/index.tsx deleted file mode 100644 index 48cbf561..00000000 --- a/example/src_oldapi/CustomConnectionLine/index.tsx +++ /dev/null @@ -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(initialElements); - const onElementsRemove = (elementsToRemove: Elements) => setElements((els) => removeElements(elementsToRemove, els)); - const onConnect = (params: Connection | Edge) => setElements((els) => addEdge(params, els)); - - return ( - - - - ); -}; - -export default ConnectionLineFlow; diff --git a/example/src_oldapi/UpdateNode/index.tsx b/example/src_oldapi/UpdateNode/index.tsx deleted file mode 100644 index a7cce8f2..00000000 --- a/example/src_oldapi/UpdateNode/index.tsx +++ /dev/null @@ -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(initialElements); - const [nodeName, setNodeName] = useState('Node 1'); - const [nodeBg, setNodeBg] = useState('#eee'); - const [nodeHidden, setNodeHidden] = useState(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 ( - -
- - setNodeName(evt.target.value)} /> - - - setNodeBg(evt.target.value)} /> - -
- - setNodeHidden(evt.target.checked)} /> -
-
-
- ); -}; - -export default UpdateNode; diff --git a/example/src_oldapi/UpdateNode/updatenode.css b/example/src_oldapi/UpdateNode/updatenode.css deleted file mode 100644 index 95438054..00000000 --- a/example/src_oldapi/UpdateNode/updatenode.css +++ /dev/null @@ -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; -}