1
9
10import { mergeAttributes, Node } from "@tiptap/core";
11
12export interface InlineAtomOptions {
13 readonly HTMLAttributes: Record<string, unknown>;
14}
15
16declare module "@tiptap/core" {
17 interface Config {
18 options: InlineAtomOptions;
19 }
20}
21
22export const InlineAtomNode = Node.create<InlineAtomOptions>({
23 name: "factoryInlineAtom",
24 group: "inline",
25 inline: true,
26 atom: true,
27 selectable: true,
28
29 addOptions() {
30 return { HTMLAttributes: { class: "factory-atom" } };
31 },
32
33 addAttributes() {
34 return {
35 kind: {
36 default: "label",
37 parseHTML: (el) => el.getAttribute("data-atom-kind") ?? "label",
38 renderHTML: (attrs) => ({ "data-atom-kind": attrs.kind }),
39 },
40 value: {
41 default: "",
42 parseHTML: (el) => el.getAttribute("data-atom-value") ?? "",
43 renderHTML: (attrs) => ({ "data-atom-value": attrs.value }),
44 },
45 };
46 },
47
48 parseHTML() {
49 return [{ tag: "span.factory-atom" }];
50 },
51
52 renderHTML({ node, HTMLAttributes }) {
53 const kind = (node.attrs.kind as string) ?? "label";
54 const value = (node.attrs.value as string) ?? "";
55 return [
56 "span",
57 mergeAttributes(
58 { class: `factory-atom factory-atom-${kind}` },
59 this.options.HTMLAttributes,
60 HTMLAttributes
61 ),
62 value
63 ];
64 },
65});
66