diff --git a/packages/vue-flow/src/components/Nodes/NodeWrapper.vue b/packages/vue-flow/src/components/Nodes/NodeWrapper.vue index 1d647ca0..26bd9fc0 100644 --- a/packages/vue-flow/src/components/Nodes/NodeWrapper.vue +++ b/packages/vue-flow/src/components/Nodes/NodeWrapper.vue @@ -30,6 +30,7 @@ const { multiSelectionActive, removeSelectedElements, getSelectedNodes, + onUpdateNodeInternals, } = $(useVueFlow()) const node = $computed(() => getNode(id)!) @@ -66,6 +67,29 @@ watch( { flush: 'post' }, ) +onUpdateNodeInternals((updateIds) => { + if (updateIds.includes(id)) { + updateNodeDimensions([{ id, nodeElement: nodeElement.value, forceUpdate: true }]) + + const xyzPos = { + x: node.position.x, + y: node.position.y, + z: node.computedPosition.z ? node.computedPosition.z : node.selected ? 1000 : 0, + } + + if (parentNode) { + if (parentNode.computedPosition.x && parentNode.computedPosition.y) { + node.computedPosition = getXYZPos( + { x: parentNode.computedPosition.x, y: parentNode.computedPosition.y, z: parentNode.computedPosition.z! }, + xyzPos, + ) + } else { + node.computedPosition = xyzPos + } + } + } +}) + onBeforeUnmount(() => observer.stop()) onMounted(() => { @@ -206,7 +230,6 @@ export default { :source-position="node.sourcePosition" :label="node.label" :drag-handle="node.dragHandle" - :node-element="nodeElement" /> diff --git a/packages/vue-flow/src/container/VueFlow/VueFlow.vue b/packages/vue-flow/src/container/VueFlow/VueFlow.vue index 3b18a0c7..09a59a89 100644 --- a/packages/vue-flow/src/container/VueFlow/VueFlow.vue +++ b/packages/vue-flow/src/container/VueFlow/VueFlow.vue @@ -84,6 +84,7 @@ const emit = defineEmits<{ (event: 'edgeUpdateStart', edgeMouseEvent: MouseEvent): void (event: 'edgeUpdate', edgeMouseEvent: MouseEvent): void (event: 'edgeUpdateEnd', edgeMouseEvent: MouseEvent): void + (event: 'updateNodeInternals', id: string): void /** v-model event definitions */ (event: 'update:modelValue', value: FlowElements): void diff --git a/packages/vue-flow/src/store/actions.ts b/packages/vue-flow/src/store/actions.ts index b19a1b62..e9f64d01 100644 --- a/packages/vue-flow/src/store/actions.ts +++ b/packages/vue-flow/src/store/actions.ts @@ -339,6 +339,10 @@ export default (state: State, getters: ComputedGetters): Actions => { ) } + const updateNodeInternals: Actions['updateNodeInternals'] = (ids) => { + state.hooks.updateNodeInternals.trigger(ids) + } + let zoomPanHelper: ReturnType state.hooks.paneReady.on(({ id }) => { @@ -416,6 +420,7 @@ export default (state: State, getters: ComputedGetters): Actions => { }, project: (position) => pointToRendererPoint(position, state.viewport, state.snapToGrid, state.snapGrid), toObject, + updateNodeInternals, $reset: () => { setState(useState()) }, diff --git a/packages/vue-flow/src/store/hooks.ts b/packages/vue-flow/src/store/hooks.ts index 50731fbe..91725b33 100644 --- a/packages/vue-flow/src/store/hooks.ts +++ b/packages/vue-flow/src/store/hooks.ts @@ -42,6 +42,7 @@ export const createHooks = (): FlowHooks => ({ edgeUpdateStart: createEventHook(), edgeUpdate: createEventHook(), edgeUpdateEnd: createEventHook(), + updateNodeInternals: createEventHook(), }) const bind = (emit: Emits, hooks: FlowHooks) => { diff --git a/packages/vue-flow/src/types/hooks.ts b/packages/vue-flow/src/types/hooks.ts index ac374d9e..691f18ed 100644 --- a/packages/vue-flow/src/types/hooks.ts +++ b/packages/vue-flow/src/types/hooks.ts @@ -75,6 +75,7 @@ export interface FlowEvents { edgeUpdateStart: EdgeMouseEvent edgeUpdate: EdgeUpdateEvent edgeUpdateEnd: EdgeMouseEvent + updateNodeInternals: string[] } export type FlowHooks = Readonly<{ diff --git a/packages/vue-flow/src/types/store.ts b/packages/vue-flow/src/types/store.ts index 86418b34..6a6ffc91 100644 --- a/packages/vue-flow/src/types/store.ts +++ b/packages/vue-flow/src/types/store.ts @@ -119,6 +119,7 @@ export type SetState = ( ) => void export type UpdateNodePosition = (dragItems: NodeDragItem[], changed: boolean, dragging: boolean) => void export type UpdateNodeDimensions = (updates: UpdateNodeDimensionsParams[]) => void +export type UpdateNodeInternals = (nodeIds: string[]) => void export interface Actions extends ViewportFunctions { /** parses elements (nodes + edges) and re-sets the state */ @@ -165,6 +166,8 @@ export interface Actions extends ViewportFunctions { setState: SetState /** return an object of graph values (elements, viewpane transform) for storage and re-loading a graph */ toObject: () => FlowExportObject + /** force update node internal data, if handle bounds are incorrect, you might want to use this */ + updateNodeInternals: UpdateNodeInternals /** internal position updater, you probably don't want to use this */ updateNodePositions: UpdateNodePosition