3 DOMConversionMap, EditorConfig,
7 import {$isListItemNode, ListItemNode, ListNode, ListType, SerializedListNode} from "@lexical/list";
8 import {$createCustomListItemNode} from "./custom-list-item";
9 import {extractDirectionFromElement} from "./_common";
12 export type SerializedCustomListNode = Spread<{
14 }, SerializedListNode>
16 export class CustomListNode extends ListNode {
24 const self = this.getWritable();
29 const self = this.getLatest();
33 static clone(node: CustomListNode) {
34 const newNode = new CustomListNode(node.__listType, node.__start, node.__key);
35 newNode.__id = node.__id;
36 newNode.__dir = node.__dir;
40 createDOM(config: EditorConfig): HTMLElement {
41 const dom = super.createDOM(config);
43 dom.setAttribute('id', this.__id);
47 dom.setAttribute('dir', this.__dir);
53 updateDOM(prevNode: ListNode, dom: HTMLElement, config: EditorConfig): boolean {
54 return super.updateDOM(prevNode, dom, config) ||
55 prevNode.__dir !== this.__dir;
58 exportJSON(): SerializedCustomListNode {
60 ...super.exportJSON(),
67 static importJSON(serializedNode: SerializedCustomListNode): CustomListNode {
68 const node = $createCustomListNode(serializedNode.listType);
69 node.setId(serializedNode.id);
70 node.setDirection(serializedNode.direction);
74 static importDOM(): DOMConversionMap | null {
76 const converter = super.importDOM().ol().conversion as DOMConversionFn<HTMLElement>;
77 const customConvertFunction = (element: HTMLElement) => {
78 const baseResult = converter(element);
79 if (element.id && baseResult?.node) {
80 (baseResult.node as CustomListNode).setId(element.id);
83 if (element.dir && baseResult?.node) {
84 (baseResult.node as CustomListNode).setDirection(extractDirectionFromElement(element));
88 baseResult.after = $normalizeChildren;
96 conversion: customConvertFunction,
100 conversion: customConvertFunction,
108 * This function is a custom normalization function to allow nested lists within list item elements.
109 * Original taken from https://github.com/facebook/lexical/blob/6e10210fd1e113ccfafdc999b1d896733c5c5bea/packages/lexical-list/src/LexicalListNode.ts#L284-L303
110 * With modifications made.
111 * Copyright (c) Meta Platforms, Inc. and affiliates.
114 function $normalizeChildren(nodes: Array<LexicalNode>): Array<ListItemNode> {
115 const normalizedListItems: Array<ListItemNode> = [];
117 for (const node of nodes) {
118 if ($isListItemNode(node)) {
119 normalizedListItems.push(node);
121 normalizedListItems.push($wrapInListItem(node));
125 return normalizedListItems;
128 function $wrapInListItem(node: LexicalNode): ListItemNode {
129 const listItemWrapper = $createCustomListItemNode();
130 return listItemWrapper.append(node);
133 export function $createCustomListNode(type: ListType): CustomListNode {
134 return new CustomListNode(type, 1);
137 export function $isCustomListNode(node: LexicalNode | null | undefined): node is CustomListNode {
138 return node instanceof CustomListNode;