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

[EuiSuggest] Accessibility #2404

Closed
30 tasks
myasonik opened this issue Oct 7, 2019 · 4 comments · Fixed by #5157
Closed
30 tasks

[EuiSuggest] Accessibility #2404

myasonik opened this issue Oct 7, 2019 · 4 comments · Fixed by #5157
Assignees
Labels
accessibility - WCAG A Level A WCAG Accessibility Criteria accessibility meta

Comments

@myasonik
Copy link
Contributor

myasonik commented Oct 7, 2019

TODOs

ARIA and DOM setup

  • div[role="combobox"]
    • aria-expanded={isResultsListOpen}
    • aria-owns={collectionId}
    • aria-haspopup="listbox"Δ
  • Inside, an input
    • labelled by a label[for="inputId"] or aria-label
    • autocomplete="off"
    • aria-expanded="{isResultsListOpen}"§
    • role="combobox"§
    • aria-autocomplete="list"
    • aria-controls="{collectionId}"
    • aria-haspopup="listbox"Δ§
    • aria-activedescendant="{descendantId}"
    • aria-describedby="{uniqueId-info} {uniqueId-instructions}"
  • A ul (ideally, the next sibling element but can be inside a portal if it must)
    • role="listbox"
    • id="{collectionId}"
    • labelled by the same label (using aria-labelledby) or aria-label as for the input
    • Children are an li with a role="option", aria-selected={isCurrentlyFocusedOption} and an id (That gets used as the descdendantId mentioned above; it can be one, static ID that moves to the appropriate li or individual IDs per li which then gets updated at the aria-activedescendant attribute)
  • Somewhere on the page, a p
    • id="{uniqueId-info}"
    • Can be visually hidden
    • Communicates the state (draft, loading, saved)
  • Somewhere on the page, a p
    • id="{uniqueId-instructions}"
    • Can be visually hidden
    • Communicates basic instructions. Something like: "Use up and down arrows to move focus over options. Enter to select. Escape to collapse options."

Focus and keyboard controls

  • TAB
    • If an option is currently active, select the current option (same as ENTER) and moves focus (as it normally would)
    • If no option is active, collapse the listbox and move focus (as it normally would)
    • When tabbing through the widget, the only tab stop should be the input§
  • ESC
    • If the listbox is open, collapse the listbox
    • Optionally, clear the input field
    • Optionally, return the state of the typeahead to whatever it was before focus was set on the input
  • DOWN_ARROW
    • If the listbox is closed and there are options, expand the listbox and set aria-activedescendant to the first option
    • If the listbox is expanded and there are subsequent options, set aria-activedescendant to the next option
    • If the listbox is expanded and there are no subsequent options, set aria-activedescendant to the first option (i.e., wrap around)
  • UP_ARROW
    • If there is a previous option, set aria-activedescendant to the previous option
    • If there are no previous options, set aria-activedescendant to the last option (i.e., wrap around)
  • ENTER
    • If an option is currently active, select the option, collapsing the listbox and clearing the input field

Notes

† Swapping the value of aria-autocomplete isn't supposed to be a dynamic thing but the spec is vague on how to handle dynamic results. It seems to work though so I think we roll with it.

Δ Using listbox here instead of grid which would also be appropriate to simplify both the implementation and the user interaction. Because grid popups are so much less common, it'll be a more difficult pattern for users to pick up.

‡ These properties follow the ARIA 1.0 spec, not the new ARIA 1.1 spec but the support is best to combine approaches

§ Using aria-activedescendant vs DOM focus is debatable. The spec is open to either implementation but I think this is the right decision based on our already TAB heavy interfaces, general lack of strong accessible navigation controls around apps, has a lower chance of throwing a user's focus back to the body, and supports a wider array of possible interfaces (e.g., adding controls at the bottom of results like saved searches wanted to do in an earlier draft UI).

An incomplete example

https://codepen.io/myasonik/pen/LYYEYXb?editors=0010


References

@anishagg17
Copy link
Contributor

@myasonik I want to work on the keyboard controls for this component

@myasonik
Copy link
Contributor Author

This isn't a good issue to take at the moment as the rewrite of EuiSelectable is likely to impact EuiSuggest's implementation

@anishagg17
Copy link
Contributor

okay would tackle it after the rewrite part is completed

@cchaos cchaos changed the title EuiSuggest a11y spec [EuiSuggest] Accessibility Mar 18, 2020
@cchaos cchaos added the meta label Mar 18, 2020
@myasonik
Copy link
Contributor Author

Closing this issue to preserve the spec, but opening a new one to reflect the latest plan to rebuild EuiSuggest on top of/with Selectable.

See #3733

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accessibility - WCAG A Level A WCAG Accessibility Criteria accessibility meta
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants