refactor(core): make it possible to batch changes
This commit is contained in:
@@ -57,6 +57,7 @@ const NodeRenderer = (props: NodeRendererProps) => {
|
||||
nodeElement: entry.target as HTMLDivElement,
|
||||
forceUpdate: true,
|
||||
}));
|
||||
|
||||
updateNodeDimensions(updates);
|
||||
});
|
||||
|
||||
|
||||
@@ -102,7 +102,12 @@ const createRFStore = () =>
|
||||
onNodesChange?.(changes);
|
||||
}
|
||||
},
|
||||
updateNodePositions: (nodeDragItems: NodeDragItem[] | Node[], positionChanged = true, dragging = false) => {
|
||||
updateNodePositions: (
|
||||
nodeDragItems: NodeDragItem[] | Node[],
|
||||
positionChanged = true,
|
||||
dragging = false,
|
||||
applyChanges = true
|
||||
) => {
|
||||
const { onNodesChange, nodeInternals, hasDefaultNodes, nodeOrigin } = get();
|
||||
|
||||
if (hasDefaultNodes || onNodesChange) {
|
||||
@@ -128,9 +133,15 @@ const createRFStore = () =>
|
||||
set({ nodeInternals: nextNodeInternals });
|
||||
}
|
||||
|
||||
onNodesChange?.(changes);
|
||||
if (applyChanges) {
|
||||
onNodesChange?.(changes);
|
||||
}
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
addSelectedNodes: (selectedNodeIds: string[]) => {
|
||||
const { multiSelectionActive, nodeInternals, edges } = get();
|
||||
|
||||
@@ -8,6 +8,7 @@ export type NodeDimensionChange = {
|
||||
id: string;
|
||||
type: 'dimensions';
|
||||
dimensions: Dimensions;
|
||||
updateStyle?: boolean;
|
||||
};
|
||||
|
||||
export type NodePositionChange = {
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { MouseEvent as ReactMouseEvent, ComponentType, MemoExoticComponent
|
||||
import type { D3DragEvent, Selection as D3Selection, SubjectPosition, ZoomBehavior } from 'd3';
|
||||
|
||||
import type { XYPosition, Rect, Transform, CoordinateExtent } from './utils';
|
||||
import type { NodeChange, EdgeChange } from './changes';
|
||||
import type { NodeChange, EdgeChange, NodePositionChange } from './changes';
|
||||
import type {
|
||||
Node,
|
||||
NodeInternals,
|
||||
@@ -215,7 +215,12 @@ export type ReactFlowActions = {
|
||||
setEdges: (edges: Edge[]) => void;
|
||||
setDefaultNodesAndEdges: (nodes?: Node[], edges?: Edge[]) => void;
|
||||
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => void;
|
||||
updateNodePositions: (nodeDragItems: NodeDragItem[] | Node[], positionChanged: boolean, dragging: boolean) => void;
|
||||
updateNodePositions: (
|
||||
nodeDragItems: NodeDragItem[] | Node[],
|
||||
positionChanged: boolean,
|
||||
dragging: boolean,
|
||||
applyChanges?: boolean
|
||||
) => NodePositionChange[] | null;
|
||||
resetSelectedElements: () => void;
|
||||
unselectNodesAndEdges: (params?: UnselectNodesAndEdgesParams) => void;
|
||||
addSelectedNodes: (nodeIds: string[]) => void;
|
||||
|
||||
@@ -50,58 +50,63 @@ function applyChanges(changes: any[], elements: any[]): any[] {
|
||||
const initElements: any[] = changes.filter((c) => c.type === 'add').map((c) => c.item);
|
||||
|
||||
return elements.reduce((res: any[], item: any) => {
|
||||
const currentChange = changes.find((c) => c.id === item.id);
|
||||
const currentChanges = changes.filter((c) => c.id === item.id);
|
||||
|
||||
if (currentChange) {
|
||||
switch (currentChange.type) {
|
||||
case 'select': {
|
||||
res.push({ ...item, selected: currentChange.selected });
|
||||
return res;
|
||||
}
|
||||
case 'position': {
|
||||
const updateItem = { ...item };
|
||||
if (currentChanges.length === 0) {
|
||||
res.push(item);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (typeof currentChange.position !== 'undefined') {
|
||||
updateItem.position = currentChange.position;
|
||||
const updateItem = { ...item };
|
||||
|
||||
for (const currentChange of currentChanges) {
|
||||
if (currentChange) {
|
||||
switch (currentChange.type) {
|
||||
case 'select': {
|
||||
updateItem.selected = currentChange.selected;
|
||||
break;
|
||||
}
|
||||
case 'position': {
|
||||
if (typeof currentChange.position !== 'undefined') {
|
||||
updateItem.position = currentChange.position;
|
||||
}
|
||||
|
||||
if (typeof currentChange.positionAbsolute !== 'undefined') {
|
||||
updateItem.positionAbsolute = currentChange.positionAbsolute;
|
||||
if (typeof currentChange.positionAbsolute !== 'undefined') {
|
||||
updateItem.positionAbsolute = currentChange.positionAbsolute;
|
||||
}
|
||||
|
||||
if (typeof currentChange.dragging !== 'undefined') {
|
||||
updateItem.dragging = currentChange.dragging;
|
||||
}
|
||||
|
||||
if (updateItem.expandParent) {
|
||||
handleParentExpand(res, updateItem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'dimensions': {
|
||||
if (typeof currentChange.dimensions !== 'undefined') {
|
||||
updateItem.width = currentChange.dimensions.width;
|
||||
updateItem.height = currentChange.dimensions.height;
|
||||
}
|
||||
|
||||
if (typeof currentChange.dragging !== 'undefined') {
|
||||
updateItem.dragging = currentChange.dragging;
|
||||
if (typeof currentChange.updateStyle !== 'undefined') {
|
||||
updateItem.style = { ...(updateItem.style || {}), ...currentChange.dimensions };
|
||||
}
|
||||
|
||||
if (updateItem.expandParent) {
|
||||
handleParentExpand(res, updateItem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (updateItem.expandParent) {
|
||||
handleParentExpand(res, updateItem);
|
||||
case 'remove': {
|
||||
return res;
|
||||
}
|
||||
|
||||
res.push(updateItem);
|
||||
return res;
|
||||
}
|
||||
case 'dimensions': {
|
||||
const updateItem = { ...item };
|
||||
|
||||
if (typeof currentChange.dimensions !== 'undefined') {
|
||||
updateItem.width = currentChange.dimensions.width;
|
||||
updateItem.height = currentChange.dimensions.height;
|
||||
}
|
||||
|
||||
if (updateItem.expandParent) {
|
||||
handleParentExpand(res, updateItem);
|
||||
}
|
||||
|
||||
res.push(updateItem);
|
||||
return res;
|
||||
}
|
||||
case 'remove': {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res.push(item);
|
||||
res.push(updateItem);
|
||||
return res;
|
||||
}, initElements);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user