-
-
Save LJ1102/0842e4bb56d9dc9c8d94329c6a2a16ee to your computer and use it in GitHub Desktop.
ValueSlider
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const sValueSliderInputEvent = new Event("input"); | |
class ValueSlider extends HTMLElement { | |
constructor () { | |
super(); | |
this.attachShadow({ mode: 'open' }); | |
this.shadowRoot.innerHTML = ` | |
<style> | |
@import '/css/theme.css'; | |
:host { | |
display: flex; | |
} | |
:host > input[type="range"] { | |
flex: 1 1 auto; | |
padding-left: 0; | |
} | |
:host > input[type="number"] { | |
flex: 0 0 auto; | |
width: 5em; | |
} | |
</style> | |
<style id="range-styles"> | |
input[type="range"]::-webkit-slider-thumb, | |
input[type="range"]:focus::-webkit-slider-thumb { | |
-webkit-appearance: none; | |
} | |
input[type="range"]::-webkit-slider-runnable-track { | |
image-rendering: pixelated; | |
background-size: contain; | |
} | |
</style> | |
<input type="range" tabindex="-1"/> | |
<input type="number"/> | |
`; | |
this._connected = false; | |
this._styles = this.shadowRoot.querySelector('#range-styles'); | |
this._rangeInput = this.shadowRoot.querySelector('input[type="range"]'); | |
this._numberInput = this.shadowRoot.querySelector('input[type="number"]'); | |
// value mirroring | |
this._rangeInput.addEventListener('input', () => { | |
this._numberInput.value = this._rangeInput.value; | |
this.dispatchEvent(sValueSliderInputEvent); | |
}); | |
this._numberInput.addEventListener('input', () => { | |
this._rangeInput.value = this._numberInput.value; | |
this.dispatchEvent(sValueSliderInputEvent); | |
}); | |
this._rangeInput.addEventListener('dblclick', () => this._numberInput.focus()); | |
// setup attributes | |
this.placeholder = this.getAttribute('placeholder'); | |
this.min = this.getAttribute('min') || 0; | |
this.max = this.getAttribute('max') || 1; | |
this.step = this.getAttribute('step') || "any"; | |
this.autostep = this.hasAttribute('autostep'); | |
this.value = this.getAttribute('value'); | |
} | |
get name () { return this.getAttribute('name'); } | |
set name (v) { | |
if (v) this.setAttribute('name', v); | |
else this.removeAttribute('name'); | |
} | |
get thumbColor () { return this.getAttribute('thumb-color'); } | |
set thumbColor (v) { this.setAttribute('thumb-color', v); } | |
get trackColor () { return this.getAttribute('track-color'); } | |
set trackColor (v) { this.setAttribute('track-color', v); } | |
get value () { return this._rangeInput.value; } | |
set value (v) { | |
const step = parseFloat(this.step); | |
if (!isNaN(step)) v = Math.round(v / step) * step; | |
let decimalPlaces = this.step.split("."); | |
if (decimalPlaces.length > 1) decimalPlaces = decimalPlaces[1].length; | |
else decimalPlaces = 0; | |
this._rangeInput.value = this._numberInput.value = v ? v.toFixed(decimalPlaces) : v; | |
} | |
get min () { return parseFloat(this.getAttribute('min')); } | |
set min (v) { | |
if (v) this.setAttribute('min', v); | |
else this.removeAttribute('min'); | |
} | |
get max () { return parseFloat(this.getAttribute('max')); } | |
set max (v) { | |
if (v) this.setAttribute('max', v); | |
else this.removeAttribute('max'); | |
} | |
get placeholder () { return this.getAttribute('placeholder'); } | |
set placeholder (v) { | |
if (v) this.setAttribute('placeholder', v); | |
else this.removeAttribute('placeholder'); | |
} | |
get step () { return this.getAttribute('step'); } | |
set step (v) { | |
if (v) this.setAttribute('step', v); | |
else this.removeAttribute('step'); | |
} | |
get autostep () { return this.hasAttribute('autostep'); } | |
set autostep (v) { this.toggleAttribute('autostep', v); } | |
_setSheetStyles () { | |
if (this._connected) { | |
this._styles.sheet.cssRules[0].style.background = this.thumbColor; | |
this._styles.sheet.cssRules[1].style.backgroundImage = this.trackColor; | |
} | |
} | |
static observedAttributes = ['min', 'max', 'placeholder', 'step', 'autostep', 'track-color', 'thumb-color']; | |
attributeChangedCallback (attr, oldVal, newVal) { | |
switch (attr) { | |
case 'min': | |
case 'max': | |
case 'step': | |
if (!isNaN(newVal)) this._rangeInput[attr] = this._numberInput[attr] = newVal; | |
else this._rangeInput.removeAttribute(attr), this._numberInput.removeAttribute(attr); | |
break; | |
case 'placeholder': | |
if (newVal) this._numberInput.placeholder = newVal; | |
else this._numberInput.removeAttribute('placeholder'); | |
break; | |
case 'autostep': | |
this._rangeInput.toggleAttribute('autostep', newVal !== void 0); | |
this._numberInput.toggleAttribute('autostep', newVal !== void 0); | |
break; | |
case 'track-color': | |
case 'thumb-color': | |
this._setSheetStyles(); | |
break; | |
} | |
} | |
connectedCallback () { | |
this._connected = true; | |
this._setSheetStyles(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment