Style suggestions with the AI Toolkit
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.
Add CSS styles to suggestions
When the default renderDecorations function is used, the following classes are applied:
.tiptap-ai-suggestion: Applied on the content that is covered by the suggestion range..tiptap-ai-suggestion--selected: Applied when the cursor is inside the suggestion range..tiptap-ai-suggestion-diff: Applied on the diff widget that is displayed next to the suggestion range..tiptap-ai-suggestion-diff--selected: Applied to the diff widget when the cursor is inside the suggestion range.
Use the above classes to style the suggestions, or provide a custom renderDecorations function for full control over the UI.
Render React components inside a suggestion
You can use the renderDecorations option, combined with React portals, to display a React component inside a suggestion.
First, define a React component with a hook to store the HTML element where the React Portal will be rendered.
import { useState } from 'react'
function MyComponent() {
  const [portalElement, setPortalElement] = useState<HTMLElement | null>(null)
  return null
}Then, in the displayOptions.renderDecorations option, create a widget decoration with a HTML element that will be used as the entry point of the React portal.
const aiToolkit = getAiToolkit(editor)
// Example method of the AI Toolkit that generates suggestions
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
      },
    },
  },
})Finally, in the React component, render any React elements inside the portal.
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
}Show a popover or a tooltip when a suggestion is selected
You can use the technique explained above to show a tooltip when a suggestion is selected.
To show a popover when you select a suggestion, you need to use the getCustomSuggestionDecoration option. This function allows you to add custom elements to the suggestions, including popovers.
Below is a simplified example on how to do it with the React UI library.
import { useState } from 'react'
import { createPortal } from 'react-dom'
// Inside the React component
function MyComponent() {
  const toolkit = getAiToolkit(editor)
  // First, define a hook to store the HTML element where the popover will be rendered
  const [popoverElement, setPopoverElement] = useState<HTMLElement | null>(null)
  // When the tool is executed, configure how the decorations are rendered
  aiToolkit.executeTool({
    reviewOptions: {
      mode: 'preview',
      displayOptions: {
        renderDecorations({ suggestion, defaultRenderDecorations }) {
          const decorations = defaultRenderDecorations()
          // Then, create a Prosemirror decoration that contains the HTML element
          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) {
    // Then, add the content to the custom element. In this example, we use React Portals to render the popover.
    return <>{createPortal(<Popover suggestion={selectedSuggestion} />, popoverElement)}</>
  }
  return null
}We recommend using the Floating UI library to display the popover.
When you render the suggestion in the popover, use the getNextWord and getPreviousWord utility functions to show the previous and next words of the sentence where the suggestion is located.
import { getNextWord, getPreviousWord } from '@tiptap-pro/ai-toolkit'
// Get the previous word in the sentence.
const { previousWord } = getPreviousWord(editor, suggestion.range.from)
// Get the next word in the sentence and the punctuation mark that follows it, if it's the end of the sentence.
const { nextWord, punctuationMark } = getNextWord(editor, suggestion.range.to)Display suggestions in a sidebar outside the editor
You can access the current suggestions from the AI Toolkit's getSuggestions method.
const toolkit = getAiToolkit(editor)
const suggestions = toolkit.getSuggestions()Then, you can use this data to render suggestions in the UI, outside the editor. Here is an example of how to do it with the React UI library:
// Get the suggestions from the AI Toolkit
const toolkit = getAiToolkit(editor)
const suggestions = toolkit.getSuggestions()
// Render the suggestions in the UI
return (
  <div>
    {suggestions.map((suggestion) => (
      <div key={suggestion.id}>
        <p>Delete: {toolkit.getTextRange(suggestion.range)}</p>
        <p>Add: {suggestion.replacementOptions[0].addSlice.toString()}</p>
      </div>
    ))}
  </div>
)Next steps
- Learn more about suggestions in the API reference. See the 
displayOptionsparameter for all the customization options.