Skip to content

Commit d869d79

Browse files
authored
feat(material/tabs): add method for programmatically setting focus (#15228)
Adds a method that allows for focus to be moved to a particular tab. This is usually tricky, because all of the DOM elements are hidden away inside the tab group template. Fixes #15007.
1 parent bd2c324 commit d869d79

File tree

4 files changed

+59
-2
lines changed

4 files changed

+59
-2
lines changed

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ import {By} from '@angular/platform-browser';
1313
import {BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations';
1414
import {CommonModule} from '@angular/common';
1515
import {Observable} from 'rxjs';
16-
import {MAT_TABS_CONFIG, MatTab, MatTabGroup, MatTabHeaderPosition, MatTabsModule} from './index';
16+
import {
17+
MAT_TABS_CONFIG,
18+
MatTab,
19+
MatTabGroup,
20+
MatTabHeaderPosition,
21+
MatTabsModule,
22+
MatTabHeader,
23+
} from './index';
1724

1825

1926
describe('MDC-based MatTabGroup', () => {
@@ -327,6 +334,21 @@ describe('MDC-based MatTabGroup', () => {
327334
.toHaveBeenCalledWith(jasmine.objectContaining({index: 2}));
328335
}));
329336

337+
it('should be able to programmatically focus a particular tab', () => {
338+
fixture.detectChanges();
339+
const tabGroup: MatTabGroup =
340+
fixture.debugElement.query(By.css('mat-tab-group')).componentInstance;
341+
const tabHeader: MatTabHeader =
342+
fixture.debugElement.query(By.css('mat-tab-header')).componentInstance;
343+
344+
expect(tabHeader.focusIndex).not.toBe(3);
345+
346+
tabGroup.focusTab(3);
347+
fixture.detectChanges();
348+
349+
expect(tabHeader.focusIndex).not.toBe(3);
350+
});
351+
330352
});
331353

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

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ import {By} from '@angular/platform-browser';
1313
import {BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations';
1414
import {CommonModule} from '@angular/common';
1515
import {Observable} from 'rxjs';
16-
import {MatTab, MatTabGroup, MatTabHeaderPosition, MatTabsModule, MAT_TABS_CONFIG} from './index';
16+
import {
17+
MatTab,
18+
MatTabGroup,
19+
MatTabHeader,
20+
MatTabHeaderPosition,
21+
MatTabsModule,
22+
MAT_TABS_CONFIG
23+
} from './index';
1724

1825

1926
describe('MatTabGroup', () => {
@@ -326,6 +333,21 @@ describe('MatTabGroup', () => {
326333
.toHaveBeenCalledWith(jasmine.objectContaining({index: 2}));
327334
}));
328335

336+
it('should be able to programmatically focus a particular tab', () => {
337+
fixture.detectChanges();
338+
const tabGroup: MatTabGroup =
339+
fixture.debugElement.query(By.css('mat-tab-group')).componentInstance;
340+
const tabHeader: MatTabHeader =
341+
fixture.debugElement.query(By.css('mat-tab-header')).componentInstance;
342+
343+
expect(tabHeader.focusIndex).not.toBe(3);
344+
345+
tabGroup.focusTab(3);
346+
fixture.detectChanges();
347+
348+
expect(tabHeader.focusIndex).not.toBe(3);
349+
});
350+
329351
});
330352

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

src/material/tabs/tab-group.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,18 @@ export abstract class _MatTabGroupBase extends _MatTabGroupMixinBase implements
287287
}
288288
}
289289

290+
/**
291+
* Sets focus to a particular tab.
292+
* @param index Index of the tab to be focused.
293+
*/
294+
focusTab(index: number) {
295+
const header = this._tabHeader;
296+
297+
if (header) {
298+
header.focusIndex = index;
299+
}
300+
}
301+
290302
_focusChanged(index: number) {
291303
this.focusChange.emit(this._createChangeEvent(index));
292304
}

tools/public_api_guard/material/tabs.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export declare abstract class _MatTabGroupBase extends _MatTabGroupMixinBase imp
5959
_removeTabBodyWrapperHeight(): void;
6060
_setTabBodyWrapperHeight(tabHeight: number): void;
6161
_tabFocusChanged(focusOrigin: FocusOrigin, index: number): void;
62+
focusTab(index: number): void;
6263
ngAfterContentChecked(): void;
6364
ngAfterContentInit(): void;
6465
ngOnDestroy(): void;

0 commit comments

Comments
 (0)