Readable output
Code diff
A unified patch with line gutters, change tints, per-hunk accept or reject, and a copyable source.
Starts when it scrolls into view
NORD FROST · DARK · RADIUS 6/10 · BASE 16PX · SHADOW
- Type
CodeDiff- Source
code_diff.rs- Story
code-diff- Demo height
- 477 px
- Events
- CodeDiffEvent
Code
Cut from the gallery story this page runs, so it stays true.
let tokens = cx.theme().semantic_tokens();
let mut file = DiffFile::from_unified(DEMO_PATCH).remove(0);
let hunks: Vec<DiffHunk> = file
.hunk_refs()
.iter()
.cloned()
.enumerate()
.map(|(index, hunk)| {
hunk.review(
self.hunk_reviews
.get(&index)
.copied()
.unwrap_or_default(),
)
})
.collect();
file = file.hunks(hunks);
let status: SharedString = self
.last_diff_event
.clone()
.unwrap_or_else(|| "Accept or reject a hunk, or collapse the file".into());
v_flex()
.gap(tokens.spacing.md)
.child(
CodeDiff::new("proposed-patch", &file)
.open(self.diff_open)
.reviewable(true)
.on_event(cx.listener(|this, event: &CodeDiffEvent, _, cx| {
match event {
CodeDiffEvent::Toggled { .. } => {
this.diff_open = !this.diff_open;
}
CodeDiffEvent::HunkAccepted { hunk, .. } => {
this.hunk_reviews.insert(*hunk, HunkReview::Accepted);
}
CodeDiffEvent::HunkRejected { hunk, .. } => {
this.hunk_reviews.insert(*hunk, HunkReview::Rejected);
}
}
this.last_diff_event = Some(format!("{event:?}").into());
cx.notify();
})),
)
.child(
div()
.id("code-diff-story-status")
.role(Role::Status)
.aria_label(status.clone())
.text_xs()
.text_color(cx.theme().muted_foreground)
.child(status),
)
Events and ownership
- Who owns the state
- CodeDiff renders state supplied by the application; it does not own durable work.
- What it emits
- Interactive intent is reported through the typed CodeDiffEvent contract and stable application IDs.
- What it means
- A unified patch with line gutters, change tints, per-hunk accept or reject, and a copyable source.
- Overflow and motion
- Growing content remains reachable in a bounded vertical surface; reduced motion preserves a useful state.
Event types
- CodeDiffEvent
What the demo does and does not show
The demo above is the same Rust as the native component, compiled to WebAssembly and drawn on a WebGPU canvas — not a mock-up, a recording, or a re-implementation. What it paints is what the component paints: layout, colour from the live theme, and motion.
The live browser specimen requires WebGPU; the native component remains the authoritative runtime.
A canvas cannot stand in for the platform, so treat everything that goes through the operating system as unproven here: keyboard handling and shortcuts, screen reader semantics, text input and IME, the clipboard, file drops, and the frame rate you would get on your own GPU. Judge those in a native build. If your browser has no WebGPU, the frame says so rather than showing an empty box.