diff --git a/src/demo-app/demo-app/demo-app.scss b/src/demo-app/demo-app/demo-app.scss index 62d5833daecc..a4f3b443a8ca 100644 --- a/src/demo-app/demo-app/demo-app.scss +++ b/src/demo-app/demo-app/demo-app.scss @@ -21,6 +21,7 @@ body { .demo-content { padding: 32px; + box-sizing: border-box; } md-toolbar { diff --git a/src/demo-app/slider/slider-demo.html b/src/demo-app/slider/slider-demo.html index 160231e67072..ed85b1700d1f 100644 --- a/src/demo-app/slider/slider-demo.html +++ b/src/demo-app/slider/slider-demo.html @@ -9,8 +9,8 @@

Slider with Min and Max

Disabled Slider

- -{{slider3.value}} + +

Slider with set value

diff --git a/src/demo-app/slider/slider-demo.ts b/src/demo-app/slider/slider-demo.ts index adf66ca9e442..780c6a61b0c2 100644 --- a/src/demo-app/slider/slider-demo.ts +++ b/src/demo-app/slider/slider-demo.ts @@ -11,4 +11,5 @@ export class SliderDemo { val: number = 50; min: number = 0; max: number = 100; + disabledValue = 0; } diff --git a/src/lib/slider/_slider-theme.scss b/src/lib/slider/_slider-theme.scss index d4a196c3daf2..b477b3bd47cc 100644 --- a/src/lib/slider/_slider-theme.scss +++ b/src/lib/slider/_slider-theme.scss @@ -10,7 +10,7 @@ $md-slider-focused-color: rgba(black, 0.38); $md-slider-disabled-color: rgba(black, 0.26); - .md-slider-track { + .md-slider-track-background { background-color: $md-slider-off-color; } @@ -29,4 +29,11 @@ .md-slider-thumb-label-text { color: md-color($accent, default-contrast); } + + .md-slider-disabled { + .md-slider-track-fill, + .md-slider-thumb { + background-color: $md-slider-off-color; + } + } } diff --git a/src/lib/slider/slider.html b/src/lib/slider/slider.html index 2d0f628a4d8a..a50837a8e39c 100644 --- a/src/lib/slider/slider.html +++ b/src/lib/slider/slider.html @@ -1,5 +1,8 @@ -
-
+
+
+
+
+
diff --git a/src/lib/slider/slider.scss b/src/lib/slider/slider.scss index 2e82aa5817ca..6f25f6d099f7 100644 --- a/src/lib/slider/slider.scss +++ b/src/lib/slider/slider.scss @@ -12,6 +12,7 @@ $md-slider-thumb-size: 20px !default; $md-slider-thumb-default-scale: 0.7 !default; $md-slider-thumb-focus-scale: 1 !default; +$md-slider-thumb-disabled-scale: 0.5 !default; $md-slider-thumb-arrow-gap: 12px !default; @@ -30,16 +31,29 @@ md-slider { vertical-align: middle; } -.md-slider-track { +.md-slider-wrapper { position: absolute; } +.md-slider-track-wrapper { + position: absolute; + top: 0; + left: 0; + overflow: hidden; +} + .md-slider-track-fill { position: absolute; transform-origin: 0 0; transition: transform $swift-ease-out-duration $swift-ease-out-timing-function; } +.md-slider-track-background { + position: absolute; + transform-origin: 100% 100%; + transition: transform $swift-ease-out-duration $swift-ease-out-timing-function; +} + .md-slider-ticks-container { position: absolute; left: 0; @@ -93,6 +107,7 @@ md-slider { // Slider sliding state. .md-slider-sliding { .md-slider-track-fill, + .md-slider-track-background, .md-slider-thumb-container { // Must use `transition-duration: 0ms` to disable animation rather than `transition: none`. // On Mobile Safari `transition: none` causes the slider thumb to appear stuck. @@ -103,7 +118,7 @@ md-slider { // Slider with ticks. .md-slider-has-ticks { - .md-slider-track::after { + .md-slider-wrapper::after { content: ''; position: absolute; border: 0 solid $md-slider-tick-color; @@ -113,7 +128,7 @@ md-slider { &.md-slider-active, &:hover { - .md-slider-track::after { + .md-slider-wrapper::after { opacity: 1; } @@ -137,6 +152,10 @@ md-slider { .md-slider-track-fill { transform-origin: 100% 100%; } + + .md-slider-track-background { + transform-origin: 0 0; + } } @@ -160,22 +179,40 @@ md-slider { } +// Disabled slider. +.md-slider-disabled { + .md-slider-thumb { + transform: scale($md-slider-thumb-disabled-scale); + } + + .md-slider-thumb-label { + display: none; + } +} + + // Horizontal slider. .md-slider-horizontal { height: $md-slider-thickness; min-width: $md-slider-min-size; - .md-slider-track { + .md-slider-wrapper { height: $md-slider-track-thickness; top: ($md-slider-thickness - $md-slider-track-thickness) / 2; left: $md-slider-padding; right: $md-slider-padding; } - .md-slider-track::after { + .md-slider-wrapper::after { height: $md-slider-track-thickness; border-left-width: $md-slider-tick-size; right: 0; + top: 0; + } + + .md-slider-track-wrapper { + height: $md-slider-track-thickness; + width: 100%; } .md-slider-track-fill { @@ -184,6 +221,12 @@ md-slider { transform: scaleX(0); } + .md-slider-track-background { + height: $md-slider-track-thickness; + width: 100%; + transform: scaleX(1); + } + .md-slider-ticks-container { height: $md-slider-track-thickness; width: 100%; @@ -230,17 +273,23 @@ md-slider { width: $md-slider-thickness; min-height: $md-slider-min-size; - .md-slider-track { + .md-slider-wrapper { width: $md-slider-track-thickness; top: $md-slider-padding; bottom: $md-slider-padding; left: ($md-slider-thickness - $md-slider-track-thickness) / 2; } - .md-slider-track::after { + .md-slider-wrapper::after { width: $md-slider-track-thickness; border-top-width: $md-slider-tick-size; bottom: 0; + left: 0; + } + + .md-slider-track-wrapper { + height: 100%; + width: $md-slider-track-thickness; } .md-slider-track-fill { @@ -249,6 +298,12 @@ md-slider { transform: scaleY(0); } + .md-slider-track-background { + height: 100%; + width: $md-slider-track-thickness; + transform: scaleY(1); + } + .md-slider-ticks-container { width: $md-slider-track-thickness; height: 100%; @@ -288,7 +343,7 @@ md-slider { // Slider in RTL languages. [dir='rtl'] { - .md-slider-track::after { + .md-slider-wrapper::after { left: 0; right: auto; } @@ -298,10 +353,18 @@ md-slider { transform-origin: 100% 100%; } + .md-slider-track-background { + transform-origin: 0 0; + } + &.md-slider-axis-inverted { .md-slider-track-fill { transform-origin: 0 0; } + + .md-slider-track-background { + transform-origin: 100% 100%; + } } } } diff --git a/src/lib/slider/slider.spec.ts b/src/lib/slider/slider.spec.ts index 85ae1c2e5efe..eb9b52cbc1c7 100644 --- a/src/lib/slider/slider.spec.ts +++ b/src/lib/slider/slider.spec.ts @@ -57,7 +57,7 @@ describe('MdSlider', () => { let sliderNativeElement: HTMLElement; let sliderInstance: MdSlider; let trackFillElement: HTMLElement; - let sliderTrackElement: HTMLElement; + let sliderWrapperElement: HTMLElement; beforeEach(() => { fixture = TestBed.createComponent(StandardSlider); @@ -68,7 +68,7 @@ describe('MdSlider', () => { sliderInstance = sliderDebugElement.componentInstance; trackFillElement = sliderNativeElement.querySelector('.md-slider-track-fill'); - sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderWrapperElement = sliderNativeElement.querySelector('.md-slider-wrapper'); }); it('should set the default values', () => { @@ -110,21 +110,21 @@ describe('MdSlider', () => { }); it('should update the track fill on click', () => { - expect(trackFillElement.style.transform).toBe('scaleX(0)'); + expect(trackFillElement.style.transform).toContain('scaleX(0)'); dispatchClickEventSequence(sliderNativeElement, 0.39); fixture.detectChanges(); - expect(trackFillElement.style.transform).toBe('scaleX(0.39)'); + expect(trackFillElement.style.transform).toContain('scaleX(0.39)'); }); it('should update the track fill on slide', () => { - expect(trackFillElement.style.transform).toBe('scaleX(0)'); + expect(trackFillElement.style.transform).toContain('scaleX(0)'); dispatchSlideEventSequence(sliderNativeElement, 0, 0.86, gestureConfig); fixture.detectChanges(); - expect(trackFillElement.style.transform).toBe('scaleX(0.86)'); + expect(trackFillElement.style.transform).toContain('scaleX(0.86)'); }); it('should add the md-slider-active class on click', () => { @@ -168,8 +168,9 @@ describe('MdSlider', () => { let fixture: ComponentFixture; let sliderDebugElement: DebugElement; let sliderNativeElement: HTMLElement; - let sliderTrackElement: HTMLElement; + let sliderWrapperElement: HTMLElement; let sliderInstance: MdSlider; + let trackFillElement: HTMLElement; beforeEach(() => { fixture = TestBed.createComponent(DisabledSlider); @@ -177,8 +178,9 @@ describe('MdSlider', () => { sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); sliderNativeElement = sliderDebugElement.nativeElement; - sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderWrapperElement = sliderNativeElement.querySelector('.md-slider-wrapper'); sliderInstance = sliderDebugElement.componentInstance; + trackFillElement = sliderNativeElement.querySelector('.md-slider-track-fill'); }); it('should be disabled', () => { @@ -218,6 +220,10 @@ describe('MdSlider', () => { expect(sliderNativeElement.classList).not.toContain('md-slider-sliding'); }); + + it ('should leave thumb gap', () => { + expect(trackFillElement.style.transform).toContain('translateX(-7px)'); + }); }); describe('slider with set min and max', () => { @@ -225,7 +231,7 @@ describe('MdSlider', () => { let sliderDebugElement: DebugElement; let sliderNativeElement: HTMLElement; let sliderInstance: MdSlider; - let sliderTrackElement: HTMLElement; + let sliderWrapperElement: HTMLElement; let trackFillElement: HTMLElement; let ticksContainerElement: HTMLElement; let ticksElement: HTMLElement; @@ -239,7 +245,7 @@ describe('MdSlider', () => { testComponent = fixture.debugElement.componentInstance; sliderNativeElement = sliderDebugElement.nativeElement; sliderInstance = sliderDebugElement.injector.get(MdSlider); - sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderWrapperElement = sliderNativeElement.querySelector('.md-slider-wrapper'); trackFillElement = sliderNativeElement.querySelector('.md-slider-track-fill'); ticksContainerElement = sliderNativeElement.querySelector('.md-slider-ticks-container'); @@ -277,7 +283,7 @@ describe('MdSlider', () => { fixture.detectChanges(); // The closest snap is halfway on the slider. - expect(trackFillElement.style.transform).toBe('scaleX(0.5)'); + expect(trackFillElement.style.transform).toContain('scaleX(0.5)'); }); it('should snap the fill to the nearest value on slide', () => { @@ -285,7 +291,7 @@ describe('MdSlider', () => { fixture.detectChanges(); // The closest snap is at the halfway point on the slider. - expect(trackFillElement.style.transform).toBe('scaleX(0.5)'); + expect(trackFillElement.style.transform).toContain('scaleX(0.5)'); }); it('should adjust fill and ticks on mouse enter when min changes', () => { @@ -295,7 +301,7 @@ describe('MdSlider', () => { dispatchMouseenterEvent(sliderNativeElement); fixture.detectChanges(); - expect(trackFillElement.style.transform).toBe('scaleX(0.75)'); + expect(trackFillElement.style.transform).toContain('scaleX(0.75)'); expect(ticksElement.style.backgroundSize).toBe('75% 2px'); // Make sure it cuts off the last half tick interval. expect(ticksElement.style.transform).toContain('translateX(37.5%)'); @@ -312,7 +318,7 @@ describe('MdSlider', () => { dispatchMouseenterEvent(sliderNativeElement); fixture.detectChanges(); - expect(trackFillElement.style.transform).toBe('scaleX(0.5)'); + expect(trackFillElement.style.transform).toContain('scaleX(0.5)'); expect(ticksElement.style.backgroundSize).toBe('50% 2px'); // Make sure it cuts off the last half tick interval. expect(ticksElement.style.transform).toContain('translateX(25%)'); @@ -325,7 +331,7 @@ describe('MdSlider', () => { let sliderDebugElement: DebugElement; let sliderNativeElement: HTMLElement; let sliderInstance: MdSlider; - let sliderTrackElement: HTMLElement; + let sliderWrapperElement: HTMLElement; beforeEach(() => { fixture = TestBed.createComponent(SliderWithValue); @@ -334,7 +340,7 @@ describe('MdSlider', () => { sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); sliderNativeElement = sliderDebugElement.nativeElement; sliderInstance = sliderDebugElement.injector.get(MdSlider); - sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderWrapperElement = sliderNativeElement.querySelector('.md-slider-wrapper'); }); it('should set the default value from the attribute', () => { @@ -363,7 +369,7 @@ describe('MdSlider', () => { let sliderDebugElement: DebugElement; let sliderNativeElement: HTMLElement; let sliderInstance: MdSlider; - let sliderTrackElement: HTMLElement; + let sliderWrapperElement: HTMLElement; let trackFillElement: HTMLElement; beforeEach(() => { @@ -373,7 +379,7 @@ describe('MdSlider', () => { sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); sliderNativeElement = sliderDebugElement.nativeElement; sliderInstance = sliderDebugElement.injector.get(MdSlider); - sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderWrapperElement = sliderNativeElement.querySelector('.md-slider-wrapper'); trackFillElement = sliderNativeElement.querySelector('.md-slider-track-fill'); }); @@ -391,7 +397,7 @@ describe('MdSlider', () => { fixture.detectChanges(); // The closest step is at 75% of the slider. - expect(trackFillElement.style.transform).toBe('scaleX(0.75)'); + expect(trackFillElement.style.transform).toContain('scaleX(0.75)'); }); it('should set the correct step value on slide', () => { @@ -406,7 +412,7 @@ describe('MdSlider', () => { fixture.detectChanges(); // The closest snap is at the end of the slider. - expect(trackFillElement.style.transform).toBe('scaleX(1)'); + expect(trackFillElement.style.transform).toContain('scaleX(1)'); }); }); @@ -476,7 +482,7 @@ describe('MdSlider', () => { let sliderDebugElement: DebugElement; let sliderNativeElement: HTMLElement; let sliderInstance: MdSlider; - let sliderTrackElement: HTMLElement; + let sliderWrapperElement: HTMLElement; let thumbLabelTextElement: Element; beforeEach(() => { @@ -486,7 +492,7 @@ describe('MdSlider', () => { sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); sliderNativeElement = sliderDebugElement.nativeElement; sliderInstance = sliderDebugElement.componentInstance; - sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderWrapperElement = sliderNativeElement.querySelector('.md-slider-wrapper'); thumbLabelTextElement = sliderNativeElement.querySelector('.md-slider-thumb-label-text'); }); @@ -543,7 +549,7 @@ describe('MdSlider', () => { let sliderDebugElement: DebugElement; let sliderNativeElement: HTMLElement; let sliderInstance: MdSlider; - let sliderTrackElement: HTMLElement; + let sliderWrapperElement: HTMLElement; let testComponent: SliderWithTwoWayBinding; beforeEach(() => { @@ -555,7 +561,7 @@ describe('MdSlider', () => { sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); sliderNativeElement = sliderDebugElement.nativeElement; sliderInstance = sliderDebugElement.injector.get(MdSlider); - sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderWrapperElement = sliderNativeElement.querySelector('.md-slider-wrapper'); }); it('should not update the control when the value is updated', () => { @@ -646,7 +652,7 @@ describe('MdSlider', () => { let sliderDebugElement: DebugElement; let sliderNativeElement: HTMLElement; let sliderInstance: MdSlider; - let sliderTrackElement: HTMLElement; + let sliderWrapperElement: HTMLElement; let testComponent: SliderWithOneWayBinding; let trackFillElement: HTMLElement; @@ -659,13 +665,13 @@ describe('MdSlider', () => { sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); sliderNativeElement = sliderDebugElement.nativeElement; sliderInstance = sliderDebugElement.injector.get(MdSlider); - sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderWrapperElement = sliderNativeElement.querySelector('.md-slider-wrapper'); trackFillElement = sliderNativeElement.querySelector('.md-slider-track-fill'); }); it('should initialize based on bound value', () => { expect(sliderInstance.value).toBe(50); - expect(trackFillElement.style.transform).toBe('scaleX(0.5)'); + expect(trackFillElement.style.transform).toContain('scaleX(0.5)'); }); it('should update when bound value changes', () => { @@ -673,7 +679,7 @@ describe('MdSlider', () => { fixture.detectChanges(); expect(sliderInstance.value).toBe(75); - expect(trackFillElement.style.transform).toBe('scaleX(0.75)'); + expect(trackFillElement.style.transform).toContain('scaleX(0.75)'); }); }); @@ -682,7 +688,7 @@ describe('MdSlider', () => { let sliderDebugElement: DebugElement; let sliderNativeElement: HTMLElement; let sliderInstance: MdSlider; - let sliderTrackElement: HTMLElement; + let sliderWrapperElement: HTMLElement; let trackFillElement: HTMLElement; beforeEach(() => { @@ -692,7 +698,7 @@ describe('MdSlider', () => { sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); sliderNativeElement = sliderDebugElement.nativeElement; sliderInstance = sliderDebugElement.componentInstance; - sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderWrapperElement = sliderNativeElement.querySelector('.md-slider-wrapper'); trackFillElement = sliderNativeElement.querySelector('.md-slider-track-fill'); }); @@ -703,7 +709,7 @@ describe('MdSlider', () => { }); it('should set the fill to the min value', () => { - expect(trackFillElement.style.transform).toBe('scaleX(0)'); + expect(trackFillElement.style.transform).toContain('scaleX(0)'); }); }); @@ -712,7 +718,7 @@ describe('MdSlider', () => { let sliderDebugElement: DebugElement; let sliderNativeElement: HTMLElement; let sliderInstance: MdSlider; - let sliderTrackElement: HTMLElement; + let sliderWrapperElement: HTMLElement; let trackFillElement: HTMLElement; beforeEach(() => { @@ -722,7 +728,7 @@ describe('MdSlider', () => { sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); sliderNativeElement = sliderDebugElement.nativeElement; sliderInstance = sliderDebugElement.componentInstance; - sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderWrapperElement = sliderNativeElement.querySelector('.md-slider-wrapper'); trackFillElement = sliderNativeElement.querySelector('.md-slider-track-fill'); }); @@ -733,7 +739,7 @@ describe('MdSlider', () => { }); it('should set the fill to the max value', () => { - expect(trackFillElement.style.transform).toBe('scaleX(1)'); + expect(trackFillElement.style.transform).toContain('scaleX(1)'); }); }); @@ -741,7 +747,7 @@ describe('MdSlider', () => { let fixture: ComponentFixture; let sliderDebugElement: DebugElement; let sliderNativeElement: HTMLElement; - let sliderTrackElement: HTMLElement; + let sliderWrapperElement: HTMLElement; let testComponent: SliderWithChangeHandler; beforeEach(() => { @@ -753,7 +759,7 @@ describe('MdSlider', () => { sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); sliderNativeElement = sliderDebugElement.nativeElement; - sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderWrapperElement = sliderNativeElement.querySelector('.md-slider-wrapper'); }); it('should emit change on click', () => { @@ -789,7 +795,7 @@ describe('MdSlider', () => { let fixture: ComponentFixture; let sliderDebugElement: DebugElement; let sliderNativeElement: HTMLElement; - let sliderTrackElement: HTMLElement; + let sliderWrapperElement: HTMLElement; let testComponent: SliderWithChangeHandler; beforeEach(() => { @@ -802,7 +808,7 @@ describe('MdSlider', () => { sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); sliderNativeElement = sliderDebugElement.nativeElement; - sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderWrapperElement = sliderNativeElement.querySelector('.md-slider-wrapper'); }); it('should emit an input event while sliding', () => { @@ -838,7 +844,7 @@ describe('MdSlider', () => { let fixture: ComponentFixture; let sliderDebugElement: DebugElement; let sliderNativeElement: HTMLElement; - let sliderTrackElement: HTMLElement; + let sliderWrapperElement: HTMLElement; let testComponent: StandardSlider; let sliderInstance: MdSlider; @@ -849,7 +855,7 @@ describe('MdSlider', () => { testComponent = fixture.debugElement.componentInstance; sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); sliderNativeElement = sliderDebugElement.nativeElement; - sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderWrapperElement = sliderNativeElement.querySelector('.md-slider-wrapper'); sliderInstance = sliderDebugElement.injector.get(MdSlider); }); @@ -922,7 +928,7 @@ describe('MdSlider', () => { let fixture: ComponentFixture; let sliderDebugElement: DebugElement; let sliderNativeElement: HTMLElement; - let sliderTrackElement: HTMLElement; + let sliderWrapperElement: HTMLElement; let sliderInstance: MdSlider; let testComponent: SliderWithDirAndInvert; @@ -934,7 +940,7 @@ describe('MdSlider', () => { sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); sliderInstance = sliderDebugElement.injector.get(MdSlider); sliderNativeElement = sliderDebugElement.nativeElement; - sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderWrapperElement = sliderNativeElement.querySelector('.md-slider-wrapper'); }); it('works in inverted mode', () => { @@ -1038,7 +1044,7 @@ describe('MdSlider', () => { let fixture: ComponentFixture; let sliderDebugElement: DebugElement; let sliderNativeElement: HTMLElement; - let sliderTrackElement: HTMLElement; + let sliderWrapperElement: HTMLElement; let trackFillElement: HTMLElement; let sliderInstance: MdSlider; let testComponent: VerticalSlider; @@ -1051,7 +1057,7 @@ describe('MdSlider', () => { sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider)); sliderInstance = sliderDebugElement.injector.get(MdSlider); sliderNativeElement = sliderDebugElement.nativeElement; - sliderTrackElement = sliderNativeElement.querySelector('.md-slider-track'); + sliderWrapperElement = sliderNativeElement.querySelector('.md-slider-wrapper'); trackFillElement = sliderNativeElement.querySelector('.md-slider-track-fill'); }); @@ -1073,24 +1079,24 @@ describe('MdSlider', () => { }); it('should update the track fill on click', () => { - expect(trackFillElement.style.transform).toBe('scaleY(0)'); + expect(trackFillElement.style.transform).toContain('scaleY(0)'); dispatchClickEventSequence(sliderNativeElement, 0.39); fixture.detectChanges(); - expect(trackFillElement.style.transform).toBe('scaleY(0.61)'); + expect(trackFillElement.style.transform).toContain('scaleY(0.61)'); }); it('should update the track fill on click in inverted mode', () => { testComponent.invert = true; fixture.detectChanges(); - expect(trackFillElement.style.transform).toBe('scaleY(0)'); + expect(trackFillElement.style.transform).toContain('scaleY(0)'); dispatchClickEventSequence(sliderNativeElement, 0.39); fixture.detectChanges(); - expect(trackFillElement.style.transform).toBe('scaleY(0.39)'); + expect(trackFillElement.style.transform).toContain('scaleY(0.39)'); }); }); }); @@ -1216,7 +1222,7 @@ class VerticalSlider { * physical location of the click. */ function dispatchClickEventSequence(sliderElement: HTMLElement, percentage: number): void { - let trackElement = sliderElement.querySelector('.md-slider-track'); + let trackElement = sliderElement.querySelector('.md-slider-wrapper'); let dimensions = trackElement.getBoundingClientRect(); let x = dimensions.left + (dimensions.width * percentage); let y = dimensions.top + (dimensions.height * percentage); @@ -1253,7 +1259,7 @@ function dispatchSlideEventSequence(sliderElement: HTMLElement, startPercent: nu */ function dispatchSlideEvent(sliderElement: HTMLElement, percent: number, gestureConfig: TestGestureConfig): void { - let trackElement = sliderElement.querySelector('.md-slider-track'); + let trackElement = sliderElement.querySelector('.md-slider-wrapper'); let dimensions = trackElement.getBoundingClientRect(); let x = dimensions.left + (dimensions.width * percent); let y = dimensions.top + (dimensions.height * percent); @@ -1272,7 +1278,7 @@ function dispatchSlideEvent(sliderElement: HTMLElement, percent: number, */ function dispatchSlideStartEvent(sliderElement: HTMLElement, percent: number, gestureConfig: TestGestureConfig): void { - let trackElement = sliderElement.querySelector('.md-slider-track'); + let trackElement = sliderElement.querySelector('.md-slider-wrapper'); let dimensions = trackElement.getBoundingClientRect(); let x = dimensions.left + (dimensions.width * percent); let y = dimensions.top + (dimensions.height * percent); @@ -1293,7 +1299,7 @@ function dispatchSlideStartEvent(sliderElement: HTMLElement, percent: number, */ function dispatchSlideEndEvent(sliderElement: HTMLElement, percent: number, gestureConfig: TestGestureConfig): void { - let trackElement = sliderElement.querySelector('.md-slider-track'); + let trackElement = sliderElement.querySelector('.md-slider-wrapper'); let dimensions = trackElement.getBoundingClientRect(); let x = dimensions.left + (dimensions.width * percent); let y = dimensions.top + (dimensions.height * percent); diff --git a/src/lib/slider/slider.ts b/src/lib/slider/slider.ts index 420c21cd4dc0..b0734d48e01a 100644 --- a/src/lib/slider/slider.ts +++ b/src/lib/slider/slider.ts @@ -38,6 +38,9 @@ import { */ const MIN_AUTO_TICK_SEPARATION = 30; +/** The thumb gap size for a disabled slider. */ +const DISABLED_THUMB_GAP = 7; + /** * Provider Expression that allows md-slider to register as a ControlValueAccessor. * This allows it to support [(ngModel)] and [formControl]. @@ -84,6 +87,7 @@ export class MdSliderChange { '[class.md-slider-sliding]': '_isSliding', '[class.md-slider-thumb-label-showing]': 'thumbLabel', '[class.md-slider-vertical]': 'vertical', + '[class.md-slider-min-value]': 'value === min', }, templateUrl: 'slider.html', styleUrls: ['slider.css'], @@ -245,11 +249,29 @@ export class MdSlider implements ControlValueAccessor { return (this.direction == 'rtl' && !this.vertical) ? !this.invertAxis : this.invertAxis; } + /** + * The amount of space to leave between the slider thumb and the track fill & track background + * elements. + */ + private get _thumbGap() { + return this.disabled ? DISABLED_THUMB_GAP : 0; + } + + /** CSS styles for the track background element. */ + get trackBackgroundStyles(): { [key: string]: string } { + let axis = this.vertical ? 'Y' : 'X'; + let sign = this.invertMouseCoords ? '-' : ''; + return { + 'transform': `translate${axis}(${sign}${this._thumbGap}px) scale${axis}(${1 - this.percent})` + }; + } + /** CSS styles for the track fill element. */ get trackFillStyles(): { [key: string]: string } { let axis = this.vertical ? 'Y' : 'X'; + let sign = this.invertMouseCoords ? '' : '-'; return { - 'transform': `scale${axis}(${this.percent})` + 'transform': `translate${axis}(${sign}${this._thumbGap}px) scale${axis}(${this.percent})` }; } @@ -561,8 +583,8 @@ export class SliderRenderer { * take up. */ getSliderDimensions() { - let trackElement = this._sliderElement.querySelector('.md-slider-track'); - return trackElement.getBoundingClientRect(); + let wrapperElement = this._sliderElement.querySelector('.md-slider-wrapper'); + return wrapperElement.getBoundingClientRect(); } /**