Make your AI a shadcn expert

Shadcn Table

React table for invoices, orders, and static reports. Built with TypeScript and Tailwind CSS for Next.js using Base UI — caption, header, body, and footer.

The shadcn table is a styled HTML table: caption, header, body, footer. Rows hover, and the wrapper scrolls sideways when the columns do not fit. Use it for invoices, orders, and any static list where the columns should line up.

Scroll to load preview...

Looking for a neobrutalism version for shadcn?

Same table, thicker borders. The NeoBrutalism table is the kit if you want that look.

Usage

import {
  Table,
  TableBody,
  TableCaption,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"
<Table>
  <TableCaption>A list of your recent invoices.</TableCaption>
  <TableHeader>
    <TableRow>
      <TableHead className="w-[100px]">Invoice</TableHead>
      <TableHead>Status</TableHead>
      <TableHead>Method</TableHead>
      <TableHead className="text-right">Amount</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell className="font-medium">INV001</TableCell>
      <TableCell>Paid</TableCell>
      <TableCell>Credit Card</TableCell>
      <TableCell className="text-right">$250.00</TableCell>
    </TableRow>
  </TableBody>
</Table>

TableCaption is the accessible name. caption-bottom puts it under the rows.

Composition

TableCaption
TableHead
TableCell

TableFooter is the totals row. colSpan on the label walks it across the empty cells.

Scroll to load preview...

Actions

A Dropdown Menu in the last cell. Icon trigger, sr-only name.

Scroll to load preview...

RTL

Wrap with DirectionProvider and dir="rtl". Use text-end on amounts so they stay on the reading end.

Scroll to load preview...

API

Prop

Type

TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell, and TableCaption take className and the native attributes for that element. data-state="selected" on TableRow paints the muted background.

Notes

The scroller is the wrapper

Table renders a div with overflow-x-auto around the <table>. className lands on the table. Sticky headers stick inside that wrapper, not the page.

Cells are whitespace-nowrap. Long text scrolls sideways instead of wrapping.

With other components

Questions

Was this page helpful?

Sign in to leave feedback.