What version of starlight
are you using?
0.2.0
What version of astro
are you using?
2.6.5
What package manager are you using?
pnpm
What operating system are you using?
Mac
What browser are you using?
Chrome
Describe the Bug
One of our keyboard-only users reported a behavior he was not expecting with the tabs component. As expected, when focus moves into the tab list and the active tab element is focused, the left and right arrow can be used to move focus to the previous and next tab elements. However, when the tabbed content is fairly large, he expected to use the Down and Up arrow keys to use the normal scrolling behavior to read the entire content of the tab panel while keeping focus on the tab element so that he could easily move to the next tab element when he is done reading. At the moment, this is not possible as the down key automatically moves the focus to the tabpanel.
Looking at the ARIA Authoring Practices Guide for the Tabs pattern, a note mentions the following:
If the tab list is horizontal, it does not listen for Down Arrow
or Up Arrow
so those keys can provide their normal browser scrolling functions even when focus is inside the tab list.
Following this guidance would allow such behavior.
In the same guide, in the keyboard interaction section, 2 optional keyboard shortcuts are also mentioned:
Home
(Optional): Moves focus to the first tab. Optionally, activates the newly focused tab (See note below).
End
(Optional): Moves focus to the last tab. Optionally, activates the newly focused tab (See note below).
I think these 2 shortcuts could be a nice addition to the tabs component.
With these changes in mind, I propose the following changes to the tabs component keydown
event handler:
// Work out which key the user is pressing and
// Calculate the new tab's index where appropriate
const dir =
e.key === 'ArrowLeft'
? index - 1
: e.key === 'ArrowRight'
? index + 1
- : e.key === 'ArrowDown'
- ? 'down'
+ : e.key === 'Home'
+ ? 0
+ : e.key === 'End'
+ ? this.tabs.length - 1
: null;
if (dir === null) return;
- // If the down key is pressed, move focus to the open panel,
- // otherwise switch to the adjacent tab
- if (dir === 'down') {
- e.preventDefault();
- this.panels[i]?.focus();
- } else if (this.tabs[dir]) {
+ if (this.tabs[dir]) {
e.preventDefault();
this.switchTab(this.tabs[dir], dir);
}
If this is acceptable and I am not missing something for the current implementation, I would be happy to submit a PR.
Link to Minimal Reproducible Example
https://stackblitz.com/edit/github-ybbceq?file=src%2Fcontent%2Fdocs%2Findex.mdx
Participation