Skip to content

Commit deb940f

Browse files
mmalerbatinayuangao
authored andcommitted
feat(slider): vertical mode (#1878)
* Addressed comments. * PercentPipe was adding extra space before '%', so replaced it. * remove CommonModule from imports. * fix(slider): keyboard support. * prevent keyboard interaction with disabled slider. * fix comment * switch to event.keyCode * added tests * comment why default: return; * fix(slider): support for rtl and inverted sliders. * clean up demo html file * fixed tests and lint issues * added tests * started work * swap left/right arrow behavior in rtl * fixed lint issues * sorta working * works (except end tick is sometimes hidden). all the tests are probably broken T-T * fix tick glitches * all translate, no margin for tick placement * make sure the last tick appears on top of fill * fix tests * fixed test issues on mobile * fix mobile bug where slide doesn't work until after click * swap the meaning of normal and inverted for vertical sliders * vertical mode tests * fix vertical slider in ie11 * fixed lint issue
1 parent 4d678d4 commit deb940f

File tree

5 files changed

+428
-152
lines changed

5 files changed

+428
-152
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@ <h1>Slider with two-way binding</h1>
3535
<input [(ngModel)]="demo">
3636

3737
<h1>Inverted slider</h1>
38-
<md-slider invert value="50"></md-slider>
38+
<md-slider invert value="50" tick-interval="5"></md-slider>
39+
40+
<h1>Vertical slider</h1>
41+
<md-slider vertical thumb-label tick-interval="auto" value="50"></md-slider>
42+
43+
<h1>Inverted vertical slider</h1>
44+
<md-slider vertical invert thumb-label tick-interval="auto" value="50"></md-slider>
3945

4046
<md-tab-group>
4147
<md-tab label="One">

src/lib/slider/slider.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<div class="md-slider-ticks-container" [ngStyle]="ticksContainerStyles">
44
<div class="md-slider-ticks" [ngStyle]="ticksStyles"></div>
55
</div>
6-
<div class="md-slider-thumb-container">
6+
<div class="md-slider-thumb-container" [ngStyle]="thumbContainerStyles">
77
<div class="md-slider-thumb"></div>
88
<div class="md-slider-thumb-label">
99
<span class="md-slider-thumb-label-text">{{value}}</span>

src/lib/slider/slider.scss

Lines changed: 224 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -23,142 +23,283 @@ $md-slider-tick-size: 2px !default;
2323

2424
md-slider {
2525
display: inline-block;
26-
box-sizing: border-box;
2726
position: relative;
28-
height: $md-slider-thickness;
29-
min-width: $md-slider-min-size;
27+
box-sizing: border-box;
3028
padding: $md-slider-padding;
3129
outline: none;
3230
vertical-align: middle;
3331
}
3432

3533
.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;
43-
}
44-
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;
48-
}
49-
50-
[dir='rtl'] .md-slider-has-ticks.md-slider-active .md-slider-track,
51-
[dir='rtl'] .md-slider-has-ticks:hover .md-slider-track {
52-
box-shadow: inset (2 * $md-slider-tick-size) 0 0 (-$md-slider-tick-size) $md-slider-tick-color;
53-
}
54-
55-
.md-slider-inverted .md-slider-track {
56-
flex-direction: row-reverse;
34+
position: absolute;
5735
}
5836

5937
.md-slider-track-fill {
60-
flex: 0 0 50%;
61-
height: $md-slider-track-thickness;
62-
transition: flex-basis $swift-ease-out-duration $swift-ease-out-timing-function;
63-
}
64-
65-
.md-slider-sliding .md-slider-track-fill {
66-
transition: none;
38+
position: absolute;
39+
transform-origin: 0 0;
40+
transition: transform $swift-ease-out-duration $swift-ease-out-timing-function;
6741
}
6842

6943
.md-slider-ticks-container {
7044
position: absolute;
7145
left: 0;
7246
top: 0;
73-
height: $md-slider-track-thickness;
74-
width: 100%;
7547
overflow: hidden;
7648
}
7749

78-
[dir='rtl'] .md-slider-ticks-container {
79-
// translateZ(0) prevents chrome bug where overflow: hidden; doesn't work.
80-
transform: translateZ(0) rotate(180deg);
81-
}
82-
8350
.md-slider-ticks {
84-
background: repeating-linear-gradient(to right, $md-slider-tick-color,
85-
$md-slider-tick-color $md-slider-tick-size, transparent 0, transparent) repeat;
86-
// Firefox doesn't draw the gradient correctly with 'to right'
87-
// (see https://bugzilla.mozilla.org/show_bug.cgi?id=1314319).
88-
background: -moz-repeating-linear-gradient(0.0001deg, $md-slider-tick-color,
89-
$md-slider-tick-color $md-slider-tick-size, transparent 0, transparent) repeat;
90-
height: $md-slider-track-thickness;
91-
width: 100%;
9251
opacity: 0;
9352
transition: opacity $swift-ease-out-duration $swift-ease-out-timing-function;
9453
}
9554

96-
.md-slider-has-ticks.md-slider-active .md-slider-ticks,
97-
.md-slider-has-ticks:hover .md-slider-ticks {
98-
opacity: 1;
99-
}
100-
10155
.md-slider-thumb-container {
102-
flex: 0 0 auto;
103-
position: relative;
104-
width: 0;
105-
height: 0;
56+
position: absolute;
57+
z-index: 1;
58+
transition: transform $swift-ease-out-duration $swift-ease-out-timing-function;
10659
}
10760

10861
.md-slider-thumb {
10962
position: absolute;
110-
left: -$md-slider-thumb-size / 2;
111-
top: -$md-slider-thumb-size / 2;
63+
right: -$md-slider-thumb-size / 2;
64+
bottom: -$md-slider-thumb-size / 2;
11265
width: $md-slider-thumb-size;
11366
height: $md-slider-thumb-size;
11467
border-radius: 50%;
115-
transform-origin: 50% 50%;
11668
transform: scale($md-slider-thumb-default-scale);
11769
transition: transform $swift-ease-out-duration $swift-ease-out-timing-function;
11870
}
11971

120-
.md-slider-active .md-slider-thumb {
121-
transform: scale($md-slider-thumb-focus-scale);
122-
}
123-
124-
.md-slider-active.md-slider-thumb-label-showing .md-slider-thumb {
125-
transform: scale(0);
126-
}
127-
12872
.md-slider-thumb-label {
129-
display: flex;
73+
display: none;
13074
align-items: center;
13175
justify-content: center;
13276
position: absolute;
133-
left: -$md-slider-thumb-label-size / 2;
134-
top: -($md-slider-thumb-label-size + $md-slider-thumb-arrow-gap);
13577
width: $md-slider-thumb-label-size;
13678
height: $md-slider-thumb-label-size;
13779
border-radius: 50%;
138-
transform: translateY($md-slider-thumb-label-size / 2 + $md-slider-thumb-arrow-gap)
139-
scale(0.4) rotate(45deg);
14080
transition: 300ms $swift-ease-in-out-timing-function;
14181
transition-property: transform, border-radius;
14282
}
14383

144-
.md-slider-active .md-slider-thumb-label {
145-
border-radius: 50% 50% 0;
146-
transform: rotate(45deg);
147-
}
148-
149-
md-slider:not(.md-slider-thumb-label-showing) .md-slider-thumb-label {
150-
display: none;
151-
}
152-
15384
.md-slider-thumb-label-text {
15485
z-index: 1;
15586
font-size: 12px;
15687
font-weight: bold;
15788
opacity: 0;
158-
transform: rotate(-45deg);
15989
transition: opacity 300ms $swift-ease-in-out-timing-function;
16090
}
16191

162-
.md-slider-active .md-slider-thumb-label-text {
163-
opacity: 1;
92+
93+
// Slider sliding state.
94+
.md-slider-sliding {
95+
.md-slider-track-fill,
96+
.md-slider-thumb-container {
97+
transition: none;
98+
}
99+
}
100+
101+
102+
// Slider with ticks.
103+
.md-slider-has-ticks {
104+
.md-slider-track::after {
105+
content: '';
106+
position: absolute;
107+
border: 0 solid $md-slider-tick-color;
108+
opacity: 0;
109+
transition: opacity 300ms $swift-ease-in-out-timing-function;
110+
}
111+
112+
&.md-slider-active,
113+
&:hover {
114+
.md-slider-track::after {
115+
opacity: 1;
116+
}
117+
118+
.md-slider-ticks {
119+
opacity: 1;
120+
}
121+
}
122+
}
123+
124+
125+
// Slider with thumb label.
126+
.md-slider-thumb-label-showing {
127+
.md-slider-thumb-label {
128+
display: flex;
129+
}
130+
}
131+
132+
133+
// Inverted slider.
134+
.md-slider-axis-inverted {
135+
.md-slider-track-fill {
136+
transform-origin: 100% 100%;
137+
}
138+
}
139+
140+
141+
// Active slider.
142+
.md-slider-active {
143+
.md-slider-thumb {
144+
transform: scale($md-slider-thumb-focus-scale);
145+
}
146+
147+
&.md-slider-thumb-label-showing .md-slider-thumb {
148+
transform: scale(0);
149+
}
150+
151+
.md-slider-thumb-label {
152+
border-radius: 50% 50% 0;
153+
}
154+
155+
.md-slider-thumb-label-text {
156+
opacity: 1;
157+
}
158+
}
159+
160+
161+
// Horizontal slider.
162+
.md-slider-horizontal {
163+
height: $md-slider-thickness;
164+
min-width: $md-slider-min-size;
165+
166+
.md-slider-track {
167+
height: $md-slider-track-thickness;
168+
top: ($md-slider-thickness - $md-slider-track-thickness) / 2;
169+
left: $md-slider-padding;
170+
right: $md-slider-padding;
171+
}
172+
173+
.md-slider-track::after {
174+
height: $md-slider-track-thickness;
175+
border-left-width: $md-slider-tick-size;
176+
right: 0;
177+
}
178+
179+
.md-slider-track-fill {
180+
height: $md-slider-track-thickness;
181+
width: 100%;
182+
transform: scaleX(0);
183+
}
184+
185+
.md-slider-ticks-container {
186+
height: $md-slider-track-thickness;
187+
width: 100%;
188+
}
189+
190+
.md-slider-ticks {
191+
background: repeating-linear-gradient(to right, $md-slider-tick-color,
192+
$md-slider-tick-color $md-slider-tick-size, transparent 0, transparent) repeat;
193+
// Firefox doesn't draw the gradient correctly with 'to right'
194+
// (see https://bugzilla.mozilla.org/show_bug.cgi?id=1314319).
195+
background: -moz-repeating-linear-gradient(0.0001deg, $md-slider-tick-color,
196+
$md-slider-tick-color $md-slider-tick-size, transparent 0, transparent) repeat;
197+
height: $md-slider-track-thickness;
198+
width: 100%;
199+
}
200+
201+
.md-slider-thumb-container {
202+
width: 100%;
203+
height: 0;
204+
top: 50%;
205+
}
206+
207+
.md-slider-thumb-label {
208+
right: -$md-slider-thumb-label-size / 2;
209+
top: -($md-slider-thumb-label-size + $md-slider-thumb-arrow-gap);
210+
transform: translateY($md-slider-thumb-label-size / 2 + $md-slider-thumb-arrow-gap) scale(0.4)
211+
rotate(45deg);
212+
}
213+
214+
.md-slider-thumb-label-text {
215+
transform: rotate(-45deg);
216+
}
217+
218+
&.md-slider-active {
219+
.md-slider-thumb-label {
220+
transform: rotate(45deg);
221+
}
222+
}
223+
}
224+
225+
226+
// Vertical slider.
227+
.md-slider-vertical {
228+
width: $md-slider-thickness;
229+
min-height: $md-slider-min-size;
230+
231+
.md-slider-track {
232+
width: $md-slider-track-thickness;
233+
top: $md-slider-padding;
234+
bottom: $md-slider-padding;
235+
left: ($md-slider-thickness - $md-slider-track-thickness) / 2;
236+
}
237+
238+
.md-slider-track::after {
239+
width: $md-slider-track-thickness;
240+
border-top-width: $md-slider-tick-size;
241+
bottom: 0;
242+
}
243+
244+
.md-slider-track-fill {
245+
height: 100%;
246+
width: $md-slider-track-thickness;
247+
transform: scaleY(0);
248+
}
249+
250+
.md-slider-ticks-container {
251+
width: $md-slider-track-thickness;
252+
height: 100%;
253+
}
254+
255+
.md-slider-ticks {
256+
background: repeating-linear-gradient(to bottom, $md-slider-tick-color,
257+
$md-slider-tick-color $md-slider-tick-size, transparent 0, transparent) repeat;
258+
width: $md-slider-track-thickness;
259+
height: 100%;
260+
}
261+
262+
.md-slider-thumb-container {
263+
height: 100%;
264+
width: 0;
265+
left: 50%;
266+
}
267+
268+
.md-slider-thumb-label {
269+
bottom: -$md-slider-thumb-label-size / 2;
270+
left: -($md-slider-thumb-label-size + $md-slider-thumb-arrow-gap);
271+
transform: translateX($md-slider-thumb-label-size / 2 + $md-slider-thumb-arrow-gap)
272+
scale(0.4) rotate(-45deg);
273+
}
274+
275+
.md-slider-thumb-label-text {
276+
transform: rotate(45deg);
277+
}
278+
279+
&.md-slider-active {
280+
.md-slider-thumb-label {
281+
transform: rotate(-45deg);
282+
}
283+
}
284+
}
285+
286+
287+
// Slider in RTL languages.
288+
[dir='rtl'] {
289+
.md-slider-track::after {
290+
left: 0;
291+
right: auto;
292+
}
293+
294+
.md-slider-horizontal {
295+
.md-slider-track-fill {
296+
transform-origin: 100% 100%;
297+
}
298+
299+
&.md-slider-axis-inverted {
300+
.md-slider-track-fill {
301+
transform-origin: 0 0;
302+
}
303+
}
304+
}
164305
}

0 commit comments

Comments
 (0)