feat: Persist collapsible block state in Super notes (#2119)

This commit is contained in:
Aman Harwara
2022-12-24 20:35:41 +05:30
committed by GitHub
parent b8da877804
commit 577318e208
4 changed files with 48 additions and 26 deletions

View File

@@ -20,6 +20,7 @@ type SerializedCollapsibleContainerNode = Spread<
{
type: 'collapsible-container';
version: 1;
open: boolean;
},
SerializedElementNode
>;
@@ -29,25 +30,27 @@ export class CollapsibleContainerNode extends ElementNode {
constructor(open: boolean, key?: NodeKey) {
super(key);
this.__open = open;
this.__open = open ?? false;
}
static getType(): string {
static override getType(): string {
return 'collapsible-container';
}
static clone(node: CollapsibleContainerNode): CollapsibleContainerNode {
static override clone(
node: CollapsibleContainerNode,
): CollapsibleContainerNode {
return new CollapsibleContainerNode(node.__open, node.__key);
}
createDOM(config: EditorConfig): HTMLElement {
override createDOM(config: EditorConfig): HTMLElement {
const dom = document.createElement('details');
dom.classList.add('Collapsible__container');
dom.open = this.__open;
return dom;
}
updateDOM(
override updateDOM(
prevNode: CollapsibleContainerNode,
dom: HTMLDetailsElement,
): boolean {
@@ -62,18 +65,19 @@ export class CollapsibleContainerNode extends ElementNode {
return {};
}
static importJSON(
static override importJSON(
serializedNode: SerializedCollapsibleContainerNode,
): CollapsibleContainerNode {
const node = $createCollapsibleContainerNode();
const node = $createCollapsibleContainerNode(serializedNode.open);
return node;
}
exportJSON(): SerializedCollapsibleContainerNode {
override exportJSON(): SerializedCollapsibleContainerNode {
return {
...super.exportJSON(),
type: 'collapsible-container',
version: 1,
open: this.__open,
};
}
@@ -91,8 +95,10 @@ export class CollapsibleContainerNode extends ElementNode {
}
}
export function $createCollapsibleContainerNode(): CollapsibleContainerNode {
return new CollapsibleContainerNode(true);
export function $createCollapsibleContainerNode(
open: boolean,
): CollapsibleContainerNode {
return new CollapsibleContainerNode(open);
}
export function $isCollapsibleContainerNode(

View File

@@ -24,21 +24,24 @@ type SerializedCollapsibleContentNode = Spread<
>;
export class CollapsibleContentNode extends ElementNode {
static getType(): string {
static override getType(): string {
return 'collapsible-content';
}
static clone(node: CollapsibleContentNode): CollapsibleContentNode {
static override clone(node: CollapsibleContentNode): CollapsibleContentNode {
return new CollapsibleContentNode(node.__key);
}
createDOM(config: EditorConfig): HTMLElement {
override createDOM(config: EditorConfig): HTMLElement {
const dom = document.createElement('div');
dom.classList.add('Collapsible__content');
return dom;
}
updateDOM(prevNode: CollapsibleContentNode, dom: HTMLElement): boolean {
override updateDOM(
prevNode: CollapsibleContentNode,
dom: HTMLElement,
): boolean {
return false;
}
@@ -46,17 +49,17 @@ export class CollapsibleContentNode extends ElementNode {
return {};
}
static importJSON(
static override importJSON(
serializedNode: SerializedCollapsibleContentNode,
): CollapsibleContentNode {
return $createCollapsibleContentNode();
}
isShadowRoot(): boolean {
override isShadowRoot(): boolean {
return true;
}
exportJSON(): SerializedCollapsibleContentNode {
override exportJSON(): SerializedCollapsibleContentNode {
return {
...super.exportJSON(),
type: 'collapsible-content',

View File

@@ -31,21 +31,34 @@ type SerializedCollapsibleTitleNode = Spread<
>;
export class CollapsibleTitleNode extends ElementNode {
static getType(): string {
static override getType(): string {
return 'collapsible-title';
}
static clone(node: CollapsibleTitleNode): CollapsibleTitleNode {
static override clone(node: CollapsibleTitleNode): CollapsibleTitleNode {
return new CollapsibleTitleNode(node.__key);
}
createDOM(config: EditorConfig, editor: LexicalEditor): HTMLElement {
override createDOM(config: EditorConfig, editor: LexicalEditor): HTMLElement {
const dom = document.createElement('summary');
dom.classList.add('Collapsible__title');
dom.onclick = (event) => {
event.preventDefault();
event.stopPropagation();
editor.update(() => {
const containerNode = this.getParentOrThrow();
if ($isCollapsibleContainerNode(containerNode)) {
containerNode.toggleOpen();
}
});
};
return dom;
}
updateDOM(prevNode: CollapsibleTitleNode, dom: HTMLElement): boolean {
override updateDOM(
prevNode: CollapsibleTitleNode,
dom: HTMLElement,
): boolean {
return false;
}
@@ -53,13 +66,13 @@ export class CollapsibleTitleNode extends ElementNode {
return {};
}
static importJSON(
static override importJSON(
serializedNode: SerializedCollapsibleTitleNode,
): CollapsibleTitleNode {
return $createCollapsibleTitleNode();
}
exportJSON(): SerializedCollapsibleTitleNode {
override exportJSON(): SerializedCollapsibleTitleNode {
return {
...super.exportJSON(),
type: 'collapsible-title',
@@ -67,12 +80,12 @@ export class CollapsibleTitleNode extends ElementNode {
};
}
collapseAtStart(_selection: RangeSelection): boolean {
override collapseAtStart(_selection: RangeSelection): boolean {
this.getParentOrThrow().insertBefore(this);
return true;
}
insertNewAfter(): ElementNode {
override insertNewAfter(): ElementNode {
const containerNode = this.getParentOrThrow();
if (!$isCollapsibleContainerNode(containerNode)) {

View File

@@ -204,7 +204,7 @@ export default function CollapsiblePlugin(): JSX.Element | null {
const content = $createCollapsibleContentNode().append(
$createParagraphNode(),
);
const container = $createCollapsibleContainerNode().append(
const container = $createCollapsibleContainerNode(true).append(
title,
content,
);