UNPKG

@adobe/coral-spectrum

Version:

Coral Spectrum is a JavaScript library of Web Components following Spectrum design patterns.

217 lines (180 loc) 5.58 kB
/** * Copyright 2019 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ import {ExtensibleSlider, Slider} from './Slider'; import range from '../templates/range'; import {commons, transform} from '../../../coral-utils'; import {Decorator} from '../../../coral-decorator'; /** @class Coral.RangedSlider @classdesc A Ranged Slider @htmltag coral-rangedslider @extends {Slider} */ const RangedSlider = Decorator(class extends ExtensibleSlider { /** Ranged sliders are always filled. @type {Boolean} @default true @htmlattribute filled @htmlattributereflected */ get filled() { return true; } set filled(value) { if (!transform.booleanAttr(value)) { commons._log('warn', 'Coral.RangedSlider: filled can not be set to false.'); } } /** This field's current value. @type {String} @default "" @htmlattribute value */ get value() { return this.startValue; } set value(value) { this.startValue = value; } /** The starting value of the range. @type {String} @default '1' @emits {change} @htmlattribute startValue */ get startValue() { return this.values[0] || '1'; } set startValue(value) { // Snap value to step value = String(this._snapValueToStep(transform.number(value), this.min, this.max, this.step)); const values = this.values; values[0] = value; this.values = values; // in order to keep the reset value in sync, we need to handle the "startvalue" attribute of the inner input const input = this._elements.inputs[0]; const valueAttribute = this.getAttribute('startvalue') || this.getAttribute('value'); input[valueAttribute ? 'setAttribute' : 'removeAttribute']('value', valueAttribute); } /** The ending value of the range. @type {String} @default '100' @emits {change} @htmlattribute endValue */ get endValue() { return this.values[1] || '100'; } set endValue(value) { // Snap value to step value = String(this._snapValueToStep(transform.number(value), this.min, this.max, this.step)); const values = this.values; values[1] = value; this.values = values; // in order to keep the reset value in sync, we need to handle the "endvalue" attribute of the inner input const input = this._elements.inputs[1]; const valueAttribute = this.getAttribute('endvalue'); input[valueAttribute ? 'setAttribute' : 'removeAttribute']('value', valueAttribute); } /** The current values of the ranged slider. @type {Array.<String>} @default [{@link Coral.RangedSlider#startValue},{@link Coral.RangedSlider#endValue}] @emits {change} */ get values() { return this._values; } set values(values) { this._values = values; } /** @private */ _getHighestValue() { return Math.max.apply(null, this.values); } /** @private */ _getLowestValue() { return Math.min.apply(null, this.values); } /** @override */ _updateValue(handle, val) { const idx = this._elements.handles.indexOf(handle); if (idx === 0) { if (val > parseFloat(this.values[1])) { val = this.values[1]; } this._elements.rightInput.min = val; this._elements.rightHandle.setAttribute('aria-valuemin', val); } else { if (val < parseFloat(this.values[0])) { val = this.values[0]; } this._elements.leftInput.max = val; this._elements.leftHandle.setAttribute('aria-valuemax', val); } const resValue = [this.values[0], this.values[1]]; resValue[idx] = val; const oldValues = this.values; this.values = resValue; const newValues = this.values; if (oldValues.join(':') !== newValues.join(':')) { this.trigger('change'); } } /** @override */ _getTemplate() { return range; } /** Inherited from {@link BaseFormField#clear}. */ clear() { this.startValue = this.min; this.endValue = this.max; } /** Inherited from {@link BaseFormField#reset}. */ reset() { // since the 'value' property is not reflected, form components use it to restore the initial value. When a // component has support for values, this method needs to be overwritten const initialStartValue = this.getAttribute('startvalue') || this.getAttribute('value'); const initialEndValue = this.getAttribute('endvalue'); this.startValue = transform.string(initialStartValue); this.endValue = transform.string(initialEndValue); } static get _attributePropertyMap() { return commons.extend(super._attributePropertyMap, { startvalue: 'startValue', endvalue: 'endValue' }); } /** @ignore */ static get observedAttributes() { return super.observedAttributes.concat([ 'startvalue', 'endvalue' ]); } /** @ignore */ render() { super.render(); this.classList.add('_coral-Slider--range'); // Set filled attribute by default this.setAttribute('filled', ''); } }); export default RangedSlider;