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

[Data Views] Experimental keyboard navigation for table view #56513

Draft
wants to merge 1 commit into
base: trunk
Choose a base branch
from

Conversation

andrewhayward
Copy link
Contributor

Important

The primary intent of this PR is ensuring tables are easier to navigate with a keyboard. As such, the code changes aren't super focused, and there's plenty of room for improvement! That being said, comments are of course welcome.

(Potentially) resolves #56328.

What?

This PR improves the keyboard navigation in list views, presenting the table as a single tab-stop to be navigated with directional keys (up, down, left, right, etc).

list-view-keyboard-navigation.mov

Why?

As per #56328...

Currently every focusable element (or "widget") in a list layout (header action buttons, linked items, etc) presents as its own tab stop. This can make it difficult and tedious for a non-mouse user to move across content.

How?

The Composite component is used to render the various table elements, to provide embedded keyboard navigation.

A Widget system is introduced to allow render functions to indicate where navigable content should replace the wrapper context in the navigation flow.

Testing Instructions

  1. Open a data view to a table layout ("list view")
  2. The table should render as before
  3. Columns should remain sortable, hideable and filterable, where relevant
  4. Grid views should continue to work

Testing Instructions for Keyboard

With a list view open:

  1. Tab to the first cell in the table
  2. Use the arrow keys to navigate around the table
  3. Interactive elements should gain focus where appropriate
  4. Tab out of the table to the pagination controls

To do

  • Focus is lost when the table is reloaded (sorting, filtering, etc)
  • The "more actions" dropdown in each row isn't an Ariakit implementation, so doesn't play nicely
  • Sometimes the table forgets it's supposed to be focusable, and you can't get back in
  • ...

@andrewhayward andrewhayward added [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Design Feedback Needs general design feedback. Needs Accessibility Feedback Need input from accessibility [Feature] DataViews Work surrounding upgrading and evolving views in the site editor and beyond labels Nov 24, 2023
@andrewhayward andrewhayward self-assigned this Nov 24, 2023
@andrewhayward andrewhayward added [Type] Enhancement A suggestion for improvement. [Type] Experimental Experimental feature or API. labels Nov 24, 2023
@@ -42,6 +48,8 @@ const defaultConfigPerViewType = {
},
};

const DefaultWidget = forwardRef( ( { render } ) => render );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only necessary until other views (i.e. GridView) implement this Widget system.

Comment on lines +38 to +43
&:focus,
&:focus-visible,
&:focus-within {
background-color: #f0f0f0;
outline: none;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gives focused cells, or cells containing focused elements, more prominence in the table. Could do with some design input here.
// @WordPress/gutenberg-design

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the video demo you shared the gray seems darker in that demo than #f0f0f0 (btw you could use $gray-100 there if you like). Was the video recorded earlier or is it just a visual illusion?

In any case my instinct is that if we are also showing the focus-ring, changing the background at the same time is likely going to be a bit noisy. It also might confuse if we end up adding a full-row background-color change on mouse hover. I'll defer to Jay, though, if he chimes in.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be good to understand the full requirements here before committing to a design.

I assume a focus style is required for cells that only contain data like the Status column in the video?

As you navigate focus transfers immediately to the first child of each cell where possible. In these cases do parent cells still need to be visually highlighted?

If the answer to these questions is yes then perhaps we need different styles for focus and focus-within.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrewhayward Given that this table should and will be applied to many contexts, I feel like the outline should remain for focus. That particular gray might blend with a page background somewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'll provide a little more context for clarity.

The request for feedback is more around how we ensure that focal context is clearly communicated, rather than on the way I specifically did it here.

The current background colour is somewhat arbitrary (I think I copied it from the unfocused search field), so could be anything; frankly, the cells don't have to have a background colour at all, as long as focus is clear.

Interactive cell content receives focus as normal, but the cells themselves receive focus when they contain no interactive content. I used a background here to maintain consistency between these two different states, but it's not strictly necessary. To @jeffgolenski's point, the cells themselves could have a focus ring, and it wouldn't be a problem.

Essentially, the problem of how best to communicate the focal context is not straightforward, and doesn't necessarily map onto our existing patterns (though it could).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We tend to use rings to denote focus throughout the Editor so I'd be inclined to try repeating that pattern here.

Comment on lines +54 to +57
DropdownMenuV2Ariakit: DropdownMenu,
DropdownMenuGroupV2Ariakit: DropdownMenuGroup,
DropdownMenuItemV2Ariakit: DropdownMenuItem,
DropdownMenuSeparatorV2Ariakit: DropdownMenuSeparator,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Migrating to the new Ariakit-based dropdown menu, which plays better with Composite.

Comment on lines +292 to +295
const Widget = forwardRef( ( widgetProps, innerRef ) => {
useEffect( () => setWidgetUsed( true ), [] );
return <CompositeItem ref={ innerRef } { ...widgetProps } />;
} );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the bit that we pass through to individual cell content render functions. If they make use of it, we adjust the layout here to not make the cell itself navigable.

{ children }
</a>
);
}

export default forwardRef( UnforwardedLink );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is necessary to allow it to be used by Composite.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is needed in order for title field to work properly, right? What happens if the components used by other fields doesn't forward the ref? In the future these fields could come from extenders. Will they need to always do that too?

If yes, can we absorb this in our internal implementation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because of how Ariakit requires custom components to be open for extension. I'm not sure how we'd absorb it, to be honest.

@WordPress WordPress deleted a comment from github-actions bot Nov 24, 2023
@WordPress WordPress deleted a comment from github-actions bot Nov 24, 2023
@oandregal oandregal removed the [Type] Enhancement A suggestion for improvement. label Dec 29, 2023
@ciampo ciampo changed the title [Data Views] Experimental keyboard navigation for list view [Data Views] Experimental keyboard navigation for table view Jan 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] DataViews Work surrounding upgrading and evolving views in the site editor and beyond [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Accessibility Feedback Need input from accessibility Needs Design Feedback Needs general design feedback. [Type] Experimental Experimental feature or API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

DataViews: Improve keyboard accessibility in table layout
6 participants