From 016ce127dec6c9ec09f9e435e86910621217b3fc Mon Sep 17 00:00:00 2001 From: u237004 Date: Thu, 14 Apr 2022 13:51:11 +0200 Subject: [PATCH] fix(material/select): don't announce selected value multiple times The screen reader already announces the selected value inside the select field. Therefore, pointing the `aria-labelledby` attribute to the value field made the screen reader announce the selected value multiple times. This pull request fixes this by removing the value field from `aria-labelledby`. --- .../mdc-select/select.spec.ts | 19 +++++++------------ src/material/select/select.spec.ts | 19 +++++++------------ src/material/select/select.ts | 8 +------- 3 files changed, 15 insertions(+), 31 deletions(-) diff --git a/src/material-experimental/mdc-select/select.spec.ts b/src/material-experimental/mdc-select/select.spec.ts index 31bf11138ada..0c01fbee4923 100644 --- a/src/material-experimental/mdc-select/select.spec.ts +++ b/src/material-experimental/mdc-select/select.spec.ts @@ -192,28 +192,24 @@ describe('MDC-based MatSelect', () => { fixture.detectChanges(); const labelId = fixture.nativeElement.querySelector('label').id; - const valueId = fixture.nativeElement.querySelector('.mat-mdc-select-value').id; - expect(select.getAttribute('aria-labelledby')).toBe(`${labelId} ${valueId} myLabelId`); + expect(select.getAttribute('aria-labelledby')).toBe(`${labelId} myLabelId`); })); - it('should set aria-labelledby to the value and label IDs', fakeAsync(() => { + it('should set aria-labelledby to the label IDs', fakeAsync(() => { fixture.detectChanges(); const labelId = fixture.nativeElement.querySelector('label').id; - const valueId = fixture.nativeElement.querySelector('.mat-mdc-select-value').id; - expect(select.getAttribute('aria-labelledby')).toBe(`${labelId} ${valueId}`); + expect(select.getAttribute('aria-labelledby')).toBe(`${labelId}`); })); - it('should trim the trigger aria-labelledby when there is no label', fakeAsync(() => { + it('should remove aria-labelledby when there is no label', fakeAsync(() => { fixture.componentInstance.hasLabel = false; fixture.detectChanges(); flush(); fixture.detectChanges(); - // Note that we assert that there are no spaces around the value. - const valueId = fixture.nativeElement.querySelector('.mat-mdc-select-value').id; - expect(select.getAttribute('aria-labelledby')).toBe(`${valueId}`); + expect(select.hasAttribute('aria-labelledby')).toBeFalse(); })); it('should set the tabindex of the select to 0 by default', fakeAsync(() => { @@ -287,15 +283,14 @@ describe('MDC-based MatSelect', () => { expect(select.getAttribute('tabindex')).toEqual('0'); })); - it('should set `aria-labelledby` to the value ID if there is no form field', () => { + it('should remove `aria-labelledby` if there is no form field', () => { fixture.destroy(); const labelFixture = TestBed.createComponent(SelectWithChangeEvent); labelFixture.detectChanges(); select = labelFixture.debugElement.query(By.css('mat-select'))!.nativeElement; - const valueId = labelFixture.nativeElement.querySelector('.mat-mdc-select-value').id; - expect(select.getAttribute('aria-labelledby')?.trim()).toBe(valueId); + expect(select.hasAttribute('aria-labelledby')).toBeFalse(); }); it('should select options via the UP/DOWN arrow keys on a closed select', fakeAsync(() => { diff --git a/src/material/select/select.spec.ts b/src/material/select/select.spec.ts index c05780ac1aba..9991b779982e 100644 --- a/src/material/select/select.spec.ts +++ b/src/material/select/select.spec.ts @@ -191,27 +191,23 @@ describe('MatSelect', () => { fixture.detectChanges(); const labelId = fixture.nativeElement.querySelector('.mat-form-field-label').id; - const valueId = fixture.nativeElement.querySelector('.mat-select-value').id; - expect(select.getAttribute('aria-labelledby')).toBe(`${labelId} ${valueId} myLabelId`); + expect(select.getAttribute('aria-labelledby')).toBe(`${labelId} myLabelId`); })); - it('should set aria-labelledby to the value and label IDs', fakeAsync(() => { + it('should set aria-labelledby to the label IDs', fakeAsync(() => { fixture.detectChanges(); const labelId = fixture.nativeElement.querySelector('.mat-form-field-label').id; - const valueId = fixture.nativeElement.querySelector('.mat-select-value').id; - expect(select.getAttribute('aria-labelledby')).toBe(`${labelId} ${valueId}`); + expect(select.getAttribute('aria-labelledby')).toBe(`${labelId}`); })); - it('should trim the trigger aria-labelledby when there is no label', fakeAsync(() => { + it('should remove aria-labelledby when there is no label', fakeAsync(() => { // Reset the `placeholder` which also controls the label of the form field. fixture.componentInstance.select.placeholder = ''; fixture.detectChanges(); - // Note that we assert that there are no spaces around the value. - const valueId = fixture.nativeElement.querySelector('.mat-select-value').id; - expect(select.getAttribute('aria-labelledby')).toBe(`${valueId}`); + expect(select.hasAttribute('aria-labelledby')).toBeFalse(); })); it('should set the tabindex of the select to 0 by default', fakeAsync(() => { @@ -285,15 +281,14 @@ describe('MatSelect', () => { expect(select.getAttribute('tabindex')).toEqual('0'); })); - it('should set `aria-labelledby` to the value ID if there is no form field', () => { + it('should remove `aria-labelledby` if there is no form field', () => { fixture.destroy(); const labelFixture = TestBed.createComponent(SelectWithChangeEvent); labelFixture.detectChanges(); select = labelFixture.debugElement.query(By.css('mat-select'))!.nativeElement; - const valueId = labelFixture.nativeElement.querySelector('.mat-select-value').id; - expect(select.getAttribute('aria-labelledby')?.trim()).toBe(valueId); + expect(select.hasAttribute('aria-labelledby')).toBeFalse(); }); it('should select options via the UP/DOWN arrow keys on a closed select', fakeAsync(() => { diff --git a/src/material/select/select.ts b/src/material/select/select.ts index fd0241d767d6..a25e70b5dd35 100644 --- a/src/material/select/select.ts +++ b/src/material/select/select.ts @@ -1127,13 +1127,7 @@ export abstract class _MatSelectBase } const labelId = this._parentFormField?.getLabelId(); - let value = (labelId ? labelId + ' ' : '') + this._valueId; - - if (this.ariaLabelledby) { - value += ' ' + this.ariaLabelledby; - } - - return value; + return this.ariaLabelledby ? labelId + ' ' + this.ariaLabelledby : labelId; } /** Called when the overlay panel is done animating. */