CodeBlock
A block of code with a title, a copy button, line numbers, wrapping and marked lines, highlighted with the package's highlighter.
Code shows code on a surface of its own: with a title and actions in a header, optional line
numbers, lines marked as added, removed or highlighted, and wrapping. It does not highlight by
itself: pass it lines from the package's highlighter, on the server with highlight or in the
browser with use (see Utilities). Every code
sample on this site is a Code. For a name in running text, use Code.
import {formatCurrency} from '@workspace/active-format';
const total = formatCurrency({amount: 1234.5, currency: 'EUR'}, 'en');// "€1,234.50"const scheme = { rate: 0.07, rate: 0.075, effectiveFrom: "2027-01-01",};// apps/docs/examples/ui/code-block.tsx'use client';
import { CodeBlock, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockHeader, CodeBlockLine, CodeBlockTitle,} from '@workspace/active-ui/components/primitives/code-block';import {useHighlightedCode} from '@workspace/active-ui/hooks/use-highlighted-code';
const SOURCE = `import {formatCurrency} from '@workspace/active-format';
const total = formatCurrency({amount: 1234.5, currency: 'EUR'}, 'en');// "€1,234.50"`;
/** * Code with a title, a copy button and line numbers, highlighted in the * browser by `useHighlightedCode`; and a change shown line by line, with * added and removed lines marked. */export default function CodeBlockExample() { const lines = useHighlightedCode(SOURCE, 'ts'); return ( <div className="flex w-full max-w-xl flex-col gap-6"> <CodeBlock variant="muted"> <CodeBlockHeader> <CodeBlockTitle>format.ts</CodeBlockTitle> <CodeBlockActions> <CodeBlockCopyButton value={SOURCE} label="Copy code" copiedLabel="Copied" /> </CodeBlockActions> </CodeBlockHeader> <CodeBlockContent lineNumbers> {lines.map((line, index) => ( <CodeBlockLine key={index}>{line}</CodeBlockLine> ))} </CodeBlockContent> </CodeBlock>
<CodeBlock variant="muted" size="sm"> <CodeBlockHeader> <CodeBlockTitle>Contribution rate</CodeBlockTitle> </CodeBlockHeader> <CodeBlockContent wrap> <CodeBlockLine>{'const scheme = {'}</CodeBlockLine> <CodeBlockLine variant="removed">{' rate: 0.07,'}</CodeBlockLine> <CodeBlockLine variant="added">{' rate: 0.075,'}</CodeBlockLine> <CodeBlockLine variant="highlighted"> {' effectiveFrom: "2027-01-01",'} </CodeBlockLine> <CodeBlockLine>{'};'}</CodeBlockLine> </CodeBlockContent> </CodeBlock> </div> );}Usage#
import { CodeBlock, CodeBlockContent, CodeBlockLine,} from '@workspace/active-ui/components/primitives/code-block';import {useHighlightedCode} from '@workspace/active-ui/hooks/use-highlighted-code';
const lines = useHighlightedCode(source, 'ts');
<CodeBlock variant="muted"> <CodeBlockContent lineNumbers> {lines.map((line, index) => ( <CodeBlockLine key={index}>{line}</CodeBlockLine> ))} </CodeBlockContent></CodeBlock>;Anatomy#
Code: the frame.Block variant:default(no fill of its own),muted(a fill of its own in light and dark, which keeps the highlighter's colours at AA wherever the block sits) ordestructive(for code that shows an error).size:defaultorsm.flushdrops the border and radius, for a block inside a frame that has its own.CodewithBlock Header CodeandBlock Title Code;Block Actions Codebelow.Block Footer Code: copiesBlock Copy Button valueto the clipboard and announces it.Code: theBlock Content <pre>.line(withNumbers start), andLine wrapto wrap long lines instead of scrolling. A plain string child is split into lines when numbered.Code: one line.Block Line variant:added(with a+),removed(with a−) orhighlighted. An empty line keeps a newline, so a copied selection keeps its blank lines.
What your application provides#
The lines, highlighted or plain, and the language for the highlighter.
labelandcopiedof the copy button: its accessible name before and after copying (required).Label The title, such as the file name.
Accessibility and keyboard#
The
<pre>takes focus (tab), so a reader can scroll long lines with the keyboard.Index={0} The copy button announces the copy through a polite live region.
Code is always left to right (
dir="ltr"), also on a right-to-left page.Marked lines show their meaning as a sign (
+,−) and a colour, not as a colour alone.
API#
CodeBlock#
Import from @workspace/
Props
- Type
boolean- Default
false
Without border and radius, inside a frame that has its own.
- Type
"default""sm"- Default
'default'
The text size and padding: default, or sm.
- Type
"default""destructive""muted"null- Default
'default'
default has no fill of its own; muted a fixed fill that keeps the highlighter's colours at AA wherever the block sits; destructive a red frame for code that shows an error.
Other props, such as the standard attributes of the underlying element, className and ref, are passed through.
CodeBlockContent#
Import from @workspace/
Props
- Type
boolean- Default
false
Numbers the lines; a plain string child is split into lines for it.
- Type
number- Default
1
The number of the first line, with line.
- Type
boolean- Default
false
Wraps long lines instead of scrolling them sideways.
Other props, such as the standard attributes of the underlying element, className and ref, are passed through.
Other parts#
CodeBlockCopyButton
Props marked Base UI are behaviour of the Base UI part this component is built on.
Props
Other props, such as the standard attributes of the underlying element, className and ref, are passed through.
CodeBlockLine
Props
- Type
"added""default""highlighted""removed"null- Default
'default'
Marks the line: added (with a +), removed (with a −) or highlighted.
Other props, such as the standard attributes of the underlying element, className and ref, are passed through.
Parts that take only their element’s attributes
Code: the attributes of aBlock Header <div>, with className and ref.Code: the attributes of aBlock Title <div>, with className and ref.Code: the attributes of aBlock Actions <div>, with className and ref.