VayuUI

Table

A responsive table component with sorting, filtering, and pagination support.

Installation

npx vayu-ui-cli@latest add table

Usage

Table Example

Default Table
A list of your recent invoices.
Invoice
Status
Method
Amount
INV001PaidCredit Card$250.00
INV002PendingPayPal$150.00
INV003UnpaidBank Transfer$350.00
INV004PaidCredit Card$450.00
INV005PaidPayPal$550.00
Total$1,750.00
Table with Selected Row
Invoice
Status
Method
Amount
INV001PaidCredit Card$250.00
INV002PendingPayPal$150.00
INV003UnpaidBank Transfer$350.00
INV004PaidCredit Card$450.00
INV005PaidPayPal$550.00
Table with Sortable Columns
Invoice
Status
Method
Amount
INV001PaidCredit Card$250.00
INV002PendingPayPal$150.00
INV003UnpaidBank Transfer$350.00
INV004PaidCredit Card$450.00
INV005PaidPayPal$550.00
Table with Selectable Rows
Invoice
Status
Method
Amount
INV001PaidCredit Card$250.00
INV002PendingPayPal$150.00
INV003UnpaidBank Transfer$350.00
INV004PaidCredit Card$450.00
INV005PaidPayPal$550.00
Table with Actions
Invoice
Status
Method
Amount
Actions
INV001PaidCredit Card$250.00
INV002PendingPayPal$150.00
INV003UnpaidBank Transfer$350.00
INV004PaidCredit Card$450.00
INV005PaidPayPal$550.00

Anatomy

import { Table } from 'vayu-ui';

<Table aria-label="Your table description">
  <Table.Caption>Table summary for screen readers.</Table.Caption>
  <Table.Head>
    <Table.Row>
      <Table.Header>Column A</Table.Header>
      <Table.Header>Column B</Table.Header>
    </Table.Row>
  </Table.Head>
  <Table.Body>
    <Table.Row>
      <Table.Cell>Data A1</Table.Cell>
      <Table.Cell>Data B1</Table.Cell>
    </Table.Row>
  </Table.Body>
  <Table.Footer>
    <Table.Row>
      <Table.Cell>Total</Table.Cell>
      <Table.Cell>$100.00</Table.Cell>
    </Table.Row>
  </Table.Footer>
</Table>;
  • Table — Root container. Wraps a native <table> inside a scrollable container with border and shadow.
  • Table.Caption — Accessible caption element. Supports visuallyHidden to hide visually while remaining readable by screen readers.
  • Table.Head — <thead> section containing column header rows.
  • Table.Body — <tbody> section containing data rows. Supports empty prop to enable aria-live announcements.
  • Table.Footer — <tfoot> section for summary or totals rows.
  • Table.Row — <tr> row element. Supports selectable and selected for interactive row selection.
  • Table.Header — <th> header cell with sort icon support via sortable and aria-sort props.
  • Table.Cell — <td> data cell with support for rowSpan, colSpan, and accessibility indexing.

Accessibility

  • Keyboard Support:
    • Tab — Moves focus to the next focusable element. Selectable rows (selectable) receive tabIndex={0}.
    • Enter / Space — Activates a selectable row (selection handling is user-implemented).
    • Enter / Space — Activates a sortable header column (sort handling is user-implemented).
  • ARIA Attributes:
    • aria-label on Table provides an accessible name for the table.
    • aria-describedby on Table references an external description element.
    • aria-colcount and aria-rowcount on Table for large or virtualized tables.
    • aria-sort on Table.Header reflects the current sort state (ascending, descending, none).
    • aria-selected on Table.Row indicates selection state when selectable is set.
    • aria-rowindex on Table.Row for row position in large tables.
    • aria-colindex on Table.Header and Table.Cell for column position.
    • aria-live="polite" on Table.Body when empty is true, announcing empty state changes.
    • headers on Table.Cell links to associated header cell IDs.
    • Sort indicator icons are marked aria-hidden="true" since state is conveyed via aria-sort.
  • Focus Behavior:
    • Selectable rows show a visible focus ring on focus-visible.
    • Sortable headers show a visible focus ring on focus-visible.
    • Focus indicators use the design system focus token (ring-focus) with offset.

Screen reader behavior

When a screen reader encounters the table, it announces the accessible name (from aria-label or Table.Caption) and describes the table structure. The screen reader reads column headers as the user navigates across rows, using the scope="col" attribute on Table.Header to associate headers with their columns. For sortable columns, the screen reader announces the current sort direction via aria-sort. Selectable rows announce their selection state through aria-selected. When the table body is empty and empty is set, the aria-live="polite" region announces content changes. For large tables using aria-rowcount and aria-colcount, the screen reader communicates the total table dimensions even when not all rows are rendered.

Component Folder Structure

Table/
├── Table.tsx          # Root component with compound component composition
├── TableCaption.tsx   # Caption with visually-hidden support
├── TableHead.tsx      # <thead> section element
├── TableBody.tsx      # <tbody> section with empty state aria-live
├── TableFooter.tsx    # <tfoot> section element
├── TableRow.tsx       # <tr> row with selectable and selected state
├── TableHeader.tsx    # <th> header cell with sort icon logic
├── TableCell.tsx      # <td> data cell
├── types.ts           # TypeScript type definitions
├── index.ts           # Re-exports all components and types
└── README.md          # Component usage reference

Props

Table

PropTypeDefaultDescription
childrenReactNode—Table sections (Caption, Head, Body, Footer).
classNamestring—Additional CSS classes.
aria-labelstring—Accessible name for the table.
aria-describedbystring—ID of an element describing the table.
aria-colcountnumber—Total column count for virtualized tables.
aria-rowcountnumber—Total row count for virtualized tables.

Table.Caption

PropTypeDefaultDescription
childrenReactNode—Caption content.
classNamestring—Additional CSS classes.
visuallyHiddenbooleanfalseHide visually but keep accessible to screen readers.

Table.Head

PropTypeDefaultDescription
childrenReactNode—Header rows.
classNamestring—Additional CSS classes.

Table.Body

PropTypeDefaultDescription
childrenReactNode—Data rows.
classNamestring—Additional CSS classes.
emptybooleanfalseEnable aria-live for empty state announcements.

Table.Footer

PropTypeDefaultDescription
childrenReactNode—Footer rows.
classNamestring—Additional CSS classes.

Table.Row

PropTypeDefaultDescription
childrenReactNode—Row cells.
classNamestring—Additional CSS classes.
aria-rowindexnumber—Row position for large tables.
selectedbooleanfalseWhether the row is currently selected.
selectablebooleanfalseEnable keyboard focus and selection cues.

Table.Header

PropTypeDefaultDescription
childrenReactNode—Header cell content.
classNamestring—Additional CSS classes.
scope"row" | "col" | "rowgroup" | "colgroup""col"Scope of the header cell.
aria-colindexnumber—Column position for accessibility.
aria-sort"ascending" | "descending" | "none" | "other"—Current sort direction.
sortablebooleanfalseShow sort indicator and enable interaction.

Table.Cell

PropTypeDefaultDescription
childrenReactNode—Cell content.
classNamestring—Additional CSS classes.
aria-colindexnumber—Column position for accessibility.
aria-rowindexnumber—Row position for accessibility.
headersstring—ID of associated header cells.

On this page