export interface VditorLike { getValue: () => string setValue: (value: string, render?: boolean) => void destroy: () => void } export interface CreateVditorLikeOptions { element: HTMLElement value: string onInput: (value: string) => void } export type CreateVditorLike = (options: CreateVditorLikeOptions) => VditorLike export interface CreateBridgeOptions { getModelValue: () => string emitUpdate: (value: string) => void createEditor: CreateVditorLike } export function createPostBodyMarkdownEditorBridge(options: CreateBridgeOptions) { let editor: VditorLike | null = null let syncingFromProps = false function mount(element: HTMLElement) { if (editor) { return editor } editor = options.createEditor({ element, value: options.getModelValue(), onInput(value) { if (syncingFromProps) { return } if (value === options.getModelValue()) { return } options.emitUpdate(value) }, }) return editor } function syncFromProps() { if (!editor) { return } const nextValue = options.getModelValue() if (editor.getValue() === nextValue) { return } syncingFromProps = true try { editor.setValue(nextValue, true) } finally { syncingFromProps = false } } function unmount() { if (!editor) { return } editor.destroy() editor = null } return { mount, syncFromProps, unmount, getEditor: () => editor, } }