Skip to content

Commit 8c22651

Browse files
crisbetovictoriaaa234
authored andcommitted
fix(tabs): unable to set aria-label or aria-labelledby on tab (#11898)
1 parent 3d1ee03 commit 8c22651

File tree

3 files changed

+67
-2
lines changed

3 files changed

+67
-2
lines changed

src/lib/tabs/tab-group.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
[attr.aria-setsize]="_tabs.length"
1212
[attr.aria-controls]="_getTabContentId(i)"
1313
[attr.aria-selected]="selectedIndex == i"
14+
[attr.aria-label]="tab.ariaLabel || null"
15+
[attr.aria-labelledby]="(!tab.ariaLabel && tab.ariaLabelledby) ? tab.ariaLabelledby : null"
1416
[class.mat-tab-label-active]="selectedIndex == i"
1517
[disabled]="tab.disabled"
1618
[matRippleDisabled]="tab.disabled || disableRipple"

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

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ describe('MatTabGroup', () => {
1919
DisabledTabsTestApp,
2020
TabGroupWithSimpleApi,
2121
TemplateTabs,
22+
TabGroupWithAriaInputs,
2223
],
2324
});
2425

@@ -233,6 +234,46 @@ describe('MatTabGroup', () => {
233234

234235
});
235236

237+
describe('aria labelling', () => {
238+
let fixture: ComponentFixture<TabGroupWithAriaInputs>;
239+
let tab: HTMLElement;
240+
241+
beforeEach(fakeAsync(() => {
242+
fixture = TestBed.createComponent(TabGroupWithAriaInputs);
243+
fixture.detectChanges();
244+
tick();
245+
tab = fixture.nativeElement.querySelector('.mat-tab-label');
246+
}));
247+
248+
it('should not set aria-label or aria-labelledby attributes if they are not passed in', () => {
249+
expect(tab.hasAttribute('aria-label')).toBe(false);
250+
expect(tab.hasAttribute('aria-labelledby')).toBe(false);
251+
});
252+
253+
it('should set the aria-label attribute', () => {
254+
fixture.componentInstance.ariaLabel = 'Fruit';
255+
fixture.detectChanges();
256+
257+
expect(tab.getAttribute('aria-label')).toBe('Fruit');
258+
});
259+
260+
it('should set the aria-labelledby attribute', () => {
261+
fixture.componentInstance.ariaLabelledby = 'fruit-label';
262+
fixture.detectChanges();
263+
264+
expect(tab.getAttribute('aria-labelledby')).toBe('fruit-label');
265+
});
266+
267+
it('should not be able to set both an aria-label and aria-labelledby', () => {
268+
fixture.componentInstance.ariaLabel = 'Fruit';
269+
fixture.componentInstance.ariaLabelledby = 'fruit-label';
270+
fixture.detectChanges();
271+
272+
expect(tab.getAttribute('aria-label')).toBe('Fruit');
273+
expect(tab.hasAttribute('aria-labelledby')).toBe(false);
274+
});
275+
});
276+
236277
describe('disable tabs', () => {
237278
let fixture: ComponentFixture<DisabledTabsTestApp>;
238279
beforeEach(() => {
@@ -661,3 +702,16 @@ class NestedTabs {}
661702
`,
662703
})
663704
class TemplateTabs {}
705+
706+
707+
@Component({
708+
template: `
709+
<mat-tab-group>
710+
<mat-tab [aria-label]="ariaLabel" [aria-labelledby]="ariaLabelledby"></mat-tab>
711+
</mat-tab-group>
712+
`
713+
})
714+
class TabGroupWithAriaInputs {
715+
ariaLabel: string;
716+
ariaLabelledby: string;
717+
}

src/lib/tabs/tab.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,19 @@ export class MatTab extends _MatTabMixinBase implements OnInit, CanDisable, OnCh
5353
/** Template inside the MatTab view that contains an `<ng-content>`. */
5454
@ViewChild(TemplateRef) _implicitContent: TemplateRef<any>;
5555

56-
/** The plain text label for the tab, used when there is no template label. */
56+
/** Plain text label for the tab, used when there is no template label. */
5757
@Input('label') textLabel: string = '';
5858

59-
/** The portal that will be the hosted content of the tab */
59+
/** Aria label for the tab. */
60+
@Input('aria-label') ariaLabel: string;
61+
62+
/**
63+
* Reference to the element that the tab is labelled by.
64+
* Will be cleared if `aria-label` is set at the same time.
65+
*/
66+
@Input('aria-labelledby') ariaLabelledby: string;
67+
68+
/** Portal that will be the hosted content of the tab */
6069
private _contentPortal: TemplatePortal | null = null;
6170

6271
/** @docs-private */

0 commit comments

Comments
 (0)