From dcc743ad93f0b18a03278ad07f41c4abe7523da7 Mon Sep 17 00:00:00 2001 From: Wendell Hu Date: Tue, 13 Oct 2020 10:38:49 +0800 Subject: [PATCH] fix(module:slider): fix slider precision when step is decimal (#5862) close #5699 --- components/slider/slider.component.ts | 12 +++++++-- components/slider/slider.spec.ts | 37 ++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/components/slider/slider.component.ts b/components/slider/slider.component.ts index aae86914dcb..6b11adf4fcd 100644 --- a/components/slider/slider.component.ts +++ b/components/slider/slider.component.ts @@ -441,15 +441,23 @@ export class NzSliderComponent implements ControlValueAccessor, OnInit, OnChange const sliderLength = this.getSliderLength(); const ratio = ensureNumberInRange((position - sliderStart) / sliderLength, 0, 1); const val = (this.nzMax - this.nzMin) * (this.nzVertical ? 1 - ratio : ratio) + this.nzMin; - const points = this.nzMarks === null ? [] : Object.keys(this.nzMarks).map(parseFloat); + const points = + this.nzMarks === null + ? [] + : Object.keys(this.nzMarks) + .map(parseFloat) + .sort((a, b) => a - b); + if (this.nzStep !== 0 && !this.nzDots) { const closestOne = Math.round(val / this.nzStep) * this.nzStep; points.push(closestOne); } + const gaps = points.map(point => Math.abs(val - point)); const closest = points[gaps.indexOf(Math.min(...gaps))]; - return this.nzStep === null ? closest : parseFloat(closest.toFixed(getPrecision(this.nzStep))); + // return parseFloat(closest.toFixed(getPrecision(this.nzStep))); + return this.nzStep === 0 ? closest : parseFloat(closest.toFixed(getPrecision(this.nzStep))); } private valueToOffset(value: number): number { diff --git a/components/slider/slider.spec.ts b/components/slider/slider.spec.ts index 0185d1852d5..7fe492ddd53 100644 --- a/components/slider/slider.spec.ts +++ b/components/slider/slider.spec.ts @@ -593,6 +593,7 @@ describe('nz-slider', () => { fixture.detectChanges(); dispatchClickEventSequence(sliderNativeElement, 0.1); + // Potentially a bug of jasmine or karma. Event handler makes calling stack destroyed. // dispatchClickEventSequence(sliderNativeElement, 0.8); fixture.detectChanges(); @@ -651,9 +652,33 @@ describe('nz-slider', () => { expect(overlayContainerElement.textContent).toContain('VALUE-13'); dispatchMouseEvent(handlerHost, 'mouseleave'); - tick(400); // Wait for tooltip's animations + tick(400); // wait for tooltip's animations expect(overlayContainerElement.textContent).not.toContain('VALUE-13'); })); + + // fix #5699, Slider should work with decimals as well + it('should work with decimals', fakeAsync(() => { + testComponent.marks = { + 0.5: '0.5', + 0.8: '0.8', + 1: '1', + 1.2: '1.2', + 1.5: '1.5', + 2: '2' + }; + testComponent.min = 0.5; + testComponent.max = 2; + testComponent.step = null; + fixture.detectChanges(); + + dispatchClickEventSequence(sliderNativeElement, 0.13); + fixture.detectChanges(); + expect(sliderInstance.value).toBe(0.8); + + dispatchClickEventSequence(sliderNativeElement, 0.6); + fixture.detectChanges(); + expect(sliderInstance.value).toBe(1.5); + })); }); describe('slider as a custom form control', () => { @@ -902,16 +927,20 @@ class ReverseSliderWithMinAndMaxComponent {} [nzDots]="dots" [nzIncluded]="included" [nzTipFormatter]="tipFormatter" + [nzMin]="min" + [nzMax]="max" > `, styles: [styles] }) class MixedSliderComponent { - range = false; - step: number | null = 1; - marks = { 22: '(22%)', 36: '(36%)' }; dots = false; included = true; + marks: { [mark: number]: string } = { 22: '(22%)', 36: '(36%)' }; + max = 100; + min = 0; + range = false; + step: number | null = 1; tipFormatter(value: number): string { return `VALUE-${value}`;