Skip to content

Commit 1be81eb

Browse files
committed
fix(select): allow custom aria-label
* Adds support for custom `aria-label` attributes on the select host element. * Also fixes that the `aria-labelledby` attribute is overwritten by the placeholder `aria-label`. Fixes angular#3762.
1 parent a25e7bb commit 1be81eb

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

src/lib/select/select.spec.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,21 @@ describe('MdSelect', () => {
10851085
expect(select.getAttribute('aria-label')).toEqual('Food');
10861086
});
10871087

1088+
it('should support setting a custom aria-label', () => {
1089+
fixture.componentInstance.ariaLabel = 'Custom Label';
1090+
fixture.detectChanges();
1091+
1092+
expect(select.getAttribute('aria-label')).toEqual('Custom Label');
1093+
});
1094+
1095+
it('should not set a aria-label if aria-labelledby is specified', () => {
1096+
fixture.componentInstance.ariaLabelledby = 'myLabelId';
1097+
fixture.detectChanges();
1098+
1099+
expect(select.getAttribute('aria-label')).toBeFalsy('Expected no aria-label to be set.');
1100+
expect(select.getAttribute('aria-labelledby')).toBe('myLabelId');
1101+
});
1102+
10881103
it('should set the tabindex of the select to 0 by default', () => {
10891104
expect(select.getAttribute('tabindex')).toEqual('0');
10901105
});
@@ -1606,7 +1621,7 @@ describe('MdSelect', () => {
16061621
template: `
16071622
<div [style.height.px]="heightAbove"></div>
16081623
<md-select placeholder="Food" [formControl]="control" [required]="isRequired"
1609-
[tabIndex]="tabIndexOverride">
1624+
[tabIndex]="tabIndexOverride" [aria-label]="ariaLabel" [aria-labelledby]="ariaLabelledby">
16101625
<md-option *ngFor="let food of foods" [value]="food.value" [disabled]="food.disabled">
16111626
{{ food.viewValue }}
16121627
</md-option>
@@ -1630,6 +1645,8 @@ class BasicSelect {
16301645
heightAbove = 0;
16311646
heightBelow = 0;
16321647
tabIndexOverride: number;
1648+
ariaLabel: string;
1649+
ariaLabelledby: string;
16331650

16341651
@ViewChild(MdSelect) select: MdSelect;
16351652
@ViewChildren(MdOption) options: QueryList<MdOption>;

src/lib/select/select.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ export type MdSelectFloatPlaceholderType = 'always' | 'never' | 'auto';
101101
host: {
102102
'role': 'listbox',
103103
'[attr.tabindex]': 'tabIndex',
104-
'[attr.aria-label]': 'placeholder',
104+
'[attr.aria-label]': '_ariaLabel',
105+
'[attr.aria-labelledby]': 'ariaLabelledby',
105106
'[attr.aria-required]': 'required.toString()',
106107
'[attr.aria-disabled]': 'disabled.toString()',
107108
'[attr.aria-invalid]': '_control?.invalid || "false"',
@@ -279,6 +280,12 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr
279280
}
280281
}
281282

283+
/** Aria label of the select. If not specified, the placeholder will be used as label. */
284+
@Input('aria-label') ariaLabel: string = '';
285+
286+
/** Input that can be used to specify the `aria-labelledby` attribute. */
287+
@Input('aria-labelledby') ariaLabelledby: string = '';
288+
282289
/** Combined stream of all of the child options' change events. */
283290
get optionSelectionChanges(): Observable<MdOptionSelectionChange> {
284291
return Observable.merge(...this.options.map(option => option.onSelectionChange));
@@ -747,6 +754,13 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr
747754
'visible' : 'hidden';
748755
}
749756

757+
/** Returns the aria-label of the select component. */
758+
get _ariaLabel(): string {
759+
// If a ariaLabelledby value has been set, the select should not overwrite the
760+
// `aria-labelledby` value by setting the ariaLabel to the placeholder.
761+
return this.ariaLabelledby ? null : this.ariaLabel || this.placeholder;
762+
}
763+
750764
/**
751765
* Calculates the y-offset of the select's overlay panel in relation to the
752766
* top start corner of the trigger. It has to be adjusted in order for the

0 commit comments

Comments
 (0)