Skip to content

DataTable

Rows of data people sort, search, select and act on: sortable headers, checkbox selection, bulk actions and a menu per row.

  • Pro
  • Version 2.0.0-rc.1
  • APG pattern: Grid (table with sortable headers, row selection and row actions)

Examples

Still previews of the real component, rendered from its stories. Pro code isn’t public, so nothing in them responds. Switch the theme and density for every preview at once.

Default

NameEmailRoleSeatsJoined
Ana Costaana@northwind.co.ukMember121 May 2026
Kofi Mensahkofi@northwind.co.ukMember19 Jul 2026
Li Weili@northwind.co.ukViewer030 Sept 2026
Priya Shahpriya@northwind.co.ukOwner414 Jan 2026
Tom Ellistom@northwind.co.ukAdmin22 Mar 2026

Select, search and bulk actions

1 selected

NameEmailRoleSeatsJoinedActions
Priya Shahpriya@northwind.co.ukOwner414 Jan 2026
Tom Ellistom@northwind.co.ukAdmin22 Mar 2026
Ana Costaana@northwind.co.ukMember121 May 2026
Kofi Mensahkofi@northwind.co.ukMember19 Jul 2026
Li Weili@northwind.co.ukViewer030 Sept 2026

Empty

No pending invites. Invite someone from Team settings.

Tokens

The 26 design tokens DataTable reads, with the value each has in the theme and density chosen above. Change a token and the component follows, in Figma and in code.

Show all 26 tokens
Tokens DataTable reads
TokenValue nowCSS variable
checkbox.bg…--sd-checkbox-bg
checkbox.bg-checked…--sd-checkbox-bg-checked
checkbox.border…--sd-checkbox-border
checkbox.border-width…--sd-checkbox-border-width
checkbox.mark…--sd-checkbox-mark
checkbox.radius…--sd-checkbox-radius
checkbox.size…--sd-checkbox-size
color.bg.brand-subtle…--sd-color-bg-brand-subtle
color.bg.muted…--sd-color-bg-muted
color.bg.subtle…--sd-color-bg-subtle
color.border.default…--sd-color-border-default
color.border.subtle…--sd-color-border-subtle
color.icon.default…--sd-color-icon-default
color.icon.strong…--sd-color-icon-strong
color.text.default…--sd-color-text-default
color.text.secondary…--sd-color-text-secondary
shape.radius-surface…--sd-shape-radius-surface
spacing.gap.md…--sd-spacing-gap-md
spacing.gap.sm…--sd-spacing-gap-sm
spacing.gap.xs…--sd-spacing-gap-xs
spacing.inset.md…--sd-spacing-inset-md
spacing.inset.sm…--sd-spacing-inset-sm
spacing.inset.xl…--sd-spacing-inset-xl
spacing.inset.xs…--sd-spacing-inset-xs
spacing.stack.sm…--sd-spacing-stack-sm
target.min…--sd-target-min

Install

Pro components come as source from the SuperDuper registry, with a licence key from Solo, Team or Studio. The registry and checkout aren’t open yet.

Add it from the registry (Pro licence key)

npx shadcn@latest add @superduperui/data-table

Then import it

import { DataTable } from "@/components/ui/data-table"

Props

DataTable props
PropTypeWhat it does
aria-labelrequiredstringNames the table (required).
columnsrequiredDataTableColumn<T>[]
rowsrequiredT[]
selectionMode'none' | 'single' | 'multiple'Default 'none'Row selection with checkboxes. Default none.
selectedKeysSelection
defaultSelectedKeysSelection
onSelectionChange(keys: Selection) => void
defaultSort{ column: string; direction: 'ascending' | 'descending' }Initial sort.
searchLabelstringShow a search field above the table that filters rows; this is its label.
bulkActions(selected: T[], clear: () => void) => ReactNodeActions shown above the table while rows are selected (e.g. Delete selected).
rowActions(row: T) => ReactNodeMenuItems for each row's action menu (adds a final column with an IconButton).
onRowAction(action: Key, row: T) => voidCalled with the MenuItem id and the row when a row action is chosen.
emptyStateReactNodeShown in the body when there are no rows (or no matches).
classNamestring

When to use it

Use it for

  • Admin lists: members, invoices, orders, projects
  • Any table where people select rows to act on them

Use something else for

  • Read-only data: use Table
  • A list of one thing with one action each: use a list
  • Very large data sets (thousands of rows): add server paging with Pagination

Accessibility

Screen readers announce "Team members, table, 6 rows"; on a row "Select Ana Costa, checkbox, not checked"; on a header "Name, sorted ascending".

WCAG 2.2 AAA criteria the component meets in Comfortable density: 1.4.6, 1.4.9, 2.1.3, 2.3.2, 2.4.13, 2.5.5, 2.5.6.

Comfortable rows are 44px (AAA). Compact rows are 24px and meet AA (2.5.8), not AAA: the documented exception.

What your product still has to do

  • Confirm or allow undo for bulk delete
  • Mark one column isRowHeader so selection and actions are named after the row

Shared patterns it ships with: 3.3.6 (bulk delete pairs with AlertDialog or undo); 2.4.8 (row header names every row action).

This release’s test results

Test results for DataTable in this release
axe-core (WCAG A, AA, AAA and best practice)80 runs across every story, theme, density and width: 0 violations
Rendered text contrast605 text runs: 0 below 7:1, lowest 8.43:1
Target size58 targets: 0 under 44px in Comfortable
Focus appearance (2.4.13)114 focus stops in 3 browser engines: all pass
Keyboard scriptChromium 8 of 8, Firefox 8 of 8, WebKit 8 of 8

Manual passes with VoiceOver and NVDA haven’t been done yet.

Keyboard

Each step is scripted and run in Chromium, Firefox and WebKit.

DataTable keyboard steps
KeyWhat happens
TabTab reaches the search field
TabTab reaches the bulk action (one row is selected)
TabTab reaches Clear selection
TabTab enters the grid once, on the selected row
ArrowDownDown moves to the next row
SpaceSpace selects the row; the bulk action counts it
ArrowRightRight moves into the row, to its checkbox
ArrowUpUp moves to the same cell in the row above

In Figma

The Figma component is DataTable, with Selection (None, Single, Multiple); State (Default, Empty, Some selected). The Figma library isn’t published yet.

Figma to code: Selection → selectionMode (None = "none", Single = "single", Multiple = "multiple"); Search label → searchLabel when Show search; Show bulk actions → bulkActions; Show row actions → rowActions; State (Default, Empty = emptyState (with rows=[]), Some selected); Rows → rows (data) with columns[].cell; nested Header → columns; nested Row → rows; nested Bulk action → bulkActions.