In the following example, you can use tab
and shift tab
in order to navigate through the list Description Details (<dd>
tag), this works by default.
<dl>
<dt style={{ textAlign: "center" }}>Beast of Bodmin</dt>
<dd>
<Button>A large feline inhabiting Bodmin Moor.</Button>
</dd>
<dt style={{ textAlign: "center" }}>Morgawr</dt>
<dd>
<Button>A sea serpent.</Button>
</dd>
<dt style={{ textAlign: "center" }}>Owlman</dt>
<dd>
<Button>A giant owl-like creature.</Button>
</dd>
</dl>
I want to achieve the same using also (or instead), up and down arrow keys.
You can find a running example in the following codesandbox:
https://codesandbox.io/s/friendly-tdd-t6z5lz?file=/src/App.tsx:329-772
Any suggestions?
CodePudding user response:
To put it more correctly, you can use Tab to navigate the buttons. It doesn’t matter what structure they are in.
Now, if you want to establish a composite component by implementing Keyboard Navigation Inside the Component, the component needs to fit an expected pattern, which then should be conveyed by visual means as well as the correct ARIA Role (affordance).
While your examples don’t hint towards the actual nature of your buttons, the Toolbar pattern seems appropriate, in its vertical configuration.
<dl role="toolbar" aria-orientation="vertical" aria-label="Name this toolbar!">
Manage focus
To actually implement keyboard navigation inside a component, the Roving tabindex usually is the easiest solution.
- Initially all buttons except the first have
tabindex="-1"
. This way, the user can enter and leave the component by means of Tab - The component needs to handle the keydown events for the arrow keys
- To focus another button, you make it focusable and then focus it programmatically
nextButton.focus();
nextButton.setAttribute('tabindex', 0);
currentButton.setAttribute('tabindex', -1);
There also are mixins available on npm that establish a roving tab index.
Communicate the assigned term
You are using a <dl>
structure, which assigns the terms <dt>
to the button’s text. Since users are navigating this component with focus, you will need to associate these terms also for assistive technology with the button, not only visually.
This can be achieved via the aria-describedby
property. That way, when focussing the button, a screen reader will also announce the term.
<dt style={{ textAlign: "center" }} id="dt-beast-bodmin">Beast of Bodmin</dt>
<dd>
<Button aria-describedby="dt-beast-bodmin">A large feline inhabiting Bodmin Moor.</Button>
</dd>