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.json
import { CodeBlock } from "@/components/iris/code-block/code-block";
Registry item code-blockBrings in foundationRegistry JSON

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 maxLines and expanded in place.
  • Use Chip for a single inline token, JsonViewer for exploring large JSON payloads and ToolChips for 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. Without code or lines, a diff copies its new side (context and added rows). Copying needs a secure context.
  • The section is labelled "{filename} source code" (or "{language} source code"); the source is focusable so keyboard users can scroll long lines, and the expand toggle uses aria-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.