Skip to content
ContentTableMenu

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.

A wide comparison that scrolls sideways, with copy and expand.

Installation

$ pnpm dlx shadcn@latest add https://chatcn.dev/r/table.json

Usage

tsx
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

PropTypeNotes
childrenReactNodethead and tbody
data{ headers, rows }Or plain data
captionstringRegion label and expanded view title
maxHeightnumber | stringDefault 400 px
hideActionsbooleanNo copy or expand
onCopy(format, text) => voidmarkdown, csv or tsv

Keyboard

KeyAction
TabFocus the table to scroll it, then Copy and Expand
Arrow keysScroll the focused table, or move through the copy menu
EscClose the menu or the expanded view

Accessibility

  • The scroll container is a labeled region. Headers stay real th cells.
  • 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.