Skip to content
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

Accessibility Issue: Ngx-mat-select-search dropdown, navigating options in the dropdown using down arrow without search value, NVDA reading blank #349

Closed
GowthamGururaj opened this issue Nov 30, 2021 · 7 comments · Fixed by #392

Comments

@GowthamGururaj
Copy link

Actual Behavior: While navigating options in the dropdown using down arrow without any search value, NVDA announcing "blank" and option in both speech viewer window and voice.

For Example: if you take country list dropdown and navigate the options without search value then NVDA announcing

blank
Albania 1 of 15

Expected Behavior: While navigating options in the dropdown using down arrow, NVDA should announce the option from the list

For Example: if you take country list dropdown and navigate the options without search value then NVDA should announce

Albania 1 of 15

I tried using disableInitialFocus attribute to "true" then in dropdown options, user wont able to navigate and focus the search input through keyboard.

Any workaround for this issue ?

ngx-mat-select-search

@macjohnny
Copy link
Member

Thanks for reporting. Would you like to fix this?

should be somewhere here:

@GowthamGururaj
Copy link
Author

Sure, will verify this change and let you know.

@kiwidude68
Copy link

@GowthamGururaj Did you get anywhere with this? I'm seeing the same issue (and MANY other accessibility problems) with this component unfortunately. Some of which are listed as open issues here (e.g. can't tab to the Select All button), and others that haven't been reported (like the approach of disabling the mat-option the Search is in means that the components that are hosted on it all get announced as "unavailable" by NVDA, unless you add aria-disabled="false" on the checkbox, input text and button).

There are a few problems around the announce stuff. The first being that it is double announcing (which is why you hear that "blank") the content of the search textbox where your focus is, followed by some info on the currently selected option (the code that macjohnny mentions above). As was indicated in the original issue report - unfortunately modifying that code won't solve your issue. A second issue is it never announces the first item in the list - it is only when the user arrows down or up that the options are announced. And then a third issue is it doesn't announce the checked state of the current item...

I have a dreaded suspicion that this component's fundamental approach is just not workable for accessibility compliance - as was hinted at in this thread comment below to do with problems of role.
angular/components#5697 (comment)

All very frustrating - it seems the Angular team have just pretended the community have never requested searching/multi-select feature dropdowns, and EVERY single implementation I have come across be it home-made or commercial has either accessibility issues or insufficient features that are found in 15 seconds of using NVDA and keyboard only.

@macjohnny
Copy link
Member

@kiwidude68 I am happy to accept your improvements to this component.
Please open separate issues for each bug or feature.

@kiwidude68
Copy link

@macjohnny - if I had the answers myself I wouldn't have needed to post :). It is a very long list of problems for accessibility unfortunately. And I honestly don't know if they even can be fixed with this approach of a fake mat-option inside a mat-select. Focus is on the search text allowing the user to type, but then the control is trying to auto-select (and announce) items in the list below it. Which is why the screenreader is confused - "I'm in a search field here, leave me alone". The most "accessible" multi-select dropdowns I have come across rely on the user hitting tab to move within the component to navigate between the sections in it (the search area and the items) - but of course that is not the way a mat-select works which is expecting arrow keys up/down etc.

It is all just very broken unfortunately...

@escheiermann
Copy link
Contributor

escheiermann commented Sep 24, 2022

@GowthamGururaj @kiwidude68 @macjohnny I had the same issue with the select search while using the NVDA screenreader. I could track down the problem and provided a pull request with a solution #392

The problem was caused by the selectSearchInput keeping focus while browsing through the options with the arrow keys. Screenreaders would announce the current value of the input before each option. When the input is empty, it would always announce 'blank' and then announce the option. This could distract users who are bound to use screenreaders and keyboard controls.

As mentioned in this example from W3C, the ARIA properties aria-activedescendant and aria-selected have to be set properly on the input and mat-option elements. Also the mat-option element containing the component must have aria-hidden set to true, so that the number of options get announced correctly.

For a quick workaround try this:

<mat-option aria-hidden="true">
  <ngx-mat-select-search #selectSearch></ngx-mat-select-search>
</mat-option>
@ViewChild("selectSearch") selectSearch: any;
private activeDescendant: HTMLElement;
ngAfterViewInit() {
  this.selectSearch._handleKeyup = (event) => { 
    if (event.keyCode === UP_ARROW || event.keyCode === DOWN_ARROW) {
      const ariaActiveDescendantId = this.selectSearch.matSelect._getAriaActiveDescendant();
      const index = this.selectSearch._options.toArray().findIndex(item => item.id === ariaActiveDescendantId);
      if (index !== -1) {
        this.activeDescendant?.removeAttribute('aria-selected');
        this.activeDescendant = this.selectSearch._options.toArray()[index]._getHostElement();
        this.activeDescendant.setAttribute('aria-selected', 'true');
        this.selectSearch.searchSelectInput.nativeElement.setAttribute('aria-activedescendant', ariaActiveDescendantId);
      }
    }
  }
}

@macjohnny
Copy link
Member

this was released in 5.0.0, thanks @escheiermann!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants