diff --git a/README.md b/README.md index 1ebc6c88..fb4e8edc 100644 --- a/README.md +++ b/README.md @@ -604,7 +604,7 @@ const TransformUpdater = ({ x, y, zoom }) => { }); ``` -If you need more control you can wrap the `ReactFlow` component with the `ReactFlowProvider` component in order to be able to call `useStoreState` outside of the `ReactFlow` component. +If you need more control you can wrap the `ReactFlow` component with the `ReactFlowProvider` component in order to be able to call `useStoreState` and `useStoreActions` outside of the `ReactFlow` component. # Examples diff --git a/example/src/Provider/index.js b/example/src/Provider/index.js index 07d3ca8d..b4b8f305 100644 --- a/example/src/Provider/index.js +++ b/example/src/Provider/index.js @@ -6,6 +6,7 @@ import Sidebar from './Sidebar'; import './provider.css'; const onElementClick = (event, element) => console.log('click', element); +const onLoad = (reactFlowInstance) => console.log('flow loaded:', reactFlowInstance); const initialElements = [ { id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } }, @@ -31,6 +32,7 @@ const ProviderFlow = () => { onElementClick={onElementClick} onConnect={onConnect} onElementsRemove={onElementsRemove} + onLoad={onLoad} > diff --git a/src/container/GraphView/index.tsx b/src/container/GraphView/index.tsx index 16466913..51718fbd 100644 --- a/src/container/GraphView/index.tsx +++ b/src/container/GraphView/index.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useRef, useCallback, memo, CSSProperties, MouseEvent } from 'react'; -import { useStoreState, useStoreActions } from '../../store/hooks'; +import { useStoreState, useStoreActions, useStore } from '../../store/hooks'; import NodeRenderer from '../NodeRenderer'; import EdgeRenderer from '../EdgeRenderer'; import UserSelection from '../../components/UserSelection'; @@ -10,7 +10,7 @@ import useD3Zoom from '../../hooks/useD3Zoom'; import useGlobalKeyHandler from '../../hooks/useGlobalKeyHandler'; import useElementUpdater from '../../hooks/useElementUpdater'; import useResizeHandler from '../../hooks/useResizeHandler'; -import { project, getElements } from '../../utils/graph'; +import { onLoadProject, onLoadGetElements } from '../../utils/graph'; import { Elements, NodeTypesType, @@ -128,6 +128,7 @@ const GraphView = ({ const fitView = useStoreActions((actions) => actions.fitView); const zoom = useStoreActions((actions) => actions.zoom); const zoomTo = useStoreActions((actions) => actions.zoomTo); + const currentStore = useStore(); const onZoomPaneClick = useCallback( (event: React.MouseEvent) => { @@ -169,8 +170,8 @@ const GraphView = ({ zoomIn: () => zoom(0.2), zoomOut: () => zoom(-0.2), zoomTo: (zoomLevel) => zoomTo(zoomLevel), - project, - getElements, + project: onLoadProject(currentStore), + getElements: onLoadGetElements(currentStore), setTransform: (transform: FlowTransform) => setInitTransform({ x: transform.x, y: transform.y, k: transform.zoom }), }); diff --git a/src/store/hooks.ts b/src/store/hooks.ts index a752a6fb..0a17ba7c 100644 --- a/src/store/hooks.ts +++ b/src/store/hooks.ts @@ -7,3 +7,4 @@ const typedHooks = createTypedHooks(); export const useStoreActions = typedHooks.useStoreActions; export const useStoreDispatch = typedHooks.useStoreDispatch; export const useStoreState = typedHooks.useStoreState; +export const useStore = typedHooks.useStore; diff --git a/src/utils/graph.ts b/src/utils/graph.ts index ad593f0b..1d104749 100644 --- a/src/utils/graph.ts +++ b/src/utils/graph.ts @@ -1,5 +1,6 @@ -import store from '../store'; +import store, { StoreModel } from '../store'; import { ElementId, Node, Edge, Elements, Transform, XYPosition, Rect, FitViewParams, Box, Connection } from '../types'; +import { Store } from 'easy-peasy'; export const isEdge = (element: Node | Connection | Edge): element is Edge => 'id' in element && 'source' in element && 'target' in element; @@ -77,6 +78,14 @@ export const pointToRendererPoint = ( return position; }; +export const onLoadProject = (currentStore: Store) => { + return (position: XYPosition): XYPosition => { + const { transform, snapToGrid, snapGrid } = currentStore.getState(); + + return pointToRendererPoint(position, transform, snapToGrid, snapGrid); + }; +}; + export const project = (position: XYPosition): XYPosition => { const { transform, snapToGrid, snapGrid } = store.getState(); @@ -207,9 +216,7 @@ export const zoomIn = (): void => zoom(0.2); export const zoomOut = (): void => zoom(-0.2); -export const getElements = (): Elements => { - const { nodes, edges } = store.getState(); - +const parseElements = (nodes: Node[], edges: Edge[]): Elements => { return [ ...nodes.map((node) => { const n = { ...node }; @@ -220,3 +227,17 @@ export const getElements = (): Elements => { ...edges.map((e) => ({ ...e })), ]; }; + +export const onLoadGetElements = (currentStore: Store) => { + return (): Elements => { + const { nodes = [], edges = [] } = currentStore.getState(); + + return parseElements(nodes, edges); + }; +}; + +export const getElements = (): Elements => { + const { nodes = [], edges = [] } = store.getState(); + + return parseElements(nodes, edges); +};