diff --git a/src/material-experimental/mdc-tabs/tab-group.spec.ts b/src/material-experimental/mdc-tabs/tab-group.spec.ts index 0aebc19b0ec9..e441d9841ba5 100644 --- a/src/material-experimental/mdc-tabs/tab-group.spec.ts +++ b/src/material-experimental/mdc-tabs/tab-group.spec.ts @@ -13,7 +13,14 @@ import {By} from '@angular/platform-browser'; import {BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations'; import {CommonModule} from '@angular/common'; import {Observable} from 'rxjs'; -import {MAT_TABS_CONFIG, MatTab, MatTabGroup, MatTabHeaderPosition, MatTabsModule} from './index'; +import { + MAT_TABS_CONFIG, + MatTab, + MatTabGroup, + MatTabHeaderPosition, + MatTabsModule, + MatTabHeader, +} from './index'; describe('MDC-based MatTabGroup', () => { @@ -327,6 +334,21 @@ describe('MDC-based MatTabGroup', () => { .toHaveBeenCalledWith(jasmine.objectContaining({index: 2})); })); + it('should be able to programmatically focus a particular tab', () => { + fixture.detectChanges(); + const tabGroup: MatTabGroup = + fixture.debugElement.query(By.css('mat-tab-group')).componentInstance; + const tabHeader: MatTabHeader = + fixture.debugElement.query(By.css('mat-tab-header')).componentInstance; + + expect(tabHeader.focusIndex).not.toBe(3); + + tabGroup.focusTab(3); + fixture.detectChanges(); + + expect(tabHeader.focusIndex).not.toBe(3); + }); + }); describe('aria labelling', () => { diff --git a/src/material/tabs/tab-group.spec.ts b/src/material/tabs/tab-group.spec.ts index 51cdaf9fb6b1..b680d887841a 100644 --- a/src/material/tabs/tab-group.spec.ts +++ b/src/material/tabs/tab-group.spec.ts @@ -13,7 +13,14 @@ import {By} from '@angular/platform-browser'; import {BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations'; import {CommonModule} from '@angular/common'; import {Observable} from 'rxjs'; -import {MatTab, MatTabGroup, MatTabHeaderPosition, MatTabsModule, MAT_TABS_CONFIG} from './index'; +import { + MatTab, + MatTabGroup, + MatTabHeader, + MatTabHeaderPosition, + MatTabsModule, + MAT_TABS_CONFIG +} from './index'; describe('MatTabGroup', () => { @@ -326,6 +333,21 @@ describe('MatTabGroup', () => { .toHaveBeenCalledWith(jasmine.objectContaining({index: 2})); })); + it('should be able to programmatically focus a particular tab', () => { + fixture.detectChanges(); + const tabGroup: MatTabGroup = + fixture.debugElement.query(By.css('mat-tab-group')).componentInstance; + const tabHeader: MatTabHeader = + fixture.debugElement.query(By.css('mat-tab-header')).componentInstance; + + expect(tabHeader.focusIndex).not.toBe(3); + + tabGroup.focusTab(3); + fixture.detectChanges(); + + expect(tabHeader.focusIndex).not.toBe(3); + }); + }); describe('aria labelling', () => { diff --git a/src/material/tabs/tab-group.ts b/src/material/tabs/tab-group.ts index d27ecf2f03b9..e6dfc398cb82 100644 --- a/src/material/tabs/tab-group.ts +++ b/src/material/tabs/tab-group.ts @@ -287,6 +287,18 @@ export abstract class _MatTabGroupBase extends _MatTabGroupMixinBase implements } } + /** + * Sets focus to a particular tab. + * @param index Index of the tab to be focused. + */ + focusTab(index: number) { + const header = this._tabHeader; + + if (header) { + header.focusIndex = index; + } + } + _focusChanged(index: number) { this.focusChange.emit(this._createChangeEvent(index)); } diff --git a/tools/public_api_guard/material/tabs.d.ts b/tools/public_api_guard/material/tabs.d.ts index a4bd4aafbb05..340cb6f98bac 100644 --- a/tools/public_api_guard/material/tabs.d.ts +++ b/tools/public_api_guard/material/tabs.d.ts @@ -59,6 +59,7 @@ export declare abstract class _MatTabGroupBase extends _MatTabGroupMixinBase imp _removeTabBodyWrapperHeight(): void; _setTabBodyWrapperHeight(tabHeight: number): void; _tabFocusChanged(focusOrigin: FocusOrigin, index: number): void; + focusTab(index: number): void; ngAfterContentChecked(): void; ngAfterContentInit(): void; ngOnDestroy(): void;