axentix
Version:
Axentix is a framework mixing fully customizable components & utility-first classes, leaving the design choice to the developer.
319 lines (318 loc) • 14.1 kB
JavaScript
var X = Object.defineProperty;
var T = (e) => {
throw TypeError(e);
};
var Y = (e, t, s) => t in e ? X(e, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : e[t] = s;
var b = (e, t, s) => Y(e, typeof t != "symbol" ? t + "" : t, s), A = (e, t, s) => t.has(e) || T("Cannot " + s);
var i = (e, t, s) => (A(e, t, "read from private field"), s ? s.call(e) : t.get(e)), x = (e, t, s) => t.has(e) ? T("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(e) : t.set(e, s), m = (e, t, s, n) => (A(e, t, "write to private field"), n ? n.call(e, s) : t.set(e, s), s), u = (e, t, s) => (A(e, t, "access private method"), s);
const E = [], g = {
components: [],
plugins: [],
prefix: "ax",
mode: ""
}, C = (e) => `--${g.prefix}-${e}`, L = (e) => g.components.find((t) => t.name === e).class, $ = () => {
const e = g.components.filter((s) => s.dataDetection), t = g.plugins.filter((s) => s.dataDetection);
return [...e, ...t].map((s) => s.name);
}, _ = (e, t) => {
if (!e.name || !e.class) {
console.error(`[Axentix] Error registering ${t} : Missing required parameters.`);
return;
}
if (g[t].some((s) => s.name === e.name)) {
console.error(`[Axentix] Error registering ${t} : Already exist.`);
return;
}
e.autoInit && (e.autoInit.selector = e.autoInit.selector += ":not(.no-axentix-init)"), g[t].push(e);
}, j = (e) => {
_(e, "components");
}, ee = (e) => e.replace(/[\w]([A-Z])/g, (t) => t[0] + "-" + t[1]).toLowerCase(), te = (e, t = "") => {
const s = ee(e);
return t ? t + "-" + s : s;
}, se = (e, t, s, n, r = "") => {
const o = t[0].toUpperCase() + t.slice(1).toLowerCase();
$().includes(o) && s !== "Collapsible" && o !== "Sidenav" && (e[t] = L(o).getDefaultOptions());
const l = r ? r + "-" + t : t, a = V(e[t], s, n, l);
if (!(Object.keys(a).length === 0 && e.constructor === Object)) return a;
}, V = (e, t, s, n = "") => Object.keys(e).reduce((r, o) => {
if (typeof e[o] == "object" && e[o] !== null) {
const l = se(e, o, t, s, n);
l && (r[o] = l);
} else if (e[o] !== null) {
const l = "data-" + t.toLowerCase() + "-" + te(o, n);
if (s.hasAttribute(l)) {
const a = s.getAttribute(l);
r[o] = typeof e[o] == "number" ? Number(a) : a, typeof e[o] == "boolean" && (r[o] = a === "true");
}
}
return r;
}, {}), ne = (e, t) => {
const s = Object.assign({}, L(e).getDefaultOptions());
return V(s, e, t);
}, oe = () => {
document.querySelectorAll("[data-ax]").forEach((t) => {
let s = t.dataset.ax;
if (s = s[0].toUpperCase() + s.slice(1).toLowerCase(), !$().includes(s)) {
console.error(
`[Axentix] Error: ${s} component doesn't exist.
Did you forget to register him ?`,
t
);
return;
}
try {
const n = L(s);
new n(`#${t.id}`);
} catch (n) {
console.error("[Axentix] Data: Unable to load " + s, n);
}
});
}, re = () => {
try {
new Axentix.Axentix("all");
} catch (e) {
console.error("[Axentix] Unable to auto init.", e);
}
};
document.addEventListener("DOMContentLoaded", () => {
document.documentElement.dataset.axentix && re(), oe();
});
const B = (...e) => e.reduce((t, s) => {
for (let n in s)
t[n] = typeof s[n] == "object" && s[n] !== null ? B(t[n], s[n]) : s[n];
return t;
}, {}), ie = (e, t, s) => B(L(e).getDefaultOptions(), ne(e, s), t), le = (e, t = document.createElement("div")) => (e[0].parentElement.insertBefore(t, e[0]), e.forEach((n) => t.appendChild(n)), t), ae = (e) => e.replaceWith(...e.childNodes), I = (e, t, s) => {
const n = new CustomEvent("ax." + t, {
detail: {},
bubbles: !0
});
e.dispatchEvent(n);
}, ce = (e) => {
const t = E.find((s) => s.type !== "Toast" && "#" + s.instance.el.id === e);
return t ? t.instance : !1;
}, de = () => Math.random().toString().split(".")[1], fe = (e) => e.checkValidity() || e.validationMessage, ue = (e, t) => {
const s = document.createElement("div");
s.axGenerated = !0, e.appendChild(s), s.classList.add("form-helper-invalid"), s.innerHTML = t;
}, he = (e) => {
const t = e.querySelector(".form-helper-invalid");
t && t.axGenerated && t.remove();
}, pe = (e) => {
e.classList.remove("form-valid", "form-invalid", "form-no-helper"), he(e);
}, me = (e, t) => {
const s = e.getAttribute("data-form-validate");
let n = !1;
if (s) {
const l = s.toLowerCase().split(",");
if (n = l.includes("auto"), l.includes("lazy") && t === "input") return;
}
const r = fe(e), o = e.closest(".form-field, .form-file");
return pe(o), r !== !0 ? (n && typeof r == "string" ? ue(o, r) : o.querySelector(".form-helper-invalid") || o.classList.add("form-no-helper"), o.classList.add("form-invalid"), !1) : (o.classList.add("form-valid"), o.querySelector(".form-helper-valid") || o.classList.add("form-no-helper"), !0);
};
let q = !0;
const w = (e) => {
e.forEach(z);
}, H = (e) => {
if (q) {
q = !1;
return;
}
setTimeout(() => {
w(e);
}, 10);
}, z = (e) => {
const t = e.closest(".form-field"), s = t.querySelector(".form-custom-select"), n = t.classList.contains("active"), r = ["date", "month", "week", "time"];
let o = s && e.tagName === "DIV" && e.innerText.length > 0;
s || (o = e.value.length > 0 || e.tagName !== "SELECT" && e.placeholder.length > 0 || e.tagName === "SELECT" || r.some((h) => e.matches(`[type="${h}"]`)));
const l = document.activeElement === e, a = e.hasAttribute("disabled") || e.hasAttribute("readonly");
e.firstInit ? (M(e, n, o, l, t, s), e.firstInit = !1, e.isInit = !0) : a || M(e, n, o, l, t, s);
}, M = (e, t, s, n, r, o) => {
const l = e.type === "textarea", a = r.querySelector("label:not(.form-check)");
!t && (s || n) ? r.classList.add("active") : t && !(s || n) && r.classList.remove("active"), l ? a && (a.style.backgroundColor = P(a)) : ve(e, r, o, a), n && !l ? r.classList.add("is-focused") : o || r.classList.remove("is-focused"), n && l ? r.classList.add("is-textarea-focused") : r.classList.remove("is-textarea-focused");
}, ve = (e, t, s, n) => {
const r = e.clientWidth, o = e.offsetLeft, l = e.clientHeight + (s ? s.offsetTop : e.offsetTop) + "px", a = e.closest(".form-material").classList.contains("form-material-bordered");
t.style.setProperty(C("form-material-position"), l);
let h = o, O = "left", Q = r + "px", R = 0;
t.classList.contains("form-rtl") && (O = "right", h = t.clientWidth - r - o), t.style.setProperty(C(`form-material-${O}-offset`), h + "px"), h != 0 && (R = o), t.style.setProperty(C("form-material-width"), Q), n && (n.style.left = R + "px", a && (n.style.backgroundColor = P(n)));
}, N = (e) => {
const t = window.getComputedStyle(e).backgroundColor;
if (t && !["transparent", "rgba(0, 0, 0, 0)"].includes(t)) return t;
}, P = (e) => {
e.style.backgroundColor = "";
let t = e;
for (; t.parentElement; ) {
const n = N(t);
if (n) return n;
t = t.parentElement;
}
const s = N(document.documentElement);
return s || "white";
}, U = (e, t) => {
e.hasAttribute("data-form-validate") && me(e, t.type);
}, xe = (e, t) => {
e.forEach((s) => {
s === t.target && z(s);
});
}, ye = (e, t) => {
t.target.tagName === "FORM" && t.target.classList.contains("form-material") && H(e);
}, ge = (e) => {
e.forEach((o) => {
o.firstInit = !0, o.validateRef = U.bind(null, o), o.addEventListener("input", o.validateRef), o.addEventListener("change", o.validateRef);
}), w(e);
const t = xe.bind(null, e);
document.addEventListener("focus", t, !0), document.addEventListener("blur", t, !0);
const s = H.bind(null, e);
window.addEventListener("pageshow", s);
const n = ye.bind(null, e);
document.addEventListener("reset", n);
const r = w.bind(null, e);
window.addEventListener("resize", r);
}, Le = (e, t) => {
const s = e.files;
s.length > 1 ? t.innerHTML = Array.from(s).map((n) => n.name).join(", ") : s[0] && (t.innerHTML = s[0].name);
}, be = (e) => {
if (e.isInit) return;
e.isInit = !0;
const t = e.querySelector('input[type="file"]'), s = e.querySelector(".form-file-path");
t.handleRef = Le.bind(null, t, s), t.validateRef = U.bind(null, t), t.addEventListener("change", t.handleRef), t.addEventListener("input", t.validateRef), t.addEventListener("change", t.validateRef);
}, Ee = () => {
const e = Array.from(document.querySelectorAll(".form-file"));
try {
e.forEach(be);
} catch (t) {
console.error("[Axentix] Form file error", t);
}
}, S = (e = document.querySelectorAll(
".form-material .form-field:not(.form-default) .form-control:not(.form-custom-select)"
)) => {
const { setupInputs: t, detectInputs: s } = Array.from(e).reduce(
(n, r) => (r.isInit ? n.detectInputs.push(r) : n.setupInputs.push(r), n),
{ setupInputs: [], detectInputs: [] }
);
Ee();
try {
t.length > 0 && ge(t), s.length > 0 && w(s);
} catch (n) {
console.error("[Axentix] Material forms error", n);
}
};
document.addEventListener("DOMContentLoaded", () => S());
class we {
constructor() {
b(this, "el");
}
removeListeners() {
}
setupListeners() {
}
setup() {
}
preventDbInstance(t) {
if (t && ce(t)) throw new Error(`Instance already exist on ${t}`);
}
sync() {
I(this.el, "component.sync"), this.removeListeners(), this.setupListeners();
}
reset() {
I(this.el, "component.reset"), this.removeListeners(), this.setup();
}
destroy() {
I(this.el, "component.destroy"), this.removeListeners();
const t = E.findIndex((s) => s.instance.el.id === this.el.id);
E.splice(t, 1);
}
}
const Ae = {
inputClasses: ""
};
var f, v, d, y, p, c, G, Z, k, F, J, D, K;
class W extends we {
constructor(s, n) {
super();
x(this, c);
b(this, "options");
x(this, f);
x(this, v);
x(this, d);
x(this, y);
x(this, p);
try {
this.preventDbInstance(s), E.push({ type: "Select", instance: this }), this.el = document.querySelector(s), this.options = ie("Select", n, this.el), this.setup();
} catch (r) {
console.error("[Axentix] Select init error", r);
}
}
setup() {
this.el.style.display = "none", m(this, v, le([this.el])), i(this, v).className = "form-custom-select", u(this, c, G).call(this);
}
reset() {
this.destroy(!0), super.reset();
}
destroy(s) {
s || super.destroy(), i(this, f) && (i(this, f).el.removeEventListener("ax.dropdown.open", i(this, p)), i(this, f).el.removeEventListener("ax.dropdown.close", i(this, p)), m(this, p, null), i(this, f).destroy(), i(this, f).el.remove(), m(this, f, null)), ae(i(this, v)), this.el.classList.add("form-custom-select"), this.el.style.display = "";
}
}
f = new WeakMap(), v = new WeakMap(), d = new WeakMap(), y = new WeakMap(), p = new WeakMap(), c = new WeakSet(), G = function() {
const s = `dropdown-${de()}`;
m(this, d, document.createElement("div")), i(this, d).className = `form-control ${this.options.inputClasses}`, i(this, d).dataset.target = s;
const n = document.createElement("div"), r = this.el.className.replace("form-control", "");
if (n.className = `dropdown-content ${r}`, this.el.disabled) {
i(this, d).setAttribute("disabled", ""), i(this, v).append(i(this, d)), u(this, c, k).call(this, n);
return;
}
m(this, p, u(this, c, F).bind(this));
const o = document.createElement("div");
o.className = "dropdown", o.id = s, o.addEventListener("ax.dropdown.open", i(this, p)), o.addEventListener("ax.dropdown.close", i(this, p)), Array.from(this.el.attributes).forEach((h) => {
h.name.startsWith("data-dropdown") && o.setAttribute(h.name, h.value);
}), o.append(i(this, d)), o.append(n), i(this, v).append(o), u(this, c, k).call(this, n);
const l = L("Dropdown");
m(this, f, new l(`#${s}`, {
closeOnClick: !this.el.multiple,
preventViewport: !0
}));
const a = window.getComputedStyle(o).zIndex;
m(this, y, this.el.closest(".form-field").querySelector("label:not(.form-check)")), i(this, y) && (i(this, y).style.zIndex = a + 5);
}, Z = function(s, n) {
const r = document.createElement("div");
r.className = "form-field";
const o = document.createElement("label");
o.className = "form-check";
const l = document.createElement("input");
l.type = "checkbox", n && l.setAttribute("disabled", "");
const a = document.createElement("span");
return a.innerHTML = s, o.append(l, a), r.append(o), r;
}, k = function(s) {
for (const n of this.el.options) {
const r = n.hasAttribute("disabled"), o = document.createElement("div");
o.className = "dropdown-item", o.innerHTML = this.el.multiple ? u(this, c, Z).call(this, n.text, r).innerHTML : n.text, o.axValue = n.value || n.text, r ? o.classList.add("form-disabled") : (o.axClickRef = u(this, c, J).bind(this, o), o.addEventListener("click", o.axClickRef)), (n.hasAttribute("selected") || !this.el.multiple && this.el.value === (n.value || n.text)) && u(this, c, D).call(this, o), s.append(o);
}
}, F = function() {
i(this, d).closest(".form-field").classList.toggle("is-focused");
}, J = function(s, n) {
n.preventDefault(), s.classList.contains("form-selected") ? u(this, c, K).call(this, s) : u(this, c, D).call(this, s);
}, D = function(s) {
const n = s.axValue;
this.el.multiple ? s.querySelector("input").checked = !0 : i(this, f) && i(this, f).el.querySelectorAll(".dropdown-item").forEach((o) => o.classList.remove("form-selected")), s.classList.add("form-selected");
const r = this.el.multiple ? [...i(this, d).innerText.split(", ").filter(Boolean), n].join(", ") : n;
i(this, d).innerText = r, this.el.value = r, S([i(this, d)]);
}, K = function(s) {
const n = s.axValue;
s.classList.remove("form-selected");
let r = "";
if (this.el.multiple) {
s.querySelector("input").checked = !1;
const o = i(this, d).innerText.split(", ").filter(Boolean), l = o.findIndex((a) => a === n);
o.splice(l, 1), r = o.join(", ");
}
i(this, d).innerText = r, this.el.value = r, S([i(this, d)]);
}, b(W, "getDefaultOptions", () => Ae);
j({
class: W,
name: "Select",
dataDetection: !0,
autoInit: {
enabled: !0,
selector: ".form-custom-select"
}
});
export {
W as Select
};