Table Guide

Table System Guide

Feature-complete DataTable with search, sort, filter, export, and bulk actions.

Table System Guide

The DataTable component handles every table use case in SentinelGrid: search, sort, filter, pagination, column visibility, bulk actions, and automatic mobile-card rendering — all from a single column config.

Overview

The DataTable is fully generic over your row type. You pass a columns array and a data array, plus optional callbacks for row clicks and bulk actions. Everything else — search box, filter dropdowns, sort headers, pagination — is built in.

Features

Search

Client-side fuzzy search across any subset of keys.

Filter

Per-column filter dropdowns with custom predicates.

Column visibility

Show or hide columns via a dropdown checklist.

Export

Bulk actions can trigger CSV, JSON, or custom export flows.

Sortable

Click any header to toggle asc/desc. Initial sort supported.

Mobile cards

Rows automatically render as cards on small viewports.

Live Example

Below is a DataTable wired to the mock incidents dataset. Try searching, sorting by clicking headers, filtering severity or status, paginating, and resizing the browser to see mobile cards kick in.

inc1High

Checkout API elevated 5xx rate in us-east-1

Investigating
inc2Medium

Billing invoice generation backlog

Monitoring
inc3Low

Auth service token validation errors in EU

Resolved
inc4Medium

Web app slow page loads (LCP regression)

Identified

Column Configuration

Each column is defined by a config object. The cell function returns JSX, sortValue enables sorting, and filterable + filterFn enable the filter dropdown.

Column definition
const columns: Column<Incident>[] = [
  {
    key: "id",
    header: "ID",
    cell: (row) => <span className="font-mono text-xs">{row.id}</span>,
    sortable: true,
    sortValue: (row) => row.id,
    width: "w-24",
  },
  {
    key: "severity",
    header: "Severity",
    cell: (row) => <SeverityBadge severity={row.severity} />,
    sortable: true,
    sortValue: (row) => row.severity,
    filterable: true,
    filterOptions: [
      { label: "Critical", value: "critical" },
      { label: "High", value: "high" },
    ],
    filterFn: (row, value) => row.severity === value,
    hideOnMobile: true,
  },
];

DataTable props

PropTypeDescription
columnsColumn<T>[]Column definitions
dataT[]Rows to render
rowKey(row: T) => stringStable key extractor
searchKeys(keyof T)[]Keys included in client-side search
pageSizenumberRows per page (default 10)
enableSelectionbooleanShow checkbox column
onRowClick(row: T) => voidRow click handler
bulkActionsBulkAction[]Actions shown when rows are selected
mobileCard(row: T) => ReactNodeCustom card render for mobile
stickyHeaderbooleanSticky table header (default true)

Mobile Cards

On viewports below the md breakpoint, the table body is replaced with a vertical card list. Provide a mobileCard render function to control the layout. Columns marked hideOnMobile: true are hidden in the table view but can still appear in your card.

Mobile card
const mobileCard = (row: Incident) => (
  <div className="p-3 space-y-1">
    <div className="flex items-center justify-between">
      <span className="font-mono text-xs text-primary">{row.id}</span>
      <SeverityBadge severity={row.severity} size="sm" />
    </div>
    <p className="text-sm font-medium truncate">{row.title}</p>
    <IncidentStatusBadge status={row.status} />
  </div>
);

<DataTable columns={columns} data={data} rowKey={(r) => r.id} mobileCard={mobileCard} />

Bulk Actions

When enableSelection is true and at least one row is checked, a bulk action bar appears above the table. Pass an array of actions; each receives the selected rows.

Bulk actions
<DataTable
  columns={columns}
  data={data}
  rowKey={(r) => r.id}
  enableSelection
  bulkActions={[
    { label: "Export CSV", icon: <Download className="w-3.5 h-3.5" />, onClick: (rows) => exportCsv(rows) },
    { label: "Acknowledge", onClick: (rows) => acknowledge(rows) },
    { label: "Close", onClick: (rows) => closeIncidents(rows), variant: "destructive" },
  ]}
/>

Pagination

Pagination is built-in with configurable pageSize. The footer shows the current range and total count, plus prev/next controls.

Command Palette

Search for a command to run...