From d5a5de2f5a853e02f210f8b55d2d9c7126695730 Mon Sep 17 00:00:00 2001 From: Wagner Maciel Date: Thu, 10 Jun 2021 05:42:50 -0700 Subject: [PATCH] =?UTF-8?q?fix(material-experimental/mdc-slider):=20initia?= =?UTF-8?q?lize=20the=20aria-valuetext=20=E2=80=A6=20(#22877)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(material-experimental/mdc-slider): initialize the aria-valuetext for slider thumb inputs * The MDC Foundation does not set the aria-valuetext of slider inputs until a value change, so we need to manually initialize it. * fixup! fix(material-experimental/mdc-slider): initialize the aria-valuetext for slider thumb inputs * fix(material-experimental/mdc-slider): reword comment Co-authored-by: Paul Gschwendtner Co-authored-by: Paul Gschwendtner --- .../mdc-slider/slider.spec.ts | 24 +++++++++++++++++++ .../mdc-slider/slider.ts | 11 +++++++++ 2 files changed, 35 insertions(+) diff --git a/src/material-experimental/mdc-slider/slider.spec.ts b/src/material-experimental/mdc-slider/slider.spec.ts index 215809988411..b8d53aec693d 100644 --- a/src/material-experimental/mdc-slider/slider.spec.ts +++ b/src/material-experimental/mdc-slider/slider.spec.ts @@ -71,6 +71,7 @@ describe('MDC-based MatSlider' , () => { expect(inputInstance.value).toBe(0); expect(sliderInstance.min).toBe(0); expect(sliderInstance.max).toBe(100); + expect(inputInstance._hostElement.getAttribute('aria-valuetext')).toBe('0'); }); it('should update the value on mousedown', () => { @@ -126,6 +127,8 @@ describe('MDC-based MatSlider' , () => { expect(endInputInstance.value).toBe(100); expect(sliderInstance.min).toBe(0); expect(sliderInstance.max).toBe(100); + expect(startInputInstance._hostElement.getAttribute('aria-valuetext')).toBe('0'); + expect(endInputInstance._hostElement.getAttribute('aria-valuetext')).toBe('100'); }); it('should update the start value on a slide', () => { @@ -657,6 +660,7 @@ describe('MDC-based MatSlider' , () => { describe('slider with custom thumb label formatting', () => { let fixture: ComponentFixture; let sliderInstance: MatSlider; + let inputInstance: MatSliderThumb; let valueIndicatorTextElement: Element; beforeEach(() => { @@ -667,6 +671,13 @@ describe('MDC-based MatSlider' , () => { sliderInstance = sliderDebugElement.componentInstance; valueIndicatorTextElement = sliderNativeElement.querySelector('.mdc-slider__value-indicator-text')!; + inputInstance = sliderInstance._getInput(Thumb.END); + }); + + it('should set the aria-valuetext attribute with the given `displayWith` function', () => { + expect(inputInstance._hostElement.getAttribute('aria-valuetext')).toBe('$1'); + sliderInstance._setValue(10000, Thumb.END); + expect(inputInstance._hostElement.getAttribute('aria-valuetext')).toBe('$10k'); }); it('should invoke the passed-in `displayWith` function with the value', () => { @@ -687,12 +698,16 @@ describe('MDC-based MatSlider' , () => { let sliderInstance: MatSlider; let startValueIndicatorTextElement: Element; let endValueIndicatorTextElement: Element; + let startInputInstance: MatSliderThumb; + let endInputInstance: MatSliderThumb; beforeEach(() => { fixture = createComponent(DiscreteRangeSliderWithDisplayWith); fixture.detectChanges(); const sliderDebugElement = fixture.debugElement.query(By.directive(MatSlider))!; sliderInstance = sliderDebugElement.componentInstance; + startInputInstance = sliderInstance._getInput(Thumb.START); + endInputInstance = sliderInstance._getInput(Thumb.END); const startThumbElement = sliderInstance._getThumbElement(Thumb.START); const endThumbElement = sliderInstance._getThumbElement(Thumb.END); @@ -702,6 +717,15 @@ describe('MDC-based MatSlider' , () => { endThumbElement.querySelector('.mdc-slider__value-indicator-text')!; }); + it('should set the aria-valuetext attribute with the given `displayWith` function', () => { + expect(startInputInstance._hostElement.getAttribute('aria-valuetext')).toBe('$1'); + expect(endInputInstance._hostElement.getAttribute('aria-valuetext')).toBe('$1000k'); + sliderInstance._setValue(250000, Thumb.START); + sliderInstance._setValue(810000, Thumb.END); + expect(startInputInstance._hostElement.getAttribute('aria-valuetext')).toBe('$250k'); + expect(endInputInstance._hostElement.getAttribute('aria-valuetext')).toBe('$810k'); + }); + it('should invoke the passed-in `displayWith` function with the start value', () => { spyOn(sliderInstance, 'displayWith').and.callThrough(); sliderInstance._setValue(1337, Thumb.START); diff --git a/src/material-experimental/mdc-slider/slider.ts b/src/material-experimental/mdc-slider/slider.ts index ae737ffb97ca..158c916d6c86 100644 --- a/src/material-experimental/mdc-slider/slider.ts +++ b/src/material-experimental/mdc-slider/slider.ts @@ -379,6 +379,7 @@ export class MatSliderThumb implements AfterViewInit, ControlValueAccessor, OnIn // By calling this in ngOnInit() we guarantee that the sibling sliders initial value by // has already been set by the time we reach ngAfterViewInit(). this._initializeInputValueAttribute(); + this._initializeAriaValueText(); } ngAfterViewInit() { @@ -503,6 +504,16 @@ export class MatSliderThumb implements AfterViewInit, ControlValueAccessor, OnIn } } + /** + * Initializes the aria-valuetext attribute. + * + * Must be called AFTER the value attribute is set. This is because the slider's parent + * `displayWith` function is used to set the `aria-valuetext` attribute. + */ + private _initializeAriaValueText(): void { + this._hostElement.setAttribute('aria-valuetext', this._slider.displayWith(this.value)); + } + static ngAcceptInputType_value: NumberInput; }