UNPKG

range-slider-element

Version:

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

264 lines (263 loc) 9.71 kB
var W = Object.defineProperty; var B = (r) => { throw TypeError(r); }; var G = (r, a, t) => a in r ? W(r, a, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[a] = t; var $ = (r, a, t) => G(r, typeof a != "symbol" ? a + "" : a, t), D = (r, a, t) => a.has(r) || B("Cannot " + t); var e = (r, a, t) => (D(r, a, "read from private field"), t ? t.call(r) : a.get(r)), u = (r, a, t) => a.has(r) ? B("Cannot add the same private member more than once") : a instanceof WeakSet ? a.add(r) : a.set(r, t), E = (r, a, t, s) => (D(r, a, "write to private field"), s ? s.call(r, t) : a.set(r, t), t), o = (r, a, t) => (D(r, a, "access private method"), t); const J = { value: "valuenow", min: "valuemin", max: "valuemax" }; function Q(r = "") { const a = String(r).split(".")[1]; return a ? a.length : 0; } function x(r, a, t) { const s = J[a]; s && r.setAttribute(`aria-${s}`, t); } const Z = ["min", "max", "step", "value", "disabled", "value-precision"], _ = { stepUp: ["ArrowUp", "ArrowRight"], stepDown: ["ArrowDown", "ArrowLeft"] }, j = document.createElement("template"); j.innerHTML = ` <div data-track></div> <div data-track-fill></div> <div data-runnable-track> <div data-thumb></div> </div> `; var c, y, h, v, l, i, m, I, H, d, S, V, L, M, T, g, N, C, z, O, R, K, k, Y, q; class p extends HTMLElement { constructor() { super(); u(this, i); u(this, c); u(this, y); u(this, h, []); u(this, v, []); u(this, l, 0); u(this, L, (t) => { t.target.dataset.thumb !== void 0 && E(this, l, Number(t.target.dataset.thumb)); }); u(this, M, (t) => { if (!this.disabled) if (this.setPointerCapture(t.pointerId), this.addEventListener("pointermove", e(this, T)), window.addEventListener("pointerup", e(this, g)), window.addEventListener("pointercancel", e(this, g)), E(this, y, this.value), t.target.dataset.thumb !== void 0) E(this, l, Number(t.target.dataset.thumb)); else { const { offsetX: s, offsetY: n } = t; E(this, l, o(this, i, K).call(this, e(this, i, m) ? n : s)), e(this, C).call(this, e(this, i, m) ? n : s); } }); u(this, T, (t) => { t.target === this && (t.preventDefault(), e(this, C).call(this, e(this, i, m) ? t.offsetY : t.offsetX)); }); u(this, g, (t) => { this.releasePointerCapture(t.pointerId), this.removeEventListener("pointermove", e(this, T)), window.removeEventListener("pointerup", e(this, g)), window.removeEventListener("pointercancel", e(this, g)), e(this, y) !== this.value && this.dispatchEvent(new Event("change", { bubbles: !0 })); }); u(this, N, (t) => { const n = Object.keys(_).find((b) => _[b].includes(t.code) && b); document.activeElement !== e(this, i, d)[e(this, l)] && e(this, i, d)[e(this, l)].focus({ focusVisible: !1 }), n && (t.preventDefault(), this[n]()); }); /** * * @param {number} offset */ u(this, C, (t) => { const n = Math.min(Math.max(t, 0), e(this, i, V)) / e(this, i, V), b = o(this, i, R).call(this, e(this, i, I) ? 1 - n : n); o(this, i, k).call(this, e(this, l), b, ["input"]); }); E(this, c, this.attachInternals()), this.addEventListener("focusin", e(this, L)), this.addEventListener("pointerdown", e(this, M)), this.addEventListener("keydown", e(this, N)); } 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 e(this, h).join(","); } get disabled() { return this.getAttribute("disabled") === "" || !1; } get valuePrecision() { return this.getAttribute("value-precision") || ""; } set min(t) { this.setAttribute("min", t); for (const s of e(this, i, d)) x(s, "min", t); } set max(t) { this.setAttribute("max", t); for (const s of e(this, i, d)) x(s, "max", t); } set step(t) { this.setAttribute("step", t); } set value(t) { String(t).split(",").map((s, n) => { o(this, i, k).call(this, n, s); }); } set disabled(t) { if (t) { this.setAttribute("disabled", ""), this.removeAttribute("tabindex"); for (const s of e(this, i, d)) s.removeAttribute("tabindex"); } else { this.removeAttribute("disabled"), this.setAttribute("tabindex", "-1"); for (const s of e(this, i, d)) s.setAttribute("tabindex", 0); } } set valuePrecision(t) { this.setAttribute("value-precision", t); } /** * Form data support * The following properties and methods aren't strictly required, * but browser-level form controls provide them. Providing them helps * ensure consistency with browser-provided controls. */ get form() { return e(this, c).form; } get name() { return this.getAttribute("name"); } get type() { return this.localName; } get validity() { return e(this, c).validity; } get validationMessage() { return e(this, c).validationMessage; } get willValidate() { return e(this, c).willValidate; } checkValidity() { return e(this, c).checkValidity(); } reportValidity() { return e(this, c).reportValidity(); } connectedCallback() { this.firstChild || this.appendChild(j.content.cloneNode(!0)), this.disabled || this.setAttribute("tabindex", "-1"), e(this, i, d).forEach((t, s) => { t.dataset.thumb = s, t.setAttribute("role", "slider"), x(t, "min", this.min), x(t, "max", this.max), this.disabled || t.setAttribute("tabindex", 0); }), this.value = this.getAttribute("value") || o(this, i, z).call(this); } disconnectedCallback() { this.removeEventListener("focusin", e(this, L)), this.removeEventListener("pointerdown", e(this, M)), this.removeEventListener("keydown", e(this, N)); } attributeChangedCallback(t, s, n) { s !== n && (t === "value" ? this.value = n : this.value = this.value); } /** * * @param {number} amount - Amount to step up */ stepUp(t = this.step) { const s = e(this, h)[e(this, l)] + t; o(this, i, k).call(this, e(this, l), s, ["change"]); } /** * * @param {number} amount - Amount to step down */ stepDown(t = this.step) { const s = e(this, h)[e(this, l)] - t; o(this, i, k).call(this, e(this, l), s, ["change"]); } } c = new WeakMap(), y = new WeakMap(), h = new WeakMap(), v = new WeakMap(), l = new WeakMap(), i = new WeakSet(), m = function() { return this.getAttribute("orientation") === "vertical"; }, I = function() { return !!(e(this, i, m) || this.getAttribute("dir") === "rtl"); }, H = function() { return e(this, i, d).length > 1; }, d = function() { return this.querySelectorAll("[data-runnable-track] [data-thumb]"); }, S = function() { return this.querySelector("[data-track-fill]"); }, V = function() { return e(this, i, m) ? this.offsetHeight : this.offsetWidth; }, L = new WeakMap(), M = new WeakMap(), T = new WeakMap(), g = new WeakMap(), N = new WeakMap(), C = new WeakMap(), z = function() { return this.max < this.min ? this.min : this.min + (this.max - this.min) / 2; }, /** * * @param {number} value * @returns */ O = function(t) { return 100 * (t - this.min) / (this.max - this.min); }, /** * Fit the percentage complete between the range [min,max] * by remapping from [0, 1] to [min, min+(max-min)]. * * @param {number} percent * @returns */ R = function(t) { return this.min + t * (this.max - this.min); }, /** * * @param {number} offset * @returns */ K = function(t) { let s; const b = Math.min(Math.max(t, 0), e(this, i, V)) / e(this, i, V), A = o(this, i, R).call(this, e(this, i, I) ? 1 - b : b), f = e(this, h).findIndex((w) => A - w < 0); if (f === 0) s = f; else if (f === -1) s = e(this, h).length - 1; else { const w = e(this, h)[f - 1], F = e(this, h)[f]; Math.abs(w - A) < Math.abs(F - A) ? s = f - 1 : s = f; } return s; }, /** * * @param {number} index * @param {number} value * @param {string[]} dispatchEvents */ k = function(t, s, n = []) { const b = e(this, h)[t], A = Number(this.valuePrecision) || Q(this.step) || 0, f = e(this, h)[t - 1] || this.min, w = e(this, h)[t + 1] || this.max, F = Math.min(Math.max(s, f), w), U = Math.round(F / this.step) * this.step, P = Number( A ? U.toFixed(A) : Math.round(U) ); b !== P && (e(this, h)[t] = P, e(this, v)[t] = o(this, i, O).call(this, P), e(this, c).setFormValue(e(this, h).join(",")), o(this, i, Y).call(this, t, P), o(this, i, q).call(this), n.map((X) => { this.dispatchEvent(new Event(X, { bubbles: !0 })); })); }, /** * * @param {number} index * @param {number} value */ Y = function(t, s) { e(this, i, d)[t] && (e(this, i, d)[t].style.setProperty( `inset-${e(this, i, m) ? "block" : "inline"}-${e(this, i, m) ? "end" : "start"}`, `${o(this, i, O).call(this, s)}%` ), x(e(this, i, d)[t], "value", s)); }, q = function() { if (!e(this, i, S)) return; const t = e(this, i, H) ? `${e(this, v)[0]}%` : 0, n = `clamp(var(--thumb-size) / 2, ${e(this, i, H) ? `${100 - e(this, v)[e(this, v).length - 1]}%` : `${100 - e(this, v)[0]}%`}, 100% - var(--thumb-size) / 2)`; e(this, i, S).style.setProperty( `inset-${e(this, i, m) ? "block" : "inline"}`, e(this, i, m) ? `${n} ${t}` : `${t} ${n}` ); }, $(p, "tagName", "range-slider"), $(p, "observedAttributes", Z), $(p, "formAssociated", !0); window.customElements.get(p.tagName) || (window.RangeSliderElement = p, window.customElements.define(p.tagName, p)); export { p as default };