FrontEnd.ro logo
Lexical / part 2

import {
  DecoratorBlockNode,
  SerializedDecoratorBlockNode,
} from '@lexical/react/LexicalDecoratorBlockNode';
import {
  Spread,
  NodeKey,
  EditorConfig,
  LexicalEditor,
  ElementFormatType,
} from "lexical";
import { TodoList } from "./TodoList";

export type SerializedTodoNode = Spread<{
  todos: string[];
  type: 'todo';
  version: 1;
}, SerializedDecoratorBlockNode>;

export class TodoNode extends DecoratorBlockNode {
  __todos: string[];

  static getType = () => 'todo';

  static clone = (node: TodoNode) => new TodoNode(
    node.__todos,
    node.__format,
    node.__key
  );

  constructor(todos: string[], format?: ElementFormatType, key?: NodeKey) {
    super(format, key);
    this.__todos = todos;
  }

  createDOM(): HTMLElement {
    return document.createElement('div');
  }

  updateDOM(): false {
    return false;
  }

  decorate(_editor: LexicalEditor, config: EditorConfig): JSX.Element {
    return (
      <TodoList todos={this.__todos} />
    )
  }

  static importJSON({ todos, format }: SerializedTodoNode): TodoNode {
    const node = createTodoNode(todos);
    node.setFormat(format);
    return node;
  }

  exportJSON() {
    return {
      ...super.exportJSON(),
      version: 1,
      todos: this.__todos,
      type: 'todo',
    };
  }
}

export const createTodoNode = (todos: string[]) => new TodoNode(todos);