Reputation: 213
Angular material gives us in-app navigation with tabs.
By Angular:
<nav mat-tab-nav-bar>
provides a tab-like UI for navigating between routes.
I want to make it more accessibile.
What we have now:
Navigation with arrows (leftrightupdown) throw the list items.
Enter activate the selected tab.
Tab focus on the elements in DOM as usual (not update the selection as the arrow keys, details below).
Accessibility requirements:
nav
item.
On the content page of the router Shift+Tab will jump from the first focusable element to the previous active element in the nav
.nav
(a
elements) will be with the right aria
roles.I don't want to change the structure, just add it the accessibility that expected from tabs.
Any help please?
How can I achieve the focus on the content from the nav
in the correct way with the Tab and Shift+Tab keys?
Looking for correct structure.
The mat-tab-nav-bar
and mat-tab-link
directive of angular for navigation are provide only a 'like' tabs UI.
I want to enable in-app routing navigation by <router-outlet></router-outlet>
directive element with keyboard accessibility.
From accessibility aspect I would expect navigate through the links with arrow keys
, Enter
activate the selected tab and Tab
key will move the focus to the content of the routed page.
Because I want to update the URL when the user chage tabs I used the nav
element with angular mat-tab-nav-bar
directive, like in the example below:
<nav mat-tab-nav-bar>
<a mat-tab-link
*ngFor="let vehicle of vehicles; let i = index"
routerLink="{{vehicle}}"
routerLinkActive="active"
(click)="activeLink = vehicle"
[active]="activeLink == vehicle">
{{vehicle}}
</a>
</nav>
<router-outlet></router-outlet>
In a 'real' nav
and a
element you can navigate with keyboard only by Tab
, but not with arrow keys.
But with the mat-tab-nav-bar
directive the routing throw the tabs work indeed by arrows, but the Tab
is not disabled for the a
element.
I want to enable the tab
key move to the content of the selected tab.
I thought about angular FocusMonitor, or KeyManager to solve this situation, but couldn't achieve the desired result.
I can also auto capture the focus to the selected tab content, but again it's not exactly the behavior of tabs.
For example, in this demo I want to navigate the tabs "Cars", "Airplanes" and "Bikes" with the arrow keys. When tab selected (with Enter
or mouse
) the Tab
key will navigate to the input filed in the content.
Currently what I achieved is just focus on the input when one tab selected (as shown in the "Bikes" tab). But I want to navigate like real tabs.
BTW,
If you navigate throw the tabs with Tab
on the mat-tab-nav-bar
directive you will see the focus move from tab to tab, and press on enter will fire the click event on the a
element. But if you press on the arrow keys to navigate throw the tabs, the focus will jump to the last active tab.
simple reproduce: navigate with Tab
key twice and press on the right-arrow
key. you'll see the focus 'jumped' one step backward.
Here you can see the difference (examples from the official site):
'Real' tabs: press on tab will enter to the content of the tab.
'Like' tabs: press on tab will just move on throw the elements in the DOM.
Thanks!
Upvotes: 3
Views: 4064
Reputation: 213
I found a great solution for the main question - the Tab/shift+Tab issue.
Simple directive do the work.
@Directive({
selector: '[mat-tab-link]',
host: {
'[attr.tabindex]': 'getTabIndex',
}
})
export class AccessibleTabNavDirective {
constructor(private tabLink: MatTabLink) { }
get getTabIndex() {
return this.tabLink.active ? 0 : -1;
}
}
Please note that in one case it's lackey. If one tab selected and previous tab focused the next tab will focus on the selected tab. For example: select the second tab and return to the previous tab (with Left-arrow) - the next Tab press will focus on the active tab and not on the page content.
But this issue happens in the 'real' angular tabs so I left it as is for now.
If you have a pretty solution for the Space too... you are welcome to comment.
Upvotes: 0