feat(rf): add fitViewOnInit option

This commit is contained in:
moklick
2021-12-08 23:19:43 +01:00
parent 91256c1f92
commit 266007b38b
2 changed files with 55 additions and 1 deletions
+51
View File
@@ -0,0 +1,51 @@
import React, { MutableRefObject, useEffect, useRef } from 'react';
import { Node } from '../../types';
import { getRectOfNodes, getTransformForBounds } from '../../utils/graph';
import { useStoreApi } from '../../store';
import useZoomPanHelper from '../../hooks/useZoomPanHelper';
type ViewFitterInnerProps = {
nodes: Node[];
viewFitted: MutableRefObject<boolean>;
};
function ViewFitterInner({ nodes, viewFitted }: ViewFitterInnerProps) {
const store = useStoreApi();
const { setTransform } = useZoomPanHelper();
useEffect(() => {
if (nodes.length > 0 && !viewFitted.current) {
const nodesInitialized = nodes.every((n) => n.width && n.height);
if (nodesInitialized) {
const { width, height, minZoom, maxZoom } = store.getState();
const bounds = getRectOfNodes(nodes);
const [x, y, zoom] = getTransformForBounds(bounds, width, height, minZoom ?? 0.5, maxZoom ?? 2);
viewFitted.current = true;
setTransform({ x, y, zoom });
}
}
}, [nodes]);
return null;
}
export type ViewFitterProps = {
nodes: Node[];
};
function ViewFitter({ nodes }: ViewFitterProps) {
// we are storing the viewFitted in this wrapper to get rid of the useEffect of the inner component
// that needs to check if the nodes changed after we fitted the view.
const viewFitted = useRef<boolean>(false);
if (viewFitted.current) {
return null;
}
return <ViewFitterInner nodes={nodes} viewFitted={viewFitted} />;
}
export default ViewFitter;
+4 -1
View File
@@ -19,6 +19,7 @@ import SelectionListener from '../../components/SelectionListener';
import { BezierEdge, StepEdge, SmoothStepEdge, StraightEdge } from '../../components/Edges';
import { createEdgeTypes } from '../EdgeRenderer/utils';
import Wrapper from './Wrapper';
import ViewFitter from '../../components/ViewFitter';
import {
OnSelectionChangeFunc,
NodeTypesType,
@@ -133,6 +134,7 @@ export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'on
noDragClassName?: string;
noWheelClassName?: string;
noPanClassName?: string;
fitViewOnInit?: boolean;
}
export type ReactFlowRefType = HTMLDivElement;
@@ -219,6 +221,7 @@ const ReactFlow: FunctionComponent<ReactFlowProps> = forwardRef<ReactFlowRefType
noDragClassName = 'nodrag',
noWheelClassName = 'nowheel',
noPanClassName = 'nopan',
fitViewOnInit = false,
...rest
},
ref
@@ -307,7 +310,7 @@ const ReactFlow: FunctionComponent<ReactFlowProps> = forwardRef<ReactFlowRefType
connectionMode={connectionMode}
translateExtent={translateExtent}
/>
{fitViewOnInit && <ViewFitter nodes={nodes} />}
{onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />}
{children}
</Wrapper>