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 9 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
4 changes: 2 additions & 2 deletions docs/pages/api-docs/data-grid/grid-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ import { GridApi } from '@mui/x-data-grid-pro';
| <span class="prop-name">hideFilterPanel</span> | <span class="prop-type">() =&gt; void</span> | Hides the filter panel. |
| <span class="prop-name">hidePreferences</span> | <span class="prop-type">() =&gt; void</span> | Hides the preferences panel. |
| <span class="prop-name">isCellEditable</span> | <span class="prop-type">(params: GridCellParams) =&gt; boolean</span> | Controls if a cell is editable. |
| <span class="prop-name">isRowSelected</span> | <span class="prop-type">(id: GridRowId) =&gt; boolean</span> | Returns the current selection status of a row |
| <span class="prop-name">publishEvent</span> | <span class="prop-type">(name: string, params?: any, event?: MuiEvent&lt;MouseEvent \| UIEvent \| Event \| SyntheticEvent&lt;Element, Event&gt; \| ClipboardEvent \| ProgressEvent&lt;EventTarget&gt; \| ErrorEvent \| AnimationEvent \| InputEvent \| FocusEvent \| CompositionEvent \| DragEvent \| FormDataEvent \| PointerEvent \| KeyboardEvent \| SecurityPolicyViolationEvent \| TouchEvent \| TransitionEvent \| WheelEvent&gt;) =&gt; void</span> | Emits an event. |
| <span class="prop-name">isRowSelected</span> | <span class="prop-type">(id: GridRowId) =&gt; boolean</span> | Determines if a row is selected or not. |
| <span class="prop-name">publishEvent</span> | <span class="prop-type">(name: string, params?: any, event?: MuiEvent&lt;MouseEvent \| UIEvent \| Event \| SyntheticEvent&lt;Element, Event&gt; \| ProgressEvent&lt;EventTarget&gt; \| ClipboardEvent \| ErrorEvent \| AnimationEvent \| InputEvent \| FocusEvent \| CompositionEvent \| DragEvent \| FormDataEvent \| PointerEvent \| KeyboardEvent \| SecurityPolicyViolationEvent \| TouchEvent \| TransitionEvent \| WheelEvent&gt;) =&gt; void</span> | Emits an event. |
| <span class="prop-name">resize</span> | <span class="prop-type">() =&gt; void</span> | Triggers a resize of the component and recalculation of width and height. |
| <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. |
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/api-docs/data-grid/grid-selection-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
{
"name": "isRowSelected",
"description": "Returns the current selection status of a row",
"description": "Determines if a row is selected or not.",
"type": "(id: GridRowId) => boolean"
},
{
Expand Down
2 changes: 1 addition & 1 deletion packages/grid/_modules_/grid/components/GridViewport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const GridViewport: ViewportType = React.forwardRef<HTMLDivElement, {}>(
<GridRow
key={id}
id={id}
selected={!!selectionLookup.get(id)}
selected={selectionLookup[id] !== undefined}
rowIndex={renderState.renderContext!.firstRowIdx! + idx}
>
<GridEmptyCell width={renderState.renderContext!.leftEmptyWidth} height={rowHeight} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ export const useGridKeyboard = (apiRef: GridApiRef): void => {

if (isSpaceKey(event.key) && event.shiftKey) {
event.preventDefault();
apiRef.current.selectRow(cellParams.id, undefined, false);
apiRef.current.selectRow(
cellParams.id,
!apiRef.current.isRowSelected(cellParams.id),
false,
);
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ export const useGridSelection = (apiRef: GridApiRef, props: GridComponentProps):

event.stopPropagation();
flaviendelangle marked this conversation as resolved.
Show resolved Hide resolved
} else {
const resetSelection = !canHaveMultipleSelection || (!hasCtrlKey && !checkboxSelection);
// Without checkboxSelection, multiple selection is only allowed if CTRL is pressed
const isMultipleSelectionDisabled = !checkboxSelection && !hasCtrlKey;
const resetSelection = !canHaveMultipleSelection || isMultipleSelectionDisabled;

if (resetSelection) {
apiRef.current.selectRow(
Expand All @@ -194,7 +196,13 @@ export const useGridSelection = (apiRef: GridApiRef, props: GridComponentProps):

lastRowToggledByClick.current = params.id;
},
[apiRef, checkboxSelection, canHaveMultipleSelection, disableSelectionOnClick, checkboxSelection],
[
apiRef,
checkboxSelection,
canHaveMultipleSelection,
disableSelectionOnClick,
checkboxSelection,
],
);

useGridApiEventHandler(apiRef, GridEvents.rowClick, handleRowClick);
Expand Down
6 changes: 3 additions & 3 deletions packages/grid/_modules_/grid/models/api/gridSelectionApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { GridRowId, GridRowModel } from '../gridRows';
export interface GridSelectionApi {
/**
* Change the selection state of a row.
* @param {GridRowId} id The id of the row
* @param {GridRowId} id The id of the row.
* @param {boolean} isSelected Pass `false` to unselect a row. Default is `true`.
* @param {boolean} resetSelection Whether to reset the already selected rows or not. Default is `false`.
*/
Expand All @@ -32,8 +32,8 @@ export interface GridSelectionApi {
resetSelection?: boolean,
) => void;
/**
* Returns the current selection status of a row
* @param {GridRowId} id The id of the row
* Determines if a row is selected or not.
* @param {GridRowId} id The id of the row.
* @returns {boolean} A boolean indicating if the row is selected.
*/
isRowSelected: (id: GridRowId) => boolean;
Expand Down
30 changes: 25 additions & 5 deletions packages/grid/data-grid/src/tests/selection.DataGrid.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,31 @@ describe('<DataGrid /> - Selection', () => {
/>,
);

// TODO: ID 1 should not be selected
// expect(getSelectedRowIndexes()).to.deep.equal([0]);
// TODO: ID 1 and 3 should not be selected
// setProps({ selectionModel: [0, 1, 2, 3] });
// expect(getSelectedRowIndexes()).to.deep.equal([0, 2])
expect(getSelectedRowIndexes()).to.deep.equal([0]);
setProps({ selectionModel: [0, 1, 2, 3] });
expect(getSelectedRowIndexes()).to.deep.equal([0, 2]);
});

it('should filter out unselectable rows when the selectionModel prop changes', () => {
const { setProps } = render(
<TestDataGridSelection
selectionModel={[1]}
isRowSelectable={(params) => params.id > 0}
checkboxSelection
/>,
);
expect(getSelectedRowIndexes()).to.deep.equal([1]);
expect(getColumnHeaderCell(0).querySelector('input')).to.have.attr(
'data-indeterminate',
'true',
);

setProps({ selectionModel: [0] });
expect(getColumnHeaderCell(0).querySelector('input')).to.have.attr(
'data-indeterminate',
'false',
);
expect(getSelectedRowIndexes()).to.deep.equal([]);
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { expect } from 'chai';
import { spy } from 'sinon';
import { getColumnValues, getSelectedRowIndexes } from 'test/utils/helperFn';
import { getColumnValues, getRow, getSelectedRowIndexes } from 'test/utils/helperFn';
import {
// @ts-expect-error need to migrate helpers to TypeScript
screen,
Expand Down