1 import {$isListNode, ListItemNode, SerializedListItemNode} from "@lexical/list";
2 import {EditorConfig} from "lexical/LexicalEditor";
3 import {DOMExportOutput, LexicalEditor, LexicalNode} from "lexical";
4 import {el} from "../helpers";
6 function updateListItemChecked(
8 listItemNode: ListItemNode,
10 // Only set task list attrs for leaf list items
11 const shouldBeTaskItem = !$isListNode(listItemNode.getFirstChild());
12 dom.classList.toggle('task-list-item', shouldBeTaskItem);
13 if (listItemNode.__checked) {
14 dom.setAttribute('checked', 'checked');
16 dom.removeAttribute('checked');
21 export class CustomListItemNode extends ListItemNode {
22 static getType(): string {
23 return 'custom-list-item';
26 static clone(node: CustomListItemNode): CustomListItemNode {
27 return new CustomListItemNode(node.__value, node.__checked, node.__key);
30 createDOM(config: EditorConfig): HTMLElement {
31 const element = document.createElement('li');
32 const parent = this.getParent();
34 if ($isListNode(parent) && parent.getListType() === 'check') {
35 updateListItemChecked(element, this);
38 element.value = this.__value;
44 prevNode: ListItemNode,
48 const parent = this.getParent();
49 if ($isListNode(parent) && parent.getListType() === 'check') {
50 updateListItemChecked(dom, this);
52 // @ts-expect-error - this is always HTMLListItemElement
53 dom.value = this.__value;
58 exportDOM(editor: LexicalEditor): DOMExportOutput {
59 const element = this.createDOM(editor._config);
60 element.style.textAlign = this.getFormatType();
62 if (element.classList.contains('task-list-item')) {
63 const input = el('input', {
67 if (element.hasAttribute('checked')) {
68 input.setAttribute('checked', 'checked');
69 element.removeAttribute('checked');
72 element.prepend(input);
80 exportJSON(): SerializedListItemNode {
82 ...super.exportJSON(),
83 type: 'custom-list-item',
88 export function $isCustomListItemNode(
89 node: LexicalNode | null | undefined,
90 ): node is CustomListItemNode {
91 return node instanceof CustomListItemNode;