make Vue nodes resizable (#5936)

## Summary

Implemented node resizing functionality for Vue nodes.


https://github.com/user-attachments/assets/a7536045-1fa5-401b-8d18-7c26b4dfbfc3

Resolves https://github.com/Comfy-Org/ComfyUI_frontend/issues/5675.

## Review Focus

ResizeObserver as single source of truth pattern eliminates feedback
loops between manual resize and reactive layout updates. Intrinsic
content sizing calculation temporarily resets DOM styles to measure
natural content dimensions.

```mermaid
graph TD
    A[User Drags Handle] --> B[Direct DOM Style Update]
    B --> C[ResizeObserver Detects Change]
    C --> D[Layout Store Update]
    D --> E[Slot Position Sync]
    
    style A fill:#f9f9f9,stroke:#333,color:#000
    style E fill:#f9f9f9,stroke:#333,color:#000
```

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5936-make-Vue-nodes-resizable-2846d73d36508160b3b9db49ad8b273e)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: DrJKL <DrJKL@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Christian Byrne
2025-10-07 15:53:10 -07:00
committed by GitHub
parent 89f4452488
commit d9157925f5
6 changed files with 190 additions and 1 deletions

View File

@@ -6,6 +6,7 @@ import type { ComponentProps } from 'vue-component-type-helpers'
import { createI18n } from 'vue-i18n'
import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
import { TransformStateKey } from '@/renderer/core/layout/injectionKeys'
import LGraphNode from '@/renderer/extensions/vueNodes/components/LGraphNode.vue'
import { useNodeEventHandlers } from '@/renderer/extensions/vueNodes/composables/useNodeEventHandlers'
import { useVueElementTracking } from '@/renderer/extensions/vueNodes/composables/useVueNodeResizeTracking'
@@ -77,6 +78,13 @@ vi.mock('@/renderer/extensions/vueNodes/preview/useNodePreviewState', () => ({
}))
}))
vi.mock('../composables/useNodeResize', () => ({
useNodeResize: vi.fn(() => ({
startResize: vi.fn(),
isResizing: computed(() => false)
}))
}))
const i18n = createI18n({
legacy: false,
locale: 'en',
@@ -96,6 +104,14 @@ function mountLGraphNode(props: ComponentProps<typeof LGraphNode>) {
}),
i18n
],
provide: {
[TransformStateKey as symbol]: {
screenToCanvas: vi.fn(),
canvasToScreen: vi.fn(),
camera: { z: 1 },
isNodeInViewport: vi.fn()
}
},
stubs: {
NodeHeader: true,
NodeSlots: true,
@@ -155,6 +171,14 @@ describe('LGraphNode', () => {
}),
i18n
],
provide: {
[TransformStateKey as symbol]: {
screenToCanvas: vi.fn(),
canvasToScreen: vi.fn(),
camera: { z: 1 },
isNodeInViewport: vi.fn()
}
},
stubs: {
NodeSlots: true,
NodeWidgets: true,