import { EditorView, minimalSetup } from 'codemirror'; import { defineComponent, onBeforeUnmount, onMounted, ref, watch } from 'vue'; import { EditorState } from '@codemirror/state'; import type { DocumentModel } from '@webank/letgo-designer'; import { autocompletion } from '@codemirror/autocomplete'; import type { ViewUpdate } from '@codemirror/view'; import { placeholder, } from '@codemirror/view'; import type { PropType } from 'vue'; import { HintTheme, hintPlugin } from './hint'; import { useHint } from './use'; import './expression-editor.less'; export const ExpressionEditor = defineComponent({ props: { documentModel: Object as PropType, hints: Object as PropType>, doc: String, onChangeDoc: Function as PropType<(doc: string) => void>, placeholder: String, }, setup(props) { const editorRefEl = ref(); let currentDoc = props.doc || ''; let editorView: EditorView; const { hintOptions } = useHint(props); const Theme = EditorView.theme({ '&': { borderRadius: '4px', border: '1px solid #cfd0d3', }, '&.cm-focused': { outline: '0', border: '1px solid #52c41a', }, '& .cm-gutters': { borderRight: 0, }, ...HintTheme, }); const genState = () => { return EditorState.create({ doc: props.doc, extensions: [ minimalSetup, Theme, placeholder(props.placeholder || '表达式'), autocompletion({ override: [hintPlugin(hintOptions)], icons: false, }), EditorView.updateListener.of((v: ViewUpdate) => { if (v.docChanged) { currentDoc = v.state.sliceDoc(); props.onChangeDoc(currentDoc); } }), ], }); }; onMounted(() => { editorView = new EditorView({ state: genState(), parent: editorRefEl.value, }); }); watch(() => props.doc, () => { if (editorView && props.doc !== currentDoc) { currentDoc = props.doc; const state = genState(); editorView.setState(state); } }); onBeforeUnmount(() => { editorView?.destroy(); }); return () => { return
; }; }, });