UNPKG

range-slider-element

Version:

A cross browser customizable and accessible <range-slider> web component

8 lines (7 loc) 6.63 kB
(function(r,h){typeof exports=="object"&&typeof module<"u"?module.exports=h():typeof define=="function"&&define.amd?define(h):(r=typeof globalThis<"u"?globalThis:r||self,r.RangeSliderElement=h())})(this,function(){"use strict";var r=typeof document<"u"?document.currentScript:null;const h={value:"valuenow",min:"valuemin",max:"valuemax"};function v(c=""){const t=String(c).split(".")[1];return t?t.length:0}function o(c,t,e){const i=h[t];i&&c.setAttribute(`aria-${i}`,e)}const g=["min","max","step","value","disabled","value-precision"],A={min:"min",max:"max",step:"step",value:"value",disabled:"disabled","value-precision":"valuePrecision"},f={stepUp:["ArrowUp","ArrowRight"],stepDown:["ArrowDown","ArrowLeft"]},b=document.createElement("template");b.innerHTML=` <div data-track></div> <div data-track-fill></div> <div data-runnable-track> <div data-thumb></div> </div> `;class u extends HTMLElement{static define(t="range-slider",e=customElements){if(!e.get(t))return e.define(t,u),u}static observedAttributes=g;static formAssociated=!0;#n;#l;#t=[];#r=[];#i=0;#a=!1;constructor(){super(),this.#n=this.attachInternals(),this.addEventListener("focusin",this.#f),this.addEventListener("pointerdown",this.#b),this.addEventListener("keydown",this.#v)}get min(){return this.hasAttribute("min")?Number(this.getAttribute("min")):0}get max(){return this.hasAttribute("max")?Number(this.getAttribute("max")):100}get step(){return this.hasAttribute("step")?Number(this.getAttribute("step")):1}get value(){return this.#t.join(",")}get disabled(){return this.hasAttribute("disabled")}get valuePrecision(){return this.getAttribute("value-precision")||""}get#s(){return this.getAttribute("orientation")==="vertical"}get#d(){return!!(this.#s||this.getAttribute("dir")==="rtl")}get#c(){return this.#e.length>1}get#e(){return this.querySelectorAll("[data-runnable-track] [data-thumb]")}get#m(){return this.querySelector("[data-track-fill]")}get#h(){return this.#s?this.offsetHeight:this.offsetWidth}set min(t){this.setAttribute("min",t);for(const e of this.#e)o(e,"min",t)}set max(t){this.setAttribute("max",t);for(const e of this.#e)o(e,"max",t)}set step(t){this.setAttribute("step",t)}set value(t){const e=String(t).split(",").map(i=>Number(i.trim())).filter(i=>!Number.isNaN(i));this.#t=[],this.#r=[],e.forEach((i,s)=>{this.#u(s,i)})}set disabled(t){this.toggleAttribute("disabled",!!t),this.#x()}set valuePrecision(t){this.setAttribute("value-precision",t)}get form(){return this.#n.form}get name(){return this.getAttribute("name")}get type(){return this.localName}get validity(){return this.#n.validity}get validationMessage(){return this.#n.validationMessage}get willValidate(){return this.#n.willValidate}checkValidity(){return this.#n.checkValidity()}reportValidity(){return this.#n.reportValidity()}formDisabledCallback(t){this.#a=t,this.#x()}connectedCallback(){this.firstChild||this.appendChild(b.content.cloneNode(!0)),!this.disabled&&!this.#a&&this.setAttribute("tabindex","-1"),this.#e.forEach((t,e)=>{t.dataset.thumb=e,t.setAttribute("role","slider"),o(t,"min",this.min),o(t,"max",this.max),!this.disabled&&!this.#a&&t.setAttribute("tabindex",0)}),this.value=this.getAttribute("value")||this.#w()}disconnectedCallback(){this.removeEventListener("focusin",this.#f),this.removeEventListener("pointerdown",this.#b),this.removeEventListener("keydown",this.#v)}attributeChangedCallback(t,e,i){if(e===i)return;if(t==="disabled"){this.disabled=i!==null;return}const s=A[t];s&&(this[s]=i)}#f=t=>{t.target.dataset.thumb!==void 0&&(this.#i=Number(t.target.dataset.thumb))};#b=t=>{if(!(this.disabled||this.#a))if(this.setPointerCapture(t.pointerId),this.addEventListener("pointermove",this.#p),window.addEventListener("pointerup",this.#o),window.addEventListener("pointercancel",this.#o),this.#l=this.value,t.target.dataset.thumb!==void 0)this.#i=Number(t.target.dataset.thumb);else{const{offsetX:e,offsetY:i}=t;this.#i=this.#T(this.#s?i:e),this.#g(this.#s?i:e)}};#p=t=>{t.target===this&&(t.preventDefault(),this.#g(this.#s?t.offsetY:t.offsetX))};#o=t=>{this.releasePointerCapture(t.pointerId),this.removeEventListener("pointermove",this.#p),window.removeEventListener("pointerup",this.#o),window.removeEventListener("pointercancel",this.#o),this.#l!==this.value&&this.dispatchEvent(new Event("change",{bubbles:!0}))};#v=t=>{const i=Object.keys(f).find(s=>f[s].includes(t.code)&&s);document.activeElement!==this.#e[this.#i]&&this.#e[this.#i].focus({focusVisible:!1}),i&&(t.preventDefault(),this[i]())};#g=t=>{const i=Math.min(Math.max(t,0),this.#h)/this.#h,s=this.#E(this.#d?1-i:i);this.#u(this.#i,s,["input"])};#w(){return this.max<this.min?this.min:this.min+(this.max-this.min)/2}#A(t){return 100*(t-this.min)/(this.max-this.min)}#E(t){return this.min+t*(this.max-this.min)}#T(t){let e;const s=Math.min(Math.max(t,0),this.#h)/this.#h,a=this.#E(this.#d?1-s:s),n=this.#t.findIndex(l=>a-l<0);if(n===0)e=n;else if(n===-1)e=this.#t.length-1;else{const l=this.#t[n-1],m=this.#t[n];Math.abs(l-a)<Math.abs(m-a)?e=n-1:e=n}return e}#u(t,e,i=[]){const s=this.#t[t],a=Number(this.valuePrecision)||v(this.step)||0,n=Math.min(this.min,this.max),l=Math.max(this.min,this.max),m=this.#t[t-1]??n,E=this.#t[t+1]??l,x=Math.min(Math.max(e,m),E)-this.min,w=Math.round(x/this.step)*this.step,p=this.min+w,d=Number(a?p.toFixed(a):Math.round(p));if(s!==d){this.#t[t]=d,this.#r[t]=this.#A(d),this.#n.setFormValue(this.#t.join(",")),this.#k(t,d),this.#y();for(const T of i)this.dispatchEvent(new Event(T,{bubbles:!0}))}}#k(t,e){this.#e[t]&&(this.#e[t].style.setProperty(`inset-${this.#s?"block":"inline"}-${this.#s?"end":"start"}`,`${this.#A(e)}%`),o(this.#e[t],"value",e))}#y(){if(!this.#m)return;const t=this.#c?`${this.#r[0]}%`:0,i=`clamp(var(--thumb-size) / 2, ${this.#c?`${100-this.#r[this.#r.length-1]}%`:`${100-this.#r[0]}%`}, 100% - var(--thumb-size) / 2)`;this.#m.style.setProperty(`inset-${this.#s?"block":"inline"}`,this.#s?`${i} ${t}`:`${t} ${i}`)}#x(){if(this.disabled||this.#a){this.removeAttribute("tabindex");for(const t of this.#e)t.removeAttribute("tabindex")}else{this.setAttribute("tabindex","-1");for(const t of this.#e)t.setAttribute("tabindex","0")}}stepUp(t=this.step){const e=this.#t[this.#i]+t;this.#u(this.#i,e,["change"])}stepDown(t=this.step){const e=this.#t[this.#i]-t;this.#u(this.#i,e,["change"])}}return new URL(typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:r&&r.tagName.toUpperCase()==="SCRIPT"&&r.src||new URL("range-slider-element.umd.cjs",document.baseURI).href).searchParams.has("define","false")||(window.RangeSliderElement=u.define()),u});