refactor(editor): Move editor-ui and design-system to frontend dir (no-changelog) (#13564)

This commit is contained in:
Alex Grozav
2025-02-28 14:28:30 +02:00
committed by GitHub
parent 684353436d
commit f5743176e5
1635 changed files with 805 additions and 1079 deletions

View File

@@ -0,0 +1,127 @@
<script setup lang="ts">
import { history } from '@codemirror/commands';
import { javascript } from '@codemirror/lang-javascript';
import { foldGutter, indentOnInput } from '@codemirror/language';
import { lintGutter } from '@codemirror/lint';
import type { Extension } from '@codemirror/state';
import { EditorState, Prec } from '@codemirror/state';
import type { ViewUpdate } from '@codemirror/view';
import {
EditorView,
dropCursor,
highlightActiveLine,
highlightActiveLineGutter,
keymap,
lineNumbers,
} from '@codemirror/view';
import { computed, onMounted, ref, watch } from 'vue';
import { editorKeymap } from '@/plugins/codemirror/keymap';
import { n8nAutocompletion } from '@/plugins/codemirror/n8nLang';
import { codeEditorTheme } from '../CodeNodeEditor/theme';
type Props = {
modelValue: string;
isReadOnly?: boolean;
fillParent?: boolean;
rows?: number;
posthogCapture?: boolean;
};
const props = withDefaults(defineProps<Props>(), { fillParent: false, isReadOnly: false, rows: 4 });
const emit = defineEmits<{
'update:modelValue': [value: string];
}>();
onMounted(() => {
createEditor();
});
watch(
() => props.modelValue,
(newValue: string) => {
const editorValue = editor.value?.state?.doc.toString();
// If model value changes from outside the component
if (
editorValue !== undefined &&
editorValue.length !== newValue.length &&
editorValue !== newValue
) {
destroyEditor();
createEditor();
}
},
);
function createEditor() {
const state = EditorState.create({ doc: props.modelValue, extensions: extensions.value });
const parent = jsEditorRef.value;
editor.value = new EditorView({ parent, state });
editorState.value = editor.value.state;
}
function destroyEditor() {
editor.value?.destroy();
}
const jsEditorRef = ref<HTMLDivElement>();
const editor = ref<EditorView | null>(null);
const editorState = ref<EditorState | null>(null);
const generatedCodeCapture = computed(() => {
return props.posthogCapture ? '' : 'ph-no-capture ';
});
const extensions = computed(() => {
const extensionsToApply: Extension[] = [
javascript(),
lineNumbers(),
EditorView.lineWrapping,
EditorState.readOnly.of(props.isReadOnly),
codeEditorTheme({
isReadOnly: props.isReadOnly,
maxHeight: props.fillParent ? '100%' : '40vh',
minHeight: '20vh',
rows: props.rows,
}),
];
if (!props.isReadOnly) {
extensionsToApply.push(
history(),
Prec.highest(keymap.of(editorKeymap)),
lintGutter(),
n8nAutocompletion(),
indentOnInput(),
highlightActiveLine(),
highlightActiveLineGutter(),
foldGutter(),
dropCursor(),
EditorView.updateListener.of((viewUpdate: ViewUpdate) => {
if (!viewUpdate.docChanged || !editor.value) return;
emit('update:modelValue', editor.value?.state.doc.toString());
}),
);
}
return extensionsToApply;
});
</script>
<template>
<div :class="$style.editor" :style="isReadOnly ? 'opacity: 0.7' : ''">
<div ref="jsEditorRef" :class="generatedCodeCapture + 'js-editor'"></div>
<slot name="suffix" />
</div>
</template>
<style lang="scss" module>
.editor {
height: 100%;
& > div {
height: 100%;
}
}
</style>