7 Polymer.IronFormElementBehavior,
8 Polymer.PaperInkyFocusBehavior,
9 Polymer.IronRangeBehavior
15 * If true, the slider thumb snaps to tick marks evenly spaced based
16 * on the `step` property value.
25 * If true, a pin with numeric value label is shown when the slider thumb
26 * is pressed. Use for settings for which users need to know the exact
27 * value of the setting.
36 * The number that represents the current secondary progress.
42 observer: '_secondaryProgressChanged'
46 * If true, an input is shown and user can use it to set the slider value.
54 * The immediate value of the slider. This value is updated while the user
55 * is dragging the slider.
65 * The maximum number of markers
71 observer: '_maxMarkersChanged'
75 * If true, the knob is expanded
84 * True when the user is dragging the slider.
106 '_updateKnob(value, min, max, snaps, step)',
109 '_valueChanged(value)',
110 '_immediateValueChanged(immediateValue)'
119 'left down pagedown home': '_decrementKey',
120 'right up pageup end': '_incrementKey'
124 // issue polymer/polymer#1305
126 this.async(function() {
127 this._updateKnob(this.value);
132 * Increases value by `step` but not above `max`.
135 increment: function() {
136 this.value = this._clampValue(this.value + this.step);
140 * Decreases value by `step` but not below `min`.
143 decrement: function() {
144 this.value = this._clampValue(this.value - this.step);
147 _updateKnob: function(value) {
148 this._positionKnob(this._calcRatio(value));
151 _minChanged: function() {
152 this.setAttribute('aria-valuemin', this.min);
155 _maxChanged: function() {
156 this.setAttribute('aria-valuemax', this.max);
159 _valueChanged: function() {
160 this.setAttribute('aria-valuenow', this.value);
161 this.fire('value-change');
164 _immediateValueChanged: function() {
166 this.fire('immediate-value-change');
168 this.value = this.immediateValue;
172 _secondaryProgressChanged: function() {
173 this.secondaryProgress = this._clampValue(this.secondaryProgress);
176 _fixForInput: function(immediateValue) {
177 // paper-input/issues/114
178 return this.immediateValue.toString();
181 _expandKnob: function() {
182 this._setExpand(true);
185 _resetKnob: function() {
186 this.cancelDebouncer('expandKnob');
187 this._setExpand(false);
190 _positionKnob: function(ratio) {
191 this._setImmediateValue(this._calcStep(this._calcKnobPosition(ratio)));
192 this._setRatio(this._calcRatio(this.immediateValue));
194 this.$.sliderKnob.style.left = (this.ratio * 100) + '%';
197 _inputChange: function() {
198 this.value = this.$$('#input').value;
202 _calcKnobPosition: function(ratio) {
203 return (this.max - this.min) * ratio + this.min;
206 _onTrack: function(event) {
207 event.stopPropagation();
208 switch (event.detail.state) {
210 this._trackStart(event);
221 _trackStart: function(event) {
222 this._w = this.$.sliderBar.offsetWidth;
223 this._x = this.ratio * this._w;
224 this._startx = this._x || 0;
225 this._minx = - this._startx;
226 this._maxx = this._w - this._startx;
227 this.$.sliderKnob.classList.add('dragging');
229 this._setDragging(true);
232 _trackX: function(e) {
233 if (!this.dragging) {
237 var dx = Math.min(this._maxx, Math.max(this._minx, e.detail.dx));
238 this._x = this._startx + dx;
240 var immediateValue = this._calcStep(this._calcKnobPosition(this._x / this._w));
241 this._setImmediateValue(immediateValue);
243 // update knob's position
244 var translateX = ((this._calcRatio(immediateValue) * this._w) - this._startx);
245 this.translate3d(translateX + 'px', 0, 0, this.$.sliderKnob);
248 _trackEnd: function() {
249 var s = this.$.sliderKnob.style;
251 this.$.sliderKnob.classList.remove('dragging');
252 this._setDragging(false);
254 this.value = this.immediateValue;
256 s.transform = s.webkitTransform = '';
261 _knobdown: function(event) {
265 event.preventDefault();
267 // set the focus manually because we will called prevent default
271 _bardown: function(event) {
272 this._w = this.$.sliderBar.offsetWidth;
273 var rect = this.$.sliderBar.getBoundingClientRect();
274 var ratio = (event.detail.x - rect.left) / this._w;
275 var prevRatio = this.ratio;
277 this._setTransiting(true);
279 this._positionKnob(ratio);
281 this.debounce('expandKnob', this._expandKnob, 60);
283 // if the ratio doesn't change, sliderKnob's animation won't start
284 // and `_knobTransitionEnd` won't be called
285 // Therefore, we need to manually update the `transiting` state
287 if (prevRatio === this.ratio) {
288 this._setTransiting(false);
291 this.async(function() {
296 event.preventDefault();
299 _knobTransitionEnd: function(event) {
300 if (event.target === this.$.sliderKnob) {
301 this._setTransiting(false);
305 _maxMarkersChanged: function(maxMarkers) {
306 var l = (this.max - this.min) / this.step;
307 if (!this.snaps && l > maxMarkers) {
308 this._setMarkers([]);
310 this._setMarkers(new Array(l));
314 _mergeClasses: function(classes) {
315 return Object.keys(classes).filter(
316 function(className) {
317 return classes[className];
321 _getClassNames: function() {
322 return this._mergeClasses({
323 disabled: this.disabled,
326 ring: this.immediateValue <= this.min,
328 dragging: this.dragging,
329 transiting: this.transiting,
330 editable: this.editable
334 _incrementKey: function(event) {
335 if (event.detail.key === 'end') {
336 this.value = this.max;
343 _decrementKey: function(event) {
344 if (event.detail.key === 'home') {
345 this.value = this.min;
354 * Fired when the slider's value changes.
356 * @event value-change
360 * Fired when the slider's immediateValue changes.
362 * @event immediate-value-change
366 * Fired when the slider's value changes due to user interaction.
368 * Changes to the slider's value due to changes in an underlying
369 * bound variable will not trigger this event.