Skip to content

Commit 73aeab4

Browse files
committed
fix(tabs): focus wrapping back to selected label when using shift + tab
Currently the `tabindex` of each of the tab labels is determined by the selected index. This means that if the user tabbed into the header, pressed the right arrow and then pressed shift + tab, their focus would end up on the selected tab. These changes switch to basing the `tabindex` on the focused index which is tied both to the selected index and the user's keyboard navigation.
1 parent a30094b commit 73aeab4

File tree

3 files changed

+22
-5
lines changed

3 files changed

+22
-5
lines changed

src/material/tabs/tab-group.spec.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {LEFT_ARROW} from '@angular/cdk/keycodes';
1+
import {LEFT_ARROW, RIGHT_ARROW} from '@angular/cdk/keycodes';
22
import {dispatchFakeEvent, dispatchKeyboardEvent} from '@angular/cdk/testing/private';
33
import {Component, OnInit, QueryList, ViewChild, ViewChildren} from '@angular/core';
44
import {async, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
@@ -291,6 +291,22 @@ describe('MatTabGroup', () => {
291291
subscription.unsubscribe();
292292
});
293293

294+
it('should update the tabindex of the labels when navigating via keyboard', () => {
295+
fixture.detectChanges();
296+
297+
const tabLabels = fixture.debugElement.queryAll(By.css('.mat-tab-label'))
298+
.map(label => label.nativeElement);
299+
const tabLabelContainer = fixture.debugElement
300+
.query(By.css('.mat-tab-label-container')).nativeElement as HTMLElement;
301+
302+
expect(tabLabels.map(label => label.getAttribute('tabindex'))).toEqual(['0', '-1', '-1']);
303+
304+
dispatchKeyboardEvent(tabLabelContainer, 'keydown', RIGHT_ARROW);
305+
fixture.detectChanges();
306+
307+
expect(tabLabels.map(label => label.getAttribute('tabindex'))).toEqual(['-1', '0', '-1']);
308+
});
309+
294310
});
295311

296312
describe('aria labelling', () => {

src/material/tabs/tab-group.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -369,11 +369,12 @@ export abstract class _MatTabGroupBase extends _MatTabGroupMixinBase implements
369369
}
370370

371371
/** Retrieves the tabindex for the tab. */
372-
_getTabIndex(tab: MatTab, idx: number): number | null {
373-
if (tab.disabled) {
372+
_getTabIndex(tab: MatTab, index: number): number | null {
373+
if (tab.disabled || !this._tabHeader) {
374374
return null;
375375
}
376-
return this.selectedIndex === idx ? 0 : -1;
376+
377+
return this._tabHeader.focusIndex === index ? 0 : -1;
377378
}
378379
}
379380

tools/public_api_guard/material/tabs.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export declare abstract class _MatTabGroupBase extends _MatTabGroupMixinBase imp
4949
constructor(elementRef: ElementRef, _changeDetectorRef: ChangeDetectorRef, defaultConfig?: MatTabsConfig, _animationMode?: string | undefined);
5050
_focusChanged(index: number): void;
5151
_getTabContentId(i: number): string;
52-
_getTabIndex(tab: MatTab, idx: number): number | null;
52+
_getTabIndex(tab: MatTab, index: number): number | null;
5353
_getTabLabelId(i: number): string;
5454
_handleClick(tab: MatTab, tabHeader: MatTabGroupBaseHeader, index: number): void;
5555
_removeTabBodyWrapperHeight(): void;

0 commit comments

Comments
 (0)