I want to implement a What-you-see-is-what-you-get markdown editor.
When the user type **bold**
, I want to render it to be an editable bold, so that when pressing backspace, it will become bol
I try this using widget to replace the markdown text, it works. But it turns out I cannot place the cursor into the widget and when the user press backspace, it will become **bold*
instead of bol
Any idea of fixing this are appreciated!
Below is my code:
import { MatchDecorator } from "@codemirror/view"
import { Decoration, DecorationSet, EditorView, ViewPlugin, ViewUpdate, WidgetType } from "@uiw/react-codemirror"
const addMatcher = new MatchDecorator({
regexp: /\*\*([^**]*)\*\*/g,
decoration: match => Decoration.replace({
widget: new AddWidget(match[1]),
})
})
export const adds = ViewPlugin.fromClass(class {
adds: DecorationSet
constructor(view: EditorView) {
this.adds = addMatcher.createDeco(view)
}
update(update: ViewUpdate) {
this.adds = addMatcher.updateDeco(update, this.adds)
}
}, {
decorations: instance => instance.adds,
provide: (plugin) =>
EditorView.decorations.of((view) => {
return view.plugin(plugin)?.adds || Decoration.none;
}),
})
class AddWidget extends WidgetType {
constructor(readonly name: string) {
super()
}
eq(other: AddWidget) {
return this.name == other.name
}
toDOM() {
const elt = document.createElement("span")
elt.style.cssText = `
font-weight: 900
`
elt.textContent = this.name
// elt.setAttribute('contenteditable', 'true')
return elt
}
ignoreEvent() {
return false
}
}