+import {$isListNode, ListItemNode, ListNode, SerializedListItemNode} from "@lexical/list";
+import {EditorConfig} from "lexical/LexicalEditor";
+import {DOMExportOutput, LexicalEditor, LexicalNode} from "lexical";
+import {el} from "../helpers";
+
+function updateListItemChecked(
+ dom: HTMLElement,
+ listItemNode: ListItemNode,
+): void {
+ // Only set task list attrs for leaf list items
+ const shouldBeTaskItem = !$isListNode(listItemNode.getFirstChild());
+ dom.classList.toggle('task-list-item', shouldBeTaskItem);
+ if (listItemNode.__checked) {
+ dom.setAttribute('checked', 'checked');
+ } else {
+ dom.removeAttribute('checked');
+ }
+}
+
+
+export class CustomListItemNode extends ListItemNode {
+ static getType(): string {
+ return 'custom-list-item';
+ }
+
+ static clone(node: CustomListItemNode): CustomListItemNode {
+ return new CustomListItemNode(node.__value, node.__checked, node.__key);
+ }
+
+ createDOM(config: EditorConfig): HTMLElement {
+ const element = document.createElement('li');
+ const parent = this.getParent();
+
+ if ($isListNode(parent) && parent.getListType() === 'check') {
+ updateListItemChecked(element, this);
+ }
+
+ element.value = this.__value;
+
+ return element;
+ }
+
+ updateDOM(
+ prevNode: ListItemNode,
+ dom: HTMLElement,
+ config: EditorConfig,
+ ): boolean {
+ const parent = this.getParent();
+ if ($isListNode(parent) && parent.getListType() === 'check') {
+ updateListItemChecked(dom, this);
+ }
+ // @ts-expect-error - this is always HTMLListItemElement
+ dom.value = this.__value;
+
+ return false;
+ }
+
+ exportDOM(editor: LexicalEditor): DOMExportOutput {
+ const element = this.createDOM(editor._config);
+ element.style.textAlign = this.getFormatType();
+
+ if (element.classList.contains('task-list-item')) {
+ const input = el('input', {
+ type: 'checkbox',
+ disabled: 'disabled',
+ });
+ if (element.hasAttribute('checked')) {
+ input.setAttribute('checked', 'checked');
+ element.removeAttribute('checked');
+ }
+
+ element.prepend(input);
+ }
+
+ return {
+ element,
+ };
+ }
+
+ exportJSON(): SerializedListItemNode {
+ return {
+ ...super.exportJSON(),
+ type: 'custom-list-item',
+ };
+ }
+}
+
+export function $isCustomListItemNode(
+ node: LexicalNode | null | undefined,
+): node is CustomListItemNode {
+ return node instanceof CustomListItemNode;
+}
\ No newline at end of file