@mkljczk/lexical-remark
Version:
This package contains Markdown helpers and functionality for Lexical using remark-parse.
109 lines (108 loc) • 3.1 kB
JavaScript
/* eslint-disable @typescript-eslint/no-use-before-define */
import { ElementNode, } from 'lexical';
export function convertDetailsElement(domNode) {
const openAttr = domNode.getAttribute('open');
const isOpen = openAttr !== null ? openAttr === 'true' : true;
const node = $createCollapsibleContainerNode(isOpen);
return {
node,
};
}
/**
* A Lexical node to represent an HTML details container
*/
export class CollapsibleContainerNode extends ElementNode {
__open;
constructor(open, key) {
super(key);
this.__open = open;
}
static getType() {
return 'collapsible-container';
}
static clone(node) {
return new CollapsibleContainerNode(node.__open, node.__key);
}
createDOM(config, editor) {
const dom = document.createElement('details');
dom.classList.add('Collapsible__container');
dom.open = this.__open;
dom.addEventListener('toggle', () => {
const open = editor.getEditorState().read(() => this.getOpen());
if (open !== dom.open) {
editor.update(() => this.toggleOpen());
}
});
return dom;
}
updateDOM(prevNode, dom) {
if (prevNode.__open !== this.__open) {
dom.open = this.__open;
}
return false;
}
static importDOM() {
return {
details: (domNode) => {
return {
conversion: convertDetailsElement,
priority: 1,
};
},
};
}
static importJSON(serializedNode) {
const node = $createCollapsibleContainerNode(serializedNode.open);
return node;
}
exportDOM() {
const element = document.createElement('details');
element.setAttribute('open', this.__open.toString());
return { element };
}
exportJSON() {
return {
...super.exportJSON(),
open: this.__open,
type: 'collapsible-container',
version: 1,
};
}
/**
* Sets the open state of the details container
*/
setOpen(open) {
const writable = this.getWritable();
writable.__open = open;
}
/**
* Gets the open state of the details container
*/
getOpen() {
return this.getLatest().__open;
}
/**
* Toggles the open state of the details container
*/
toggleOpen() {
this.setOpen(!this.getOpen());
}
}
/**
* Creates a Collapsible Container node with an initial open state
*
* @param isOpen The initial open state of the container
* @returns A Collapsible Container node
*/
export function $createCollapsibleContainerNode(isOpen) {
return new CollapsibleContainerNode(isOpen);
}
/**
* A typeguard function to assert on a Collapsible Container node
*
* @param node A Lexical node
* @returns true if the node is a Collapsible Container node, otherwise false
*/
export function $isCollapsibleContainerNode(node) {
return node instanceof CollapsibleContainerNode;
}