DataTable
When to use
Section titled “When to use”Product lists, inventory grids, operational tables needing sort/filter/pagination. Built-in column types: PRODUCT, RFID, BADGE_BAR, CLASSIFICATION, PRICE.
When NOT to use
Section titled “When NOT to use”Simple static HTML tables — use Podium layout. Editable spreadsheet grids — WCL does not ship a data-grid editor.
Podium primitives composed
Section titled “Podium primitives composed”- Podium
TextField - Podium
Select - Podium
Button - Podium
Checkbox - Podium
Text
Required providers
Section titled “Required providers”- SlideOutProvider (app-level, required for product drill-down only)
Related stores
Section titled “Related stores”usePicklistCartStore
Common pitfalls
Section titled “Common pitfalls”- Column
accessormust match row data keys exactly. filterType: 'color'requirescolorOptionswith hex codes without#.- RFID columns need
offsiteEnabledaligned with store config. SlideOutProvideris an app-level singleton — do not wrapDataTablein its own; add it once near the app root.- Pass
productSlideOutconfig on theDataTableprop, not on individual column definitions. - Use
autoHeightonly in pages with fixed chrome above the table.
Auto-generated from
src/components/DataTable/DataTable.types.ts. Do not edit by hand. Runpnpm docs:propsafter changing source JSDoc.
DataTableProps
Section titled “DataTableProps”| Prop | Type | Required | Description |
|---|---|---|---|
ariaLabel |
string |
No | Accessible name for the table element (aria-label). |
autoHeight |
boolean |
No | When true, the table sizes its scrollable wrapper to fill remaining viewport space below the table’s top edge, leaving room for the pagination footer. The available height is recomputed on window resize. Use this when the table sits in an unbounded vertical container (e.g. a page with overflow: visible chrome above it) and you want the table body to scroll instead of pushing the pagination footer off-screen. Ignored when an explicit maxHeight is provided. Default: false |
autoHeightOffset |
number |
No | Pixels reserved below the table when autoHeight is on — typically the height of the pagination footer plus any page bottom padding. The table’s computed max-height is window.innerHeight - wrapperTop - autoHeightOffset. Default: 100 |
closeSlideOutSignal |
number |
No | Increment this value to programmatically close the ProductSlideOut panel. Useful when a competing panel (e.g. a receiving-log drawer) opens and the two panels should be mutually exclusive. |
columns |
DataTableColumn<TData>[] |
Yes | Column definitions including accessors, labels, filters, and column types. |
contained |
boolean |
No | When true, table scrolls inside a bordered container instead of full bleed. |
data |
TData[] |
Yes | Row data array. Keys must match column accessor values. |
emptyMessage |
string |
No | Message shown when data is empty. |
externalFilterOptions |
Record<string, SelectOption[]> |
No | Precomputed filter options per column accessor (bypasses auto-derivation from data). |
filterPosition |
'side' | 'top' |
No | Place filters in a top bar (top) or side panel (side). |
hasMore |
boolean |
No | Whether more pages exist for infinite scroll mode. |
hideZeroCountOptions |
boolean |
No | When true, filter options whose count drops to zero are hidden entirely. When false (default), zero-count options remain visible but are disabled. Top-bar filters default to hiding zeros; side-panel filters default to showing disabled zeros — this prop overrides both positions. |
infiniteScroll |
boolean |
No | Enable infinite scroll instead of pagination footer. |
loading |
boolean |
No | Show table-level loading skeleton overlay. |
loadingMore |
boolean |
No | Show loading indicator at the bottom while fetching the next infinite-scroll page. |
maxHeight |
string |
No | Explicit max height for the scrollable table body (CSS length). Overrides autoHeight. |
mobileBreakpoint |
number |
No | Pixel width below which the table switches to a mobile card view. Omit to disable mobile card view entirely. |
mobileCardTitle |
((row: TData) => ReactNode) | keyof TData |
No | Accessor key (or render function) used as the bold heading in each mobile card. When the referenced column is a PRODUCT type, the full product image + details are shown in the card header. Defaults to the first PRODUCT column if present. |
onLoadMore |
() => void |
No | Callback when infinite scroll nears the bottom and hasMore is true. |
onRowClick |
(row: TData) => void |
No | Row click handler (entire row is clickable when provided). |
onSelectionChange |
(rows: TData[]) => void |
No | Controlled selection callback when selectable is enabled. |
onSlideOutOpen |
(styleColor: string) => void |
No | Called whenever the ProductSlideOut panel transitions to the open state (i.e. NOT when it’s toggled closed). Use this to close competing panels. |
onSortingChange |
OnChangeFn<SortingState> |
No | Controlled or uncontrolled TanStack Table sorting state handler. |
pageSize |
number |
No | Rows per page when using pagination (non-infinite) mode. |
pageSizeOptions |
number[] |
No | Options shown in the page-size selector. |
picklistCart |
PicklistCartConfig<TData> |
No | When provided, enables the PicklistCart feature: - adds a picklist checkbox column to the left of all other columns - highlights rows that are currently in the cart - renders a PicklistCart FAB that drives the SlideOutProvider drawer Requires a ancestor in the tree. |
productSlideOut |
ProductSlideOutConfig |
No | When provided, enables the ProductSlideOut panel for PRODUCT-type columns. |
searchable |
boolean |
No | Show global search input that scans searchable columns. |
selectable |
boolean |
No | Enable row selection checkboxes. |
selectedRows |
TData[] |
No | Controlled selected rows when selectable is enabled. |
sorting |
SortingState |
No | Controlled or initial TanStack Table sorting state. |
DataTableColumn
Section titled “DataTableColumn”| Prop | Type | Required | Description |
|---|---|---|---|
accessor |
keyof TData & string |
Yes | Key into the row data object. Required for every column. |
colorOptions |
ColorOption[] |
No | Required when filterType: 'color'. Swatch options with hex codes without #. |
columnType |
ColumnType |
No | Built-in cell renderer (PRODUCT, RFID, BADGE_BAR, CLASSIFICATION, PRICE). |
customDisplay |
(value: unknown, row: TData) => ReactNode |
No | Custom cell renderer receiving the raw accessor value and full row. |
filterBy |
boolean |
No | When true, includes this column in the filter bar or side panel. |
filterType |
'color' | 'range' | 'select' |
No | Filter UI style for filterBy: true columns. - 'select' — dropdown of distinct values (default when omitted) - 'color' — color swatch picker; requires colorOptions - 'range' — numeric min/max slider; requires rangeOptions |
headerTooltip |
ReactNode |
No | Optional tooltip content rendered next to the column header label via an InfoCircle icon. Accepts any ReactNode (text, styled spans, etc.). Takes effect for all column types except RFID (which has its own built-in segmented-quantity legend tooltip). |
hidden |
boolean |
No | When true, the column does not render as a visible table column but still participates in side-panel filtering. Defaults to false. |
label |
string |
Yes | Column header display text. |
mobilePriority |
boolean |
No | When true, always shown first in the mobile card view (before “View More”). |
offsiteEnabled |
boolean |
No | For columnType: 'RFID' columns only. When true, an Offsite segment is shown in the column-header tooltip (alongside Sales Floor and Back of House). Should mirror the store-level offsite feature flag so users are not shown a segment that has no data. Defaults to false. |
rangeOptions |
RangeFilterOptions |
No | Required when filterType: 'range'. Min/max bounds and optional step for the numeric range slider. |
searchAliases |
(string | { alias: string; field: string })[] |
No | Alternate field names included in global table search for this column. |
sortable |
boolean |
No | Enable column header sort control. |
sortBy |
string[] |
No | Server-side sort field names when accessor differs from API sort key. |
truncateAt |
number |
No | Truncate cell text after this character count with ellipsis. |
width |
string |
No | CSS width for the column (e.g. '120px', '20%'). |
Examples
Section titled “Examples”Minimal columns
Section titled “Minimal columns”import { DataTable } from '@nike/whisker-component-library';
const columns = [ { accessor: 'name', label: 'Name', sortable: true }, { accessor: 'status', label: 'Status', filterBy: true },];
<DataTable columns={columns} data={rows} ariaLabel="Products" />;Product column with slide-out
Section titled “Product column with slide-out”SlideOutProvider must be mounted at app level. Pass productSlideOut config to DataTable, not to columns.
// app root (once)<SlideOutProvider> <ModuleRoot /></SlideOutProvider>;
// inside your moduleconst columns = [{ accessor: 'product', label: 'Product', columnType: 'PRODUCT' }];
<DataTable columns={columns} data={products} productSlideOut={{ accessToken, storeId, isProd, }}/>;