Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041import { useEffect, useRef } from 'react'import { EditorState } from '@codemirror/state'import { EditorView, drawSelection, keymap } from '@codemirror/view'import { defaultKeymap, history, historyKeymap } from '@codemirror/commands'import type { useDocumentSync } from '../sync/use-document-sync'
type Binding = Pick<ReturnType<typeof useDocumentSync>, 'bindView' | 'onDocumentUpdate'>
/** Ordinary .base text uses the same Automerge/CM6 document binding as other editors. */export function BaseSourceEditor({ source, binding, onTextChange, onView }: { source: string; binding: Binding; onTextChange: (text: string) => void; onView?: (view: EditorView | null) => void }) { const parent = useRef<HTMLDivElement>(null) const initialSource = useRef(source) const bindView = binding.bindView const onUpdate = useRef(binding.onDocumentUpdate) const onText = useRef(onTextChange) const onViewRef = useRef(onView) onUpdate.current = binding.onDocumentUpdate onText.current = onTextChange onViewRef.current = onView useEffect(() => { if (!parent.current) return const view = new EditorView({ parent: parent.current, state: EditorState.create({ doc: initialSource.current, extensions: [ history(), drawSelection(), EditorView.lineWrapping, keymap.of([...defaultKeymap, ...historyKeymap]), EditorView.contentAttributes.of({ 'aria-label': 'Query definition' }), EditorView.updateListener.of(update => { if (!update.docChanged) return onText.current(update.state.doc.toString()) onUpdate.current(update) }), ] }), }) bindView(view) onViewRef.current?.(view) return () => { onViewRef.current?.(null); bindView(null, undefined, view); view.destroy() } }, [bindView]) return <div className="reams-base-source-editor cm6-editor-container" ref={parent} />}