Table

Table

Markdown

Native table primitives for structured data, sorting, selection, density, and responsive overflow.

Use Table for data whose row and column relationships are meaningful. Use layout primitives rather than a table when content does not have tabular semantics.

Default

RoleStatusUpdated
Ada LovelaceOwnerActive2m ago
Alan TuringAdminActive12m ago
Grace HopperMemberInvited1h ago
Katherine JohnsonMemberActive3h ago
Linus TorvaldsMemberPaused5d ago

Bordered container

NameRoleStatusUpdated
Ada LovelaceOwnerActive2m ago
Alan TuringAdminActive12m ago
Grace HopperMemberInvited1h ago

Compact

NameRoleStatusUpdated
Ada LovelaceOwnerActive2m ago
Alan TuringAdminActive12m ago
Grace HopperMemberInvited1h ago

Empty

NameRoleStatusUpdated

No entries yet

Add an entry to see it here.

Member table

Installation

$npx shadcn@latest add @patchui/table

The copied source is available in the registry JSON. The canonical implementation lives in packages/react/src/components/table.tsx.

Usage

<Table>
  <TableHeader>
    <TableRow>
      <TableHead>Plan</TableHead>
      <TableHead align="right">Price</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>Team</TableCell>
      <TableCell align="right">$49</TableCell>
    </TableRow>
  </TableBody>
</Table>

Every part renders its corresponding native table element, so browser table semantics and native attributes are preserved.

Structural behavior

  • The header provides the primary column divider. Body rows use quiet horizontal dividers.
  • Numeric cells should use align="right", which also enables tabular numerals.
  • Sorting state belongs on aria-sort on TableHead; TableSortButton provides the interactive control and direction icon.
  • Selected rows expose aria-selected. Use interactive on the root when rows are actionable.
  • TableEmpty must span the visible columns through colSpan.

API reference

The primitives accept their corresponding native table attributes. The entries below cover behavior added by Patch UI. See the canonical source for exhaustive TypeScript definitions.

PropTypeDefaultDescription
Table.borderedbooleanfalseAdds a radius-12 layer surface with an outer hairline.
Table.size"sm" | "md""md"Selects compact or standard row density.
Table.interactivebooleanfalseAdds the shared hover treatment to actionable body rows.
Table.scrollablebooleantrueProvides horizontal overflow. Disable it when an external container owns scrolling.
Table.stickyHeaderbooleanfalsePins header cells inside a fixed-height scrolling container.
TableRow.selectedbooleanfalseApplies the selected treatment and sets aria-selected.
TableSortButton.direction"asc" | "desc" | "none""none"Controls the direction icon. Sorting state remains application-owned.

Accessibility

  • Keep TableHead, TableBody, TableRow, and cell parts in valid native table order.
  • Add a TableCaption when surrounding content does not already identify the table.
  • Put aria-sort="ascending" or aria-sort="descending" on the sorted TableHead, not on the sort button.
  • Do not add row click behavior without an accessible interactive control or an established composite-widget keyboard model.
  • Preserve horizontal scrolling on narrow screens rather than compressing columns until content becomes unreadable.

Responsive behavior

Table scrolls horizontally by default. Set scrollable={false} only when a parent owns overflow, such as a fixed-height container used with stickyHeader.