AI chat
Chat code block
A fenced code block with a copy button, built on `Code`.
Import
import { ChatCodeBlock } from '@the_viveksingh/vivek-ui'Code in a reply
Copy state is announced, not just shown. highlight takes your own highlighter, so no syntax-highlighting library is bundled into the package.
import { Button, ToastProvider, useToast } from '@the_viveksingh/vivek-ui'
function Save() {
const { toast } = useToast()
return <Button onClick={() => toast({ title: 'Saved' })}>Save</Button>
}<ChatCodeBlock
filename="save-button.tsx"
language="tsx"
code={snippet}
onCopy={(code) => track('copied', code.length)}
/>Wrapping long lines
wrap suits a shell command, where horizontal scrolling hides the end of it.
npm install @the_viveksingh/vivek-ui && echo 'now import @the_viveksingh/vivek-ui/styles.css once, at the root of your app'<ChatCodeBlock language="bash" wrap code="npm install @the_viveksingh/vivek-ui" />Props
Generated from the package's own type declarations, so this table cannot drift from the code.
| Prop | Type | Default | Description |
|---|---|---|---|
code | string | — | The source. Rendered as text, never as markup. |
language | string | — | Language tag shown in the header, and passed to `highlight`. |
filename | string | — | Shown in the header, and used as the code region's accessible name. |
copy | boolean | — | Show the copy button. Defaults to `true`. |
copyLabel | string | — | Accessible name of the copy button. Stable - it does not change on success. |
copiedLabel | string | — | Announced, and shown on the button, after a successful copy. |
copyErrorLabel | string | — | Announced when the clipboard write fails or is unavailable. |
onCopy | (code: string) => void | — | Called with the source after a successful copy. |
highlight | ChatCodeBlockHighlighter | — | Plug your own highlighter in. Without it the source renders as plain text. |
wrap | boolean | — | Soft-wrap long lines instead of scrolling horizontally. |
feedbackDuration | number | — | How long the copied/error state sticks, in ms. Defaults to 2000. |
Every remaining prop is spread onto the root element, so all standard HTML and ARIA attributes work. className and style are merged with the library's own, never replaced, and the ref forwards to the root DOM node.
Rendering
ChatCodeBlock declares 'use client' because it needs state, effects or event handlers. Importing it into a Server Component creates a client boundary at this component — everything above it stays on the server.