WebberUI

AI Diff Suggestion Card

AI suggestions presented as an inline diff — deletions struck through in red, additions in green, accepted or rejected one by one.

This is a WebberUI Pro component

Free during the launch campaign: sign up or sign in, then hit “Copy install command” in the preview above and it installs straight away — no payment, no credit card. The command below returns 401 while you are signed out.

How to install Pro components →See the plans →

AI edit suggestions presented as diff markers inside a paragraph of text — deleted original text gets a red background with a strikethrough, added text gets a green background — and hovering a marker floats out small accept and reject buttons: accepting plays a green confirmation animation, rejecting restores the original. A header offers "Accept all" and a remaining count, which suits AI writing assistants, copy polishing, and review workflows.

Loading preview…
npx shadcn@latest add "https://webberui.com/r/ai-diff-suggestion.json?t=<install token>"

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

<AiDiffSuggestion />

Installation

npx shadcn@latest add "https://webberui.com/r/ai-diff-suggestion.json?t=<install token>"

Or, once registries are configured in components.json, install it as @webberui/ai-diff-suggestion.

Usage

import {
  AiDiffSuggestion,
  type DiffSegment,
} from "@/components/ui/ai-diff-suggestion";

const segments: DiffSegment[] = [
  { type: "text", content: "Thank you for " },
  { type: "suggestion", id: "s1", removed: "trying", added: "taking the time to experience" },
  { type: "text", content: " our service." },
];

<AiDiffSuggestion
  segments={segments}
  onResolve={(id, action) => console.log(id, action)}
/>

Props

PropTypeDefaultDescription
segmentsDiffSegment[]The sequence of diff segments, interleaving plain text with AI suggestions
titlestring"AI 修改建議" ("AI edit suggestions")Card title
onResolve(id: string, action: "accept" | "reject") => voidFires when a single suggestion is accepted or rejected
onComplete() => voidFires once when every suggestion has been resolved
classNamestringForwarded to the card's outer container

DiffSegment is a union of two types:

FieldTypeDescription
type"text" | "suggestion"text is a plain text segment, suggestion is an AI suggestion segment
contentstringPlain text content (text only)
idstringUnique identifier of the suggestion, returned through onResolve (suggestion only)
removedstringThe original text the suggestion deletes; an empty string means a pure addition (suggestion only)
addedstringThe text the suggestion adds; an empty string means a pure deletion (suggestion only)

Accessibility

  • Deletions and additions use the semantic del and ins elements, so assistive technology can tell what kind of revision each one is
  • Accept and reject are real button elements with an aria-label, focusable with Tab, and the buttons surface automatically on focus
  • Touch devices have no hover: tapping the marker itself pins the accept / reject buttons in place
  • When the user has "reduce motion" enabled at the system level, the green confirmation flash and the cascade animation of "Accept all" are skipped and the result is shown directly

On this page