From bd606b98a205a6fe9f40be76a57a025a7605e424 Mon Sep 17 00:00:00 2001 From: Braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Sun, 31 Aug 2025 13:51:33 +0200 Subject: [PATCH] refactor(core): avoid passing reactive values to position changes (#1937) Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> --- packages/core/src/composables/useDrag.ts | 4 +-- packages/core/src/utils/drag.ts | 35 ++++++++++++------------ packages/core/src/utils/graph.ts | 8 +++--- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/packages/core/src/composables/useDrag.ts b/packages/core/src/composables/useDrag.ts index 47bf39d0..adda79cc 100644 --- a/packages/core/src/composables/useDrag.ts +++ b/packages/core/src/composables/useDrag.ts @@ -42,7 +42,7 @@ export function useDrag(params: UseDragParams) { snapToGrid, snapGrid, noDragClassName, - nodes, + nodeLookup, nodeExtent, nodeDragThreshold, viewport, @@ -169,7 +169,7 @@ export function useDrag(params: UseDragParams) { const pointerPos = getPointerPosition(event.sourceEvent) lastPos = pointerPos - dragItems = getDragItems(nodes.value, nodesDraggable.value, pointerPos, findNode, id) + dragItems = getDragItems(nodeLookup.value, nodesDraggable.value, pointerPos, id) if (dragItems.length) { const [currentNode, nodes] = getEventHandlerParams({ diff --git a/packages/core/src/utils/drag.ts b/packages/core/src/utils/drag.ts index ccc107f2..70b70b0b 100644 --- a/packages/core/src/utils/drag.ts +++ b/packages/core/src/utils/drag.ts @@ -1,4 +1,3 @@ -import { markRaw } from 'vue' import type { Actions, CoordinateExtent, @@ -6,6 +5,7 @@ import type { Dimensions, GraphNode, NodeDragItem, + NodeLookup, State, XYPosition, } from '../types' @@ -27,39 +27,38 @@ export function hasSelector(target: Element, selector: string, node: Element): b return false } -export function getDragItems( - nodes: GraphNode[], - nodesDraggable: boolean, - mousePos: XYPosition, - findNode: Actions['findNode'], - nodeId?: string, -): NodeDragItem[] { - const dragItems: NodeDragItem[] = [] - for (const node of nodes) { +// looks for all selected nodes and created a NodeDragItem for each of them +export function getDragItems(nodeLookup: NodeLookup, nodesDraggable: boolean, mousePos: XYPosition, nodeId?: string) { + const dragItems = new Map() + + for (const [id, node] of nodeLookup) { if ( (node.selected || node.id === nodeId) && - (!node.parentNode || !isParentSelected(node, findNode)) && + (!node.parentNode || !isParentSelected(node, nodeLookup)) && (node.draggable || (nodesDraggable && typeof node.draggable === 'undefined')) ) { - dragItems.push( - markRaw({ + const internalNode = nodeLookup.get(id) + + if (internalNode) { + dragItems.set(id, { id: node.id, position: node.position || { x: 0, y: 0 }, distance: { x: mousePos.x - node.computedPosition?.x || 0, y: mousePos.y - node.computedPosition?.y || 0, }, - from: node.computedPosition, + from: { x: node.computedPosition.x, y: node.computedPosition.y }, extent: node.extent, parentNode: node.parentNode, - dimensions: node.dimensions, + dimensions: { ...node.dimensions }, expandParent: node.expandParent, - }), - ) + }) + } } } - return dragItems + // todo: work with map in `useDrag` instead of array + return Array.from(dragItems.values()) } export function getEventHandlerParams({ diff --git a/packages/core/src/utils/graph.ts b/packages/core/src/utils/graph.ts index 60b18557..fd8764c4 100644 --- a/packages/core/src/utils/graph.ts +++ b/packages/core/src/utils/graph.ts @@ -1,6 +1,5 @@ import { markRaw } from 'vue' import type { - Actions, Box, Connection, CoordinateExtent, @@ -16,6 +15,7 @@ import type { GraphNode, MaybeElement, Node, + NodeLookup, Rect, ViewportTransform, XYPosition, @@ -471,12 +471,12 @@ export function getXYZPos(parentPos: XYZPosition, computedPosition: XYZPosition) } } -export function isParentSelected(node: GraphNode, findNode: Actions['findNode']): boolean { +export function isParentSelected(node: GraphNode, nodeLookup: NodeLookup): boolean { if (!node.parentNode) { return false } - const parent = findNode(node.parentNode) + const parent = nodeLookup.get(node.parentNode) if (!parent) { return false } @@ -485,7 +485,7 @@ export function isParentSelected(node: GraphNode, findNode: Actions['findNode']) return true } - return isParentSelected(parent, findNode) + return isParentSelected(parent, nodeLookup) } export function getMarkerId(marker: EdgeMarkerType | undefined, vueFlowId?: string) {