zendeskgarden/react-components

A11y: Autocomplete's value isn't ready by VoiceOver

kgoggin opened this issue · 0 comments

Expectations

When using the Autocomplete component with VoiceOver enabled, the field's selected value ought to be read by the screen reader.

Reality

The screen reader doesn't read the current value of the field.

Screen Shot 2021-08-16 at 1 49 06 PM

Steps to Reproduce

  1. In the Garden storybook, open the Autocomplete story.
  2. Turn on VoiceOver in Mac OS (Cmd-F5)
  3. Tab to the field in the story. Notice that the screen reader doesn't read the value (default is Asparagus).

Initial Investigation Notes

I took some time to try to understand what was causing this. I'll say up front that this is my second week at Zendesk and so I'm 100% new to Garden and its code 😆.

After inspecting the rendered output, I noticed that the underlying <input /> that's being rendered didn't have any value set on it. The input props being passed in from the prop getter seem to always have value set to "", even after selecting a value. In fact, even when the Storybook component initially renders and selectedItem is set to "Asparagus", the input's value is "" - this is because the input's state is being controlled externally via the story itself, but even after selecting a new value the input's value gets reset to "".

I wanted to see if having a value set would fix the screen reader issue, so I stopped passing in the inputValue to the example and let Downshift take over managing that state. I found that, on the initial render, the underlying <input /> had its value set to "Asparagus", and the screen reader correctly read it out! 🎉 . But, if I changed the value, the inputValue being tracked in the internal state again got reset to "", and it broke again.

It looks like there's some logic that was added in #747 to handle explicitly clearing out the input field in certain circumstances. I think this is likely what's resetting that value in the internal state and leaving the DOM element without a value. Since I'm not familiar with the desired behavior there I wasn't comfortable trying to modify it, but it seems to me that if that could be tweaked to maintain the input's value that would effectively fix this.

Interestingly, I noticed that the other components that are based on the Dropdown don't have the same screen reader behavior, but they do seem to also have a blank value on their underlying <input /> components. So, it does seem like this is also bumping into some interesting behavior related to the screen reader itself and how it handle different DOM nodes? I think that also opens up the possibility that there could be a work-around for getting the screen reader to respond correctly that doesn't involve having the value set on the input... but it does seem more "correct" for the DOM to represent the current selection.

Fine Print

  • Component: Autocomplete
  • Version: latest - tested with Garden's Storybook on master
  • Browsers: Safari + Chrome on Mac OS using VoiceOver. Unsure about other screen readers.