feat(hooks): add useReactFlow hook, refactor types and properties
This commit is contained in:
+24
-28
@@ -1,15 +1,12 @@
|
||||
import { useState, MouseEvent } from 'react';
|
||||
import { MouseEvent } from 'react';
|
||||
|
||||
import ReactFlow, {
|
||||
addEdge,
|
||||
ReactFlowProvider,
|
||||
Background,
|
||||
BackgroundVariant,
|
||||
Node,
|
||||
Edge,
|
||||
Connection,
|
||||
useNodesState,
|
||||
useEdgesState,
|
||||
ReactFlowInstance,
|
||||
useReactFlow,
|
||||
} from 'react-flow-renderer';
|
||||
|
||||
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
|
||||
@@ -28,52 +25,45 @@ const initialEdges: Edge[] = [
|
||||
];
|
||||
|
||||
const BasicFlow = () => {
|
||||
const [rfInstance, setRfInstance] = useState<ReactFlowInstance | null>(null);
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||
const onConnect = (params: Edge | Connection) => setEdges((els) => addEdge(params, els));
|
||||
const onPaneReady = (reactFlowInstance: ReactFlowInstance) => setRfInstance(reactFlowInstance);
|
||||
const instance = useReactFlow();
|
||||
|
||||
const updatePos = () => {
|
||||
setNodes((nds) => {
|
||||
return nds.map((node) => {
|
||||
instance.setNodes((nodes) =>
|
||||
nodes.map((node) => {
|
||||
node.position = {
|
||||
x: Math.random() * 400,
|
||||
y: Math.random() * 400,
|
||||
};
|
||||
|
||||
return node;
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const logToObject = () => console.log(rfInstance?.toObject());
|
||||
const resetTransform = () => rfInstance?.setTransform({ x: 0, y: 0, zoom: 1 });
|
||||
const logToObject = () => console.log(instance.toObject());
|
||||
const resetTransform = () => instance.setViewport({ x: 0, y: 0, zoom: 1 });
|
||||
|
||||
const toggleClassnames = () => {
|
||||
setNodes((nds) => {
|
||||
return nds.map((node) => {
|
||||
instance.setNodes((nodes) =>
|
||||
nodes.map((node) => {
|
||||
node.className = node.className === 'light' ? 'dark' : 'light';
|
||||
|
||||
return node;
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
onPaneReady={onPaneReady}
|
||||
defaultNodes={initialNodes}
|
||||
defaultEdges={initialEdges}
|
||||
onNodeClick={onNodeClick}
|
||||
onConnect={onConnect}
|
||||
onNodeDragStop={onNodeDragStop}
|
||||
className="react-flow-basic-example"
|
||||
defaultZoom={1.5}
|
||||
minZoom={0.2}
|
||||
maxZoom={4}
|
||||
fitViewOnInit
|
||||
>
|
||||
<Background variant={BackgroundVariant.Lines} />
|
||||
|
||||
@@ -93,4 +83,10 @@ const BasicFlow = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default BasicFlow;
|
||||
export default function App() {
|
||||
return (
|
||||
<ReactFlowProvider>
|
||||
<BasicFlow />
|
||||
</ReactFlowProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import { useState } from 'react';
|
||||
import ReactFlow, {
|
||||
useReactFlow,
|
||||
Background,
|
||||
BackgroundVariant,
|
||||
Node,
|
||||
Edge,
|
||||
ReactFlowInstance,
|
||||
ReactFlowProvider,
|
||||
useUpdateNodes,
|
||||
useUpdateEdges,
|
||||
} from 'react-flow-renderer';
|
||||
|
||||
const defaultNodes: Node[] = [
|
||||
@@ -27,40 +24,34 @@ const defaultEdgeOptions = {
|
||||
};
|
||||
|
||||
const DefaultNodes = () => {
|
||||
const [rfInstance, setRfInstance] = useState<ReactFlowInstance | null>(null);
|
||||
const updateNodes = useUpdateNodes();
|
||||
const updateEdges = useUpdateEdges();
|
||||
const instance = useReactFlow();
|
||||
|
||||
const logToObject = () => console.log(rfInstance?.toObject());
|
||||
const resetTransform = () => rfInstance?.setTransform({ x: 0, y: 0, zoom: 1 });
|
||||
const logToObject = () => console.log(instance.toObject());
|
||||
const resetTransform = () => instance.setViewport({ x: 0, y: 0, zoom: 1 });
|
||||
|
||||
const updateNodePositions = () => {
|
||||
updateNodes((nodes, setNodes) => {
|
||||
setNodes(
|
||||
nodes.map((node) => {
|
||||
node.position = {
|
||||
x: Math.random() * 400,
|
||||
y: Math.random() * 400,
|
||||
};
|
||||
instance.setNodes((nodes) =>
|
||||
nodes.map((node) => {
|
||||
node.position = {
|
||||
x: Math.random() * 400,
|
||||
y: Math.random() * 400,
|
||||
};
|
||||
|
||||
return node;
|
||||
})
|
||||
);
|
||||
});
|
||||
return node;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const updateEdgeColors = () => {
|
||||
updateEdges((edges, setEdges) => {
|
||||
setEdges(
|
||||
edges.map((edge) => {
|
||||
edge.style = {
|
||||
stroke: '#ff5050',
|
||||
};
|
||||
instance.setEdges((edges) =>
|
||||
edges.map((edge) => {
|
||||
edge.style = {
|
||||
stroke: '#ff5050',
|
||||
};
|
||||
|
||||
return edge;
|
||||
})
|
||||
);
|
||||
});
|
||||
return edge;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -68,7 +59,6 @@ const DefaultNodes = () => {
|
||||
defaultNodes={defaultNodes}
|
||||
defaultEdges={defaultEdges}
|
||||
defaultEdgeOptions={defaultEdgeOptions}
|
||||
onPaneReady={setRfInstance}
|
||||
fitViewOnInit
|
||||
>
|
||||
<Background variant={BackgroundVariant.Lines} />
|
||||
|
||||
@@ -7,7 +7,7 @@ import ReactFlow, {
|
||||
Connection,
|
||||
Edge,
|
||||
PanOnScrollMode,
|
||||
FlowTransform,
|
||||
Viewport,
|
||||
useNodesState,
|
||||
useEdgesState,
|
||||
} from 'react-flow-renderer';
|
||||
@@ -31,7 +31,7 @@ const onEdgeClick = (_: MouseEvent, edge: Edge) => console.log('click', edge);
|
||||
const onPaneClick = (event: MouseEvent) => console.log('onPaneClick', event);
|
||||
const onPaneScroll = (event?: WheelEvent) => console.log('onPaneScroll', event);
|
||||
const onPaneContextMenu = (event: MouseEvent) => console.log('onPaneContextMenu', event);
|
||||
const onMoveEnd = (flowTranasform?: FlowTransform) => console.log('onMoveEnd', flowTranasform);
|
||||
const onMoveEnd = (viewport?: Viewport) => console.log('onMoveEnd', viewport);
|
||||
|
||||
const InteractionFlow = () => {
|
||||
const [nodes, , onNodesChange] = useNodesState(initialNodes);
|
||||
|
||||
@@ -107,7 +107,7 @@ const NestedFlow = () => {
|
||||
};
|
||||
|
||||
const logToObject = () => console.log(rfInstance?.toObject());
|
||||
const resetTransform = () => rfInstance?.setTransform({ x: 0, y: 0, zoom: 1 });
|
||||
const resetTransform = () => rfInstance?.setViewport({ x: 0, y: 0, zoom: 1 });
|
||||
|
||||
const toggleClassnames = () => {
|
||||
setNodes((nds) => {
|
||||
|
||||
@@ -5,7 +5,7 @@ import ReactFlow, {
|
||||
Controls,
|
||||
Background,
|
||||
Node,
|
||||
FlowTransform,
|
||||
Viewport,
|
||||
SnapGrid,
|
||||
Connection,
|
||||
Edge,
|
||||
@@ -36,8 +36,8 @@ const onPaneReady = (reactFlowInstance: ReactFlowInstance) => {
|
||||
console.log('pane ready:', reactFlowInstance);
|
||||
};
|
||||
|
||||
const onMoveStart = (transform?: FlowTransform) => console.log('zoom/move start', transform);
|
||||
const onMoveEnd = (transform?: FlowTransform) => console.log('zoom/move end', transform);
|
||||
const onMoveStart = (transform?: Viewport) => console.log('zoom/move start', transform);
|
||||
const onMoveEnd = (transform?: Viewport) => console.log('zoom/move end', transform);
|
||||
const onEdgeContextMenu = (_: MouseEvent, edge: Edge) => console.log('edge context menu', edge);
|
||||
const onEdgeMouseEnter = (_: MouseEvent, edge: Edge) => console.log('edge mouse enter', edge);
|
||||
const onEdgeMouseMove = (_: MouseEvent, edge: Edge) => console.log('edge mouse move', edge);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { memo, useCallback, Dispatch, FC } from 'react';
|
||||
import { useZoomPanHelper, ReactFlowInstance, Edge, Node, FlowExportObject } from 'react-flow-renderer';
|
||||
import { useReactFlow, ReactFlowInstance, Edge, Node, ReactFlowJsonObject } from 'react-flow-renderer';
|
||||
import localforage from 'localforage';
|
||||
|
||||
localforage.config({
|
||||
@@ -18,7 +18,7 @@ type ControlsProps = {
|
||||
};
|
||||
|
||||
const Controls: FC<ControlsProps> = ({ rfInstance, setNodes, setEdges }) => {
|
||||
const { setTransform } = useZoomPanHelper();
|
||||
const { setViewport } = useReactFlow();
|
||||
|
||||
const onSave = useCallback(() => {
|
||||
if (rfInstance) {
|
||||
@@ -29,18 +29,18 @@ const Controls: FC<ControlsProps> = ({ rfInstance, setNodes, setEdges }) => {
|
||||
|
||||
const onRestore = useCallback(() => {
|
||||
const restoreFlow = async () => {
|
||||
const flow: FlowExportObject | null = await localforage.getItem(flowKey);
|
||||
const flow: ReactFlowJsonObject | null = await localforage.getItem(flowKey);
|
||||
|
||||
if (flow) {
|
||||
const [x = 0, y = 0] = flow.position;
|
||||
const { x, y, zoom } = flow.viewport;
|
||||
setNodes(flow.nodes || []);
|
||||
setEdges(flow.edges || []);
|
||||
setTransform({ x, y, zoom: flow.zoom || 0 });
|
||||
setViewport({ x, y, zoom: zoom || 0 });
|
||||
}
|
||||
};
|
||||
|
||||
restoreFlow();
|
||||
}, [setNodes, setEdges, setTransform]);
|
||||
}, [setNodes, setEdges, setViewport]);
|
||||
|
||||
const onAdd = useCallback(() => {
|
||||
const newNode = {
|
||||
|
||||
@@ -129,7 +129,7 @@ const BasicFlow = () => {
|
||||
};
|
||||
|
||||
const logToObject = () => console.log(rfInstance?.toObject());
|
||||
const resetTransform = () => rfInstance?.setTransform({ x: 0, y: 0, zoom: 1 });
|
||||
const resetTransform = () => rfInstance?.setViewport({ x: 0, y: 0, zoom: 1 });
|
||||
|
||||
const toggleClassnames = () => {
|
||||
setNodes((nds) => {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import ReactFlow, {
|
||||
useReactFlow,
|
||||
NodeTypesType,
|
||||
addEdge,
|
||||
useZoomPanHelper,
|
||||
ReactFlowProvider,
|
||||
Node,
|
||||
Connection,
|
||||
@@ -184,7 +184,7 @@ const UpdateNodeInternalsFlow = () => {
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||
|
||||
const onConnect = (params: Edge | Connection) => setEdges((els) => addEdge(params, els));
|
||||
const { project } = useZoomPanHelper();
|
||||
const { project } = useReactFlow();
|
||||
const onEdgeUpdate = (oldEdge: Edge, newConnection: Connection) =>
|
||||
setEdges((els) => updateEdge(oldEdge, newConnection, els));
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useCallback, CSSProperties } from 'react';
|
||||
import ReactFlow, {
|
||||
NodeTypesType,
|
||||
addEdge,
|
||||
useZoomPanHelper,
|
||||
useReactFlow,
|
||||
ReactFlowProvider,
|
||||
Node,
|
||||
Connection,
|
||||
@@ -41,7 +41,7 @@ const UpdateNodeInternalsFlow = () => {
|
||||
const onConnect = (params: Edge | Connection) => setEdges((els) => addEdge(params, els));
|
||||
|
||||
const updateNodeInternals = useUpdateNodeInternals();
|
||||
const { project } = useZoomPanHelper();
|
||||
const { project } = useReactFlow();
|
||||
|
||||
const onPaneClick = useCallback(
|
||||
(evt) =>
|
||||
|
||||
@@ -5,7 +5,7 @@ import ReactFlow, {
|
||||
addEdge,
|
||||
Background,
|
||||
MiniMap,
|
||||
useZoomPanHelper,
|
||||
useReactFlow,
|
||||
ReactFlowProvider,
|
||||
Connection,
|
||||
Edge,
|
||||
@@ -33,7 +33,7 @@ const UseZoomPanHelperFlow = () => {
|
||||
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 { project, setCenter, zoomIn, zoomOut } = useReactFlow();
|
||||
|
||||
const onPaneClick = useCallback(
|
||||
(evt) => {
|
||||
|
||||
Reference in New Issue
Block a user