merg main
This commit is contained in:
@@ -32,6 +32,7 @@ function ResizeControl({
|
||||
maxWidth = Number.MAX_VALUE,
|
||||
maxHeight = Number.MAX_VALUE,
|
||||
keepAspectRatio = false,
|
||||
resizeDirection,
|
||||
shouldResize,
|
||||
onResizeStart,
|
||||
onResize,
|
||||
@@ -117,11 +118,12 @@ function ResizeControl({
|
||||
}
|
||||
|
||||
if (change.width !== undefined && change.height !== undefined) {
|
||||
const setAttributes = !resizeDirection ? true : resizeDirection === 'horizontal' ? 'width' : 'height';
|
||||
const dimensionChange: NodeDimensionChange = {
|
||||
id,
|
||||
type: 'dimensions',
|
||||
resizing: true,
|
||||
setAttributes: true,
|
||||
setAttributes,
|
||||
dimensions: {
|
||||
width: change.width,
|
||||
height: change.height,
|
||||
@@ -166,6 +168,7 @@ function ResizeControl({
|
||||
maxHeight,
|
||||
},
|
||||
keepAspectRatio,
|
||||
resizeDirection,
|
||||
onResizeStart,
|
||||
onResize,
|
||||
onResizeEnd,
|
||||
|
||||
@@ -3,6 +3,7 @@ import type {
|
||||
ControlPosition,
|
||||
ControlLinePosition,
|
||||
ResizeControlVariant,
|
||||
ResizeControlDirection,
|
||||
ShouldResize,
|
||||
OnResizeStart,
|
||||
OnResize,
|
||||
@@ -97,6 +98,11 @@ export type ResizeControlProps = Pick<
|
||||
* @example ResizeControlVariant.Handle, ResizeControlVariant.Line
|
||||
*/
|
||||
variant?: ResizeControlVariant;
|
||||
/**
|
||||
* The direction the user can resize the node.
|
||||
* If not provided, the user can resize in any direction.
|
||||
*/
|
||||
resizeDirection?: ResizeControlDirection;
|
||||
className?: string;
|
||||
style?: CSSProperties;
|
||||
children?: ReactNode;
|
||||
@@ -105,6 +111,6 @@ export type ResizeControlProps = Pick<
|
||||
/**
|
||||
* @expand
|
||||
*/
|
||||
export type ResizeControlLineProps = ResizeControlProps & {
|
||||
export type ResizeControlLineProps = Omit<ResizeControlProps, 'resizeDirection'> & {
|
||||
position?: ControlLinePosition;
|
||||
};
|
||||
|
||||
@@ -40,28 +40,27 @@ export function BatchProvider<NodeType extends Node = Node, EdgeType extends Edg
|
||||
next = typeof payload === 'function' ? payload(next) : payload;
|
||||
}
|
||||
|
||||
const changes = getElementsDiffChanges({
|
||||
items: next,
|
||||
lookup: nodeLookup,
|
||||
}) as NodeChange<NodeType>[];
|
||||
|
||||
if (hasDefaultNodes) {
|
||||
setNodes(next);
|
||||
} else {
|
||||
// When a controlled flow is used we need to collect the changes
|
||||
const changes = getElementsDiffChanges({
|
||||
items: next,
|
||||
lookup: nodeLookup,
|
||||
}) as NodeChange<NodeType>[];
|
||||
}
|
||||
|
||||
// We only want to fire onNodesChange if there are changes to the nodes
|
||||
if (changes.length > 0) {
|
||||
onNodesChange?.(changes);
|
||||
} else if (fitViewQueued) {
|
||||
// If there are no changes to the nodes, we still need to call setNodes
|
||||
// to trigger a re-render and fitView.
|
||||
window.requestAnimationFrame(() => {
|
||||
const { fitViewQueued, nodes, setNodes } = store.getState();
|
||||
if (fitViewQueued) {
|
||||
setNodes(nodes);
|
||||
}
|
||||
});
|
||||
}
|
||||
// We only want to fire onNodesChange if there are changes to the nodes
|
||||
if (changes.length > 0) {
|
||||
onNodesChange?.(changes);
|
||||
} else if (fitViewQueued) {
|
||||
// If there are no changes to the nodes, we still need to call setNodes
|
||||
// to trigger a re-render and fitView.
|
||||
window.requestAnimationFrame(() => {
|
||||
const { fitViewQueued, nodes, setNodes } = store.getState();
|
||||
if (fitViewQueued) {
|
||||
setNodes(nodes);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -3,18 +3,49 @@ import { useState, type ReactNode } from 'react';
|
||||
import { Provider } from '../../contexts/StoreContext';
|
||||
import { createStore } from '../../store';
|
||||
import { BatchProvider } from '../BatchProvider';
|
||||
import type { Node, Edge } from '../../types';
|
||||
import type { Node, Edge, FitViewOptions } from '../../types';
|
||||
import { CoordinateExtent, NodeOrigin } from '@xyflow/system';
|
||||
|
||||
export type ReactFlowProviderProps = {
|
||||
/** These nodes are used to initialize the flow. They are not dynamic. */
|
||||
initialNodes?: Node[];
|
||||
/** These edges are used to initialize the flow. They are not dynamic. */
|
||||
initialEdges?: Edge[];
|
||||
/** These nodes are used to initialize the flow. They are not dynamic. */
|
||||
defaultNodes?: Node[];
|
||||
/** These edges are used to initialize the flow. They are not dynamic. */
|
||||
defaultEdges?: Edge[];
|
||||
/** The initial width is necessary to be able to use fitView on the server */
|
||||
initialWidth?: number;
|
||||
/** The initial height is necessary to be able to use fitView on the server */
|
||||
initialHeight?: number;
|
||||
/** When `true`, the flow will be zoomed and panned to fit all the nodes initially provided. */
|
||||
fitView?: boolean;
|
||||
/**
|
||||
* You can provide an object of options to customize the initial fitView behavior.
|
||||
*/
|
||||
initialFitViewOptions?: FitViewOptions;
|
||||
/** Initial minimum zoom level */
|
||||
initialMinZoom?: number;
|
||||
/** Initial maximum zoom level */
|
||||
initialMaxZoom?: number;
|
||||
/**
|
||||
* The origin of the node to use when placing it in the flow or looking up its `x` and `y`
|
||||
* position. An origin of `[0, 0]` means that a node's top left corner will be placed at the `x`
|
||||
* and `y` position.
|
||||
* @default [0, 0]
|
||||
* @example
|
||||
* [0, 0] // default, top left
|
||||
* [0.5, 0.5] // center
|
||||
* [1, 1] // bottom right
|
||||
*/
|
||||
nodeOrigin?: NodeOrigin;
|
||||
/**
|
||||
* By default, nodes can be placed on an infinite flow. You can use this prop to set a boundary.
|
||||
*
|
||||
* The first pair of coordinates is the top left boundary and the second pair is the bottom right.
|
||||
* @example [[-1000, -10000], [1000, 1000]]
|
||||
*/
|
||||
nodeExtent?: CoordinateExtent;
|
||||
children: ReactNode;
|
||||
};
|
||||
@@ -60,6 +91,9 @@ export function ReactFlowProvider({
|
||||
defaultEdges,
|
||||
initialWidth: width,
|
||||
initialHeight: height,
|
||||
initialMinZoom: minZoom,
|
||||
initialMaxZoom: maxZoom,
|
||||
initialFitViewOptions: fitViewOptions,
|
||||
fitView,
|
||||
nodeOrigin,
|
||||
nodeExtent,
|
||||
@@ -74,6 +108,9 @@ export function ReactFlowProvider({
|
||||
width,
|
||||
height,
|
||||
fitView,
|
||||
minZoom,
|
||||
maxZoom,
|
||||
fitViewOptions,
|
||||
nodeOrigin,
|
||||
nodeExtent,
|
||||
})
|
||||
|
||||
@@ -67,7 +67,7 @@ const MarkerDefinitions = ({ defaultColor, rfId }: MarkerDefinitionsProps) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<svg className="react-flow__marker">
|
||||
<svg className="react-flow__marker" aria-hidden="true">
|
||||
<defs>
|
||||
{markers.map((marker: MarkerProps) => (
|
||||
<Marker
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useContext, type ReactNode } from 'react';
|
||||
|
||||
import StoreContext from '../../contexts/StoreContext';
|
||||
import { ReactFlowProvider } from '../../components/ReactFlowProvider';
|
||||
import type { Node, Edge } from '../../types';
|
||||
import type { Node, Edge, FitViewOptions } from '../../types';
|
||||
import { CoordinateExtent, NodeOrigin } from '@xyflow/system';
|
||||
|
||||
export function Wrapper({
|
||||
@@ -14,6 +14,9 @@ export function Wrapper({
|
||||
width,
|
||||
height,
|
||||
fitView,
|
||||
fitViewOptions,
|
||||
minZoom,
|
||||
maxZoom,
|
||||
nodeOrigin,
|
||||
nodeExtent,
|
||||
}: {
|
||||
@@ -25,6 +28,9 @@ export function Wrapper({
|
||||
width?: number;
|
||||
height?: number;
|
||||
fitView?: boolean;
|
||||
fitViewOptions?: FitViewOptions;
|
||||
minZoom?: number;
|
||||
maxZoom?: number;
|
||||
nodeOrigin?: NodeOrigin;
|
||||
nodeExtent?: CoordinateExtent;
|
||||
}) {
|
||||
@@ -47,6 +53,9 @@ export function Wrapper({
|
||||
initialWidth={width}
|
||||
initialHeight={height}
|
||||
fitView={fitView}
|
||||
initialFitViewOptions={fitViewOptions}
|
||||
initialMinZoom={minZoom}
|
||||
initialMaxZoom={maxZoom}
|
||||
nodeOrigin={nodeOrigin}
|
||||
nodeExtent={nodeExtent}
|
||||
>
|
||||
|
||||
@@ -177,6 +177,9 @@ function ReactFlow<NodeType extends Node = Node, EdgeType extends Edge = Edge>(
|
||||
width={width}
|
||||
height={height}
|
||||
fitView={fitView}
|
||||
fitViewOptions={fitViewOptions}
|
||||
minZoom={minZoom}
|
||||
maxZoom={maxZoom}
|
||||
nodeOrigin={nodeOrigin}
|
||||
nodeExtent={nodeExtent}
|
||||
>
|
||||
|
||||
@@ -9,15 +9,17 @@ export type UseNodesInitializedOptions = {
|
||||
};
|
||||
|
||||
const selector = (options: UseNodesInitializedOptions) => (s: ReactFlowState) => {
|
||||
if (!options.includeHiddenNodes) {
|
||||
return s.nodesInitialized;
|
||||
}
|
||||
|
||||
if (s.nodeLookup.size === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const [, { hidden, internals }] of s.nodeLookup) {
|
||||
if (options.includeHiddenNodes || !hidden) {
|
||||
if (internals.handleBounds === undefined || !nodeHasDimensions(internals.userNode)) {
|
||||
return false;
|
||||
}
|
||||
for (const [, { internals }] of s.nodeLookup) {
|
||||
if (internals.handleBounds === undefined || !nodeHasDimensions(internals.userNode)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
isRectObject,
|
||||
NodeRemoveChange,
|
||||
nodeToRect,
|
||||
withResolvers,
|
||||
type Rect,
|
||||
} from '@xyflow/system';
|
||||
|
||||
@@ -280,7 +281,7 @@ export function useReactFlow<NodeType extends Node = Node, EdgeType extends Edge
|
||||
fitView: async (options: FitViewOptions<NodeType> | undefined) => {
|
||||
// We either create a new Promise or reuse the existing one
|
||||
// Even if fitView is called multiple times in a row, we only end up with a single Promise
|
||||
const fitViewResolver = store.getState().fitViewResolver ?? Promise.withResolvers<boolean>();
|
||||
const fitViewResolver = store.getState().fitViewResolver ?? withResolvers<boolean>();
|
||||
|
||||
// We schedule a fitView by setting fitViewQueued and triggering a setNodes
|
||||
store.setState({ fitViewQueued: true, fitViewOptions: options, fitViewResolver });
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
|
||||
import { applyEdgeChanges, applyNodeChanges, createSelectionChange, getSelectionChanges } from '../utils/changes';
|
||||
import getInitialState from './initialState';
|
||||
import type { ReactFlowState, Node, Edge, UnselectNodesAndEdgesParams } from '../types';
|
||||
import type { ReactFlowState, Node, Edge, UnselectNodesAndEdgesParams, FitViewOptions } from '../types';
|
||||
|
||||
const createStore = ({
|
||||
nodes,
|
||||
@@ -28,6 +28,9 @@ const createStore = ({
|
||||
width,
|
||||
height,
|
||||
fitView,
|
||||
fitViewOptions,
|
||||
minZoom,
|
||||
maxZoom,
|
||||
nodeOrigin,
|
||||
nodeExtent,
|
||||
}: {
|
||||
@@ -38,6 +41,9 @@ const createStore = ({
|
||||
width?: number;
|
||||
height?: number;
|
||||
fitView?: boolean;
|
||||
fitViewOptions?: FitViewOptions;
|
||||
minZoom?: number;
|
||||
maxZoom?: number;
|
||||
nodeOrigin?: NodeOrigin;
|
||||
nodeExtent?: CoordinateExtent;
|
||||
}) =>
|
||||
@@ -70,7 +76,20 @@ const createStore = ({
|
||||
}
|
||||
|
||||
return {
|
||||
...getInitialState({ nodes, edges, width, height, fitView, nodeOrigin, nodeExtent, defaultNodes, defaultEdges }),
|
||||
...getInitialState({
|
||||
nodes,
|
||||
edges,
|
||||
width,
|
||||
height,
|
||||
fitView,
|
||||
fitViewOptions,
|
||||
minZoom,
|
||||
maxZoom,
|
||||
nodeOrigin,
|
||||
nodeExtent,
|
||||
defaultNodes,
|
||||
defaultEdges,
|
||||
}),
|
||||
setNodes: (nodes: Node[]) => {
|
||||
const { nodeLookup, parentLookup, nodeOrigin, elevateNodesOnSelect, fitViewQueued } = get();
|
||||
/*
|
||||
@@ -91,9 +110,9 @@ const createStore = ({
|
||||
|
||||
if (fitViewQueued && nodesInitialized) {
|
||||
resolveFitView();
|
||||
set({ nodes, fitViewQueued: false, fitViewOptions: undefined });
|
||||
set({ nodes, nodesInitialized, fitViewQueued: false, fitViewOptions: undefined });
|
||||
} else {
|
||||
set({ nodes });
|
||||
set({ nodes, nodesInitialized });
|
||||
}
|
||||
},
|
||||
setEdges: (edges: Edge[]) => {
|
||||
@@ -297,7 +316,11 @@ const createStore = ({
|
||||
get().panZoom?.setClickDistance(clickDistance);
|
||||
},
|
||||
resetSelectedElements: () => {
|
||||
const { edges, nodes, triggerNodeChanges, triggerEdgeChanges } = get();
|
||||
const { edges, nodes, triggerNodeChanges, triggerEdgeChanges, elementsSelectable } = get();
|
||||
|
||||
if (!elementsSelectable) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nodeChanges = nodes.reduce<NodeSelectionChange[]>(
|
||||
(res, node) => (node.selected ? [...res, createSelectionChange(node.id, false)] : res),
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
CoordinateExtent,
|
||||
} from '@xyflow/system';
|
||||
|
||||
import type { Edge, InternalNode, Node, ReactFlowStore } from '../types';
|
||||
import type { Edge, FitViewOptions, InternalNode, Node, ReactFlowStore } from '../types';
|
||||
|
||||
const getInitialState = ({
|
||||
nodes,
|
||||
@@ -22,6 +22,9 @@ const getInitialState = ({
|
||||
width,
|
||||
height,
|
||||
fitView,
|
||||
fitViewOptions,
|
||||
minZoom = 0.5,
|
||||
maxZoom = 2,
|
||||
nodeOrigin,
|
||||
nodeExtent,
|
||||
}: {
|
||||
@@ -32,6 +35,9 @@ const getInitialState = ({
|
||||
width?: number;
|
||||
height?: number;
|
||||
fitView?: boolean;
|
||||
fitViewOptions?: FitViewOptions;
|
||||
minZoom?: number;
|
||||
maxZoom?: number;
|
||||
nodeOrigin?: NodeOrigin;
|
||||
nodeExtent?: CoordinateExtent;
|
||||
} = {}): ReactFlowStore => {
|
||||
@@ -46,7 +52,7 @@ const getInitialState = ({
|
||||
const storeNodeExtent = nodeExtent ?? infiniteExtent;
|
||||
|
||||
updateConnectionLookup(connectionLookup, edgeLookup, storeEdges);
|
||||
adoptUserNodes(storeNodes, nodeLookup, parentLookup, {
|
||||
const nodesInitialized = adoptUserNodes(storeNodes, nodeLookup, parentLookup, {
|
||||
nodeOrigin: storeNodeOrigin,
|
||||
nodeExtent: storeNodeExtent,
|
||||
elevateNodesOnSelect: false,
|
||||
@@ -59,7 +65,14 @@ const getInitialState = ({
|
||||
filter: (node) => !!((node.width || node.initialWidth) && (node.height || node.initialHeight)),
|
||||
});
|
||||
|
||||
const { x, y, zoom } = getViewportForBounds(bounds, width, height, 0.5, 2, 0.1);
|
||||
const { x, y, zoom } = getViewportForBounds(
|
||||
bounds,
|
||||
width,
|
||||
height,
|
||||
minZoom,
|
||||
maxZoom,
|
||||
fitViewOptions?.padding ?? 0.1
|
||||
);
|
||||
transform = [x, y, zoom];
|
||||
}
|
||||
|
||||
@@ -69,6 +82,7 @@ const getInitialState = ({
|
||||
height: 0,
|
||||
transform,
|
||||
nodes: storeNodes,
|
||||
nodesInitialized,
|
||||
nodeLookup,
|
||||
parentLookup,
|
||||
edges: storeEdges,
|
||||
@@ -79,8 +93,8 @@ const getInitialState = ({
|
||||
hasDefaultNodes: defaultNodes !== undefined,
|
||||
hasDefaultEdges: defaultEdges !== undefined,
|
||||
panZoom: null,
|
||||
minZoom: 0.5,
|
||||
maxZoom: 2,
|
||||
minZoom,
|
||||
maxZoom,
|
||||
translateExtent: infiniteExtent,
|
||||
nodeExtent: storeNodeExtent,
|
||||
nodesSelectionActive: false,
|
||||
@@ -109,7 +123,7 @@ const getInitialState = ({
|
||||
multiSelectionActive: false,
|
||||
|
||||
fitViewQueued: fitView ?? false,
|
||||
fitViewOptions: undefined,
|
||||
fitViewOptions,
|
||||
fitViewResolver: null,
|
||||
|
||||
connection: { ...initialConnection },
|
||||
|
||||
@@ -85,22 +85,11 @@ export interface ReactFlowProps<NodeType extends Node = Node, EdgeType extends E
|
||||
defaultEdges?: EdgeType[];
|
||||
/**
|
||||
* Defaults to be applied to all new edges that are added to the flow.
|
||||
*
|
||||
* Properties on a new edge will override these defaults if they exist.
|
||||
* @example
|
||||
* const defaultEdgeOptions = {
|
||||
* type: 'customEdgeType',
|
||||
* animated: true,
|
||||
* interactionWidth: 10,
|
||||
* data: { label: 'custom label' },
|
||||
* hidden: false,
|
||||
* deletable: true,
|
||||
* selected: false,
|
||||
* focusable: true,
|
||||
* markerStart: EdgeMarker.ArrowClosed,
|
||||
* markerEnd: EdgeMarker.ArrowClosed,
|
||||
* zIndex: 12,
|
||||
* ariaLabel: 'custom aria label'
|
||||
* animated: true
|
||||
* }
|
||||
*/
|
||||
defaultEdgeOptions?: DefaultEdgeOptions;
|
||||
@@ -137,7 +126,6 @@ export interface ReactFlowProps<NodeType extends Node = Node, EdgeType extends E
|
||||
/**
|
||||
* This handler is called when the source or target of a reconnectable edge is dragged from the
|
||||
* current node. It will fire even if the edge's source or target do not end up changing.
|
||||
*
|
||||
* You can use the `reconnectEdge` utility to convert the connection to a new edge.
|
||||
*/
|
||||
onReconnect?: OnReconnect<EdgeType>;
|
||||
@@ -148,7 +136,6 @@ export interface ReactFlowProps<NodeType extends Node = Node, EdgeType extends E
|
||||
/**
|
||||
* This event fires when the user releases the source or target of an editable edge. It is called
|
||||
* even if an edge update does not occur.
|
||||
*
|
||||
*/
|
||||
onReconnectEnd?: (event: MouseEvent | TouchEvent, edge: EdgeType, handleType: HandleType) => void;
|
||||
/**
|
||||
@@ -209,7 +196,6 @@ export interface ReactFlowProps<NodeType extends Node = Node, EdgeType extends E
|
||||
onSelectionContextMenu?: (event: ReactMouseEvent, nodes: NodeType[]) => void;
|
||||
/**
|
||||
* When a connection line is completed and two nodes are connected by the user, this event fires with the new connection.
|
||||
*
|
||||
* You can use the `addEdge` utility to convert the connection to a complete edge.
|
||||
* @example // Use helper function to update edges onConnect
|
||||
* import ReactFlow, { addEdge } from '@xyflow/react';
|
||||
@@ -277,9 +263,7 @@ export interface ReactFlowProps<NodeType extends Node = Node, EdgeType extends E
|
||||
onBeforeDelete?: OnBeforeDelete<NodeType, EdgeType>;
|
||||
/**
|
||||
* Custom node types to be available in a flow.
|
||||
*
|
||||
* React Flow matches a node's type to a component in the `nodeTypes` object.
|
||||
* @TODO check if @default is correct
|
||||
* @default {
|
||||
* input: InputNode,
|
||||
* default: DefaultNode,
|
||||
@@ -294,9 +278,7 @@ export interface ReactFlowProps<NodeType extends Node = Node, EdgeType extends E
|
||||
nodeTypes?: NodeTypes;
|
||||
/**
|
||||
* Custom edge types to be available in a flow.
|
||||
*
|
||||
* React Flow matches an edge's type to a component in the `edgeTypes` object.
|
||||
* @TODO check if @default is correct
|
||||
* @default {
|
||||
* default: BezierEdge,
|
||||
* straight: StraightEdge,
|
||||
@@ -312,7 +294,6 @@ export interface ReactFlowProps<NodeType extends Node = Node, EdgeType extends E
|
||||
edgeTypes?: EdgeTypes;
|
||||
/**
|
||||
* The type of edge path to use for connection lines.
|
||||
*
|
||||
* Although created edges can be of any type, React Flow needs to know what type of path to render for the connection line before the edge is created!
|
||||
* @default ConnectionLineType.Bezier
|
||||
*/
|
||||
@@ -333,7 +314,7 @@ export interface ReactFlowProps<NodeType extends Node = Node, EdgeType extends E
|
||||
/**
|
||||
* If set, pressing the key or chord will delete any selected nodes and edges. Passing an array
|
||||
* represents multiple keys that can be pressed.
|
||||
*
|
||||
|
||||
* For example, `["Delete", "Backspace"]` will delete selected elements when either key is pressed.
|
||||
* @default 'Backspace'
|
||||
*/
|
||||
@@ -450,7 +431,6 @@ export interface ReactFlowProps<NodeType extends Node = Node, EdgeType extends E
|
||||
selectNodesOnDrag?: boolean;
|
||||
/**
|
||||
* Enabling this prop allows users to pan the viewport by clicking and dragging.
|
||||
*
|
||||
* You can also set this prop to an array of numbers to limit which mouse buttons can activate panning.
|
||||
* @default true
|
||||
* @example [0, 2] // allows panning with the left and right mouse buttons
|
||||
@@ -489,7 +469,6 @@ export interface ReactFlowProps<NodeType extends Node = Node, EdgeType extends E
|
||||
onViewportChange?: (viewport: Viewport) => void;
|
||||
/**
|
||||
* By default, the viewport extends infinitely. You can use this prop to set a boundary.
|
||||
*
|
||||
* The first pair of coordinates is the top left boundary and the second pair is the bottom right.
|
||||
* @default [[-∞, -∞], [+∞, +∞]]
|
||||
* @example [[-1000, -10000], [1000, 1000]]
|
||||
@@ -502,7 +481,6 @@ export interface ReactFlowProps<NodeType extends Node = Node, EdgeType extends E
|
||||
preventScrolling?: boolean;
|
||||
/**
|
||||
* By default, nodes can be placed on an infinite flow. You can use this prop to set a boundary.
|
||||
*
|
||||
* The first pair of coordinates is the top left boundary and the second pair is the bottom right.
|
||||
* @example [[-1000, -10000], [1000, 1000]]
|
||||
*/
|
||||
@@ -524,21 +502,18 @@ export interface ReactFlowProps<NodeType extends Node = Node, EdgeType extends E
|
||||
zoomOnPinch?: boolean;
|
||||
/**
|
||||
* Controls if the viewport should pan by scrolling inside the container.
|
||||
*
|
||||
* Can be limited to a specific direction with `panOnScrollMode`.
|
||||
* @default false
|
||||
*/
|
||||
panOnScroll?: boolean;
|
||||
/**
|
||||
* Controls how fast viewport should be panned on scroll.
|
||||
*
|
||||
* Use together with `panOnScroll` prop.
|
||||
* @default 0.5
|
||||
*/
|
||||
panOnScrollSpeed?: number;
|
||||
/**
|
||||
* This prop is used to limit the direction of panning when `panOnScroll` is enabled.
|
||||
*
|
||||
* The `"free"` option allows panning in any direction.
|
||||
* @default "free"
|
||||
* @example "horizontal" | "vertical"
|
||||
@@ -671,10 +646,8 @@ export interface ReactFlowProps<NodeType extends Node = Node, EdgeType extends E
|
||||
isValidConnection?: IsValidConnection<EdgeType>;
|
||||
/**
|
||||
* With a threshold greater than zero you can delay node drag events.
|
||||
*
|
||||
* If threshold equals 1, you need to drag the node 1 pixel before a drag event is fired.
|
||||
*
|
||||
* 1 is the default value, so clicks don't trigger drag events.
|
||||
* 1 is the default value, so that clicks don't trigger drag events.
|
||||
* @default 1
|
||||
*/
|
||||
nodeDragThreshold?: number;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
ConnectionMode,
|
||||
withResolvers,
|
||||
type ConnectionState,
|
||||
type CoordinateExtent,
|
||||
type InternalNodeUpdate,
|
||||
@@ -53,6 +54,7 @@ export type ReactFlowStore<NodeType extends Node = Node, EdgeType extends Edge =
|
||||
height: number;
|
||||
transform: Transform;
|
||||
nodes: NodeType[];
|
||||
nodesInitialized: boolean;
|
||||
nodeLookup: NodeLookup<InternalNode<NodeType>>;
|
||||
parentLookup: ParentLookup<InternalNode<NodeType>>;
|
||||
edges: EdgeType[];
|
||||
@@ -121,7 +123,7 @@ export type ReactFlowStore<NodeType extends Node = Node, EdgeType extends Edge =
|
||||
|
||||
fitViewQueued: boolean;
|
||||
fitViewOptions: FitViewOptions | undefined;
|
||||
fitViewResolver: PromiseWithResolvers<boolean> | null;
|
||||
fitViewResolver: ReturnType<typeof withResolvers<boolean>> | null;
|
||||
|
||||
onNodesDelete?: OnNodesDelete<NodeType>;
|
||||
onEdgesDelete?: OnEdgesDelete<EdgeType>;
|
||||
|
||||
@@ -130,8 +130,12 @@ function applyChange(change: any, element: any): any {
|
||||
element.measured.height = change.dimensions.height;
|
||||
|
||||
if (change.setAttributes) {
|
||||
element.width = change.dimensions.width;
|
||||
element.height = change.dimensions.height;
|
||||
if (change.setAttributes === true || change.setAttributes === 'width') {
|
||||
element.width = change.dimensions.width;
|
||||
}
|
||||
if (change.setAttributes === true || change.setAttributes === 'height') {
|
||||
element.height = change.dimensions.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user