File
Blob: src/shared/editor/schema/page-mention.ts
| 1 | import { mergeAttributes, Node } from "@tiptap/core"; |
| 2 | import type { Range } from "@tiptap/core"; |
| 3 | |
| 4 | declare module "@tiptap/core" { |
| 5 | interface Commands<ReturnType> { |
| 6 | pageMention: { |
| 7 | insertPageMention: (attrs: { pageId: string; range?: Range }) => ReturnType; |
| 8 | }; |
| 9 | } |
| 10 | } |
| 11 | |
| 12 | export const SharedPageMentionNode = Node.create({ |
| 13 | name: "pageMention", |
| 14 | inline: true, |
| 15 | group: "inline", |
| 16 | atom: true, |
| 17 | selectable: true, |
| 18 | draggable: false, |
| 19 | |
| 20 | addAttributes() { |
| 21 | return { |
| 22 | pageId: { |
| 23 | default: null as string | null, |
| 24 | parseHTML: (element) => element.getAttribute("data-page-id"), |
| 25 | renderHTML: (attrs) => { |
| 26 | if (!attrs.pageId) return {}; |
| 27 | return { "data-page-id": attrs.pageId }; |
| 28 | }, |
| 29 | }, |
| 30 | }; |
| 31 | }, |
| 32 | |
| 33 | parseHTML() { |
| 34 | return [{ tag: "span[data-page-mention][data-page-id]" }]; |
| 35 | }, |
| 36 | |
| 37 | renderHTML({ HTMLAttributes }) { |
| 38 | return ["span", mergeAttributes(HTMLAttributes, { "data-page-mention": "" }), ""]; |
| 39 | }, |
| 40 | |
| 41 | addCommands() { |
| 42 | return { |
| 43 | insertPageMention: |
| 44 | ({ pageId, range }) => |
| 45 | ({ chain, editor }) => { |
| 46 | if (!editor.isEditable || !pageId) return false; |
| 47 | const c = chain().focus(null, { scrollIntoView: false }); |
| 48 | if (range) c.deleteRange(range); |
| 49 | return c |
| 50 | .insertContent([ |
| 51 | { type: "pageMention", attrs: { pageId } }, |
| 52 | { type: "text", text: " " }, |
| 53 | ]) |
| 54 | .run(); |
| 55 | }, |
| 56 | }; |
| 57 | }, |
| 58 | }); |