Files
xyflow/example/src/SaveRestore/Controls.tsx
T

62 lines
1.7 KiB
TypeScript

import React, { memo, useCallback, Dispatch, FC } from 'react';
import { useZoomPanHelper, OnLoadParams, Elements, 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?: OnLoadParams;
setElements: Dispatch<React.SetStateAction<Elements<any>>>;
};
const Controls: FC<ControlsProps> = ({ rfInstance, setElements }) => {
const { transform } = 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;
setElements(flow.elements || []);
transform({ x, y, zoom: flow.zoom || 0 });
}
};
restoreFlow();
}, [setElements, transform]);
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 },
};
setElements((els) => els.concat(newNode));
}, [setElements]);
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);