Plate 如何给选中文本添加批注式 Comment 评论?

发布时间:2026/9/15 13:16:44
Plate 如何给选中文本添加批注式 Comment 评论? Plate 如何给选中文本添加批注式 Comment 评论【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate在 Plate 编辑器里批注式评论Comment是把一段选中文本包上文本标记text mark 内联注释实现文字上的悬停批注、多人对同一段文字叠加多条评论、以及先建草稿再定稿的协作流程。这个能力由platejs/comment提供核心是BaseCommentPlugin暴露的tf.comment.setDraft对当前选区打上一个评论标记再通过工具栏按钮或Cmd Shift M快捷键触发。本文基于 Comment 插件文档/(collaboration)/comment.mdx)给出从安装到给选中文本加批注的完整操作路径。前提一个已创建好的 Plate 编辑器两条接入路径都要求你已经用platejs/react的createPlateEditor创建过编辑器并能向它的plugins数组里追加插件import { createPlateEditor } from platejs/react; const editor createPlateEditor({ plugins: [ // ...otherPlugins, ], });路径一用 CommentKit 快速接入最快方式是引入预配置好的CommentKit它包含commentPlugin、CommentLeaf渲染评论文本标记和BlockDiscussion渲染带评论的讨论 UI以及配套 Plate UI 组件。Kit 的源码可以在仓库里直接查看comment-kit.tsx。import { createPlateEditor } from platejs/react; import { CommentKit } from /components/editor/plugins/comment-kit; const editor createPlateEditor({ plugins: [ // ...otherPlugins, ...CommentKit, ], });Kit 路径下不需要自己写插件配置加进plugins后即可使用。路径二手动配置 commentPlugin需要自定义状态、快捷键或渲染组件时走手动路径。1. 安装插件包npm install platejs/comment2. 扩展 BaseCommentPlugin声明评论状态BaseCommentPlugin之外扩展三个 options用来跟踪当前激活的评论和正在评论的块import { type ExtendConfig, type Path, isSlateString } from platejs; import { type BaseCommentConfig, BaseCommentPlugin, getDraftCommentKey, } from platejs/comment; import { toTPlatePlugin } from platejs/react; import { CommentLeaf } from /components/ui/comment-node; type CommentConfig ExtendConfig BaseCommentConfig, { activeId: string | null; commentingBlock: Path | null; hoverId: string | null; } ; export const commentPlugin toTPlatePluginCommentConfig( BaseCommentPlugin, ({ editor }) ({ options: { activeId: null, commentingBlock: null, hoverId: null, }, render: { node: CommentLeaf, }, }) );options.activeId当前激活评论的 ID用于视觉高亮options.commentingBlock正在被评论的块的 Pathoptions.hoverId当前悬停评论的 ID用于 hover 效果render.node指定CommentLeaf渲染评论文本标记组件实现见 comment-node.tsx3.可选添加点击处理跟踪激活评论点击文档中的评论标记时更新activeId点击评论外区域时清空。这一步服务于评论 UI 的激活/悬停视觉反馈export const commentPlugin toTPlatePluginCommentConfig( BaseCommentPlugin, ({ editor }) ({ handlers: { // Set active comment when clicking on comment marks onClick: ({ api, event, setOption, type }) { let leaf event.target as HTMLElement; let isSet false; const unsetActiveComment () { setOption(activeId, null); isSet true; }; if (!isSlateString(leaf)) unsetActiveComment(); while (leaf.parentElement) { if (leaf.classList.contains(slate-${type})) { const commentsEntry api.comment.node(); if (!commentsEntry) { unsetActiveComment(); break; } const id api.comment.nodeId(commentsEntry[0]); setOption(activeId, id ?? null); isSet true; break; } leaf leaf.parentElement; } if (!isSet) unsetActiveComment(); }, }, // ... previous options and render }) );处理逻辑沿 DOM 向上查找带slate-${type}class 的元素找到后用api.comment.node()取出评论节点、api.comment.nodeId()取出评论 ID 并写入activeId未命中则清空activeId。4. 扩展 setDraft绑定快捷键关键一步是扩展tf.comment.setDraft加评论前先选中所在块再打上草稿标记最后记录草稿 key 和评论块路径并绑定modshiftm快捷键export const commentPlugin toTPlatePluginCommentConfig( BaseCommentPlugin, ({ editor }) ({ // ... previous configuration }) ) .extendTransforms( ({ editor, setOption, tf: { comment: { setDraft }, }, }) ({ setDraft: () { if (editor.api.isCollapsed()) { editor.tf.select(editor.api.block()![1]); } setDraft(); editor.tf.collapse(); setOption(activeId, getDraftCommentKey()); setOption(commentingBlock, editor.selection!.focus.path.slice(0, 1)); }, }) ) .configure({ node: { component: CommentLeaf }, shortcuts: { setDraft: { keys: modshiftm }, }, });getDraftCommentKey返回草稿评论专用的 key草稿评论在最终定稿之前用这个 key 标识。5. 加入工具栏按钮并注册插件把 CommentToolbarButton 加到你的 Toolbar 中作为给选中文本加评论的显式入口。然后把插件注册进编辑器import { createPlateEditor } from platejs/react; const editor createPlateEditor({ plugins: [ // ...otherPlugins, commentPlugin, ], });如何给选中文本添加批注接好插件后给选中文本加批注有两种等价入口在编辑器里选中一段文字点击工具栏上的 Comment 按钮选中文字后按Cmd Shift M快捷键由上面的shortcuts.setDraft配置。两种入口都触发setDraft在选区上创建评论文本标记由CommentLeaf渲染为可交互的批注。同一个文本节点可以携带多条评论TCommentText除comment布尔属性外还有按评论 ID 区分的comment_id属性多条批注可叠加在同一段文字上即文档所述 Overlapping Comments。如何核对批注已生效文档给出了可编程的核查方式api.comment.has({ id })返回boolean判断指定 ID 的评论是否存在api.comment.node({ id })/api.comment.nodes()按 ID 或isDraft取回评论节点条目getCommentCount(node)统计评论节点中非草稿评论的数量。例如定稿后可以用api.comment.has({ id: 评论 ID })确认该 ID 的批注已落在文档里用api.comment.node({ isDraft: true })查看草稿是否已清除。管理评论标记用这些 transformtf.comment.removeMark从当前选区或指定位置移除评论标记tf.comment.unsetMark({ id })移除指定 ID 的评论标记传{ id, transient: true }时一次性移除所有 AI 评论默认false工具类getCommentKey(id)/getCommentKeyId(key)/getCommentKeys(node)/isCommentKey(key)用于评论 key 与 ID 的相互换算。可选与 Discussion 插件组合文档说明 comment 插件与 discussion 插件/(collaboration)/discussion.mdx) 组合可获得完整协作能力BlockDiscussion组件block-discussion.tsx负责渲染讨论 UI。需要时把discussionPlugin与commentPlugin一起加入pluginsimport { discussionPlugin } from /components/editor/plugins/discussion-kit; const editor createPlateEditor({ plugins: [ // ...otherPlugins, discussionPlugin, commentPlugin, ], });限制说明批注以文本标记形式落在文本节点上CommentLeaf未配置时评论标记没有对应渲染组件草稿评论使用getDraftCommentKey()返回的固定 key 标识与正式评论 ID 区分开tf.comment.unsetMark的transient选项按文档说明针对 AI 评论的一次性移除普通评论请显式传id。完整的插件配置项、API 参数表以 comment.mdx/(collaboration)/comment.mdx) 为准。【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考