diff --git a/packages/frontend/editor-ui/src/App.vue b/packages/frontend/editor-ui/src/App.vue
index 23afc37ab2..6634aa1903 100644
--- a/packages/frontend/editor-ui/src/App.vue
+++ b/packages/frontend/editor-ui/src/App.vue
@@ -10,7 +10,12 @@ import Telemetry from '@/components/Telemetry.vue';
import AskAssistantFloatingButton from '@/components/AskAssistant/Chat/AskAssistantFloatingButton.vue';
import AssistantsHub from '@/components/AskAssistant/AssistantsHub.vue';
import { loadLanguage } from '@n8n/i18n';
-import { APP_MODALS_ELEMENT_ID, HIRING_BANNER, VIEWS } from '@/constants';
+import {
+ APP_MODALS_ELEMENT_ID,
+ CODEMIRROR_TOOLTIP_CONTAINER_ELEMENT_ID,
+ HIRING_BANNER,
+ VIEWS,
+} from '@/constants';
import { useRootStore } from '@n8n/stores/useRootStore';
import { useAssistantStore } from '@/stores/assistant.store';
import { useBuilderStore } from '@/stores/builder.store';
@@ -135,6 +140,7 @@ watch(
+
diff --git a/packages/frontend/editor-ui/src/composables/useExpressionEditor.ts b/packages/frontend/editor-ui/src/composables/useExpressionEditor.ts
index 63ba80d05c..0d0c6c80c5 100644
--- a/packages/frontend/editor-ui/src/composables/useExpressionEditor.ts
+++ b/packages/frontend/editor-ui/src/composables/useExpressionEditor.ts
@@ -206,7 +206,11 @@ export const useExpressionEditor = ({
const state = EditorState.create({
doc: toValue(editorValue),
extensions: [
- TARGET_NODE_PARAMETER_FACET.of(toValue(targetNodeParameterContext)),
+ TARGET_NODE_PARAMETER_FACET.of(
+ expressionLocalResolveContext.value
+ ? { nodeName: expressionLocalResolveContext.value.nodeName, parameterPath: '' }
+ : toValue(targetNodeParameterContext),
+ ),
customExtensions.value.of(toValue(extensions)),
readOnlyExtensions.value.of([EditorState.readOnly.of(toValue(isReadOnly))]),
telemetryExtensions.value.of([]),
diff --git a/packages/frontend/editor-ui/src/composables/useStyles.ts b/packages/frontend/editor-ui/src/composables/useStyles.ts
index 6a1c5c6726..fb07213294 100644
--- a/packages/frontend/editor-ui/src/composables/useStyles.ts
+++ b/packages/frontend/editor-ui/src/composables/useStyles.ts
@@ -14,6 +14,7 @@ const APP_Z_INDEXES = {
TOASTS: 2100,
ASK_ASSISTANT_FLOATING_BUTTON: 3000,
ASK_ASSISTANT_FLOATING_BUTTON_TOOLTIP: 3000,
+ CODEMIRROR_TOOLTIP: 3000,
DRAGGABLE: 9999999,
ACTIVE_STICKY: 9999999,
WORKFLOW_PREVIEW_NDV: 9999999,
diff --git a/packages/frontend/editor-ui/src/constants.ts b/packages/frontend/editor-ui/src/constants.ts
index 5722081c09..d9d0680bdf 100644
--- a/packages/frontend/editor-ui/src/constants.ts
+++ b/packages/frontend/editor-ui/src/constants.ts
@@ -953,8 +953,8 @@ export const ExpressionLocalResolveContextSymbol = Symbol(
'ExpressionLocalResolveContext',
) as InjectionKey>;
-/** Auth */
export const APP_MODALS_ELEMENT_ID = 'app-modals';
+export const CODEMIRROR_TOOLTIP_CONTAINER_ELEMENT_ID = 'cm-tooltip-container';
export const AI_NODES_PACKAGE_NAME = '@n8n/n8n-nodes-langchain';
diff --git a/packages/frontend/editor-ui/src/plugins/codemirror/tooltips/InfoBoxTooltip.ts b/packages/frontend/editor-ui/src/plugins/codemirror/tooltips/InfoBoxTooltip.ts
index 8b9c992fad..7cecc599f1 100644
--- a/packages/frontend/editor-ui/src/plugins/codemirror/tooltips/InfoBoxTooltip.ts
+++ b/packages/frontend/editor-ui/src/plugins/codemirror/tooltips/InfoBoxTooltip.ts
@@ -12,12 +12,14 @@ import {
hoverTooltip,
keymap,
showTooltip,
+ tooltips,
type Command,
type EditorView,
type Tooltip,
} from '@codemirror/view';
import type { SyntaxNode } from '@lezer/common';
import type { createInfoBoxRenderer } from '../completions/infoBoxRenderer';
+import { CODEMIRROR_TOOLTIP_CONTAINER_ELEMENT_ID } from '@/constants';
const findNearestParentOfType =
(type: string) =>
@@ -308,6 +310,9 @@ export const closeCursorInfoBox: Command = (view) => {
export const infoBoxTooltips = (): Extension[] => {
return [
+ tooltips({
+ parent: document.getElementById(CODEMIRROR_TOOLTIP_CONTAINER_ELEMENT_ID) ?? undefined,
+ }),
cursorInfoBoxTooltip,
hoverInfoBoxTooltip,
keymap.of([
diff --git a/packages/frontend/editor-ui/src/styles/plugins/_codemirror.scss b/packages/frontend/editor-ui/src/styles/plugins/_codemirror.scss
index 210791d562..28b9203e16 100644
--- a/packages/frontend/editor-ui/src/styles/plugins/_codemirror.scss
+++ b/packages/frontend/editor-ui/src/styles/plugins/_codemirror.scss
@@ -1,13 +1,21 @@
+#cm-tooltip-container {
+ position: relative;
+ z-index: var(--z-index-codemirror-tooltip);
+ max-width: 0;
+ max-height: 0;
+}
+
.code-node-editor .cm-editor .cm-tooltip-autocomplete > ul[role='listbox'] {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
-.cm-editor .cm-tooltip-autocomplete {
+#cm-tooltip-container .cm-tooltip-autocomplete {
background-color: var(--color-background-xlight) !important;
box-shadow: var(--box-shadow-light);
border: none;
+ border-radius: var(--border-radius-base);
.cm-tooltip {
overflow: hidden;
@@ -90,9 +98,9 @@
}
}
-.cm-editor .cm-tooltip.cm-completionInfo,
-.cm-editor .cm-tooltip.cm-cursorInfo,
-.cm-editor .cm-tooltip-hover {
+#cm-tooltip-container .cm-tooltip.cm-completionInfo,
+#cm-tooltip-container .cm-tooltip.cm-cursorInfo,
+#cm-tooltip-container .cm-tooltip-hover {
// Add padding when infobox only contains text
&:not(:has(div)) {
padding: var(--spacing-xs);
@@ -293,7 +301,7 @@
}
}
-.cm-editor .cm-tooltip.cm-completionInfo {
+#cm-tooltip-container .cm-tooltip.cm-completionInfo {
background-color: var(--color-background-xlight);
border: var(--border-base);
box-shadow: var(--box-shadow-light);
@@ -335,8 +343,8 @@
}
}
-.cm-editor .cm-tooltip.cm-cursorInfo,
-.cm-editor .cm-tooltip-hover {
+#cm-tooltip-container .cm-tooltip.cm-cursorInfo,
+#cm-tooltip-container .cm-tooltip-hover {
background-color: var(--color-infobox-background);
border: var(--border-base);
box-shadow: var(--box-shadow-light);