自定义变更的显示方式
AI Changes 扩展旨在提供灵活性。作为一个无 UI 库,它让你可以完全控制编辑器中变更的显示方式。
默认样式
默认情况下,AI Changes 扩展会应用 CSS 类以突出显示修改过的内容:
tiptap-ai-changes--old表示删除的文本tiptap-ai-changes--new表示插入的文本
该扩展不包含任何内置样式,因此你需要自行定义 CSS。以下是用于变更高亮的基础样式完整示例:
:root {
--color-green-100: oklch(0.962 0.044 156.743);
--color-green-700: oklch(0.527 0.154 150.069);
--color-red-100: oklch(0.936 0.032 17.717);
--color-red-700: oklch(0.505 0.213 27.518);
}
.tiptap-ai-changes--old,
.tiptap-ai-changes--old > * {
color: var(--color-red-700);
background-color: var(--color-red-100);
}
.tiptap-ai-changes--new,
.tiptap-ai-changes--new > * {
color: var(--color-green-700);
background-color: var(--color-green-100);
}这会给删除文本应用红色背景,给插入文本应用绿色背景。
想要更高级的样式,请使用 getCustomDecorations 配置选项。
选中的变更
当选择光标在某个变更上时,该变更被视为“选中”。
你可以从扩展的存储对象中获取当前选中的变更:
const storage = editor.extensionStorage.aiChanges
const selectedChange = storage.getSelectedChange()要以编程方式选中某个变更,可以使用 selectAiChange 命令。
editor.commands.selectAiChange(changeId)这会将光标移到变更的起始位置,从而使其被视为“选中”。
选中变更的文本可以在 getCustomDecorations 函数中引用,以应用自定义样式。
自定义变更外观
getCustomDecorations 选项允许你控制变更的外观,并向用户提供视觉提示。
它接受以下参数:
change:包含变更信息的变更对象。changes:所有追踪变更的列表。isSelected:布尔值,表示该变更是否被选中。当光标在变更上时,视为选中。getDefaultDecorations:返回该变更默认装饰的函数。如果不提供getCustomDecorations函数,则使用默认装饰。editor:Tiptap 编辑器实例。previousDoc:AI 修改前的文档。通过将当前文档与此文档对比,得出变更。currentDoc:AI 修改后的文档。
AiChanges.configure({
getCustomDecorations({ change, isSelected, getDefaultDecorations }) {
// 你可以将 AI Changes 扩展的默认装饰与自定义装饰结合使用
const decorations = getDefaultDecorations()
// 在变更插入文本之后添加自定义元素
decorations.push(
Decoration.widget(change.newRange.to, () => {
const element = document.createElement('span')
element.textContent = '✅'
return element
}),
)
return decorations
},
})自定义样式和元素通过 Prosemirror Decorations API 实现。
要了解如何在选中变更时显示弹出层,请查看 此指南。
选中变更时显示弹出层
在大多数用户审核流程中,你需要在选中的变更上显示弹出层或工具提示,提供接受或拒绝操作。
要在选中变更时显示弹出层,请使用 getCustomDecorations 选项。它允许你向变更添加自定义元素,包括弹出层。
以下是使用 React 的简化示例:
// 首先,定义一个 Hook 用于保存将渲染弹出层的 HTML 元素
const [popoverElement, setPopoverElement] = useState<HTMLElement | null>(null)
AiChanges.configure({
getCustomDecorations({ change, isSelected, getDefaultDecorations }) {
const decorations = getDefaultDecorations()
// 选中变更时,在插入文本之后创建一个 Prosemirror 装饰,包含 HTML 元素
if (isSelected) {
decorations.push(
Decoration.widget(change.newRange.to, () => {
const element = document.createElement('span')
setPopoverElement(element)
return element
}),
)
}
return decorations
},
})
const selectedChange = editor.extensionStorage.aiChanges.getSelectedChange()
if (popoverElement && selectedChange) {
// 然后,将 HTML 内容添加到自定义元素中。本例中使用 React Portals 渲染弹出层。
ReactDOM.createPortal(<Popover change={selectedChange} />, popoverElement)
}我们推荐使用 Floating UI 库来显示弹出层。你可以在 示例演示 中查看如何实现。
在编辑器外侧边栏显示变更
你可以从扩展的存储对象访问变更数据:
const storage = editor.extensionStorage.aiChanges
const changes = storage.getChanges()然后用这些数据渲染自定义 UI 组件。下面是一个使用 React 的示例:
// 从编辑器状态获取变更
const storage = editor.extensionStorage.aichange
const changes = storage.getchanges()
// 在 UI 中渲染变更
return (
<div>
{changes.map((change) => (
<div key={change.id}>
<button onClick={() => editor.commands.acceptAiChange(change.id)}>接受</button>
<button onClick={() => editor.commands.rejectAiChange(change.id)}>拒绝</button>
</div>
))}
</div>
)隐藏和显示变更
在某些情况下,你可能想继续追踪变更,但在 UI 中隐藏它们。例如,当你正在流式生成 AI 内容时。你可以使用 setShowAiChanges 命令以编程方式隐藏和显示变更。
// 隐藏变更
editor.commands.setShowAiChanges(false)
// 显示变更
editor.commands.setShowAiChanges(true)这仅影响变更的视觉显示 —— 追踪机制仍在后台工作,且所有变更仍可通过扩展的存储方法访问。