Search code examples
javascriptaccessibilityweb-componentwai-arianvda

How to make an accessible list in a web component?


I built a select web component (a button toggling a list of options in a dropdown). It is actually 2 components: x-select and x-option. I have a div role="list" in x-select (inside its shadow DOM, wrapping the <slot />) and each x-option has a role="listitem". With Shadow DOM enabled for both components, NVDA (with Chrome) is not picking up the text content of the options; it announces something like "list item (6 of 12)".

<!-- x-select -->
<button aria-controls="listbox-id">Select an option</button>
<div role="listbox" id="listbox-id">
    <slot />
</div>


<!-- x-option -->
<Host role="option">
  <slot />
</Host>


<!-- usage -->
<x-select>
  <x-option>Red</x-option>
  <x-option>Blue</x-option>
  <x-option>Green</x-option>
</x-select>

This seems to be caused by the fact that the list is within the shadow DOM of my-select, while listitems are in the light DOM (slotted).

NVDA does read the options text when shadow DOM is disabled for the option component, but this is not a satisfying solution for me.

Is this a bug in NVDA? Is there a workaround, or is there a better way to build this component?

UPDATE
After further testing, I noticed my code works in VoiceOver/Safari, NVDA/Firefox and NVDA/JAWS, and fails in NVDA/Chrome, JAWS/Chrome, NVDA/Edge and JAWS/Edge. Seems like a bug in Chromium (which powers both Chrome and Edge). I filed a bug here


Solution

  • The issue was actually due to a bug in Chrome, which has been fixed. See https://bugs.chromium.org/p/chromium/issues/detail?id=1214277