Skip to content
Component installs need the registry setup— the Base UI shadcn project, the @vegastack namespace and the Cloudflare Access service token.
VegaStack Design

Code Block

A code panel with a language header and copy affordance — the shared code surface for chat transcripts, 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

Add Code Block from the VegaStack registry. The CLI verifies the item's integrity hash before writing it.

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

The same command installs the registry items it composes: @vegastack/copy-button.

Usage

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 labelled, copyable surface with no extra wiring.

Anatomy

A <figure>: the header (<figcaption>) carries the language in the mono-label voice and a CopyButton when copyValue is set; the body is the sunken bg-muted panel with overflow-x-auto and text-code mono. Omit both header props for a bare block.

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 ${language ?? 'code'}`Accessible label for the copy control.
copyValuestringWhen set, a CopyButton for this raw source appears in the header.
languagestringLanguage label shown in the header (mono uppercase voice). Omit both this and copyValue to render a bare, headerless 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"

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