shadcn.io is not affiliated with official shadcn/ui
Diff Text shows a change the way a pull request does, and plays it: removed lines tint red and are struck through, then added lines slide in tinted green, one after the other, while the unchanged lines around them stay put. You write it as a unified diff, the lines git diff prints, starting with +, - or a space.
Use it for a changelog, a migration guide or a hero that shows one change in a few lines. For a code sample that comes in token by token, use Syntax Text; for a data object, JSON Text. Each changed line runs a CSS keyframe animation the install adds to your stylesheet, delayed by its place among the changes, once the diff scrolls into view, with no animation library. With reduced motion the diff is simply there.
Installation
Usage
import { DiffText } from "@/components/ui/diff-text";<DiffText
text={`
const cache = createCache();
-cache.set(key, value);
+cache.set(key, value, { ttl: 60 });
`}
/>Demos
Prose
Diff Text isn't only for code: a copy edit or a release note reads the same way. The diff takes the font you give it, so font-sans sets it as prose; long lines wrap under their text, never under the + or -.
Timing
delay is the wait before the first change, 200 ms by default; stagger the time between one changed line and the next, 200 ms; duration how long one line takes to change, 500 ms. Unchanged lines take no time, so the changes follow each other however far apart they are.
Accessibility
Removed lines are real <del> and added lines real <ins>, each with a visually hidden "Removed:" or "Added:" before it, so screen readers say what changed rather than relying on red and green; the + and - are hidden from them. Pass removedLabel and addedLabel in your page's language. The diff always reads left to right, even on a right-to-left page, as code does. With reduced motion every line is in its final state from the start.
FAQ
How do I write the diff?
One line per line, as git diff prints a hunk: + before an added line, - before a removed one, a space before an unchanged one. A blank line at the very start or end is dropped, so a template literal can open and close on its own lines. Leave out the diff --git, ---, +++ and @@ headers.
Where do the colours come from?
Your theme: removed lines use --destructive, added lines --success and --success-foreground, which the install adds to your theme if it doesn't have them. They're tints, so the text stays readable in light and dark.
When does it play?
Once, when a quarter of the diff is in view. Pass trigger="mount" to play it as soon as the page shows it. A page without JavaScript shows the finished diff.
Can I show a long diff?
Yes, but it reads best at five to fifteen lines. The time grows with the number of changes, not lines; for many changes, lower stagger.
API Reference
DiffText
<div> data-slot="diff-text"
textstring
The diff, a line per line as in a unified diff: + starts an added
line, - a removed one, a space (or anything else) an unchanged one.
addedLabel?string
What screen readers say before an added line. @default "Added".
- Default
"Added"
delay?number
The wait before the first change, in milliseconds. @default 200.
duration?number
How long one line takes to change, in milliseconds. @default 500.
removedLabel?string
What screen readers say before a removed line. @default "Removed".
- Default
"Removed"
stagger?number
The time between one changed line and the next, in milliseconds. @default 200.
trigger?"mount" | "view"
When it plays: as soon as it's on the page, or once it scrolls into view.
- Type
"mount" | "view"- Default
"view"
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Merged with the part's classes.
data-change?string
Mirrors change.
data-view?string
"in" when visible is true, otherwise "out".
--diff-text-delaystring
The wait before the first change (200ms).
--diff-text-durationstring
One line's change (500ms).
--diff-text-staggerstring
The time between one changed line and the next (200ms).
Related
- Pro
Syntax Text
EntranceCode that comes in token by token
- Pro
JSON Text
EntranceA data object written key by key
- Pro
Terminal Text
EntranceA command typed, then its output
- Pro
Text Reveal
InteractiveA before and after the pointer wipes
- Pro
Regex Text
DecorativeMatches of a pattern, walked in turn
- Pro
Log Stream Text
MotionA live log for the same dev page