Diff Viewer
A diff you can style, and accept or reject hunk by hunk.
- Data
- 2 files
- 1 npm package
- Accessibility notes
Loading the example…
pnpm dlx @dowel-ui/cli add diff-viewernpm packages installed: diff.
import { DiffViewer } from "@/components/ui/diff-viewer";Default
Split
With Toolbar
Agent Proposal
Collapsed Context
Without Word Detail
No Changes
Wipe Entrance
Collapse Rejected
<DiffViewer>
| Prop | Type | Default |
|---|---|---|
hunks (required) | DiffHunk[] | — |
label (required)Names the diff — usually the path of the file being changed. | string | — |
collapseRejectedCollapse a rejected hunk's lines. Its header and controls stay, so the decision can still be reversed, and the header says the lines are hidden. | boolean | false |
decisionsPer-hunk decisions, keyed by hunk id. Controlled. | Record<string, HunkDecision> | — |
entranceEntrance for added lines. | "none" | "wipe" | "none" |
onDecision | (hunkId: string, decision: HunkDecision) => void | — |
view | "unified" | "split" | "unified" |
children | ReactNode | — |
Plus every attribute of <div> except children.
<DiffViewerToolbar>
| Prop | Type | Default |
|---|---|---|
onViewChange (required) | (view: "unified" | "split") => void | — |
view (required) | "unified" | "split" | — |
Plus every attribute of <div> except onChange.
A semantic table, not a grid. role="grid" would promise cell-by-cell arrow navigation that does not exist here and makes no sense for reading code. Every row states added, removed or unchanged in text, because a plus sign and a green tint are not information — a diff read aloud without it is just the same file twice. Line numbers are aria-hidden: they orient a sighted reader, and announcing two numbers before every line makes the diff unlistenable. Changed words are marked with mark elements so they survive as structure, and the empty half of a split pair is hidden rather than read as a blank line of code. The optional wipe entrance is visual only — every row is in the DOM and its kind text is never clipped from assistive technology. With collapseRejected, a rejected hunk's lines are inert and hidden, its header says so in words, and Accept stays available so the decision can be reversed.
9/10
checks passed
- Tested — passes
- axe assertion — passes
- Keyboard tested — fails
- Storybook examples — passes
- Accessibility documented — passes
- Semantic tokens only — passes
- Motion from tokens — passes
- className merged — passes
- Visible focus — passes
- No fixed widths — passes