Skip to content
Component installs need the registry setup
VegaStack Design

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
stable
Since
0.3.0
Accessibility pattern
figure with caption

Last updated

SQL
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:build

Install

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-block

Install with the pinned shadcn CLI. Bare shadcn does not verify VegaStack signature or integrity.

pnpm dlx shadcn@4.21.0 add @vegastack/code-block

Run 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.

CodeBlock — data-slot="code-block" | "code-block-header" | "code-block-pre"

Examples

With and without a header

SQL
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:build

Long 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.

Bash
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-closed

API Reference

PropTypeDefaultDescription
copyLabelstring"Copy"The copy control's accessible name (an icon button).
copyValuestring—When set, a Copy button for this raw source shows top-right on hover.
languagestring—The fence's language (ts, python, …): picks the highlighting grammar, and its display name shows top-left on hover. Omit it for plain text.
wrapbooleanfalseWrap long lines instead of scrolling them sideways inside the block.

Data attributes and CSS variables on CodeBlock

AttributeValues
data-languagemirrors a prop or state value
data-slot"code-block" | "code-block-header" | "code-block-pre"
data-wrap""

Accessibility

  • A supplied language becomes the visible <figcaption> label; the code remains real selectable text.
  • The composed CopyButton provides 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.
ContractStates tested
Behaviourdefault
Accessibilitynative-or-base-ui-semantics, browser-accessibility-test
Visualdefault

Do / Don't

Do
Pass the exact raw source to copyValue and a short official language identifier when the block has a header.
Don't
Put prose paragraphs or interactive controls inside the preformatted code body.

On this page