mapbox / mapbox-gl-geocoder

Geocoder control for mapbox-gl-js using Mapbox Geocoding API
https://mapbox.com/mapbox-gl-js/example/mapbox-gl-geocoder/
ISC License
362 stars 181 forks source link

Accessibility: search suggestions menu is not accessible to screen readers and has unexpected keyboard behavior (fails WCAG criteria) #517

Open maggiewachs opened 9 months ago

maggiewachs commented 9 months ago

mapbox-gl-js version: Latest browser: All

Why we need this fixed

I'm a web accessibility engineer for a digital agency, and one of our clients is a Federal US agency with millions of website visitors per month. They have a few licensed implementations of Mapbox, and the ones that use the GL search feature display the following bugs and do not conform to accessibility requirements. Fixing this issue will mean our disabled users can take full advantage of Mapbox functionality, and most importantly, have a much better online experience when performing a Mapbox search.

Steps to Trigger Behavior

  1. Enable a screen reader (I tested using VoiceOver and Safari, MacOS 14.1)
  2. Open this demo: https://docs.mapbox.com/mapbox-gl-js/example/mapbox-gl-geocoder-outside-the-map/
  3. Enter a term in the search input, like "restaurant", that displays a menu of options
  4. Hitting the Tab key selects the first item and submits the form, which is unexpected. Tab should move focus to the next interactive element.
  5. In the search input, use the down arrow key to traverse the menu. You'll notice the following:
    • Focus remains on the input and does not move to the menu.
    • On the first press of the down arrow, selection (active style) skips the first item and moves to the second menu item.
    • The screen reader does not read any of the menu items aloud until a selection is made. (VoiceOver repeats the input's text value every time a new selection is made.)

Link to Demonstration

The issues are present in this demo: https://docs.mapbox.com/mapbox-gl-js/example/mapbox-gl-geocoder-outside-the-map/

Expected Behavior

When a user enters text in the search box:

Patterns to emulate: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/

Actual Behavior

When a user enters text in the search box:

hsdonkin commented 4 months ago

We also have this issue, and it was flagged by our ADA compliance partner 👍

It's a bit of a damned-if-you-don't situation for us, because we can't use the Geocoder class without adding it to the DOM, as it throws errors looking for the DOM elements to toggle loading states.

What's interesting is that the keyboard interactions seem to work in the examples, but we can't get them to work in production. Recording 2024-04-15 at 13 42 13

hsdonkin commented 4 months ago

@maggiewachs Digging into this, it seems like this combobox runs on this suggestions library. The way it's implemented is that the list is internally tracked by keydowns, but keyboard focus isn't actually placed on those elements, so the screenreader can't read them. There isn't an aria-live announcer or anything either.

https://github.com/tristen/suggestions

I forked this, modernized, made an accessible version using WCAG's combobox example. You can install and override the dependency as a github package, or you can download a zip and install it as a local file dependency.

https://github.com/hsdonkin/suggestions

In our package.json:

"dependencies" : {
  ...
  "suggestions": "github:hsdonkin/suggestions",
},
"overrides": {
  "suggestions": "$suggestions"
}

Basically, any website using the old version is open to an ADA lawsuit 😅 so this should be replaced @mapbox

maggiewachs commented 4 months ago

@hsdonkin thank you! I'll take a look.

swirtSJW commented 4 months ago

@hsdonkin What would it take to get your fix as Pull request either against this repo or maybe against upstream suggestions repo so we can get the fix farther upstream rather than switching to your fork.

hsdonkin commented 4 months ago

@hsdonkin What would it take to get your fix as Pull request either against this repo or maybe against upstream suggestions repo so we can get the fix farther upstream rather than switching to your fork.

I could put in a PR to @tristen 's suggestions, I had some issues getting local dev online but I think I've got things working. My fork includes a different dev pipeline, and a more modern implementation via classes