

## Overview [#overview]

Use `interaction="row-selection"` with `enableRowSelection` to select eligible
rows by clicking the row or pressing Space. Add the checkbox column when users
also need explicit row and select-all controls.

Buttons, links, inputs, editable content, and `[data-grid-interactive]`
descendants retain their own behavior without selecting the row. Call
`event.preventDefault()` from a custom cell handler when it should own the
gesture.

## Row-click selection [#row-click-selection]

Set `enableMultiRowSelection` to `false` for single selection. The preview
switches between single and multiple selection.

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="DataGridRowSelectionScenario" />
  </Tab>

  <Tab value="Code">
    ```tsx
    const [selectionMode, setSelectionMode] =
      useState<"multiple" | "single">("multiple");

    const table = useDataGridTable({
      columns,
      data,
      getRowId: (row) => row.id,
      enableRowSelection: true,
      enableMultiRowSelection: selectionMode === "multiple",
    });

    <DataGrid interaction="row-selection" table={table}>
      <DataGrid.Viewport aria-label="Report sections" />
    </DataGrid>
    ```
  </Tab>
</Tabs>

The row-selection preset uses the same row-first keyboard model as
[Row Navigation](/components/data-grid/row-navigation). Up, Down, Home, and End
move row focus; Space toggles the focused row; Escape clears the selection and
returns focus to the viewport. Hierarchical models use treegrid semantics and
retain their expansion navigation.

## Per-row activation [#per-row-activation]

Pair `getRowCanActivate` with `onRowActivate` when specific rows should perform
an action instead of using the selection preset. Matching rows activate on
click or Enter; other eligible rows continue to select on click or Space.

```tsx
const table = useDataGridTable({
  columns,
  data,
  enableRowSelection: (row) => !row.getIsGrouped(),
});

<DataGrid
  getRowCanActivate={(row) => row.getIsGrouped()}
  interaction="row-selection"
  onRowActivate={({ row }) => row.toggleExpanded()}
  table={table}
>
  <DataGrid.Viewport aria-label="Grouped matters" />
</DataGrid>
```

Activation overrides only the matching row gesture. Selection remains native,
and an optional checkbox can still select any row allowed by
`enableRowSelection`. Both activation props are required together.

## Selection checkbox column [#selection-checkbox-column]

Set `rowSelectionColumn: true` when users should have explicit row and
select-all checkboxes. This convenience option enables row selection
when `enableRowSelection` is omitted. Supply `enableRowSelection` as a predicate
when eligibility differs per row. An explicit `enableRowSelection: false`
keeps both selection and the convenience column off.

The checkbox column is independent of the root interaction preset. It can
accompany passive tables, row navigation, row selection, or spreadsheets.
Checkbox interaction never activates a row or applies row-click selection
twice.

The column is always leading. It cannot be hidden, resized, grouped, sorted,
pinned, edited, or reordered. When a consumer column is pinned left, the
selection column becomes the first sticky column; otherwise it remains leading
and scrolls normally. It never appears in consumer `columnOrder` or
`columnPinning` state.

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="DataGridRowSelectionColumnScenario" />
  </Tab>

  <Tab value="Code">
    ```tsx
    const table = useDataGridTable({
      columns,
      data,
      getRowId: (row) => row.id,
      rowSelectionColumn: true,
    });

    <DataGrid
      interaction="row-navigation"
      onRowActivate={({ row }) => openMatter(row.original.id)}
      table={table}
    >
      <DataGrid.Viewport aria-label="Matters with row navigation and selection" />
    </DataGrid>
    ```
  </Tab>
</Tabs>

## API Reference [#api-reference]

### DataGrid props [#datagrid-props]

| Prop                | Type                                  | Default | Description                                                                                         |
| ------------------- | ------------------------------------- | ------- | --------------------------------------------------------------------------------------------------- |
| `interaction`       | `"row-selection"`                     | -       | Enables row focus, keyboard navigation, and row-click selection. Required.                          |
| `getRowCanActivate` | `(row) => boolean`                    | -       | Selects rows that activate instead of applying the row-selection gesture. Requires `onRowActivate`. |
| `onRowActivate`     | `DataGridRowActivationHandler<TData>` | -       | Handles activation for matching rows. Requires `getRowCanActivate`.                                 |

### Selection options [#selection-options]

DataGrid defaults `enableRowSelection` to `false`. Row-click selection and the
optional checkbox column share the same selection behavior, including
configured eligibility and Shift-range selection.

| Option                     | Type                              | Default         | Description                                                                                            |
| -------------------------- | --------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------ |
| `enableRowSelection`       | `boolean \| ((row) => boolean)`   | `false`         | Enables selection for every row or rows that match a predicate.                                        |
| `rowSelectionColumn`       | `boolean`                         | `false`         | Adds the fixed leading checkbox column and enables row selection when `enableRowSelection` is omitted. |
| `enableMultiRowSelection`  | `boolean \| ((row) => boolean)`   | `true`          | Allows rows to remain selected together. Strict `false` removes the select-all header.                 |
| `enableSubRowSelection`    | `boolean \| ((row) => boolean)`   | `true`          | Controls whether selecting a parent also selects eligible descendants.                                 |
| `enableRowRangeSelection`  | `boolean`                         | `true`          | Enables inclusive Shift-range selection.                                                               |
| `isRowRangeSelectionEvent` | `(event: unknown) => boolean`     | Shift-key event | Determines whether a selection gesture extends from the previous row.                                  |
| `onRowSelectionChange`     | `OnChangeFn<RowSelectionState>`   | State updater   | Receives row-selection updates when the consumer controls the slice.                                   |
| `getRowId`                 | `(row, index, parent?) => string` | Index-derived   | Supplies stable application IDs for selection state.                                                   |

### Selection methods [#selection-methods]

| API                         | Signature                                 | Description                                                  |
| --------------------------- | ----------------------------------------- | ------------------------------------------------------------ |
| `table.getSelectedRowIds`   | `() => string[]`                          | Returns all selected row IDs.                                |
| `table.getSelectedRowModel` | `() => RowModel<DataGridFeatures, TData>` | Returns selected rows from the core row model.               |
| `table.setRowSelection`     | `(updater) => void`                       | Updates row-selection state.                                 |
| `table.resetRowSelection`   | `(defaultState?) => void`                 | Restores initial selection, or clears it when passed `true`. |
| `row.getCanSelect`          | `() => boolean`                           | Returns whether the row is eligible for selection.           |
| `row.getIsSelected`         | `() => boolean`                           | Returns whether the row ID is selected.                      |
| `row.getIsSomeSelected`     | `() => boolean`                           | Returns whether some selectable descendants are selected.    |
| `row.toggleSelected`        | `(selected?, options?) => void`           | Toggles or sets the row and optionally its descendants.      |
