This content was inserted as HTML and normalized by Lexical.
\",\n \"Great editors should be easy to paste into and out of.\",\n].join(\"\");\n", "path": "registry/pytah/editor/components/editor/core/constants.ts", "target": "src/components/editor/core/constants.ts", "type": "registry:file" }, { "content": "import { addClassNamesToElement, IS_CHROME } from \"@lexical/utils\";\nimport {\n $getSiblingCaret,\n $isElementNode,\n $rewindSiblingCaret,\n type DOMConversionMap,\n type DOMConversionOutput,\n type DOMExportOutput,\n type EditorConfig,\n ElementNode,\n isHTMLElement,\n type LexicalEditor,\n type LexicalNode,\n type LexicalUpdateJSON,\n type NodeKey,\n type RangeSelection,\n type SerializedElementNode,\n type Spread,\n} from \"lexical\";\nimport { setDomHiddenUntilFound } from \"./dom-utils\";\n\nexport type SerializedCollapsibleContainerNode = Spread<\n {\n open: boolean;\n },\n SerializedElementNode\n>;\n\nconst applyContainerOpenState = (dom: HTMLElement, open: boolean) => {\n dom.dataset.open = open ? \"true\" : \"false\";\n\n const titleDom = dom.firstElementChild;\n if (isHTMLElement(titleDom)) {\n titleDom.dataset.open = open ? \"true\" : \"false\";\n }\n};\n\nconst convertDetailsElement = (domNode: HTMLElement): DOMConversionOutput => {\n const detailsElement = domNode as HTMLDetailsElement;\n return {\n node: $createCollapsibleContainerNode(detailsElement.open ?? true),\n };\n};\n\nconst convertCollapsibleContainerElement = (\n domNode: HTMLElement\n): DOMConversionOutput => {\n return {\n node: $createCollapsibleContainerNode(domNode.dataset.open !== \"false\"),\n };\n};\n\nexport class CollapsibleContainerNode extends ElementNode {\n __open: boolean;\n\n constructor(open: boolean, key?: NodeKey) {\n super(key);\n this.__open = open;\n }\n\n static getType(): string {\n return \"collapsible-container\";\n }\n\n static clone(node: CollapsibleContainerNode): CollapsibleContainerNode {\n return new CollapsibleContainerNode(node.__open, node.__key);\n }\n\n static importDOM(): DOMConversionMap | null {\n return {\n details: () => ({\n conversion: convertDetailsElement,\n priority: 1,\n }),\n div: (domNode: HTMLElement) => {\n if (!domNode.hasAttribute(\"data-lexical-collapsible-container\")) {\n return null;\n }\n\n return {\n conversion: convertCollapsibleContainerElement,\n priority: 2,\n };\n },\n };\n }\n\n static importJSON(\n serializedNode: SerializedCollapsibleContainerNode\n ): CollapsibleContainerNode {\n return $createCollapsibleContainerNode().updateFromJSON(serializedNode);\n }\n\n createDOM(config: EditorConfig, editor: LexicalEditor): HTMLElement {\n let dom: HTMLElement;\n\n if (IS_CHROME) {\n dom = document.createElement(\"div\");\n } else {\n const detailsDom = document.createElement(\"details\");\n detailsDom.addEventListener(\"toggle\", () => {\n const open = editor.getEditorState().read(() => this.getOpen());\n if (detailsDom.open !== open) {\n editor.update(() => {\n this.toggleOpen();\n });\n }\n });\n dom = detailsDom;\n }\n\n dom.setAttribute(\"data-lexical-collapsible-container\", \"true\");\n applyContainerOpenState(dom, this.__open);\n\n if (this.__open) {\n dom.setAttribute(\"open\", \"\");\n }\n\n if (typeof config.theme.collapsibleContainer === \"string\") {\n addClassNamesToElement(dom, config.theme.collapsibleContainer);\n }\n\n return dom;\n }\n\n updateDOM(prevNode: this, dom: HTMLElement): boolean {\n if (prevNode.__open === this.__open) {\n return false;\n }\n\n applyContainerOpenState(dom, this.__open);\n\n if (this.__open) {\n dom.setAttribute(\"open\", \"\");\n } else {\n dom.removeAttribute(\"open\");\n }\n\n if (IS_CHROME) {\n const contentDom = dom.children[1];\n if (!isHTMLElement(contentDom)) {\n throw new Error(\"Expected collapsible content DOM element\");\n }\n\n if (this.__open) {\n contentDom.hidden = false;\n } else {\n setDomHiddenUntilFound(contentDom);\n }\n } else if (dom instanceof HTMLDetailsElement) {\n dom.open = this.__open;\n }\n\n return false;\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"details\");\n element.setAttribute(\"data-lexical-collapsible-container\", \"true\");\n element.dataset.open = this.__open ? \"true\" : \"false\";\n\n if (this.__open) {\n element.setAttribute(\"open\", \"\");\n }\n\n return { element };\n }\n\n exportJSON(): SerializedCollapsibleContainerNode {\n return {\n ...super.exportJSON(),\n open: this.__open,\n type: \"collapsible-container\",\n version: 1,\n };\n }\n\n updateFromJSON(\n serializedNode: LexicalUpdateJSON
\n Add headings to see the outline.\n
\n );\n }\n\n return (\n \n );\n}\n\nfunction EditorTableOfContentsInner({\n className,\n editor,\n entries,\n}: {\n className?: string;\n editor: LexicalEditor;\n entries: readonly TableOfContentsEntry[];\n}) {\n const activeKey = useActiveHeading(entries, editor);\n\n return (\n