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 when data is empty; emptyMessage sets its text (default "No results."). Search for a name that is not listed to see it

Infinite loading instead of pagination

Appends the next page as the table's end comes into view. pageSize is set to the number of rows fetched so far, since infinite loading is what replaces the pager.

PersonEventWhen
Priya Nairopened a PR1h ago
Kenji Satoleft a review2h ago
Marco Rossimerged a branch3h ago
Ada Iwuclosed an issue4h ago
Priya Nairopened a PR5h ago
Kenji Satoleft a review6h ago
Marco Rossimerged a branch7h ago
Ada Iwuclosed an issue8h ago
  • Keep the scroll container bounded (max-h) so there is something to scroll

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

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 UI duration tokens, which zero under prefers-reduced-motion.
Reduced transparencySupportedTable surfaces flatten to opaque under Glass + prefers-reduced-transparency, same as other Fuji UI surfaces.
Mobile touch behaviorSupportedHorizontal scroll with touch-friendly row heights; verified down to 320px.

API reference

borderedtrue
boolean

Wraps the table in a bordered panel. Defaults to on - pass `false` for a borderless table.

Also accepts everything from React.TableHTMLAttributes<HTMLTableElement>.

Table.Row props

interactivefalse
boolean

Hover/click row; with `onClick`, also Enter/Space-activatable. Defaults to off. **Not the accessible affordance:** a `<tr>` has no activatable role/name; put the real action in a cell.

Also accepts everything from React.HTMLAttributes<HTMLTableRowElement>.

DataTable props

columns *None
DataTableColumn<Row>[]

Column definitions, in display order.

data *None
Row[]

Every row. Sorting and paging happen here, not in the consumer.

rowKey *None
(row: Row) => string

Stable React key per row - an id, not the array index.

borderedtrue
boolean

Draws the table's cell borders.

emptyMessage"No results."
string

Shown in place of the rows when `data` is empty.

loadingfalse
boolean

Shows skeleton rows instead of data - for async loads.

pageSize8
number

Rows per page. Wrapping the table in `InfiniteScroll` instead? Set this to the number of rows fetched so far, so nothing is paged out of view.

Also accepts everything from React.HTMLAttributes<HTMLDivElement>.

Coding agents read this reference, with its examples, from the version your project has installed, through the Fuji UI MCP server. Set up your agent