import { DecoratorNode, ElementNode, type LexicalNode, type SerializedElementNode, type SerializedLexicalNode, type Spread } from "lexical"; import { FocusableNode } from "./focusable_node"; import type { ReactNode } from "react"; import { TermIcon } from "~/components/editor/term_icon"; type SerializedTermNode = Spread; export class TermNode extends FocusableNode { __term: string; getTerm() { const self = this.getLatest(); return self.__term; } static getType() { return "term"; } static clone(node: TermNode) { return new TermNode(node.__term, node.__key, node.__hasFocus); } constructor(term: string, key?: string, hasFocus?: boolean) { super(key, hasFocus); this.__term = term; } isInline() { return true; } createDOM() { const element = super.createDOM(); element.classList.add("term"); return element; } updateDOM(old: TermNode, dom: HTMLElement) { return super.updateDOM(old, dom); } exportJSON(): SerializedTermNode { return { ...super.exportJSON(), type: "term", term: this.__term, }; } static importJSON(serializedNode: SerializedTermNode) { return $createTermNode(serializedNode.term); } } export function $createTermNode(term: string) { return new TermNode(term); } export function $isTermNode(node?: LexicalNode | null): node is TermNode { return node instanceof TermNode; } export class TermMarkerNode extends ElementNode { static getType() { return "term-marker"; } static clone(node: TermMarkerNode) { return new TermMarkerNode(node.__key); } isInline() { return true; } createDOM() { const element = document.createElement("span"); element.classList.add("term-marker"); return element; } updateDOM() { return false; } exportJSON() { return { ...super.exportJSON(), type: "term-marker", }; } static importJSON() { return $createTermMarkerNode(); } } export function $createTermMarkerNode() { return new TermMarkerNode(); } export function $isTermMarkerNode(node?: LexicalNode | null): node is TermMarkerNode { return node instanceof TermMarkerNode; } type SerializedTermIconNode = Spread; export class TermIconNode extends DecoratorNode { __term: string; getTerm() { const self = this.getLatest(); return self.__term; } static getType() { return "term-icon"; } static clone(node: TermIconNode) { return new TermIconNode(node.__term, node.__key); } constructor(term: string, key?: string) { super(key); this.__term = term; } createDOM() { return document.createElement("span"); } updateDOM() { return false; } decorate(): ReactNode { return (); } exportJSON(): SerializedTermIconNode { return { ...super.exportJSON(), type: "term-icon", term: this.__term, }; } static importJSON(serializedNode: SerializedTermIconNode) { return $createTermIconNode(serializedNode.term); } } export function $createTermIconNode(term: string) { return new TermIconNode(term); } export function $isTermIconNode(node?: LexicalNode | null): node is TermIconNode { return node instanceof TermIconNode; }