I’d like to use code mirror 6 in an Elm project via a custom element. Does anyone have example code that I could use to get started?
I think this will do
import { indentWithTab } from "@codemirror/commands";
import { keymap } from "@codemirror/view";
import { EditorView, basicSetup } from "codemirror";
export class CustomEditor extends HTMLElement {
static get observedAttributes() {
return ["value"];
}
editor: EditorView | null = null;
get value() {
return this.editor?.state.doc.toString() || "";
}
set value(newValue: string) {
this._setContent(newValue);
}
constructor() {
super();
this.attachShadow({ mode: "open" });
const template = document.createElement("div");
template.id = "editor";
this.shadowRoot?.appendChild(template);
const attributes: { [key: string]: any } = {};
for (let i = 0; i < this.attributes.length; i++) {
if (this.attributes[i].nodeValue) {
attributes[this.attributes[i].nodeName] = this.attributes[i].nodeValue;
}
}
this.editor = new EditorView({
...attributes,
parent: this.shadowRoot?.getElementById("editor") as HTMLElement,
doc: this.value,
extensions: [
basicSetup,
keymap.of([indentWithTab]),
EditorView.updateListener.of(function (e) {
new CustomEvent("input", { detail: e.state.doc.toString() });
}),
],
});
}
private _setContent(value: string) {
this.editor?.dispatch({
changes: {
from: 0,
to: this.editor.state.doc.length,
insert: value,
},
});
}
attributeChangedCallback(name: string, oldValue: any, newValue: any) {
if (name === "value") {
this._setContent(newValue);
}
}
}