Build · New

Table

Rows of records people compare and act on: transactions, orders, users. A real table with column headers and cells.

Preview

Mirrored is the same English content laid out right to left: it separates a mirroring bug from a translation one.

Installation

SoonInstalling from the registry opens at launch. Until then the command below is what it will be.
npx shadcn@latest add @ritla/table

Dependencies it brings: @phosphor-icons/react

Usage

import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
<Table>
  <TableHeader variant="gray">
    <TableRow>
      <TableHead sort="descending" onSort={toggle}>Date</TableHead>
      <TableHead align="end">Amount</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>12/09/2026</TableCell>
      <TableCell numeric>+2,450.00 JOD</TableCell>
    </TableRow>
  </TableBody>
</Table>

Examples

Row selection

A checkbox in the first column (CheckboxBox with a name), an avatar and a subtitle in the cell; a checked row keeps its fill.

White header and info

variant="white" (the default), a leading icon, an info tooltip, and no column dividers (dividers={false}).

API reference

Table

PropTypeDefaultDescription
dividersbooleantrueFigma's Show divider: a line at each column's end.
aria-label / TableCaptionstring / ReactNodeThe table's name for screen readers.

TableHeader

PropTypeDefaultDescription
variant"white" | "gray""white"Figma's Color on Table header cell.

TableRow

PropTypeDefaultDescription
selectedbooleanfalseFigma's State = Hover/selected, kept on for a checked row.

TableHead

PropTypeDefaultDescription
childrenReactNodeFigma's Label.
sort"none" | "ascending" | "descending"A sortable column and its state; leave it out on the rest.
onSort / sortHref() => void / stringA sort button (client code) or a link (server pages).
leadingIconIconComponentFigma's Leading icon.
infoReactNodeFigma's Show tooltip: an info tooltip after the label.
align"start" | "end""start"end for numeric columns.

TableCell

PropTypeDefaultDescription
childrenReactNodeFigma's Cell Title.
subtitleReactNodeFigma's Cell Subtitle.
leading / trailingReactNodeBefore and after the text: an avatar, icon, tag, checkbox…
numericbooleanfalseAn amount or count: at the column's end, in tabular figures, left to right.

Accessibility

Keyboard

Keys are written for left-to-right. In right-to-left the arrow keys swap: the one pointing toward the reading direction moves forward.

KeyAction
TabReaches the sort buttons and the controls inside cells only.
EnterSpaceSorts the column.

ARIA

  • A real table: table, th scope="col" and td, so screen readers pair each cell with its header.
  • A sortable column is a button inside a th that carries aria-sort.
  • Selection checkboxes have names ("Select all", the row's name).

Arabic and RTL notes

Mirrors

  • The first column sits on the right, text at the cell's start (its right), the divider at its end (its left).
  • Numeric columns sit at the cell's end (its left in Arabic).

Does not mirror

  • Amounts stay left to right, so the sign stays next to the number.
  • Emails and IDs in <bdi dir="ltr">.
Numerals
Dates and amounts in the chosen numerals; one format per column.
Arabic typography
body-12 Semibold headers, body-14 Medium cells, body-12 subtitles.
Mixed-direction text
Don't mix LTR and RTL cells in one table: the direction comes from the page.

All components ›