-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Fix the List View focus management #69190
base: trunk
Are you sure you want to change the base?
Conversation
Size Change: +183 B (+0.01%) Total Size: 1.84 MB
ℹ️ View Unchanged
|
483936c
to
2ae83b0
Compare
2ae83b0
to
a90b76b
Compare
Flaky tests detected in 263f379. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/13457053249
|
a90b76b
to
263f379
Compare
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
I'd recommend to test this PR with a post that contains at least one nested block e.g. a PAragraph within a Group. Sample content:
|
What?
Closes #69147
It is important to understand the List View focus management and the intended behavior of the keyboard shortcut as implemented in #45135
This mechanism is buggy for several user flows, some of them are detailed on the associated issue #69147.
This PR aims to make the focus management and the keyboard shortcut behavior more reliable and adds e2e tests to cover some failing scenarios.
Why?
The List View keyboard shortcut should always work as intended.
The currently selected item (if any) should always receive focus when opening the List View or when using the keyboard shortcut.
How?
Initial focus
One notable change is about initial focus:
When there are no blocks selected:
Initial focus is now set on the first tab of the Document Overview panel because of two reasons:
RovingTabIndexItem
handles logic to make only one item "tabbable" at a time. Attempting to set initial focus on mount on the first item conflicts with theRovingTabIndexItem
internal logic and may end up in two items being "tabbable", which should never happen.When there are blocks selected:
Initial focus should be set to the corresponding item in the List View. On trunk, this fails in at lest two cases:
The 'Always open List View' preference
With this preference enabled, things are a little more complicated because:
The
core/editor/toggle-list-view
is used globally and it is also used in the ListViewSidebar component.This isn't a big deal when the panel is closed by default. However, when the panel is open by default because of the 'Always open List View' preference, using the keyboard shortcut will actually run both of them, the 'local' one and the 'global' one. As a result, the panel closes and then reopens immediately. It does it so fast that it's invisible to the eyes and it seems like nothing happened, the panel stays open. Apparently, this unintended behavior missed some proper testing when the preference was implemented.
Note: This happens only on first page load. This PR tries to introduce some logic to determine whether the
ListViewSidebar
renders for the first time or not.Technical points for discussion
ListViewSidebar
now uses arenderCounter
variable to determine if it renders for the first time or not. I'm not sure this is the best 'React' way to do it but I couldn't find other ways. I also tried to useuseInstanceId
but it doesn't guarantee the count is correct because it must be used inside the component and at that point it appears the component already rendered twice. Any suggestions for a better approach are welcome.ListViewComponent
now uses a timeout when callingfocusListItem
, which is the function responsible for setting focus on the selected item. The timeout is important to preventuseFocusOnMount
(which internally does use a timeout) to set focus last. Actually,focusListItem
should be called last instead.data-is-selected
attribute to make moving focus to the actual selected item more reliable. Suggestions for any better approach are welcome.Testing Instructions
Regardless of whether the List View is opened and closed by clicking the toggle button in the top bar or via the keyboard shortcut the most important behaviors to test are:
Testing Instructions for Keyboard
Screenshots or screencast