Skip to content

DataTable

Product lists, inventory grids, operational tables needing sort/filter/pagination. Built-in column types: PRODUCT, RFID, BADGE_BAR, CLASSIFICATION, PRICE.

Simple static HTML tables — use Podium layout. Editable spreadsheet grids — WCL does not ship a data-grid editor.

  • Podium TextField
  • Podium Select
  • Podium Button
  • Podium Checkbox
  • Podium Text
  • SlideOutProvider (app-level, required for product drill-down only)
  • usePicklistCartStore
  • Column accessor must match row data keys exactly.
  • filterType: 'color' requires colorOptions with hex codes without #.
  • RFID columns need offsiteEnabled aligned with store config.
  • SlideOutProvider is an app-level singleton — do not wrap DataTable in its own; add it once near the app root.
  • Pass productSlideOut config on the DataTable prop, not on individual column definitions.
  • Use autoHeight only in pages with fixed chrome above the table.

Auto-generated from src/components/DataTable/DataTable.types.ts. Do not edit by hand. Run pnpm docs:props after changing source JSDoc.

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.
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%').
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" />;

SlideOutProvider must be mounted at app level. Pass productSlideOut config to DataTable, not to columns.

// app root (once)
<SlideOutProvider>
<ModuleRoot />
</SlideOutProvider>;
// inside your module
const columns = [{ accessor: 'product', label: 'Product', columnType: 'PRODUCT' }];
<DataTable
columns={columns}
data={products}
productSlideOut={{
accessToken,
storeId,
isProd,
}}
/>;