Docs
Table

Table

A responsive table component for basic data.

Table presents basic tabular data presentation within a Card.

Loading...
import {
  Card,
  Table,
  TableBody,
  TableCaption,
  TableCell,
  TableFooter,
  TableHead,
  TableHeader,
  TableRow,
} from 'ui'
 
const invoices = [
  {
    invoice: 'INV001',
    paymentStatus: 'Paid',
    totalAmount: '$250.00',
    paymentMethod: 'Credit card',
    description: 'Website design services',
  },
  {
    invoice: 'INV002',
    paymentStatus: 'Pending',
    totalAmount: '$150.00',
    paymentMethod: 'PayPal',
    description: 'Monthly subscription fee',
  },
  {
    invoice: 'INV003',
    paymentStatus: 'Unpaid',
    totalAmount: '$350.00',
    paymentMethod: 'Bank transfer',
    description: 'Consulting hours',
  },
  {
    invoice: 'INV004',
    paymentStatus: 'Paid',
    totalAmount: '$450.00',
    paymentMethod: 'Credit card',
    description: 'Software license renewal',
  },
  {
    invoice: 'INV005',
    paymentStatus: 'Paid',
    totalAmount: '$550.00',
    paymentMethod: 'PayPal',
    description: 'Custom development work',
  },
  {
    invoice: 'INV006',
    paymentStatus: 'Pending',
    totalAmount: '$200.00',
    paymentMethod: 'Bank transfer',
    description: 'Hosting and maintenance',
  },
  {
    invoice: 'INV007',
    paymentStatus: 'Unpaid',
    totalAmount: '$300.00',
    paymentMethod: 'Credit card',
    description: 'Training session package',
  },
]
 
export function TableDemo() {
  return (
    <Card className="w-full pb-4">
      <Table>
        <TableCaption>A list of your recent invoices</TableCaption>
        <TableHeader>
          <TableRow>
            <TableHead>Invoice</TableHead>
            <TableHead>Status</TableHead>
            <TableHead>Method</TableHead>
            <TableHead className="hidden md:table-cell">Description</TableHead>
            <TableHead className="text-right">Amount</TableHead>
          </TableRow>
        </TableHeader>
        <TableBody>
          {invoices.map((invoice) => (
            <TableRow key={invoice.invoice}>
              <TableCell className="text-foreground">{invoice.invoice}</TableCell>
              <TableCell className="text-foreground-lighter">{invoice.paymentStatus}</TableCell>
              <TableCell className="text-foreground-lighter">{invoice.paymentMethod}</TableCell>
              <TableCell className="hidden md:table-cell text-foreground-muted">
                {invoice.description}
              </TableCell>
              <TableCell className="text-right">{invoice.totalAmount}</TableCell>
            </TableRow>
          ))}
        </TableBody>
        <TableFooter className="border-t">
          <TableRow>
            <TableCell colSpan={4}>Total</TableCell>
            <TableCell className="text-right">$2,250.00</TableCell>
          </TableRow>
        </TableFooter>
      </Table>
    </Card>
  )
}

Columns will naturally take the width of their content. Width specification is therefore not required unless you require columns to span a specific width. An example use-case may be when placing multiple Table instances on the one page, where columns on each table should optically align.

TableHead includes a whitespace-nowrap utility class to prevent its text from wrapping. TableCell must have any custom width specified, as there are legitimate use cases for both wrapping (or truncated) text.

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>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>

Sortable Columns

Use TableHeadSort inside TableHead to enable column sorting.

PropTypeDescription
columnstringUnique identifier for the column
currentSortstringCurrent sort state in format "column:order" (e.g., "name:asc")
onSortChange(column: string) => voidCallback fired when column header is clicked
<TableHead>
  <TableHeadSort column="name" currentSort={sort} onSortChange={handleSortChange}>
    Name
  </TableHeadSort>
</TableHead>

Data Table

You can use the <Table /> component to build more complex data tables. Combine it with @tanstack/react-table to create tables with sorting, filtering and pagination.

See the Data Table documentation for more information.

You can also see an example of a data table in the Tasks demo.