Table
Styled table primitives for structured data, with header, body, footer, row, cell and caption parts on native table elements.
import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from "@plexui/ui/components/Table";
import { DataTable, DataTableColumnHeader } from "@plexui/ui/components/DataTable";Table Primitives
Overview
| Invoice | Status | Method | Amount |
|---|---|---|---|
| INV001 | Paid | Credit Card | $250.00 |
| INV002 | Pending | PayPal | $150.00 |
| INV003 | Unpaid | Bank Transfer | $350.00 |
| INV004 | Paid | Credit Card | $450.00 |
| INV005 | Paid | PayPal | $550.00 |
| Total | $1,750.00 | ||
With footer
| Product | Qty | Price | Total |
|---|---|---|---|
| Pro Plan | 3 | $29.00 | $87.00 |
| Storage Add-on | 1 | $9.00 | $9.00 |
| Subtotal | $96.00 | ||
Minimal
| Name | Title | |
|---|---|---|
| Lindsay Walton | Front-end Developer | lindsay@example.com |
| Courtney Henry | Designer | courtney@example.com |
| Tom Cook | Director of Product | tom@example.com |
DataTable
The examples import users (15 rows) and its User type from a local ./data file. Header and cell renderers are functions that return JSX, rendered with TanStack Table's flexRender.
Variant
variant
| Role | Department | Status | |
|---|---|---|---|
| Lindsay Walton | Front-end Developer | Engineering | Active |
| Courtney Henry | Designer | Design | Active |
| Tom Cook | Director of Product | Product | Active |
| Whitney Francis | Copywriter | Marketing | Inactive |
| Leonard Krasner | Senior Developer | Engineering | Active |
| Floyd Miles | UX Researcher | Design | Active |
Sorting
| Alicia Bell | Product Manager | Active |
| Anna Roberts | Backend Developer | Active |
| Benjamin Russel | DevOps Engineer | Active |
| Courtney Henry | Designer | Active |
| Emily Selman | VP Marketing | Active |
Rows per page
1–5 of 15
Pagination
| ID | Name | Department | Status |
|---|---|---|---|
| USR-001 | Lindsay Walton | Engineering | Active |
| USR-002 | Courtney Henry | Design | Active |
| USR-003 | Tom Cook | Product | Active |
| USR-004 | Whitney Francis | Marketing | Inactive |
| USR-005 | Leonard Krasner | Engineering | Active |
Rows per page
1–5 of 15
Row click
| Role | ||
|---|---|---|
| Lindsay Walton | lindsay@example.com | Front-end Developer |
| Courtney Henry | courtney@example.com | Designer |
| Tom Cook | tom@example.com | Director of Product |
| Whitney Francis | whitney@example.com | Copywriter |
Rows per page
1–4 of 8
Click a row to see selected user details.
Row selection
| Role | Status | ||
|---|---|---|---|
| Lindsay Walton | Front-end Developer | Active | |
| Courtney Henry | Designer | Active | |
| Tom Cook | Director of Product | Active | |
| Whitney Francis | Copywriter | Inactive | |
| Leonard Krasner | Senior Developer | Active |
Rows per page
1–5 of 15
0 of 15 rows selected
Cell variants
| ID | Name | Status | Joined | Salary |
|---|---|---|---|---|
| USR-001 | Lindsay Walton | Active | Jan 15, 2023, 09:00 AM | $95,000 |
| USR-002 | Courtney Henry | Active | Mar 22, 2023, 09:00 AM | $88,000 |
| USR-003 | Tom Cook | Active | Jun 10, 2022, 09:00 AM | $120,000 |
| USR-004 | Whitney Francis | Inactive | Jul 4, 2023, 09:00 AM | $72,000 |
| USR-005 | Leonard Krasner | Active | Feb 18, 2022, 09:00 AM | $115,000 |
| USR-006 | Floyd Miles | Active | May 11, 2023, 09:00 AM | $85,000 |
Rows per page
1–6 of 15
Filtering
| Role | Department | Status | |
|---|---|---|---|
| Lindsay Walton | Front-end Developer | Engineering | Active |
| Courtney Henry | Designer | Design | Active |
| Tom Cook | Director of Product | Product | Active |
| Whitney Francis | Copywriter | Marketing | Inactive |
| Leonard Krasner | Senior Developer | Engineering | Active |
Rows per page
1–5 of 15
Column visibility
| Role | Department | Status | Salary | |
|---|---|---|---|---|
| Lindsay Walton | Front-end Developer | Engineering | Active | $95,000 |
| Courtney Henry | Designer | Design | Active | $88,000 |
| Tom Cook | Director of Product | Product | Active | $120,000 |
| Whitney Francis | Copywriter | Marketing | Inactive | $72,000 |
| Leonard Krasner | Senior Developer | Engineering | Active | $115,000 |
Rows per page
1–5 of 15
Empty state
| ID | Name | Status | |
|---|---|---|---|
| No users found. | |||
API
Table Primitives
| Prop | Type | Default | Description |
|---|---|---|---|
Table | table | — | Root table container with horizontal scroll wrapper |
TableHeader | thead | — | Table header group |
TableBody | tbody | — | Table body group |
TableFooter | tfoot | — | Table footer group |
TableRow | tr | — | Table row |
TableHead | th | — | Table header cell |
TableCell | td | — | Table data cell |
TableCaption | caption | — | Table caption |
Every part renders its native element, merges className after its own, and forwards all other props (colSpan, scope, onClick, ...).
DataTable
| Prop | Type | Default | Description |
|---|---|---|---|
columns | ColumnDef<TData>[] | — | Column definitions following TanStack Table v8 API (required) |
data | TData[] | — | Data array to display (required) |
variant | "default" | "bordered" | "default" | Visual variant: bordered adds a rounded border and tinted header |
pageSize | number | 10 | Rows per page. Set 0 or Infinity to disable pagination. The rows-per-page select offers 10, 20, 50, 100 and this size |
initialSorting | SortingState | — | Initial column sorting state |
globalFilter | string | — | Controlled search/filter string |
onGlobalFilterChange | (value: string) => void | — | Callback when filter changes |
onRowClick | (row: TData) => void | — | Click handler for rows. Makes rows interactive: they take Tab and call it on Enter or Space |
columnVisibility | VisibilityState | — | Controlled column visibility state |
onColumnVisibilityChange | (visibility: VisibilityState) => void | — | Callback when visibility changes |
enableRowSelection | boolean | false | Adds a first column (id select) with a checkbox per row and a header checkbox that selects every row on all pages, mixed when some are selected. A click on a checkbox is not a row click |
rowSelection | RowSelectionState | — | Controlled row selection state |
onRowSelectionChange | (selection: RowSelectionState) => void | — | Callback when selection changes |
getRowId | (row: TData) => string | — | Custom row ID accessor; selection keys use it |
emptyMessage | ReactNode | "No results." | Shown when no rows |
showPagination | boolean | true | Whether to show pagination controls. They hide on their own when every row fits on one page |
className | string | — | Class applied to outermost wrapper |
Column groups (a column definition with columns) render a header that spans its columns.
DataTableColumnHeader
| Prop | Type | Default | Description |
|---|---|---|---|
column | Column<TData, TValue> | — | TanStack Table column object (required) |
title | string | — | Display text for the header (required) |
className | string | — | Class applied to the header button (or text when the column cannot sort) |
Column helpers
| Prop | Type | Default | Description |
|---|---|---|---|
idCell(accessor) | CellComponent | — | Monospace ID with copy-on-click tooltip |
dateTimeCell(accessor, options?) | CellComponent | — | Formatted datetime with Intl.DateTimeFormat |
statusCell(accessor, colorMap?) | CellComponent | — | Badge cell with automatic status-to-color mapping |
tooltipHeader(label, description) | HeaderComponent | — | Header with dashed underline and info tooltip |
Styling
Table reads these component tokens. Override them at any scope to restyle it:
--table-border-color: border color (defaultvar(--color-border))--table-caption-color: caption color (defaultvar(--color-text-tertiary))--table-caption-font-size: caption font size (defaultvar(--font-text-sm-size))--table-cell-color: cell color (defaultvar(--color-text))--table-cell-font-size: cell font size (defaultvar(--font-text-sm-size))--table-cell-line-height: cell line height (defaultvar(--font-text-sm-line-height))--table-cell-padding: cell padding (defaultspacing(3) spacing(4))--table-footer-background: footer background (defaulttransparent)--table-footer-font-weight: footer font weight (defaultvar(--font-weight-medium))--table-header-background: header background (defaulttransparent)--table-header-color: header color (defaultvar(--color-text-secondary))--table-header-font-weight: header font weight (defaultvar(--font-weight-medium))--table-row-hover-background: row hover background (defaultlight-dark(var(--alpha-02), var(--alpha-04)))