| 1 | "use client"; |
| 2 | |
| 3 | import { |
| 4 | BaseCommentPlugin, |
| 5 | getDraftCommentKey, |
| 6 | type BaseCommentConfig, |
| 7 | } from "@platejs/comment"; |
| 8 | import { isSlateString, type ExtendConfig, type Path } from "platejs"; |
| 9 | import { toTPlatePlugin } from "platejs/react"; |
| 10 | |
| 11 | import { CommentLeaf } from "@/components/plate/ui/comment-node"; |
| 12 | |
| 13 | type CommentConfig = ExtendConfig< |
| 14 | BaseCommentConfig, |
| 15 | { |
| 16 | activeId: string | null; |
| 17 | commentingBlock: Path | null; |
| 18 | hoverId: string | null; |
| 19 | uniquePathMap: Map<string, Path>; |
| 20 | } |
| 21 | >; |
| 22 | |
| 23 | export const commentPlugin = toTPlatePlugin<CommentConfig>(BaseCommentPlugin, { |
| 24 | handlers: { |
| 25 | onClick: ({ api, event, setOption, type }) => { |
| 26 | let leaf = event.target as HTMLElement; |
| 27 | let isSet = false; |
| 28 | |
| 29 | const unsetActiveSuggestion = () => { |
| 30 | setOption("activeId", null); |
| 31 | isSet = true; |
| 32 | }; |
| 33 | |
| 34 | if (!isSlateString(leaf)) unsetActiveSuggestion(); |
| 35 | |
| 36 | while (leaf.parentElement) { |
| 37 | if (leaf.classList.contains(`slate-${type}`)) { |
| 38 | const commentsEntry = api.comment!.node(); |
| 39 | |
| 40 | if (!commentsEntry) { |
| 41 | unsetActiveSuggestion(); |
| 42 | |
| 43 | break; |
| 44 | } |
| 45 | |
| 46 | const id = api.comment!.nodeId(commentsEntry[0]); |
| 47 | |
| 48 | setOption("activeId", id ?? null); |
| 49 | isSet = true; |
| 50 | |
| 51 | break; |
| 52 | } |
| 53 | |
| 54 | leaf = leaf.parentElement; |
| 55 | } |
| 56 | |
| 57 | if (!isSet) unsetActiveSuggestion(); |
| 58 | }, |
| 59 | }, |
| 60 | options: { |
| 61 | activeId: null, |
| 62 | commentingBlock: null, |
| 63 | hoverId: null, |
| 64 | uniquePathMap: new Map(), |
| 65 | }, |
| 66 | }) |
| 67 | .extendTransforms( |
| 68 | ({ |
| 69 | editor, |
| 70 | setOption, |
| 71 | tf: { |
| 72 | comment: { setDraft }, |
| 73 | }, |
| 74 | }) => ({ |
| 75 | setDraft: () => { |
| 76 | if (editor.api.isCollapsed()) { |
| 77 | editor.tf.select(editor.api.block()![1]); |
| 78 | } |
| 79 | |
| 80 | setDraft(); |
| 81 | |
| 82 | editor.tf.collapse(); |
| 83 | setOption("activeId", getDraftCommentKey()); |
| 84 | setOption("commentingBlock", editor.selection!.focus.path.slice(0, 1)); |
| 85 | }, |
| 86 | }), |
| 87 | ) |
| 88 | .configure({ |
| 89 | node: { component: CommentLeaf }, |
| 90 | shortcuts: { |
| 91 | setDraft: { keys: "mod+shift+m" }, |
| 92 | }, |
| 93 | }); |
| 94 | |
| 95 | export const CommentKit = [commentPlugin]; |
| 96 |