Skip to main content

Selection & bulk actions

Single or multi-row selection with a checkbox column. selectMode="all" uses include/exclude semantics so select all works across server pages without loading every row. When rows are selected, a bulk-actions bar appears with your custom actions.

Loading demo…
<DataTable
columns={columns}
data={data}
enableRowSelection
selectMode="page" // "page" | "all"
enableBulkActions
renderBulkActions={(selection) => (
<Button onClick={() => deleteRows(selection)}>Delete</Button>
)}
onSelectionChange={(s) => console.log(s)}
/>

Props

PropTypeDefaultDescription
enableRowSelectionboolean | (row) => booleanfalseAdd a selection checkbox column.
enableMultiRowSelectionbooleantrueAllow selecting multiple rows.
selectMode'page' | 'all''page'Select-all scope (include/exclude).
isRowSelectable({ row, id }) => booleanDisable selection for specific rows.
selectOnRowClickbooleanfalseToggle a row's selection by clicking anywhere in it.
enableBulkActionsbooleanfalseShow the bulk-actions bar.
renderBulkActions(selection) => ReactNodeCustom action buttons.
onSelectionChange(selection) => voidSelection changed.

The bulk-actions bar defaults to the primary palette; retint it with the --dt-bulkbar-bg / --dt-bulkbar-fg tokens, styleOverrides.bulkActionsToolbar, or slotProps.bulkActionsToolbar — see Toolbar → Bulk-actions bar.

Select by clicking the row

By default only the checkbox toggles selection. Set selectOnRowClick and a click anywhere in the row toggles its selection too:

<DataTable columns={columns} data={rows} enableRowSelection selectOnRowClick />

It respects single vs. multi mode (enableMultiRowSelection) and per-row selectability (isRowSelectable), and clicks on interactive cell content — the checkbox, the row expander, action buttons, an editing cell — don't trigger it (they stop propagation). It composes with onRowClick: if you set both, a row click toggles selection and calls your handler.

Clipboard copy

enableClipboardCopy adds a Copy action to the bulk-actions bar — copies the selected rows (visible, exportable columns) as tab-separated text that pastes straight into Sheets/Excel. Also available imperatively: apiRef.current.clipboard.copySelectedRows() (resolves the count actually copied). Hook onClipboardCopy for a toast.

Copy serializes the loaded selected rows. Under server pagination with selectMode="all" (exclude mode), only rows on the current page are copied — the same scope limit as any client-side bulk action over server data; copy all by routing through a server export instead.

Loading demo…
<DataTable columns={columns} data={data} enableRowSelection enableBulkActions enableClipboardCopy />

Selection state

onSelectionChange and apiRef.current.selection.getSelectionState() return { ids, type: 'include' \| 'exclude' }. In exclude mode (after select all in selectMode="all"), ids are the deselected rows — so the payload stays tiny even for millions of rows.