UNPKG

@decidables/decidables-elements

Version:

decidables-elements: Basic UI Web Components for the decidables project

334 lines (271 loc) 10 kB
import {ifDefined} from 'lit/directives/if-defined.js'; /* eslint-disable-line import/extensions */ import {html, css, unsafeCSS} from 'lit'; import DecidablesElement from './decidables-element'; export default class DecidablesSlider extends DecidablesElement { static get properties() { return { disabled: { attribute: 'disabled', type: Boolean, reflect: true, }, max: { attribute: 'max', type: Number, reflect: true, }, min: { attribute: 'min', type: Number, reflect: true, }, step: { attribute: 'step', type: Number, reflect: true, }, value: { attribute: 'value', type: Number, reflect: true, }, }; } constructor() { super(); // Attributes this.disabled = false; this.max = undefined; this.min = undefined; this.step = undefined; this.value = undefined; } changed(event) { this.value = event.target.value; this.dispatchEvent(new CustomEvent('change', { detail: { value: this.value, }, bubbles: true, })); } inputted(event) { this.value = event.target.value; } static get styles() { return [ super.styles, css` :host { ---shadow-2-rotate: var(--shadow-2-rotate, ${unsafeCSS(this.cssBoxShadow(2, true, false))}); ---shadow-4-rotate: var(--shadow-4-rotate, ${unsafeCSS(this.cssBoxShadow(4, true, false))}); ---shadow-8-rotate: var(--shadow-8-rotate, ${unsafeCSS(this.cssBoxShadow(8, true, false))}); display: flex; flex-direction: column; align-items: center; justify-content: center; } label { margin: 0.25rem 0.25rem 0; } .range { display: inline-block; width: 3.5rem; height: 4.75rem; margin: 0 0.25rem 0.25rem; } decidables-spinner { --decidables-spinner-input-width: 3.5rem; margin: 0 0.25rem 0.25rem; } /* Adapted from http://danielstern.ca/range.css/#/ */ /* Overall */ input[type=range] { width: 4.75rem; height: 3.5rem; padding: 0; margin: 0; background-color: unset; transform: rotate(-90deg); transform-origin: 2.375rem 2.375rem; /* stylelint-disable-next-line property-no-vendor-prefix */ -webkit-appearance: none; } input[type=range]:enabled { cursor: ns-resize; } input[type=range]:focus { outline: none; } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]::-ms-tooltip { display: none; } /* Track */ /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]::-webkit-slider-runnable-track { width: 100%; height: 4px; background: var(---color-element-disabled); border: 0; border-radius: 2px; box-shadow: none; } input[type=range]:focus::-webkit-slider-runnable-track { background: var(---color-element-disabled); } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]::-moz-range-track { width: 100%; height: 4px; background: var(---color-element-disabled); border: 0; border-radius: 2px; box-shadow: none; } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]::-ms-track { width: 100%; height: 4px; color: transparent; background: transparent; border-color: transparent; } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]::-ms-fill-lower { background: #cccccc; /* background: var(---color-element-disabled); */ border: 0; border-radius: 2px; box-shadow: none; } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]::-ms-fill-upper { background: #cccccc; /* background: var(---color-element-disabled); */ border: 0; border-radius: 2px; box-shadow: none; } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]:focus::-ms-fill-lower { background: var(---color-element-disabled); } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]:focus::-ms-fill-upper { background: var(---color-element-disabled); } /* Thumb */ /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]::-webkit-slider-thumb { width: 10px; height: 20px; margin-top: -8px; border: 0; border-radius: 4px; /* stylelint-disable-next-line property-no-vendor-prefix */ -webkit-appearance: none; } input[type=range]:disabled::-webkit-slider-thumb { background: var(---color-element-disabled); box-shadow: none; } input[type=range]:enabled::-webkit-slider-thumb { background: var(---color-element-enabled); box-shadow: var(---shadow-2-rotate); } input[type=range]:enabled:hover::-webkit-slider-thumb { box-shadow: var(---shadow-4-rotate); } input[type=range]:enabled:active::-webkit-slider-thumb { box-shadow: var(---shadow-8-rotate); } :host(.keyboard) input[type=range]:enabled:focus::-webkit-slider-thumb { box-shadow: var(---shadow-4-rotate); } :host(.keyboard) input[type=range]:focus:active::-webkit-slider-thumb { box-shadow: var(---shadow-8-rotate); } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]::-moz-range-thumb { width: 10px; height: 20px; border: 0; border-radius: 4px; } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]:disabled::-moz-range-thumb { background: var(---color-element-disabled); box-shadow: none; } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]:enabled::-moz-range-thumb { background: var(---color-element-enabled); box-shadow: var(---shadow-2-rotate); } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]:enabled:hover::-moz-range-thumb { box-shadow: var(---shadow-4-rotate); } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]:enabled:active::-moz-range-thumb { box-shadow: var(---shadow-8-rotate); } :host(.keyboard) input[type=range]:enabled:focus::-moz-range-thumb { box-shadow: var(---shadow-4-rotate); } :host(.keyboard) input[type=range]:enabled:focus:active::-moz-range-thumb { box-shadow: var(---shadow-8-rotate); } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]::-ms-thumb { width: 10px; height: 20px; margin-top: 0; background: #999999; /* background: var(---color-element-enabled); */ border: 0; border-radius: 4px; box-shadow: var(---shadow-2-rotate); } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]:disabled::-ms-thumb { background: var(---color-element-disabled); box-shadow: none; } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]:enabled::-ms-thumb { background: var(---color-element-enabled); box-shadow: var(---shadow-2-rotate); } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]:enabled:hover::-ms-thumb { box-shadow: var(---shadow-4-rotate); } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ input[type=range]:enabled:active::-ms-thumb { box-shadow: var(---shadow-8-rotate); } /* stylelint-disable-next-line no-descending-specificity */ /* stylelint ERROR */ :host(.keyboard) input[type=range]:enabled:focus::-ms-thumb { box-shadow: var(---shadow-4-rotate); } :host(.keyboard) input[type=range]:enabled:focus:active::-ms-thumb { box-shadow: var(---shadow-8-rotate); } `, ]; } render() { return html` <label for="slider"> <slot></slot> </label> <div class="range"> <input ?disabled=${this.disabled} type="range" id="slider" min=${ifDefined(this.min)} max=${ifDefined(this.max)} step=${ifDefined(this.step)} .value=${this.value} @change=${this.changed.bind(this)} @input=${this.inputted.bind(this)}> </div> <decidables-spinner ?disabled=${this.disabled} min=${ifDefined(this.min)} max=${ifDefined(this.max)} step=${ifDefined(this.step)} .value=${this.value} @input=${this.inputted.bind(this)}></decidables-spinner> `; } } customElements.define('decidables-slider', DecidablesSlider);