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