1 import {$getRoot, createEditor, ElementNode} from 'lexical';
2 import {createEmptyHistoryState, registerHistory} from '@lexical/history';
3 import {HeadingNode, QuoteNode, registerRichText} from '@lexical/rich-text';
4 import {mergeRegister} from '@lexical/utils';
5 import {$generateNodesFromDOM} from '@lexical/html';
7 class CalloutParagraph extends ElementNode {
15 return new CalloutParagraph(node.__category, node.__key);
18 constructor(category, key) {
20 this.__category = category;
23 createDOM(_config, _editor) {
24 const dom = document.createElement('p');
25 dom.classList.add('callout', this.__category || '');
29 updateDOM(prevNode, dom) {
30 // Returning false tells Lexical that this node does not need its
31 // DOM element replacing with a new copy from createDOM.
38 if (node.classList.contains('callout')) {
40 conversion: element => {
41 let category = 'info';
42 const categories = ['info', 'success', 'warning', 'danger'];
44 for (const c of categories) {
45 if (element.classList.contains(c)) {
52 node: new CalloutParagraph(category),
65 ...super.exportJSON(),
68 category: this.__category,
73 // TODO - Extract callout to own file
74 // TODO - Add helper functions
75 // https://lexical.dev/docs/concepts/nodes#creating-custom-nodes
77 export function createPageEditorInstance(editArea) {
78 console.log('creating editor', editArea);
81 namespace: 'BookStackPageEditor',
82 nodes: [HeadingNode, QuoteNode, CalloutParagraph],
83 onError: console.error,
86 const startingHtml = editArea.innerHTML;
87 const parser = new DOMParser();
88 const dom = parser.parseFromString(startingHtml, 'text/html');
90 const editor = createEditor(config);
91 editor.setRootElement(editArea);
94 registerRichText(editor),
95 registerHistory(editor, createEmptyHistoryState(), 300),
99 const startingNodes = $generateNodesFromDOM(editor, dom);
100 const root = $getRoot();
101 root.append(...startingNodes);
104 const debugView = document.getElementById('lexical-debug');
105 editor.registerUpdateListener(({editorState}) => {
106 console.log('editorState', editorState.toJSON());
107 debugView.textContent = JSON.stringify(editorState.toJSON(), null, 2);