-
-
Notifications
You must be signed in to change notification settings - Fork 190
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
Fixes accessibility issue created by incorrect dialog role #285
Conversation
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/react-component/dialog/G27qhEgFJsdzcc7jVeNSexDsvk9d |
|
||
export type ContentRef = { | ||
focus: () => void; | ||
changeActive: (next: boolean) => void; | ||
} | ||
}; |
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 prettier
@zombieJ we had an external accessibility audit conducted that discovered this finding. |
Hi, CI breaks. Pls update test snapshot |
Codecov Report
@@ Coverage Diff @@
## master #285 +/- ##
=======================================
Coverage 98.05% 98.05%
=======================================
Files 6 6
Lines 154 154
Branches 46 46
=======================================
Hits 151 151
Misses 2 2
Partials 1 1
📣 Codecov can now indicate which changes are the most critical in Pull Requests. Learn more |
@zombieJ Any update on this? |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
@@ -182,7 +182,6 @@ export default function Dialog(props: IDialogChildProps) { | |||
className={classNames(`${prefixCls}-wrap`, wrapClassName)} | |||
ref={wrapperRef} | |||
onClick={onWrapperClick} | |||
role="dialog" |
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.
why did we remove role
here but kept aria-labelledby
?
This is a breaking change who are querying getByRole('dialog', { name: /title/i })
in react-testing-library
We have to workaround in every test to query as getByLabelText(/title/i)
which is not the right way to query dialog. refer- https://testing-library.com/docs/queries/about#priority
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.
The role property was moved because it was on the wrong html element and therefore was causing screen reader users to be unable to properly use it. This PR fixed that.
@@ -141,7 +141,8 @@ const Content = React.forwardRef<ContentRef, ContentProps>((props, ref) => { | |||
{({ className: motionClassName, style: motionStyle }, motionRef) => ( | |||
<div | |||
key="dialog-element" | |||
role="document" | |||
role="dialog" |
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.
Refering to the below comment, we can add aria-labelledby
here to fix the breaking changes.
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.
Can you explain why you are recommending the addition of an attribute whose purpose is purely for the benefit of screen reader users to solve a problem with how your specific app has decided to define RTL selectors?
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.
@mellis481
For good accessibility, everything needs to be properly labelled. A modal dialog needs to inform screen reader users about is content and purpose so it needs to be labelled.
The aria-labelledby
and aria-describedby
attributes are “relationship” attributes that connect the dialog to its title and description explicitly. So when focus is moved to the dialog or inside it, the text within those two elements will be read in succession.
Consider your app wants to find a unique dialog in DOM, aria-labelledby
will make it unique for reading.
Not talking for our specific app but documentation suggests how to query various role
for better accessibility- https://testing-library.com/docs/queries/about#priority
Other refs-
https://accessibility.huit.harvard.edu/technique-accessible-modal-dialogs
http://ncamftp.wgbh.org/sp/tests/dialog/modalDialog.html
https://developer.yoast.com/blog/the-a11y-monthly-making-modals-accessible/ - Give the modal dialog a label section
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.
Your understanding of those aria attributes is completely incorrect.
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.
How are those aria attributes not helpful? Please help me understand.
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.
It looks like this PR fixes the oversight: #290
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.
@JeffreyATW “Oversight” is a bit of an over-exaggeration. The PR that broke your tests was created to improve the lives of screen readers after a professional 3rd party accessibility auditor reviewed the AntD library. And the fix in this PR did not break the tests in this repository. No library can be expected to release HTML changes without breaking test code. In fact that’s what RTL’s philosophy is actually saying right? Ie test it the way users use it which is by finding the role on the dialogue itself.
I hope that it’s clear that the role was previously on something that was not actually the modal (it was on the background if I recall correctly from @mellis481 ’s PR). So that change was necessary to improve the relationship with the screen readers and also to get this component to pass automated a11y auditing tools.
If tests need to change, they need to change so we can support users who need our help.
If #290 allows a workaround without creating new a11y problems then that’s great. But from my perspective, the test code is incorrect not the component itself. Let’s make sure that #290 doesn’t create extra hardship for screen reader users.
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.
If you look at the page Mike linked in his first post, you'll see that aria-labelledby
should be applied to the same element as role="dialog"
.
I agree that role="dialog"
was applied to the wrong element prior to this PR. But aria-labelledby
should have been moved along with it.
Please see this comment for my findings when using a screen reader: #290 (comment)
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.
Thank you for confirming that #290 doesn’t create hardship. I’m pleased to know that it actually improves the accessibility. Thank you so much. It seems like the fix PR has the correct HTML as you mentioned. I commented asking Zombie to consider it.
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.
@JeffreyATW It sounds like I did not correctly interpret the message @hedaukartik was trying to communicate. I'm glad that this PR and #290 that has been created will get the modal in a much better position a11y-wise.
Issue
Dialog's boundaries are not communicated because of improper structure.
User Impact
When this is not done, it is unclear to screen readers when they are leaving or entering a dialog when using the virtual cursor.
Compliant Code Example
https://www.w3.org/TR/wai-aria-practices/examples/dialog-modal/dialog.html
Additional Details
Role=document
does not need to be used.role=dialog
should be moved to where yourrole=document
was.