自定义建议显示方式
AI 建议扩展是无头且完全可定制的。这意味着你可以完全控制建议在编辑器中的显示方式。
显示加载建议时的加载/错误状态
你可以通过读取扩展的存储对象来访问当前的加载状态
const storage = editor.extensionStorage.aiSuggestion
if (storage.isLoading) {
// 显示加载动画
} else if (storage.error) {
// 显示错误信息。
}storage.error 属性将包含加载建议时抛出的错误对象。你可以根据错误类型使用该对象显示不同的错误信息。
默认建议样式
默认情况下,AI 建议扩展会向每个建议添加 CSS 类 tiptap-ai-suggestion。它还会添加带有以下颜色变量的 style 属性:--tiptap-ai-suggestion-color 和 --tiptap-ai-suggestion-background-color。类 tiptap-ai-suggestion 可用于在编辑器中为建议应用简单样式。
.tiptap-ai-suggestion {
border-bottom: 2px solid var(--tiptap-ai-suggestion-color);
margin-bottom: -2px;
}如果需要更高级的样式,请使用 getCustomSuggestionDecoration 配置选项。
选中建议
当光标悬停在建议上时,该建议被视为“选中”。
你可以从扩展的存储对象中读取选中的建议
const storage = editor.extensionStorage.aiSuggestion
const selectedSuggestion = storage.getSelectedSuggestion()要通过编程方式选中某个建议,请使用 selectAiSuggestion 命令。
editor.commands.selectAiSuggestion(suggestionId)这会将光标移至建议的起始位置,从而使其被视为“选中”。
默认情况下,AI 建议扩展会向选中的建议应用 CSS 类 tiptap-ai-suggestion--selected。此类可用于在编辑器中为选中的建议添加样式。
.tiptap-ai-suggestion--selected {
background-color: var(--tiptap-ai-suggestion-background-color);
transition: background-color 0.5s;
}自定义建议的外观
getCustomSuggestionDecoration 选项允许你控制建议的外观,并为用户提供视觉提示。你可以向建议添加自定义 CSS 类,也可以在建议前后添加自定义元素。这对于向建议添加弹出层、工具提示、图标或其他元素非常有用。
自定义建议样式是通过 Prosemirror Decorations API 应用的。
要了解如何在选中建议时显示弹出层,请参考本指南。
AiSuggestion.configure({
getCustomSuggestionDecoration({ suggestion, isSelected, getDefaultDecorations }) {
// 你可以将 AI 建议扩展的默认装饰与自定义装饰结合起来
const decorations = getDefaultDecorations()
// 在建议文本后添加自定义元素
decorations.push(
Decoration.widget(suggestion.deleteRange.to, () => {
const element = document.createElement('span')
element.textContent = '⚠️'
return element
}),
)
return decorations
},
})选中建议时显示弹出层
现代 AI 建议的一个核心功能是在选中建议时显示弹出层或工具提示。该弹出层通常提供该建议的额外信息,并允许用户接受或拒绝该建议。
要在选中建议时显示弹出层,需使用 getCustomSuggestionDecoration 选项。该函数允许你向建议添加自定义元素,包括弹出层。
下面是用 React UI 库简化实现的示例。
// 首先,定义一个 hook 来存储弹出层渲染的 HTML 元素
const [popoverElement, setPopoverElement] = useState<HTMLElement | null>(null)
AiSuggestion.configure({
getCustomSuggestionDecoration({ suggestion, isSelected, getDefaultDecorations }) {
const decorations = getDefaultDecorations()
// 然后,创建包含该 HTML 元素的 Prosemirror 装饰
if (isSelected) {
decorations.push(
Decoration.widget(suggestion.deleteRange.to, () => {
const element = document.createElement('span')
setPopoverElement(element)
return element
}),
)
}
return decorations
},
})
const selectedSuggestion = editor.extensionStorage.aiSuggestion.getSelectedSuggestion()
if (popoverElement && selectedSuggestion) {
// 然后,将内容添加到该自定义元素中。在此示例中,我们使用 React 门户将弹出层渲染到编辑器内。
ReactDOM.createPortal(<Popover suggestion={selectedSuggestion} />, popoverElement)
}我们推荐使用 Floating UI 库来显示弹出层。你可以在 演示示例 中查看具体实现。
在弹出层中渲染建议时,你可能希望显示该句子的前后单词,为用户提供更多上下文。我们已经创建了 getNextWord 和 getPreviousWord 实用函数,免去你自己实现的麻烦。你可以从 @tiptap-pro/extension-ai-suggestion 库中导入它们。
import { getNextWord, getPreviousWord } from '@tiptap-pro/extension-ai-suggestion'
// 获取句子中的前一个单词。
const { previousWord } = getPreviousWord(editor, suggestion.deleteRange.from)
// 获取句子中的下一个单词及其后的标点符号(如果已到句尾)。
const { nextWord, punctuationMark } = getNextWord(editor, suggestion.deleteRange.to)在编辑器外的侧边栏显示建议
你可以从扩展的存储对象访问当前建议。
const storage = editor.extensionStorage.aiSuggestion
const suggestions = storage.getSuggestions()然后,你可以使用这些数据在 UI 中(编辑器外)渲染建议。以下是使用 React UI 库实现的示例:
// 从编辑器状态中获取建议。
const storage = editor.extensionStorage.aiSuggestion
const suggestions = storage.getSuggestions()
// 在 UI 中渲染建议
return (
<div>
{suggestions.map((suggestion) => (
<div key={suggestion.id}>
<p>{suggestion.deleteText}</p>
<ul>
{suggestion.replacementOptions.map((option) => (
<li key={option.id}>{option.addText}</li>
))}
</ul>
</div>
))}
</div>
)