refactor(react): init store with user nodeOrigin

This commit is contained in:
moklick
2024-06-27 17:01:01 +02:00
parent 15241b4fd0
commit aa0e131162
8 changed files with 27 additions and 11 deletions
@@ -4,6 +4,7 @@ import { Provider } from '../../contexts/StoreContext';
import { createStore } from '../../store';
import { BatchProvider } from '../BatchProvider';
import type { Node, Edge } from '../../types';
import { NodeOrigin } from '@xyflow/system';
export type ReactFlowProviderProps = {
initialNodes?: Node[];
@@ -13,6 +14,7 @@ export type ReactFlowProviderProps = {
initialWidth?: number;
initialHeight?: number;
fitView?: boolean;
nodeOrigin?: NodeOrigin;
children: ReactNode;
};
@@ -24,6 +26,7 @@ export function ReactFlowProvider({
initialWidth: width,
initialHeight: height,
fitView,
nodeOrigin,
children,
}: ReactFlowProviderProps) {
const [store] = useState(() =>
@@ -35,6 +38,7 @@ export function ReactFlowProvider({
width,
height,
fitView,
nodeOrigin,
})
);
@@ -3,6 +3,7 @@ import { useContext, type ReactNode } from 'react';
import StoreContext from '../../contexts/StoreContext';
import { ReactFlowProvider } from '../../components/ReactFlowProvider';
import type { Node, Edge } from '../../types';
import { NodeOrigin } from '@xyflow/system';
export function Wrapper({
children,
@@ -13,6 +14,7 @@ export function Wrapper({
width,
height,
fitView,
nodeOrigin,
}: {
children: ReactNode;
nodes?: Node[];
@@ -22,6 +24,7 @@ export function Wrapper({
width?: number;
height?: number;
fitView?: boolean;
nodeOrigin?: NodeOrigin;
}) {
const isWrapped = useContext(StoreContext);
@@ -40,6 +43,7 @@ export function Wrapper({
initialWidth={width}
initialHeight={height}
fitView={fitView}
nodeOrigin={nodeOrigin}
>
{children}
</ReactFlowProvider>
@@ -157,7 +157,7 @@ function ReactFlow<NodeType extends Node = Node, EdgeType extends Edge = Edge>(
data-testid="rf__wrapper"
id={id}
>
<Wrapper nodes={nodes} edges={edges} width={width} height={height} fitView={fitView}>
<Wrapper nodes={nodes} edges={edges} width={width} height={height} fitView={fitView} nodeOrigin={nodeOrigin}>
<GraphView<NodeType, EdgeType>
onInit={onInit}
onNodeClick={onNodeClick}
+4 -1
View File
@@ -12,6 +12,7 @@ import {
EdgeSelectionChange,
NodeSelectionChange,
ParentExpandChild,
NodeOrigin,
} from '@xyflow/system';
import { applyEdgeChanges, applyNodeChanges, createSelectionChange, getSelectionChanges } from '../utils/changes';
@@ -26,6 +27,7 @@ const createStore = ({
width,
height,
fitView,
nodeOrigin,
}: {
nodes?: Node[];
edges?: Edge[];
@@ -34,10 +36,11 @@ const createStore = ({
width?: number;
height?: number;
fitView?: boolean;
nodeOrigin?: NodeOrigin;
}) =>
createWithEqualityFn<ReactFlowState>(
(set, get) => ({
...getInitialState({ nodes, edges, width, height, fitView, defaultNodes, defaultEdges }),
...getInitialState({ nodes, edges, width, height, fitView, nodeOrigin, defaultNodes, defaultEdges }),
setNodes: (nodes: Node[]) => {
const { nodeLookup, parentLookup, nodeOrigin, elevateNodesOnSelect } = get();
// setNodes() is called exclusively in response to user actions:
+7 -3
View File
@@ -7,6 +7,7 @@ import {
updateConnectionLookup,
devWarn,
getInternalNodesBounds,
NodeOrigin,
} from '@xyflow/system';
import type { Edge, InternalNode, Node, ReactFlowStore } from '../types';
@@ -19,6 +20,7 @@ const getInitialState = ({
width,
height,
fitView,
nodeOrigin,
}: {
nodes?: Node[];
edges?: Edge[];
@@ -27,6 +29,7 @@ const getInitialState = ({
width?: number;
height?: number;
fitView?: boolean;
nodeOrigin?: NodeOrigin;
} = {}): ReactFlowStore => {
const nodeLookup = new Map<string, InternalNode>();
const parentLookup = new Map();
@@ -34,20 +37,21 @@ const getInitialState = ({
const edgeLookup = new Map();
const storeEdges = defaultEdges ?? edges ?? [];
const storeNodes = defaultNodes ?? nodes ?? [];
const storeNodeOrigin = nodeOrigin ?? [0, 0];
updateConnectionLookup(connectionLookup, edgeLookup, storeEdges);
adoptUserNodes(storeNodes, nodeLookup, parentLookup, {
nodeOrigin: [0, 0],
nodeOrigin: storeNodeOrigin,
elevateNodesOnSelect: false,
});
let transform: Transform = [0, 0, 1];
if (fitView && width && height) {
// @todo users nodeOrigin should be used here
const bounds = getInternalNodesBounds(nodeLookup, {
filter: (node) => !!((node.width || node.initialWidth) && (node.height || node.initialHeight)),
});
const { x, y, zoom } = getViewportForBounds(bounds, width, height, 0.5, 2, 0.1);
transform = [x, y, zoom];
}
@@ -81,7 +85,7 @@ const getInitialState = ({
domNode: null,
paneDragging: false,
noPanClassName: 'nopan',
nodeOrigin: [0, 0],
nodeOrigin: storeNodeOrigin,
nodeDragThreshold: 1,
snapGrid: [15, 15],
+2 -1
View File
@@ -27,6 +27,7 @@ import {
type NodeLookup,
NodeChange,
EdgeChange,
ParentLookup,
} from '@xyflow/system';
import type {
@@ -54,7 +55,7 @@ export type ReactFlowStore<NodeType extends Node = Node, EdgeType extends Edge =
transform: Transform;
nodes: NodeType[];
nodeLookup: NodeLookup<InternalNode<NodeType>>;
parentLookup: Map<string, Map<string, InternalNode<NodeType>>>;
parentLookup: ParentLookup<InternalNode<NodeType>>;
edges: Edge[];
edgeLookup: EdgeLookup<EdgeType>;
connectionLookup: ConnectionLookup;
+4 -4
View File
@@ -75,8 +75,8 @@ export const nodeToRect = (node: InternalNodeBase | NodeBase, nodeOrigin: NodeOr
return {
x,
y,
width: node.measured?.width ?? node.width ?? 0,
height: node.measured?.height ?? node.height ?? 0,
width: node.measured?.width ?? node.width ?? node.initialWidth ?? 0,
height: node.measured?.height ?? node.height ?? node.initialHeight ?? 0,
};
};
@@ -88,8 +88,8 @@ export const nodeToBox = (node: InternalNodeBase | NodeBase, nodeOrigin: NodeOri
return {
x,
y,
x2: x + (node.measured?.width ?? node.width ?? 0),
y2: y + (node.measured?.height ?? node.height ?? 0),
x2: x + (node.measured?.width ?? node.width ?? node.initialWidth ?? 0),
y2: y + (node.measured?.height ?? node.height ?? node.initialHeight ?? 0),
};
};
+1 -1
View File
@@ -166,7 +166,7 @@ export const getInternalNodesBounds = <NodeType extends InternalNodeBase | NodeD
let box = { x: Infinity, y: Infinity, x2: -Infinity, y2: -Infinity };
nodeLookup.forEach((node) => {
if (params.filter == undefined || params.filter(node)) {
if (params.filter === undefined || params.filter(node)) {
const nodeBox = nodeToBox(node as InternalNodeBase);
box = getBoundsOfBoxes(box, nodeBox);
}