Preamble
There are 3 focus strategies: the default one (tabbing works as expected), roving tabindex, and aria-activedescendant.
The default one just works so there's nothing for us to do. aria-activedescendant is pretty rare so let's not worry about it at the moment. But roving tabindex does come up with decent frequency so I'd like to explore creating a reusable pattern (component? util? hook?) for quickly implementing it. Ideally it'd be exportable so consumers as well as EUI could benefit from it.
Summary
With several tab-heavy, discrete components we want to keep the keyboard experience streamlined. Taking Kibana as an example, tabbing through the app can become an arduous and long process depending on the page.
One way to streamline this is a roving tabindex. All the tabbable items of a component get tabindex=-1 except the first one which is at tabindex=0. Once you're on the first element, you can use arrow keys to move your focus between the tabbable items. Pressing tab again moves you out of the component. Tabbing back into it (e.g., shift+tab) returns can optionally return you to either the first tabbable item again or return you to the same one when you exited (depending on whichever makes most sense for the component).
ARIA spec for reference
Technical considerations
- Should optionally reset to first item or last item to be focused
- How many axises do we want to support? (Only 1-axis would be simpler for sure, but 2-axis use cases also exist.)
- Should only be allowed on specific aria roles (I can make a list of which once we get to this.)
Design/UX considerations
-
It can sometimes be unexpected when the tabbing strategy switches. Do we want any sort of visual indicator? (I've seen a little arrow keys icon popup on the page sometimes for when roving tab focus is in place. Could also do something with custom focus states on either the wrapping component or each tabbable element. Probably other ideas out there as well.)
All that said, solving this isn't a big deal in my opinion because the cost of not knowing is pretty low. (A user may tab past the component but should always be able to tab back and arrow keys are a common alternative so there shouldn't be any teaching required.)
-
Some things are assumed to be one axis but can overflow to more line. In those cases, it's a toss up rather focus should support 2-axis arrow navigation as well. Assuming everything is technically feasible, what would we want to do? (For example, a toolbar that spans two lines.)
Examples in EUI today
- DataGrid* is a great example of 2-axis roving focus (
role=grid)
- BottomBar and ControlBar should support x-axis roving (
role=toolbar)
- ButtonGroup with more than 3 buttons should support x-axis roving (
role=toolbar)
- TreeView should support y-axis roving (
role=tree)
- Tabs with more than 3 tabs should support x-axis roving (
role=tablist)
- Pills inside a ComboBox should support x-axis roving (
role=list, I think...)
- FilterGroup with more than 3 FilterGroupButton items should support x-axis roving (
role=toolbar, I think...)
- Misc other "toolbars" (e.g., above the DataGrid, above the Markdown)
- DataGrid, I believe, is the only implemented on today. It's also the most complicated one.
- TreeView and DataGrid (will) have significant other arrow key controls which we should make sure don't interfere.
Preamble
There are 3 focus strategies: the default one (tabbing works as expected), roving tabindex, and
aria-activedescendant.The default one just works so there's nothing for us to do.
aria-activedescendantis pretty rare so let's not worry about it at the moment. But roving tabindex does come up with decent frequency so I'd like to explore creating a reusable pattern (component? util? hook?) for quickly implementing it. Ideally it'd be exportable so consumers as well as EUI could benefit from it.Summary
With several tab-heavy, discrete components we want to keep the keyboard experience streamlined. Taking Kibana as an example, tabbing through the app can become an arduous and long process depending on the page.
One way to streamline this is a roving tabindex. All the tabbable items of a component get
tabindex=-1except the first one which is attabindex=0. Once you're on the first element, you can use arrow keys to move your focus between the tabbable items. Pressing tab again moves you out of the component. Tabbing back into it (e.g., shift+tab) returns can optionally return you to either the first tabbable item again or return you to the same one when you exited (depending on whichever makes most sense for the component).ARIA spec for reference
Technical considerations
Design/UX considerations
It can sometimes be unexpected when the tabbing strategy switches. Do we want any sort of visual indicator? (I've seen a little arrow keys icon popup on the page sometimes for when roving tab focus is in place. Could also do something with custom focus states on either the wrapping component or each tabbable element. Probably other ideas out there as well.)
All that said, solving this isn't a big deal in my opinion because the cost of not knowing is pretty low. (A user may tab past the component but should always be able to tab back and arrow keys are a common alternative so there shouldn't be any teaching required.)
Some things are assumed to be one axis but can overflow to more line. In those cases, it's a toss up rather focus should support 2-axis arrow navigation as well. Assuming everything is technically feasible, what would we want to do? (For example, a toolbar that spans two lines.)
Examples in EUI today
role=grid)role=toolbar)role=toolbar)role=tree)role=tablist)role=list, I think...)role=toolbar, I think...)