diff --git a/cypress/pages/workflow.ts b/cypress/pages/workflow.ts
index ef5cb62190..5d13bc64bc 100644
--- a/cypress/pages/workflow.ts
+++ b/cypress/pages/workflow.ts
@@ -62,7 +62,8 @@ export class WorkflowPage extends BasePage {
this.getters.canvasNodeByName(nodeTypeName).dblclick();
},
openExpressionEditor: () => {
- cy.get('input[value="expression"]').parent('label').click();
+ cy.contains('Expression').invoke('show').click();
+ cy.getByTestId('expander').invoke('show').click();
},
typeIntoParameterInput: (parameterName: string, content: string) => {
this.getters.ndvParameterInput(parameterName).type(content);
diff --git a/packages/design-system/src/components/N8nIcon/Icon.vue b/packages/design-system/src/components/N8nIcon/Icon.vue
index 1e6c9e4ae0..1329442190 100644
--- a/packages/design-system/src/components/N8nIcon/Icon.vue
+++ b/packages/design-system/src/components/N8nIcon/Icon.vue
@@ -1,5 +1,5 @@
-
+
diff --git a/packages/design-system/src/css/_tokens.scss b/packages/design-system/src/css/_tokens.scss
index 8ec5bc0861..944bb55f54 100644
--- a/packages/design-system/src/css/_tokens.scss
+++ b/packages/design-system/src/css/_tokens.scss
@@ -461,6 +461,7 @@
--font-weight-regular: 400;
--font-weight-bold: 600;
--font-family: 'Open Sans', sans-serif;
+ --font-family-monospace: Menlo, Consolas, 'DejaVu Sans Mono', monospace;
--spacing-5xs: 0.125rem;
--spacing-4xs: 0.25rem;
diff --git a/packages/editor-ui/package.json b/packages/editor-ui/package.json
index 2aa39a53c6..8b135558b9 100644
--- a/packages/editor-ui/package.json
+++ b/packages/editor-ui/package.json
@@ -40,6 +40,7 @@
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/vue-fontawesome": "^2.0.2",
"axios": "^0.21.1",
+ "codemirror-lang-n8n-expression": "^0.1.0",
"dateformat": "^3.0.3",
"esprima-next": "5.8.4",
"fast-json-stable-stringify": "^2.1.0",
diff --git a/packages/editor-ui/src/components/CodeNodeEditor/CodeNodeEditor.vue b/packages/editor-ui/src/components/CodeNodeEditor/CodeNodeEditor.vue
index 78daa5bda8..80b4dd392d 100644
--- a/packages/editor-ui/src/components/CodeNodeEditor/CodeNodeEditor.vue
+++ b/packages/editor-ui/src/components/CodeNodeEditor/CodeNodeEditor.vue
@@ -1,5 +1,5 @@
-
+
+
+
diff --git a/packages/editor-ui/src/components/ExpressionEditorModal/ExpressionModalOutput.vue b/packages/editor-ui/src/components/ExpressionEditorModal/ExpressionEditorModalOutput.vue
similarity index 76%
rename from packages/editor-ui/src/components/ExpressionEditorModal/ExpressionModalOutput.vue
rename to packages/editor-ui/src/components/ExpressionEditorModal/ExpressionEditorModalOutput.vue
index 6d40157df9..b6545b2bda 100644
--- a/packages/editor-ui/src/components/ExpressionEditorModal/ExpressionModalOutput.vue
+++ b/packages/editor-ui/src/components/ExpressionEditorModal/ExpressionEditorModalOutput.vue
@@ -1,5 +1,5 @@
-
+
+
+
diff --git a/packages/editor-ui/src/components/ExpressionParameterInput.vue b/packages/editor-ui/src/components/ExpressionParameterInput.vue
new file mode 100644
index 0000000000..d2cc37b047
--- /dev/null
+++ b/packages/editor-ui/src/components/ExpressionParameterInput.vue
@@ -0,0 +1,293 @@
+
+
+
+
+
+
+ {{ $locale.baseText('parameterInput.resultForItem') }} {{ hoveringItemNumber }}
+
+
+
+
+
+
+ {{ $locale.baseText('parameterInput.anythingInside') }}
+
+
+
+ {{ $locale.baseText('parameterInput.isJavaScript') }}
+
+
+ {{ $locale.baseText('parameterInput.learnMore') }}
+
+
+
+
+
+
+
+
+
diff --git a/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionEditorInput.vue b/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionEditorInput.vue
new file mode 100644
index 0000000000..53468eb5d2
--- /dev/null
+++ b/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionEditorInput.vue
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
diff --git a/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionEditorOutput.vue b/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionEditorOutput.vue
new file mode 100644
index 0000000000..bf5c111494
--- /dev/null
+++ b/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionEditorOutput.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
diff --git a/packages/editor-ui/src/components/InlineExpressionEditor/theme.ts b/packages/editor-ui/src/components/InlineExpressionEditor/theme.ts
new file mode 100644
index 0000000000..0e11f5e8c9
--- /dev/null
+++ b/packages/editor-ui/src/components/InlineExpressionEditor/theme.ts
@@ -0,0 +1,68 @@
+import { EditorView } from '@codemirror/view';
+import { highlighter } from '@/plugins/codemirror/resolvableHighlighter';
+
+const commonThemeProps = {
+ '&.cm-focused': {
+ outline: '0 !important',
+ },
+ '.cm-content': {
+ fontFamily: 'var(--font-family-monospace)',
+ color: 'var(--input-font-color, var(--color-text-dark))',
+ },
+ '.cm-line': {
+ padding: '0',
+ },
+};
+
+export const inputTheme = ({ isSingleLine } = { isSingleLine: false }) => {
+ const theme = EditorView.theme({
+ ...commonThemeProps,
+ '&': {
+ maxHeight: isSingleLine ? '30px' : '112px',
+ minHeight: '30px',
+ width: '100%',
+ fontSize: 'var(--font-size-2xs)',
+ padding: '0 0 0 var(--spacing-2xs)',
+ borderWidth: 'var(--border-width-base)',
+ borderStyle: 'var(--input-border-style, var(--border-style-base))',
+ borderColor: 'var(--input-border-color, var(--border-color-base))',
+ borderRadius: 'var(--input-border-radius, var(--border-radius-base))',
+ borderTopLeftRadius: '0',
+ borderBottomLeftRadius: '0',
+ backgroundColor: 'white',
+ },
+ '.cm-scroller': {
+ lineHeight: '1.68',
+ },
+ });
+
+ return [theme, highlighter.resolvableStyle];
+};
+
+export const outputTheme = () => {
+ const theme = EditorView.theme({
+ ...commonThemeProps,
+ '&': {
+ maxHeight: '95px',
+ width: '100%',
+ fontSize: 'var(--font-size-2xs)',
+ padding: '0',
+ borderTopLeftRadius: '0',
+ borderBottomLeftRadius: '0',
+ backgroundColor: 'white',
+ },
+ '.cm-scroller': {
+ lineHeight: '1.6',
+ },
+ '.cm-valid-resolvable': {
+ padding: '0 2px',
+ borderRadius: '2px',
+ },
+ '.cm-invalid-resolvable': {
+ padding: '0 2px',
+ borderRadius: '2px',
+ },
+ });
+
+ return [theme, highlighter.resolvableStyle];
+};
diff --git a/packages/editor-ui/src/components/ParameterInput.vue b/packages/editor-ui/src/components/ParameterInput.vue
index 6a598a63e3..da565e27a7 100644
--- a/packages/editor-ui/src/components/ParameterInput.vue
+++ b/packages/editor-ui/src/components/ParameterInput.vue
@@ -12,11 +12,7 @@
@closeDialog="closeExpressionEditDialog"
@valueChanged="expressionUpdated"
>
-