UNPKG

axentix

Version:

Axentix is a framework mixing fully customizable components & utility-first classes, leaving the design choice to the developer.

182 lines (181 loc) 7.73 kB
const f = { components: [], plugins: [], prefix: "ax", mode: "" }, p = (e) => `--${f.prefix}-${e}`, D = (e) => f.components.find((t) => t.name === e).class, k = () => { const e = f.components.filter((s) => s.dataDetection), t = f.plugins.filter((s) => s.dataDetection); return [...e, ...t].map((s) => s.name); }, q = () => { document.querySelectorAll("[data-ax]").forEach((t) => { let s = t.dataset.ax; if (s = s[0].toUpperCase() + s.slice(1).toLowerCase(), !k().includes(s)) { console.error( `[Axentix] Error: ${s} component doesn't exist. Did you forget to register him ?`, t ); return; } try { const o = D(s); new o(`#${t.id}`); } catch (o) { console.error("[Axentix] Data: Unable to load " + s, o); } }); }, T = () => { try { new Axentix.Axentix("all"); } catch (e) { console.error("[Axentix] Unable to auto init.", e); } }; document.addEventListener("DOMContentLoaded", () => { document.documentElement.dataset.axentix && T(), q(); }); const $ = (e, t, s) => { const o = new CustomEvent("ax." + t, { detail: s || {}, bubbles: !0 }); e.dispatchEvent(o); }, O = () => window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches, V = (e) => e.checkValidity() || e.validationMessage, P = (e, t) => { const s = document.createElement("div"); s.axGenerated = !0, e.appendChild(s), s.classList.add("form-helper-invalid"), s.innerHTML = t; }, B = (e) => { const t = e.querySelector(".form-helper-invalid"); t && t.axGenerated && t.remove(); }, b = (e) => { e.classList.remove("form-valid", "form-invalid", "form-no-helper"), B(e); }, E = (e, t) => { const s = e.getAttribute("data-form-validate"); let o = !1; if (s) { const a = s.toLowerCase().split(","); if (o = a.includes("auto"), a.includes("lazy") && t === "input") return; } const r = V(e), n = e.closest(".form-field, .form-file"); return b(n), r !== !0 ? (o && typeof r == "string" ? P(n, r) : n.querySelector(".form-helper-invalid") || n.classList.add("form-no-helper"), n.classList.add("form-invalid"), !1) : (n.classList.add("form-valid"), n.querySelector(".form-helper-valid") || n.classList.add("form-no-helper"), !0); }, H = (e) => { e.querySelectorAll("[data-form-validate]").forEach((s) => b(s.closest(".form-field, .form-file"))); }, N = (e) => [...e.querySelectorAll("[data-form-validate]")].map((s) => E(s, "change")).every((s) => s); let y = !0; const m = (e) => { e.forEach(A); }, I = (e) => { if (y) { y = !1; return; } setTimeout(() => { m(e); }, 10); }, A = (e) => { const t = e.closest(".form-field"), s = t.querySelector(".form-custom-select"), o = t.classList.contains("active"), r = ["date", "month", "week", "time"]; let n = s && e.tagName === "DIV" && e.innerText.length > 0; s || (n = e.value.length > 0 || e.tagName !== "SELECT" && e.placeholder.length > 0 || e.tagName === "SELECT" || r.some((c) => e.matches(`[type="${c}"]`))); const a = document.activeElement === e, l = e.hasAttribute("disabled") || e.hasAttribute("readonly"); e.firstInit ? (L(e, o, n, a, t, s), e.firstInit = !1, e.isInit = !0) : l || L(e, o, n, a, t, s); }, L = (e, t, s, o, r, n) => { const a = e.type === "textarea", l = r.querySelector("label:not(.form-check)"); !t && (s || o) ? r.classList.add("active") : t && !(s || o) && r.classList.remove("active"), a ? l && (l.style.backgroundColor = w(l)) : _(e, r, n, l), o && !a ? r.classList.add("is-focused") : n || r.classList.remove("is-focused"), o && a ? r.classList.add("is-textarea-focused") : r.classList.remove("is-textarea-focused"); }, _ = (e, t, s, o) => { const r = e.clientWidth, n = e.offsetLeft, a = e.clientHeight + (s ? s.offsetTop : e.offsetTop) + "px", l = e.closest(".form-material").classList.contains("form-material-bordered"); t.style.setProperty(p("form-material-position"), a); let c = n, v = "left", R = r + "px", g = 0; t.classList.contains("form-rtl") && (v = "right", c = t.clientWidth - r - n), t.style.setProperty(p(`form-material-${v}-offset`), c + "px"), c != 0 && (g = n), t.style.setProperty(p("form-material-width"), R), o && (o.style.left = g + "px", l && (o.style.backgroundColor = w(o))); }, x = (e) => { const t = window.getComputedStyle(e).backgroundColor; if (t && !["transparent", "rgba(0, 0, 0, 0)"].includes(t)) return t; }, w = (e) => { e.style.backgroundColor = ""; let t = e; for (; t.parentElement; ) { const o = x(t); if (o) return o; t = t.parentElement; } const s = x(document.documentElement); return s || "white"; }, C = (e, t) => { e.hasAttribute("data-form-validate") && E(e, t.type); }, j = (e, t) => { e.forEach((s) => { s === t.target && A(s); }); }, z = (e, t) => { t.target.tagName === "FORM" && t.target.classList.contains("form-material") && I(e); }, U = (e) => { e.forEach((n) => { n.firstInit = !0, n.validateRef = C.bind(null, n), n.addEventListener("input", n.validateRef), n.addEventListener("change", n.validateRef); }), m(e); const t = j.bind(null, e); document.addEventListener("focus", t, !0), document.addEventListener("blur", t, !0); const s = I.bind(null, e); window.addEventListener("pageshow", s); const o = z.bind(null, e); document.addEventListener("reset", o); const r = m.bind(null, e); window.addEventListener("resize", r); }, W = (e, t) => { const s = e.files; s.length > 1 ? t.innerHTML = Array.from(s).map((o) => o.name).join(", ") : s[0] && (t.innerHTML = s[0].name); }, G = (e) => { if (e.isInit) return; e.isInit = !0; const t = e.querySelector('input[type="file"]'), s = e.querySelector(".form-file-path"); t.handleRef = W.bind(null, t, s), t.validateRef = C.bind(null, t), t.addEventListener("change", t.handleRef), t.addEventListener("input", t.validateRef), t.addEventListener("change", t.validateRef); }, J = () => { const e = Array.from(document.querySelectorAll(".form-file")); try { e.forEach(G); } 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( (o, r) => (r.isInit ? o.detectInputs.push(r) : o.setupInputs.push(r), o), { setupInputs: [], detectInputs: [] } ); J(); try { t.length > 0 && U(t), s.length > 0 && m(s); } catch (o) { console.error("[Axentix] Material forms error", o); } }; document.addEventListener("DOMContentLoaded", () => S()); const K = { updateInputs: S, validate: N, resetValidation: H }; let d = "system", i = "", h = !1; const Q = () => { h = !0, M(); }, X = () => h = !1, u = (e = "system") => { h && (d = e, e === "system" && (e = O() ? "dark" : "light", localStorage.removeItem("ax-theme")), i && document.documentElement.classList.remove(i), i = `theme-${e}`, document.documentElement.classList.add(i), K.updateInputs(), $(document.documentElement, "theme.change", { theme: i }), d !== "system" && localStorage.setItem("ax-theme", i)); }, M = () => { const e = localStorage.getItem("ax-theme"); u(e ? e.replace("theme-", "") : d); }, Y = () => { window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => d === "system" && u("system")), M(); }; document.addEventListener("DOMContentLoaded", Y); const Z = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, disable: X, enable: Q, get enabled() { return h; }, get theme() { return i; }, get themeMode() { return d; }, toggle: u }, Symbol.toStringTag, { value: "Module" })); export { Z as Theme };