-
Notifications
You must be signed in to change notification settings - Fork 842
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
[EuiDataGrid] Fix multiple grid focus restoration issues #5530
Conversation
- and use this to determine whether or not the entire grid should have a tabindex/be focusable, rather than a simple 'hasFocus' check which doesn't account for virtualization - Add new mockFocusContext for easier testing for various tests that need to set a focus context - EuiDataGridCell - DRY out an `this.isFocusedCell` method - Call `setIsFocusedCellInView` on mount and on unmount (`setFocusedCell` handles setting true/false on new cell focus) - Write new unit tests for componentWillUnmount - Clean up unnecessary uncovered function fallback for this.unsubscribeCell - we're already checking for a falsy value before calling it
…ntent - see http://localhost:8030/#/tabular-content/data-grid-focus
…irtualized refs - see https://react-window.vercel.app/#/api/FixedSizeGrid for `onItemsRendered` API - this struck me as the quickest/easiest way to determine which virtualized cells are in view - I opted to save this as a ref instead of as state as I didn't see the need to cause a rerender - `focusFirstVisibleInteractiveCell` was split out to its own fn as it will shortly be used elsewhere to fix another focus bug in the grid
@1Copenut Tagging you in for QA help, since you opened at least one of the issues I'm fixing in this PR and have familiarity with the first one. Let me know if you see any issues with the fixes! |
Preview documentation changes for this PR: https://eui.elastic.co/pr_5530/ |
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.
LGTM, tested with the modified focus.js and the main example. Also messed with some of the tests locally to ensure their effectiveness 👍 .
…lling content" This reverts commit 7f031ac.
@1Copenut going to go ahead with turning auto merge on this PR, but feel free to confirm that the issue you opened is resolved after (+ ping me if you find anything else)! |
Preview documentation changes for this PR: https://eui.elastic.co/pr_5530/ |
- gridItemsRendered will be falsey if rowCount is 0 and will cause an error on tab, so we should opt to simply leave focus on the grid body wrapper
Preview documentation changes for this PR: https://eui.elastic.co/pr_5530/ |
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.
Changes L even more GTM; tested the focus example with rowCounter={0}
with both non- & interactive headers, and played more with the main example.
Trevor just found an issue that I'll push up another bugfix for:
I'm going to have to adjust the branching logic a bit further to account for this. Questions on how we prefer to treat this:
Do we have any preference between the two options @1Copenut @chandlerprall? While 2 is kind of appealing as being "more intelligent", I think 1 is probably more straightforward and less likely to lead to edge cases/shenanigans - WDYT? |
I feel like the first option, focusing the first visible data cell, would be a good experience. I could arrow up once to get into the header row, and left, right, down to move through the virtualized grid cells as normal. How difficult is it to detect if a cell is in view? User scrolling will leave us with inexact "stops" -- users might have half a cell in the visible frame when the stop scrolling, does that cell get "snapped" to just below the header row? I might be inventing problems that'll be addressed as code is updated. |
After more testing, I'm going to go with option 2 because I actually realized the issue can be fully reproduced by an even simpler means:
Fixing the arrow down key behavior on the sticky header will generally be a more robust fix IMO. edit to add: we could also try to force row 0 into view with a manual |
@1Copenut sorry, totally forgot to address a few points in your comment:
Just wanted to clarify that even with this new fix, users will still need to go all the way to the first row (row 0) to be able to up arrow key into the sticky header. Not sure there is any way around this and this is how it's always been UX-wise AFAICT. In theory the Home key should allow users to quickly jump to row 0.
We get this for free from react-window, they have an
Not inventing problems at all, this is an open issue (#3151) that I currently have a separate open PR for: #5515 One downside of the disparate modular PRs is that we don't get to see them altogether in action just yet. So currently this PR will still have the same issue where you can down arrow key from the sticky header into a cell that's just barely visible. Once this PR merges, I'll absolutely update that PR to test out the combined behavior and make sure that newly focused cells are always in view. |
Preview documentation changes for this PR: https://eui.elastic.co/pr_5530/ |
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.
LGTM! I did a fair bit of random key pressing after this latest update. The focus handling and setting to the first row, first cell on virtualized scroll all feels smooth and intuitive. Thank you Constance!
Going to merge this in now as I suspect I'll need |
Summary
This PR fixes 3 bugs with EuiDataGrid around restoring correct focus/keyboard navigation to the grid:
c06db86 and 7f031ac closes #5517
If the user scrolls the currently focused cell out of view (via mouse) and then attempts to tab back into the grid (via keyboard), the grid should intelligently focus into the first visible and interactive cell (instead of the entire grid becoming unfocusable).
refocus_grid.mp4
d29d938 closes #4923
Problem: If the user hides the current column via the column header's actions popover, the popover cannot focus back into the now-removed cell, and sets the current focus back to the top of the document
Fix: Focus should be manually set to the grid by targeting its first visible and interactive cell (which is not perfect, but at least does not strand the user and require them tab all the way back to the grid)
hide_column.mp4
8a035de closes #5476
Fixes keyboard focus index being incorrect after moving a column left or right via the header's actions popover.
move_column.mp4
Checklist
- [ ] Check against all themes for compatibility in both light and dark modes- [ ] Checked in mobile- [ ] Props have proper autodocs and playground toggles- [ ] Added documentation- [ ] Checked Code Sandbox works for any docs examples- [ ] Checked for breaking changes and labeled appropriately