Code Block

Highlighted code on a field panel, with a title bar and a copy button.

debounce.ts
export function debounce(fn, wait) {  let timer;  return (...args) => {    clearTimeout(timer);    timer = setTimeout(() => fn(...args), wait);  };}

Installation

Copy the source into components/ui/code-block.tsx. Registry items that depend on it install it automatically.

components/ui/code-block.tsx

Usage

The component is the chrome; pass it a pre element, highlighted or plain. In MDX every fenced code block on this site renders through it.

import { CodeBlock } from "@/components/ui/code-block";

export function Example() {
  return (
    <CodeBlock title="example.ts">
      <pre>
        <code>{'const answer = 42;'}</code>
      </pre>
    </CodeBlock>
  );
}

Examples

Collapse long code

Set maxCollapsedLines to keep a long block compact. It measures the rendered line height after mount, so the initial viewport holds that many complete lines, then offers the full source without changing what the copy button copies.

<CodeBlock maxCollapsedLines={12} title="generated.ts">
  <pre>
    <code>{source}</code>
  </pre>
</CodeBlock>

The toggle appears only when the rendered code has more than the requested number of lines.

Without a title

When there is no header, the copy button floats in the corner and appears on hover.

npx assistant-ui init

API Reference

CodeBlock

CodeBlockProps
title?ReactNode

Header label, usually the file name. Without it the copy button floats in the corner.

viewportClassName?string

Classes for the scrollable code region, e.g. a max height.

copyText?string

Text for the copy button; defaults to the rendered code's text.

onCopied?() => void

Called after the copy button writes the clipboard.

lineNumbers?boolean

Numbers the lines when the pre does not carry data-line-numbers itself.

maxCollapsedLines?number

Positive line limit before the viewport collapses. The full code remains available to the copy button.

className?string

Additional CSS classes on the outer figure.

Lines marked .highlighted by the highlighter get the blue gutter bar, and data-line-numbers on the pre turns on the counter gutter. In dark mode each token falls back to its --shiki-dark variable.