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.
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 initAPI Reference
CodeBlock
- 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.