Skip to main content

Design system components

CodeBlock

Multi-line source with an optional filename header, line numbers, highlighted, added and removed rows, copy and a caption.

Status: beta. Group: structure. Markdown version: /design-system/components/code-block.md

When to use

CodeBlock shows source the reader will scan or paste. Pass code as a string (highlighted at runtime) or a Shiki tree from the MDX pipeline. Give a filename when the code has a paste destination, highlight only the lines under discussion and mark diffs as added and removed rows instead of comments, so copy-paste still yields working code.

When not to use

  • Do not use for a single command the reader pastes into a terminal; use Snippet.
  • Do not use for one identifier inside a sentence; use Code.

Look-alikes

  • Code: Do not use for one identifier inside a sentence; use Code.
  • Snippet: Do not use for a single command the reader pastes into a terminal; use Snippet.

Props

CodeBlock props
PropTypeDefaultDescriptionRequired
codestringnoneSource to show. Highlighted at runtime for the common languages; with language="diff" the leading +/- of each line become added and removed rows. Pass either code or a pre-highlighted Shiki tree as children.No
childrenReact.ReactNodenoneA Shiki <pre><code> tree (rehype-pretty-code output). Callouts come from the MDX meta string: a line range highlights, and a range with the id "added" or "removed" marks a diff.No
languagestringnoneLanguage of the code; shown in the header and drives highlighting.No
filenamestringnoneFile name shown in the header. Giving one turns the header on.No
headerbooleantrue when `filename` is setShow the header bar.No
lineNumbersbooleanthe Shiki tree's showLineNumbers, else falseNumber the lines.No
highlightLinesCodeLineSpecnoneLines to highlight: [2, 3] or "2-3,7". 1-based.No
addedLinesCodeLineSpecnoneLines to mark as added.No
removedLinesCodeLineSpecnoneLines to mark as removed. Copy leaves them out.No
captionReact.ReactNodenoneCaption under the card.No
theme"light" | "terminal"lightterminal renders the block in the dark theme on any page. In the high-contrast themes it follows the page so contrast stays at the high-contrast level.No
wrapbooleanfalseWrap long lines instead of scrolling sideways.No
maxHeightstring | numbernoneCap the body height (any CSS length, or pixels) and scroll inside it.No
copyablebooleantrueShow the copy button.No
copyLabelstring"Copy code" (translated)Accessible name for the copy button.No
onCopy(text: string) => voidnoneCalled with the copied text.No

Variants

  • Available themes: light, terminal (default light).

Invalid combinations

The contract records no invalid combinations.

Keyboard

CodeBlock keyboard behaviour
KeyBehaviour
TabReaches the copy button, then the code body when it scrolls.
arrow keysScroll the focused body.

Rules

Every item under When not to use is a MUST NOT. MUST and SHOULD follow RFC 2119.

CodeBlock rules
LevelRuleHow it is checked
MUSTARIA: The body becomes a named, focusable region only when it overflows, so a short block adds no tab stop.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTARIA: Added and removed rows carry a sign with translated alternative text (Added line, Removed line); state never rests on colour alone.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTARIA: Line numbers are generated content with empty alternative text, so screen readers read the code only.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTARIA: With a caption the block is a figure and the caption its figcaption.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTRequired stories produce no axe violations at the configured severity.Automated by npm run test:stories:matrix:ci. WCAG 2.5.8.
MUSTThe accessibility tree (role, name, state) matches the committed snapshot for every required story.Automated by npm run test:stories:matrix:ci. WCAG 1.3.1, 4.1.2.
MUSTThe component remains legible and operable under a real browser forced-colors: active pass.Automated by npm run test:stories:hc.
MUSTEvery documented keyboard interaction works as specified.Not yet verified: no evidence record. WCAG 2.1.1, 2.1.2.
MUSTA human completed an end-to-end accessibility review of this component.Manual review, last on 2026-10-25.
SHOULDAlways set language; highlighting is the reason to choose CodeBlock over a plain pre.Not stated in the contract.
SHOULDShow a filename when the snippet belongs in a specific file; leave it out for throwaway examples.Not stated in the contract.
SHOULDMark changes with addedLines and removedLines or language="diff"; copy leaves removed lines out.Not stated in the contract.
SHOULD NOTDo not highlight most of the block; a block where every line is highlighted reads like no highlight.Not stated in the contract.
SHOULD NOTDo not turn on line numbers for blocks under five lines.Not stated in the contract.
SHOULD NOTDo not nest it in another scroll container; use maxHeight.Not stated in the contract.

Install and import

  • Install: npm install @digitaltableteur/react (version 0.9.1, restricted access on npm).
  • Import: import { CodeBlock } from "@digitaltableteur/react";
  • Entry point: @digitaltableteur/react/content exports it too.
  • Styles: import @digitaltableteur/react/style.css once at the app boundary.
  • Also available as the custom element <dt-code-block>; see the custom elements manifest.