Skip to content

Commit 974d330

Browse files
DMezhenskyiamysorto
authored andcommitted
fix(material/slider): Ticks updated wrongly if the max property 0 (#24218)
* fix(material/slider): Ticks updated wrongly if the max property changed to 0 When we get equal min & max value for the slider then we can get division by zero which leads to an improper style value for the background-size (Infinity%). This fix introduces a tiny function that checks if we deal with finite numbers during calculations where potentially division by zero may occur. Fixes #23913 * fix(material/slider): Check if interval persentage a valid number Fixes #23913 (cherry picked from commit c1f25bc)
1 parent 5d7d6ea commit 974d330

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

src/material/slider/slider.spec.ts

+20
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,26 @@ describe('MatSlider', () => {
450450
expect(sliderInstance.percent).toBe(1);
451451
},
452452
);
453+
it('should properly update ticks when max value changed to 0', () => {
454+
testComponent.min = 0;
455+
testComponent.max = 100;
456+
fixture.detectChanges();
457+
458+
dispatchMouseenterEvent(sliderNativeElement);
459+
fixture.detectChanges();
460+
461+
expect(ticksElement.style.backgroundSize).toBe('6% 2px');
462+
expect(ticksElement.style.transform).toContain('translateX(3%)');
463+
464+
testComponent.max = 0;
465+
fixture.detectChanges();
466+
467+
dispatchMouseenterEvent(sliderNativeElement);
468+
fixture.detectChanges();
469+
470+
expect(ticksElement.style.backgroundSize).toBe('0% 2px');
471+
expect(ticksElement.style.transform).toContain('translateX(0%)');
472+
});
453473
});
454474

455475
describe('slider with set value', () => {

src/material/slider/slider.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -860,15 +860,17 @@ export class MatSlider
860860
return;
861861
}
862862

863+
let tickIntervalPercent: number;
863864
if (this.tickInterval == 'auto') {
864865
let trackSize = this.vertical ? this._sliderDimensions.height : this._sliderDimensions.width;
865866
let pixelsPerStep = (trackSize * this.step) / (this.max - this.min);
866867
let stepsPerTick = Math.ceil(MIN_AUTO_TICK_SEPARATION / pixelsPerStep);
867868
let pixelsPerTick = stepsPerTick * this.step;
868-
this._tickIntervalPercent = pixelsPerTick / trackSize;
869+
tickIntervalPercent = pixelsPerTick / trackSize;
869870
} else {
870-
this._tickIntervalPercent = (this.tickInterval * this.step) / (this.max - this.min);
871+
tickIntervalPercent = (this.tickInterval * this.step) / (this.max - this.min);
871872
}
873+
this._tickIntervalPercent = isSafeNumber(tickIntervalPercent) ? tickIntervalPercent : 0;
872874
}
873875

874876
/** Creates a slider change object from the specified value. */
@@ -883,7 +885,8 @@ export class MatSlider
883885

884886
/** Calculates the percentage of the slider that a value is. */
885887
private _calculatePercentage(value: number | null) {
886-
return ((value || 0) - this.min) / (this.max - this.min);
888+
const percentage = ((value || 0) - this.min) / (this.max - this.min);
889+
return isSafeNumber(percentage) ? percentage : 0;
887890
}
888891

889892
/** Calculates the value a percentage of the slider corresponds to. */
@@ -954,6 +957,11 @@ export class MatSlider
954957
}
955958
}
956959

960+
/** Checks if number is safe for calculation */
961+
function isSafeNumber(value: number) {
962+
return !isNaN(value) && isFinite(value);
963+
}
964+
957965
/** Returns whether an event is a touch event. */
958966
function isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent {
959967
// This function is called for every pixel that the user has dragged so we need it to be

0 commit comments

Comments
 (0)