Diff View
A unified or side-by-side diff. Takes parsed hunks rather than a patch string, with parseUnifiedDiff exported alongside for when you only have the text.
src/components/ui/diff-view.tsxAbout
From the component's own source, where it was written.
A unified or split diff.
Takes parsed hunks rather than a raw patch string: parsing unified-diff text is a separate concern with its own edge cases (renames, binary files, "\ No newline at end of file"), and baking a half-parser into a view component means every caller inherits its bugs. parseUnifiedDiff is exported alongside for the common case.
Split mode pairs deletions with insertions positionally within a hunk, which is what a side-by-side view actually shows — not a semantic word-level match, which needs a real diff algorithm and a lot more code than this earns.
Install
npx astralyx-ui add diff-view
Usage
import { DiffView, parseUnifiedDiff } from '@/components/ui/diff-view'
<DiffView
file={{ path: 'src/lib/styles.ts', hunks: parseUnifiedDiff(patch) }}
view="split"
/>Composer
Change the props and the source below follows.
<DiffView
file={{ path: 'src/lib/styles.ts', hunks: parseUnifiedDiff(patch) }}
view="unified"
collapsible={true}
/>Examples
Unified and split
<DiffView file={file} />
<DiffView file={file} view="split" />API
Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.
DiffView
Extends ComponentProps<'div'>.
| Prop | Type | Default | Description |
|---|---|---|---|
| file | DiffFile | required | { path, previousPath?, status?, hunks }. Additions and deletions are counted from the hunks rather than passed in, so the header can never disagree with the body. |
| view | 'unified' | 'split' | 'unified' | Split pairs removals with additions positionally inside each hunk — what a side-by-side view actually shows, without a word-level diff algorithm. |
| collapsible | boolean | true | Fold the file behind its header, for a review with many files. |
| defaultOpen | boolean | true | Fold the file behind its header, for a review with many files. |
DiffViewList
Several files in one review, sharing a view mode.
Extends Omit<ComponentProps<'div'>, 'children'>.
| Prop | Type | Default | Description |
|---|---|---|---|
| files | DiffFile[] | required | — |
| view | 'unified' | 'split' | 'unified' | Split pairs removals with additions positionally inside each hunk — what a side-by-side view actually shows, without a word-level diff algorithm. |
| children | ReactNode | — | — |
Functions
| Function | Signature | Description |
|---|---|---|
| parseUnifiedDiff | (patch: string) => DiffHunk[] | Parses standard unified-diff text, tracking old and new line numbers across hunks. |
Types
DiffLine
A unified or split diff.
| Field | Type | Description |
|---|---|---|
| type | 'add' | 'remove' | 'context' | 'meta' | — |
| content | string | — |
| oldLine? | number | 1-based line number in the old file. |
| newLine? | number | 1-based line number in the new file. |
DiffHunk
| Field | Type | Description |
|---|---|---|
| header | string | — |
| lines | DiffLine[] | — |
DiffFile
| Field | Type | Description |
|---|---|---|
| path | string | — |
| previousPath? | string | Set when the file was moved. |
| status? | 'modified' | 'added' | 'removed' | 'renamed' | — |
| hunks | DiffHunk[] | — |