-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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] Improve selection with keyboard #4157
[DataGrid] Improve selection with keyboard #4157
Conversation
These are the results for the performance tests:
|
packages/grid/x-data-grid/src/hooks/features/selection/useGridSelection.ts
Show resolved
Hide resolved
@@ -64,6 +63,7 @@ export const useDataGridComponent = (props: DataGridProcessedProps) => { | |||
useGridInitializeState(rowsMetaStateInitializer, apiRef, props); | |||
useGridInitializeState(columnMenuStateInitializer, apiRef, props); | |||
|
|||
useGridKeyboardNavigation(apiRef, props); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useGridSelection
must consume the cellKeydown
after the navigation have been applied.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the preview, it seems you did not fix the issue #4156
In expandRowRangeSelection
, there is
if (startIndex > endIndex) {
endId = visibleRowIds[endIndex + 1];
} else {
endId = visibleRowIds[endIndex - 1];
}
Which forget the case when user click on the same cell
else if (startIndex === endIndex) {
endId = visibleRowIds[endIndex];
}
packages/grid/x-data-grid/src/hooks/features/selection/useGridSelection.ts
Outdated
Show resolved
Hide resolved
I mis-read the issue and fixed another bug 😆 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bug could be tested, but I'm not sure it's interesting to add it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be very careful when changing how the selection works. I would prefer to have a PR only fixing #4156. With #4157 I can't expand the selection holding Shift while pressing ArrowDown.
This happens because we do nothing if the target is not the cell root. There's a TODO to improve this check but I don't know the side effects doing it now.
mui-x/packages/grid/x-data-grid/src/hooks/features/selection/useGridSelection.ts
Line 387 in 50f084d
if (!isGridCellRoot(event.target as Element)) { |
packages/grid/x-data-grid/src/hooks/features/selection/useGridSelection.ts
Show resolved
Hide resolved
@@ -108,6 +112,9 @@ export const useGridSelection = ( | |||
const visibleRowIds = gridVisibleSortedRowIdsSelector(apiRef); | |||
const startIndex = visibleRowIds.findIndex((rowId) => rowId === startId); | |||
const endIndex = visibleRowIds.findIndex((rowId) => rowId === endId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could apiRef.current.getRowIndexRelativeToVisibleRows
be used here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so because when expanding with the mouse, we support cross-page expansion.
You click on a row of page 1
You go to page 2
You shift click a row of page 2
=> It selects all the row between your two clicks.
packages/grid/x-data-grid/src/hooks/features/selection/useGridSelection.ts
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid/src/hooks/features/selection/useGridSelection.ts
Show resolved
Hide resolved
I will extract the fix for #4156 in a standalone PR 👍
@m4theushw ok so before this PR, the Do we need the check at all for selection ? Was this check for some scenarios but not others the right behavior or just an error ? |
The check was added to fix #701. It might be useless now. But if keep it, then it's better to extend to check if the |
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
packages/grid/x-data-grid/src/hooks/features/keyboardNavigation/useGridKeyboardNavigation.ts
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid/src/tests/selection.DataGrid.test.tsx
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid/src/hooks/features/selection/useGridSelection.ts
Show resolved
Hide resolved
packages/grid/x-data-grid/src/hooks/features/selection/useGridSelection.ts
Outdated
Show resolved
Hide resolved
// Get the most recent params because the cell mode may have changed by another listener | ||
const cellParams = apiRef.current.getCellParams(params.id, params.field); | ||
|
||
if (cellParams.cellMode !== GridCellModes.Edit && isNavigationKey(event.key)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (focusCell && focusCell.id !== params.id) { | ||
event.preventDefault(); | ||
|
||
const isPreviousRowSelected = apiRef.current.isRowSelected(focusCell.id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're relying on the fact that the focus was not updated yet. If the order of the listeners is changed, or we change to listen for the event in the capture phase, it won't work. Would it work if lastRowToggled
is used here instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're relying on the fact that the focus was not updated yet.
The opposite, I missed-named this variable, it should be isNewRowSelected
I access the previous row through params.id
and the new one through focusCell.id
I don't think we could easily cover all use cases
If you navigate with the keyboard without selecting rows, your "previousRow" still needs to be the cell the focus is currently in, not the last row toggled.
I agree that this is a constraint on the call order and that is why I am putting useGridKeyboardNavigation
before useGridSelection
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds fair. I only don't like the constraint on the call order, but I don't have any other simple solution. We could listen to cellFocusIn
and try to track if the new focus came from the keyboard navigation. It's a way to not depend on the call order but much more complex. We can leave it as it is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively, the keyboard navigation could publish an event keyboardNavigation
with the cell before and after.
packages/grid/x-data-grid/src/hooks/features/selection/useGridSelection.ts
Outdated
Show resolved
Hide resolved
} else { | ||
// We are navigating to the top of the page and adding selected rows | ||
start = newRowIndex; | ||
end = previousRowIndex - 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
@@ -346,48 +346,48 @@ describe('<DataGrid /> - Selection', () => { | |||
}); | |||
}); | |||
|
|||
/* eslint-disable material-ui/disallow-active-element-as-key-event-target */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you update the tests so we don't need to ignore this ESLint rule? To keep consistent with the core.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
packages/grid/x-data-grid/src/tests/selection.DataGrid.test.tsx
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid/src/hooks/features/selection/useGridSelection.ts
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid/src/hooks/features/selection/useGridSelection.ts
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignore.
packages/grid/x-data-grid/src/tests/selection.DataGrid.test.tsx
Outdated
Show resolved
Hide resolved
Co-authored-by: Matheus Wichman <matheushw@outlook.com>
Fixes #4185
useGridKeyboard
(movie the publication ofcellNavigationKeydown
inuseGridKeyboardNavigation
and the content ofexpandCellSelection
inuseGridSelection
)