beercss 3.2.4 → 3.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -110,19 +110,19 @@ From jsdelivr.net.
110
110
 
111
111
  ```html
112
112
  // with html
113
- <link href="https://cdn.jsdelivr.net/npm/beercss@3.2.4/dist/cdn/beer.min.css" rel="stylesheet" />
114
- <script type="module" src="https://cdn.jsdelivr.net/npm/beercss@3.2.4/dist/cdn/beer.min.js"></script>
113
+ <link href="https://cdn.jsdelivr.net/npm/beercss@3.2.5/dist/cdn/beer.min.css" rel="stylesheet" />
114
+ <script type="module" src="https://cdn.jsdelivr.net/npm/beercss@3.2.5/dist/cdn/beer.min.js"></script>
115
115
  <script type="module" src="https://cdn.jsdelivr.net/npm/material-dynamic-colors@0.1.7/dist/cdn/material-dynamic-colors.min.js"></script>
116
116
  ```
117
117
 
118
118
  ```css
119
119
  // with css
120
- @import "https://cdn.jsdelivr.net/npm/beercss@3.2.4/dist/cdn/beer.min.css";
120
+ @import "https://cdn.jsdelivr.net/npm/beercss@3.2.5/dist/cdn/beer.min.css";
121
121
  ```
122
122
 
123
123
  ```js
124
124
  // with javascript
125
- import "https://cdn.jsdelivr.net/npm/beercss@3.2.4/dist/cdn/beer.min.js";
125
+ import "https://cdn.jsdelivr.net/npm/beercss@3.2.5/dist/cdn/beer.min.js";
126
126
  import "https://cdn.jsdelivr.net/npm/material-dynamic-colors@0.1.7/dist/cdn/material-dynamic-colors.min.js";
127
127
  ```
128
128
 
@@ -180,8 +180,8 @@ You can use this html to setup your project. See on [Codepen](https://codepen.io
180
180
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
181
181
  <meta name="google" content="notranslate">
182
182
  <title>Hello world</title>
183
- <link href="https://cdn.jsdelivr.net/npm/beercss@3.2.4/dist/cdn/beer.min.css" rel="stylesheet">
184
- <script type="module" src="https://cdn.jsdelivr.net/npm/beercss@3.2.4/dist/cdn/beer.min.js"></script>
183
+ <link href="https://cdn.jsdelivr.net/npm/beercss@3.2.5/dist/cdn/beer.min.css" rel="stylesheet">
184
+ <script type="module" src="https://cdn.jsdelivr.net/npm/beercss@3.2.5/dist/cdn/beer.min.js"></script>
185
185
  <script type="module" src="https://cdn.jsdelivr.net/npm/material-dynamic-colors@0.1.7/dist/cdn/material-dynamic-colors.min.js"></script>
186
186
  </head>
187
187
  <body class="light">
@@ -1 +1 @@
1
- export default(()=>{const v=globalThis;let m=null,$=null,A=null,C;const u={light:"",dark:""},B=async t=>await new Promise(e=>setTimeout(e,t)),I=()=>"fxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{const e=Math.random()*16|0;return(t==="x"?e:e&3|8).toString(16)}),g=(t,e)=>{try{return typeof t=="string"?(e!=null?e:document).querySelector(t):t}catch{}},f=(t,e)=>{try{return typeof t=="string"?(e!=null?e:document).querySelectorAll(t):t}catch{}},c=(t,e)=>t==null?void 0:t.classList.contains(e),x=(t,e)=>(t==null?void 0:t.tagName.toLowerCase())===e,k=(t,e)=>(t==null?void 0:t.type.toLowerCase())===e,y=(t,e)=>{t==null||t.classList.add(e)},s=(t,e)=>{t==null||t.classList.remove(e)},h=(t,e,n)=>{t.addEventListener(e,n,!0)},W=(t,e,n)=>{t.removeEventListener(e,n,!0)},j=(t,e)=>e==null?void 0:e.parentNode.insertBefore(t,e),N=t=>t==null?void 0:t.previousElementSibling,O=t=>t==null?void 0:t.nextElementSibling,b=t=>t==null?void 0:t.parentElement,R=t=>{const e=document.createElement("div");for(const n in t)e[n]=t[n];return e},V=(t,e)=>{if(t.offsetWidth>0)return t.offsetWidth;if(!C){const n=document.createElement("canvas");n.style.display="none",document.body.append(n),C=n.getContext("2d")}return C.font=e,C.measureText(t.textContent).width},L=t=>{const e=t;k(e,"number")&&!e.value&&(e.value="");const n=b(t),r=g("label",n),o=c(n,"border")&&!c(n,"fill");if(document.activeElement===t||e.value||g("[selected]",e)||k(e,"date")||k(e,"time")){if(o&&r){let l=V(r,"0.75rem Arial"),a=c(r,"active")?l:Math.round(l/1.33);a=a/16;const d=c(n,"round")?1.25:.75,p=a+d+.5;e.style.clipPath=`polygon(0% 0%, ${d}rem 0%, ${d}rem 0.5rem, ${p}rem 0.5rem, ${p}rem 0%, 100% 0%, 100% 100%, 0% 100%)`}else e.style.clipPath="";y(r,"active")}else s(r,"active"),e.style.clipPath="";t.getAttribute("data-ui")&&M(t)},Z=t=>{const e=t.currentTarget;x(e,"input")||M(e)},z=t=>{const e=t.currentTarget,n=g("input:not([type=file], [type=checkbox], [type=radio]), select, textarea",b(e));n&&n.focus()},H=t=>{const e=t.currentTarget;L(e)},K=t=>{const e=t.currentTarget;L(e)},F=t=>{const e=t.currentTarget;f("menu.active").forEach(r=>s(r,"active")),W(e,"click",F)},G=t=>{const e=t.currentTarget;s(e,"active"),m&&clearTimeout(m)},J=t=>{const e=t.currentTarget;P(e)},Q=t=>{const e=t.currentTarget;P(e,t)},U=t=>{const e=t.currentTarget;_(e)},S=()=>{$&&clearTimeout($),$=setTimeout(()=>{w()},180)},P=(t,e)=>{if(e){if(e.key!=="Enter")return;const o=e.currentTarget,i=O(o);return!i||!k(i,"file")?void 0:i.click()}const n=t,r=N(t);!r||!k(r,"text")||(r.value=Array.from(n.files).map(o=>o.name).join(", "),r.readOnly=!0,r.addEventListener("keydown",Q),L(r))},_=t=>{const e=b(t),n=g("span",e),r=f("input",e),o=g(".tooltip",e);if(!r.length||!n)return;const i=[],l=[];for(let E=0;E<r.length;E++){const D=parseFloat(r[E].min||"0"),ct=parseFloat(r[E].max||"100"),q=parseFloat(r[E].value||"0"),st=(q-D)*100/(ct-D);i.push(st),l.push(q)}o&&o.textContent!=l.join()&&(o.innerHTML=l.join());let a=i[0],d=0,p=100-d-a;r.length>1&&(a=Math.abs(i[1]-i[0]),d=i[1]>i[0]?i[0]:i[1],p=100-d-a),n.style.left=`${d}%`,n.style.right=`${p}%`},M=(t,e,n)=>{if(e||(e=g(t.getAttribute("data-ui"))),x(e,"dialog"))return tt(t,e);if(x(e,"menu"))return Y(t,e);if(c(e,"toast"))return et(t,e,n);if(c(e,"page"))return X(t,e);if(c(e,"progress"))return nt(e,n);if(T(t),c(e,"active"))return s(e,"active");y(e,"active")},T=t=>{const e=b(t);if(!c(e,"tabs"))return;f("a",e).forEach(r=>s(r,"active")),y(t,"active")},X=(t,e)=>{T(t);const n=b(e);for(let r=0;r<n.children.length;r++)c(n.children[r],"page")&&s(n.children[r],"active");y(e,"active")},Y=(t,e)=>{if(T(t),c(e,"active"))return s(e,"active");f("menu.active").forEach(r=>s(r,"active")),y(e,"active"),h(document.body,"click",F)},tt=async(t,e)=>{T(t);let n=N(e);const r=e,o=c(e,"active")||r.open,i=c(e,"modal"),l=b(e),a=x(l,"nav");c(n,"overlay")||(n=R({className:"overlay"}),j(n,e),await B(90)),n.onclick=()=>{i||(s(t,"active"),s(e,"active"),s(n,"active"),r.close())},a&&f("dialog, a, .overlay",l).forEach(p=>{s(p,"active"),p.open&&p.close()}),o?(s(t,"active"),s(n,"active"),s(e,"active"),r.close()):(!x(t,"button")&&!c(t,"button")&&!c(t,"chip")&&y(t,"active"),y(n,"active"),y(e,"active"),i?r.showModal():r.show())},et=(t,e,n)=>{T(t),f(".toast.active").forEach(o=>s(o,"active")),y(e,"active"),h(e,"click",G),m&&clearTimeout(m),n!==-1&&(m=setTimeout(()=>{s(e,"active")},n!=null?n:6e3))},nt=(t,e)=>{const n=t;if(c(n,"left")){n.style.clipPath=`polygon(0% 0%, 0% 100%, ${e}% 100%, ${e}% 0%)`;return}if(c(n,"top")){n.style.clipPath=`polygon(0% 0%, 100% 0%, 100% ${e}%, 0% ${e}%)`;return}if(c(n,"right")){n.style.clipPath=`polygon(100% 0%, 100% 100%, ${100-e}% 100%, ${100-e}% 0%)`;return}c(n,"bottom")&&(n.style.clipPath=`polygon(0% 100%, 100% 100%, 100% ${100-e}%, 0% ${100-e}%)`)},rt=()=>{if(u.light&&u.dark)return u;const t=document.createElement("body");t.className="light",document.body.appendChild(t);const e=document.createElement("body");e.className="dark",document.body.appendChild(e);const n=getComputedStyle(t),r=getComputedStyle(e),o=["--primary","--on-primary","--primary-container","--on-primary-container","--secondary","--on-secondary","--secondary-container","--on-secondary-container","--tertiary","--on-tertiary","--tertiary-container","--on-tertiary-container","--error","--on-error","--error-container","--on-error-container","--background","--on-background","--surface","--on-surface","--outline","--surface-variant","--on-surface-variant","--inverse-surface","--inverse-on-surface","--inverse-primary","--inverse-on-primary"];for(let i=0;i<o.length;i++)u.light+=o[i]+":"+n.getPropertyValue(o[i])+";",u.dark+=o[i]+":"+r.getPropertyValue(o[i])+";";return document.body.removeChild(t),document.body.removeChild(e),u},at=t=>{if(!t||!v.materialDynamicColors)return rt();const e=/dark/i.test(document.body.className)?"dark":"light";return(t==null?void 0:t.light)&&(t==null?void 0:t.dark)?(u.light=t.light,u.dark=t.dark,document.body.setAttribute("style",t[e]),t):v.materialDynamicColors(t).then(n=>{const r=o=>{let i="";for(const l in o){const a=l.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g,"$1-$2").toLowerCase(),d=o[l];i+="--"+a+":"+d+";"}return i};return u.light=r(n.light),u.dark=r(n.dark),document.body.setAttribute("style",u[e]),u})},it=t=>t?(document.body.classList.remove("light","dark"),document.body.classList.add(t),v.materialDynamicColors&&document.body.setAttribute("style",u[t]),t):/dark/i.test(document.body.className)?"dark":"light",ot=()=>{if(!A)return A=new MutationObserver(S),A.observe(document.body,{childList:!0,subtree:!0}),S()},w=(t,e)=>{if(t){if(t==="setup")return void ot();if(t==="guid")return I();if(t==="mode")return it(e);if(t==="theme")return at(e);const a=g(t),d=g("[data-ui='#"+a.id+"']");M(d,a,e)}f("[data-ui]").forEach(a=>h(a,"click",Z)),f(".field > label").forEach(a=>h(a,"click",z)),f(".field > input:not([type=file], [type=checkbox], [type=radio]), .field > select, .field > textarea").forEach(a=>{h(a,"focus",H),h(a,"blur",K),L(a)}),f(".field > input[type=file]").forEach(a=>{h(a,"change",J),P(a)}),f(".slider > input[type=range]").forEach(a=>{h(a,"input",U),_(a)})};return v.addEventListener&&v.addEventListener("load",()=>w("setup")),v.beercss=w,v.ui=w,v.ui})();
1
+ export default(()=>{const v=globalThis;let m=null,A=null,$=null,E;const l={light:"",dark:""};async function I(t){return await new Promise(n=>setTimeout(n,t))}function W(){return"fxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{const n=Math.random()*16|0;return(t==="x"?n:n&3|8).toString(16)})}function y(t,n){try{return typeof t=="string"?(n!=null?n:document).querySelector(t):t}catch{}}function d(t,n){try{return typeof t=="string"?(n!=null?n:document).querySelectorAll(t):t}catch{}}function c(t,n){return t==null?void 0:t.classList.contains(n)}function C(t,n){return(t==null?void 0:t.tagName.toLowerCase())===n}function x(t,n){return(t==null?void 0:t.type.toLowerCase())===n}function p(t,n){t==null||t.classList.add(n)}function u(t,n){t==null||t.classList.remove(n)}function h(t,n,e){t.addEventListener(n,e,!0)}function j(t,n,e){t.removeEventListener(n,e,!0)}function O(t,n){return n==null?void 0:n.parentNode.insertBefore(t,n)}function N(t){return t==null?void 0:t.previousElementSibling}function R(t){return t==null?void 0:t.nextElementSibling}function b(t){return t==null?void 0:t.parentElement}function V(t){const n=document.createElement("div");for(const e in t)n[e]=t[e];return n}function Z(t,n){if(t.offsetWidth>0)return t.offsetWidth;if(!E){const e=document.createElement("canvas");e.style.display="none",document.body.append(e),E=e.getContext("2d")}return E.font=n,E.measureText(t.textContent).width}function L(t){const n=t;x(n,"number")&&!n.value&&(n.value="");const e=b(t),r=y("label",e),a=c(e,"border")&&!c(e,"fill");if(document.activeElement===t||n.value||y("[selected]",n)||x(n,"date")||x(n,"time")){if(a&&r){const s=Z(r,"0.75rem Arial");let o=c(r,"active")?s:Math.round(s/1.33);o=o/16;const f=c(e,"round")?1.25:.75,g=o+f+.5;n.style.clipPath=`polygon(0% 0%, ${f}rem 0%, ${f}rem 0.5rem, ${g}rem 0.5rem, ${g}rem 0%, 100% 0%, 100% 100%, 0% 100%)`}else n.style.clipPath="";p(r,"active")}else u(r,"active"),n.style.clipPath="";t.getAttribute("data-ui")&&M(t)}function z(t){const n=t.currentTarget;M(n,null,null,t)}function H(t){const n=t.currentTarget,e=y("input:not([type=file], [type=checkbox], [type=radio]), select, textarea",b(n));e&&e.focus()}function K(t){const n=t.currentTarget;L(n)}function G(t){const n=t.currentTarget;L(n)}function S(t){j(document.body,"click",S);const n=t.target;d("menu.active").forEach(r=>F(n,r,t))}function J(t){const n=t.currentTarget;u(n,"active"),m&&clearTimeout(m)}function Q(t){const n=t.currentTarget;P(n)}function U(t){const n=t.currentTarget;P(n,t)}function X(t){const n=t.currentTarget;D(n)}function _(){A&&clearTimeout(A),A=setTimeout(()=>{w()},180)}function P(t,n){if(n){if(n.key!=="Enter")return;const a=n.currentTarget,i=R(a);return!i||!x(i,"file")?void 0:i.click()}const e=t,r=N(t);!r||!x(r,"text")||(r.value=Array.from(e.files).map(a=>a.name).join(", "),r.readOnly=!0,r.addEventListener("keydown",U),L(r))}function D(t){const n=b(t),e=y("span",n),r=d("input",n),a=y(".tooltip",n);if(!r.length||!e)return;const i=[],s=[];for(let T=0;T<r.length;T++){const q=parseFloat(r[T].min||"0"),ct=parseFloat(r[T].max||"100"),B=parseFloat(r[T].value||"0"),ut=(B-q)*100/(ct-q);i.push(ut),s.push(B)}a&&a.textContent!==s.join()&&(a.innerHTML=s.join());let o=i[0],f=0,g=100-f-o;r.length>1&&(o=Math.abs(i[1]-i[0]),f=i[1]>i[0]?i[0]:i[1],g=100-f-o),e.style.left=`${f}%`,e.style.right=`${g}%`}function M(t,n,e,r){if(n||(n=y(t.getAttribute("data-ui"))),C(n,"dialog"))return tt(t,n);if(C(n,"menu"))return F(t,n,r);if(c(n,"toast"))return nt(t,n,e);if(c(n,"page"))return Y(t,n);if(c(n,"progress"))return et(n,e);if(k(t),c(n,"active"))return u(n,"active");p(n,"active")}function k(t){const n=b(t);if(!c(n,"tabs"))return;d("a",n).forEach(r=>u(r,"active")),p(t,"active")}function Y(t,n){k(t);const e=b(n);for(let r=0;r<e.children.length;r++)c(e.children[r],"page")&&u(e.children[r],"active");p(n,"active")}function F(t,n,e){if(h(document.body,"click",S),e==null||e.stopPropagation(),k(t),c(n,"active")){if(!e)return u(n,"active");const a=e.target,i=y(a.getAttribute("data-ui")),s=a.closest("menu"),o=!y("menu",a.closest("[data-ui]"));return i&&i!==s?F(a,i):!i&&!o&&s?!1:u(n,"active")}d("menu.active").forEach(a=>u(a,"active")),p(n,"active")}async function tt(t,n){k(t);let e=N(n);const r=n,a=c(n,"active")||r.open,i=c(n,"modal"),s=b(n),o=C(s,"nav");c(e,"overlay")||(e=V({className:"overlay"}),O(e,n),await I(90)),e.onclick=()=>{i||(u(t,"active"),u(n,"active"),u(e,"active"),r.close())},o&&d("dialog, a, .overlay",s).forEach(g=>{u(g,"active"),g.open&&g.close()}),a?(u(t,"active"),u(e,"active"),u(n,"active"),r.close()):(!C(t,"button")&&!c(t,"button")&&!c(t,"chip")&&p(t,"active"),p(e,"active"),p(n,"active"),i?r.showModal():r.show())}function nt(t,n,e){k(t),d(".toast.active").forEach(a=>u(a,"active")),p(n,"active"),h(n,"click",J),m&&clearTimeout(m),e!==-1&&(m=setTimeout(()=>{u(n,"active")},e!=null?e:6e3))}function et(t,n){const e=t;if(c(e,"left")){e.style.clipPath=`polygon(0% 0%, 0% 100%, ${n}% 100%, ${n}% 0%)`;return}if(c(e,"top")){e.style.clipPath=`polygon(0% 0%, 100% 0%, 100% ${n}%, 0% ${n}%)`;return}if(c(e,"right")){e.style.clipPath=`polygon(100% 0%, 100% 100%, ${100-n}% 100%, ${100-n}% 0%)`;return}c(e,"bottom")&&(e.style.clipPath=`polygon(0% 100%, 100% 100%, 100% ${100-n}%, 0% ${100-n}%)`)}function rt(){if(l.light&&l.dark)return l;const t=document.createElement("body");t.className="light",document.body.appendChild(t);const n=document.createElement("body");n.className="dark",document.body.appendChild(n);const e=getComputedStyle(t),r=getComputedStyle(n),a=["--primary","--on-primary","--primary-container","--on-primary-container","--secondary","--on-secondary","--secondary-container","--on-secondary-container","--tertiary","--on-tertiary","--tertiary-container","--on-tertiary-container","--error","--on-error","--error-container","--on-error-container","--background","--on-background","--surface","--on-surface","--outline","--surface-variant","--on-surface-variant","--inverse-surface","--inverse-on-surface","--inverse-primary","--inverse-on-primary"];for(let i=0;i<a.length;i++)l.light+=a[i]+":"+e.getPropertyValue(a[i])+";",l.dark+=a[i]+":"+r.getPropertyValue(a[i])+";";return document.body.removeChild(t),document.body.removeChild(n),l}function it(t){if(!t||!v.materialDynamicColors)return rt();const n=/dark/i.test(document.body.className)?"dark":"light";return(t==null?void 0:t.light)&&(t==null?void 0:t.dark)?(l.light=t.light,l.dark=t.dark,document.body.setAttribute("style",t[n]),t):v.materialDynamicColors(t).then(e=>{const r=a=>{let i="";for(const s in a){const o=s.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g,"$1-$2").toLowerCase(),f=a[s];i+="--"+o+":"+f+";"}return i};return l.light=r(e.light),l.dark=r(e.dark),document.body.setAttribute("style",l[n]),l})}function at(t){return t?(document.body.classList.remove("light","dark"),document.body.classList.add(t),v.materialDynamicColors&&document.body.setAttribute("style",l[t]),t):/dark/i.test(document.body.className)?"dark":"light"}function ot(){$||($=new MutationObserver(_),$.observe(document.body,{childList:!0,subtree:!0}),_())}function w(t,n){if(t){if(t==="setup")return ot();if(t==="guid")return W();if(t==="mode")return at(n);if(t==="theme")return it(n);const o=y(t),f=y("[data-ui='#"+o.id+"']");M(f,o,n)}d("[data-ui]").forEach(o=>h(o,"click",z)),d(".field > label").forEach(o=>h(o,"click",H)),d(".field > input:not([type=file], [type=checkbox], [type=radio]), .field > select, .field > textarea").forEach(o=>{h(o,"focus",K),h(o,"blur",G),L(o)}),d(".field > input[type=file]").forEach(o=>{h(o,"change",Q),P(o)}),d(".slider > input[type=range]").forEach(o=>{h(o,"input",X),D(o)})}return v.addEventListener&&v.addEventListener("load",()=>w("setup")),v.beercss=w,v.ui=w,v.ui})();
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "author": "Everton and Leonardo",
3
3
  "description": "Build material design interfaces in record time... without stress for devs.",
4
4
  "homepage": "https://www.beercss.com/",
5
- "version": "3.2.4",
5
+ "version": "3.2.5",
6
6
  "name": "beercss",
7
7
  "license": "MIT",
8
8
  "type": "module",
package/src/cdn/beer.ts CHANGED
@@ -3,97 +3,97 @@ export default (() => {
3
3
  let _timeoutToast: ReturnType<typeof setTimeout> = null;
4
4
  let _timeoutMutation: ReturnType<typeof setTimeout> = null;
5
5
  let _mutation: MutationObserver = null;
6
- let _canvas:CanvasRenderingContext2D;
6
+ let _canvas: CanvasRenderingContext2D;
7
7
  const _lastTheme: IBeerCssTheme = {
8
8
  light: "",
9
9
  dark: "",
10
10
  };
11
11
 
12
- const wait = async (milliseconds: number) => {
12
+ async function wait (milliseconds: number) {
13
13
  return await new Promise((resolve: Function) => setTimeout(resolve, milliseconds));
14
- };
14
+ }
15
15
 
16
- const guid = (): string => {
16
+ function guid (): string {
17
17
  return "fxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c: string) => {
18
18
  const r = (Math.random() * 16) | 0;
19
19
  const v = c === "x" ? r : (r & 0x3) | 0x8;
20
20
  return v.toString(16);
21
21
  });
22
- };
22
+ }
23
23
 
24
- const query = (selector: string | Element, element?: Element): Element => {
24
+ function query (selector: string | Element, element?: Element): Element {
25
25
  try {
26
26
  return typeof selector === "string"
27
27
  ? (element ?? document).querySelector(selector)
28
28
  : selector;
29
29
  } catch {}
30
- };
30
+ }
31
31
 
32
- const queryAll = (selector: string | NodeListOf<Element>, element?: Element) => {
32
+ function queryAll (selector: string | NodeListOf<Element>, element?: Element) {
33
33
  try {
34
34
  return typeof selector === "string"
35
35
  ? (element ?? document).querySelectorAll(selector)
36
36
  : selector;
37
37
  } catch {}
38
- };
38
+ }
39
39
 
40
- const hasClass = (element: Element, name: string): boolean => {
40
+ function hasClass (element: Element, name: string): boolean {
41
41
  return element?.classList.contains(name);
42
- };
42
+ }
43
43
 
44
- const hasTag = (element: Element, name: string): boolean => {
44
+ function hasTag (element: Element, name: string): boolean {
45
45
  return element?.tagName.toLowerCase() === name;
46
- };
46
+ }
47
47
 
48
- const hasType = (element: HTMLInputElement, name: string): boolean => {
48
+ function hasType (element: HTMLInputElement, name: string): boolean {
49
49
  return element?.type.toLowerCase() === name;
50
- };
50
+ }
51
51
 
52
- const addClass = (element: Element, name: string) => {
52
+ function addClass (element: Element, name: string) {
53
53
  element?.classList.add(name);
54
- };
54
+ }
55
55
 
56
- const removeClass = (element: Element, name: string) => {
56
+ function removeClass (element: Element, name: string) {
57
57
  element?.classList.remove(name);
58
- };
58
+ }
59
59
 
60
- const on = (element: Element, name: string, callback: any) => {
60
+ function on (element: Element, name: string, callback: any) {
61
61
  element.addEventListener(name, callback, true);
62
- };
62
+ }
63
63
 
64
- const off = (element: Element, name: string, callback: any) => {
64
+ function off (element: Element, name: string, callback: any) {
65
65
  element.removeEventListener(name, callback, true);
66
- };
66
+ }
67
67
 
68
- const insertBefore = (newElement: Element, element: Element): Element => {
68
+ function insertBefore (newElement: Element, element: Element): Element {
69
69
  return element?.parentNode.insertBefore(newElement, element);
70
- };
70
+ }
71
71
 
72
- const prev = (element: Element): Element => {
72
+ function prev (element: Element): Element {
73
73
  return element?.previousElementSibling;
74
- };
74
+ }
75
75
 
76
- const next = (element: Element): Element => {
76
+ function next (element: Element): Element {
77
77
  return element?.nextElementSibling;
78
- };
78
+ }
79
79
 
80
- const parent = (element: Element): Element => {
80
+ function parent (element: Element): Element {
81
81
  return element?.parentElement;
82
- };
82
+ }
83
83
 
84
- const create = (json: any): HTMLElement => {
84
+ function create (json: any): HTMLElement {
85
85
  const element = document.createElement("div");
86
86
 
87
87
  for (const i in json) { element[i] = json[i]; }
88
88
 
89
89
  return element;
90
- };
90
+ }
91
91
 
92
- const textWidth = (element: HTMLElement, font: string): number => {
92
+ function textWidth (element: HTMLElement, font: string): number {
93
93
  if (element.offsetWidth > 0) return element.offsetWidth;
94
94
 
95
95
  if (!_canvas) {
96
- const canvasElement = document.createElement("canvas") as HTMLCanvasElement;
96
+ const canvasElement = document.createElement("canvas");
97
97
  canvasElement.style.display = "none";
98
98
  document.body.append(canvasElement);
99
99
  _canvas = canvasElement.getContext("2d");
@@ -103,7 +103,7 @@ export default (() => {
103
103
  return _canvas.measureText(element.textContent).width;
104
104
  }
105
105
 
106
- const updateInput = (target: Element) => {
106
+ function updateInput (target: Element) {
107
107
  const input = target as HTMLInputElement;
108
108
  if (hasType(input, "number") && !input.value) input.value = "";
109
109
 
@@ -114,7 +114,7 @@ export default (() => {
114
114
 
115
115
  if (toActive) {
116
116
  if (isBorder && label) {
117
- let labelWidth = textWidth(label, "0.75rem Arial");
117
+ const labelWidth = textWidth(label, "0.75rem Arial");
118
118
  let width = hasClass(label, "active") ? labelWidth : Math.round(labelWidth / 1.33);
119
119
  width = width / 16;
120
120
  const start = hasClass(parentTarget, "round") ? 1.25 : 0.75;
@@ -128,65 +128,64 @@ export default (() => {
128
128
  }
129
129
 
130
130
  if (target.getAttribute("data-ui")) open(target);
131
- };
131
+ }
132
132
 
133
- const onClickElement = (e: Event) => {
133
+ function onClickElement (e: Event) {
134
134
  const target = e.currentTarget as HTMLElement;
135
- if (hasTag(target, "input")) return;
136
- open(target);
137
- };
135
+ open(target, null, null, e);
136
+ }
138
137
 
139
- const onClickLabel = (e: Event) => {
138
+ function onClickLabel (e: Event) {
140
139
  const target = e.currentTarget as Element;
141
140
  const input = query("input:not([type=file], [type=checkbox], [type=radio]), select, textarea", parent(target)) as HTMLElement;
142
141
  if (input) input.focus();
143
- };
142
+ }
144
143
 
145
- const onFocusInput = (e: Event) => {
144
+ function onFocusInput (e: Event) {
146
145
  const target = e.currentTarget as Element;
147
146
  updateInput(target);
148
- };
147
+ }
149
148
 
150
- const onBlurInput = (e: Event) => {
149
+ function onBlurInput (e: Event) {
151
150
  const target = e.currentTarget as Element;
152
151
  updateInput(target);
153
- };
152
+ }
154
153
 
155
- const onClickDocument = (e: Event) => {
156
- const target = e.currentTarget as Element;
154
+ function onClickDocument (e: Event) {
155
+ off(document.body, "click", onClickDocument);
156
+ const target = e.target as Element;
157
157
  const menus = queryAll("menu.active");
158
- menus.forEach((x: Element) => removeClass(x, "active"));
159
- off(target, "click", onClickDocument);
160
- };
158
+ menus.forEach((x: Element) => menu(target, x, e));
159
+ }
161
160
 
162
- const onClickToast = (e: Event) => {
161
+ function onClickToast (e: Event) {
163
162
  const target = e.currentTarget as Element;
164
163
  removeClass(target, "active");
165
164
 
166
165
  if (_timeoutToast) clearTimeout(_timeoutToast);
167
- };
166
+ }
168
167
 
169
- const onChangeFile = (e: Event) => {
168
+ function onChangeFile (e: Event) {
170
169
  const target = e.currentTarget as HTMLInputElement;
171
170
  updateFile(target);
172
- };
171
+ }
173
172
 
174
- const onKeydownFile = (e: KeyboardEvent) => {
173
+ function onKeydownFile (e: KeyboardEvent) {
175
174
  const target = e.currentTarget as HTMLInputElement;
176
175
  updateFile(target, e);
177
- };
176
+ }
178
177
 
179
- const onInputRange = (e: Event) => {
178
+ function onInputRange (e: Event) {
180
179
  const target = e.currentTarget as HTMLInputElement;
181
180
  updateRange(target);
182
- };
181
+ }
183
182
 
184
- const onMutation = () => {
183
+ function onMutation () {
185
184
  if (_timeoutMutation) clearTimeout(_timeoutMutation);
186
185
  _timeoutMutation = setTimeout(() => { void ui(); }, 180);
187
- };
186
+ }
188
187
 
189
- const updateFile = (target: Element, e?: KeyboardEvent) => {
188
+ function updateFile (target: Element, e?: KeyboardEvent) {
190
189
  if (e) {
191
190
  if (e.key !== "Enter") return;
192
191
 
@@ -203,9 +202,9 @@ export default (() => {
203
202
  previousTarget.readOnly = true;
204
203
  previousTarget.addEventListener("keydown", onKeydownFile);
205
204
  updateInput(previousTarget);
206
- };
205
+ }
207
206
 
208
- const updateRange = (target: Element) => {
207
+ function updateRange (target: Element) {
209
208
  const parentTarget = parent(target) as HTMLElement;
210
209
  const bar = query("span", parentTarget) as HTMLElement;
211
210
  const inputs = queryAll("input", parentTarget) as NodeListOf<HTMLInputElement>;
@@ -223,7 +222,7 @@ export default (() => {
223
222
  values.push(value);
224
223
  }
225
224
 
226
- if (tooltip && tooltip.textContent != values.join()) tooltip.innerHTML = values.join();
225
+ if (tooltip && tooltip.textContent !== values.join()) tooltip.innerHTML = values.join();
227
226
 
228
227
  let percent = percents[0];
229
228
  let left = 0;
@@ -236,12 +235,12 @@ export default (() => {
236
235
 
237
236
  bar.style.left = `${left}%`;
238
237
  bar.style.right = `${right}%`;
239
- };
238
+ }
240
239
 
241
- const open = (from?: Element, to?: Element, options?: any): any => {
240
+ function open (from?: Element, to?: Element, options?: any, e?: Event): any {
242
241
  if (!to) to = query(from.getAttribute("data-ui"));
243
242
  if (hasTag(to, "dialog")) return dialog(from, to);
244
- if (hasTag(to, "menu")) return menu(from, to);
243
+ if (hasTag(to, "menu")) return menu(from, to, e);
245
244
  if (hasClass(to, "toast")) return toast(from, to, options);
246
245
  if (hasClass(to, "page")) return page(from, to);
247
246
  if (hasClass(to, "progress")) return progress(to, options);
@@ -251,9 +250,9 @@ export default (() => {
251
250
  if (hasClass(to, "active")) return removeClass(to, "active");
252
251
 
253
252
  addClass(to, "active");
254
- };
253
+ }
255
254
 
256
- const tab = (from: Element) => {
255
+ function tab (from: Element) {
257
256
  const container = parent(from);
258
257
  if (!hasClass(container, "tabs")) return;
259
258
 
@@ -261,30 +260,41 @@ export default (() => {
261
260
  tabs.forEach((x: Element) => removeClass(x, "active"));
262
261
 
263
262
  addClass(from, "active");
264
- };
263
+ }
265
264
 
266
- const page = (from: Element, to: Element) => {
265
+ function page (from: Element, to: Element) {
267
266
  tab(from);
268
267
 
269
268
  const container = parent(to);
270
269
  for (let i = 0; i < container.children.length; i++) { if (hasClass(container.children[i], "page")) removeClass(container.children[i], "active"); }
271
270
 
272
271
  addClass(to, "active");
273
- };
272
+ }
274
273
 
275
- const menu = (from: Element, to: Element) => {
274
+ function menu (from: Element, to: Element, e?: Event) {
275
+ on(document.body, "click", onClickDocument);
276
+ e?.stopPropagation();
276
277
  tab(from);
277
278
 
278
- if (hasClass(to, "active")) return removeClass(to, "active");
279
+ if (hasClass(to, "active")) {
280
+ if (!e) return removeClass(to, "active");
281
+
282
+ const trustedFrom = e.target as Element;
283
+ const trustedTo = query(trustedFrom.getAttribute("data-ui"));
284
+ const trustedMenu = trustedFrom.closest("menu");
285
+ const trustedActive = !query("menu", trustedFrom.closest("[data-ui]"));
286
+
287
+ if (trustedTo && trustedTo !== trustedMenu) return menu(trustedFrom, trustedTo);
288
+ if (!trustedTo && !trustedActive && trustedMenu) return false;
289
+ return removeClass(to, "active");
290
+ }
279
291
 
280
292
  const menus = queryAll("menu.active");
281
293
  menus.forEach((x: Element) => removeClass(x, "active"));
282
-
283
294
  addClass(to, "active");
284
- on(document.body, "click", onClickDocument);
285
- };
295
+ }
286
296
 
287
- const dialog = async (from: Element, to: Element) => {
297
+ async function dialog (from: Element, to: Element) {
288
298
  tab(from);
289
299
 
290
300
  let overlay = prev(to) as HTMLElement;
@@ -330,9 +340,9 @@ export default (() => {
330
340
  if (isModal) target.showModal();
331
341
  else target.show();
332
342
  }
333
- };
343
+ }
334
344
 
335
- const toast = (from: Element, to: Element, milliseconds?: number) => {
345
+ function toast (from: Element, to: Element, milliseconds?: number) {
336
346
  tab(from);
337
347
 
338
348
  const elements = queryAll(".toast.active");
@@ -347,9 +357,9 @@ export default (() => {
347
357
  _timeoutToast = setTimeout(() => {
348
358
  removeClass(to, "active");
349
359
  }, milliseconds ?? 6000);
350
- };
360
+ }
351
361
 
352
- const progress = (to: Element, percentage: number) => {
362
+ function progress (to: Element, percentage: number) {
353
363
  const element = to as HTMLElement;
354
364
 
355
365
  if (hasClass(element, "left")) {
@@ -368,9 +378,9 @@ export default (() => {
368
378
  }
369
379
 
370
380
  if (hasClass(element, "bottom")) element.style.clipPath = `polygon(0% 100%, 100% 100%, 100% ${100 - percentage}%, 0% ${100 - percentage}%)`;
371
- };
381
+ }
372
382
 
373
- const lastTheme = (): IBeerCssTheme => {
383
+ function lastTheme (): IBeerCssTheme {
374
384
  if (_lastTheme.light && _lastTheme.dark) return _lastTheme;
375
385
 
376
386
  const light = document.createElement("body");
@@ -392,9 +402,9 @@ export default (() => {
392
402
  document.body.removeChild(light);
393
403
  document.body.removeChild(dark);
394
404
  return _lastTheme;
395
- };
405
+ }
396
406
 
397
- const theme = (source?: IBeerCssTheme | any): IBeerCssTheme | Promise<IBeerCssTheme> => {
407
+ function theme (source?: IBeerCssTheme | any): IBeerCssTheme | Promise<IBeerCssTheme> {
398
408
  if (!source || !_window.materialDynamicColors) return lastTheme();
399
409
 
400
410
  const mode = /dark/i.test(document.body.className) ? "dark" : "light";
@@ -421,26 +431,26 @@ export default (() => {
421
431
  document.body.setAttribute("style", _lastTheme[mode]);
422
432
  return _lastTheme;
423
433
  });
424
- };
434
+ }
425
435
 
426
- const mode = (value: string | any): string => {
436
+ function mode (value: string | any): string {
427
437
  if (!value) return /dark/i.test(document.body.className) ? "dark" : "light";
428
438
  document.body.classList.remove("light", "dark");
429
439
  document.body.classList.add(value);
430
440
  if (_window.materialDynamicColors) document.body.setAttribute("style", _lastTheme[value]);
431
441
  return value;
432
- };
442
+ }
433
443
 
434
- const setup = () => {
444
+ function setup () {
435
445
  if (_mutation) return;
436
446
  _mutation = new MutationObserver(onMutation);
437
447
  _mutation.observe(document.body, { childList: true, subtree: true });
438
- return onMutation();
439
- };
448
+ onMutation();
449
+ }
440
450
 
441
- const ui = (selector?: string | Element, options?: string | number | IBeerCssTheme): string | IBeerCssTheme | Promise<IBeerCssTheme> => {
451
+ function ui (selector?: string | Element, options?: string | number | IBeerCssTheme): string | IBeerCssTheme | Promise<IBeerCssTheme> {
442
452
  if (selector) {
443
- if (selector === "setup") return void setup();
453
+ if (selector === "setup") return setup() as undefined;
444
454
  if (selector === "guid") return guid();
445
455
  if (selector === "mode") return mode(options);
446
456
  if (selector === "theme") return theme(options);
@@ -474,7 +484,7 @@ export default (() => {
474
484
  on(x, "input", onInputRange);
475
485
  updateRange(x);
476
486
  });
477
- };
487
+ }
478
488
 
479
489
  if (_window.addEventListener) _window.addEventListener("load", () => ui("setup"));
480
490
  _window.beercss = ui;