FlowWrapper.tsx 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import React from "react";
  2. import ReactFlow, {
  3. ControlButton,
  4. Controls,
  5. Elements,
  6. MiniMap,
  7. NodeExtent,
  8. OnLoadParams,
  9. } from "react-flow-renderer";
  10. import { StorageConfig } from "src/typings/global";
  11. import { useLocalStorage } from "usehooks-ts";
  12. import { defaultValue } from "../JsonEditor";
  13. import { getLayout, getLayoutPosition } from "./helpers";
  14. import { CustomNodeComponent } from "./Node";
  15. const nodeExtent: NodeExtent = [
  16. [0, 0],
  17. [1000, 1000],
  18. ];
  19. const nodeTypes = {
  20. special: CustomNodeComponent,
  21. };
  22. export const FlowWrapper: React.FC = () => {
  23. const [json] = useLocalStorage("json", JSON.stringify(defaultValue));
  24. const [config] = useLocalStorage<StorageConfig>("config", {
  25. layout: "RL",
  26. minimap: true,
  27. controls: true,
  28. });
  29. const [elements, setElements] = React.useState<Elements>([]);
  30. const [rfInstance, setRfInstance] = React.useState<OnLoadParams | null>(null);
  31. const [valid, setValid] = React.useState(true);
  32. const handleClick = () => {
  33. setElements(getLayoutPosition(config.layout, elements));
  34. };
  35. React.useEffect(() => {
  36. if (rfInstance) rfInstance.fitView();
  37. }, [rfInstance]);
  38. React.useEffect(() => {
  39. try {
  40. const layoutedElements = getLayout(config.layout, json);
  41. setElements(layoutedElements);
  42. setValid(true);
  43. } catch (error) {
  44. setValid(false);
  45. }
  46. }, [rfInstance, json, config]);
  47. if (!valid) return null;
  48. return (
  49. <ReactFlow
  50. nodeExtent={nodeExtent}
  51. elements={elements}
  52. nodeTypes={nodeTypes}
  53. onLoad={setRfInstance}
  54. >
  55. {config.minimap && <MiniMap />}
  56. {config.controls && (
  57. <Controls>
  58. <ControlButton
  59. onClick={handleClick}
  60. style={{ gridColumn: "1 / 3", width: "auto" }}
  61. >
  62. Format
  63. </ControlButton>
  64. </Controls>
  65. )}
  66. </ReactFlow>
  67. );
  68. };