2 Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
3 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
4 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
5 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
6 Code distributed by Google as part of the polymer project is also
7 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
11 `paper-slider` allows user to select a value from a range of values by
12 moving the slider thumb. The interactive nature of the slider makes it a
13 great choice for settings that reflect intensity levels, such as volume,
14 brightness, or color saturation.
18 <paper-slider></paper-slider>
20 Use `min` and `max` to specify the slider range. Default is 0 to 100.
24 <paper-slider min="10" max="200" value="110"></paper-slider>
28 To change the slider progress bar color:
30 paper-slider::shadow #sliderBar::shadow #activeProgress {
31 background-color: #0f9d58;
34 To change the slider knob color:
36 paper-slider::shadow #sliderKnobInner {
37 background-color: #0f9d58;
40 To change the slider pin color:
42 paper-slider::shadow #sliderKnobInner::before {
43 background-color: #0f9d58;
46 To change the slider pin's font color:
48 paper-slider::shadow #sliderKnob > #sliderKnobInner::after {
52 To change the slider secondary progress bar color:
54 paper-slider::shadow #sliderBar::shadow #secondaryProgress {
55 background-color: #0f9d58;
64 <link rel=
"import" href=
"../core-a11y-keys/core-a11y-keys.html">
65 <link rel=
"import" href=
"../paper-progress/paper-progress.html">
66 <link rel=
"import" href=
"../paper-input/paper-input.html">
68 <polymer-element name=
"paper-slider" extends=
"core-range" attributes=
"snaps pin disabled secondaryProgress editable immediateValue" role=
"slider" tabindex=
"0" aria-valuemin=
"0" aria-valuemax=
"100">
71 <link rel=
"stylesheet" href=
"paper-slider.css">
73 <template if=
"{{!disabled}}">
74 <core-a11y-keys target=
"{{}}" keys=
"left down pagedown home" on-keys-pressed=
"{{decrementKey}}"></core-a11y-keys>
75 <core-a11y-keys target=
"{{}}" keys=
"right up pageup end" on-keys-pressed=
"{{incrementKey}}"></core-a11y-keys>
78 <div id=
"sliderContainer" class=
"{{ {disabled: disabled, pin: pin, snaps: snaps, ring: immediateValue <= min, expand: expand, dragging: dragging, transiting: transiting, editable: editable} | tokenList }}">
80 <div class=
"bar-container">
81 <paper-progress id=
"sliderBar" aria-hidden=
"true" min=
"{{min}}" max=
"{{max}}" value=
"{{immediateValue}}" secondaryProgress=
"{{secondaryProgress}}"
82 on-down=
"{{bardown}}" on-up=
"{{resetKnob}}"
83 on-trackstart=
"{{trackStart}}" on-trackx=
"{{trackx}}" on-trackend=
"{{trackEnd}}"></paper-progress>
86 <template if=
"{{snaps && !disabled}}">
87 <div class=
"slider-markers" horizontal layout
>
88 <template repeat=
"{{markers}}">
89 <div flex
class=
"slider-marker"></div>
94 <div id=
"sliderKnob" on-down=
"{{knobdown}}" on-up=
"{{resetKnob}}"
95 on-trackstart=
"{{trackStart}}" on-trackx=
"{{trackx}}" on-trackend=
"{{trackEnd}}"
96 on-transitionend=
"{{knobTransitionEnd}}"
97 center-justified center horizontal layout
>
99 <div id=
"sliderKnobInner" value=
"{{immediateValue}}"></div>
105 <template if=
"{{editable}}">
106 <paper-input id=
"input" class=
"slider-input" value=
"{{immediateValue}}" disabled?=
"{{disabled}}" on-change=
"{{inputChange}}"></paper-input>
112 Polymer('paper-slider', {
115 * Fired when the slider's value changes.
121 * Fired when the slider's immediateValue changes.
123 * @event immediate-value-change
127 * Fired when the slider's value changes due to user interaction.
129 * Changes to the slider's value due to changes in an underlying
130 * bound variable will not trigger this event.
136 * If true, the slider thumb snaps to tick marks evenly spaced based
137 * on the `step` property value.
146 * If true, a pin with numeric value label is shown when the slider thumb
147 * is pressed. Use for settings for which users need to know the exact
148 * value of the setting.
157 * If true, this slider is disabled. A disabled slider cannot be tapped
158 * or dragged to change the slider value.
160 * @attribute disabled
167 * The number that represents the current secondary progress.
169 * @attribute secondaryProgress
173 secondaryProgress
: 0,
176 * If true, an input is shown and user can use it to set the slider value.
178 * @attribute editable
185 * The immediate value of the slider. This value is updated while the user
186 * is dragging the slider.
188 * @attribute immediateValue
196 'step snaps': 'update'
204 this.positionKnob(this.calcRatio(this.value
));
205 this.updateMarkers();
208 minChanged: function() {
210 this.setAttribute('aria-valuemin', this.min
);
213 maxChanged: function() {
215 this.setAttribute('aria-valuemax', this.max
);
218 valueChanged: function() {
220 this.setAttribute('aria-valuenow', this.value
);
221 this.fire('core-change');
224 disabledChanged: function() {
226 this.removeAttribute('tabindex');
232 immediateValueChanged: function() {
233 if (!this.dragging
) {
234 this.value
= this.immediateValue
;
236 this.fire('immediate-value-change');
239 expandKnob: function() {
243 resetKnob: function() {
244 this.expandJob
&& this.expandJob
.stop();
248 positionKnob: function(ratio
) {
249 this.immediateValue
= this.calcStep(this.calcKnobPosition(ratio
)) || 0;
250 this._ratio
= this.snaps
? this.calcRatio(this.immediateValue
) : ratio
;
251 this.$.sliderKnob
.style
.left
= this._ratio
* 100 + '%';
254 inputChange: function() {
255 this.value
= this.$.input
.value
;
259 calcKnobPosition: function(ratio
) {
260 return (this.max
- this.min
) * ratio
+ this.min
;
263 trackStart: function(e
) {
264 this._w
= this.$.sliderBar
.offsetWidth
;
265 this._x
= this._ratio
* this._w
;
266 this._startx
= this._x
|| 0;
267 this._minx
= - this._startx
;
268 this._maxx
= this._w
- this._startx
;
269 this.$.sliderKnob
.classList
.add('dragging');
270 this.dragging
= true;
274 trackx: function(e
) {
275 var x
= Math
.min(this._maxx
, Math
.max(this._minx
, e
.dx
));
276 this._x
= this._startx
+ x
;
277 this.immediateValue
= this.calcStep(
278 this.calcKnobPosition(this._x
/ this._w
)) || 0;
279 var s
= this.$.sliderKnob
.style
;
280 s
.transform
= s
.webkitTransform
= 'translate3d(' + (this.snaps
?
281 (this.calcRatio(this.immediateValue
) * this._w
) - this._startx
: x
) + 'px, 0, 0)';
284 trackEnd: function() {
285 var s
= this.$.sliderKnob
.style
;
286 s
.transform
= s
.webkitTransform
= '';
287 this.$.sliderKnob
.classList
.remove('dragging');
288 this.dragging
= false;
290 this.value
= this.immediateValue
;
294 knobdown: function(e
) {
299 bardown: function(e
) {
301 this.transiting
= true;
302 this._w
= this.$.sliderBar
.offsetWidth
;
303 var rect
= this.$.sliderBar
.getBoundingClientRect();
304 var ratio
= (e
.x
- rect
.left
) / this._w
;
305 this.positionKnob(ratio
);
306 this.expandJob
= this.job(this.expandJob
, this.expandKnob
, 60);
310 knobTransitionEnd: function(e
) {
311 if (e
.target
=== this.$.sliderKnob
) {
312 this.transiting
= false;
316 updateMarkers: function() {
318 var l
= (this.max
- this.min
) / this.step
;
319 if (!this.snaps
&& l
> this.maxMarkers
) {
322 for (var i
= 0; i
< l
; i
++) {
323 this.markers
.push('');
327 increment: function() {
328 this.value
= this.clampValue(this.value
+ this.step
);
331 decrement: function() {
332 this.value
= this.clampValue(this.value
- this.step
);
335 incrementKey: function(ev
, keys
) {
336 if (keys
.key
=== "end") {
337 this.value
= this.max
;
344 decrementKey: function(ev
, keys
) {
345 if (keys
.key
=== "home") {
346 this.value
= this.min
;