-
-
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] Store the outlined cell in the state #7111
Conversation
These are the results for the performance tests:
|
08a0fcb
to
4babd8b
Compare
@@ -224,7 +258,7 @@ export const useGridFocus = ( | |||
[apiRef], | |||
); | |||
|
|||
const focussedColumnGroup = unstable_gridFocusColumnGroupHeaderSelector(apiRef); | |||
const focusedColumnGroup = unstable_gridFocusColumnGroupHeaderSelector(apiRef); |
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.
Just a typo.
const handleCellBlur = useEventCallback(() => { | ||
if (lastKeydownEvent.current?.key !== 'Tab') { | ||
return; | ||
} | ||
apiRef.current.setState((state) => ({ | ||
...state, | ||
// The tabIndex is kept to allow the focus to return to this cell if Shift+Tab is pressed | ||
focus: { cell: null, columnHeader: null, columnGroupHeader: null }, | ||
outline: { cell: null }, | ||
})); | ||
apiRef.current.forceUpdate(); | ||
}); | ||
|
||
const handleCellFocus = useEventCallback((params: GridCellParams) => { | ||
if (lastKeydownEvent.current?.key === 'Tab') { | ||
apiRef.current.setCellFocus(params.id, params.field); | ||
} | ||
}); |
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.
This is the fix for #3844
|
||
if ( | ||
process.env.NODE_ENV === 'test' && | ||
rootProps.experimentalFeatures?.warnIfFocusStateIsNotSynced |
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.
This flag is useless now because when a cell is focused via keyboard, onFocus
is called before we update the focus state. I don't consider a breaking change because it's already experimental and it didn't have a good reception: #3850
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
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.
Nice work! I just have a couple of notes/questions but other than those it's good from my side
packages/grid/x-data-grid/src/components/containers/GridRootStyles.ts
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid/src/components/containers/GridRootStyles.ts
Outdated
Show resolved
Hide resolved
apiRef.current.setState((state) => ({ | ||
...state, | ||
// The tabIndex is kept to allow the focus to return to this cell if Shift+Tab is pressed | ||
focus: { cell: null, columnHeader: null, columnGroupHeader: null }, |
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.
It's more of a general question but do we also have a focus on a row? I'm asking because of the row selection and things like row grouping.
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.
No, because rows don't have the outline.
@@ -124,7 +124,7 @@ export const GridRootStyles = styled('div', { | |||
padding: '0 10px', | |||
boxSizing: 'border-box', | |||
}, | |||
[`& .${gridClasses.columnHeader}:focus-within, & .${gridClasses.cell}:focus-within`]: { | |||
[`& .${gridClasses.columnHeader}:focus-within, & .${gridClasses['cell--outlined']}`]: { |
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.
Should we ditch :focus-within
in the column header as well?
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 we need to do this change now. Creating a .MuiDataGrid-columnHeader--outlined
will create complexity that's not necessary for now. If some day we implement a range selection for column headers, then we'll need to do this.
@@ -6,6 +6,13 @@ | |||
"params": "GridAggregationModel", | |||
"event": "MuiEvent<{}>" | |||
}, | |||
{ | |||
"projects": ["x-data-grid", "x-data-grid-pro", "x-data-grid-premium"], | |||
"name": "cellBlur", |
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.
Do we still need cellFocusIn
/cellFocusOut
events?
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.
Yes, for editing. cellBlur
is tied to the blur
DOM event, meaning that it's published every time a cell loses focus, including when the focus is lost to a portaled element inside the same cell. In the other hand, cellFocusOut
is only published when focus state is updated. If a cell loses focus to an portaled element inside it, cellFocusOut
is not published but cellBlur
is.
- To update the outline style of a focused cell, use the `.MuiDataGrid-cell--outlined` class instead of the `:focus-within` selector. | ||
```diff | ||
-'.MuiDataGrid-cell:focus-within': { | ||
+'.MuiDataGrid-cell--outlined': { |
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.
+'.MuiDataGrid-cell--outlined': { | |
+'.MuiDataGrid-cell--outlined': { | |
- `.${gridClasses.cell}:focus-within` | |
+ `.${gridClasses['cell--outlined']}` |
Maybe include an example with gridClasses
as well?
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.
Added!
packages/grid/x-data-grid/src/hooks/features/focus/gridFocusStateSelector.ts
Show resolved
Hide resolved
I'm not sure we have to decouple focus/outline states to implement the correct behavior for cell selection. |
@cherniavskii I'm not sure I understood you. The problem is not to know which cell was the last selected, but to put the outline in another cell. By default, the outlined cell is the last one clicked. In a range selection created by clicking two cells, the outlined cell is the last one, however, I need to keep the outline in the first clicked cell. |
Sorry, I thought you were solving a different issue. |
@cherniavskii The outline has to stay in the first-clicked cell only in cell selection. It's how most spreadsheet apps work: #6567 (comment) For everything else nothing has changed, the outlined cell is always the last clicked cell. |
I believe the focus and outline states are always synced in Spreadsheet. Screen.Recording.2023-01-06.at.16.04.01.movAfter Shift+Click the first cell is still outlined and focused. You can check that by navigating using the arrow keys - the focus will move from the cell that was outlined, not the one that was clicked with Shift. |
This reverts commit 0203346.
Part of #6567 (comment)
Fixes #3844
Here I'm moving to the state the information of which cell has the outline. Previously, the outline style was added by CSS using
:focus-within
, but for cell selection a cell might focused but not have the outline. During normal usage, e.g. keyboard navigation, the outline is synced with the focus insideapiRef.current.setCellFocus
. This means that if the focus is not correctly updated, the cell won't have the outline. A way to review this PR is to battle test the focus logic ensuring that the focus is always updated.To implement the correct behavior for cell selection I'll open another PR allowing
apiRef.current.setCellFocus
to skip the outline update. Then we can add aapiRef.current.setOutlinedCell
to update only the outline state.Release
Breaking changes
To update the outline style of a focused cell, use the
.MuiDataGrid-cell--outlined
CSS class instead of the:focus-within
selector.