Agent Code Block

Displays code from an agent, including code still streaming in.

lib/trips.tstypescript

Installation

pnpm dlx shadcn@latest add @paneui/agent-code-block

Usage

Examples

Without Header

Excerpt

Without Line Numbers

Turn line numbers off for shell commands and short snippets.

Wrap

Not Copyable

Turn copying off for read-only output that shouldn't be pasted back.

Copy Button

Scrollbars

The code area scrolls in a Scroll Area on both axes, below the header and inside the rounded frame.

Streaming

While streaming, the block follows the newest line unless the reader scrolls away, and keeps already-coloured tokens so lines never flash back to plain text.

Motion

The copy-to-check swap cross-fades without scaling under reduced motion, and the streaming follow jumps instead of smooth-scrolling.

API Reference

AgentCodeBlock

Syntax-highlighted code surface (light and dark themes) for agent output. Also accepts every prop of div.

code*
string
Source text.
language
string
Syntax language id. Inferred from filename when omitted; unknown ids render as plain text.
filename
ReactNode
Shown in a header with the language chip and copy button. Without it the copy button floats.
showLineNumbers= true
boolean
Show the sticky line-number gutter.
startLine= 1
number
First line number, for excerpts.
highlightLines
(number | [start: number, end: number])[]
Line numbers or [start, end] ranges, as displayed, to emphasise.
streaming= false
boolean
Show a live caret and Writing badge and follow the newest line.
maxHeight= 360
number
Max height of the scrolling code area in px.
copyable= true
boolean
Show the copy button.
wrap= false
boolean
Wrap long lines instead of scrolling horizontally.
PropTypeDefaultDescription
code*string—Source text.
languagestring—Syntax language id. Inferred from filename when omitted; unknown ids render as plain text.
filenameReactNode—Shown in a header with the language chip and copy button. Without it the copy button floats.
showLineNumbersbooleantrueShow the sticky line-number gutter.
startLinenumber1First line number, for excerpts.
highlightLines(number | [start: number, end: number])[]—Line numbers or [start, end] ranges, as displayed, to emphasise.
streamingbooleanfalseShow a live caret and Writing badge and follow the newest line.
maxHeightnumber360Max height of the scrolling code area in px.
copyablebooleantrueShow the copy button.
wrapbooleanfalseWrap long lines instead of scrolling horizontally.
data-streaming
On the root while streaming.
data-line
On each line, its displayed number.
data-highlighted
On lines listed in highlightLines.
Data attributeDescription
data-streamingOn the root while streaming.
data-lineOn each line, its displayed number.
data-highlightedOn lines listed in highlightLines.

CodeCopyButton

Round icon button that copies and swaps to a check. Also accepts every prop of button.

value*
string | (() => string)
Text to copy, or a function returning it at click time.
label= "Copy code"
string
Accessible label before copying.
className
string
Merged onto the button.
PropTypeDefaultDescription
value*string | (() => string)—Text to copy, or a function returning it at click time.
labelstring"Copy code"Accessible label before copying.
classNamestring—Merged onto the button.
data-copied
Present for 1.6s after a successful copy.
Data attributeDescription
data-copiedPresent for 1.6s after a successful copy.

useCodeTokens

(code: string, language: string) => CodeToken[][] | null. Tokenises with light and dark colours; null until the first pass.

CodeLine

Renders one line from (possibly stale) tokens.

text*
string
The line's text.
tokens
CodeToken[]
Tokens for that line from useCodeTokens.
PropTypeDefaultDescription
text*string—The line's text.
tokensCodeToken[]—Tokens for that line from useCodeTokens.

useCopy

(timeout = 1600) => { copied: boolean; copy: (text: string) => Promise<void> }.

languageFromFilename

(filename?: string, fallback = "text") => string. Maps an extension like .tsx to a language id.