Table
Tables that stay readable at any width: two-way scroll under a sticky header, copy as Markdown, CSV or TSV, and an expanded view.
On this page
A wide comparison that scrolls sideways, with copy and expand.
Installation
Usage
import { Table } from "@/components/ui/chatcn/table"
<Table caption="Endpoint latency">
<thead>…</thead>
<tbody>…</tbody>
</Table>
<Table data={{ headers: ["Route", "p50"], rows: [["/api/runs", "96 ms"]] }} />Children are any thead and tbody, so Markdown tables and your own JSX look the same. Copy reads the rendered cells, so formatted content exports as text.
Examples
Long table
The body scrolls under a sticky header.
Props
| Prop | Type | Notes |
|---|---|---|
children | ReactNode | thead and tbody |
data | { headers, rows } | Or plain data |
caption | string | Region label and expanded view title |
maxHeight | number | string | Default 400 px |
hideActions | boolean | No copy or expand |
onCopy | (format, text) => void | markdown, csv or tsv |
Keyboard
| Key | Action |
|---|---|
Tab | Focus the table to scroll it, then Copy and Expand |
Arrow keys | Scroll the focused table, or move through the copy menu |
Esc | Close the menu or the expanded view |
Accessibility
- The scroll container is a labeled region. Headers stay real
thcells. - Actions are always visible on touch; with a mouse they appear on hover or focus, so keyboard users always reach them.
Motion
- Actions appear instantly. The copy menu grows from its trigger in 180 ms and does not animate when opened from the keyboard.
- The expanded view uses the Dialog motion: 220 ms in, 160 ms out.