Data Display/Table

Table

A responsive table component.

Themed

When to Use

Use Table when you need to:

  • Display structured data in rows and columns (invoices, users, products)
  • Show comparison data where users scan across multiple attributes
  • Present tabular data with optional footer summaries or totals
  • Render read-only data sets that benefit from aligned columns
  • Build the presentation layer for more complex data table features

When Not to Use

  • Sortable, filterable, or paginated data - use Data Table with TanStack Table
  • Key-value pair display - use a description list or Card layout
  • Page layout purposes - use CSS Grid or Flexbox instead of table elements
  • Single-column lists - use a standard list or Item component

Invoice Table

Full-featured table with header, body, footer, and caption.

A list of your recent invoices.
InvoiceStatusMethodAmount
INV001PaidCredit Card$250.00
INV002PendingPayPal$150.00
INV003UnpaidBank Transfer$350.00
INV004PaidCredit Card$450.00
INV005PaidPayPal$550.00
INV006PendingBank Transfer$200.00
INV007UnpaidCredit Card$300.00
Total$2,250.00

Simple

Basic table with header and body rows.

NameEmailRole
John Doejohn@example.comAdmin
Jane Smithjane@example.comEditor
Bob Wilsonbob@example.comViewer

With Status Badges

Table displaying status and priority using Badge components.

TaskStatusPriorityDue Date
Design reviewCompletedHigh2024-01-15
Code implementationIn ProgressMedium2024-01-20
DocumentationPendingLow2024-01-25

Striped Rows

Alternating row backgrounds for improved readability using bg-muted/50.

ProductCategoryStockPrice
Laptop ProElectronics45$1,299.00
Wireless MouseAccessories120$49.99
USB-C HubAccessories78$89.99
Monitor 27"Electronics32$449.00
KeyboardAccessories95$129.00

With Actions

Table rows with dropdown action menus for contextual operations.

CustomerEmailStatusActions
Alice Johnsonalice@example.comActive
Michael Chenmichael@example.comPending
Sarah Davissarah@example.comInactive

UX & Design Guidelines

Visual Hierarchy

Use TableHead with font-medium to clearly distinguish headers from data rows. Apply text-right to numeric columns (amounts, quantities) for easier scanning. Use font-medium on the primary identifier cell in each row (e.g., invoice number, name).

Spacing & Layout

Table cells use p-2 padding by default. Set explicit widths on header cells (className="w-[100px]") to prevent column shifting during data updates. The table container provides overflow-x-auto for horizontal scrolling on smaller viewports. Wrap the table in a rounded-lg border border-border container for a polished appearance.

Responsive Behavior

The Table component automatically enables horizontal scrolling when content overflows. On mobile, consider hiding less critical columns with className="hidden md:table-cell". For narrow screens, evaluate whether a list-based layout (using Card) would provide a better reading experience.

Color & Contrast

Row hover state uses hover:bg-muted/50 for subtle feedback. Selected rows use data-[state=selected]:bg-muted for clear visual indication. The footer uses bg-muted/50 to visually separate summary rows from data. Ensure all text content meets WCAG 2.1 AA contrast ratios against both default and striped row backgrounds.

Accessibility

Keyboard Navigation

  • Tab — Move focus to the next interactive element within the table (links, buttons, checkboxes)
  • Shift + Tab — Move focus to the previous interactive element
  • Enter or Space — Activate focused buttons or checkboxes within cells
  • Arrow Keys — Navigate within dropdown menus triggered from action cells

Screen Reader Support

  • Use TableCaption to provide a descriptive summary of the table content
  • Add scope="col" on column headers and scope="row" on row headers for complex tables
  • Screen readers announce the table structure (rows and columns) and navigate cell-by-cell
  • Avoid using aria-hidden on cells that contain meaningful data

Sortable Columns

  • Use aria-sort="ascending" or aria-sort="descending" on sortable column headers
  • Provide a visual sort indicator (arrow icon) that matches the aria-sort value
  • Announce sort changes to assistive technology using an aria-live region

Selection States

When rows are selectable, use role="checkbox" with aria-checked on selection controls. The data-state="selected" attribute provides visual feedback while the checkbox communicates state to assistive technology. Use a "Select all" checkbox in the header with aria-label="Select all rows".

ARIA Attributes

{/* Always provide a caption for screen readers */}
<Table>
  <TableCaption>Monthly revenue by product line.</TableCaption>
  <TableHeader>
    <TableRow>
      <TableHead scope="col">Product</TableHead>
      <TableHead scope="col">Revenue</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>...</TableBody>
</Table>

{/* Sortable column headers */}
<TableHead
  scope="col"
  aria-sort={sortDir === "asc" ? "ascending" : "descending"}
>
  <Button variant="ghost" onClick={toggleSort}>
    Name <ArrowUpDown className="ml-2 size-4" />
  </Button>
</TableHead>

{/* Row headers for two-dimensional data */}
<TableRow>
  <TableHead scope="row">Q1 2024</TableHead>
  <TableCell>$12,400</TableCell>
  <TableCell>$9,800</TableCell>
</TableRow>

API Reference

The Table component is composed of eight sub-components. Each accepts standard HTML attributes in addition to the props listed below.

Table

The root container, wrapped in a scrollable div for responsive overflow.

PropTypeDefaultDescription
classNamestringAdditional CSS classes for the table element.
childrenReactNodeTable content (TableHeader, TableBody, TableFooter, TableCaption).

TableHeader

The thead element. Child rows receive a bottom border.

PropTypeDefaultDescription
classNamestringAdditional CSS classes for the thead element.

TableBody

The tbody element. The last row's bottom border is removed.

PropTypeDefaultDescription
classNamestringAdditional CSS classes for the tbody element.

TableFooter

The tfoot element with a muted background and top border for summary rows.

PropTypeDefaultDescription
classNamestringAdditional CSS classes for the tfoot element. Renders with a muted background.

TableRow

A table row with hover and selected state styling.

PropTypeDefaultDescription
classNamestringAdditional CSS classes for the row.
data-state"selected"When set to 'selected', applies highlighted row styles via bg-muted.

TableHead

A header cell (th) with medium font weight and left alignment.

PropTypeDefaultDescription
classNamestringAdditional CSS classes for the header cell.
scope"col" | "row"Specifies whether the header is for a column or row (improves accessibility).

TableCell

A standard data cell (td) with consistent padding and alignment.

PropTypeDefaultDescription
classNamestringAdditional CSS classes for the cell.
colSpannumber1Number of columns the cell should span.

TableCaption

A caption element rendered below the table for descriptive context.

PropTypeDefaultDescription
classNamestringAdditional CSS classes for the caption element.
childrenReactNodeDescriptive text for the table, rendered below the table body.