Uh oh!
There was an error while loading. Please reload this page.
fix(material/dialog): improve screen reader support when opened - #23085
Conversation
crisbeto
left a comment
There was a problem hiding this comment.
Also worth noting that the commit message mentions the MDC dialog, but all the changes are to the non-MDC one.
Uh oh!
There was an error while loading. Please reload this page.
@crisbeto I was only testing against the MDC-dialog, but they both use the same code for this. How should I write the commit message in that case? |
So after looking into this some more, here's what I've got to work with
|
0e636aa to
abffbf3Compareabffbf3 to
d59d5ebComparecrisbeto
commented
Jun 30, 2021
I think the check should happen in the dialog service since it is the one that determines if a dialog can open. One thing that I hadn't really considered when I posted my comment is what we would return if we decide not to open a dialog. We can't create a dialog ref without actually creating the dialog. |
Splaktar
commented
Jun 30, 2021
Right. For the moment, I'm throwing an |
crisbeto
commented
Jun 30, 2021
I'm not sure that throwing the error would be the right thing either, because it would be a breaking change and consumers wouldn't have a way of fixing it. |
I don't quite follow how these changes would be fixing the dialog information not being read. What mechanically is changing about how focus is set that leads to the cause in behavior change? |
Splaktar
commented
Jun 30, 2021
Agreed, but I don't have a better approach in mind atm. We could do a different breaking change to have |
Splaktar
commented
Jun 30, 2021
The quick swap of the focus from the trigger button to the dialog container and then to the first focusable element in the dialog is what causes the screen reader to bail out and not announce anything other than being on a focusable element. This approach does work to avoid multiple dialogs being opened while one is animating open. I've verified two paths to fixing this, while still avoiding multiple dialogs being opened while one is animating open
|
jelbourn
commented
Jun 30, 2021
So to make sure I understand correctly: Previously, the dialog always focused itself, and then moved focus to the first tabbable elements / cdkFocusInitial element once the animation finishes? With the PR, this focus only ever goes to the configured element once the animation finishes without going to the container? How does the case of multiple dialogs opening simultaneously play into this? Is it just that they fight for focus in a way that messes up the reader? Rather than throwing an error for this case, we could try to figure out if we can decide not to care as much about that case, since multiple/nested modal dialogs are already somewhat of an anti-pattern. |
crisbeto
commented
Jun 30, 2021
To provide some context: this bouncing around of focus was introduced, because if you have a button that opens a dialog and you press it using the keyboard, you could end up triggering multiple "clicks" if your finger lingers on the button a bit longer than expected. This is made more likely by the fact that we only move focus away from the button once the ~300ms dialog animation has finished. |
jelbourn
commented
Jun 30, 2021
Ah, I see. What do you think about setting the activeElement to |
crisbeto
commented
Jun 30, 2021
I haven't actually tried it, but I would assume that setting
We can always try it and see what happens. We could also try to do something where we save the trigger element when a dialog is opened. If another one is triggered while the dialog is animating, we return the previous dialog ref. |
zarend
commented
Aug 3, 2021
presubmit (internal) had build failures last night 🤦 . I fixed the build failures, and will run the tests tonight 🤞 . |
Splaktar
commented
Aug 3, 2021
@devversion this code seems to run fine on all platforms other than iOS (Sauce Labs). components/src/material-experimental/mdc-dialog/dialog.spec.ts Lines 1330 to 1339 in 087ed2c components/src/material-experimental/mdc-dialog/dialog.spec.ts Lines 1370 to 1380 in 087ed2c I'm not sure why it was passing before, but now it's failing with the changes in this PR, but only on iOS. |
devversion
commented
Aug 3, 2021
@Splaktar Not sure from the top of my head. This seems like something that needs to be investigated within the emulator. |
zarend
commented
Aug 5, 2021
The internal test results are available, 13 broken targets. |
Splaktar
commented
Aug 5, 2021
Great! Are any of those related to iOS? |
Splaktar
commented
Aug 6, 2021
I am able to reproduce these iOS test failures in a Simulator locally, investigating... |
e6b838d to
235b0bcComparezarend
commented
Aug 6, 2021
I did a quick glance at the internal failures. They're mostly screenshot failures, and don't look iOS related. Jeremy and I are going over them in more detail later this afternoon. |
Splaktar
commented
Aug 6, 2021
OK, I think that I've got a solution for the iOS test failures on Sauce Labs. It works locally and now I'm just waiting on this CI run to confirm. |
Uh oh!
There was an error while loading. Please reload this page.
- notify screen reader users that they have entered a dialog - previously only the focused element would be read i.e. "Close Button Press Search plus Space to activate" - now the screen reader user gets the normal dialog behavior, which is to read the dialog title, role, content, and then tell the user about the focused element - this matches the guidance here: https://www.w3.org/TR/wai-aria-practices-1.1/examples/dialog-modal/dialog.html - Avoid opening multiple of the same dialog before animations complete by returning the previous `MatDialogRef` - update material/dialog API golden file Fixesangular#21840
235b0bc to
5dd0503CompareSplaktar
commented
Aug 9, 2021
Resolved conflict in test. |
Splaktar
commented
Aug 12, 2021
@zarend any progress with these presubmit failures? |
zarend
commented
Aug 12, 2021
yes, I have a passing presubmit, which I got to pass by patching failing tests 🎉 . I am the caretaker today and tomorrow, so I'll merge and sync this PR after we finish the sync that's in progress. |
zarend
commented
Aug 12, 2021
ohh, we still need PR reviews for this. |
| case true: | ||
| case 'first-tabbable': | ||
| this._focusTrap.focusInitialElementWhenReady(); | ||
| this._focusTrap.focusInitialElementWhenReady().then(focusedSuccessfully => { |
There was a problem hiding this comment.
Im not too sure if this can have a target of patch. This is touching code from #22780, which will go into the next minor release.
There was a problem hiding this comment.
Also, does sidenav or bottom sheet need special handling too?
There was a problem hiding this comment.
@amysorto Special handling when opening to support screen readers? Probably not, unless they did the bouncing of focus that dialog did prior to this PR.
There was a problem hiding this comment.
We should double-check that they don't
There was a problem hiding this comment.
- Check that bottom sheet behaves properly in a screen reader when opened
- Check that sidenav behaves properly in a screen reader when opened
There was a problem hiding this comment.
@zarend found some similar issues with Bottom Sheet and he's investigating them now.
zarend
left a comment
There was a problem hiding this comment.
this seems reasonable to me 👍
| case true: | ||
| case 'first-tabbable': | ||
| this._focusTrap.focusInitialElementWhenReady(); | ||
| this._focusTrap.focusInitialElementWhenReady().then(focusedSuccessfully => { |
There was a problem hiding this comment.
We should double-check that they don't
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
i.e. "Close Button Press Search plus Space to activate"
read the dialog title, role, content, and then tell the user about the
focused element
- this matches the guidance here:
https://www.w3.org/TR/wai-aria-practices-1.1/examples/dialog-modal/dialog.html
the previous
MatDialogRefFixes#21840