Add back promise resolution for transitioning on fitView

This commit is contained in:
peterkogo
2025-03-05 15:00:44 +01:00
parent ee1ef205eb
commit f208223400
6 changed files with 21 additions and 18 deletions

View File

@@ -279,9 +279,11 @@ export function useReactFlow<NodeType extends Node = Node, EdgeType extends Edge
.connectionLookup.get(`${nodeId}${type ? (handleId ? `-${type}-${handleId}` : `-${type}`) : ''}`)
?.values() ?? []
),
fitView: (options: FitViewOptions<NodeType> | undefined) => {
store.setState({ fitViewQueued: true, fitViewOptions: options });
fitView: async (options: FitViewOptions<NodeType> | undefined) => {
const fitViewResolver = store.getState().fitViewResolver ?? Promise.withResolvers<boolean>();
store.setState({ fitViewQueued: true, fitViewOptions: options, fitViewResolver });
batchContext.nodeQueue.push((nodes) => [...nodes]);
return fitViewResolver.promise;
},
};
}, []);

View File

@@ -62,10 +62,9 @@ const createStore = ({
checkEquality: true,
});
let viewportFitted = false;
if (fitViewQueued && nodesInitialized && panZoom) {
const { fitViewOptions, width, height, minZoom, maxZoom } = get();
viewportFitted = fitViewport(
const { fitViewOptions, fitViewResolver, width, height, minZoom, maxZoom } = get();
const fitViewPromise = fitViewport(
{
nodes: nodeLookup,
width,
@@ -76,9 +75,10 @@ const createStore = ({
},
fitViewOptions
);
}
if (viewportFitted) {
fitViewPromise.then((value) => {
fitViewResolver?.resolve(value);
set({ fitViewResolver: null });
});
set({ nodes, fitViewQueued: false, fitViewOptions: undefined });
} else {
set({ nodes });

View File

@@ -110,6 +110,7 @@ const getInitialState = ({
fitViewQueued: false,
fitViewOptions: undefined,
fitViewResolver: null,
connection: { ...initialConnection },
connectionClickStartHandle: null,

View File

@@ -109,7 +109,7 @@ export type FitViewParams<NodeType extends Node = Node> = FitViewParamsBase<Node
* @public
*/
export type FitViewOptions<NodeType extends Node = Node> = FitViewOptionsBase<NodeType>;
export type FitView<NodeType extends Node = Node> = (fitViewOptions?: FitViewOptions<NodeType>) => void;
export type FitView<NodeType extends Node = Node> = (fitViewOptions?: FitViewOptions<NodeType>) => Promise<boolean>;
export type OnInit<NodeType extends Node = Node, EdgeType extends Edge = Edge> = (
reactFlowInstance: ReactFlowInstance<NodeType, EdgeType>
) => void;

View File

@@ -121,6 +121,7 @@ export type ReactFlowStore<NodeType extends Node = Node, EdgeType extends Edge =
fitViewQueued: boolean;
fitViewOptions: FitViewOptions | undefined;
fitViewResolver: PromiseWithResolvers<boolean> | null;
onNodesDelete?: OnNodesDelete<NodeType>;
onEdgesDelete?: OnEdgesDelete<EdgeType>;

View File

@@ -351,16 +351,15 @@ function getFitViewNodes<
return fitViewNodes;
}
export function fitViewport<Params extends FitViewParamsBase<NodeBase>, Options extends FitViewOptionsBase<NodeBase>>(
export async function fitViewport<
Params extends FitViewParamsBase<NodeBase>,
Options extends FitViewOptionsBase<NodeBase>
>(
{ nodes, width, height, panZoom, minZoom, maxZoom }: Params,
options?: Omit<Options, 'nodes' | 'includeHiddenNodes'>
): boolean {
): Promise<boolean> {
if (nodes.size === 0) {
return true;
}
if (!panZoom) {
return false;
return Promise.resolve(true);
}
const nodesToFit = getFitViewNodes(nodes, options);
@@ -376,9 +375,9 @@ export function fitViewport<Params extends FitViewParamsBase<NodeBase>, Options
options?.padding ?? 0.1
);
panZoom.setViewport(viewport, { duration: options?.duration });
await panZoom.setViewport(viewport, { duration: options?.duration });
return true;
return Promise.resolve(true);
}
/**