Installation
Section titled “Installation”- Package
@bigbang/ui- Import
import { DataTable } from '@bigbang/ui';- Source
- DataTable.tsx
- Storybook
- DataTable · Playground
DataTable is in the @bigbang/ui package and is built on TanStack Table (v9) and TanStack Virtual; both come as dependencies of the package. Installation and style files are the same as for Button; see the Button code tab.
import { createDataTableColumnHelper, DataTable } from '@bigbang/ui';
type Row = { id: string; name: string; count: number };
const helper = createDataTableColumnHelper<Row>();
// Define the columns outside the component, or keep them stable with useMemo.const columns = [ helper.accessor('name', { header: 'Name', meta: { rowHeader: true } }), helper.accessor('count', { header: 'Count', meta: { numeric: true } }),];
<DataTable columns={columns} data={rows} getRowId={(row) => row.id} caption="Item list" />;columnsRequired- Description
- The column definitions (TanStack
ColumnDef). Keep the array stable, withuseMemoor a module constant. Options for the cell go inmeta:align,numeric,truncate,headerLabel,rowHeader. - Type
DataTableColumnDef<TRow>[]
dataRequired- Description
- The rows to show. Keep the array stable between renders; a new array on every render recomputes the table.
- Type
TRow[]
getRowIdRequired- Description
- Returns a stable unique id for a row, such as its record id. Selection and focus follow this id, so never use the index for data that changes.
- Type
(row: TRow, index: number) => string
captionRequired- Description
- The table's title. It names the table and its scroll region for screen readers.
- Type
ReactNode
captionHidden- Description
- Hides the caption visually and keeps it for assistive technology.
- Type
boolean- Default
false
sorting- Description
- Sorting state,
[{ id: 'name', desc: false }]. Setting it makes sorting controlled; pair it withonSortingChange. - Type
SortingState
defaultSorting- Description
- The initial sorting when you do not control it.
- Type
SortingState
onSortingChange- Description
- Called with the new sorting when the user clicks a sortable header.
- Type
(sorting: SortingState) => void
manualSorting- Description
- Sorting happens on the server: the table shows
datain the given order and only reports the sorting throughonSortingChange. - Type
boolean- Default
false
selectionMode- Description
- Adds a checkbox column.
multiplealso adds a select-all checkbox that shows a mixed state;singleallows one selected row. - Type
'none' | 'single' | 'multiple'- Default
'none'
rowSelection- Description
- Selected rows as
{ [rowId]: true }. Setting it makes selection controlled; pair it withonRowSelectionChange. - Type
RowSelectionState
defaultRowSelection- Description
- The initial selection when you do not control it.
- Type
RowSelectionState
onRowSelectionChange- Description
- Called with the new selection when the user toggles a row or the select-all checkbox.
- Type
(selection: RowSelectionState) => void
getRowLabel- Description
- Returns the text that names a row, such as its name. It labels the row checkbox ("Select row Item 1"). Without it the row id is used.
- Type
(row: TRow) => string
columnVisibility- Description
- Column visibility,
{ [columnId]: false }hides a column. Setting it makes visibility controlled. - Type
ColumnVisibilityState
defaultColumnVisibility- Description
- The initial visibility when you do not control it.
- Type
ColumnVisibilityState
onColumnVisibilityChange- Description
- Called with the new visibility when a column is shown or hidden.
- Type
(visibility: ColumnVisibilityState) => void
columnToggle- Description
- Shows the built-in column button above the table, a panel of checkboxes that shows or hides columns.
- Type
boolean- Default
false
toolbar- Description
- Content at the start of the bar above the table, such as a filter bar or a search field.
- Type
ReactNode
density- Description
- Row height:
compactuses 6 px,standard8 px andcomfortable12 px of block padding in each cell. - Type
'compact' | 'standard' | 'comfortable'- Default
'standard'
stickyHeader- Description
- Keeps the header cells at the top while the body scrolls. Give the scroll container a height with
scrollClassName. - Type
boolean- Default
false
hoverable- Description
- Tints a body row on hover with a colour change only.
- Type
boolean- Default
true
striped- Description
- Tints every second body row.
- Type
boolean- Default
false
status- Description
- What the table shows:
readythe rows;loadingskeleton rows under the header andaria-busy;emptyandfiltered-emptya message;errora message with a retry button. Areadytable with no rows shows the empty message. - Type
'ready' | 'loading' | 'empty' | 'filtered-empty' | 'error'- Default
'ready'
onClearFilters- Description
- Adds a "Clear filters" button to the
filtered-emptymessage. - Type
() => void
onRetry- Description
- Adds a "Try again" button to the
errormessage. - Type
() => void
rowActions- Description
- Renders the actions of a row, such as
IconButtons, in a last column that stays at the inline end. Each action is its own tab stop and needs a name. - Type
(row: TRow) => ReactNode
onRowOpen- Description
- Makes the first column's cell content a button that calls this with the row, so a row is never click-only.
- Type
(row: TRow) => void
renderExpanded- Description
- Content shown in a full-width row under a row when it is expanded, such as installments or refund history. Adds a first column of expand buttons.
- Type
(row: TRow) => ReactNode
getRowCanExpand- Description
- Returns whether a row can expand; rows without details get no button. Without it every row can expand.
- Type
(row: TRow) => boolean
expanded- Description
- Expanded rows as
{ [rowId]: true }. Setting it makes expansion controlled; pair it withonExpandedChange. - Type
Record<string, boolean>
defaultExpanded- Description
- The rows expanded on first render when you do not control them.
- Type
Record<string, boolean>
onExpandedChange- Description
- Called with the new expanded rows when the user opens or closes one.
- Type
(expanded: Record<string, boolean>) => void
virtualize- Description
- Renders only the rows in view plus an overscan, with padding rows keeping the scroll height. Use it from about 1,000 rows. It needs a fixed-height scroll container (
scrollClassName) and rows of equal height. - Type
boolean | { estimateRowHeight?: number; overscan?: number; }- Default
false
totalRowCount- Description
- Total number of rows when
dataholds only part of them, such as one server page. It setsaria-rowcount. - Type
number
messages- Description
- Replaces library texts, such as
{ empty: 'No items yet' }. - Type
Partial<Record<DataTableMessageKey, string>>
scrollClassName- Description
- Classes for the scroll container that holds the table, such as
max-h-96for a sticky header or a virtualised list. - Type
string
className- Description
- For layout only: width and margins of the whole component.
- Type
string
Column definitions
Section titled “Column definitions”columns are TanStack Table v9 column definitions. createDataTableColumnHelper<Row>() wires the types for you. The column meta field takes these options:
meta |
Meaning |
|---|---|
align |
start, center or end alignment. |
numeric |
Aligns to the end and uses tabular numerals. |
truncate |
Cuts long text on one line; the column needs a width. |
headerLabel |
The name of the sort button, the column panel and announcements when the header is not text. |
rowHeader |
Makes the cells of the column row headers (<th scope="row">). |
const columns = [ helper.accessor('name', { header: 'Name', meta: { rowHeader: true } }), // A custom cell: a StatusBadge from the status vocabulary helper.accessor('status', { header: 'Status', enableSorting: false, cell: (context) => <StatusBadge status={context.getValue()} />, }), // The header is not text: give it a name with headerLabel helper.accessor('owner', { header: () => <Icon name="user" />, meta: { headerLabel: 'Owner' } }),];enableSorting: false makes a column unsortable; enableHiding: false removes it from the column panel; sortFn and the other TanStack options apply.
| Part | Element | Props |
|---|---|---|
DataTable.ColumnToggle |
<div> and a button |
columns ({ id, label, visible }), onVisibleChange, label. The part the columnToggle prop uses; you can also use it alone in a custom toolbar. |
Exports
Section titled “Exports”DataTable, createDataTableColumnHelper, dataTableStyles and these types: DataTableProps, DataTableColumnDef, DataTableColumnMeta, DataTableMessages, DataTableColumnVisibility, DataTableRowSelection, DataTableSorting.
Data attributes
Section titled “Data attributes”data-component="data-table",data-status: on the outer container.data-part:toolbar,column-toggle,column-toggle-panel,select-header,select-cell,sort,open,actions-header,actions-cell,skeleton-row,state-row,message,spacer,footer,live.- The table and row attributes come from Table (
data-density,data-selectedand so on). data-pin(start,end), anddata-pin-edgeon the cell at the edge of the pinned area: on pinned cells.data-part:expand-header,expand-cell,expanded-row.
Managing state
Section titled “Managing state”const [sorting, setSorting] = useState<DataTableSorting>([{ id: 'count', desc: true }]);const [selection, setSelection] = useState<DataTableRowSelection>({});
<DataTable columns={columns} data={rows} getRowId={(row) => row.id} caption="Item list" sorting={sorting} onSortingChange={setSorting} selectionMode="multiple" rowSelection={selection} onRowSelectionChange={setSelection}/>;Server-side sorting and pagination
Section titled “Server-side sorting and pagination”<DataTable columns={columns} data={page.rows} getRowId={(row) => row.id} caption="Item list" manualSorting sorting={sorting} onSortingChange={setSorting} totalRowCount={page.total} status={isLoading ? 'loading' : isError ? 'error' : 'ready'} onRetry={refetch} footer={<Pagination … />}/>Virtualisation
Section titled “Virtualisation”<DataTable columns={columns} data={rows} getRowId={(row) => row.id} caption="Item list" virtualize scrollClassName="max-h-96" density="compact" />virtualize={{ estimateRowHeight: 40, overscan: 12 }} sets the row height and overscan. The default row height is 32 px for compact, 40 px for standard and 48 px for comfortable.
Changing the texts
Section titled “Changing the texts”<DataTable … status="empty" messages={{ empty: 'No items yet' }} />messages keys: empty, filtered-empty, clear-filters, error, retry, loading, select-all, select-row, select-column, actions, columns, sorted-asc, sorted-desc, sorted-none, selected-count. The {column}, {row} and {count} placeholders are replaced in the texts that have them.