Components / AI interface
CodeBlock
Source code with a filename, copy and collapse, or a unified diff of changed lines.
Install
npx shadcn@latest add https://irisui.dev/r/code-block.jsonimport { CodeBlock } from "@/components/iris/code-block/code-block";Preview
CodeBlock
A framed code sample with a file header, lightweight syntax colouring and a copy action, shown as plain source or as a unified diff, optionally collapsed to a set number of lines.
When to use
- Showing a snippet people will read or copy: install commands, config, API requests and responses.
- Reviewing a change an agent proposes, as a diff with old and new line numbers, tinted rows and word-level highlights.
- Long samples, collapsed with
maxLinesand expanded in place. - Use
Chipfor a single inline token,JsonViewerfor exploring large JSON payloads andToolChipsfor multi-file change summaries.
Usage
import { CodeBlock } from "@/components/iris/code-block/code-block";
h(CodeBlock, {
filename: "fairrent-score.json",
language: "json",
maxLines: 6,
code: JSON.stringify(score, null, 2),
});
h(CodeBlock, {
filename: "db.ts",
language: "ts",
diff: [
{
old: 3,
cur: null,
type: "del",
pieces: [{ text: " url: process.env.CAPYDB_" }, { text: "DIRECT", change: "del" }, { text: "_URL," }],
},
{
old: null,
cur: 3,
type: "add",
pieces: [{ text: " url: process.env.CAPYDB_" }, { text: "POOLED", change: "add" }, { text: "_URL," }],
},
],
});
Props
| Prop | Type | Default | Description |
|---|---|---|---|
code |
string |
– | Source shown in the block and copied by the action. |
lines |
string[] |
– | The source as lines, used when code is not set. |
diff |
{ old: number | null; cur: number | null; type: "ctx" | "add" | "del"; pieces: { text: string; change?: "add" | "del" }[] }[] |
– | Unified-diff rows. When set, the block shows the diff instead of the plain source. A change on a piece gives it the word-level highlight. |
filename |
string |
"Source code" |
Shown in the header and used in the accessible name. |
language |
string |
"tsx" |
Header label and highlighting mode (tsx, jsx, ts, json, css, html…). A leading dot is ignored. |
maxLines |
number |
– | Collapse longer sources (or diffs with more rows) to this many lines, with a "Show all N lines" toggle that expands in place. |
labels |
Partial<{ copy: string; copied: string }> |
Copy code / Copied |
Text on the copy action. |
onCopy |
(text: string) => void |
– | Called with the copied text after a successful copy. |
Notes
- The copy action is
CopyButton. Withoutcodeorlines, a diff copies its new side (context and added rows). Copying needs a secure context. - The
sectionis labelled "{filename} source code" (or "{language} source code"); the source is focusable so keyboard users can scroll long lines, and the expand toggle usesaria-expanded/aria-controls. - The diff header shows added and removed row counts; the single gutter shows the old number on removed rows and the new number elsewhere, and removed rows carry a hatched bar so the change reads without colour.
- Highlighting is a small tokenizer (strings, keywords, numbers, properties, tags, functions), not a full grammar; token colours are fixed OKLCH values with separate light and dark sets. Lines do not wrap; long lines scroll.
- Expand and collapse animate the height; a new file name or source crossfades in place. All of it is instant under reduced motion.