-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Change aria-checked to only be used on matching ARIA roles for MenuItem. #11459
Conversation
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.
Hi @BE-Webdesign - thanks for working on this, it's not a straightforward issue, but this looks like an improvement to the current code.
I think there are some things to address, so I left comments.
I'd also like to invite @afercia in to review this.
@@ -74,15 +74,21 @@ export function MenuItem( { | |||
props.icon = icon; | |||
} | |||
|
|||
const atts = { |
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.
Convention is that this should be called 'props' instead of atts
. I think childProps
is a good name given props
is already used in this scope. Alternatively could avoid extracting the props into a variable and keep them inline:
const supportsAriaChecked = role === 'menuitemcheckbox' || role === 'menuitemradio';
const ariaChecked = supportsAriaChecked ? isSelected : undefined;
// ... snip
return createElement(
tagName,
{
'aria-label': label,
'aria-checked': ariaChecked,
role,
className,
...props,
},
}; | ||
|
||
// Make sure aria-checked matches spec https://www.w3.org/TR/wai-aria-1.1/#aria-checked | ||
if ( role === 'menuitemcheckbox' || role === 'menuitemradio' ) { |
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've worked on this before and wondered what the right behaviour should be.
Quoting the original issue:
The component should make sure aria-checked is set only when the role prop is menuitemcheckbox or menuitemradio.
This PR satisfies the above logic.
Also, it should make sure that when a isSelected prop is passed, the actual intent of the developers is to communicate a "checked" state, thus a menuitemcheckbox or menuitemradio should be used.
However I think this request in the issue still has a question mark—a developer could still easily use the wrong role, only now they'd not have aria-checked output at all.
This PR does at least document the constraint in the form of code, so that's good. I think it'd be good to update the README.md for the MenuItem detailing the intended behaviour of the props as well.
<MenuItem role="menuitem"><div /></MenuItem> | ||
); | ||
|
||
expect( wrapper.prop( 'aria-checked' ) ).toBeUndefined(); |
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 this test is quite right since it would have passed with the previous code as well (aria-checked would be undefined whenever isSelected is undefined), so there's no assertion that the behaviour has changed. The MenuItem should have an isSelected prop to demonstrate that the prop is not included in the rendered output.
@talldan All set. |
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.
Thanks for addressing those things. This looks good code-wise for me. Would still love an a11y check, to make sure it addresses the issue.
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.
From an a11y perspective LGTM. Love to see specifications enforced through code, thank you.
The Menu component has now a good a11y, can be used for generic items, single choice, and multiple choice with a proper feedback for assistive technologies.
Re: the blocks navigation menu, worth noting if it's meant to support nested blocks too (e.g. blocks within Columns) then I guess it should be changed in something else than a menu. Will discuss this with the accessibility team and report the feedback,
Great, thanks for checking @afercia. Let's merge this. |
Fixes #11431.
Description
Changes aria-checked to only be used on matching ARIA roles for MenuItem. Fixes an a11y issue where Screen readers can not properly understand the BlockNavigationList for which block is currently active.
How has this been tested?
Via Jest and manually: see here
Types of changes
Updates the MenuItem component from the general components library to only use aria-checked when the aria-role is either menuitemcheckbox, or menuitemradio. This also changes BlockNavigationList to use the menuitemradio role, so screen readers can properly understand which block is currently active.
Checklist: