UNPKG

@zenithui/utils

Version:

A collection of utility functions and hooks to simplify development in the ZenithUI ecosystem.

164 lines (160 loc) 18.3 kB
import*as e from"react";import*as t from"react-dom";function n(){let[t,n]=(0,e.useState)(null);return{copiedText:t,copyToClipboard:(0,e.useCallback)(async(e,t=!1)=>{if(!navigator?.clipboard)return console.warn("Clipboard not supported"),!!t&&(function(e){let t=document.createElement("textarea");t.value=e,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t)}(e),n(e),!0);try{return await navigator.clipboard.writeText(e),n(e),!0}catch(e){return console.warn("Copy failed",e),!1}},[])}}let i="undefined"!=typeof window?e.useLayoutEffect:e.useEffect;function r(){let t=(0,e.useCallback)(()=>{let e=window.innerWidth;return e<480?"smallMobile":e>=480&&e<768?"largeMobile":e>=768&&e<1024?"tablet":"desktop"},[]),[n,r]=(0,e.useState)("smallMobile");return i(()=>{let e=()=>r(t);return window.addEventListener("resize",e),e(),()=>window.removeEventListener("resize",e)},[t]),n}let o=function(t,n,r,o){let a=(0,e.useRef)(n);i(()=>{a.current=n},[n]),(0,e.useEffect)(()=>{let e=r?.current??window;if(!e?.addEventListener)return;let n=e=>{a.current(e)};return e.addEventListener(t,n,o),()=>{e.removeEventListener(t,n,o)}},[t,r,o])};function a(t={}){let[n,i]=(0,e.useState)({loading:!0,accuracy:null,altitude:null,altitudeAccuracy:null,heading:null,latitude:null,longitude:null,speed:null,timestamp:null,error:null}),r=(0,e.useRef)(t);return(0,e.useEffect)(()=>{let e=({coords:e,timestamp:t})=>{i({loading:!1,timestamp:t,latitude:e.latitude,longitude:e.longitude,altitude:e.altitude,accuracy:e.accuracy,altitudeAccuracy:e.altitudeAccuracy,heading:e.heading,speed:e.speed})},t=e=>{i(t=>({...t,loading:!1,error:e}))};navigator.geolocation.getCurrentPosition(e,t,r.current);let n=navigator.geolocation.watchPosition(e,t,r.current);return()=>{navigator.geolocation.clearWatch(n)}},[]),n}function l(){let[t,n]=(0,e.useState)(!1),i=(0,e.useRef)(null),r=(0,e.useCallback)(()=>{n(!0)},[]),o=(0,e.useCallback)(()=>{n(!1)},[]);return[(0,e.useCallback)(e=>{i.current?.nodeType===Node.ELEMENT_NODE&&(i.current.removeEventListener("mouseenter",r),i.current.removeEventListener("mouseleave",o)),e?.nodeType===Node.ELEMENT_NODE&&(e.addEventListener("mouseenter",r),e.addEventListener("mouseleave",o)),i.current=e},[r,o]),t]}function c({threshold:t=0,root:n=null,rootMargin:i="0%",freezeOnceVisible:r=!1,initialIsIntersecting:o=!1,onChange:a}={}){let[l,s]=(0,e.useState)(null),[u,d]=(0,e.useState)(()=>({isIntersecting:o,entry:void 0})),p=(0,e.useRef)(null);p.current=a;let m=u.entry?.isIntersecting&&r;(0,e.useEffect)(()=>{let e;if(!l||!("IntersectionObserver"in window)||m)return;let o=new IntersectionObserver(t=>{let n=Array.isArray(o.thresholds)?o.thresholds:[o.thresholds];for(let i of t){let t=i.isIntersecting&&n.some(e=>i.intersectionRatio>=e);d({isIntersecting:t,entry:i}),p.current&&p.current(t,i),t&&r&&e&&(e(),e=void 0)}},{threshold:t,root:n,rootMargin:i});return o.observe(l),()=>{o.disconnect()}},[l,t,n,i,m,r]);let f=(0,e.useRef)(null);(0,e.useEffect)(()=>{!l&&u.entry?.target&&!r&&!m&&f.current!==u.entry.target&&(f.current=u.entry.target,d({isIntersecting:o,entry:void 0}))},[l,u.entry,r,m,o]);let h=[s,!!u.isIntersecting,u.entry];return h.ref=h[0],h.isIntersecting=h[1],h.entry=h[2],h}let s="undefined"==typeof window;function u(t,{defaultValue:n=!1,initializeWithValue:r=!0}={}){let o=e=>s?n:window.matchMedia(e).matches,[a,l]=(0,e.useState)(()=>r?o(t):n);function c(){l(o(t))}return i(()=>{let e=window.matchMedia(t);return c(),e.addListener?e.addListener(c):e.addEventListener("change",c),()=>{e.removeListener?e.removeListener(c):e.removeEventListener("change",c)}},[t]),a}function d(){let t=(0,e.useCallback)(()=>{let e;e="undefined"!=typeof window?localStorage.getItem("theme")??"":"system";let t=!1;"undefined"!=typeof document&&(t=document.body.classList.contains("dark")||document.getElementById("root")?.classList.contains("dark")||!1);let n=!1;return"system"!==e&&e?"dark"===e||t?"dark":"":("undefined"!=typeof window&&(n=window.matchMedia("(prefers-color-scheme: dark)").matches),t||n?"dark":"")},[]),[n,r]=(0,e.useState)("");return i(()=>{let e=()=>{r(t())},n=e=>{"system"!==localStorage.getItem("theme")&&localStorage.getItem("theme")||r(e.matches?"dark":"")};window.addEventListener("storage",e);let i=window.matchMedia("(prefers-color-scheme: dark)");i.addEventListener("change",n);let o=localStorage.setItem;return localStorage.setItem=(t,n)=>{o.call(localStorage,t,n),"theme"===t&&e()},e(),()=>{window.removeEventListener("storage",e),i.removeEventListener("change",n),localStorage.setItem=o}},[t]),n}function p(t){let n=(0,e.useRef)(t);n.current=t,(0,e.useEffect)(()=>()=>{n.current()},[])}let m="undefined"!=typeof window,f=()=>{if(m){let e="zenithui-theme-switch-base-style";if(!document.getElementById(e)){let t=document.createElement("style");t.id=e;let n=window.innerWidth>=3e3||window.innerHeight>=2e3;t.textContent=` ::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; ${n?"transform: translateZ(0);":""} } ${n?` ::view-transition-group(root), ::view-transition-image-pair(root), ::view-transition-old(root), ::view-transition-new(root) { backface-visibility: hidden; perspective: 1000px; transform: translate3d(0, 0, 0); } `:""} `,document.head.appendChild(t)}}},h=n=>{let{duration:i=750,easing:r="ease-in-out",pseudoElement:o="::view-transition-new(root)",globalClassName:a="dark",animationType:l="CIRCLE",blurAmount:c=2,styleId:s="zenithui-theme-switch-style",isDarkMode:u,rippleCount:d=3,splitDirection:p="vertical",pixelSize:h=10,glitchIntensity:w=5,onDarkModeChange:g}=n||{},y="undefined"!=typeof window&&(window.innerWidth>=3e3||window.innerHeight>=2e3)?Math.max(.8*i,500):i;(0,e.useEffect)(()=>{f()},[]);let[x,$]=(0,e.useState)(!!m&&"dark"===localStorage.getItem("theme")),v=u??x,E=e=>{let t="function"==typeof e?e(v):e;g?g(t):$(t)},b=(0,e.useRef)(null),M=e=>{let t="undefined"!=typeof window&&(window.innerWidth>=3e3||window.innerHeight>=2e3),n=`<filter id="blur"><feGaussianBlur stdDeviation="${e}" /></filter>`;return`url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="-50 -50 100 100"><defs>${n}</defs><circle cx="0" cy="0" r="${t?20:25}" fill="white" filter="url(%23blur)"/></svg>')`},k=async()=>{if(!b.current||!document.startViewTransition||window.matchMedia("(prefers-reduced-motion: reduce)").matches){E(e=>!e);return}let e=document.getElementById(s);e&&e.remove();let{top:n,left:i,width:a,height:u}=b.current.getBoundingClientRect(),m=i+a/2,f=n+u/2,g=Math.hypot(m,f),x=Math.hypot(window.innerWidth-m,f),$=Math.max(g,x,Math.hypot(m,window.innerHeight-f),Math.hypot(window.innerWidth-m,window.innerHeight-f)),v=Math.max(window.innerWidth,window.innerHeight)+200,k=window.innerWidth>=3e3||window.innerHeight>=2e3,C=k?2.5:4,I=k?Math.min(v*C,5e3):v*C;if("CIRCLE-BLUR"===l){let e=document.createElement("style");e.id=s;let t=Math.max(I,2.5*$);e.textContent=` ::view-transition-group(root) { animation-duration: ${y}ms; animation-timing-function: ${k?"cubic-bezier(0.2, 0, 0.2, 1)":"linear(0 0%, 0.2342 12.49%, 0.4374 24.99%,0.6093 37.49%, 0.6835 43.74%,0.7499 49.99%, 0.8086 56.25%,0.8593 62.5%, 0.9023 68.75%, 0.9375 75%,0.9648 81.25%, 0.9844 87.5%,0.9961 93.75%, 1 100%)"}; will-change: transform; } ::view-transition-new(root) { mask: ${M(c*(k?1.5:1.2))} 0 0 / 100% 100% no-repeat; mask-position: ${m}px ${f}px; animation: maskScale ${y}ms ${r}; transform-origin: ${m}px ${f}px; will-change: mask-size, mask-position; } ::view-transition-old(root), .dark::view-transition-old(root) { animation: maskScale ${y}ms ${r}; transform-origin: ${m}px ${f}px; z-index: -1; will-change: mask-size, mask-position; } @keyframes maskScale { 0% { mask-size: 0px; mask-position: ${m}px ${f}px; } 100% { mask-size: ${t}px; mask-position: ${m-t/2}px ${f-t/2}px; } } `,document.head.appendChild(e)}if(await document.startViewTransition(()=>{(0,t.flushSync)(()=>{E(e=>!e)})}).ready,"CIRCLE"===l&&document.documentElement.animate({clipPath:[`circle(0px at ${m}px ${f}px)`,`circle(${$}px at ${m}px ${f}px)`]},{duration:y,easing:r,pseudoElement:o}),"CIRCLE-BLUR"===l&&setTimeout(()=>{let e=document.getElementById(s);e&&e.remove()},y),"SWIPE"===l){let e=k?8:4;document.documentElement.animate({clipPath:[`polygon(0% 0%, ${e}px 0%, ${e}px 100%, 0% 100%)`,"polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)"]},{duration:y,easing:r,pseudoElement:o})}if("DIAMOND"===l){let e=Math.hypot(window.innerWidth,window.innerHeight);document.documentElement.animate({clipPath:[`polygon(${m}px ${f}px, ${m}px ${f}px, ${m}px ${f}px, ${m}px ${f}px)`,`polygon(${m}px ${f-e}px, ${m+e}px ${f}px, ${m}px ${f+e}px, ${m-e}px ${f}px)`]},{duration:y,easing:r,pseudoElement:o})}if("RIPPLE"===l){let e=document.createElement("style");e.id=s;let t=Array.from({length:d},(e,t)=>{let n=$*(1+.3*t);return` @keyframes ripple${t} { 0% { clip-path: circle(0px at ${m}px ${f}px); opacity: ${1-.2*t}; } 100% { clip-path: circle(${n}px at ${m}px ${f}px); opacity: 0; } } `}).join("\n");e.textContent=` ${t} ::view-transition-new(root) { animation: ripple0 ${y}ms ${r}; } `,document.head.appendChild(e),document.documentElement.animate({clipPath:[`circle(0px at ${m}px ${f}px)`,`circle(${$}px at ${m}px ${f}px)`]},{duration:y,easing:r,pseudoElement:o})}if("SHUTTER"===l){let e=1.5*$,t=(t,n)=>{let i=t+45,r=n?e:0,o=m+Math.cos(t*Math.PI/180)*r,a=f+Math.sin(t*Math.PI/180)*r,l=m+Math.cos(i*Math.PI/180)*r,c=f+Math.sin(i*Math.PI/180)*r;return`${m}px ${f}px, ${o}px ${a}px, ${l}px ${c}px`},n=Array.from({length:8},(e,n)=>t(45*n,!1)).join(", "),i=Array.from({length:8},(e,n)=>t(45*n,!0)).join(", ");document.documentElement.animate({clipPath:[`polygon(${n})`,`polygon(${i})`]},{duration:y,easing:"cubic-bezier(0.65, 0, 0.35, 1)",pseudoElement:o})}if("SPLIT"===l){let e=[];e="horizontal"===p?[`polygon(0% ${f/window.innerHeight*100}%, 100% ${f/window.innerHeight*100}%, 100% ${f/window.innerHeight*100}%, 0% ${f/window.innerHeight*100}%)`,"polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)"]:"vertical"===p?[`polygon(${m/window.innerWidth*100}% 0%, ${m/window.innerWidth*100}% 0%, ${m/window.innerWidth*100}% 100%, ${m/window.innerWidth*100}% 100%)`,"polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)"]:[`polygon(${m}px ${f}px, ${m}px ${f}px, ${m}px ${f}px)`,"polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)"],document.documentElement.animate({clipPath:e},{duration:y,easing:r,pseudoElement:o})}if("SPIRAL"===l){let e=document.createElement("style");e.id=s,Array.from({length:60},(e,t)=>{let n=t/60,i=6*n*Math.PI,r=n*$,o=m+Math.cos(i)*r,a=f+Math.sin(i)*r;return`${o}px ${a}px`}).join(", "),e.textContent=` @keyframes spiral { 0% { clip-path: circle(0px at ${m}px ${f}px); transform: rotate(0deg); } 100% { clip-path: circle(${$}px at ${m}px ${f}px); transform: rotate(1080deg); } } ::view-transition-new(root) { animation: spiral ${y}ms cubic-bezier(0.4, 0, 0.2, 1); transform-origin: ${m}px ${f}px; } `,document.head.appendChild(e)}if("PIXELATE"===l){let e=document.createElement("style");e.id=s;let t=Math.ceil(window.innerWidth/h),n=Math.ceil(window.innerHeight/h);e.textContent=` @keyframes pixelate { 0% { filter: blur(${h}px) brightness(0.5); transform: scale(0.9); } 50% { filter: blur(${h/2}px) brightness(0.75); } 100% { filter: blur(0px) brightness(1); transform: scale(1); } } ::view-transition-new(root) { animation: pixelate ${y}ms steps(${Math.min(t,n,20)}) forwards; } ::view-transition-old(root) { animation: pixelate ${y}ms steps(${Math.min(t,n,20)}) reverse; } `,document.head.appendChild(e)}if("WARP"===l){let e=document.createElement("style");e.id=s,e.textContent=` @keyframes warp { 0% { transform: perspective(1000px) rotateY(90deg) scale(0.5); filter: blur(10px); opacity: 0; } 50% { transform: perspective(1000px) rotateY(45deg) scale(0.75); filter: blur(5px); opacity: 0.5; } 100% { transform: perspective(1000px) rotateY(0deg) scale(1); filter: blur(0px); opacity: 1; } } ::view-transition-new(root) { animation: warp ${y}ms cubic-bezier(0.34, 1.56, 0.64, 1); transform-origin: center center; } `,document.head.appendChild(e)}if("CORNERS"===l){let e=[{x:0,y:0},{x:window.innerWidth,y:0},{x:window.innerWidth,y:window.innerHeight},{x:0,y:window.innerHeight}],t=Math.hypot(window.innerWidth,window.innerHeight)/1.5;e.map(e=>`circle(0px at ${e.x}px ${e.y}px)`).join(", "),e.map(e=>`circle(${t}px at ${e.x}px ${e.y}px)`).join(", "),document.documentElement.animate({clipPath:[`circle(0px at ${m}px ${f}px)`,`circle(${$}px at ${m}px ${f}px)`]},{duration:y,easing:"cubic-bezier(0.25, 0.46, 0.45, 0.94)",pseudoElement:o})}if("RANDOM_BLOCKS"===l){let e=document.createElement("style");e.id=s;let t=Math.ceil(window.innerWidth/50),n=Math.ceil(window.innerHeight/50);e.textContent=` @keyframes randomBlocks { 0% { clip-path: polygon(0% 0%, 0% 0%, 0% 0%, 0% 0%); } 100% { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); } } ::view-transition-new(root) { animation: randomBlocks ${y}ms steps(${Math.min(t*n,50)}) forwards; } `,document.head.appendChild(e)}if("GLITCH"===l){let e=document.createElement("style");e.id=s;let t=Array.from({length:10},(e,t)=>{let n=Math.random()*w-w/2;return`${10*t}% { transform: translate(${n}px, 0); }`}).join("\n");e.textContent=` @keyframes glitch { ${t} 100% { transform: translate(0, 0); } } @keyframes glitchRGB { 0%, 100% { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); filter: none; } 25% { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); filter: hue-rotate(90deg); } 50% { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); filter: hue-rotate(180deg); } 75% { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); filter: hue-rotate(270deg); } } ::view-transition-new(root) { animation: glitch ${.3*y}ms steps(20) 3, glitchRGB ${y}ms ease-in-out; } `,document.head.appendChild(e)}};return(0,e.useEffect)(()=>{v?(document.documentElement.classList.add(a),localStorage.theme="dark"):(document.documentElement.classList.remove(a),localStorage.theme="light")},[v,a]),{ref:b,toggleSwitchTheme:k,isDarkMode:v}};function w(t){let n=(0,e.useRef)(t);return(0,e.useEffect)(()=>{n.current=t},[t]),n.current}function g(t,n){let[i,r]=(0,e.useState)(t);return(0,e.useEffect)(()=>{let e=setTimeout(()=>r(t),n);return()=>clearTimeout(e)},[t,n]),i}function y(t,n){let[i,r]=(0,e.useState)(t);return null==i?[n,r]:[i,r]}function x(t){(0,e.useEffect)(()=>{document.title=t},[t])}function $(t){(0,e.useEffect)(()=>{let e=document.querySelector('link[rel~="icon"]');e?e.href=t:((e=document.createElement("link")).type="image/x-icon",e.rel="icon",e.href=t,document.head.appendChild(e))},[t])}function v(...e){return e.flat(Number.POSITIVE_INFINITY).filter(Boolean).map(e=>"object"!=typeof e||null===e||Array.isArray(e)?e:Object.entries(e).filter(([e,t])=>!!e&&!!t).map(([e])=>e).join(" ")).join(" ")}function E(e,t,n="asc"){return[...e].sort((e,i)=>{let r=e[t],o=i[t];return r<o?"asc"===n?-1:1:r>o?"asc"===n?1:-1:0})}function b(e,t){if(e===t)return!0;if("object"!=typeof e||"object"!=typeof t||null===e||null===t)return!1;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(Array.isArray(e)!==Array.isArray(t))return!1;let n=Object.keys(e),i=Object.keys(t);if(n.length!==i.length)return!1;for(let r of n)if(!i.includes(r)||!b(e[r],t[r]))return!1;return!0}function M(e,t){return e.reduce((e,n)=>{let i=String(n[t]);return e[i]=e[i]||[],e[i].push(n),e},{})}function k(e,t){let n=new Set;return e.filter(e=>{let i=e[t];return!n.has(i)&&(n.add(i),!0)})}function C(e,t){let n=null;return(...i)=>{n&&clearTimeout(n),n=setTimeout(()=>e(...i),t)}}function I(e,t){let n=0;return(...i)=>{let r=Date.now();r-n>=t&&(n=r,e(...i))}}function L(e){return JSON.parse(JSON.stringify(e,(e,t)=>t instanceof Map||t instanceof Set?void 0:t instanceof RegExp?{}:t))}function S(e,t){return t.reduce((t,n)=>(n in e&&(t[n]=e[n]),t),{})}function T(e,t){let n={...e};for(let e of t)delete n[e];return n}function R(e,t){return Math.floor(Math.random()*(t-e+1))+e}function B(e){return new Promise(t=>setTimeout(t,e))}function P(e,t=2){if(!e)return"0 Bytes";let n=Math.floor(Math.log(e)/Math.log(1024));return`${Number.parseFloat((e/1024**n).toFixed(t))} ${["Bytes","KB","MB","GB","TB"][n]}`}function A(){return crypto.randomUUID()}function W(e){return e.split(" ").map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLocaleLowerCase()).join(" ")}export{W as capitalize,L as cloneDeep,v as cn,C as debounce,b as deepEqual,P as formatBytes,M as groupBy,T as omit,S as pick,R as randomInt,B as sleep,E as sortByKey,I as throttle,k as uniqueByKey,n as useCopyToClipboard,g as useDebounce,y as useDefault,r as useDeviceType,x as useDocumentTitle,o as useEventListener,$ as useFavicon,a as useGeolocation,l as useHover,c as useIntersectionObserver,i as useIsomorphicLayoutEffect,u as useMediaQuery,w as usePrevious,d as useTheme,h as useThemeMode,p as useUnMount,A as uuid};