From 93af3409c4ece2800765512b164e4c546aee466f Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 14 Aug 2024 16:33:08 +0200 Subject: [PATCH] fix(react/fitView): only trigger for resize observer --- .../react/src/hooks/useUpdateNodeInternals.ts | 2 +- packages/react/src/store/index.ts | 35 +++++++++++-------- packages/react/src/types/store.ts | 2 +- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/packages/react/src/hooks/useUpdateNodeInternals.ts b/packages/react/src/hooks/useUpdateNodeInternals.ts index 63965d72..6486afd8 100644 --- a/packages/react/src/hooks/useUpdateNodeInternals.ts +++ b/packages/react/src/hooks/useUpdateNodeInternals.ts @@ -25,6 +25,6 @@ export function useUpdateNodeInternals(): UpdateNodeInternals { } }); - requestAnimationFrame(() => updateNodeInternals(updates)); + requestAnimationFrame(() => updateNodeInternals(updates, { triggerFitView: false })); }, []); } diff --git a/packages/react/src/store/index.ts b/packages/react/src/store/index.ts index 01604143..c45d8f2d 100644 --- a/packages/react/src/store/index.ts +++ b/packages/react/src/store/index.ts @@ -77,7 +77,7 @@ const createStore = ({ // Every node gets registerd at a ResizeObserver. Whenever a node // changes its dimensions, this function is called to measure the // new dimensions and update the nodes. - updateNodeInternals: (updates) => { + updateNodeInternals: (updates, params = { triggerFitView: true }) => { const { triggerNodeChanges, nodeLookup, @@ -105,23 +105,28 @@ const createStore = ({ updateAbsolutePositions(nodeLookup, parentLookup, { nodeOrigin }); - // we call fitView once initially after all dimensions are set - let nextFitViewDone = fitViewDone; + if (params.triggerFitView) { + // we call fitView once initially after all dimensions are set + let nextFitViewDone = fitViewDone; - if (!fitViewDone && fitViewOnInit) { - nextFitViewDone = fitViewSync({ - ...fitViewOnInitOptions, - nodes: fitViewOnInitOptions?.nodes, - }); + if (!fitViewDone && fitViewOnInit) { + nextFitViewDone = fitViewSync({ + ...fitViewOnInitOptions, + nodes: fitViewOnInitOptions?.nodes, + }); + } + + // here we are cirmumventing the onNodesChange handler + // in order to be able to display nodes even if the user + // has not provided an onNodesChange handler. + // Nodes are only rendered if they have a width and height + // attribute which they get from this handler. + set({ fitViewDone: nextFitViewDone }); + } else { + // we always want to trigger useStore calls whenever updateNodeInternals is called + set({}); } - // here we are cirmumventing the onNodesChange handler - // in order to be able to display nodes even if the user - // has not provided an onNodesChange handler. - // Nodes are only rendered if they have a width and height - // attribute which they get from this handler. - set({ fitViewDone: nextFitViewDone }); - if (changes?.length > 0) { if (debug) { console.log('React Flow: trigger node changes', changes); diff --git a/packages/react/src/types/store.ts b/packages/react/src/types/store.ts index 8ddd2ff8..beeb85b3 100644 --- a/packages/react/src/types/store.ts +++ b/packages/react/src/types/store.ts @@ -152,7 +152,7 @@ export type ReactFlowActions = { setNodes: (nodes: NodeType[]) => void; setEdges: (edges: EdgeType[]) => void; setDefaultNodesAndEdges: (nodes?: NodeType[], edges?: EdgeType[]) => void; - updateNodeInternals: (updates: Map) => void; + updateNodeInternals: (updates: Map, params?: { triggerFitView: boolean }) => void; updateNodePositions: UpdateNodePositions; resetSelectedElements: () => void; unselectNodesAndEdges: (params?: UnselectNodesAndEdgesParams) => void;