chore(applyChanges): cleanup

This commit is contained in:
moklick
2024-01-11 16:26:59 +01:00
parent 2ba35de186
commit 70d76611b1
3 changed files with 50 additions and 12 deletions
+36 -6
View File
@@ -1,4 +1,4 @@
import { MouseEvent } from 'react'; import { MouseEvent, useCallback } from 'react';
import { import {
ReactFlow, ReactFlow,
MiniMap, MiniMap,
@@ -53,10 +53,11 @@ const initialEdges: Edge[] = [
const defaultEdgeOptions = {}; const defaultEdgeOptions = {};
const BasicFlow = () => { const BasicFlow = () => {
const instance = useReactFlow(); const { setNodes, getNodes, setEdges, getEdges, deleteElements, updateNodeData, toObject, setViewport } =
useReactFlow();
const updatePos = () => { const updatePos = () => {
instance.setNodes((nodes) => setNodes((nodes) =>
nodes.map((node) => { nodes.map((node) => {
node.position = { node.position = {
x: Math.random() * 400, x: Math.random() * 400,
@@ -68,11 +69,11 @@ const BasicFlow = () => {
); );
}; };
const logToObject = () => console.log(instance.toObject()); const logToObject = () => console.log(toObject());
const resetTransform = () => instance.setViewport({ x: 0, y: 0, zoom: 1 }); const resetTransform = () => setViewport({ x: 0, y: 0, zoom: 1 });
const toggleClassnames = () => { const toggleClassnames = () => {
instance.setNodes((nodes) => setNodes((nodes) =>
nodes.map((node) => { nodes.map((node) => {
node.className = node.className === 'light' ? 'dark' : 'light'; node.className = node.className === 'light' ? 'dark' : 'light';
@@ -81,6 +82,30 @@ const BasicFlow = () => {
); );
}; };
const deleteSelectedElements = useCallback(() => {
const selectedNodes = getNodes().filter((node) => node.selected);
const selectedEdges = getEdges().filter((edge) => edge.selected);
deleteElements({ nodes: selectedNodes, edges: selectedEdges });
}, [deleteElements]);
const deleteSomeElements = useCallback(() => {
deleteElements({ nodes: [{ id: '2' }], edges: [{ id: 'e1-3' }] });
}, []);
const onSetNodes = () => {
setNodes([
{ id: 'a', position: { x: 0, y: 0 }, data: { label: 'Node a' } },
{ id: 'b', position: { x: 0, y: 150 }, data: { label: 'Node b' } },
]);
setEdges([{ id: 'a-b', source: 'a', target: 'b' }]);
};
const onUpdateNode = () => {
updateNodeData('1', { label: 'update' });
updateNodeData('2', { label: 'update' });
};
return ( return (
<ReactFlow <ReactFlow
defaultNodes={initialNodes} defaultNodes={initialNodes}
@@ -106,6 +131,11 @@ const BasicFlow = () => {
<button onClick={updatePos}>change pos</button> <button onClick={updatePos}>change pos</button>
<button onClick={toggleClassnames}>toggle classnames</button> <button onClick={toggleClassnames}>toggle classnames</button>
<button onClick={logToObject}>toObject</button> <button onClick={logToObject}>toObject</button>
<button onClick={deleteSelectedElements}>deleteSelectedElements</button>
<button onClick={deleteSomeElements}>deleteSomeElements</button>
<button onClick={onSetNodes}>setNodes</button>
<button onClick={onUpdateNode}>updateNode</button>
</Panel> </Panel>
</ReactFlow> </ReactFlow>
); );
@@ -1,16 +1,21 @@
import { memo, ChangeEventHandler } from 'react'; import { memo, useState } from 'react';
import { Position, NodeProps, Handle, useReactFlow } from '@xyflow/react'; import { Position, NodeProps, Handle, useReactFlow } from '@xyflow/react';
function TextNode({ id, data }: NodeProps) { function TextNode({ id, data }: NodeProps) {
const { updateNodeData } = useReactFlow(); const { updateNodeData } = useReactFlow();
const [text, setText] = useState(data.text);
const onChange: ChangeEventHandler<HTMLInputElement> = (evt) => updateNodeData(id, { text: evt.target.value }); const updateText = (text: string) => {
// avoid jumping caret with a synchronous update
setText(text);
// update actual node data
updateNodeData(id, { text });
};
return ( return (
<div style={{ background: '#eee', color: '#222', padding: 10, fontSize: 12, borderRadius: 10 }}> <div style={{ background: '#eee', color: '#222', padding: 10, fontSize: 12, borderRadius: 10 }}>
<div>node {id}</div> <div>node {id}</div>
<div> <div>
<input onChange={onChange} value={data.text} /> <input onChange={(evt) => updateText(evt.target.value)} value={text} />
</div> </div>
<Handle type="source" position={Position.Right} /> <Handle type="source" position={Position.Right} />
</div> </div>
+5 -2
View File
@@ -68,12 +68,13 @@ export function useReactFlow<NodeType extends Node = Node, EdgeType extends Edge
} else if (onNodesChange) { } else if (onNodesChange) {
const changes: NodeChange[] = getElementsDiffChanges({ items: setNodesData.current, lookup: nodeLookup }); const changes: NodeChange[] = getElementsDiffChanges({ items: setNodesData.current, lookup: nodeLookup });
onNodesChange(changes); onNodesChange(changes);
setNodesData.current = undefined;
} }
setNodesData.current = undefined;
}, 0); }, 0);
}, []); }, []);
// this is used to handle multiple syncronous setNodes calls // this is used to handle multiple syncronous setEdges calls
const setEdgesData = useRef<Edge[]>(); const setEdgesData = useRef<Edge[]>();
const setEdgesTimeout = useRef<ReturnType<typeof setTimeout>>(); const setEdgesTimeout = useRef<ReturnType<typeof setTimeout>>();
const setEdges = useCallback<Instance.SetEdges<EdgeType>>((payload) => { const setEdges = useCallback<Instance.SetEdges<EdgeType>>((payload) => {
@@ -93,6 +94,8 @@ export function useReactFlow<NodeType extends Node = Node, EdgeType extends Edge
const changes: EdgeChange[] = getElementsDiffChanges({ items: nextEdges, lookup: edgeLookup }); const changes: EdgeChange[] = getElementsDiffChanges({ items: nextEdges, lookup: edgeLookup });
onEdgesChange(changes); onEdgesChange(changes);
} }
setEdgesData.current = undefined;
}, 0); }, 0);
}, []); }, []);