Table
Tables allow users to review, sort, edit or action large amounts of sequential information. Use them to compare data points, find specific records within a large dataset, and display long lists of structured content.
preview
props
TableProps
| Prop | Type | Default | Description |
|---|---|---|---|
columns | ColumnDef[] | required | Column definitions controlling id, label, width, cell type, and sort behaviour. |
data | Record<string, unknown>[] | required | Array of row objects. Each key should match a column id. |
onRowClick | (row) => void | — | When provided, rows become clickable and display a hover state. |
onSortChange | (columnId, direction) => void | — | Called after each sort change. Use for server-side sorting; omit to let the table sort internally. |
ColumnDef
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | required | Key used to read the cell value from each row object. |
label | string | required | Column header text, rendered uppercase. |
width | string | 1fr | Column width — pixel value ("200px") or fractional ("2fr"). |
cellType | CellType | 'text' | Controls how the cell value is rendered. See Cell Types below. |
sortable | boolean | false | Adds a sort affordance to the header. Clicking cycles asc → desc → clear. |
currencyVariant | 'success' | 'error' | 'default' | 'default' | Colour treatment for currency cells. |
best practices
Tables are useful for organising data in grids. They work best when used to compare data points, find insights, locate specific information within a large dataset, or show long lists of sequential or structured content.
Do
- Keep cell content short and succinct
- Use sortable columns to help users find what they need faster
- Ensure each column has a clear, descriptive label
- Use the appropriate cell type to communicate the data format
Don't
- Write long-form content inside table cells
- Put a table inside another table
- Use a table for minimal information where a list would suffice
- Use detailed tables in small spaces like modals or drawers
interaction
Users can perform a single action across a row. Pass onRowClick to make rows interactive — clicking can open a modal, drawer, or navigate to a detail view. When no handler is provided the table is non-interactive and rows show no hover state.
onRowClickresponsive
When a table has more columns than the available width, it scrolls horizontally. A right-edge shadow appears automatically to signal that content is hidden — it fades away as the user scrolls to the end. The column header scrolls together with the body so labels always stay aligned.
cell types
Set cellType on each ColumnDef to control how values are rendered. Each type expects a specific value shape in the row data.
Leading
The primary identity cell. Pairs an Avatar with a bold title and optional muted description. Use for people, organisations, or any entity that benefits from visual identification.
Status
Communicates the state of a record with a coloured icon badge, a label, and an optional description. Five variants cover the full sentiment spectrum.
Text
Plain body text. Use for string values that don't need special treatment. This is the default cell type when cellType is omitted.
Currency
Semibold numeric value with a colour variant to communicate financial sentiment. Values are passed as pre-formatted strings.
Link
A tappable anchor styled with the brand link colour. Pass a string for a simple href or a LinkCellValue object to control the label, href, and onClick separately.
Progress
Uses the ProgressBar component inline. Pass current, total, and an optional intent. The percentage is computed automatically. Use intent to convey sentiment — warning when partially complete, positive when done.
Date
Condensed date cell with a calendar icon. Pass a pre-formatted date string. If the value is empty the cell enters the incomplete state, showing a warning colour and a 'Date missing' label.
Time
Condensed time cell with a clock icon. Same incomplete behaviour as the date cell when the value is empty.
Location
Condensed location cell with a map-pin icon. Same incomplete behaviour when the value is empty.