Skip to content

Commit

Permalink
fix(slider): update thumb pos & ticks when min/max change (#1598)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmalerba authored and jelbourn committed Oct 26, 2016
1 parent 8f50c35 commit ff84842
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 6 deletions.
4 changes: 3 additions & 1 deletion src/demo-app/slider/slider-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ <h1>Default Slider</h1>
{{slidey.value}}

<h1>Slider with Min and Max</h1>
<md-slider min="5" max="7" #slider2></md-slider>
<input [(ngModel)]="min">
<md-slider [min]="min" [max]="max" tick-interval="5" #slider2></md-slider>
{{slider2.value}}
<input [(ngModel)]="max">

<h1>Disabled Slider</h1>
<md-slider disabled #slider3></md-slider>
Expand Down
2 changes: 2 additions & 0 deletions src/demo-app/slider/slider-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ import {Component} from '@angular/core';
export class SliderDemo {
demo: number;
val: number = 50;
min: number = 0;
max: number = 100;
}
44 changes: 42 additions & 2 deletions src/lib/slider/slider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = <HTMLElement>sliderNativeElement.querySelector('.md-slider-track');
sliderDimensions = sliderTrackElement.getBoundingClientRect();
trackFillElement = <HTMLElement>sliderNativeElement.querySelector('.md-slider-track-fill');
thumbElement = <HTMLElement>sliderNativeElement.querySelector('.md-slider-thumb-position');
tickContainerElement =
<HTMLElement>sliderNativeElement.querySelector('.md-slider-tick-container');
});

it('should set the default values from the attributes', () => {
Expand Down Expand Up @@ -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)`);
});
});

Expand Down Expand Up @@ -767,11 +804,14 @@ class StandardSlider { }
class DisabledSlider { }

@Component({
template: `<md-slider min="4" max="6"></md-slider>`,
template: `<md-slider [min]="min" [max]="max" tick-interval="6"></md-slider>`,
styles: [noTransitionStyle],
encapsulation: ViewEncapsulation.None
})
class SliderWithMinAndMax { }
class SliderWithMinAndMax {
min = 4;
max = 6;
}

@Component({
template: `<md-slider value="26"></md-slider>`
Expand Down
19 changes: 16 additions & 3 deletions src/lib/slider/slider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ export class MdSlider implements AfterContentInit, ControlValueAccessor {
if (!this._isInitialized) {
this.value = this._min;
}
this.snapThumbToValue();
this._updateTickSeparation();
}

@Input()
Expand All @@ -136,6 +138,8 @@ export class MdSlider implements AfterContentInit, ControlValueAccessor {

set max(v: number) {
this._max = Number(v);
this.snapThumbToValue();
this._updateTickSeparation();
}

@Input()
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -429,8 +436,10 @@ export class SliderRenderer {
* Draws ticks onto the tick container.
*/
drawTicks(tickSeparation: number) {
let sliderTrackContainer =
<HTMLElement>this._sliderElement.querySelector('.md-slider-track-container');
let tickContainerWidth = sliderTrackContainer.getBoundingClientRect().width;
let tickContainer = <HTMLElement>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.
Expand All @@ -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 = '';
}
}
}
Expand Down

0 comments on commit ff84842

Please sign in to comment.