diff --git a/packages/react/src/hooks/useMoveSelectedNodes.ts b/packages/react/src/hooks/useMoveSelectedNodes.ts index d189642b..52503c04 100644 --- a/packages/react/src/hooks/useMoveSelectedNodes.ts +++ b/packages/react/src/hooks/useMoveSelectedNodes.ts @@ -19,7 +19,7 @@ export function useMoveSelectedNodes() { const moveSelectedNodes = useCallback((params: { direction: XYPosition; factor: number }) => { const { nodeExtent, snapToGrid, snapGrid, nodesDraggable, onError, updateNodePositions, nodeLookup, nodeOrigin } = store.getState(); - const nodeUpdates = []; + const nodeUpdates = new Map(); const isSelected = selectedAndDraggable(nodesDraggable); // by default a node moves 5px on each key press @@ -56,7 +56,7 @@ export function useMoveSelectedNodes() { node.position = position; node.internals.positionAbsolute = positionAbsolute; - nodeUpdates.push(node); + nodeUpdates.set(node.id, node); } updateNodePositions(nodeUpdates); diff --git a/packages/react/src/store/index.ts b/packages/react/src/store/index.ts index 50d981c2..48010a2e 100644 --- a/packages/react/src/store/index.ts +++ b/packages/react/src/store/index.ts @@ -16,7 +16,7 @@ import { import { applyEdgeChanges, applyNodeChanges, createSelectionChange, getSelectionChanges } from '../utils/changes'; import getInitialState from './initialState'; -import type { ReactFlowState, Node, Edge, UnselectNodesAndEdgesParams, FitViewOptions, InternalNode } from '../types'; +import type { ReactFlowState, Node, Edge, UnselectNodesAndEdgesParams, FitViewOptions } from '../types'; const createRFStore = ({ nodes, @@ -124,27 +124,26 @@ const createRFStore = ({ } }, updateNodePositions: (nodeDragItems, dragging = false) => { - const { nodeLookup, parentLookup } = get(); const parentExpandChildren: ParentExpandChild[] = []; + const changes = []; - const changes: NodeChange[] = nodeDragItems.map((node) => { + for (const [id, dragItem] of nodeDragItems) { // @todo add expandParent to drag item so that we can get rid of the look up here - const internalNode = nodeLookup.get(node.id); const change: NodeChange = { - id: node.id, + id, type: 'position', - position: node.position, + position: dragItem.position, dragging, }; - if (internalNode?.expandParent && internalNode?.parentId && change.position) { + if (dragItem?.expandParent && dragItem?.parentId && change.position) { parentExpandChildren.push({ - id: internalNode.id, - parentId: internalNode.parentId, + id, + parentId: dragItem.parentId, rect: { - ...node.internals.positionAbsolute, - width: internalNode.measured.width!, - height: internalNode.measured.height!, + ...dragItem.internals.positionAbsolute, + width: dragItem.measured.width!, + height: dragItem.measured.height!, }, }); @@ -152,10 +151,11 @@ const createRFStore = ({ change.position.y = Math.max(0, change.position.y); } - return change; - }); + changes.push(change); + } if (parentExpandChildren.length > 0) { + const { nodeLookup, parentLookup } = get(); const parentExpandChanges = handleExpandParent(parentExpandChildren, nodeLookup, parentLookup); changes.push(...parentExpandChanges); } diff --git a/packages/svelte/src/lib/store/index.ts b/packages/svelte/src/lib/store/index.ts index 07d4ab76..39c9cad4 100644 --- a/packages/svelte/src/lib/store/index.ts +++ b/packages/svelte/src/lib/store/index.ts @@ -64,14 +64,14 @@ export function createStore({ const updateNodePositions: UpdateNodePositions = (nodeDragItems, dragging = false) => { const nodeLookup = get(store.nodeLookup); - for (const nodeDragItem of nodeDragItems) { - const node = nodeLookup.get(nodeDragItem.id)?.internals.userNode; + for (const [id, dragItem] of nodeDragItems) { + const node = nodeLookup.get(id)?.internals.userNode; if (!node) { continue; } - node.position = nodeDragItem.position; + node.position = dragItem.position; node.dragging = dragging; } diff --git a/packages/system/src/types/general.ts b/packages/system/src/types/general.ts index 2fd0e3ab..91a08082 100644 --- a/packages/system/src/types/general.ts +++ b/packages/system/src/types/general.ts @@ -127,7 +127,7 @@ export type SelectionRect = Rect & { export type OnError = (id: string, message: string) => void; -export type UpdateNodePositions = (dragItems: NodeDragItem[] | InternalNodeBase[], dragging?: boolean) => void; +export type UpdateNodePositions = (dragItems: Map, dragging?: boolean) => void; export type PanBy = (delta: XYPosition) => boolean; export type UpdateConnection = (params: { diff --git a/packages/system/src/xydrag/XYDrag.ts b/packages/system/src/xydrag/XYDrag.ts index 3f26ba06..8633b669 100644 --- a/packages/system/src/xydrag/XYDrag.ts +++ b/packages/system/src/xydrag/XYDrag.ts @@ -10,7 +10,7 @@ import { getInternalNodesBounds, rectToBox, } from '../utils'; -import { getDragItems, getEventHandlerParams, hasSelector, wrapSelectionDragFunc } from './utils'; +import { getDragItems, getEventHandlerParams, hasSelector } from './utils'; import type { NodeBase, NodeDragItem, diff --git a/packages/system/src/xydrag/utils.ts b/packages/system/src/xydrag/utils.ts index 1611cf6b..a0a26cb2 100644 --- a/packages/system/src/xydrag/utils.ts +++ b/packages/system/src/xydrag/utils.ts @@ -1,9 +1,5 @@ import { type NodeDragItem, type XYPosition, InternalNodeBase, NodeBase, NodeLookup } from '../types'; -export function wrapSelectionDragFunc(selectionFunc?: (event: MouseEvent, nodes: NodeBase[]) => void) { - return (event: MouseEvent, _: NodeBase, nodes: NodeBase[]) => selectionFunc?.(event, nodes); -} - export function isParentSelected(node: NodeType, nodeLookup: NodeLookup): boolean { if (!node.parentId) { return false;