Skip to content

Commit 7b5264d

Browse files
committed
fix(slider): refactor the slider to use percent values for the track fill and thumb position.
1 parent 80491a9 commit 7b5264d

File tree

6 files changed

+471
-657
lines changed

6 files changed

+471
-657
lines changed

src/demo-app/slider/slider-demo.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,12 @@ <h1>Slider with one-way binding</h1>
3333
<h1>Slider with two-way binding</h1>
3434
<md-slider [(ngModel)]="demo" step="40"></md-slider>
3535
<input [(ngModel)]="demo">
36+
37+
<md-tab-group>
38+
<md-tab>
39+
<template md-tab-label>One</template>
40+
<template md-tab-content>
41+
<md-slider min="1" max="5" value="3"></md-slider>
42+
</template>
43+
</md-tab>
44+
</md-tab-group>

src/lib/slider/_slider-theme.scss

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@
1818
background-color: md-color($accent);
1919
}
2020

21-
.md-slider-thumb::after {
21+
.md-slider-thumb {
2222
background-color: md-color($accent);
23-
border-color: md-color($accent);
2423
}
2524

2625
.md-slider-thumb-label {

src/lib/slider/slider.html

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
1-
<div class="md-slider-wrapper">
2-
<div class="md-slider-container"
3-
[class.md-slider-sliding]="isSliding"
4-
[class.md-slider-active]="isActive"
5-
[class.md-slider-thumb-label-showing]="thumbLabel">
6-
<div class="md-slider-track-container">
7-
<div class="md-slider-track"></div>
8-
<div class="md-slider-track md-slider-track-fill"></div>
9-
<div class="md-slider-tick-container"></div>
10-
<div class="md-slider-last-tick-container"></div>
11-
</div>
12-
<div class="md-slider-thumb-container">
13-
<div class="md-slider-thumb-position">
14-
<div class="md-slider-thumb"></div>
15-
<div class="md-slider-thumb-label">
16-
<span class="md-slider-thumb-label-text">{{value}}</span>
17-
</div>
18-
</div>
1+
<div class="md-slider-track">
2+
<div class="md-slider-track-fill" [style.flexBasis]="percent * 100 + '%'"></div>
3+
<div class="md-slider-ticks-container" [style.marginLeft]="-tickIntervalPercent / 2 * 100 + '%'">
4+
<div class="md-slider-ticks" [style.marginLeft]="tickIntervalPercent / 2 * 100 + '%'"
5+
[style.backgroundSize]="tickIntervalPercent * 100 + '% 2px'"></div>
6+
</div>
7+
<div class="md-slider-thumb-container">
8+
<div class="md-slider-thumb"></div>
9+
<div class="md-slider-thumb-label">
10+
<span class="md-slider-thumb-label-text">{{value}}</span>
1911
</div>
2012
</div>
21-
</div>
13+
</div>

src/lib/slider/slider.scss

Lines changed: 69 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -7,148 +7,129 @@ $md-slider-thickness: 48px !default;
77
$md-slider-min-size: 128px !default;
88
$md-slider-padding: 8px !default;
99

10-
$md-slider-track-height: 2px !default;
10+
$md-slider-track-thickness: 2px !default;
1111
$md-slider-thumb-size: 20px !default;
1212

1313
$md-slider-thumb-default-scale: 0.7 !default;
1414
$md-slider-thumb-focus-scale: 1 !default;
1515

16-
$md-slider-thumb-arrow-height: 16px !default;
17-
$md-slider-thumb-arrow-width: 28px !default;
16+
$md-slider-thumb-arrow-gap: 12px !default;
1817

1918
$md-slider-thumb-label-size: 28px !default;
20-
// The thumb has to be moved down so that it appears right over the slider track when visible and
21-
// on the slider track when not.
22-
$md-slider-thumb-label-top: ($md-slider-thickness / 2) -
23-
($md-slider-thumb-default-scale * $md-slider-thumb-size / 2) - $md-slider-thumb-label-size -
24-
$md-slider-thumb-arrow-height + 10px !default;
2519

26-
// Uses a container height and an item height to center an item vertically within the container.
27-
@function center-vertically($containerHeight, $itemHeight) {
28-
@return ($containerHeight / 2) - ($itemHeight / 2);
29-
}
20+
$md-slider-tick-color: rgba(0, 0, 0, .6) !default;
21+
$md-slider-tick-size: 2px !default;
3022

31-
// Positions the thumb based on its width and height.
32-
@mixin slider-thumb-position($width: $md-slider-thumb-size, $height: $md-slider-thumb-size) {
33-
position: absolute;
34-
top: center-vertically($md-slider-thickness, $height);
35-
// This makes it so that the center of the thumb aligns with where the click was.
36-
// This is not affected by the movement of the thumb.
37-
left: (-$width / 2);
38-
width: $width;
39-
height: $height;
40-
border-radius: max($width, $height);
41-
}
4223

4324
md-slider {
25+
display: inline-block;
26+
box-sizing: border-box;
27+
position: relative;
4428
height: $md-slider-thickness;
4529
min-width: $md-slider-min-size;
46-
position: relative;
47-
padding: 0;
48-
display: inline-block;
30+
padding: $md-slider-padding;
4931
outline: none;
5032
vertical-align: middle;
5133
}
5234

53-
md-slider *,
54-
md-slider *::after {
55-
box-sizing: border-box;
35+
.md-slider-track {
36+
display: flex;
37+
flex-grow: 1;
38+
align-items: center;
39+
position: relative;
40+
top: ($md-slider-thickness - $md-slider-track-thickness) / 2 - $md-slider-padding;
41+
height: $md-slider-track-thickness;
42+
transition: box-shadow $swift-ease-out-duration $swift-ease-out-timing-function;
5643
}
5744

58-
// Exists in order to pad the slider and keep everything positioned correctly.
59-
// Cannot be merged with the .md-slider-container.
60-
.md-slider-wrapper {
61-
width: 100%;
62-
height: 100%;
63-
padding-left: $md-slider-padding;
64-
padding-right: $md-slider-padding;
45+
.md-slider-has-ticks.md-slider-active .md-slider-track,
46+
.md-slider-has-ticks:hover .md-slider-track {
47+
box-shadow: inset (-2 * $md-slider-tick-size) 0 0 (-$md-slider-tick-size) $md-slider-tick-color;
6548
}
6649

67-
68-
// Holds the isActive and isSliding classes as well as helps with positioning the children.
69-
// Cannot be merged with .md-slider-wrapper.
70-
.md-slider-container {
71-
position: relative;
50+
.md-slider-track-fill {
51+
flex: 0 0 50%;
52+
height: $md-slider-track-thickness;
53+
transition: flex-basis $swift-ease-out-duration $swift-ease-out-timing-function;
7254
}
7355

74-
.md-slider-track-container {
75-
width: 100%;
76-
position: absolute;
77-
top: center-vertically($md-slider-thickness, $md-slider-track-height);
78-
height: $md-slider-track-height;
56+
.md-slider-sliding .md-slider-track-fill {
57+
transition: none;
7958
}
8059

81-
.md-slider-track {
60+
.md-slider-ticks-container {
8261
position: absolute;
83-
left: 0;
84-
right: 0;
85-
height: 100%;
62+
height: $md-slider-track-thickness;
63+
width: 100%;
64+
overflow: hidden;
8665
}
8766

88-
.md-slider-track-fill {
89-
transition-duration: $swift-ease-out-duration;
90-
transition-timing-function: $swift-ease-out-timing-function;
91-
transition-property: width, height;
67+
.md-slider-ticks {
68+
background: repeating-linear-gradient(to right, $md-slider-tick-color,
69+
$md-slider-tick-color $md-slider-tick-size, transparent 0, transparent) repeat-x;
70+
height: $md-slider-track-thickness;
71+
width: 100%;
72+
opacity: 0;
73+
transition: opacity $swift-ease-out-duration $swift-ease-out-timing-function;
9274
}
9375

94-
.md-slider-tick-container, .md-slider-last-tick-container {
95-
position: absolute;
96-
left: 0;
97-
right: 0;
98-
height: 100%;
76+
.md-slider-has-ticks.md-slider-active .md-slider-ticks,
77+
.md-slider-has-ticks:hover .md-slider-ticks {
78+
opacity: 1;
9979
}
10080

10181
.md-slider-thumb-container {
102-
position: absolute;
103-
left: 0;
104-
top: 50%;
105-
transform: translate3d(-50%, -50%, 0);
106-
transition-duration: $swift-ease-out-duration;
107-
transition-timing-function: $swift-ease-out-timing-function;
108-
transition-property: left, bottom;
109-
}
110-
111-
.md-slider-thumb-position {
112-
transition: transform $swift-ease-out-duration $swift-ease-out-timing-function;
82+
flex: 0 0 auto;
83+
position: relative;
84+
width: 0;
85+
height: 0;
11386
}
11487

11588
.md-slider-thumb {
116-
z-index: 1;
117-
118-
@include slider-thumb-position($md-slider-thumb-size, $md-slider-thumb-size);
89+
position: absolute;
90+
left: -$md-slider-thumb-size / 2;
91+
top: -$md-slider-thumb-size / 2;
92+
width: $md-slider-thumb-size;
93+
height: $md-slider-thumb-size;
94+
border-radius: 50%;
95+
transform-origin: 50% 50%;
11996
transform: scale($md-slider-thumb-default-scale);
12097
transition: transform $swift-ease-out-duration $swift-ease-out-timing-function;
12198
}
12299

123-
.md-slider-thumb::after {
124-
content: '';
125-
position: absolute;
126-
width: $md-slider-thumb-size;
127-
height: $md-slider-thumb-size;
128-
border-radius: max($md-slider-thumb-size, $md-slider-thumb-size);
129-
// Separate border properties because, if you combine them into "border", it defaults to 'black'.
130-
border-width: 3px;
131-
border-style: solid;
132-
transition: inherit;
100+
.md-slider-active .md-slider-thumb {
101+
transform: scale($md-slider-thumb-focus-scale);
102+
}
103+
104+
.md-slider-active.md-slider-thumb-label-showing .md-slider-thumb {
105+
transform: scale(0);
133106
}
134107

135108
.md-slider-thumb-label {
136109
display: flex;
137110
align-items: center;
138111
justify-content: center;
139-
140112
position: absolute;
141-
left: -($md-slider-thumb-label-size / 2);
142-
top: $md-slider-thumb-label-top;
113+
left: -$md-slider-thumb-label-size / 2;
114+
top: -($md-slider-thumb-label-size + $md-slider-thumb-arrow-gap);
143115
width: $md-slider-thumb-label-size;
144116
height: $md-slider-thumb-label-size;
145117
border-radius: 50%;
146-
147-
transform: scale(0.4) translate3d(0, (-$md-slider-thumb-label-top + 10) / 0.4, 0) rotate(45deg);
118+
transform: translateY($md-slider-thumb-label-size / 2 + $md-slider-thumb-arrow-gap)
119+
scale(0.4) rotate(45deg);
148120
transition: 300ms $swift-ease-in-out-timing-function;
149121
transition-property: transform, border-radius;
150122
}
151123

124+
.md-slider-active .md-slider-thumb-label {
125+
border-radius: 50% 50% 0;
126+
transform: rotate(45deg);
127+
}
128+
129+
md-slider:not(.md-slider-thumb-label-showing) .md-slider-thumb-label {
130+
display: none;
131+
}
132+
152133
.md-slider-thumb-label-text {
153134
z-index: 1;
154135
font-size: 12px;
@@ -158,29 +139,6 @@ md-slider *::after {
158139
transition: opacity 300ms $swift-ease-in-out-timing-function;
159140
}
160141

161-
.md-slider-container:not(.md-slider-thumb-label-showing) .md-slider-thumb-label {
162-
display: none;
163-
}
164-
165-
.md-slider-active.md-slider-thumb-label-showing .md-slider-thumb {
166-
transform: scale(0);
167-
}
168-
169-
.md-slider-sliding .md-slider-thumb-position,
170-
.md-slider-sliding .md-slider-track-fill {
171-
transition: none;
172-
cursor: default;
173-
}
174-
175-
.md-slider-active .md-slider-thumb {
176-
transform: scale($md-slider-thumb-focus-scale);
177-
}
178-
179-
.md-slider-active .md-slider-thumb-label {
180-
border-radius: 50% 50% 0;
181-
transform: rotate(45deg);
182-
}
183-
184142
.md-slider-active .md-slider-thumb-label-text {
185143
opacity: 1;
186144
}

0 commit comments

Comments
 (0)