Skip to content

Commit aa32621

Browse files
authored
fix(material/slider): first keypress ignored if out-of-bounds value is assigned (#23827)
We allow for an out-of-bounds value to be assigned to a `mat-slider` programmatically, however our key press logic didn't account for it. This meant that it might appear as if the first key press is ignored if such a value is assigned by the user. Fixes #23817.
1 parent 66c9e4e commit aa32621

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

src/material/slider/slider.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,7 @@ describe('MatSlider', () => {
962962
let sliderNativeElement: HTMLElement;
963963
let testComponent: SliderWithChangeHandler;
964964
let sliderInstance: MatSlider;
965+
let trackFillElement: HTMLElement;
965966

966967
beforeEach(() => {
967968
fixture = createComponent(SliderWithChangeHandler);
@@ -974,6 +975,7 @@ describe('MatSlider', () => {
974975
sliderDebugElement = fixture.debugElement.query(By.directive(MatSlider))!;
975976
sliderNativeElement = sliderDebugElement.nativeElement;
976977
sliderInstance = sliderDebugElement.injector.get<MatSlider>(MatSlider);
978+
trackFillElement = sliderNativeElement.querySelector('.mat-slider-track-fill') as HTMLElement;
977979
});
978980

979981
it('should increment slider by 1 on up arrow pressed', () => {
@@ -1028,6 +1030,21 @@ describe('MatSlider', () => {
10281030
expect(sliderInstance.value).toBe(99);
10291031
});
10301032

1033+
it('should decrement from max when interacting after out-of-bounds value is assigned', () => {
1034+
sliderInstance.max = 100;
1035+
sliderInstance.value = 200;
1036+
fixture.detectChanges();
1037+
1038+
expect(sliderInstance.value).toBe(200);
1039+
expect(trackFillElement.style.transform).toContain('scale3d(1, 1, 1)');
1040+
1041+
dispatchKeyboardEvent(sliderNativeElement, 'keydown', LEFT_ARROW);
1042+
fixture.detectChanges();
1043+
1044+
expect(sliderInstance.value).toBe(99);
1045+
expect(trackFillElement.style.transform).toContain('scale3d(0.99, 1, 1)');
1046+
});
1047+
10311048
it('should increment slider by 10 on page up pressed', () => {
10321049
expect(testComponent.onChange).not.toHaveBeenCalled();
10331050

src/material/slider/slider.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,10 @@ export class MatSlider
793793

794794
/** Increments the slider by the given number of steps (negative number decrements). */
795795
private _increment(numSteps: number) {
796-
this.value = this._clamp((this.value || 0) + this.step * numSteps, this.min, this.max);
796+
// Pre-clamp the current value since it's allowed to be
797+
// out of bounds when assigned programmatically.
798+
const clampedValue = this._clamp(this.value || 0, this.min, this.max);
799+
this.value = this._clamp(clampedValue + this.step * numSteps, this.min, this.max);
797800
}
798801

799802
/** Calculate the new value from the new physical location. The value will always be snapped. */

0 commit comments

Comments
 (0)