From 4f606d7ae4f3358142dae954df3e25b2968882aa Mon Sep 17 00:00:00 2001 From: Dawid Myslak Date: Wed, 7 Jan 2026 12:25:40 +0100 Subject: [PATCH] fix(core): Fix for jumpy UI when using drag/drop to fields in NDV (#23516) Co-authored-by: Michael Kret --- .../src/app/components/DropArea/DropArea.vue | 7 +++++-- .../components/ExpressionParameterInput.vue | 13 +++++++++---- .../ndv/parameters/components/ParameterInput.vue | 16 +++++++++++----- .../components/CodeNodeEditor/CodeNodeEditor.vue | 7 ++++--- .../editors/components/CssEditor/CssEditor.vue | 7 ++++--- .../editors/components/HtmlEditor/HtmlEditor.vue | 7 ++++--- .../editors/components/SqlEditor/SqlEditor.vue | 7 ++++--- .../workflows/editor/expressions/mapping.spec.ts | 4 ++-- 8 files changed, 43 insertions(+), 25 deletions(-) diff --git a/packages/frontend/editor-ui/src/app/components/DropArea/DropArea.vue b/packages/frontend/editor-ui/src/app/components/DropArea/DropArea.vue index 7bee5f1e117..9602284f40e 100644 --- a/packages/frontend/editor-ui/src/app/components/DropArea/DropArea.vue +++ b/packages/frontend/editor-ui/src/app/components/DropArea/DropArea.vue @@ -41,13 +41,16 @@ const onDrop = (value: string) => { } .droppable { - border-color: var(--ndv--droppable-parameter--color); - border-width: 1.5px; + border-color: transparent; + outline: 1.5px dashed var(--ndv--droppable-parameter--color); + outline-offset: -1.5px; background: var(--ndv--droppable-parameter--color--background); } .active { border-color: var(--color--success); + border-width: 1px; background: var(--ndv--droppable-parameter--color--background--active); + outline: none; } diff --git a/packages/frontend/editor-ui/src/features/ndv/parameters/components/ExpressionParameterInput.vue b/packages/frontend/editor-ui/src/features/ndv/parameters/components/ExpressionParameterInput.vue index 9d5cd076e5b..68515866420 100644 --- a/packages/frontend/editor-ui/src/features/ndv/parameters/components/ExpressionParameterInput.vue +++ b/packages/frontend/editor-ui/src/features/ndv/parameters/components/ExpressionParameterInput.vue @@ -315,12 +315,14 @@ defineExpose({ focus, select }); } .droppable { - --input--border-color: var(--ndv--droppable-parameter--color); - --input--border-right-color: var(--ndv--droppable-parameter--color); - --input--border-style: dashed; + --input--border-color: transparent; + --input--border-right-color: transparent; :global(.cm-editor) { - border-width: 1.5px; + border-color: transparent; + outline: 1.5px dashed var(--ndv--droppable-parameter--color); + outline-offset: -1.5px; + transition: none; } } @@ -332,7 +334,10 @@ defineExpose({ focus, select }); :global(.cm-editor) { cursor: grabbing !important; + border-color: var(--color--success); border-width: 1px; + outline: none; + transition: none; } } diff --git a/packages/frontend/editor-ui/src/features/ndv/parameters/components/ParameterInput.vue b/packages/frontend/editor-ui/src/features/ndv/parameters/components/ParameterInput.vue index c31030f541e..bd97a3b8b8a 100644 --- a/packages/frontend/editor-ui/src/features/ndv/parameters/components/ParameterInput.vue +++ b/packages/frontend/editor-ui/src/features/ndv/parameters/components/ParameterInput.vue @@ -1910,14 +1910,16 @@ onUpdated(async () => { } .droppable { - --input--border-color: var(--ndv--droppable-parameter--color); - --input--border-right-color: var(--ndv--droppable-parameter--color); - --input--border-style: dashed; + --input--border-color: transparent; + --input--border-right-color: transparent; textarea, input, .cm-editor { - border-width: 1.5px; + border-color: transparent; + outline: 1.5px dashed var(--ndv--droppable-parameter--color); + outline-offset: -1.5px; + transition: none; } } @@ -1928,9 +1930,13 @@ onUpdated(async () => { --input--border-style: solid; textarea, - input { + input, + .cm-editor { cursor: grabbing !important; + border-color: var(--color--success); border-width: 1px; + outline: none; + transition: none; } } diff --git a/packages/frontend/editor-ui/src/features/shared/editors/components/CodeNodeEditor/CodeNodeEditor.vue b/packages/frontend/editor-ui/src/features/shared/editors/components/CodeNodeEditor/CodeNodeEditor.vue index 7b81ab5bdda..ef5a80edf65 100644 --- a/packages/frontend/editor-ui/src/features/shared/editors/components/CodeNodeEditor/CodeNodeEditor.vue +++ b/packages/frontend/editor-ui/src/features/shared/editors/components/CodeNodeEditor/CodeNodeEditor.vue @@ -341,9 +341,9 @@ defineExpose({ .editorInput.droppable { :global(.cm-editor) { - border-color: var(--ndv--droppable-parameter--color); - border-style: dashed; - border-width: 1.5px; + border-color: transparent; + outline: 1.5px dashed var(--ndv--droppable-parameter--color); + outline-offset: -1.5px; } } @@ -353,6 +353,7 @@ defineExpose({ border-style: solid; cursor: grabbing; border-width: 1px; + outline: none; } } diff --git a/packages/frontend/editor-ui/src/features/shared/editors/components/CssEditor/CssEditor.vue b/packages/frontend/editor-ui/src/features/shared/editors/components/CssEditor/CssEditor.vue index b494f731602..95f32de96e2 100644 --- a/packages/frontend/editor-ui/src/features/shared/editors/components/CssEditor/CssEditor.vue +++ b/packages/frontend/editor-ui/src/features/shared/editors/components/CssEditor/CssEditor.vue @@ -131,9 +131,9 @@ defineExpose({ .droppable { :global(.cm-editor) { - border-color: var(--ndv--droppable-parameter--color); - border-style: dashed; - border-width: 1.5px; + border-color: transparent; + outline: 1.5px dashed var(--ndv--droppable-parameter--color); + outline-offset: -1.5px; } } @@ -143,6 +143,7 @@ defineExpose({ border-style: solid; cursor: grabbing; border-width: 1px; + outline: none; } } diff --git a/packages/frontend/editor-ui/src/features/shared/editors/components/HtmlEditor/HtmlEditor.vue b/packages/frontend/editor-ui/src/features/shared/editors/components/HtmlEditor/HtmlEditor.vue index f8465682cb5..cb8a4d61df5 100644 --- a/packages/frontend/editor-ui/src/features/shared/editors/components/HtmlEditor/HtmlEditor.vue +++ b/packages/frontend/editor-ui/src/features/shared/editors/components/HtmlEditor/HtmlEditor.vue @@ -292,9 +292,9 @@ defineExpose({ .droppable { :global(.cm-editor) { - border-color: var(--ndv--droppable-parameter--color); - border-style: dashed; - border-width: 1.5px; + border-color: transparent; + outline: 1.5px dashed var(--ndv--droppable-parameter--color); + outline-offset: -1.5px; } } @@ -304,6 +304,7 @@ defineExpose({ border-style: solid; cursor: grabbing; border-width: 1px; + outline: none; } } diff --git a/packages/frontend/editor-ui/src/features/shared/editors/components/SqlEditor/SqlEditor.vue b/packages/frontend/editor-ui/src/features/shared/editors/components/SqlEditor/SqlEditor.vue index 2ee6bc45e3b..8a6b5b95f6a 100644 --- a/packages/frontend/editor-ui/src/features/shared/editors/components/SqlEditor/SqlEditor.vue +++ b/packages/frontend/editor-ui/src/features/shared/editors/components/SqlEditor/SqlEditor.vue @@ -249,9 +249,9 @@ defineExpose({ .codemirror.droppable { :global(.cm-editor) { - border-color: var(--ndv--droppable-parameter--color); - border-style: dashed; - border-width: 1.5px; + border-color: transparent; + outline: 1.5px dashed var(--ndv--droppable-parameter--color); + outline-offset: -1.5px; } } @@ -261,6 +261,7 @@ defineExpose({ border-style: solid; cursor: grabbing; border-width: 1px; + outline: none; } } diff --git a/packages/testing/playwright/tests/e2e/workflows/editor/expressions/mapping.spec.ts b/packages/testing/playwright/tests/e2e/workflows/editor/expressions/mapping.spec.ts index 0bf064d21dc..ecda13cdcb6 100644 --- a/packages/testing/playwright/tests/e2e/workflows/editor/expressions/mapping.spec.ts +++ b/packages/testing/playwright/tests/e2e/workflows/editor/expressions/mapping.spec.ts @@ -333,10 +333,10 @@ test.describe('Data Mapping', () => { await expect(n8n.ndv.getParameterTextInput('includeOtherFields')).toBeVisible(); const includeOtherFieldsInput = n8n.ndv.getParameterTextInput('includeOtherFields'); - await expect(includeOtherFieldsInput).toHaveCSS('border', /dashed.*rgb\(90, 76, 194\)/); + await expect(includeOtherFieldsInput).toHaveCSS('outline', /rgb\(90, 76, 194\) dashed/); const valueInput = n8n.ndv.getParameterTextInput('value'); - await expect(valueInput).toHaveCSS('border', /dashed.*rgb\(90, 76, 194\)/); + await expect(valueInput).toHaveCSS('outline', /rgb\(90, 76, 194\) dashed/); await n8n.page.mouse.up(); });