---
id: "packages/active-ui/code-block"
title: "CodeBlock"
description: "A block of code with a title, a copy button, line numbers, wrapping and marked lines, highlighted with the package's highlighter."
url: "/packages/active-ui/code-block"
locale: "en"
revision: "e223e35e9f1c8940"
---

# CodeBlock

`CodeBlock` 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 `highlightCode` or in the
browser with [`useHighlightedCode`](/packages/active-ui/hooks) (see [Utilities](/packages/active-ui/utilities)). Every code
sample on this site is a `CodeBlock`. For a name in running text, use [Code](/packages/active-ui/code).

**Example: Highlighted with line numbers, and a change**

Client: Runs entirely in your browser. Source: `examples/ui/code-block.tsx`.

```tsx
// 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

```tsx
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

- `CodeBlock`: the frame. `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) or
  `destructive` (for code that shows an error). `size`: `default` or `sm`. `flush` drops the
  border and radius, for a block inside a frame that has its own.
- `CodeBlockHeader` with `CodeBlockTitle` and `CodeBlockActions`; `CodeBlockFooter` below.
- `CodeBlockCopyButton`: copies `value` to the clipboard and announces it.
- `CodeBlockContent`: the `<pre>`. `lineNumbers` (with `startLine`), and `wrap` to wrap long lines
  instead of scrolling. A plain string child is split into lines when numbered.
- `CodeBlockLine`: one line. `variant`: `added` (with a `+`), `removed` (with a `−`) or
  `highlighted`. 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.
- `label` and `copiedLabel` of the copy button: its accessible name before and after copying
  (required).
- The title, such as the file name.

## Accessibility and keyboard

- The `<pre>` takes focus (`tabIndex={0}`), so a reader can scroll long lines with the keyboard.
- 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

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `flush` | `boolean` | no | Without border and radius, inside a frame that has its own. |
| `size` | `"default" \| "sm"` | no | The text size and padding: `default`, or `sm`. |
| `variant` | `"default" \| "destructive" \| "muted" \| null` | no | `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. |

### CodeBlockContent

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `lineNumbers` | `boolean` | no | Numbers the lines; a plain string child is split into lines for it. |
| `startLine` | `number` | no | The number of the first line, with `lineNumbers`. |
| `wrap` | `boolean` | no | Wraps long lines instead of scrolling them sideways. |

### Other parts

**CodeBlockHeader**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

CodeBlockHeader has no props of its own.

**CodeBlockTitle**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

CodeBlockTitle has no props of its own.

**CodeBlockActions**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

CodeBlockActions has no props of its own.

**CodeBlockCopyButton**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `copiedLabel` | `string` | yes | Accessible name after copying, also announced politely, e.g. "Copied". |
| `label` | `string` | yes | Accessible name of the button before copying, e.g. "Copy code". |
| `value` | `string \| (readonly string[] & string)` | yes |  |
| `size` | `"default" \| "icon" \| "icon-lg" \| "icon-sm" \| "icon-xs" \| "lg" \| "sm" \| "xs" \| null` | no | The height and padding. `xs`, `sm`, `default` and `lg` for a button with text; `icon-xs`, `icon-sm`, `icon` and `icon-lg` for a square button with only an icon, which then needs an accessible name (`aria-label`). |
| `variant` | `"default" \| "destructive" \| "ghost" \| "link" \| "outline" \| "secondary" \| null` | no | The visual weight of the button. `default` for the main action of a screen or form; `outline` and `secondary` for other actions; `ghost` for a quiet action in a toolbar or a list; `destructive` for an action that deletes or cannot be undone; `link` for an action that reads as a link. Every variant but `link` sinks 1px while pressed; a link-styled action keeps its text and icon in place (`button-link-still`). |
| `focusableWhenDisabled` | `boolean` | no | Whether the button should be focusable when disabled. |
| `nativeButton` | `boolean` | no | Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`). |
| `render` | `ComponentRenderFn<HTMLProps, ButtonState> \| ReactElement<unknown, string \| JSXElementConstructor<any>>` | no | Allows you to replace the component's HTML element with a different tag, or compose it with another component.  Accepts a `ReactElement` or a function that returns the element to render. |

**CodeBlockLine**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `variant` | `"added" \| "default" \| "highlighted" \| "removed" \| null` | no | Marks the line: `added` (with a `+`), `removed` (with a `−`) or `highlighted`. |

**CodeBlockFooter**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

CodeBlockFooter has no props of its own.
