Code Block
alphav0.1.4Code surface with view, edit, and terminal modes — Shiki highlighting, dual-theme CSS variables, and chrome presets for docs, chat, and terminal UIs.
Context
Substrate for every 'render code professionally' surface in the library — chat assistants, fenced markdown blocks, JSON / config viewers, card-tree code sections, virtual terminal walkthroughs, and snippet editors. View mode uses Shiki's GitHub Light + GitHub Dark Default themes (toggled via the active `.dark` class with zero re-tokenize). Edit mode wraps a CodeMirror 6 instance with a custom HighlightStyle approximating the same GitHub palette (near-match in v0.1.0; pixel-perfect Shiki → CodeMirror bridge defers to v0.2.0). Terminal mode renders structured `TerminalLine[]` rows with prompt detection on `$ `, `> `, `# ` prefixes and macOS-style traffic-light decoration. Streaming-friendly via an explicit `streaming` flag that batches re-tokenization to rAF and shows a blinking tail cursor. Filename → lang derivation works out of the box for ~30 extensions; consumer can override via `filenameToLang`. Object-shape callbacks throughout (per F-cross-12).
Installation
pnpm dlx shadcn@latest init"registries": {
"@ilinxa": "https://ui.ilinxa.com/r/{name}.json"
}pnpm dlx shadcn@latest add @ilinxa/code-blockAdd -fixtures for dummy data:
pnpm dlx shadcn@latest add @ilinxa/code-block-fixturesPreview
1. View mode — TypeScript (the default)
Filename + language pill + copy button. GitHub Light / Dark token palette.
2. Line highlights + annotations
Highlighted rows draw the eye; severity icons in the gutter open tooltips with messages.
3. Streaming — chat assistant style
Click Replay to emit 10-char chunks at 50 ms intervals. Tail cursor blinks while streaming; tokenization stays smooth.
4. JSON config + long-block collapse
Long blocks fade out with a 'Show all' button. Click to expand inline.
5. Terminal — virtual install walkthrough
Structured `lines: TerminalLine[]` API. Input rows show the prompt; output rows are muted; error rows in destructive red. macOS traffic-light decoration optional.
6. Edit mode — controlled CodeMirror editor
Same JetBrains Mono font, same line-height, near-match token colors via custom CodeMirror HighlightStyle. v0.2.0 will swap in a pixel-perfect Shiki bridge.
7. Custom header — action slot
The header `actions` slot accepts any ReactNode; pre-built buttons (copy, wrap, expand) compose around it.
8. Python sample — multi-language coverage
Shiki loads grammars on demand; common languages stay synchronously bundled (~10), the rest dynamic-import.
9. Error trace — annotations on a plain log
`lang='plaintext'` works as a viewer for arbitrary text. Combine with annotations + line-highlights for a debug surface.
10. Inline JSON (no chrome)
`header={false}` for a minimal embed.
Demo source
Usage
When to use
CodeBlockis the substrate for every “render code professionally” surface in the library: chat assistants, fenced markdown blocks, JSON/config viewers, card-tree “code” sections, virtual terminal walkthroughs, and snippet editors. Three modes (view / edit / terminal) cover the common cases. Streaming-friendly. Language-agnostic.
Basic — view
import { CodeBlock } from "@/components/code-block";
<CodeBlock filename="app.tsx" value={code} />Edit mode (controlled)
<CodeBlock
mode="edit"
lang="ts"
filename="greet.ts"
value={code}
onChange={({ value }) => setCode(value)}
onSave={({ value }) => save(value)}
/>Streaming (chat assistant)
<CodeBlock
lang="ts"
value={partial}
streaming={isStillStreaming}
/>Terminal
<CodeBlock
mode="terminal"
showTrafficLights
lines={[
{ kind: "input", text: "$ pnpm install" },
{ kind: "output", text: "Resolving... done" },
{ kind: "error", text: "ENOENT: no such file" },
]}
/>Notes
- Filename → lang priority:
lang(if set) wins; elsefilenameToLangconsumer override; else built-in extension map; elseplaintext. - Streaming: explicit
streamingprop. Final clean-tokenize fires when you flip it back tofalse. Don't auto-detect from update frequency. - RSC posture: the v0.1.0 client variant SSRs the first paint fine in Next.js. A dedicated zero-client-Shiki
/serverexport defers to v0.2.0. - Edit ↔ view continuity: near-match in v0.1.0 (custom CodeMirror HighlightStyle approximating GitHub Light + Dark Default). Pixel-perfect Shiki bridge defers to v0.2.0.
- Diff: use
lang="diff"for unified diff text in v0.1.0; split-view will be a siblingcode-diffcomponent. - Long blocks: opt-in via
maxLines; renders a fade-out + “Show all (N more lines)” button.
Features
- Three render modes (view / edit / terminal) in one component, switched by `mode` prop
- Shiki tokenization for view mode (GitHub Light + Dark Default by default; consumer overridable)
- CodeMirror 6 in edit mode with custom HighlightStyle for near-match view/edit visual continuity
- Streaming-friendly: explicit `streaming` prop, rAF-batched re-tokenization, blinking tail cursor
- Terminal mode with `lines: TerminalLine[]` API (input / output / error kinds) + prompt detection + optional macOS traffic-lights
- Chrome: filename pill, language label, copy button (with success animation), expand-to-modal, wrap toggle, download button — all gated by `show*` flags
- Body: optional line numbers (default off in view), wrap or scroll, highlighted line ranges, severity-icon annotations with tooltips, long-block collapse with 'Show all'
- Filename → lang priority chain: `lang` prop > consumer `filenameToLang` > built-in 30-entry extension map > plaintext
- Dual-theme via CSS variables: `.dark` class toggles palette with zero re-tokenize
- Standalone header parts exported (`<CodeBlockCopyButton>`, `<CodeBlockTrafficLights>`, etc.) for `renderHeader` slot composition
- Object-shape callbacks throughout (per F-cross-12)
- Imperative handle: `copy()`, `focus()`, `getValue()`, `scrollToLine()`