Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DataGrid] Allow to select range of rows with shift key #2456

Merged
merged 61 commits into from
Oct 5, 2021
Merged
Show file tree
Hide file tree
Changes from 54 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
f3e4234
[DataGrid] Allow to select range of rows with shift key
flaviendelangle Aug 26, 2021
903fb99
Work
flaviendelangle Aug 26, 2021
4bf5240
Rework
flaviendelangle Aug 27, 2021
373f09c
Fix
flaviendelangle Aug 27, 2021
244220b
Fix
flaviendelangle Aug 27, 2021
3c75548
Merge
flaviendelangle Sep 1, 2021
ad00397
Work
flaviendelangle Sep 1, 2021
5e04bab
Regen docs
flaviendelangle Sep 1, 2021
d990c31
Add tests
flaviendelangle Sep 1, 2021
1523956
Fix
flaviendelangle Sep 1, 2021
4ce88ad
[DataGrid] Clean the selection public api
flaviendelangle Sep 2, 2021
49590a5
Work
flaviendelangle Sep 2, 2021
d6e61c1
Merge
flaviendelangle Sep 2, 2021
02d512c
Fix
flaviendelangle Sep 2, 2021
b247afa
Merge branch 'rework-selection-api' into selection-range
flaviendelangle Sep 2, 2021
0886d10
Fix
flaviendelangle Sep 2, 2021
57d837e
Merge
flaviendelangle Sep 2, 2021
781f7bd
Merge
flaviendelangle Sep 3, 2021
e98c4d1
Fix
flaviendelangle Sep 3, 2021
47b8a64
Merge
flaviendelangle Sep 8, 2021
153f03d
Fix
flaviendelangle Sep 8, 2021
614e76f
Fix shit + space key
flaviendelangle Sep 8, 2021
24185b2
Fix
flaviendelangle Sep 8, 2021
3d0c4e3
Fix
flaviendelangle Sep 8, 2021
e4c1a1d
Prettier
flaviendelangle Sep 8, 2021
0796451
Merge
flaviendelangle Sep 8, 2021
a7e00cc
Merge
flaviendelangle Sep 10, 2021
5af8328
Working improvments
flaviendelangle Sep 10, 2021
5f12225
Improve perfs
flaviendelangle Sep 10, 2021
89d1567
Code review : remove DOM selection
flaviendelangle Sep 13, 2021
927a5b0
Fix
flaviendelangle Sep 13, 2021
c72829e
Code review
flaviendelangle Sep 13, 2021
e7cab9c
Build doc api
flaviendelangle Sep 13, 2021
e14d0e2
Merge branch 'next' into selection-range
flaviendelangle Sep 13, 2021
e9bd3a6
Merge
flaviendelangle Sep 13, 2021
dff7cb1
Fix
flaviendelangle Sep 13, 2021
b465773
Merge branch 'next' into selection-range
flaviendelangle Sep 14, 2021
f9ee108
Update feature comparison
flaviendelangle Sep 14, 2021
86fbd9d
Update feature comparison
flaviendelangle Sep 14, 2021
a5d8c72
Code review
flaviendelangle Sep 15, 2021
51f9766
Code review
flaviendelangle Sep 15, 2021
b200b3d
Fix
flaviendelangle Sep 15, 2021
7b4edf0
Merge branch 'next' into selection-range
flaviendelangle Sep 27, 2021
6bc387c
Handle range selection on checkboxes
flaviendelangle Sep 27, 2021
c6e2cc2
Fix docs
flaviendelangle Sep 27, 2021
1cbc155
Update docs/src/pages/components/data-grid/selection/selection.md
flaviendelangle Sep 29, 2021
30e7d8d
Code review
flaviendelangle Sep 29, 2021
8801185
Update docs/src/pages/components/data-grid/getting-started/getting-st…
flaviendelangle Sep 29, 2021
5ba4eeb
Update docs/src/pages/components/data-grid/accessibility/accessibilit…
flaviendelangle Sep 29, 2021
f81bd2e
prettier
flaviendelangle Sep 29, 2021
d8b1323
Remove console
flaviendelangle Sep 29, 2021
fb1f202
Use events for selection checkboxes
flaviendelangle Sep 29, 2021
4a9ca83
Proptypes
flaviendelangle Sep 29, 2021
02e5b52
Fix
flaviendelangle Sep 29, 2021
c61bc1d
Merge branch 'next' into selection-range
flaviendelangle Oct 1, 2021
946ed4f
Code review
flaviendelangle Oct 1, 2021
c014676
Code review
flaviendelangle Oct 4, 2021
95b5def
Remove header checkbox improvments
flaviendelangle Oct 5, 2021
13c9d36
Update packages/grid/_modules_/grid/constants/eventsConstants.ts
flaviendelangle Oct 5, 2021
7be97ba
Clean expandSelection
flaviendelangle Oct 5, 2021
94d40ce
Regen docs
flaviendelangle Oct 5, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/pages/api-docs/data-grid/grid-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import { GridApi } from '@mui/x-data-grid-pro';
| <span class="prop-name">scroll</span> | <span class="prop-type">(params: Partial&lt;GridScrollParams&gt;) =&gt; void</span> | Triggers the viewport to scroll to the given positions (in pixels). |
| <span class="prop-name">scrollToIndexes</span> | <span class="prop-type">(params: Partial&lt;GridCellIndexCoordinates&gt;) =&gt; boolean</span> | Triggers the viewport to scroll to the cell at indexes given by `params`.<br />Returns `true` if the grid had to scroll to reach the target. |
| <span class="prop-name">selectRow</span> | <span class="prop-type">(id: GridRowId, isSelected?: boolean, resetSelection?: boolean) =&gt; void</span> | Change the selection state of a row. |
| <span class="prop-name">selectRowRange</span> | <span class="prop-type">(range: { endId: GridRowId; startId: GridRowId }, isSelected?: boolean, resetSelection?: boolean) =&gt; void</span> | Change the selection state of all the selectable rows in a range. |
| <span class="prop-name">selectRows</span> | <span class="prop-type">(ids: GridRowId[], isSelected?: boolean, resetSelection?: boolean) =&gt; void</span> | Change the selection state of multiple rows. |
| <span class="prop-name">setCellFocus</span> | <span class="prop-type">(id: GridRowId, field: string) =&gt; void</span> | Sets the focus to the cell at the given `id` and `field`. |
| <span class="prop-name">setCellMode</span> | <span class="prop-type">(id: GridRowId, field: string, mode: GridCellMode) =&gt; void</span> | Sets the mode of a cell. |
Expand Down
5 changes: 5 additions & 0 deletions docs/pages/api-docs/data-grid/grid-selection-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
"description": "Change the selection state of a row.",
"type": "(id: GridRowId, isSelected?: boolean, resetSelection?: boolean) => void"
},
{
"name": "selectRowRange",
"description": "Change the selection state of all the selectable rows in a range.",
"type": "(range: { endId: GridRowId; startId: GridRowId }, isSelected?: boolean, resetSelection?: boolean) => void"
},
{
"name": "selectRows",
"description": "Change the selection state of multiple rows.",
Expand Down
23 changes: 12 additions & 11 deletions docs/src/pages/components/data-grid/accessibility/accessibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,18 @@ Use the arrow keys to move the focus.

### Selection

| Keys | Description |
| -------------------------------------------------------------------------------------------------: | :--------------------------------------------------- |
| <kbd class="key">Shift</kbd> + <kbd class="key">Space</kbd> | Select the current row |
| <kbd class="key">Shift</kbd> + <kbd class="key">Space</kbd> + <kbd class="key">Arrow Up/Down</kbd> | Select the current row and the row above or below |
| <kbd class="key">CTRL</kbd> + <kbd class="key">A</kbd> | Select all rows |
| <kbd class="key">CTRL</kbd> + <kbd class="key">C</kbd> | Copy the currently selected row(s) |
| <kbd class="key">ALT</kbd> + <kbd class="key">C</kbd> | Copy the currently selected row(s) including headers |
| <kbd class="key">CTRL</kbd> + Click on cell | Enable multi-selection |
| <kbd class="key">CTRL</kbd> + Click on a selected row | Deselect the row |
| <kbd class="key">Enter</kbd> | Sort column when column header is focused |
| <kbd class="key">CTRL</kbd> + <kbd class="key">Enter</kbd> | Open column menu when column header is focused |
| Keys | Description |
| -------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------- |
| <kbd class="key">Shift</kbd> + <kbd class="key">Space</kbd> | Select the current row |
| <kbd class="key">Shift</kbd> + <kbd class="key">Space</kbd> + <kbd class="key">Arrow Up/Down</kbd> | Select the current row and the row above or below |
| <kbd class="key">Shift</kbd> + Click on cell | Select the range of rows between the first and the last clicked rows |
| <kbd class="key">CTRL</kbd> + <kbd class="key">A</kbd> | Select all rows |
| <kbd class="key">CTRL</kbd> + <kbd class="key">C</kbd> | Copy the currently selected row(s) |
| <kbd class="key">ALT</kbd> + <kbd class="key">C</kbd> | Copy the currently selected row(s) including headers |
| <kbd class="key">CTRL</kbd> + Click on cell | Enable multi-selection |
| <kbd class="key">CTRL</kbd> + Click on a selected row | Deselect the row |
| <kbd class="key">Enter</kbd> | Sort column when column header is focused |
| <kbd class="key">CTRL</kbd> + <kbd class="key">Enter</kbd> | Open column menu when column header is focused |

### Sorting

Expand Down
8 changes: 8 additions & 0 deletions docs/src/pages/components/data-grid/events/events.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@
"name": "filterModelChange",
"description": "Fired when the filter model changes.\nCalled with a GridFilterModel object."
},
{
"name": "headerSelectionCheckboxChange",
"description": "Fired when the value of the selection checkbox of the header is changed\nCalled with a GridHeaderSelectionCheckboxParams object"
},
{ "name": "pageChange", "description": "Fired when the page changes." },
{ "name": "pageSizeChange", "description": "Fired when the page size changes." },
{
Expand Down Expand Up @@ -159,6 +163,10 @@
"name": "rowOver",
"description": "Fired when a <code>mouseover</code> event happens in a row. Called with a <a href=\"/api/data-grid/grid-row-params/\">GridRowParams</a> object."
},
{
"name": "rowSelectionCheckboxChange",
"description": "Fired when the value of the selection checkbox of a row is changed\nCalled with a GridRowSelectionCheckboxParams object"
},
{
"name": "rowsScroll",
"description": "Fired during the scroll of the grid viewport. Called with a GridScrollParams object."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,10 @@ The enterprise components come in two plans: Pro and Premium.
| [Row spanning](/components/data-grid/rows/#row-spanning) | 🚧 | 🚧 | 🚧 |
| [Row reordering](/components/data-grid/rows/#row-reorder) | ❌ | 🚧 | 🚧 |
| **Selection** | | | |
| [Row selection](/components/data-grid/selection/#single-row-selection) | ✅ | ✅ | ✅ |
| [Multi-row selection](/components/data-grid/selection/#multiple-row-selection) | ❌ | ✅ | ✅ |
| [Range selection](/components/data-grid/selection/#range-selection) | ❌ | ❌ | 🚧 |
| [Single row selection](/components/data-grid/selection/#single-row-selection) | ✅ | ✅ | ✅ |
| [Checkbox selection](/components/data-grid/selection/#checkbox-selection) | ✅ | ✅ | ✅ |
| [Multiple row selection](/components/data-grid/selection/#multiple-row-selection) | ❌ | ✅ | ✅ |
| [Cell range selection](/components/data-grid/selection/#range-selection) | ❌ | ❌ | 🚧 |
| **Filtering** | | | |
| [Quick filter](/components/data-grid/filtering/#quick-filter) | 🚧 | 🚧 | 🚧 |
| [Column filters](/components/data-grid/filtering/#column-filters) | ✅ | ✅ | ✅ |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import { useDemoData } from '@mui/x-data-grid-generator';
export default function MultipleRowSelectionGrid() {
const { data } = useDemoData({
dataSet: 'Commodity',
rowLength: 10,
rowLength: 100,
maxColumns: 6,
});

return (
<div style={{ height: 400, width: '100%' }}>
<DataGridPro {...data} />
<DataGridPro {...data} pagination pageSize={10} />
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import { useDemoData } from '@mui/x-data-grid-generator';
export default function MultipleRowSelectionGrid() {
const { data } = useDemoData({
dataSet: 'Commodity',
rowLength: 10,
rowLength: 100,
maxColumns: 6,
});

return (
<div style={{ height: 400, width: '100%' }}>
<DataGridPro {...data} />
<DataGridPro {...data} pagination pageSize={10} />
</div>
);
}
5 changes: 4 additions & 1 deletion docs/src/pages/components/data-grid/selection/selection.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ For the `DataGridPro`, you need to disable multiple row selection with `disableM

### Multiple row selection [<span class="pro"></span>](https://material-ui.com/store/items/material-ui-pro/)

To select multiple rows on the `DataGridPro` component, hold the <kbd class="key">CTRL</kbd> key while selecting rows.
On the `DataGridPro` component, you can select multiple rows in two ways:

- To select multiple independent rows, hold the <kbd class="key">CTRL</kbd> key while selecting rows.
- To select a range of rows, hold the <kbd class="key">SHIFT</kbd> key while selecting rows.

{{"demo": "pages/components/data-grid/selection/MultipleRowSelectionGrid.js", "disableAd": true, "bg": "inline"}}

Expand Down
2 changes: 1 addition & 1 deletion packages/grid/_modules_/grid/components/GridRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function GridRow(props: GridRowProps) {
[apiRef, id],
);

const mouseEventsHandlers = React.useMemo(
const mouseEventsHandlers = React.useMemo<Partial<React.HTMLAttributes<HTMLDivElement>>>(
() => ({
onClick: publish(GridEvents.rowClick),
onDoubleClick: publish(GridEvents.rowDoubleClick),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { getDataGridUtilityClass } from '../../gridClasses';
import { composeClasses } from '../../utils/material-ui-utils';
import { GridComponentProps } from '../../GridComponentProps';
import { GridRowSelectionCheckboxParams } from '../../models/params/gridRowSelectionCheckboxParams';

type OwnerState = { classes: GridComponentProps['classes'] };

Expand All @@ -35,7 +36,8 @@ const GridCellCheckboxForwardRef = React.forwardRef<HTMLInputElement, GridCellPa
const element = apiRef.current.getCellElement(id, field);

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
apiRef.current.selectRow(id, event.target.checked, false);
const params: GridRowSelectionCheckboxParams = { value: event.target.checked, id };
apiRef.current.publishEvent(GridEvents.rowSelectionCheckboxChange, params, event);
};

const handleClick = (event: React.MouseEvent<HTMLInputElement>) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import * as React from 'react';
import PropTypes from 'prop-types';
import { GridEvents } from '../../constants/eventsConstants';
import { useGridSelector } from '../../hooks/features/core/useGridSelector';
import { gridPaginatedVisibleSortedGridRowIdsSelector } from '../../hooks/features/pagination/gridPaginationSelector';
import { visibleSortedGridRowIdsSelector } from '../../hooks/features/filter/gridFilterSelector';
import { gridTabIndexColumnHeaderSelector } from '../../hooks/features/focus/gridFocusStateSelector';
import { gridRowCountSelector } from '../../hooks/features/rows/gridRowsSelector';
import { gridSelectionStateSelector } from '../../hooks/features/selection/gridSelectionSelector';
Expand All @@ -14,6 +12,7 @@ import { getDataGridUtilityClass } from '../../gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { composeClasses } from '../../utils/material-ui-utils';
import { GridComponentProps } from '../../GridComponentProps';
import { GridHeaderSelectionCheckboxParams } from '../../models/params/gridHeaderSelectionCheckboxParams';

type OwnerState = { classes: GridComponentProps['classes'] };

Expand Down Expand Up @@ -52,15 +51,12 @@ const GridHeaderCheckbox = React.forwardRef<HTMLInputElement, GridColumnHeaderPa
const isChecked = (totalSelectedRows > 0 && totalSelectedRows === totalRows) || isIndeterminate;

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const checked = event.target.checked;
const params: GridHeaderSelectionCheckboxParams = {
value: event.target.checked,
indeterminate: event.target.indeterminate,
flaviendelangle marked this conversation as resolved.
Show resolved Hide resolved
};

const shouldLimitSelectionToCurrentPage =
rootProps.checkboxSelectionVisibleOnly && rootProps.pagination;

const rowsToBeSelected = shouldLimitSelectionToCurrentPage
? gridPaginatedVisibleSortedGridRowIdsSelector(apiRef.current.state)
: visibleSortedGridRowIdsSelector(apiRef.current.state);
apiRef.current.selectRows(rowsToBeSelected, checked, !event.target.indeterminate);
apiRef.current.publishEvent(GridEvents.headerSelectionCheckboxChange, params);
};

const tabIndex = tabIndexState !== null && tabIndexState.field === props.field ? 0 : -1;
Expand Down
11 changes: 10 additions & 1 deletion packages/grid/_modules_/grid/constants/eventsConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export enum GridEvents {
* Fired when a cell is double-clicked. Called with a [[GridCellParams]] object.
*/
cellDoubleClick = 'cellDoubleClick',

/**
* Fired when a `mousedown` event happens in a cell. Called with a [[GridCellParams]] object.
*/
Expand Down Expand Up @@ -238,6 +237,16 @@ export enum GridEvents {
* Called with a [[GridSelectionModelChangeParams]] object.
*/
selectionChange = 'selectionChange',
/**
* Fired when the value of the selection checkbox of a row is changed
* Called with a [[GridRowSelectionCheckboxParams]] object
flaviendelangle marked this conversation as resolved.
Show resolved Hide resolved
*/
rowSelectionCheckboxChange = 'rowSelectionCheckboxChange',
/**
* Fired when the value of the selection checkbox of the header is changed
* Called with a [[GridHeaderSelectionCheckboxParams]] object
*/
headerSelectionCheckboxChange = 'headerSelectionCheckboxChange',
/**
* Fired when the page changes.
*/
Expand Down
Loading