LexicalEditor,
LexicalNode,
SerializedElementNode, Spread,
- EditorConfig,
+ EditorConfig, DOMExportOutput,
} from 'lexical';
-import {el} from "../../utils/dom";
import {extractDirectionFromElement} from "lexical/nodes/common";
export type SerializedDetailsNode = Spread<{
id: string;
+ summary: string;
}, SerializedElementNode>
export class DetailsNode extends ElementNode {
__id: string = '';
+ __summary: string = '';
static getType() {
return 'details';
return self.__id;
}
+ setSummary(summary: string) {
+ const self = this.getWritable();
+ self.__summary = summary;
+ }
+
+ getSummary(): string {
+ const self = this.getLatest();
+ return self.__summary;
+ }
+
static clone(node: DetailsNode): DetailsNode {
const newNode = new DetailsNode(node.__key);
newNode.__id = node.__id;
newNode.__dir = node.__dir;
+ newNode.__summary = node.__summary;
return newNode;
}
el.setAttribute('dir', this.__dir);
}
+ const summary = document.createElement('summary');
+ summary.textContent = this.__summary;
+ summary.setAttribute('contenteditable', 'false');
+ el.append(summary);
+
return el;
}
node.setDirection(extractDirectionFromElement(element));
}
+ const summaryElem = Array.from(element.children).find(e => e.nodeName === 'SUMMARY');
+ node.setSummary(summaryElem?.textContent || '');
+
return {node};
},
priority: 3,
};
},
+ summary(node: HTMLElement): DOMConversion|null {
+ return {
+ conversion: (element: HTMLElement): DOMConversionOutput|null => {
+ return {node: 'ignore'};
+ },
+ priority: 3,
+ };
+ },
};
}
+ exportDOM(editor: LexicalEditor): DOMExportOutput {
+ const element = this.createDOM(editor._config, editor);
+ const editable = element.querySelectorAll('[contenteditable]');
+ for (const elem of editable) {
+ elem.removeAttribute('contenteditable');
+ }
+
+ return {element};
+ }
+
exportJSON(): SerializedDetailsNode {
return {
...super.exportJSON(),
type: 'details',
version: 1,
id: this.__id,
+ summary: this.__summary,
};
}
export function $isDetailsNode(node: LexicalNode | null | undefined): node is DetailsNode {
return node instanceof DetailsNode;
}
-
-export class SummaryNode extends ElementNode {
-
- static getType() {
- return 'summary';
- }
-
- static clone(node: SummaryNode) {
- return new SummaryNode(node.__key);
- }
-
- createDOM(_config: EditorConfig, _editor: LexicalEditor) {
- return el('summary');
- }
-
- updateDOM(prevNode: DetailsNode, dom: HTMLElement) {
- return false;
- }
-
- static importDOM(): DOMConversionMap|null {
- return {
- summary(node: HTMLElement): DOMConversion|null {
- return {
- conversion: (element: HTMLElement): DOMConversionOutput|null => {
- return {
- node: new SummaryNode(),
- };
- },
- priority: 3,
- };
- },
- };
- }
-
- exportJSON(): SerializedElementNode {
- return {
- ...super.exportJSON(),
- type: 'summary',
- version: 1,
- };
- }
-
- static importJSON(serializedNode: SerializedElementNode): SummaryNode {
- return $createSummaryNode();
- }
-
-}
-
-export function $createSummaryNode(): SummaryNode {
- return new SummaryNode();
-}
-
-export function $isSummaryNode(node: LexicalNode | null | undefined): node is SummaryNode {
- return node instanceof SummaryNode;
-}
} from "lexical";
import {LinkNode} from "@lexical/link";
import {ImageNode} from "@lexical/rich-text/LexicalImageNode";
-import {DetailsNode, SummaryNode} from "@lexical/rich-text/LexicalDetailsNode";
+import {DetailsNode} from "@lexical/rich-text/LexicalDetailsNode";
import {ListItemNode, ListNode} from "@lexical/list";
import {TableCellNode, TableNode, TableRowNode} from "@lexical/table";
import {HorizontalRuleNode} from "@lexical/rich-text/LexicalHorizontalRuleNode";
TableCellNode,
ImageNode, // TODO - Alignment
HorizontalRuleNode,
- DetailsNode, SummaryNode,
+ DetailsNode,
CodeBlockNode,
DiagramNode,
MediaNode, // TODO - Alignment