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