Skip to content

Commit

Permalink
[DataGrid] Allow to control the indeterminate checkbox behavior (#14247)
Browse files Browse the repository at this point in the history
  • Loading branch information
MBilalShafi authored Aug 29, 2024
1 parent d8f1654 commit 8e898bb
Show file tree
Hide file tree
Showing 17 changed files with 123 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as React from 'react';
import { DataGrid } from '@mui/x-data-grid';
import { useDemoData } from '@mui/x-data-grid-generator';

export default function CheckboxSelectionIndeterminateGrid() {
const { data } = useDemoData({
dataSet: 'Commodity',
rowLength: 10,
maxColumns: 5,
});

return (
<div style={{ width: '100%', height: 300 }}>
<DataGrid {...data} checkboxSelection indeterminateCheckboxAction="select" />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as React from 'react';
import { DataGrid } from '@mui/x-data-grid';
import { useDemoData } from '@mui/x-data-grid-generator';

export default function CheckboxSelectionIndeterminateGrid() {
const { data } = useDemoData({
dataSet: 'Commodity',
rowLength: 10,
maxColumns: 5,
});

return (
<div style={{ width: '100%', height: 300 }}>
<DataGrid {...data} checkboxSelection indeterminateCheckboxAction="select" />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<DataGrid {...data} checkboxSelection indeterminateCheckboxAction="select" />
7 changes: 7 additions & 0 deletions docs/data/data-grid/row-selection/row-selection.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ Always set the `checkboxSelection` prop to `true` even when providing a custom c
Otherwise, the data grid might remove your column.
:::

### Customize indeterminate checkbox behavior

The parent checkboxes (like "Select All" checkbox) when clicked in an indeterminate state will deselect the selected rows.
You can customize this behavior by using the [`indeterminateCheckboxAction` prop](/x/api/data-grid/data-grid/#data-grid-prop-indeterminateCheckboxAction).

{{"demo": "CheckboxSelectionIndeterminateGrid.js", "bg": "inline"}}

### Visible rows selection [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')

By default, when you click the "Select All" checkbox, all rows in the data grid are selected.
Expand Down
4 changes: 4 additions & 0 deletions docs/pages/x/api/data-grid/data-grid-premium.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@
},
"default": "false"
},
"indeterminateCheckboxAction": {
"type": { "name": "enum", "description": "'deselect'<br>&#124;&nbsp;'select'" },
"default": "\"deselect\""
},
"initialState": { "type": { "name": "object" } },
"isCellEditable": {
"type": { "name": "func" },
Expand Down
4 changes: 4 additions & 0 deletions docs/pages/x/api/data-grid/data-grid-pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@
},
"default": "false"
},
"indeterminateCheckboxAction": {
"type": { "name": "enum", "description": "'deselect'<br>&#124;&nbsp;'select'" },
"default": "\"deselect\""
},
"initialState": { "type": { "name": "object" } },
"isCellEditable": {
"type": { "name": "func" },
Expand Down
4 changes: 4 additions & 0 deletions docs/pages/x/api/data-grid/data-grid.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@
},
"default": "false"
},
"indeterminateCheckboxAction": {
"type": { "name": "enum", "description": "'deselect'<br>&#124;&nbsp;'select'" },
"default": "\"deselect\""
},
"initialState": { "type": { "name": "object" } },
"isCellEditable": {
"type": { "name": "func" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@
"ignoreValueFormatterDuringExport": {
"description": "If <code>true</code>, the Data Grid will not use <code>valueFormatter</code> when exporting to CSV or copying to clipboard. If an object is provided, you can choose to ignore the <code>valueFormatter</code> for CSV export or clipboard export."
},
"indeterminateCheckboxAction": {
"description": "If <code>select</code>, a group header checkbox in indeterminate state (like &quot;Select All&quot; checkbox) will select all the rows under it. If <code>deselect</code>, it will deselect all the rows under it. Works only if <code>checkboxSelection</code> is enabled."
},
"initialState": {
"description": "The initial state of the DataGridPremium. The data in it is set in the state on initialization but isn&#39;t controlled. If one of the data in <code>initialState</code> is also being controlled, then the control state wins."
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@
"ignoreValueFormatterDuringExport": {
"description": "If <code>true</code>, the Data Grid will not use <code>valueFormatter</code> when exporting to CSV or copying to clipboard. If an object is provided, you can choose to ignore the <code>valueFormatter</code> for CSV export or clipboard export."
},
"indeterminateCheckboxAction": {
"description": "If <code>select</code>, a group header checkbox in indeterminate state (like &quot;Select All&quot; checkbox) will select all the rows under it. If <code>deselect</code>, it will deselect all the rows under it. Works only if <code>checkboxSelection</code> is enabled."
},
"initialState": {
"description": "The initial state of the DataGridPro. The data in it will be set in the state on initialization but will not be controlled. If one of the data in <code>initialState</code> is also being controlled, then the control state wins."
},
Expand Down
3 changes: 3 additions & 0 deletions docs/translations/api-docs/data-grid/data-grid/data-grid.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@
"ignoreValueFormatterDuringExport": {
"description": "If <code>true</code>, the Data Grid will not use <code>valueFormatter</code> when exporting to CSV or copying to clipboard. If an object is provided, you can choose to ignore the <code>valueFormatter</code> for CSV export or clipboard export."
},
"indeterminateCheckboxAction": {
"description": "If <code>select</code>, a group header checkbox in indeterminate state (like &quot;Select All&quot; checkbox) will select all the rows under it. If <code>deselect</code>, it will deselect all the rows under it. Works only if <code>checkboxSelection</code> is enabled."
},
"initialState": {
"description": "The initial state of the DataGrid. The data in it will be set in the state on initialization but will not be controlled. If one of the data in <code>initialState</code> is also being controlled, then the control state wins."
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,14 @@ DataGridPremiumRaw.propTypes = {
}),
PropTypes.bool,
]),
/**
* If `select`, a group header checkbox in indeterminate state (like "Select All" checkbox)
* will select all the rows under it.
* If `deselect`, it will deselect all the rows under it.
* Works only if `checkboxSelection` is enabled.
* @default "deselect"
*/
indeterminateCheckboxAction: PropTypes.oneOf(['deselect', 'select']),
/**
* The initial state of the DataGridPremium.
* The data in it is set in the state on initialization but isn't controlled.
Expand Down
8 changes: 8 additions & 0 deletions packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,14 @@ DataGridProRaw.propTypes = {
}),
PropTypes.bool,
]),
/**
* If `select`, a group header checkbox in indeterminate state (like "Select All" checkbox)
* will select all the rows under it.
* If `deselect`, it will deselect all the rows under it.
* Works only if `checkboxSelection` is enabled.
* @default "deselect"
*/
indeterminateCheckboxAction: PropTypes.oneOf(['deselect', 'select']),
/**
* The initial state of the DataGridPro.
* The data in it will be set in the state on initialization but will not be controlled.
Expand Down
8 changes: 8 additions & 0 deletions packages/x-data-grid/src/DataGrid/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,14 @@ DataGridRaw.propTypes = {
}),
PropTypes.bool,
]),
/**
* If `select`, a group header checkbox in indeterminate state (like "Select All" checkbox)
* will select all the rows under it.
* If `deselect`, it will deselect all the rows under it.
* Works only if `checkboxSelection` is enabled.
* @default "deselect"
*/
indeterminateCheckboxAction: PropTypes.oneOf(['deselect', 'select']),
/**
* The initial state of the DataGrid.
* The data in it will be set in the state on initialization but will not be controlled.
Expand Down
2 changes: 2 additions & 0 deletions packages/x-data-grid/src/DataGrid/useDataGridProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ export const DATA_GRID_PROPS_DEFAULT_VALUES: DataGridPropsWithDefaultValues = {
hideFooterSelectedRowCount: false,
ignoreDiacritics: false,
ignoreValueFormatterDuringExport: false,
// TODO v8: Update to 'select'
indeterminateCheckboxAction: 'deselect',
keepColumnPositionIfDraggedOutside: false,
keepNonExistentRowsSelected: false,
loading: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,16 @@ const GridHeaderCheckbox = React.forwardRef<HTMLButtonElement, GridColumnHeaderP
isChecked ? 'checkboxSelectionUnselectAllRows' : 'checkboxSelectionSelectAllRows',
);

const checked =
rootProps.indeterminateCheckboxAction === 'select'
? isChecked && !isIndeterminate
: isChecked;

return (
<rootProps.slots.baseCheckbox
ref={ref}
indeterminate={isIndeterminate}
checked={isChecked}
checked={checked}
onChange={handleChange}
className={classes.root}
inputProps={{ 'aria-label': label }}
Expand Down
8 changes: 8 additions & 0 deletions packages/x-data-grid/src/models/props/DataGridProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,14 @@ export interface DataGridPropsWithDefaultValues<R extends GridValidRowModel = an
* @default false
*/
ignoreDiacritics: boolean;
/**
* If `select`, a group header checkbox in indeterminate state (like "Select All" checkbox)
* will select all the rows under it.
* If `deselect`, it will deselect all the rows under it.
* Works only if `checkboxSelection` is enabled.
* @default "deselect"
*/
indeterminateCheckboxAction: 'select' | 'deselect';
/**
* If `true`, the selection model will retain selected rows that do not exist.
* Useful when using server side pagination and row selections need to be retained
Expand Down
20 changes: 20 additions & 0 deletions packages/x-data-grid/src/tests/rowSelection.DataGrid.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,26 @@ describe('<DataGrid /> - Row selection', () => {
});
expect(grid('selectedRowCount')?.textContent).to.equal('1 row selected');
});

describe('prop: indeterminateCheckboxAction = "select"', () => {
it('should select all the rows when clicking on "Select All" checkbox in indeterminate state', () => {
render(<TestDataGridSelection checkboxSelection indeterminateCheckboxAction="select" />);
const selectAllCheckbox = screen.getByRole('checkbox', { name: 'Select all rows' });
fireEvent.click(screen.getAllByRole('checkbox', { name: /select row/i })[0]);
fireEvent.click(selectAllCheckbox);
expect(getSelectedRowIds()).to.deep.equal([0, 1, 2, 3]);
});
});

describe('prop: indeterminateCheckboxAction = "deselect"', () => {
it('should deselect all the rows when clicking on "Select All" checkbox in indeterminate state', () => {
render(<TestDataGridSelection checkboxSelection indeterminateCheckboxAction="deselect" />);
const selectAllCheckbox = screen.getByRole('checkbox', { name: 'Select all rows' });
fireEvent.click(screen.getAllByRole('checkbox', { name: /select row/i })[0]);
fireEvent.click(selectAllCheckbox);
expect(getSelectedRowIds()).to.deep.equal([]);
});
});
});

describe('prop: checkboxSelection = true (multi selection), with keyboard events', () => {
Expand Down

0 comments on commit 8e898bb

Please sign in to comment.