Diff View
A single-file diff with a collapsible header showing path, change counts and a five-cell bar, old/new line gutters, add/remove rows marked by tint and glyph, and foldable unchanged context.
Preview
| Old line | New line | Change | Code |
|---|---|---|---|
| 1 | 1 | unchanged | import { roundCents } from "./money"; |
| 2 | 2 | unchanged | import type { LineItem } from "./types"; |
| 3 | 3 | unchanged | |
| 4 | removed | export function invoiceTotal(items: LineItem[], taxRate: number) { | |
| 4 | added | export function invoiceTotal(items: LineItem[], taxRate: number, discount = 0) { | |
| 5 | 5 | unchanged | let subtotal = 0; |
| 6 | 6 | unchanged | for (const item of items) { |
| 7 | 7 | unchanged | subtotal += item.unitPrice * item.quantity; |
| 15 | 15 | unchanged | const issued = new Date().toISOString(); |
| 16 | 16 | unchanged | const due = addDays(issued, 30); |
| 17 | 17 | unchanged | const ref = makeReference(issued, lines); |
| 18 | removed | const tax = cents * taxRate; | |
| 19 | removed | return roundCents(cents + tax); | |
| 18 | added | const discounted = Math.max(0, cents - discount); | |
| 19 | added | const tax = discounted * taxRate; | |
| 20 | added | return roundCents(discounted + tax); | |
| 20 | 21 | unchanged | } |
| 21 | 22 | unchanged | |
| 22 | 23 | unchanged | export function formatTotal(cents: number) { |
| @@ -48,5 +49,4 @@export function formatTotal(cents: number) { | |||
| 48 | 49 | unchanged | export function dueLabel(days: number) { |
| 49 | 50 | unchanged | if (days <= 0) return "Due today"; |
| 50 | removed | if (days === 1) return "Due tomorrow"; | |
| 51 | 51 | unchanged | return `Due in ${days} days`; |
| 52 | 52 | unchanged | } |
| Old line | New line | Change | Code |
|---|---|---|---|
| @@ -4,3 +4,3 @@ | |||
| 4 | 4 | unchanged | export const theme = { |
| 5 | removed | radius: "0.5rem", | |
| 5 | added | radius: "0.625rem", | |
| 6 | 6 | unchanged | font: "var(--font-sans)", |
Install
Pro source requires Pebble Pro. Try the full preview above.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| path | string | — | Current file path (required). |
| oldPath | string | — | Previous path; implies renamed when it differs. |
| status | "modified" | "added" | "deleted" | "renamed" | inferred | Status pill in the header. |
| hunks | DiffHunk[] | — | Hunks { oldStart, newStart, header?, lines: { type, content }[] } (required); parseUnifiedDiff builds them from a unified diff. |
| contextLines | number | 3 | Unchanged lines kept beside each change; longer runs fold. |
| defaultOpen | boolean | true | Initial open state when uncontrolled. |
| open | boolean | — | Controlled open state; pair with onOpenChange. |
| onOpenChange | (open: boolean) => void | — | Called when the header toggles. |
| wrap | boolean | false | Wrap long lines instead of scrolling sideways. |
| actions | ReactNode | — | Controls at the end of the header, outside the toggle. |
Pro component
Try the full preview above. Editable source and build guides require Pebble Pro.
