Components

Code Block

new

A code panel with tabs, line numbers, highlighted lines and a copy button.

pnpm dlx shadcn@latest add @blank/code-block

Installation

npx shadcn@latest add @blank/code-block

Usage

import {
  CodeBlock,
  CodeBlockCode,
  CodeBlockCopy,
  CodeBlockHeader,
  CodeBlockTitle,
} from "@/components/ui/code-block"
<CodeBlock>
  <CodeBlockHeader>
    <CodeBlockTitle>button.tsx</CodeBlockTitle>
    <CodeBlockCopy />
  </CodeBlockHeader>
  <CodeBlockCode code={source} language="tsx" />
</CodeBlock>

The root is a tabs root, so the same parts cover one snippet or several: add a CodeBlockList of CodeBlockTriggers and wrap each snippet in a CodeBlockContent. One CodeBlockCopy serves every tab — it copies whichever code is on screen. It is a CopyButton, so it takes the same props and confirms a copy the same way.

The built-in highlighter knows JS, TS, JSX, shell and JSON, and adds nothing to your bundle beyond a few regular expressions. Its colors are CSS variables (--code-keyword, --code-string, --code-number, --code-function, --code-comment). By default they are one ink at three strengths, so code reads in the same monochrome as the rest of the page; set them on any ancestor to bring color back. For other languages, render Shiki or Prism output as the children of CodeBlockCode instead of passing code.

Examples

File with highlighted lines

save-button.tsx
import { Button } from "@/components/ui/button"import { Spinner } from "@/components/ui/spinner"export function SaveButton({ pending }: { pending: boolean }) {  return (    <Button disabled={pending} aria-busy={pending}>      {pending ? <Spinner /> : null}      Save changes    </Button>  )}