From ff8484225982be15344e1b13765db0e0d836fd17 Mon Sep 17 00:00:00 2001 From: mmalerba Date: Wed, 26 Oct 2016 15:03:59 -0700 Subject: [PATCH] fix(slider): update thumb pos & ticks when min/max change (#1598) --- src/demo-app/slider/slider-demo.html | 4 ++- src/demo-app/slider/slider-demo.ts | 2 ++ src/lib/slider/slider.spec.ts | 44 ++++++++++++++++++++++++++-- src/lib/slider/slider.ts | 19 ++++++++++-- 4 files changed, 63 insertions(+), 6 deletions(-) diff --git a/src/demo-app/slider/slider-demo.html b/src/demo-app/slider/slider-demo.html index 8496236039b5..2050cd374534 100644 --- a/src/demo-app/slider/slider-demo.html +++ b/src/demo-app/slider/slider-demo.html @@ -3,8 +3,10 @@

Default Slider

{{slidey.value}}

Slider with Min and Max

- + + {{slider2.value}} +

Disabled Slider

diff --git a/src/demo-app/slider/slider-demo.ts b/src/demo-app/slider/slider-demo.ts index 2aba4410f874..adf66ca9e442 100644 --- a/src/demo-app/slider/slider-demo.ts +++ b/src/demo-app/slider/slider-demo.ts @@ -9,4 +9,6 @@ import {Component} from '@angular/core'; export class SliderDemo { demo: number; val: number = 50; + min: number = 0; + max: number = 100; } diff --git a/src/lib/slider/slider.spec.ts b/src/lib/slider/slider.spec.ts index 736067cf2c67..4268ce0e5b0f 100644 --- a/src/lib/slider/slider.spec.ts +++ b/src/lib/slider/slider.spec.ts @@ -251,18 +251,23 @@ describe('MdSlider', () => { let sliderDimensions: ClientRect; let trackFillElement: HTMLElement; let thumbElement: HTMLElement; + let tickContainerElement: HTMLElement; + let testComponent: SliderWithMinAndMax; beforeEach(() => { fixture = TestBed.createComponent(SliderWithMinAndMax); fixture.detectChanges(); sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); + testComponent = fixture.debugElement.componentInstance; sliderNativeElement = sliderDebugElement.nativeElement; sliderInstance = sliderDebugElement.injector.get(MdSlider); sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); sliderDimensions = sliderTrackElement.getBoundingClientRect(); trackFillElement = sliderNativeElement.querySelector('.md-slider-track-fill'); thumbElement = sliderNativeElement.querySelector('.md-slider-thumb-position'); + tickContainerElement = + sliderNativeElement.querySelector('.md-slider-tick-container'); }); it('should set the default values from the attributes', () => { @@ -314,7 +319,39 @@ describe('MdSlider', () => { // The closest snap is at the halfway point on the slider. expect(thumbDimensions.left).toBe(sliderDimensions.left + sliderDimensions.width * 0.5); expect(trackFillDimensions.width).toBe(thumbPosition); + }); + + it('should adjust thumb and ticks when min changes', () => { + testComponent.min = -2; + fixture.detectChanges(); + let trackFillDimensions = trackFillElement.getBoundingClientRect(); + let tickContainerDimensions = tickContainerElement.getBoundingClientRect(); + + expect(trackFillDimensions.width).toBe(sliderDimensions.width * 6 / 8); + expect(tickContainerDimensions.width) + .toBe(sliderDimensions.width - sliderDimensions.width * 6 / 8); + expect(tickContainerElement.style.background) + .toContain(`repeating-linear-gradient(to right, black, black 2px, transparent 2px, ` + + `transparent ${sliderDimensions.width * 6 / 8 - 1}px)`); + }); + + it('should adjust thumb and ticks when max changes', () => { + testComponent.min = -2; + fixture.detectChanges(); + + testComponent.max = 10; + fixture.detectChanges(); + + let trackFillDimensions = trackFillElement.getBoundingClientRect(); + let tickContainerDimensions = tickContainerElement.getBoundingClientRect(); + + expect(trackFillDimensions.width).toBe(sliderDimensions.width * 6 / 12); + expect(tickContainerDimensions.width) + .toBe(sliderDimensions.width - sliderDimensions.width * 6 / 12); + expect(tickContainerElement.style.background) + .toContain(`repeating-linear-gradient(to right, black, black 2px, transparent 2px, ` + + `transparent ${sliderDimensions.width * 6 / 12 - 1}px)`); }); }); @@ -767,11 +804,14 @@ class StandardSlider { } class DisabledSlider { } @Component({ - template: ``, + template: ``, styles: [noTransitionStyle], encapsulation: ViewEncapsulation.None }) -class SliderWithMinAndMax { } +class SliderWithMinAndMax { + min = 4; + max = 6; +} @Component({ template: `` diff --git a/src/lib/slider/slider.ts b/src/lib/slider/slider.ts index b7d2aa22017e..a91108e605fa 100644 --- a/src/lib/slider/slider.ts +++ b/src/lib/slider/slider.ts @@ -126,6 +126,8 @@ export class MdSlider implements AfterContentInit, ControlValueAccessor { if (!this._isInitialized) { this.value = this._min; } + this.snapThumbToValue(); + this._updateTickSeparation(); } @Input() @@ -136,6 +138,8 @@ export class MdSlider implements AfterContentInit, ControlValueAccessor { set max(v: number) { this._max = Number(v); + this.snapThumbToValue(); + this._updateTickSeparation(); } @Input() @@ -277,6 +281,9 @@ export class MdSlider implements AfterContentInit, ControlValueAccessor { * is set to something other than a number or 'auto', nothing happens. */ private _updateTickSeparation() { + if (!this._sliderDimensions) { + return; + } if (this._tickInterval == 'auto') { this._updateAutoTickSeparation(); } else if (Number(this._tickInterval)) { @@ -429,8 +436,10 @@ export class SliderRenderer { * Draws ticks onto the tick container. */ drawTicks(tickSeparation: number) { + let sliderTrackContainer = + this._sliderElement.querySelector('.md-slider-track-container'); + let tickContainerWidth = sliderTrackContainer.getBoundingClientRect().width; let tickContainer = this._sliderElement.querySelector('.md-slider-tick-container'); - let tickContainerWidth = tickContainer.getBoundingClientRect().width; // An extra element for the last tick is needed because the linear gradient cannot be told to // always draw a tick at the end of the gradient. To get around this, there is a second // container for ticks that has a single tick mark on the very right edge. @@ -444,10 +453,14 @@ export class SliderRenderer { lastTickContainer.style.background = `linear-gradient(to left, black, black 2px, transparent ` + `2px, transparent)`; - // If the second to last tick is too close (a separation of less than half the normal - // separation), don't show it by decreasing the width of the tick container element. if (tickContainerWidth % tickSeparation < (tickSeparation / 2)) { + // If the second to last tick is too close (a separation of less than half the normal + // separation), don't show it by decreasing the width of the tick container element. tickContainer.style.width = tickContainerWidth - tickSeparation + 'px'; + } else { + // If there is enough space for the second-to-last tick, restore the default width of the + // tick container. + tickContainer.style.width = ''; } } }