使用 AI 工具包的样式建议
When the AI makes changes to the document, you can display them as suggestions in the editor. In this guide, you'll learn how to customize the suggestions' appearance by modifying their styles and displaying custom elements like menus inside them.
为建议添加 CSS 样式
当使用默认的 renderDecorations 函数时,会应用以下类名:
.tiptap-ai-suggestion:应用于被建议范围覆盖的内容。.tiptap-ai-suggestion--selected:当光标位于建议范围内时应用。.tiptap-ai-suggestion--change-group:当建议是多个更改组成的组而非单个更改时应用。.tiptap-ai-suggestion-sub-change:应用于更改组中的单个子更改。.tiptap-ai-suggestion-diff:应用于显示在建议范围旁边的差异部件。.tiptap-ai-suggestion-diff--selected:当光标位于建议范围内,应用于差异部件。.tiptap-ai-suggestion-diff--change-group:当差异部件是多个更改组成的组而非单个更改时应用。.tiptap-ai-suggestion-diff-sub-change:应用于差异更改组中的单个子更改。
您可以使用上述类来样式化建议,或提供自定义的 renderDecorations 函数以完全控制 UI。
CSS 样式示例
我们提供示例 CSS 样式供您快速上手。
预览模式
Use these styles in Preview mode, to preview changes before they are inserted into the document.
/* 将删除文字高亮为红色 */
.tiptap-ai-suggestion,
.tiptap-ai-suggestion > * {
background-color: oklch(80.8% 0.114 19.571);
color: oklch(0.396 0.141 25.723);
}
/* 更改组的背景色较浅(子更改变为较强高亮) */
.tiptap-ai-suggestion.tiptap-ai-suggestion--change-group,
.tiptap-ai-suggestion.tiptap-ai-suggestion--change-group > *:not(.tiptap-ai-suggestion-sub-change) {
background-color: oklch(0.936 0.032 17.717);
}
/* 行内更改组内的子更改高亮 */
.tiptap-ai-suggestion-sub-change {
background-color: oklch(80.8% 0.114 19.571);
}
/* 将插入文字高亮为绿色 */
.tiptap-ai-suggestion-diff,
.tiptap-ai-suggestion-diff > * {
background-color: oklch(87.1% 0.15 154.449);
}
/* 差异更改组的背景色较浅(子更改变为较强高亮) */
.tiptap-ai-suggestion-diff.tiptap-ai-suggestion-diff--change-group,
.tiptap-ai-suggestion-diff.tiptap-ai-suggestion-diff--change-group
> *:not(.tiptap-ai-suggestion-diff-sub-change) {
background-color: oklch(0.962 0.044 156.743);
}
/* 替换差异部件内的子更改高亮 */
.tiptap-ai-suggestion-diff-sub-change {
background-color: oklch(87.1% 0.15 154.449);
}
/* 正确渲染表格行插入 */
.tiptap-ai-suggestion-diff:has(tr) {
display: contents;
}
.tiptap-ai-suggestion-diff:has(tr) td,
.tiptap-ai-suggestion-diff:has(tr) th {
background-color: oklch(87.1% 0.15 154.449);
}审阅模式 / 文档比较
Use these styles in Review mode, to review changes after inserting them in the document.
显示由文档比较功能生成的建议时也使用这些样式。
/* 将插入文字高亮为绿色 */
.tiptap-ai-suggestion,
.tiptap-ai-suggestion > * {
background-color: oklch(87.1% 0.15 154.449);
}
/* 更改组的背景色较浅(子更改变为较强高亮) */
.tiptap-ai-suggestion.tiptap-ai-suggestion--change-group,
.tiptap-ai-suggestion.tiptap-ai-suggestion--change-group > *:not(.tiptap-ai-suggestion-sub-change) {
background-color: oklch(0.962 0.044 156.743);
}
/* 行内更改组内的子更改高亮 */
.tiptap-ai-suggestion-sub-change {
background-color: oklch(87.1% 0.15 154.449);
}
/* 将删除文字高亮为红色 */
.tiptap-ai-suggestion-diff,
.tiptap-ai-suggestion-diff > * {
background-color: oklch(80.8% 0.114 19.571);
color: oklch(0.396 0.141 25.723);
}
/* 差异更改组的背景色较浅(子更改变为较强高亮) */
.tiptap-ai-suggestion-diff.tiptap-ai-suggestion-diff--change-group,
.tiptap-ai-suggestion-diff.tiptap-ai-suggestion-diff--change-group
> *:not(.tiptap-ai-suggestion-diff-sub-change) {
background-color: oklch(0.936 0.032 17.717);
}
/* 替换差异部件内的子更改高亮 */
.tiptap-ai-suggestion-diff-sub-change {
background-color: oklch(80.8% 0.114 19.571);
}
/* 正确渲染表格行删除 */
.tiptap-ai-suggestion-diff:has(tr) {
display: contents;
}
.tiptap-ai-suggestion-diff:has(tr) td,
.tiptap-ai-suggestion-diff:has(tr) th {
background-color: oklch(80.8% 0.114 19.571);
}在建议内渲染 React 组件
您可以使用 renderDecorations 选项,结合React 门户,在建议内显示 React 组件。
首先,定义一个 React 组件并用 hook 存储 React 门户的挂载 HTML 元素。
import { useState } from 'react'
function MyComponent() {
const [portalElement, setPortalElement] = useState<HTMLElement | null>(null)
return null
}然后,在 displayOptions.renderDecorations 选项里,创建一个带有 HTML 元素的小部件装饰,用作 React 门户的入口点。
const aiToolkit = getAiToolkit(editor)
// AI 工具包中生成建议的示例方法
aiToolkit.executeTool({
reviewOptions: {
mode: 'preview',
displayOptions: {
renderDecorations({ suggestion, defaultRenderDecorations }) {
const decorations = defaultRenderDecorations()
decorations.push(
Decoration.widget(suggestion.range.to, () => {
const element = document.createElement('span')
setPortalElement(element)
return element
}),
)
return decorations
},
},
},
})最后,在 React 组件内,将任意 React 元素渲染到该门户内。
import { useState } from 'react'
import { createPortal } from 'react-dom'
function MyComponent() {
const [portalElement, setPortalElement] = useState<HTMLElement | null>(null)
if (portalElement) {
return <>{createPortal(<div>Hello, world!</div>, portalElement)}</>
}
return null
}选中建议时显示弹出框或提示框
您可以使用上述技术,在选中建议时显示提示框。
若要在选中建议时显示弹出框,需要使用 getCustomSuggestionDecoration 选项。此函数允许您向建议中添加自定义元素,包括弹出框。
下面是使用 React UI 库实现的简化示例。
import { useState } from 'react'
import { createPortal } from 'react-dom'
// 在 React 组件内部
function MyComponent() {
const toolkit = getAiToolkit(editor)
// 首先,定义 hook 存储弹出框挂载的 HTML 元素
const [popoverElement, setPopoverElement] = useState<HTMLElement | null>(null)
// 工具执行时,配置装饰的渲染方式
aiToolkit.executeTool({
reviewOptions: {
mode: 'preview',
displayOptions: {
renderDecorations({ suggestion, defaultRenderDecorations }) {
const decorations = defaultRenderDecorations()
// 创建包含 HTML 元素的 Prosemirror 装饰
decorations.push(
Decoration.widget(suggestion.range.to, () => {
const element = document.createElement('span')
setPopoverElement(element)
return element
}),
)
return decorations
},
},
},
})
const selectedSuggestion = toolkit.getSelectedSuggestion()
if (popoverElement && selectedSuggestion) {
// 将内容添加到自定义元素中。本例使用 React 门户渲染弹出框。
return <>{createPortal(<Popover suggestion={selectedSuggestion} />, popoverElement)}</>
}
return null
}我们推荐使用 Floating UI 库来显示弹出框。
在弹出框中渲染建议时,可以使用 getNextWord 和 getPreviousWord 工具函数,显示建议所在句子的前后单词。
import { getNextWord, getPreviousWord } from '@tiptap-pro/ai-toolkit'
// 获取句子中的前一个单词。
const { previousWord } = getPreviousWord(editor, suggestion.range.from)
// 获取句子中的后一个单词及其后面的标点符号(如果为句尾)。
const { nextWord, punctuationMark } = getNextWord(editor, suggestion.range.to)在编辑器外的侧边栏中显示建议
您可以通过 AI 工具包的 getSuggestions 方法获取当前建议。
const toolkit = getAiToolkit(editor)
const suggestions = toolkit.getSuggestions()然后,您可以使用这些数据在 UI 中(编辑器外)渲染建议。以下是使用 React UI 库实现的示例:
// 从 AI 工具包获取建议
const toolkit = getAiToolkit(editor)
const suggestions = toolkit.getSuggestions()
// 在 UI 中渲染建议
return (
<div>
{suggestions.map((suggestion) => (
<div key={suggestion.id}>
<p>删除内容: {toolkit.getTextRange(suggestion.range)}</p>
<p>添加内容: {suggestion.replacementOptions[0].content.toString()}</p>
</div>
))}
</div>
)后续步骤
- Learn more about suggestions in the API reference. See the
displayOptionsparameter for all the customization options.