Code Block
A syntax-highlighted code panel with the language and a copy button on hover — the shared code surface for chat, docs prose and examples.
- Status
- Since
0.3.0- Accessibility pattern
- figure with caption
Last updated
SELECT
COALESCE(primary_location.country_code, 'Not recorded') AS country,
COUNT(record_id) AS company_count
FROM companies
GROUP BY country
ORDER BY company_count DESC;# headerless: no language, no copy
pnpm run registry:buildInstall
Configure registry credentials first using the Quickstart. Before copying this item or any transitive registry dependency, verify the signed manifest and save the exact bytes for Code Block before installation. Retain the digest printed by this command.
pnpm exec vegastack-design verify code-blockInstall with the pinned shadcn CLI. Bare shadcn does not verify VegaStack signature or integrity.
pnpm dlx shadcn@4.21.0 add @vegastack/code-blockRun the exact offline --post-write command printed by the preflight, using its saved item path and independently retained --expected-integrity digest. Use the saved preflight for every transitive registry dependency too; stop on any mismatch before using the components.
The same command installs the registry items it composes: @vegastack/copy-button, @vegastack/code-highlight, @vegastack/block-toolbar.
It also adds the sanctioned engines to your package.json: hast-util-to-jsx-runtime, lowlight.
Usage
Unknown fence languages, including inherited object-property names, render as plain text.
import { CodeBlock } from "@/components/ui/code-block";
<CodeBlock language="sql" copyValue={query}>
{query}
</CodeBlock>;MarkdownView integration
MarkdownView delegates every fenced code block here automatically — the language comes from
the fence info string and the copy source from the block's text, so chat transcripts and
rendered markdown get the highlighted, copyable surface with no extra wiring. TextEdit's code
block wears the same surface, with a searchable language picker in place of the label.
Anatomy
A <figure> on bg-muted/60, rounded-lg, with no border or header bar. On hover or focus inside
(always on a touch screen) the language's display name (<figcaption>, "TypeScript" for ts)
shows top-left and a Copy CopyButton (check and "Copied" after a copy) top-right when
copyValue is set. The body is 13px mono with relaxed leading, px-4 py-3, scrolling sideways. A
string child is highlighted with lowlight's common grammars (fence aliases such as ts, js, sh
and yml resolve), coloured by the token-mapped .hljs-* rules in utilities.css.
Examples
With and without a header
SELECT
COALESCE(primary_location.country_code, 'Not recorded') AS country,
COUNT(record_id) AS company_count
FROM companies
GROUP BY country
ORDER BY company_count DESC;# headerless: no language, no copy
pnpm run registry:buildLong lines
Code does not wrap. A line wider than the panel scrolls inside the block's own horizontal scroll container, so a long command never widens the page around it — which is what keeps a 320px viewport reflowing instead of scrolling sideways.
docker run --rm -it --name vegastack-registry --env REGISTRY_BASE_URL=https://design.vegastack.com/r --env CF_ACCESS_CLIENT_ID=$CF_ACCESS_CLIENT_ID --volume "$PWD":/workspace ghcr.io/vegastack/registry-preflight:latest --verify --fail-closedAPI Reference
| Prop | Type | Default | Description |
|---|---|---|---|
copyLabel | string | "Copy" | The copy control's accessible name (an icon button). |
copyValue | string | — | When set, a Copy button for this raw source shows top-right on hover. |
language | string | — | The fence's language (ts, python, …): picks the highlighting grammar, and its display name
shows top-left on hover. Omit it for plain text. |
wrap | boolean | false | Wrap long lines instead of scrolling them sideways inside the block. |
Data attributes and CSS variables on CodeBlock
| Attribute | Values |
|---|---|
data-language | mirrors a prop or state value |
data-slot | "code-block" | "code-block-header" | "code-block-pre" |
data-wrap | "" |
Accessibility
- A supplied
languagebecomes the visible<figcaption>label; the code remains real selectable text. - The composed
CopyButtonprovides its own keyboard interaction, accessible name, and polite copied-state announcement. - Horizontal overflow scrolls inside the code panel so long lines do not force page-level overflow at 320px.
| Contract | States tested |
|---|---|
| Behaviour | default |
| Accessibility | native-or-base-ui-semantics, browser-accessibility-test |
| Visual | default |
Do / Don't
Markdown View
Render a markdown string to safe, token-styled HTML — headings, lists, code, blockquotes, links, and GFM tables — XSS-safe with no raw HTML.
Mermaid Block
A mermaid diagram drawn in the browser — lazily loaded, strictly configured, in token colours — and the Diagram block view for TextEdit and MarkdownView.