From 783dbb3a337da15349c22c5432ab5675f5ea36a7 Mon Sep 17 00:00:00 2001 From: Philippe MARTIN Date: Wed, 26 Oct 2016 23:56:23 +0200 Subject: [PATCH] fix(slider): clamp thumb between min and max (#1617) Fixes #1557 --- src/lib/slider/slider.spec.ts | 92 +++++++++++++++++++++++++++++++++++ src/lib/slider/slider.ts | 3 +- 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/src/lib/slider/slider.spec.ts b/src/lib/slider/slider.spec.ts index acc7562aea6f..736067cf2c67 100644 --- a/src/lib/slider/slider.spec.ts +++ b/src/lib/slider/slider.spec.ts @@ -24,6 +24,8 @@ describe('MdSlider', () => { SliderWithThumbLabel, SliderWithOneWayBinding, SliderWithTwoWayBinding, + SliderWithValueSmallerThanMin, + SliderWithValueGreaterThanMax, ], providers: [ {provide: HAMMER_GESTURE_CONFIG, useFactory: () => { @@ -670,6 +672,82 @@ describe('MdSlider', () => { expect(thumbPosition).toBe(sliderDimensions.width * 3 / 4); }); }); + + describe('slider with set min and max and a value smaller than min', () => { + let fixture: ComponentFixture; + let sliderDebugElement: DebugElement; + let sliderNativeElement: HTMLElement; + let sliderInstance: MdSlider; + let sliderTrackElement: HTMLElement; + let sliderDimensions: ClientRect; + let thumbElement: HTMLElement; + let thumbDimensions: ClientRect; + + beforeEach(() => { + + fixture = TestBed.createComponent(SliderWithValueSmallerThanMin); + fixture.detectChanges(); + + sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); + sliderNativeElement = sliderDebugElement.nativeElement; + sliderInstance = sliderDebugElement.componentInstance; + + sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderDimensions = sliderTrackElement.getBoundingClientRect(); + + thumbElement = sliderNativeElement.querySelector('.md-slider-thumb-position'); + thumbDimensions = thumbElement.getBoundingClientRect(); + }); + + it('should set the value smaller than the min value', () => { + expect(sliderInstance.value).toBe(3); + expect(sliderInstance.min).toBe(4); + expect(sliderInstance.max).toBe(6); + }); + + it('should place the thumb on the min value', () => { + thumbDimensions = thumbElement.getBoundingClientRect(); + expect(thumbDimensions.left).toBe(sliderDimensions.left); + }); + }); + + describe('slider with set min and max and a value greater than max', () => { + let fixture: ComponentFixture; + let sliderDebugElement: DebugElement; + let sliderNativeElement: HTMLElement; + let sliderInstance: MdSlider; + let sliderTrackElement: HTMLElement; + let sliderDimensions: ClientRect; + let thumbElement: HTMLElement; + let thumbDimensions: ClientRect; + + beforeEach(() => { + fixture = TestBed.createComponent(SliderWithValueGreaterThanMax); + fixture.detectChanges(); + + sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); + sliderNativeElement = sliderDebugElement.nativeElement; + sliderInstance = sliderDebugElement.componentInstance; + + sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderDimensions = sliderTrackElement.getBoundingClientRect(); + + thumbElement = sliderNativeElement.querySelector('.md-slider-thumb-position'); + thumbDimensions = thumbElement.getBoundingClientRect(); + + }); + + it('should set the value greater than the max value', () => { + expect(sliderInstance.value).toBe(7); + expect(sliderInstance.min).toBe(4); + expect(sliderInstance.max).toBe(6); + }); + + it('should place the thumb on the max value', () => { + thumbDimensions = thumbElement.getBoundingClientRect(); + expect(thumbDimensions.left).toBe(sliderDimensions.right); + }); + }); }); // The transition has to be removed in order to test the updated positions without setTimeout. @@ -734,6 +812,20 @@ class SliderWithTwoWayBinding { control = new FormControl(''); } +@Component({ + template: ``, + styles: [noTransitionStyle], + encapsulation: ViewEncapsulation.None +}) +class SliderWithValueSmallerThanMin { } + +@Component({ + template: ``, + styles: [noTransitionStyle], + encapsulation: ViewEncapsulation.None +}) +class SliderWithValueGreaterThanMax { } + /** * Dispatches a click event from an element. * Note: The mouse event truncates the position for the click. diff --git a/src/lib/slider/slider.ts b/src/lib/slider/slider.ts index 455b8f83dfb6..b7d2aa22017e 100644 --- a/src/lib/slider/slider.ts +++ b/src/lib/slider/slider.ts @@ -267,7 +267,8 @@ export class MdSlider implements AfterContentInit, ControlValueAccessor { snapThumbToValue() { this.updatePercentFromValue(); if (this._sliderDimensions) { - this._renderer.updateThumbAndFillPosition(this._percent, this._sliderDimensions.width); + let renderedPercent = this.clamp(this._percent); + this._renderer.updateThumbAndFillPosition(renderedPercent, this._sliderDimensions.width); } }