chore: update collapsible node

This commit is contained in:
Aman Harwara
2023-04-01 14:53:22 +05:30
parent fbb0dc0cea
commit f884e2cd66
4 changed files with 96 additions and 23 deletions

View File

@@ -32,7 +32,7 @@
border-style: solid; border-style: solid;
border-color: transparent; border-color: transparent;
border-width: 4px 6px 4px 6px; border-width: 4px 6px 4px 6px;
border-left-color: #000; border-left-color: var(--sn-stylekit-contrast-color);
display: block; display: block;
content: ''; content: '';
position: absolute; position: absolute;

View File

@@ -8,8 +8,11 @@
import { import {
DOMConversionMap, DOMConversionMap,
DOMConversionOutput,
DOMExportOutput,
EditorConfig, EditorConfig,
ElementNode, ElementNode,
LexicalEditor,
LexicalNode, LexicalNode,
NodeKey, NodeKey,
SerializedElementNode, SerializedElementNode,
@@ -25,6 +28,14 @@ type SerializedCollapsibleContainerNode = Spread<
SerializedElementNode SerializedElementNode
> >
export function convertDetailsElement(domNode: HTMLDetailsElement): DOMConversionOutput | null {
const isOpen = domNode.open !== undefined ? domNode.open : true
const node = $createCollapsibleContainerNode(isOpen)
return {
node,
}
}
export class CollapsibleContainerNode extends ElementNode { export class CollapsibleContainerNode extends ElementNode {
__open: boolean __open: boolean
@@ -41,10 +52,16 @@ export class CollapsibleContainerNode extends ElementNode {
return new CollapsibleContainerNode(node.__open, node.__key) return new CollapsibleContainerNode(node.__open, node.__key)
} }
override createDOM(_: EditorConfig): HTMLElement { override createDOM(_: EditorConfig, editor: LexicalEditor): HTMLElement {
const dom = document.createElement('details') const dom = document.createElement('details')
dom.classList.add('Collapsible__container') dom.classList.add('Collapsible__container')
dom.open = this.__open dom.open = this.__open
dom.addEventListener('toggle', () => {
const open = editor.getEditorState().read(() => this.getOpen())
if (open !== dom.open) {
editor.update(() => this.toggleOpen())
}
})
return dom return dom
} }
@@ -56,8 +73,15 @@ export class CollapsibleContainerNode extends ElementNode {
return false return false
} }
static importDOM(): DOMConversionMap | null { static importDOM(): DOMConversionMap<HTMLDetailsElement> | null {
return {} return {
details: () => {
return {
conversion: convertDetailsElement,
priority: 1,
}
},
}
} }
static override importJSON(serializedNode: SerializedCollapsibleContainerNode): CollapsibleContainerNode { static override importJSON(serializedNode: SerializedCollapsibleContainerNode): CollapsibleContainerNode {
@@ -65,6 +89,14 @@ export class CollapsibleContainerNode extends ElementNode {
return node return node
} }
exportDOM(): DOMExportOutput {
const element = document.createElement('details')
if (this.getLatest().__open) {
element.setAttribute('open', '')
}
return { element }
}
override exportJSON(): SerializedCollapsibleContainerNode { override exportJSON(): SerializedCollapsibleContainerNode {
return { return {
...super.exportJSON(), ...super.exportJSON(),
@@ -80,7 +112,7 @@ export class CollapsibleContainerNode extends ElementNode {
} }
getOpen(): boolean { getOpen(): boolean {
return this.__open return this.getLatest().__open
} }
toggleOpen(): void { toggleOpen(): void {

View File

@@ -6,7 +6,16 @@
* *
*/ */
import { DOMConversionMap, EditorConfig, ElementNode, LexicalNode, SerializedElementNode, Spread } from 'lexical' import {
DOMConversionMap,
DOMConversionOutput,
DOMExportOutput,
EditorConfig,
ElementNode,
LexicalNode,
SerializedElementNode,
Spread,
} from 'lexical'
type SerializedCollapsibleContentNode = Spread< type SerializedCollapsibleContentNode = Spread<
{ {
@@ -16,6 +25,13 @@ type SerializedCollapsibleContentNode = Spread<
SerializedElementNode SerializedElementNode
> >
export function convertCollapsibleContentElement(): DOMConversionOutput | null {
const node = $createCollapsibleContentNode()
return {
node,
}
}
export class CollapsibleContentNode extends ElementNode { export class CollapsibleContentNode extends ElementNode {
static override getType(): string { static override getType(): string {
return 'collapsible-content' return 'collapsible-content'
@@ -36,7 +52,17 @@ export class CollapsibleContentNode extends ElementNode {
} }
static importDOM(): DOMConversionMap | null { static importDOM(): DOMConversionMap | null {
return {} return {
div: (domNode: HTMLElement) => {
if (!domNode.hasAttribute('data-lexical-collapsible-content')) {
return null
}
return {
conversion: convertCollapsibleContentElement,
priority: 2,
}
},
}
} }
static override importJSON(_serializedNode: SerializedCollapsibleContentNode): CollapsibleContentNode { static override importJSON(_serializedNode: SerializedCollapsibleContentNode): CollapsibleContentNode {
@@ -47,6 +73,12 @@ export class CollapsibleContentNode extends ElementNode {
return true return true
} }
exportDOM(): DOMExportOutput {
const element = document.createElement('div')
element.setAttribute('data-lexical-collapsible-content', 'true')
return { element }
}
override exportJSON(): SerializedCollapsibleContentNode { override exportJSON(): SerializedCollapsibleContentNode {
return { return {
...super.exportJSON(), ...super.exportJSON(),

View File

@@ -10,10 +10,10 @@ import {
$createParagraphNode, $createParagraphNode,
$isElementNode, $isElementNode,
DOMConversionMap, DOMConversionMap,
EditorConfig, DOMConversionOutput,
DOMExportOutput,
ElementFormatType, ElementFormatType,
ElementNode, ElementNode,
LexicalEditor,
LexicalNode, LexicalNode,
NodeKey, NodeKey,
RangeSelection, RangeSelection,
@@ -32,6 +32,13 @@ type SerializedCollapsibleTitleNode = Spread<
SerializedElementNode SerializedElementNode
> >
export function convertSummaryElement(): DOMConversionOutput | null {
const node = $createCollapsibleTitleNode()
return {
node,
}
}
export class CollapsibleTitleNode extends ElementNode { export class CollapsibleTitleNode extends ElementNode {
static override getType(): string { static override getType(): string {
return 'collapsible-title' return 'collapsible-title'
@@ -48,21 +55,11 @@ export class CollapsibleTitleNode extends ElementNode {
return new CollapsibleTitleNode({ key: node.__key }) return new CollapsibleTitleNode({ key: node.__key })
} }
override createDOM(_config: EditorConfig, editor: LexicalEditor): HTMLElement { override createDOM(): HTMLElement {
const dom = document.createElement('summary') const dom = document.createElement('summary')
dom.classList.add('Collapsible__title') dom.classList.add('Collapsible__title')
const format = this.getFormatType() const format = this.getFormatType()
dom.style.textAlign = format dom.style.textAlign = format
dom.onclick = (event) => {
event.preventDefault()
event.stopPropagation()
editor.update(() => {
const containerNode = this.getParentOrThrow()
if ($isCollapsibleContainerNode(containerNode)) {
containerNode.toggleOpen()
}
})
}
return dom return dom
} }
@@ -71,13 +68,25 @@ export class CollapsibleTitleNode extends ElementNode {
} }
static importDOM(): DOMConversionMap | null { static importDOM(): DOMConversionMap | null {
return {} return {
summary: () => {
return {
conversion: convertSummaryElement,
priority: 1,
}
},
}
} }
static override importJSON(serializedNode: SerializedCollapsibleTitleNode): CollapsibleTitleNode { static override importJSON(serializedNode: SerializedCollapsibleTitleNode): CollapsibleTitleNode {
return $createCollapsibleTitleNode(serializedNode.format) return $createCollapsibleTitleNode(serializedNode.format)
} }
exportDOM(): DOMExportOutput {
const element = document.createElement('summary')
return { element }
}
override exportJSON(): SerializedCollapsibleTitleNode { override exportJSON(): SerializedCollapsibleTitleNode {
return { return {
...super.exportJSON(), ...super.exportJSON(),
@@ -91,7 +100,7 @@ export class CollapsibleTitleNode extends ElementNode {
return true return true
} }
override insertNewAfter(): ElementNode { override insertNewAfter(_: RangeSelection, restoreSelection = true): ElementNode {
const containerNode = this.getParentOrThrow() const containerNode = this.getParentOrThrow()
if (!$isCollapsibleContainerNode(containerNode)) { if (!$isCollapsibleContainerNode(containerNode)) {
@@ -114,7 +123,7 @@ export class CollapsibleTitleNode extends ElementNode {
} }
} else { } else {
const paragraph = $createParagraphNode() const paragraph = $createParagraphNode()
containerNode.insertAfter(paragraph) containerNode.insertAfter(paragraph, restoreSelection)
return paragraph return paragraph
} }
} }