Skip to content
Component

Table

Table is the styled semantic primitive; DataTable adds client-side search, sorting, and pagination on top.

Basic table

NameRole
Gean LykaDesigner
Kenji SatoEngineer
Priya NairPM
Marco DiazEngineer
Yuki TanakaDesigner

Borderless, with footer

NameRole
Gean LykaDesigner
Kenji SatoEngineer
2 of 5 rows

DataTable: search, sort, and pagination

5 results
Status
Gean LykaDesignerActive
Kenji SatoEngineerActive
Priya NairPMInvited
  • Search and page-size are ordinary component state; DataTable just receives the filtered rows
  • The empty state renders automatically when the filtered result set is empty

When to use

  • Table: any tabular data with a fixed, known row set - a summary, a static report, a small list.
  • DataTable: the same tabular data plus client-side search, column sorting, and pagination without hand-wiring any of it.

When not to use

  • Server-side pagination/sorting over a large dataset - DataTable's search/sort/pagination are all client-side over the rows you pass it; wire your own controls to a server query for large datasets instead.
  • Non-tabular grouped content - List or DescriptionList usually reads better than forcing rows/columns.

Keyboard

KeyAction
TabMoves through interactive rows/cells (sort buttons, row actions) in DOM order.
Enter / SpaceActivates a sortable column header or an interactive row (when Table.Row has interactive + onClick).

Mobile behavior

  • The table wrapper scrolls horizontally (overflow-x-auto) rather than reflowing columns, so wide tables stay readable instead of squeezing every column.
  • DataTable's search/page-size controls stack above the table and remain fully usable at phone widths.

Accessibility notes

  • Renders real <table>/<thead>/<tbody>/<th>/<td> elements, so assistive tech gets native table semantics for free - no ARIA table role reimplementation.
  • Table.Row's interactive mode adds a roving tabIndex and Enter/Space activation only when paired with onClick, so plain display rows never pick up unwanted focus stops.

Common mistakes

  • Making every row interactive/clickable when only a few need it - it adds unnecessary Tab stops for rows with no action.
  • Passing thousands of rows straight into DataTable and expecting virtualization - it's a client-paginated table, not a virtualized grid.

Known limitations

  • No column resizing, reordering, or row virtualization - DataTable covers search/sort/pagination only.

Related components

DataTable props

columnsNone
DataTableColumn<T>[]

Column defs: key, header, accessor or render, and optional sortable.

dataNone
T[]

The full row set - filtering happens before this prop, sorting/pagination happen inside DataTable.

rowKeyNone
(row: T) => string

Stable key extractor for each row.

pageSizeNone
number

Rows shown per page.

loadingfalse
boolean

Shows a loading state in place of rows.

CriterionStatusNote
Keyboard supportSupportedNative table semantics; interactive rows/sort headers are reachable and activatable via Tab/Enter/Space.
Focus managementNot applicableNot an overlay - no focus trap or portal involved.
Screen reader labelsSupportedReal <table> markup gives native row/column announcements without extra ARIA.
Reduced motionSupportedRow hover/transition uses the shared Fuji duration tokens, which zero under prefers-reduced-motion.
Reduced transparencySupportedTable surfaces flatten to opaque under Glass + prefers-reduced-transparency, same as other Fuji surfaces.
Mobile touch behaviorSupportedHorizontal scroll with touch-friendly row heights; verified down to 320px.

API reference

borderedtrue
boolean

Shows the outer bordered panel; set false for a borderless table.

Header / Body / Row / Head / Cell / FooterNone
compound parts

Semantic table sections and cells.

classNameNone
string

Additional classes applied to the component root.