Table

A structural, stateless table primitive built on native HTML table semantics with composable parts for header, body, footer, rows, cells, and captions.

Features

  • Native table semantics
  • Composable parts
  • Row and column headers
  • Stateless
  • Forwards refs and native props
  • Horizontal overflow support

Installation

npm install @ariaui/table

Examples

Composable table parts—Header, Body, Row, Cell, Footer, and Caption—over native <table> semantics.

The first playground is a static invoice listing with badges. The second is an interactive data table (filter input, column menu, selection, row actions) with a matching exampleSource fence; shared layout classes live in tableExampleTokens.ts.

Invoice table

Header, body, footer, and caption with status badges.

Preview

No preview output yet.

live.tsxReady

Data table

Filtering, column visibility, row selection, status badges, and row actions.

Preview

No preview output yet.

live.tsxReady

Anatomy

tsx
import * as Table from "@ariaui/table";

export default function Example() {
  return (
    <Table.Root>
      <Table.Caption />
      <Table.Header>
        <Table.Row>
          <Table.ColumnHeader />
        </Table.Row>
      </Table.Header>
      <Table.Body>
        <Table.Row>
          <Table.RowHeader />
          <Table.Cell />
        </Table.Row>
      </Table.Body>
      <Table.Footer>
        <Table.Row>
          <Table.Cell />
        </Table.Row>
      </Table.Footer>
    </Table.Root>
  );
}

API Reference

Root

Wraps the table in an overflow container for horizontal scrolling. The ref is forwarded to the inner `<table>` element.

Body

Renders a `<tbody>` element.

Row

Renders a `<tr>` element.

Cell

Renders a `<td>` element.

ColumnHeader

Renders a `<th>` element for column header semantics. Pass `scope="col"` explicitly when you need to be strict about the association.

RowHeader

Renders a `<th>` with `scope="row"` by default so the cell names its row for assistive tech.

PropTypeDefault
scope
string'row'

Caption

Renders a `<caption>` element that provides an accessible name for the table.

Accessibility

Table is built on native HTML table semantics, which assistive tech already understands:

  • Root renders a <table>, so screen readers announce row and column counts and support built-in table navigation (in NVDA/JAWS, Ctrl+Alt+Arrow keys move between cells).
  • Provide a Caption — or pair the table with an aria-labelledby / aria-label — so the table has a human-readable name.
  • Use ColumnHeader for column <th> cells and RowHeader for row-identifying <th> cells. RowHeader defaults to scope="row"; add scope="col" on ColumnHeader when you need to be explicit.
  • Do not remove default roles with role="presentation" or wrap cells in non-semantic elements — the native markup is what makes the table accessible.
  • For sortable columns add aria-sort on the relevant ColumnHeader; for selectable rows use aria-selected on Row and manage focus yourself — Table is intentionally stateless.
  • When the table scrolls horizontally inside Root, make the scroll container focusable (tabIndex={0}) and give it a label so keyboard-only users can scroll it.
Previous
Switch
Next
Tabs