Skip to content

Commit

Permalink
fix(slider): value not being rounded when using keyboard and decimal …
Browse files Browse the repository at this point in the history
…step (#11574)

When incrementing a slider using the keyboard, the value can end up looking like
33.300000000000004, if the consumer set a decimal step. We fixed this a while ago for dragging, but that didn't cover the keyboard interactions. These changes move the logic from the earlier fix so it can apply everywhere.

Relates to #10951.
  • Loading branch information
crisbeto authored and andrewseguin committed Jun 7, 2018
1 parent 555d8f4 commit 61f0f2a
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 9 deletions.
11 changes: 11 additions & 0 deletions src/lib/slider/slider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,17 @@ describe('MatSlider', () => {
expect(sliderInstance.value).toBe(33.3);
});

it('should truncate long decimal values when using a decimal step and the arrow keys', () => {
fixture.componentInstance.step = 0.1;
fixture.detectChanges();

for (let i = 0; i < 3; i++) {
dispatchKeyboardEvent(sliderNativeElement, 'keydown', UP_ARROW);
}

expect(sliderInstance.value).toBe(0.3);
});

});

describe('slider with auto ticks', () => {
Expand Down
20 changes: 11 additions & 9 deletions src/lib/slider/slider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,15 @@ export class MatSlider extends _MatSliderMixinBase
}
set value(v: number | null) {
if (v !== this._value) {
this._value = coerceNumberProperty(v);
let value = coerceNumberProperty(v);

// While incrementing by a decimal we can end up with values like 33.300000000000004.
// Truncate it to ensure that it matches the label and to make it easier to work with.
if (this._roundToDecimal) {
value = parseFloat(value.toFixed(this._roundToDecimal));
}

this._value = value;
this._percent = this._calculatePercentage(this._value);

// Since this also modifies the percentage, we need to let the change detection know.
Expand Down Expand Up @@ -638,17 +646,11 @@ export class MatSlider extends _MatSliderMixinBase
} else if (percent === 1) {
this.value = this.max;
} else {
let exactValue = this._calculateValue(percent);
const exactValue = this._calculateValue(percent);

// This calculation finds the closest step by finding the closest
// whole number divisible by the step relative to the min.
let closestValue = Math.round((exactValue - this.min) / this.step) * this.step + this.min;

// If we've got a step with a decimal, we may end up with something like 33.300000000000004.
// Truncate the value to ensure that it matches the label and to make it easier to work with.
if (this._roundToDecimal) {
closestValue = parseFloat(closestValue.toFixed(this._roundToDecimal));
}
const closestValue = Math.round((exactValue - this.min) / this.step) * this.step + this.min;

// The value needs to snap to the min and max.
this.value = this._clamp(closestValue, this.min, this.max);
Expand Down

0 comments on commit 61f0f2a

Please sign in to comment.