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

Fix issue with top bar menu having unique ARIA roles #13059

Closed
wants to merge 22 commits into from

Conversation

Firestorm980
Copy link

@Firestorm980 Firestorm980 commented Dec 21, 2018

Description

Closes #12505. Adds role options to menus so that the items within the main more menu can now be groups within the menu. Should fix issues with keyboard navigation as well as roles. The menu options/props default to what they used to be, so if it isn't specified and these menus are used elsewhere, it should fallback to the old functionality.

How has this been tested?

  • Manual keyboard navigation testing in the admin with VoiceOver.
  • Ran test-e2e within Gutenberg docker.

Types of changes

  • Updates menu group component to have a default role, label, and keyboard event control
  • Changes menus used in the top nav to use group instead of menu and wraps within a parent menu
  • Changes menus used in the top nav to let the parent menu handle overall keyboard event navigation

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.

Copy link
Member

@jorgefilipecosta jorgefilipecosta left a comment

Choose a reason for hiding this comment

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

Hi @Firestorm980 thank you for your contribution. I don't notice any visual changes and it looks like things are working correctly.
Previously on the ellipsis menu, it was not possible to use the arrow down to navigate between all the menu items and now it is (which is an improvament).
cc: @afercia, @tofumatt would it be possible to have a look at this PR regarding the a11y point of view?

@@ -33,9 +37,14 @@ export function MenuGroup( {
return (
<div className={ classNames }>
{ label &&
<div className="components-menu-group__label" id={ labelId }>{ label }</div>
<div
className={ `components-menu-group__label ${ ( isScreenReaderLabel ) ? 'screen-reader-text' : '' }` }
Copy link
Member

Choose a reason for hiding this comment

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

Here if isScreenReaderLabel is false we add an unnecessary space. What if we use the classnames util e.g:

className={ classnames( 'components-menu-group__label', {
['screen-reader-text']: isScreenReaderLabel
} }

}
<NavigableMenu orientation="vertical" aria-labelledby={ labelId }>
<NavigableMenu orientation="vertical" aria-labelledby={ labelId } role={ role } useEventToOffset={ useEventToOffset }>
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems to me the wrapper element (the one with role=menu) has now an aria-labelledby attribute that points to a non existing ID (while the groups are OK). It makes sense to use the visible titles for the groups but also the menu should be labelled.

In the W3C example, the menu uses an aria-label="Text Formatting". In the same way, this menu could use an aria-label when the role === menu.

@afercia
Copy link
Contributor

afercia commented Dec 27, 2018

@Firestorm980 thanks so much for working on this 🙂 I've left one minor comment (the whole menu should be labelled). Keyboard interaction is greatly improved 👍

@gziolo
Copy link
Member

gziolo commented Jan 31, 2019

@Firestorm980 - do you plan to address feedback left? It looks like it is very close to be ready to ship. We would like to include it in the plugin's release planned for the middle of February.

Edit: It now has some conflicts with master branch that must be resolved.

@gziolo gziolo added the [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). label Jan 31, 2019
@gziolo gziolo added this to the 5.1 (Gutenberg) milestone Jan 31, 2019
@Firestorm980
Copy link
Author

@gziolo I should be able to get to this one in the next couple days.

@Firestorm980
Copy link
Author

Firestorm980 commented Feb 3, 2019

@gziolo @afercia Fixes should be included now.

@gziolo gziolo self-requested a review February 7, 2019 13:27
@@ -19,6 +19,10 @@ export function MenuGroup( {
className = '',
instanceId,
label,
role = 'menu',
labelRole = ( role === 'group' ) ? { role: 'presentation' } : {},
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd remove this, as role=presentation is useful to "flatten" the accessibility tree but there's no need for it, as the div it applies to is already ignored.

@gziolo gziolo added this to the 5.3 (Gutenberg) milestone Mar 4, 2019
@youknowriad youknowriad removed this from the 5.3 (Gutenberg) milestone Mar 18, 2019
@afercia
Copy link
Contributor

afercia commented Mar 19, 2019

@Firestorm980 hello. Do you have time to address the pending issues? If not, please let us know. These changes would greatly improve keyboard interaction in the more menu. If you don't have time, we can always copy your branch to the main repo preserving commits and attributions, and proceed from there. Thanks!

@gziolo
Copy link
Member

gziolo commented Mar 20, 2019

@afercia in case we don't hear back from @Firestorm980 soon, I opened #14525 whit all commits transferred. In addition, I rebased new PR with all the changes applied in master branch. Feel free to work on new PR.

@gziolo gziolo added the [Status] Stale Gives the original author opportunity to update before closing. Can be reopened as needed. label Mar 20, 2019
@chrisvanpatten chrisvanpatten removed the [Status] Stale Gives the original author opportunity to update before closing. Can be reopened as needed. label Mar 22, 2019
@chrisvanpatten
Copy link
Contributor

Removed the "stale" label as it seems it no longer is :)

@Firestorm980
Copy link
Author

Sorry about the delay in communication on this one. Hopefully will have another commit up soon with fixes.

Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

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

See my comments. In general, this PR goes in the right direction but it would be nice to explore whether we should introduce new common component Menu which represents the modified version of MenuGroup. While those two are similar, they are conceptually different.

@@ -68,6 +68,11 @@ class NavigableContainer extends Component {
const { getFocusableContext } = this;
const { cycle = true, eventToOffset, onNavigate = noop, stopNavigationEvents } = this.props;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const { cycle = true, eventToOffset, onNavigate = noop, stopNavigationEvents } = this.props;
const { cycle = true, eventToOffset = noop, onNavigate = noop, stopNavigationEvents } = this.props;

This should be enough to make this work instead of the check:

// This avoids a console error when eventToOffset is null

<PluginMoreMenuGroup.Slot fillProps={ { onClose } } />
<ToolsMoreMenuGroup.Slot fillProps={ { onClose } } />
<MenuGroup>
<MenuGroup label={ menuLabel } isLabelHidden={ true }>
Copy link
Member

Choose a reason for hiding this comment

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

Fragment is no longer necessary to wrap components.

@@ -19,6 +19,9 @@ export function MenuGroup( {
className = '',
instanceId,
label,
role = 'menu',
Copy link
Member

Choose a reason for hiding this comment

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

It feels wrong to see the default role set menu for the component which is called MenuGroup and then see it overridden back to group in other places. It seems like we need to introduce another component called Menu which will have role set to menu, its class name which will hide the label for the menu, and will always have useEventToOffset set to true. This will make it possible to leave MenuGroup usage unchanged.

Copy link
Contributor

Choose a reason for hiding this comment

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

@gziolo should we spin up a new issue for that?

Copy link
Member

Choose a reason for hiding this comment

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

I would feel comfortable doing it as part of this PR because in the current form you might see unexpected role="menu" in all plugins using MenuGroup.

@gziolo gziolo added the General Interface Parts of the UI which don't fall neatly under other labels. label Mar 27, 2019
@gziolo gziolo assigned aduth and Firestorm980 and unassigned aduth Mar 27, 2019
@aduth
Copy link
Member

aduth commented Apr 8, 2019

In general, this PR goes in the right direction but it would be nice to explore whether we should introduce new common component Menu which represents the modified version of MenuGroup. While those two are similar, they are conceptually different.

This will make it possible to leave MenuGroup usage unchanged.

Arriving here via #14843 and considering the recommendations from #12505, I wonder what it is that MenuGroup is supposed to represent that we're trying to leave untouched. From its current documentation, it's not clear to me why it implements behaviors (navigating by arrow keys) and not instead rely on that to be handled by the context in which it's rendered. Indeed, this seems to be the recommendation in #12505:

Basically, the MenuGroup component should be just a group of menu items and not render a NavigableMenu. Then, the groups should be wrapped by an ARIA menu, i.e. a single NavigableMenu.

The challenge is in how it's used today, the "More Options" menu doesn't implement any of these behaviors on the wrapping dropdown. It seems like something we'd expect out of the DropdownMenu component, but as it exists today, it's not possible to actually use groupings there. #14843 is a step in the direction of making this possible, though.

I would expect:

tl;dr We seem to be trying to let MenuGroup to have some behaviors for a standalone context, and I'm not sure why?

@Firestorm980
Copy link
Author

@gziolo @aduth just a heads up that my schedule is getting pretty full so I don't have a lot of spare time to tackle this one, especially now that the scope of the ticket appears to be changing somewhat.

@gziolo
Copy link
Member

gziolo commented Apr 10, 2019

@gziolo @aduth just a heads up that my schedule is getting pretty full so I don't have a lot of spare time to tackle this one, especially now that the scope of the ticket appears to be changing somewhat.

Thank you for your contribution so far, it helped us better understand what would be the best approach here. I'm personally leaning towards including the changes proposed here in #14843. It means there is going to be more aggressive refactoring required to make it work as @afercia described in #12505. However, it seems like we would be able to address all concerns shared in the original issue. In addition, this will give us more control over DropdownMenu and will improve the default usage of this component in the context of its accessibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). General Interface Parts of the UI which don't fall neatly under other labels.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

The top bar More Menu should be a unique ARIA menu
8 participants