range-slider-element
Version:
A cross browser customizable and accessible <range-slider> web component
264 lines (263 loc) • 9.71 kB
JavaScript
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
};