From 9c5dc23556ddf3a9d251c33ddaf0c65984a2f615 Mon Sep 17 00:00:00 2001 From: Subagent 5 Date: Wed, 28 Jan 2026 20:41:51 -0800 Subject: [PATCH] fix: prevent node drag when selecting text in InputText widgets Add capture-phase pointer event modifiers to WidgetInputText.vue to stop pointer events from bubbling up to LGraphNode, which was initiating node drag instead of allowing text selection. Pattern matches existing fix in WidgetTextarea.vue (lines 22-24). Amp-Thread-ID: https://ampcode.com/threads/T-019c07b2-9558-7270-bb0c-d034f14f357a Co-authored-by: Amp --- .../components/WidgetInputText.test.ts | 50 ++++++++++++++++++- .../widgets/components/WidgetInputText.vue | 3 ++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/renderer/extensions/vueNodes/widgets/components/WidgetInputText.test.ts b/src/renderer/extensions/vueNodes/widgets/components/WidgetInputText.test.ts index 599f85306f7..b84d0a5b656 100644 --- a/src/renderer/extensions/vueNodes/widgets/components/WidgetInputText.test.ts +++ b/src/renderer/extensions/vueNodes/widgets/components/WidgetInputText.test.ts @@ -3,7 +3,7 @@ import PrimeVue from 'primevue/config' import InputText from 'primevue/inputtext' import type { InputTextProps } from 'primevue/inputtext' import Textarea from 'primevue/textarea' -import { describe, expect, it } from 'vitest' +import { describe, expect, it, vi } from 'vitest' import type { SimplifiedWidget } from '@/types/simplifiedWidget' @@ -177,4 +177,52 @@ describe('WidgetInputText Value Binding', () => { expect(emitted![0]).toContain(unicodeText) }) }) + + describe('Pointer Event Propagation', () => { + it('stops pointerdown propagation to prevent node drag during text selection', async () => { + const widget = createMockWidget('test text') + const wrapper = mountComponent(widget, 'test text') + + const input = wrapper.find('input[type="text"]') + expect(input.exists()).toBe(true) + + const parentPointerdownHandler = vi.fn() + const wrapperEl = wrapper.element as HTMLElement + wrapperEl.addEventListener('pointerdown', parentPointerdownHandler) + + await input.trigger('pointerdown') + + expect(parentPointerdownHandler).not.toHaveBeenCalled() + }) + + it('stops pointermove propagation during text selection', async () => { + const widget = createMockWidget('test text') + const wrapper = mountComponent(widget, 'test text') + + const input = wrapper.find('input[type="text"]') + + const parentPointermoveHandler = vi.fn() + const wrapperEl = wrapper.element as HTMLElement + wrapperEl.addEventListener('pointermove', parentPointermoveHandler) + + await input.trigger('pointermove') + + expect(parentPointermoveHandler).not.toHaveBeenCalled() + }) + + it('stops pointerup propagation after text selection', async () => { + const widget = createMockWidget('test text') + const wrapper = mountComponent(widget, 'test text') + + const input = wrapper.find('input[type="text"]') + + const parentPointerupHandler = vi.fn() + const wrapperEl = wrapper.element as HTMLElement + wrapperEl.addEventListener('pointerup', parentPointerupHandler) + + await input.trigger('pointerup') + + expect(parentPointerupHandler).not.toHaveBeenCalled() + }) + }) }) diff --git a/src/renderer/extensions/vueNodes/widgets/components/WidgetInputText.vue b/src/renderer/extensions/vueNodes/widgets/components/WidgetInputText.vue index eff22f1efc9..4b549a2a8ea 100644 --- a/src/renderer/extensions/vueNodes/widgets/components/WidgetInputText.vue +++ b/src/renderer/extensions/vueNodes/widgets/components/WidgetInputText.vue @@ -7,6 +7,9 @@ :aria-label="widget.name" size="small" :pt="{ root: 'truncate min-w-[4ch]' }" + @pointerdown.capture.stop + @pointermove.capture.stop + @pointerup.capture.stop />