Code Block

Code is content you look into, so the block is a debossed well with the copy key embossed in its header. Syntax highlighting resolves asynchronously — until it does, the raw text renders, so a streaming fence is never blank and never breaks.

tsx
import { Button } from "@/components/ui/button"

export function Save() {
  return <Button variant="secondary">Save changes</Button>
}
tsx
import { CodeBlock } from "@/registry/seam/ui/code-block"

const CODE = `import { Button } from "@/components/ui/button"

export function Save() {
  return <Button variant="secondary">Save changes</Button>
}`

export default function CodeBlockDemo() {
  return (
    <div className="w-full max-w-md">
      <CodeBlock code={CODE} language="tsx" />
    </div>
  )
}
bunx --bun @seamui/cli@latest add code-block

Notes

  • Highlighting uses Shiki in dual-theme mode, so the same markup adapts to light and dark without shipping a second payload. Pass showHeader={false} for a bare block.
  • No entrance of its own — it enters with its parent message. The only motion is the copy confirmation, an opacity crossfade to a check and back, so it's identical under reduced motion; press feedback on the copy key is inherited from Button.
  • The copy key's aria-label flips to “Copied” on success; copy falls back to a silent no-op in insecure contexts where the clipboard API is unavailable.
  • The scrollable code region is keyboard-focusable, so a wide block can be scrolled without a mouse.

Press feedback, reduced motion, and haptics follow the global policy — see Motion and Haptics.