diff --git a/docs/components/markdown-editor.md b/docs/components/markdown-editor.md index df35be280..4fd6f74f5 100644 --- a/docs/components/markdown-editor.md +++ b/docs/components/markdown-editor.md @@ -7,6 +7,10 @@ const description1 = ref(null); const description2 = ref(null); const description3 = ref(null); +const description4 = ref("Hello, world! This is a **bold** statement."); + +const isDisabled = ref(false); + const onImageUpload = (file) => { return URL.createObjectURL(file).replace("blob:", ""); }; @@ -79,3 +83,34 @@ const description = ref(null) ``` + +## With default value + + + + +```vue + + + +``` + +## Disabled + + + + + +```vue + + + +``` diff --git a/lib/components/base/MarkdownEditor.vue b/lib/components/base/MarkdownEditor.vue index d72c066b3..f8344a73d 100644 --- a/lib/components/base/MarkdownEditor.vue +++ b/lib/components/base/MarkdownEditor.vue @@ -250,7 +250,7 @@ -
+
import { type Component, computed, ref, onMounted, onBeforeUnmount, toRef, watch } from 'vue' -import { EditorState } from '@codemirror/state' +import { Compartment, EditorState } from '@codemirror/state' import { EditorView, keymap, placeholder as cm_placeholder } from '@codemirror/view' import { markdown } from '@codemirror/lang-markdown' import { indentWithTab, historyKeymap, history } from '@codemirror/commands' @@ -327,6 +327,7 @@ const props = withDefaults( const editorRef = ref() let editor: EditorView | null = null +let isDisabledCompartment: Compartment | null = null const emit = defineEmits(['update:modelValue']) @@ -338,7 +339,7 @@ onMounted(() => { }) const theme = EditorView.theme({ - // in defualts.scss there's references to .cm-content and such to inherit global styles + // in defaults.scss there's references to .cm-content and such to inherit global styles '.cm-content': { marginBlockEnd: '0.5rem', padding: '0.5rem', @@ -355,6 +356,10 @@ onMounted(() => { }, }) + isDisabledCompartment = new Compartment() + + const disabledCompartment = EditorState.readOnly.of(props.disabled) + const eventHandlers = EditorView.domEventHandlers({ paste: (ev, view) => { const { clipboardData } = ev @@ -437,13 +442,23 @@ onMounted(() => { keymap.of(historyKeymap), cm_placeholder(props.placeholder || ''), inputFilter, + isDisabledCompartment.of(disabledCompartment), ], }) editor = new EditorView({ state: editorState, parent: editorRef.value, - doc: props.modelValue, + doc: props.modelValue ?? '', // This doesn't work for some reason + }) + + // set editor content to props.modelValue + editor?.dispatch({ + changes: { + from: 0, + to: editor.state.doc.length, + insert: props.modelValue, + }, }) }) @@ -541,18 +556,35 @@ const BUTTONS: ButtonGroupMap = { }, } +watch( + () => props.disabled, + (newValue) => { + if (editor && isDisabledCompartment) { + editor.dispatch({ + effects: isDisabledCompartment.reconfigure(EditorState.readOnly.of(newValue)), + }) + } + } +) + const currentValue = toRef(props, 'modelValue') -watch(currentValue, (newValue) => { - if (editor) { - editor.dispatch({ - changes: { - from: 0, - to: editor.state.doc.length, - insert: newValue, - }, - }) +watch( + currentValue, + (newValue) => { + if (editor && newValue !== editor.state.doc.toString()) { + editor.dispatch({ + changes: { + from: 0, + to: editor.state.doc.length, + insert: newValue, + }, + }) + } + }, + { + immediate: true, } -}) +) const updateCurrentValue = (newValue: string) => { emit('update:modelValue', newValue)