import { $createParagraphNode, $createTextNode, $getRoot, $isElementNode, createEditor, } from "lexical"; import { registerHistory, createEmptyHistoryState } from "@lexical/history"; import { $createHeadingNode, HeadingNode, registerRichText, } from "@lexical/rich-text"; import { onCleanup, onMount } from "solid-js"; import type Pages from "../../protocol/pages"; import "./editor.css"; const editor = createEditor({ nodes: [HeadingNode] }); function ref(el: HTMLElement) { editor.setRootElement(el); } export default (props: { id: number; title: string; text: string; onUpdatePage: (content: Pages.RequestContentPage) => void; }) => { const initialEditorState = () => { const root = $getRoot(); for (const [i, text] of props.text.split("\n").entries()) { const line = i === 0 ? $createHeadingNode("h2") : $createParagraphNode(); const indent = text.match(/^\s*/)?.[0]?.length ?? 0; line.setIndent(indent); line.append($createTextNode(text.slice(indent))); root.append(line); } }; onCleanup(registerRichText(editor, initialEditorState)); onCleanup(registerHistory(editor, createEmptyHistoryState(), 333)); onCleanup( editor.registerUpdateListener(() => editor.update(() => { const root = $getRoot(); const lines = root.getChildren().map((line, i) => { if (i === 0) return line.getTextContent().trim(); const indent = $isElementNode(line) ? line.getIndent() : 0; return `${" ".repeat(indent)}${line.getTextContent()}`; }); const title = lines[0]; const text = lines.join("\n"); props.onUpdatePage({ id: props.id, title: title ?? "", text }); }) ) ); onMount(() => editor.focus()); return
; };