AI
DiffAIPro
A text diff with inline and split modes, word level highlights inside changed lines and optional line numbers. Shows what an AI edit or a new version changes.
npx prodular-ui add diffPart of Prodular UI Pro. Preview and read the docs freely, install with a license. See pricing
Inline
Removed and added lines stacked, with the changed words highlighted inside them.
import { Diff, DiffHeader, DiffStat, DiffTitle } from "@/components/ui/diff"
const before = `subject: Invoice {{invoice.number}} is overduefrom: ar@ledgerline.appdelay_days: 7tone: firm
Hi {{contact.first_name}},Invoice {{invoice.number}} for {{invoice.total}} is now overdue.Please pay it as soon as possible.`
const after = `subject: A reminder about invoice {{invoice.number}}from: ar@ledgerline.appdelay_days: 10tone: friendly
Hi {{contact.first_name}},Invoice {{invoice.number}} for {{invoice.total}} was due on {{invoice.due_date}}.You can pay it in a minute with the link below.Reply to this email if anything looks wrong.`
export default function DiffInline() { return ( <Diff before={before} after={after} lineNumbers className="mx-auto max-w-2xl self-start"> <DiffHeader> <DiffTitle>second-notice.tmpl</DiffTitle> <DiffStat /> </DiffHeader> </Diff> )}Split
Before and after side by side. variant="prose" uses the UI font and wraps long lines.
import { Diff, DiffHeader, DiffStat, DiffTitle } from "@/components/ui/diff"
const before = `Technicians must check in at the site office on arrival.Visits over 2 hours need a supervisor sign off.Parts under $200 can be bought on the company card.Photos are optional for completed jobs.`
const after = `Technicians check in through the app on arrival.Visits over 2 hours need a supervisor sign off.Parts under $350 can be bought on the company card.Upload at least 2 photos before closing a job.`
export default function DiffSplit() { return ( <Diff before={before} after={after} mode="split" variant="prose" lineNumbers className="mx-auto max-w-3xl self-start"> <DiffHeader> <DiffTitle>Field policy, version 4 to 5</DiffTitle> <DiffStat /> </DiffHeader> </Diff> )}Inline text
DiffText flows inside a paragraph. Used by Inline Assist to show a proposed edit in place.
Close for Q3 is basicallysubstantially donecomplete. We're are still waiting on 3 vendor credits, which meansso accounts payable is a little higher than it shouldtemporarily beoverstated.
The Team plan grew faster than we expected after the July price change. With showRemoved off, only additions are marked.
import { DiffText } from "@/components/ui/diff"
export default function DiffProse() { return ( <div className="flex w-full max-w-xl flex-col gap-4 text-[0.9375rem] leading-7"> <p> <DiffText before="Close for Q3 is basically done. We're still waiting on 3 vendor credits, which means accounts payable is a little higher than it should be." after="Close for Q3 is substantially complete. We are still waiting on 3 vendor credits, so accounts payable is temporarily overstated." /> </p> <p className="border-t pt-4 text-muted-foreground"> <span className="text-foreground"> <DiffText showRemoved={false} before="The Team plan grew faster then we expected." after="The Team plan grew faster than we expected after the July price change." /> </span>{" "} With showRemoved off, only additions are marked. </p> </div> )}Anatomy
<Diff before={original} after={proposed} lineNumbers> <DiffHeader> <DiffTitle>second-notice.tmpl</DiffTitle> <DiffStat /> </DiffHeader></Diff>Guidance
Use it when
- Show a diff before anyone accepts a change the model proposed to existing text, a template or a config.
- Use mode="inline" in narrow spaces and mode="split" when there is room and lines change a lot.
- Use variant="prose" for sentences and paragraphs, variant="code" for templates, configs and code.
- Use DiffText inside running text, for example a proposed rewrite of one paragraph.
Avoid
- Showing only the new version of a generated edit. People need to see what is removed.
- Diffs of very long documents in one view. Diff the section that changed.
- Coloring removed and added text yourself. The component uses the success and destructive subtle tokens.
Rules for AI agents
Published in llms-full.txt and the registry, so coding agents follow them when they build with this component.
- Pass the original text as before and the proposed text as after, as plain strings. Do not pre mark changes.
- Pair every AI proposed edit with a diff and explicit Accept and Reject actions. Never apply the after text on render.
- Turn lineNumbers on for code and configs, off for prose.
- Put DiffHeader with DiffTitle and DiffStat inside Diff when the diff stands alone, so people know what file or document changed.
API
Diff
| Prop | Type | Default | Description |
|---|---|---|---|
| before / after | string | The original and the changed text. | |
| mode | "inline" | "split" | "inline" | Stacked or side by side. Exposed as data-mode. |
| variant | "code" | "prose" | "code" | Mono and no wrapping, or UI font with wrapping. |
| lineNumbers | boolean | false | Old and new line numbers. |
| wordLevel | boolean | true | Highlight changed words inside changed lines. |
DiffText
| Prop | Type | Default | Description |
|---|---|---|---|
| before / after | string | A word level diff that flows inside text. | |
| showRemoved | boolean | true | Hide deletions to preview the result. |
diffWords / diffLines
| Prop | Type | Default | Description |
|---|---|---|---|
| (before, after) | DiffOp<string>[] | The underlying diff, if you need to render it yourself. |