@zuzjs/hooks 0.1.2

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 ADDED
@@ -0,0 +1,44 @@
1
+ # @zuzjs/ui
2
+
3
+ The `@zuzjs/ui` library provides a collection of reusable components and blocks designed to streamline your development process. It also includes an automatic CSS generator to help you maintain consistent styling across your application.
4
+
5
+ ## Features
6
+
7
+ - **Components**: A variety of pre-built UI components to speed up your development.
8
+ - **Blocks**: Modular blocks that can be easily integrated into your projects.
9
+ - **Auto CSS Generator**: Automatically generates CSS to ensure consistent and maintainable styles.
10
+
11
+ ## Installation
12
+
13
+ To install the `@zuzjs/ui` library, use the following command:
14
+
15
+ ```bash
16
+ npm install @zuzjs/ui
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ Import the components and blocks you need and start building your UI:
22
+
23
+ ```javascript
24
+ import { Box, Button, Text } from '@zuzjs/ui';
25
+
26
+ function App() {
27
+ return (
28
+ <Box as={`w:100 h:100 bg:red`}>
29
+ <Button as={`s:18 bold tac`}>Click Me</Button>
30
+ <Text as={`s:18 tac`}>Hello World!</Text>
31
+ </Box>
32
+ );
33
+ }
34
+ ```
35
+
36
+ The auto CSS generator will handle the styling for you, ensuring a cohesive look and feel.
37
+
38
+ ## Documentation
39
+
40
+ Documention in progress.
41
+
42
+ ## License
43
+
44
+ This project is licensed under the MIT License.
package/dist/index.cjs ADDED
@@ -0,0 +1,8 @@
1
+ 'use strict';var react=require('react'),core=require('@zuzjs/core');/* ZuzJS UI CLI */
2
+ var _=(s=>(s.Circle="circle",s.Square="square",s))(_||{}),J=(t=>(t[t.Backspace=8]="Backspace",t[t.Tab=9]="Tab",t[t.Enter=13]="Enter",t[t.Shift=16]="Shift",t[t.Ctrl=17]="Ctrl",t[t.Alt=18]="Alt",t[t.PauseBreak=19]="PauseBreak",t[t.Command=19]="Command",t[t.CapsLock=20]="CapsLock",t[t.Escape=27]="Escape",t[t.Space=32]="Space",t[t.PageUp=33]="PageUp",t[t.PageDown=34]="PageDown",t[t.End=35]="End",t[t.Home=36]="Home",t[t.ArrowLeft=37]="ArrowLeft",t[t.ArrowUp=38]="ArrowUp",t[t.ArrowRight=39]="ArrowRight",t[t.ArrowDown=40]="ArrowDown",t[t.Insert=45]="Insert",t[t.Delete=46]="Delete",t[t.Digit0=48]="Digit0",t[t.Digit1=49]="Digit1",t[t.Digit2=50]="Digit2",t[t.Digit3=51]="Digit3",t[t.Digit4=52]="Digit4",t[t.Digit5=53]="Digit5",t[t.Digit6=54]="Digit6",t[t.Digit7=55]="Digit7",t[t.Digit8=56]="Digit8",t[t.Digit9=57]="Digit9",t[t.KeyA=65]="KeyA",t[t.KeyB=66]="KeyB",t[t.KeyC=67]="KeyC",t[t.KeyD=68]="KeyD",t[t.KeyE=69]="KeyE",t[t.KeyF=70]="KeyF",t[t.KeyG=71]="KeyG",t[t.KeyH=72]="KeyH",t[t.KeyI=73]="KeyI",t[t.KeyJ=74]="KeyJ",t[t.KeyK=75]="KeyK",t[t.KeyL=76]="KeyL",t[t.KeyM=77]="KeyM",t[t.KeyN=78]="KeyN",t[t.KeyO=79]="KeyO",t[t.KeyP=80]="KeyP",t[t.KeyQ=81]="KeyQ",t[t.KeyR=82]="KeyR",t[t.KeyS=83]="KeyS",t[t.KeyT=84]="KeyT",t[t.KeyU=85]="KeyU",t[t.KeyV=86]="KeyV",t[t.KeyW=87]="KeyW",t[t.KeyX=88]="KeyX",t[t.KeyY=89]="KeyY",t[t.KeyZ=90]="KeyZ",t[t.Numpad0=96]="Numpad0",t[t.Numpad1=97]="Numpad1",t[t.Numpad2=98]="Numpad2",t[t.Numpad3=99]="Numpad3",t[t.Numpad4=100]="Numpad4",t[t.Numpad5=101]="Numpad5",t[t.Numpad6=102]="Numpad6",t[t.Numpad7=103]="Numpad7",t[t.Numpad8=104]="Numpad8",t[t.Numpad9=105]="Numpad9",t[t.NumpadMultiply=106]="NumpadMultiply",t[t.NumpadAdd=107]="NumpadAdd",t[t.NumpadSubtract=109]="NumpadSubtract",t[t.NumpadDecimal=110]="NumpadDecimal",t[t.NumpadDivide=111]="NumpadDivide",t[t.F1=112]="F1",t[t.F2=113]="F2",t[t.F3=114]="F3",t[t.F4=115]="F4",t[t.F5=116]="F5",t[t.F6=117]="F6",t[t.F7=118]="F7",t[t.F8=119]="F8",t[t.F9=120]="F9",t[t.F10=121]="F10",t[t.F11=122]="F11",t[t.F12=123]="F12",t[t.NumLock=144]="NumLock",t[t.ScrollLock=145]="ScrollLock",t[t.Semicolon=186]="Semicolon",t[t.Equal=187]="Equal",t[t.Comma=188]="Comma",t[t.Minus=189]="Minus",t[t.Period=190]="Period",t[t.Slash=191]="Slash",t[t.Backquote=192]="Backquote",t[t.BracketLeft=219]="BracketLeft",t[t.Backslash=220]="Backslash",t[t.BracketRight=221]="BracketRight",t[t.Quote=222]="Quote",t))(J||{});var dt=({command:e="/",commands:o=[],cmd:s,ref:n})=>{let[r,u]=react.useState(-1),[f,p]=react.useState(false),[h,b]=react.useState({top:0,left:0}),w=react.useRef(null),m=x=>{let l=n.current;if(l&&f){let{value:c}=l;(r<0||r>=c.length||c[r]!==e)&&p(false);}},v=x=>{let l=n.current;if(!l)return;let{selectionStart:c}=l;if(x.key===e){u(c||-1);let i=S(l,c||-1);b({top:i.top+20,left:i.left}),p(true);}else x.key==="Escape"&&(x.preventDefault(),x.stopPropagation(),p(false));},g=x=>{let l=n.current;if(l){if(s)s(x,l);else {let{value:c,selectionStart:i}=l,a=c.slice(0,r)+x+c.slice(i||-1);l.value=a,l.setSelectionRange(r+x.length,r+x.length);let M=new Event("input",{bubbles:true});l.dispatchEvent(M);}p(false),l.focus();}},S=(x,l)=>{let c=document.createElement("canvas"),i=c.getContext("2d");if(!i)return {top:0,left:0};let a=window.getComputedStyle(x);i.font=`${a.fontSize} ${a.fontFamily}`;let E=x.value.substring(0,l).split(`
3
+ `),T=E[E.length-1],d=i.measureText(T).width,P=parseFloat(a.lineHeight)||parseFloat(a.fontSize)*1.2,D=(E.length-1)*P,k=parseFloat(a.paddingTop)||0,F=parseFloat(a.paddingLeft)||0,R=x.scrollTop;return c.remove(),{top:D-R+k,left:d+F}};return react.useEffect(()=>{let x=l=>{n.current&&w.current&&!n.current.contains(l.target)&&!w.current.contains(l.target)&&p(false);};return document.addEventListener("mousedown",x),()=>{document.removeEventListener("mousedown",x);}},[n]),{showDropdown:f,dropdownPosition:h,handleKeyDown:v,handleInput:m,handleCommandSelect:g,parentRef:w}},ht=dt;var vt=e=>{let{name:o,version:s,meta:n}=e,r=react.useRef(null),[u,f]=react.useState(null);react.useEffect(()=>{let l=indexedDB.open(o,+s.toString().replace(/\./g,""));return l.onupgradeneeded=c=>{let i=c.target.result;n.forEach(a=>{if(!i.objectStoreNames.contains(a.name)){let M=i.createObjectStore(a.name,a.config);a.schema.forEach(E=>{M.createIndex(E.name,E.key||E.name,{unique:E.unique||false});});}});},l.onsuccess=c=>{r.current=c.target.result;},l.onerror=()=>{f("Failed to open database");},()=>r.current?.close()},[o,s]);let p=()=>new Promise((l,c)=>{r.current&&l(r.current);let i=indexedDB.open(o,+s.toString().replace(/\./g,""));i.onsuccess=a=>{r.current=a.target.result,l(r.current);},i.onerror=a=>{c(["Failed to open database",a].join(`
4
+ `));};}),h=(l,c)=>({store:r.current.transaction(l,c).objectStore(l)});return {getAll:l=>new Promise((c,i)=>{p().then(a=>{let{store:M}=h(l,"readonly"),E=M.getAll();E.onsuccess=T=>{T.target.result==null&&i("Record not found"),c(T.target.result);},E.onerror=T=>{i(`SELECT Failed. ${T.target.result}`);};}).catch(a=>{console.log("[getAll]",a),i("Database either corrupted or not initialized");});}),getByID:(l,c)=>new Promise((i,a)=>{p().then(M=>{let{store:E}=h(l,"readonly"),T=E.get(c);T.onsuccess=d=>{d.target.result==null&&a("Record not found"),i(d.target.result);},T.onerror=d=>{a(`SELECT Failed. ${d.target.result}`);};}).catch(M=>{console.log("[getByID]",M),a("Database either corrupted or not initialized");});}),getStore:(l,c)=>new Promise((i,a)=>{p().then(M=>{let{store:E}=h(l,"readonly"),T=E.getAll();T.onsuccess=d=>{d.target.result==null&&a("Record not found"),i(d.target.result);},T.onerror=d=>{a(`SELECT Failed. ${d.target.result}`);};}).catch(M=>{a(M.message||"Database either corrupted or not initialized");});}),insert:(l,c,i)=>new Promise((a,M)=>{p().then(E=>{let{store:T}=h(l,"readwrite"),d=T.add(c,i);d.onsuccess=P=>{a(P.target.result);},d.onerror=P=>{M(`INSERTION Failed. ${P.target.result}`);};}).catch(E=>{M(E.message||"Database either corrupted or not initialized");});}),update:(l,c)=>new Promise((i,a)=>{p().then(M=>{let {store:E}=h(l,"readwrite"),d=E.put(c);d.onsuccess=P=>{i();},d.onerror=P=>{a(`UPDATE Failed. ${P.target.result}`);};}).catch(M=>{a(`UPDATE Failed. ${M}`);});}),update_one:(l,c,i)=>new Promise((a,M)=>{p().then(E=>{let{store:T}=h(l,"readwrite"),d=T.get(i);d.onsuccess=()=>{let P=d.result;if(!P){M(`Record with key ${i} not found.`);return}let D=T.put({...P,...c});D.onsuccess=()=>a(),D.onerror=k=>M(`Update failed. ${k.target.error}`);},d.onerror=P=>{M(`Failed to get existing record. ${P.target.error}`);};}).catch(E=>{M("Database either corrupted or not initialized");});}),remove:(l,c)=>new Promise((i,a)=>{p().then(M=>{let{store:E}=h(l,"readwrite"),T=E.delete(c);T.onsuccess=d=>{i();};}).catch(M=>{console.log(M),a(`Delete failed from ${l} with key: ${c}`);});}),error:u}},Mt=vt;var Tt=(e,o,s={})=>{let[n,r]=react.useState({top:0,left:0}),{offsetX:u=0,offsetY:f=0,overflow:p=true}=s,h=react.useRef(null),b=react.useCallback(()=>{let w=0,m=0;if(o)w=o.clientY+f,m=o.clientX+u;else if(e){let v=e.getBoundingClientRect();w=v.bottom+f,m=v.left+u;}if(p&&h.current){let v=h.current.getBoundingClientRect(),{innerWidth:g,innerHeight:S}=window;m+v.width>g&&(m=g-v.width-10),w+v.height>S&&(w=S-v.height-10);}r({top:w,left:m});},[o,e,u,f,p]);return react.useEffect(()=>(b(),window.addEventListener("resize",b),window.addEventListener("scroll",b),()=>{window.removeEventListener("resize",b),window.removeEventListener("scroll",b);}),[b]),{position:n,targetRef:h}},Lt=Tt;var Rt=e=>e%4===0&&e%100!==0||e%400===0,It=(e,o)=>{switch(e){case 1:return Rt(o)?29:28;case 3:case 5:case 8:case 10:return 30;default:return 31}},tt=(e,o)=>e.toLocaleString("default",{weekday:o}),et=(e,o)=>{let s=new Date;return s.setMonth(e),s.toLocaleString("default",{month:o})},Ft=(e=1,o,s)=>{let[n,r]=react.useState(new Date),u=()=>{r(m=>{let v=new Date(m);return v.setMonth(m.getMonth()+e),v});},f=()=>{r(m=>{let v=new Date(m);return v.setMonth(v.getMonth()-e),v});},p=It(n.getMonth(),n.getFullYear()),h=et(n.getMonth(),s||"long"),b=tt(n,o||"short"),w=Array.from({length:p},(m,v)=>{let g=new Date(n.getFullYear(),n.getMonth(),v+1);return {day:tt(g,o||"short"),date:g.getDate(),month:et(g.getMonth(),s||"long"),year:g.getFullYear()}});return {today:n,daysCount:p,month:h,day:b,days:w,next:u,prev:f}},Ot=Ft;var Nt=(e,o)=>{let s=react.useRef(null);return react.useCallback((...r)=>{s.current&&clearTimeout(s.current),s.current=setTimeout(()=>{e(...r);},o);},[e,o])},Wt=Nt;var yt=(e=100)=>{let[o,s]=react.useState(false);return react.useEffect(()=>{let n=setTimeout(()=>s(true),e);return ()=>clearTimeout(n)},[e]),o},nt=yt;var Xt=e=>{let[o,s]=react.useState({width:0,height:0,top:0,left:0,bottom:0,right:0,x:0,y:0}),n=()=>{if(e){let{width:r,height:u,top:f,left:p,bottom:h,right:b,x:w,y:m}=e.getBoundingClientRect();s({width:r,height:u,top:f,left:p,bottom:h,right:b,x:w,y:m});}else s({width:window.innerWidth,height:window.innerHeight,top:0,left:0,bottom:0,right:0,x:0,y:0});};return react.useEffect(()=>(n(),window.addEventListener("resize",n),()=>window.removeEventListener("resize",n)),[]),o},Z=Xt;var zt=()=>{let e=navigator.userAgent,o=/Mobi|Android/i.test(e),s=/Tablet|iPad/i.test(e),n=Z();return react.useEffect(()=>{},[]),{isMobile:o,isTablet:s,isDesktop:!o&&!s,...n}},Qt=zt;var jt=(e,o=false)=>(react.useEffect(()=>{if(e){if(!window.fbq){let u=document.createElement("script");u.async=true,u.src="https://connect.facebook.net/en_US/fbevents.js",document.head.appendChild(u),window._fbq=window._fbq||[],window.fbq=function(){window._fbq.push(arguments);},window.fbq("init",e),o&&window.fbq("set","debug",true);}window.fbq("track","PageView");}},[e,o]),{trackPageView:()=>{e&&window.fbq("track","PageView");},trackEvent:(u,f)=>{e&&window.fbq("track",u,f);},trackCustom:(u,f)=>{e&&window.fbq("trackCustom",u,f);}}),_t=jt;var Gt=e=>(react.useEffect(()=>{if(e){if(!window.gtag){let n=document.createElement("script");n.async=true,n.src=`https://www.googletagmanager.com/gtag/js?id=${e}`,document.head.appendChild(n),window.dataLayer=window.dataLayer||[],window.gtag=function(){window.dataLayer.push(arguments);},window.gtag("js",new Date);}window.gtag("config",e);}},[e]),{trackPageView:n=>{e&&window.gtag("config",e,{page_path:n||window.location.pathname});},trackEvent:(n,r)=>{e&&window.gtag("event",n,r);}}),Zt=Gt;var ee=(e,o,s)=>{let[n,r]=react.useState({loaded:false,error:null}),u=react.useRef(null);return react.useEffect(()=>{if(e&&e!==""){var f=new Image;o&&(f.crossOrigin=o),s&&(f.referrerPolicy=s),f.onload=()=>{u.current=f,r({loaded:true,error:null});},f.onerror=()=>{r({loaded:false,error:`Failed to load image at ${e}`});},f.src=e;}},[e]),[u.current?u.current.src:"",n.loaded,n.error]},ne=ee;var re=(e,o,s="circle",n=1)=>{let[r,u]=react.useState(false),[f,p]=react.useState({x:0,y:0}),[h,b]=react.useState(n),w=react.useRef(null),m=react.useRef(null),v=()=>{let c=m.current,i=c?.getContext("2d"),a=w.current;!c||!i||!a||(c.width=o,c.height=o,i.clearRect(0,0,o,o),i.globalAlpha=.5,i.drawImage(a,f.x,f.y,a.width*h,a.height*h),i.globalAlpha=1,i.save(),s==="circle"&&(i.beginPath(),i.arc(o/2,o/2,o/2,0,Math.PI*2),i.closePath(),i.clip()),i.drawImage(a,f.x,f.y,a.width*h,a.height*h),i.restore());};return react.useEffect(v,[h]),react.useEffect(()=>{if(e){let c=new Image;c.onload=()=>{w.current=c,v();},c.src=e;}},[e,f]),{canvasRef:m,crop:()=>{let c=m.current;return c?c.toDataURL("image/png"):null},setScale:b,handleMouseDown:()=>u(true),handleMouseUp:()=>u(false),handleMouseMove:c=>{!r||!w.current||p(i=>({x:i.x+c.movementX,y:i.y+c.movementY}));}}},se=re;var ae=(e,o={})=>{let[s,n]=react.useState(e&&e.length>0?new Array(e.length).fill(0):[]);return react.useEffect(()=>{if(!e||!e.length)return;let r=new IntersectionObserver(u=>{requestAnimationFrame(()=>{n(f=>{let p=[...f],h=false;return u.forEach(b=>{let w=e.findIndex(m=>m.current===b.target);w!==-1&&p[w]!==b.intersectionRatio&&(p[w]=b.intersectionRatio,h=true);}),h?p:f});});},{rootMargin:"200px",threshold:[1],...o});return e.forEach(u=>{u.current&&r.observe(u.current);}),()=>{e.forEach(u=>{u.current&&r.unobserve(u.current);});}},[e,o]),s},ce=ae;var it=(e,o,s,n=20)=>{if(!e||e.length===0||o<=0||s<=0)return "";let r=Math.min(...e.map(g=>g.x)),u=Math.max(...e.map(g=>g.x)),f=Math.min(...e.map(g=>g.y)),p=Math.max(...e.map(g=>g.y)),h=(o-2*n)/(u-r),b=(s-2*n)/(p-f),w=g=>{let S=(g.x-r)*h+n,x=s-((g.y-f)*b+n);return {x:S,y:x}},m=e.map(w),v="";if(m.length>0){v=`M ${m[0].x},${m[0].y}`;for(let g=0;g<m.length-1;g++){let S=m[g],x=m[g+1],l={x:(S.x+x.x)/2,y:S.y},c={x:(S.x+x.x)/2,y:x.y};v+=` C ${l.x},${l.y} ${c.x},${c.y} ${x.x},${x.y}`;}}return v},le=(e,o,s,n=20)=>{if(!e||e.length===0)return "";let r=it(e,o,s,n),u=Math.min(...e.map(m=>m.x)),f=Math.max(...e.map(m=>m.x)),p=(o-2*n)/(f-u),h=(e[0].x-u)*p+n,b=(e[e.length-1].x-u)*p+n,w=s-n;return `${r} L ${b},${w} L ${h},${w} Z`},me=(e,o={width:600,height:300},s=20)=>{let[n,r]=react.useState(""),[u,f]=react.useState("");return react.useEffect(()=>{let p=it(e,o.width,o.height,s);r(p);let h=le(e,o.width,o.height,s);f(h);},[e,o.width,o.height,s]),{pathD:n,areaPathD:u}},fe=me;var de=(e,o,s={childList:true,subtree:true})=>{let n=react.useRef(null);react.useEffect(()=>{if(e)return n.current=new MutationObserver(o),n.current.observe(e,s),()=>{n.current&&n.current.disconnect();}},[e,o,s]);},K=de;var we=()=>{let[e,o]=react.useState(null),s=()=>{o(navigator.onLine);};return react.useEffect(()=>(setTimeout(()=>o(navigator.onLine)),window.addEventListener("online",s),window.addEventListener("offline",s),()=>{window.removeEventListener("online",s),window.removeEventListener("offline",s);}),[]),e},xe=we;var Se=(e=15)=>{if(e<=0)throw new Error("intervalMinutes must be greater than 0");let o=b=>{let w=new Date(b),m=w.getMinutes(),v=m%e;return v===0?w.setMinutes(m+e):w.setMinutes(m+(e-v)),w.setSeconds(0),w.setMilliseconds(0),w},[s,n]=react.useState(()=>o(new Date));react.useEffect(()=>{let b=()=>{let v=o(new Date);v.getTime()!==s.getTime()&&n(v);};b();let w=setInterval(b,1e3);return ()=>clearInterval(w)},[e,s]);let r=new Date,u=Math.max(0,s.getTime()-r.getTime()),f=Math.floor(u/6e4),p=Math.floor(u%6e4/1e3),h=`${f}m ${p.toString().padStart(2,"0")}s`;return {minutes:f,seconds:p,formatted:h,nextBoundary:s}},Ee=Se;var Pe=e=>{let{vapidPublicKey:o,serviceWorkerPath:s="/sw.js",requestPermissionOnMount:n=false}=e,[r,u]=react.useState("default"),[f,p]=react.useState(null),[h,b]=react.useState(null),[w,m]=react.useState(null),[v,g]=react.useState(false),[S,x]=react.useState(null),[l,c]=react.useState(false),i=react.useCallback(async()=>{if(!l)return null;try{let d=await navigator.serviceWorker.register(s,{scope:"/",updateViaCache:"all"});return x(d),d}catch(d){return console.error("Service Worker registration failed:",d),m("Failed to register service worker"),null}},[s,l]),a=react.useCallback(async d=>{try{let P=await d.pushManager.getSubscription();return p(P),b(P?P.toJSON():null),P}catch(P){return console.error("Failed to get subscription:",P),m("Failed to get subscription"),null}},[]),M=react.useCallback(async()=>{if(!l||!S)return m("Push not supported or service worker not registered"),null;g(true),m(null);try{let d=await Notification.requestPermission();if(u(d),d!=="granted")return m("Permission not granted for notifications"),g(!1),null;let P=core.urlBase64ToUint8Array(o),D=await S.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:P});return p(D),b(D.toJSON()),g(!1),D}catch(d){return console.error("Subscription failed:",d),m(d.message||"Failed to subscribe"),g(false),null}},[l,S,o]),E=react.useCallback(async()=>{if(!f)return true;try{let d=await f.unsubscribe();return d&&(p(null),b(null)),d}catch(d){return console.error("Failed to unsubscribe:",d),false}},[f]),T=react.useCallback(async()=>{let d=await Notification.requestPermission();return u(d),d},[]);return react.useEffect(()=>{let d="PushManager"in window&&"serviceWorker"in navigator;if(c(d),!d){m("Push notifications not supported in this browser");return}let P=true;return (async()=>{let k=await i();!k||!P||(u(Notification.permission),await a(k),n&&Notification.permission==="default"&&await T());})(),()=>{P=false;}},[l,i,a,n,T]),react.useEffect(()=>{if(!("permissions"in navigator))return;let d=false;(async()=>{if(d)return;let D=await navigator.permissions.query({name:"notifications"});D.onchange=()=>{u(Notification.permission),Notification.permission==="denied"&&(d=true,E());};})();},[E]),{permission:r,subscription:f,subscriptionMeta:h,isSupported:l,subscribe:M,unsubscribe:E,requestPermission:T,error:w,isLoading:v}},Te=Pe;var Re=e=>{let[o,s]=react.useState({width:0,height:0,top:0,left:0});return react.useEffect(()=>{let n=e instanceof HTMLElement?e:e.current,r=f=>{for(let p of f){let{width:h,height:b,top:w,left:m}=p.contentRect;s({width:h,height:b,top:w,left:m});}},u=new ResizeObserver(r);return n&&u.observe(n),()=>{n&&u.unobserve(n);}},[e]),o},Ie=Re;var qe=(e,o={})=>{let s=react.useRef(null),n=react.useRef(null),r=react.useRef(null),u=react.useRef(null),f=react.useMemo(()=>e??1,[e]),p=react.useRef(false),h=react.useRef(false),b=react.useRef(0),w=react.useRef(0),m=react.useRef(0),v=react.useRef(0),g=react.useRef(null),S=react.useCallback(()=>{if(!n.current||!r.current||!u.current)return;let{clientHeight:D,scrollHeight:k,scrollTop:F,clientWidth:R,scrollWidth:W,scrollLeft:O}=n.current,N=Math.max(D/k*D,30),A=D-N,I=F/(k-D)*A;r.current.style.height=`${N}px`,r.current.style.transform=`translateY(${I}px)`,r.current.style.willChange="transform, height";let Y=Math.max(R/W*R,30),z=R-Y,ft=O/(W-R)*z;u.current.style.width=`${Y}px`,u.current.style.transform=`translateX(${ft}px)`,u.current.style.willChange="transform, width",k<=D&&s.current?s.current.classList.add("--no-y"):s.current&&s.current.classList.remove("--no-y"),W<=R&&s.current?s.current.classList.add("--no-x"):s.current&&s.current.classList.remove("--no-x");},[]),x=react.useCallback(()=>{g.current&&cancelAnimationFrame(g.current),g.current=requestAnimationFrame(()=>{if(S(),n.current){let{scrollTop:D,scrollHeight:k,clientHeight:F,scrollLeft:R,scrollWidth:W,clientWidth:O}=n.current,B=D/(k-F)*100,N=R/(W-O)*100;Object.keys(o).forEach(A=>{let I=parseFloat(A);Math.abs(B-I)<1&&o[I]?.(),Math.abs(N-I)<1&&o[I]?.();});}});},[S,o]),l=react.useCallback(()=>{n.current&&x();},[x]),c=D=>{p.current=true,w.current=D.clientY,m.current=n.current?.scrollTop||0,document.body.style.userSelect="none",s.current&&s.current?.classList.add("--scrolling");},i=D=>{h.current=true,b.current=D.clientX,v.current=n.current?.scrollLeft||0,document.body.style.userSelect="none",s.current&&s.current?.classList.add("--scrolling");},a=react.useCallback(D=>{if(!n.current||!p.current&&!h.current)return;let{clientHeight:k,scrollHeight:F,clientWidth:R,scrollWidth:W}=n.current;if(p.current){let O=F-k,B=r.current?.clientHeight||30,N=k-B,A=D.clientY-w.current,I=Math.min(Math.max(m.current+A/N*O,0),O);n.current.scrollTop=I;}if(h.current){let O=W-R,B=u.current?.clientWidth||30,N=R-B,A=D.clientX-b.current,I=Math.min(Math.max(v.current+A/N*O,0),O);n.current.scrollLeft=I;}},[]),M=()=>{p.current=false,h.current=false,document.body.style.userSelect="",s.current&&s.current?.classList.remove("--scrolling"),g.current&&cancelAnimationFrame(g.current);},E=()=>n.current?.scrollTo({top:0,behavior:"smooth"}),T=()=>n.current?.scrollTo({top:n.current.scrollHeight,behavior:"smooth"}),d=()=>n.current?.scrollTo({left:0,behavior:"smooth"}),P=()=>n.current?.scrollTo({left:n.current.scrollWidth,behavior:"smooth"});return react.useEffect(()=>{let D=n.current;if(!D)return;let k=F=>{if(!n.current)return;let{scrollTop:R,scrollHeight:W,clientHeight:O,scrollLeft:B,scrollWidth:N,clientWidth:A}=n.current,I=R,X=B,Y=false;if(Math.abs(F.deltaY)>Math.abs(F.deltaX)){let z=W-O;I=R+F.deltaY*f,I=Math.max(0,Math.min(I,z)),I!==R&&(n.current.scrollTop=I,Y=true);}else {let z=N-A;X=B+F.deltaX*f,X=Math.max(0,Math.min(X,z)),X!==B&&(n.current.scrollLeft=X,Y=true);}Y&&x();};return window.addEventListener("resize",x),D.addEventListener("scroll",l,{passive:true}),D.addEventListener("wheel",k,{passive:true}),document.addEventListener("mousemove",a),document.addEventListener("mouseup",M),x(),()=>{window.removeEventListener("resize",x),D.removeEventListener("scroll",l),D.removeEventListener("wheel",k),document.removeEventListener("mousemove",a),document.removeEventListener("mouseup",M),g.current&&cancelAnimationFrame(g.current);}},[l,a,x,f]),K(n.current,x),{rootRef:s,containerRef:n,thumbY:r,thumbX:u,scrollToTop:E,scrollToBottom:T,scrollToLeft:d,scrollToRight:P,onScrollY:c,onScrollX:i}},Be=qe;var Ae=(e,o)=>{let{lerpFactor:s=.1,x:n,y:r,xMultiplier:u=.25,yMultiplier:f=.25,scale:p,rotate:h}=o,b=react.useRef(0),w=react.useRef(0),m=react.useRef(0),v=react.useRef(0),g=react.useRef(performance.now()),S=react.useRef(null),x=react.useRef(false),l=react.useRef(0),c=.2;return react.useEffect(()=>{if(typeof window>"u")return;let i=()=>{let M=performance.now(),E=(M-g.current)/1e3;g.current=M;let T=v.current-m.current,d=T/E;if(m.current+=T*s,b.current=m.current,w.current=d,l.current+=(d-l.current)*s,e.current){let P=n?b.current*n*u:0,D=r?b.current*r*f:0,k=p?core.clamp(p.max-Math.abs(l.current)*p.factor,p.min,p.max):1,F=h?w.current*(h.multiplier??1)*(h.direction??1):0;e.current.style.transform=`
5
+ translate3d(${P}px, ${D}px, 0)
6
+ scale(${k})
7
+ rotate(${F}deg)
8
+ `.trim();}Math.abs(T)>c||Math.abs(d)>c?S.current=requestAnimationFrame(i):(x.current=false,S.current=null);},a=()=>{v.current=window.scrollY,x.current||(g.current=performance.now(),S.current=requestAnimationFrame(i),x.current=true);};return window.addEventListener("scroll",a,{passive:true}),()=>{window.removeEventListener("scroll",a),S.current&&cancelAnimationFrame(S.current);}},[s,n,r,u,f,p,h]),{position:b,velocity:w}},He=Ae;var $e=(e,o)=>{react.useEffect(()=>{let s=n=>{let r=[];n.ctrlKey&&r.push(17),n.shiftKey&&r.push(16),n.altKey&&r.push(18),n.metaKey&&r.push(19),r.push(n.keyCode),e.forEach(({keys:u,callback:f})=>{u.every(p=>r.includes(p))&&((o??true)&&n.preventDefault(),f(n));});};return window.addEventListener("keydown",s),()=>window.removeEventListener("keydown",s)},[e,o]);},Ue=$e;var Qe=e=>{let{apiUrl:o,onChange:s,onQueFinished:n}=e,r=react.useRef({que:[],index:-1,speed:0,stamp:null,token:null,status:0}),u=()=>s?.(b()),f=()=>{},p=()=>{r.current.stamp=Date.now();let g=b(),S=new FormData;S.append("ID",g.ID),S.append("dir",g.dir),S.append("server",g.server.ID),S.append("token",g.server.token),S.append("file",g.file),S.append("fs",g.file.size.toString()),r.current.cancelToken=core.getCancelToken(),core.withPost(`${r.current.que[r.current.index].server.uri}/receive`,S,86400,true,void 0,x=>{r.current.que[r.current.index].status=2,s?.({...b(),progress:x.progress||0});}).then(x=>{r.current.que[r.current.index].progress=1,r.current.que[r.current.index].status=4,r.current.status=0,u(),m();}).catch(x=>{r.current.que[r.current.index].status=-1,r.current.status=0,u(),m();});},h=g=>{r.current.que[r.current.index].status=1,u(),core.withPost(`${o}get_server`,{size:b().file.size}).then(S=>{r.current.que[r.current.index].server=S.server,r.current.que[r.current.index].status=2,u(),p();}).catch(S=>{r.current.que[r.current.index].status=-1,r.current.status=0,u(),m();});},b=()=>r.current.que[r.current.index],w=()=>r.current.que,m=()=>{r.current.status==0&&r.current.que.length-1>r.current.index?(r.current.status=2,r.current.index++,r.current.que[r.current.index].status=2,u(),r.current.que[r.current.index].remote?f():h()):n?.();};return {get:()=>r,getQue:w,addToQue:g=>{r.current.que.push({ID:core.uuid(12),file:g.file,dir:g.dir,remote:g.remote,progress:0,speed:0,eta:0,bytes:0,status:0,server:null}),m();}}},Ve=Qe;var $=new Map,H=new Map,j=new Map,je=(e,o)=>{let{onOpen:s,onClose:n,onRawMessage:r,onMessage:u,onError:f,reconnect:p=true}=o||{},[h,b]=react.useState(false),[w,m]=react.useState([]),v=c=>j.get(c)??2,g=c=>{let i=v(c),a=Math.min(i*2,60);return j.set(c,a),a*1e3},S=c=>{j.set(c,2);},x=react.useCallback(()=>{if($.has(e)){let i=$.get(e);i&&(i.onmessage=a=>{m(E=>[...E,a.data]),r?.(a);let M=JSON.parse(Buffer.isBuffer(a)?a.toString("utf8"):typeof a=="string"?a:a.data);u?.(M),H.get(e)?.forEach(E=>E(a));});return}let c=new WebSocket(e);$.set(e,c),H.set(e,[]),c.onopen=i=>{b(true),S(e),s?.(i);},c.onmessage=i=>{m(M=>[...M,i.data]),r?.(i);let a=JSON.parse(Buffer.isBuffer(i)?i.toString("utf8"):typeof i=="string"?i:i.data);u?.(a),H.get(e)?.forEach(M=>M(i));},c.onerror=i=>{f?.(i);},c.onclose=i=>{if(b(false),n?.(i),$.delete(e),H.delete(e),p&&i.code!==1e3){let a=g(e);console.log(`Reconnecting in ${a/1e3} seconds...`),setTimeout(()=>{$.has(e)||x();},a);}};},[e,s,n,u,f,p]);react.useEffect(()=>(x(),()=>{H.get(e)?.length===0&&($.get(e)?.close(),$.delete(e),H.delete(e),j.delete(e));}),[]),react.useEffect(()=>{let c=i=>m(a=>[...a,i.data]);return H.get(e)?.push(c),()=>{let i=H.get(e)||[];H.set(e,i.filter(a=>a!==c));}},[e]);let l=react.useCallback(c=>{let i=$.get(e);if(i&&i.readyState===WebSocket.OPEN){let a=typeof c=="string"?c:JSON.stringify(c);i.send(a);}else console.log("WebSocket is not connected.");},[e]);return {isConnected:h,messages:w,sendMessage:l}},_e=je;exports.CropShape=_;exports.KeyCode=J;exports.useAnchorPosition=Lt;exports.useCalendar=Ot;exports.useCommandActions=ht;exports.useDB=Mt;exports.useDebounce=Wt;exports.useDelayed=nt;exports.useDevice=Qt;exports.useDimensions=Z;exports.useFacebookPixel=_t;exports.useGoogleTagManager=Zt;exports.useImage=ne;exports.useImageCropper=se;exports.useIntersectionObserver=ce;exports.useLineChart=fe;exports.useMounted=nt;exports.useMutationObserver=K;exports.useNetworkStatus=xe;exports.useNextInterval=Ee;exports.usePushNotifications=Te;exports.useResizeObserver=Ie;exports.useScrollPhysics=He;exports.useScrollbar=Be;exports.useShortcuts=Ue;exports.useUploader=Ve;exports.useWebSocket=_e;
@@ -0,0 +1,487 @@
1
+ import * as react from 'react';
2
+ import { RefObject, ReactNode } from 'react';
3
+ import { CancelTokenSource } from '@zuzjs/core';
4
+
5
+ type dynamic = {
6
+ [x: string]: any;
7
+ };
8
+ type CalendarWeekdayFormat = "long" | "short" | "narrow";
9
+ type CalendarMonthFormat = CalendarWeekdayFormat | "numeric" | "2-digit";
10
+ declare enum CropShape {
11
+ Circle = "circle",
12
+ Square = "square"
13
+ }
14
+ declare enum KeyCode {
15
+ Backspace = 8,
16
+ Tab = 9,
17
+ Enter = 13,
18
+ Shift = 16,
19
+ Ctrl = 17,
20
+ Alt = 18,
21
+ PauseBreak = 19,
22
+ Command = 19,
23
+ CapsLock = 20,
24
+ Escape = 27,
25
+ Space = 32,
26
+ PageUp = 33,
27
+ PageDown = 34,
28
+ End = 35,
29
+ Home = 36,
30
+ ArrowLeft = 37,
31
+ ArrowUp = 38,
32
+ ArrowRight = 39,
33
+ ArrowDown = 40,
34
+ Insert = 45,
35
+ Delete = 46,
36
+ Digit0 = 48,
37
+ Digit1 = 49,
38
+ Digit2 = 50,
39
+ Digit3 = 51,
40
+ Digit4 = 52,
41
+ Digit5 = 53,
42
+ Digit6 = 54,
43
+ Digit7 = 55,
44
+ Digit8 = 56,
45
+ Digit9 = 57,
46
+ KeyA = 65,
47
+ KeyB = 66,
48
+ KeyC = 67,
49
+ KeyD = 68,
50
+ KeyE = 69,
51
+ KeyF = 70,
52
+ KeyG = 71,
53
+ KeyH = 72,
54
+ KeyI = 73,
55
+ KeyJ = 74,
56
+ KeyK = 75,
57
+ KeyL = 76,
58
+ KeyM = 77,
59
+ KeyN = 78,
60
+ KeyO = 79,
61
+ KeyP = 80,
62
+ KeyQ = 81,
63
+ KeyR = 82,
64
+ KeyS = 83,
65
+ KeyT = 84,
66
+ KeyU = 85,
67
+ KeyV = 86,
68
+ KeyW = 87,
69
+ KeyX = 88,
70
+ KeyY = 89,
71
+ KeyZ = 90,
72
+ Numpad0 = 96,
73
+ Numpad1 = 97,
74
+ Numpad2 = 98,
75
+ Numpad3 = 99,
76
+ Numpad4 = 100,
77
+ Numpad5 = 101,
78
+ Numpad6 = 102,
79
+ Numpad7 = 103,
80
+ Numpad8 = 104,
81
+ Numpad9 = 105,
82
+ NumpadMultiply = 106,
83
+ NumpadAdd = 107,
84
+ NumpadSubtract = 109,
85
+ NumpadDecimal = 110,
86
+ NumpadDivide = 111,
87
+ F1 = 112,
88
+ F2 = 113,
89
+ F3 = 114,
90
+ F4 = 115,
91
+ F5 = 116,
92
+ F6 = 117,
93
+ F7 = 118,
94
+ F8 = 119,
95
+ F9 = 120,
96
+ F10 = 121,
97
+ F11 = 122,
98
+ F12 = 123,
99
+ NumLock = 144,
100
+ ScrollLock = 145,
101
+ Semicolon = 186,// ;
102
+ Equal = 187,// =
103
+ Comma = 188,// ,
104
+ Minus = 189,// -
105
+ Period = 190,// .
106
+ Slash = 191,// /
107
+ Backquote = 192,// `
108
+ BracketLeft = 219,// [
109
+ Backslash = 220,// \
110
+ BracketRight = 221,// ]
111
+ Quote = 222
112
+ }
113
+
114
+ type Command = {
115
+ label: string;
116
+ value: string;
117
+ icon?: string;
118
+ type?: 'command' | 'submenu' | 'action';
119
+ subCommands?: Command[];
120
+ action?: React.ReactNode | ((props: {
121
+ onSelect: (value: string) => void;
122
+ }) => React.ReactNode);
123
+ };
124
+ type CommandActionProps = {
125
+ command?: string;
126
+ commands?: Command[];
127
+ cmd?: (value: string, textarea: HTMLTextAreaElement | HTMLInputElement) => void;
128
+ ref: RefObject<HTMLTextAreaElement | HTMLInputElement | null>;
129
+ };
130
+ declare const useCommandActions: ({ command, commands, cmd, ref, }: CommandActionProps) => {
131
+ showDropdown: boolean;
132
+ dropdownPosition: {
133
+ top: number;
134
+ left: number;
135
+ };
136
+ handleKeyDown: (event: React.KeyboardEvent<HTMLTextAreaElement | HTMLInputElement>) => void;
137
+ handleInput: (event: React.FormEvent<HTMLTextAreaElement | HTMLInputElement>) => void;
138
+ handleCommandSelect: (value: string) => void;
139
+ parentRef: RefObject<HTMLDivElement | null>;
140
+ };
141
+
142
+ type IDBOptions = {
143
+ name: string;
144
+ version: number;
145
+ meta: IDBMeta[];
146
+ };
147
+ interface IDBMeta {
148
+ name: string;
149
+ config: {
150
+ keyPath: string;
151
+ autoIncrement: boolean;
152
+ };
153
+ schema: IDBSchema[];
154
+ }
155
+ interface IDBSchema {
156
+ name: string;
157
+ key?: string;
158
+ unique?: boolean;
159
+ }
160
+ declare const useDB: (options: IDBOptions) => {
161
+ getAll: <T>(storeName: string) => Promise<T>;
162
+ getByID: <T>(storeName: string, id: string | number) => Promise<T>;
163
+ getStore: <T>(storeName: string, id: string | number) => Promise<T>;
164
+ insert: <T>(storeName: string, value: T, key?: any) => Promise<number>;
165
+ update: <T>(storeName: string, values: {
166
+ [x: string | number | symbol]: T;
167
+ }) => Promise<void>;
168
+ update_one: <T extends Object>(storeName: string, value: Partial<T>, key: IDBValidKey) => Promise<void>;
169
+ remove: (storeName: string, key: IDBValidKey) => Promise<void>;
170
+ error: string | null;
171
+ };
172
+
173
+ type AnchorOptions = {
174
+ offsetX?: number;
175
+ offsetY?: number;
176
+ overflow?: boolean;
177
+ };
178
+ declare const useAnchorPosition: (parent?: HTMLElement, event?: MouseEvent, options?: AnchorOptions) => {
179
+ position: {
180
+ top: number;
181
+ left: number;
182
+ };
183
+ targetRef: react.RefObject<HTMLDivElement | null>;
184
+ };
185
+
186
+ declare const useCalendar: (range?: number, dayFormat?: CalendarWeekdayFormat, monthFormat?: CalendarMonthFormat) => {
187
+ today: Date;
188
+ daysCount: number;
189
+ month: string;
190
+ day: string;
191
+ days: {
192
+ day: string;
193
+ date: number;
194
+ month: string;
195
+ year: number;
196
+ }[];
197
+ next: () => void;
198
+ prev: () => void;
199
+ };
200
+
201
+ declare const useDebounce: <T extends (...args: any[]) => void>(func: T, delay: number) => (...args: Parameters<T>) => void;
202
+
203
+ /**
204
+ * Custom hook that sets a mounted state to true after a specified delay.
205
+ *
206
+ * @param {number} [delay=100] - The delay in milliseconds before setting the mounted state to true.
207
+ * @returns {boolean} - The mounted state.
208
+ *
209
+ * @example
210
+ * const isMounted = useMounted(200);
211
+ *
212
+ * useEffect(() => {
213
+ * if (isMounted) {
214
+ * // Component is mounted after 200ms
215
+ * }
216
+ * }, [isMounted]);
217
+ */
218
+ declare const useMounted: (delay?: number) => boolean;
219
+
220
+ interface Dimensions {
221
+ width: number;
222
+ height: number;
223
+ top: number;
224
+ left: number;
225
+ bottom: number;
226
+ right: number;
227
+ x: number;
228
+ y: number;
229
+ }
230
+ declare const useDimensions: (el?: HTMLElement | ReactNode) => Dimensions;
231
+
232
+ declare const useDevice: () => {
233
+ isMobile: boolean;
234
+ isTablet: boolean;
235
+ isDesktop: boolean;
236
+ } & Dimensions;
237
+
238
+ /**
239
+ * Custom hook for Facebook Pixel tracking
240
+ * @param pixelId - Facebook Pixel ID (e.g., '123456789012345')
241
+ * @param debug - Optional debug mode (default: false)
242
+ */
243
+ declare const useFacebookPixel: (pixelId?: string, debug?: boolean) => {
244
+ trackPageView: () => void;
245
+ trackEvent: (eventName: string, params?: Record<string, any>) => void;
246
+ trackCustom: (eventName: string, params?: Record<string, any>) => void;
247
+ };
248
+
249
+ /**
250
+ * Custom hook for Google gtag (Global Site Tag) tracking
251
+ * @param id - Google Analytics tracking ID (e.g., 'G-XXXXXXXXXX')
252
+ */
253
+ declare const useGtag: (id?: string) => {
254
+ trackPageView: (path?: string) => void;
255
+ trackEvent: (eventName: string, params?: Record<string, any>) => void;
256
+ };
257
+
258
+ declare const useImage: (url: string, crossOrigin?: "anonymous" | "use-credentials", referrerPolicy?: "no-referrer" | "no-referrer-when-downgrade" | "origin" | "origin-when-cross-origin" | "same-origin" | "strict-origin" | "strict-origin-when-cross-origin" | "unsafe-url") => any[];
259
+
260
+ declare const useImageCropper: (imageUrl: string, cropSize: number, cropShape?: CropShape, scale?: number) => {
261
+ canvasRef: react.RefObject<HTMLCanvasElement | null>;
262
+ crop: () => string | null;
263
+ setScale: react.Dispatch<react.SetStateAction<number>>;
264
+ handleMouseDown: () => void;
265
+ handleMouseUp: () => void;
266
+ handleMouseMove: (e: React.MouseEvent<HTMLCanvasElement>) => void;
267
+ };
268
+
269
+ interface IntersectionObserverOptions {
270
+ root?: Element | null;
271
+ rootMargin?: string;
272
+ threshold?: number | number[];
273
+ }
274
+ declare const useIntersectionObserver: (refs: RefObject<HTMLElement | null>[], options?: IntersectionObserverOptions) => number[];
275
+
276
+ interface DataPoint {
277
+ x: number;
278
+ y: number;
279
+ }
280
+ interface UseLineChartDimensions {
281
+ width: number;
282
+ height: number;
283
+ }
284
+ interface UseLineChartReturn {
285
+ pathD: string;
286
+ areaPathD: string;
287
+ }
288
+ interface LineChartProps {
289
+ data: DataPoint[];
290
+ width?: string | number;
291
+ height?: string | number;
292
+ lineColor?: string;
293
+ strokeWidth?: number;
294
+ gradientStartColor?: string;
295
+ gradientEndColor?: string;
296
+ padding?: number;
297
+ animated?: boolean;
298
+ }
299
+ declare const useLineChart: (data: DataPoint[], dimensions?: UseLineChartDimensions, padding?: number) => UseLineChartReturn;
300
+
301
+ type MutationCallback = (mutations: MutationRecord[], observer: MutationObserver) => void;
302
+ declare const useMutationObserver: (target: HTMLElement | null, callback: MutationCallback, options?: MutationObserverInit) => void;
303
+
304
+ declare const useNetworkStatus: () => boolean | null;
305
+
306
+ interface Countdown {
307
+ minutes: number;
308
+ seconds: number;
309
+ formatted: string;
310
+ nextBoundary: Date;
311
+ }
312
+ /**
313
+ * React hook that counts down to the next N-minute boundary.
314
+ *
315
+ * @param intervalMinutes The interval in minutes (e.g., 1, 5, 15, 30, 60)
316
+ * @returns Countdown info + next boundary time
317
+ */
318
+ declare const useNextInterval: (intervalMinutes?: number) => Countdown;
319
+
320
+ type PushSubscriptionMeta = {
321
+ endpoint: string;
322
+ keys: {
323
+ p256dh: string;
324
+ auth: string;
325
+ };
326
+ };
327
+ type PushNotificationsOptions = {
328
+ /**
329
+ * VAPID public key (required for subscription)
330
+ */
331
+ vapidPublicKey: string;
332
+ /**
333
+ * Path to your service worker file
334
+ * @default '/sw.js'
335
+ */
336
+ serviceWorkerPath?: string;
337
+ /**
338
+ * Auto-request permission on mount
339
+ * @default false
340
+ */
341
+ requestPermissionOnMount?: boolean;
342
+ };
343
+ type PushNotificationsResult = {
344
+ /** Current permission state */
345
+ permission: NotificationPermission;
346
+ /** Push subscription object (or null if not subscribed) */
347
+ subscription: PushSubscription | null;
348
+ /** JSON representation of subscription (easy to send to backend) */
349
+ subscriptionMeta: PushSubscriptionMeta | null;
350
+ /** Is push supported in this browser? */
351
+ isSupported: boolean;
352
+ /** Request permission and subscribe */
353
+ subscribe: () => Promise<PushSubscription | null>;
354
+ /** Unsubscribe from push */
355
+ unsubscribe: () => Promise<boolean>;
356
+ /** Request notification permission only */
357
+ requestPermission: () => Promise<NotificationPermission>;
358
+ /** Error state */
359
+ error: string | null;
360
+ /** Loading state */
361
+ isLoading: boolean;
362
+ };
363
+ declare const usePushNotifications: (options: PushNotificationsOptions) => PushNotificationsResult;
364
+
365
+ interface Size {
366
+ width: number;
367
+ height: number;
368
+ top: number;
369
+ left: number;
370
+ }
371
+ declare const useResizeObserver: (ref: RefObject<HTMLElement | null> | HTMLElement) => Size;
372
+
373
+ interface ScrollBreakpoint {
374
+ [key: number]: () => void;
375
+ }
376
+ declare const useScrollbar: (speed: number, breakpoints?: ScrollBreakpoint) => {
377
+ rootRef: react.RefObject<HTMLDivElement | null>;
378
+ containerRef: react.RefObject<HTMLDivElement | null>;
379
+ thumbY: react.RefObject<HTMLDivElement | null>;
380
+ thumbX: react.RefObject<HTMLDivElement | null>;
381
+ scrollToTop: () => void | undefined;
382
+ scrollToBottom: () => void | undefined;
383
+ scrollToLeft: () => void | undefined;
384
+ scrollToRight: () => void | undefined;
385
+ onScrollY: (e: React.MouseEvent) => void;
386
+ onScrollX: (e: React.MouseEvent) => void;
387
+ };
388
+
389
+ type ScrollPhysicsOptions = {
390
+ lerpFactor?: number;
391
+ x?: number;
392
+ y?: number;
393
+ xMultiplier?: number;
394
+ yMultiplier?: number;
395
+ scale?: {
396
+ min: number;
397
+ max: number;
398
+ factor: number;
399
+ };
400
+ rotate?: {
401
+ direction?: 1 | -1;
402
+ multiplier?: number;
403
+ };
404
+ };
405
+ declare const useScrollPhysics: (ref: RefObject<HTMLElement>, options: ScrollPhysicsOptions) => {
406
+ position: RefObject<number>;
407
+ velocity: RefObject<number>;
408
+ };
409
+
410
+ type Shortcut = {
411
+ keys: KeyCode[];
412
+ callback: (event: KeyboardEvent) => void;
413
+ };
414
+ declare const useShortcuts: (shortcuts: Shortcut[], preventDefault?: boolean) => void;
415
+
416
+ declare enum Status {
417
+ Error = -1,
418
+ Idle = 0,
419
+ FetchingServer = 1,
420
+ Uploading = 2,
421
+ Saving = 3,
422
+ Saved = 4
423
+ }
424
+ interface QueItem {
425
+ ID: string;
426
+ file: File;
427
+ dir: string;
428
+ remote: false;
429
+ progress: number;
430
+ speed: number;
431
+ eta: number;
432
+ bytes: number;
433
+ status: Status;
434
+ server?: Server | null;
435
+ }
436
+ type Server = {
437
+ ID: string;
438
+ uri: string;
439
+ token: string;
440
+ rmf: string | null;
441
+ };
442
+ type Uploadify = {
443
+ que: QueItem[];
444
+ index: number;
445
+ speed: number;
446
+ stamp: number | null;
447
+ token: string | null;
448
+ status: Status;
449
+ cancelToken?: CancelTokenSource | null;
450
+ };
451
+ interface Uploader {
452
+ apiUrl: string;
453
+ onChange?: (file: QueItem | null) => void;
454
+ onComplete?: (index: number, que: QueItem[], currentFile: QueItem | null) => void;
455
+ onError?: (index: number, que: QueItem[], currentFile: QueItem | null) => void;
456
+ onQueFinished?: () => void;
457
+ }
458
+ declare const useUploader: (conf: Uploader) => {
459
+ get: () => react.RefObject<Uploadify>;
460
+ getQue: () => QueItem[];
461
+ addToQue: (f: dynamic) => void;
462
+ };
463
+
464
+ type WebSocketOptions = {
465
+ onOpen?: (event: Event) => void;
466
+ onClose?: (event: CloseEvent) => void;
467
+ onRawMessage?: (event: MessageEvent) => void;
468
+ onMessage?: (data: dynamic) => void;
469
+ onError?: (event: Event) => void;
470
+ reconnect?: boolean;
471
+ };
472
+ declare const useWebSocket: (url: string, options?: WebSocketOptions) => {
473
+ isConnected: boolean;
474
+ messages: any[];
475
+ sendMessage: (message: string | object) => void;
476
+ };
477
+
478
+ declare global {
479
+ interface Window {
480
+ fbq: (...args: any[]) => void;
481
+ _fbq: any;
482
+ gtag: (...args: any[]) => void;
483
+ dataLayer: Record<string, any>[];
484
+ }
485
+ }
486
+
487
+ export { type CalendarMonthFormat, type CalendarWeekdayFormat, type Command, type CommandActionProps, CropShape, type DataPoint, type IDBOptions, type IDBSchema, KeyCode, type LineChartProps, type MutationCallback, type PushNotificationsOptions, type PushNotificationsResult, type PushSubscriptionMeta, type QueItem as UploadQueItem, Status as UploadStatus, type Uploadify, type UseLineChartDimensions, type UseLineChartReturn, type WebSocketOptions, useAnchorPosition, useCalendar, useCommandActions, useDB, useDebounce, useMounted as useDelayed, useDevice, useDimensions, useFacebookPixel, useGtag as useGoogleTagManager, useImage, useImageCropper, useIntersectionObserver, useLineChart, useMounted, useMutationObserver, useNetworkStatus, useNextInterval, usePushNotifications, useResizeObserver, useScrollPhysics, useScrollbar, useShortcuts, useUploader, useWebSocket };
@@ -0,0 +1,487 @@
1
+ import * as react from 'react';
2
+ import { RefObject, ReactNode } from 'react';
3
+ import { CancelTokenSource } from '@zuzjs/core';
4
+
5
+ type dynamic = {
6
+ [x: string]: any;
7
+ };
8
+ type CalendarWeekdayFormat = "long" | "short" | "narrow";
9
+ type CalendarMonthFormat = CalendarWeekdayFormat | "numeric" | "2-digit";
10
+ declare enum CropShape {
11
+ Circle = "circle",
12
+ Square = "square"
13
+ }
14
+ declare enum KeyCode {
15
+ Backspace = 8,
16
+ Tab = 9,
17
+ Enter = 13,
18
+ Shift = 16,
19
+ Ctrl = 17,
20
+ Alt = 18,
21
+ PauseBreak = 19,
22
+ Command = 19,
23
+ CapsLock = 20,
24
+ Escape = 27,
25
+ Space = 32,
26
+ PageUp = 33,
27
+ PageDown = 34,
28
+ End = 35,
29
+ Home = 36,
30
+ ArrowLeft = 37,
31
+ ArrowUp = 38,
32
+ ArrowRight = 39,
33
+ ArrowDown = 40,
34
+ Insert = 45,
35
+ Delete = 46,
36
+ Digit0 = 48,
37
+ Digit1 = 49,
38
+ Digit2 = 50,
39
+ Digit3 = 51,
40
+ Digit4 = 52,
41
+ Digit5 = 53,
42
+ Digit6 = 54,
43
+ Digit7 = 55,
44
+ Digit8 = 56,
45
+ Digit9 = 57,
46
+ KeyA = 65,
47
+ KeyB = 66,
48
+ KeyC = 67,
49
+ KeyD = 68,
50
+ KeyE = 69,
51
+ KeyF = 70,
52
+ KeyG = 71,
53
+ KeyH = 72,
54
+ KeyI = 73,
55
+ KeyJ = 74,
56
+ KeyK = 75,
57
+ KeyL = 76,
58
+ KeyM = 77,
59
+ KeyN = 78,
60
+ KeyO = 79,
61
+ KeyP = 80,
62
+ KeyQ = 81,
63
+ KeyR = 82,
64
+ KeyS = 83,
65
+ KeyT = 84,
66
+ KeyU = 85,
67
+ KeyV = 86,
68
+ KeyW = 87,
69
+ KeyX = 88,
70
+ KeyY = 89,
71
+ KeyZ = 90,
72
+ Numpad0 = 96,
73
+ Numpad1 = 97,
74
+ Numpad2 = 98,
75
+ Numpad3 = 99,
76
+ Numpad4 = 100,
77
+ Numpad5 = 101,
78
+ Numpad6 = 102,
79
+ Numpad7 = 103,
80
+ Numpad8 = 104,
81
+ Numpad9 = 105,
82
+ NumpadMultiply = 106,
83
+ NumpadAdd = 107,
84
+ NumpadSubtract = 109,
85
+ NumpadDecimal = 110,
86
+ NumpadDivide = 111,
87
+ F1 = 112,
88
+ F2 = 113,
89
+ F3 = 114,
90
+ F4 = 115,
91
+ F5 = 116,
92
+ F6 = 117,
93
+ F7 = 118,
94
+ F8 = 119,
95
+ F9 = 120,
96
+ F10 = 121,
97
+ F11 = 122,
98
+ F12 = 123,
99
+ NumLock = 144,
100
+ ScrollLock = 145,
101
+ Semicolon = 186,// ;
102
+ Equal = 187,// =
103
+ Comma = 188,// ,
104
+ Minus = 189,// -
105
+ Period = 190,// .
106
+ Slash = 191,// /
107
+ Backquote = 192,// `
108
+ BracketLeft = 219,// [
109
+ Backslash = 220,// \
110
+ BracketRight = 221,// ]
111
+ Quote = 222
112
+ }
113
+
114
+ type Command = {
115
+ label: string;
116
+ value: string;
117
+ icon?: string;
118
+ type?: 'command' | 'submenu' | 'action';
119
+ subCommands?: Command[];
120
+ action?: React.ReactNode | ((props: {
121
+ onSelect: (value: string) => void;
122
+ }) => React.ReactNode);
123
+ };
124
+ type CommandActionProps = {
125
+ command?: string;
126
+ commands?: Command[];
127
+ cmd?: (value: string, textarea: HTMLTextAreaElement | HTMLInputElement) => void;
128
+ ref: RefObject<HTMLTextAreaElement | HTMLInputElement | null>;
129
+ };
130
+ declare const useCommandActions: ({ command, commands, cmd, ref, }: CommandActionProps) => {
131
+ showDropdown: boolean;
132
+ dropdownPosition: {
133
+ top: number;
134
+ left: number;
135
+ };
136
+ handleKeyDown: (event: React.KeyboardEvent<HTMLTextAreaElement | HTMLInputElement>) => void;
137
+ handleInput: (event: React.FormEvent<HTMLTextAreaElement | HTMLInputElement>) => void;
138
+ handleCommandSelect: (value: string) => void;
139
+ parentRef: RefObject<HTMLDivElement | null>;
140
+ };
141
+
142
+ type IDBOptions = {
143
+ name: string;
144
+ version: number;
145
+ meta: IDBMeta[];
146
+ };
147
+ interface IDBMeta {
148
+ name: string;
149
+ config: {
150
+ keyPath: string;
151
+ autoIncrement: boolean;
152
+ };
153
+ schema: IDBSchema[];
154
+ }
155
+ interface IDBSchema {
156
+ name: string;
157
+ key?: string;
158
+ unique?: boolean;
159
+ }
160
+ declare const useDB: (options: IDBOptions) => {
161
+ getAll: <T>(storeName: string) => Promise<T>;
162
+ getByID: <T>(storeName: string, id: string | number) => Promise<T>;
163
+ getStore: <T>(storeName: string, id: string | number) => Promise<T>;
164
+ insert: <T>(storeName: string, value: T, key?: any) => Promise<number>;
165
+ update: <T>(storeName: string, values: {
166
+ [x: string | number | symbol]: T;
167
+ }) => Promise<void>;
168
+ update_one: <T extends Object>(storeName: string, value: Partial<T>, key: IDBValidKey) => Promise<void>;
169
+ remove: (storeName: string, key: IDBValidKey) => Promise<void>;
170
+ error: string | null;
171
+ };
172
+
173
+ type AnchorOptions = {
174
+ offsetX?: number;
175
+ offsetY?: number;
176
+ overflow?: boolean;
177
+ };
178
+ declare const useAnchorPosition: (parent?: HTMLElement, event?: MouseEvent, options?: AnchorOptions) => {
179
+ position: {
180
+ top: number;
181
+ left: number;
182
+ };
183
+ targetRef: react.RefObject<HTMLDivElement | null>;
184
+ };
185
+
186
+ declare const useCalendar: (range?: number, dayFormat?: CalendarWeekdayFormat, monthFormat?: CalendarMonthFormat) => {
187
+ today: Date;
188
+ daysCount: number;
189
+ month: string;
190
+ day: string;
191
+ days: {
192
+ day: string;
193
+ date: number;
194
+ month: string;
195
+ year: number;
196
+ }[];
197
+ next: () => void;
198
+ prev: () => void;
199
+ };
200
+
201
+ declare const useDebounce: <T extends (...args: any[]) => void>(func: T, delay: number) => (...args: Parameters<T>) => void;
202
+
203
+ /**
204
+ * Custom hook that sets a mounted state to true after a specified delay.
205
+ *
206
+ * @param {number} [delay=100] - The delay in milliseconds before setting the mounted state to true.
207
+ * @returns {boolean} - The mounted state.
208
+ *
209
+ * @example
210
+ * const isMounted = useMounted(200);
211
+ *
212
+ * useEffect(() => {
213
+ * if (isMounted) {
214
+ * // Component is mounted after 200ms
215
+ * }
216
+ * }, [isMounted]);
217
+ */
218
+ declare const useMounted: (delay?: number) => boolean;
219
+
220
+ interface Dimensions {
221
+ width: number;
222
+ height: number;
223
+ top: number;
224
+ left: number;
225
+ bottom: number;
226
+ right: number;
227
+ x: number;
228
+ y: number;
229
+ }
230
+ declare const useDimensions: (el?: HTMLElement | ReactNode) => Dimensions;
231
+
232
+ declare const useDevice: () => {
233
+ isMobile: boolean;
234
+ isTablet: boolean;
235
+ isDesktop: boolean;
236
+ } & Dimensions;
237
+
238
+ /**
239
+ * Custom hook for Facebook Pixel tracking
240
+ * @param pixelId - Facebook Pixel ID (e.g., '123456789012345')
241
+ * @param debug - Optional debug mode (default: false)
242
+ */
243
+ declare const useFacebookPixel: (pixelId?: string, debug?: boolean) => {
244
+ trackPageView: () => void;
245
+ trackEvent: (eventName: string, params?: Record<string, any>) => void;
246
+ trackCustom: (eventName: string, params?: Record<string, any>) => void;
247
+ };
248
+
249
+ /**
250
+ * Custom hook for Google gtag (Global Site Tag) tracking
251
+ * @param id - Google Analytics tracking ID (e.g., 'G-XXXXXXXXXX')
252
+ */
253
+ declare const useGtag: (id?: string) => {
254
+ trackPageView: (path?: string) => void;
255
+ trackEvent: (eventName: string, params?: Record<string, any>) => void;
256
+ };
257
+
258
+ declare const useImage: (url: string, crossOrigin?: "anonymous" | "use-credentials", referrerPolicy?: "no-referrer" | "no-referrer-when-downgrade" | "origin" | "origin-when-cross-origin" | "same-origin" | "strict-origin" | "strict-origin-when-cross-origin" | "unsafe-url") => any[];
259
+
260
+ declare const useImageCropper: (imageUrl: string, cropSize: number, cropShape?: CropShape, scale?: number) => {
261
+ canvasRef: react.RefObject<HTMLCanvasElement | null>;
262
+ crop: () => string | null;
263
+ setScale: react.Dispatch<react.SetStateAction<number>>;
264
+ handleMouseDown: () => void;
265
+ handleMouseUp: () => void;
266
+ handleMouseMove: (e: React.MouseEvent<HTMLCanvasElement>) => void;
267
+ };
268
+
269
+ interface IntersectionObserverOptions {
270
+ root?: Element | null;
271
+ rootMargin?: string;
272
+ threshold?: number | number[];
273
+ }
274
+ declare const useIntersectionObserver: (refs: RefObject<HTMLElement | null>[], options?: IntersectionObserverOptions) => number[];
275
+
276
+ interface DataPoint {
277
+ x: number;
278
+ y: number;
279
+ }
280
+ interface UseLineChartDimensions {
281
+ width: number;
282
+ height: number;
283
+ }
284
+ interface UseLineChartReturn {
285
+ pathD: string;
286
+ areaPathD: string;
287
+ }
288
+ interface LineChartProps {
289
+ data: DataPoint[];
290
+ width?: string | number;
291
+ height?: string | number;
292
+ lineColor?: string;
293
+ strokeWidth?: number;
294
+ gradientStartColor?: string;
295
+ gradientEndColor?: string;
296
+ padding?: number;
297
+ animated?: boolean;
298
+ }
299
+ declare const useLineChart: (data: DataPoint[], dimensions?: UseLineChartDimensions, padding?: number) => UseLineChartReturn;
300
+
301
+ type MutationCallback = (mutations: MutationRecord[], observer: MutationObserver) => void;
302
+ declare const useMutationObserver: (target: HTMLElement | null, callback: MutationCallback, options?: MutationObserverInit) => void;
303
+
304
+ declare const useNetworkStatus: () => boolean | null;
305
+
306
+ interface Countdown {
307
+ minutes: number;
308
+ seconds: number;
309
+ formatted: string;
310
+ nextBoundary: Date;
311
+ }
312
+ /**
313
+ * React hook that counts down to the next N-minute boundary.
314
+ *
315
+ * @param intervalMinutes The interval in minutes (e.g., 1, 5, 15, 30, 60)
316
+ * @returns Countdown info + next boundary time
317
+ */
318
+ declare const useNextInterval: (intervalMinutes?: number) => Countdown;
319
+
320
+ type PushSubscriptionMeta = {
321
+ endpoint: string;
322
+ keys: {
323
+ p256dh: string;
324
+ auth: string;
325
+ };
326
+ };
327
+ type PushNotificationsOptions = {
328
+ /**
329
+ * VAPID public key (required for subscription)
330
+ */
331
+ vapidPublicKey: string;
332
+ /**
333
+ * Path to your service worker file
334
+ * @default '/sw.js'
335
+ */
336
+ serviceWorkerPath?: string;
337
+ /**
338
+ * Auto-request permission on mount
339
+ * @default false
340
+ */
341
+ requestPermissionOnMount?: boolean;
342
+ };
343
+ type PushNotificationsResult = {
344
+ /** Current permission state */
345
+ permission: NotificationPermission;
346
+ /** Push subscription object (or null if not subscribed) */
347
+ subscription: PushSubscription | null;
348
+ /** JSON representation of subscription (easy to send to backend) */
349
+ subscriptionMeta: PushSubscriptionMeta | null;
350
+ /** Is push supported in this browser? */
351
+ isSupported: boolean;
352
+ /** Request permission and subscribe */
353
+ subscribe: () => Promise<PushSubscription | null>;
354
+ /** Unsubscribe from push */
355
+ unsubscribe: () => Promise<boolean>;
356
+ /** Request notification permission only */
357
+ requestPermission: () => Promise<NotificationPermission>;
358
+ /** Error state */
359
+ error: string | null;
360
+ /** Loading state */
361
+ isLoading: boolean;
362
+ };
363
+ declare const usePushNotifications: (options: PushNotificationsOptions) => PushNotificationsResult;
364
+
365
+ interface Size {
366
+ width: number;
367
+ height: number;
368
+ top: number;
369
+ left: number;
370
+ }
371
+ declare const useResizeObserver: (ref: RefObject<HTMLElement | null> | HTMLElement) => Size;
372
+
373
+ interface ScrollBreakpoint {
374
+ [key: number]: () => void;
375
+ }
376
+ declare const useScrollbar: (speed: number, breakpoints?: ScrollBreakpoint) => {
377
+ rootRef: react.RefObject<HTMLDivElement | null>;
378
+ containerRef: react.RefObject<HTMLDivElement | null>;
379
+ thumbY: react.RefObject<HTMLDivElement | null>;
380
+ thumbX: react.RefObject<HTMLDivElement | null>;
381
+ scrollToTop: () => void | undefined;
382
+ scrollToBottom: () => void | undefined;
383
+ scrollToLeft: () => void | undefined;
384
+ scrollToRight: () => void | undefined;
385
+ onScrollY: (e: React.MouseEvent) => void;
386
+ onScrollX: (e: React.MouseEvent) => void;
387
+ };
388
+
389
+ type ScrollPhysicsOptions = {
390
+ lerpFactor?: number;
391
+ x?: number;
392
+ y?: number;
393
+ xMultiplier?: number;
394
+ yMultiplier?: number;
395
+ scale?: {
396
+ min: number;
397
+ max: number;
398
+ factor: number;
399
+ };
400
+ rotate?: {
401
+ direction?: 1 | -1;
402
+ multiplier?: number;
403
+ };
404
+ };
405
+ declare const useScrollPhysics: (ref: RefObject<HTMLElement>, options: ScrollPhysicsOptions) => {
406
+ position: RefObject<number>;
407
+ velocity: RefObject<number>;
408
+ };
409
+
410
+ type Shortcut = {
411
+ keys: KeyCode[];
412
+ callback: (event: KeyboardEvent) => void;
413
+ };
414
+ declare const useShortcuts: (shortcuts: Shortcut[], preventDefault?: boolean) => void;
415
+
416
+ declare enum Status {
417
+ Error = -1,
418
+ Idle = 0,
419
+ FetchingServer = 1,
420
+ Uploading = 2,
421
+ Saving = 3,
422
+ Saved = 4
423
+ }
424
+ interface QueItem {
425
+ ID: string;
426
+ file: File;
427
+ dir: string;
428
+ remote: false;
429
+ progress: number;
430
+ speed: number;
431
+ eta: number;
432
+ bytes: number;
433
+ status: Status;
434
+ server?: Server | null;
435
+ }
436
+ type Server = {
437
+ ID: string;
438
+ uri: string;
439
+ token: string;
440
+ rmf: string | null;
441
+ };
442
+ type Uploadify = {
443
+ que: QueItem[];
444
+ index: number;
445
+ speed: number;
446
+ stamp: number | null;
447
+ token: string | null;
448
+ status: Status;
449
+ cancelToken?: CancelTokenSource | null;
450
+ };
451
+ interface Uploader {
452
+ apiUrl: string;
453
+ onChange?: (file: QueItem | null) => void;
454
+ onComplete?: (index: number, que: QueItem[], currentFile: QueItem | null) => void;
455
+ onError?: (index: number, que: QueItem[], currentFile: QueItem | null) => void;
456
+ onQueFinished?: () => void;
457
+ }
458
+ declare const useUploader: (conf: Uploader) => {
459
+ get: () => react.RefObject<Uploadify>;
460
+ getQue: () => QueItem[];
461
+ addToQue: (f: dynamic) => void;
462
+ };
463
+
464
+ type WebSocketOptions = {
465
+ onOpen?: (event: Event) => void;
466
+ onClose?: (event: CloseEvent) => void;
467
+ onRawMessage?: (event: MessageEvent) => void;
468
+ onMessage?: (data: dynamic) => void;
469
+ onError?: (event: Event) => void;
470
+ reconnect?: boolean;
471
+ };
472
+ declare const useWebSocket: (url: string, options?: WebSocketOptions) => {
473
+ isConnected: boolean;
474
+ messages: any[];
475
+ sendMessage: (message: string | object) => void;
476
+ };
477
+
478
+ declare global {
479
+ interface Window {
480
+ fbq: (...args: any[]) => void;
481
+ _fbq: any;
482
+ gtag: (...args: any[]) => void;
483
+ dataLayer: Record<string, any>[];
484
+ }
485
+ }
486
+
487
+ export { type CalendarMonthFormat, type CalendarWeekdayFormat, type Command, type CommandActionProps, CropShape, type DataPoint, type IDBOptions, type IDBSchema, KeyCode, type LineChartProps, type MutationCallback, type PushNotificationsOptions, type PushNotificationsResult, type PushSubscriptionMeta, type QueItem as UploadQueItem, Status as UploadStatus, type Uploadify, type UseLineChartDimensions, type UseLineChartReturn, type WebSocketOptions, useAnchorPosition, useCalendar, useCommandActions, useDB, useDebounce, useMounted as useDelayed, useDevice, useDimensions, useFacebookPixel, useGtag as useGoogleTagManager, useImage, useImageCropper, useIntersectionObserver, useLineChart, useMounted, useMutationObserver, useNetworkStatus, useNextInterval, usePushNotifications, useResizeObserver, useScrollPhysics, useScrollbar, useShortcuts, useUploader, useWebSocket };
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ import {useState,useRef,useEffect,useCallback,useMemo}from'react';import {urlBase64ToUint8Array,uuid,clamp,withPost,getCancelToken}from'@zuzjs/core';var J=(s=>(s.Circle="circle",s.Square="square",s))(J||{}),G=(t=>(t[t.Backspace=8]="Backspace",t[t.Tab=9]="Tab",t[t.Enter=13]="Enter",t[t.Shift=16]="Shift",t[t.Ctrl=17]="Ctrl",t[t.Alt=18]="Alt",t[t.PauseBreak=19]="PauseBreak",t[t.Command=19]="Command",t[t.CapsLock=20]="CapsLock",t[t.Escape=27]="Escape",t[t.Space=32]="Space",t[t.PageUp=33]="PageUp",t[t.PageDown=34]="PageDown",t[t.End=35]="End",t[t.Home=36]="Home",t[t.ArrowLeft=37]="ArrowLeft",t[t.ArrowUp=38]="ArrowUp",t[t.ArrowRight=39]="ArrowRight",t[t.ArrowDown=40]="ArrowDown",t[t.Insert=45]="Insert",t[t.Delete=46]="Delete",t[t.Digit0=48]="Digit0",t[t.Digit1=49]="Digit1",t[t.Digit2=50]="Digit2",t[t.Digit3=51]="Digit3",t[t.Digit4=52]="Digit4",t[t.Digit5=53]="Digit5",t[t.Digit6=54]="Digit6",t[t.Digit7=55]="Digit7",t[t.Digit8=56]="Digit8",t[t.Digit9=57]="Digit9",t[t.KeyA=65]="KeyA",t[t.KeyB=66]="KeyB",t[t.KeyC=67]="KeyC",t[t.KeyD=68]="KeyD",t[t.KeyE=69]="KeyE",t[t.KeyF=70]="KeyF",t[t.KeyG=71]="KeyG",t[t.KeyH=72]="KeyH",t[t.KeyI=73]="KeyI",t[t.KeyJ=74]="KeyJ",t[t.KeyK=75]="KeyK",t[t.KeyL=76]="KeyL",t[t.KeyM=77]="KeyM",t[t.KeyN=78]="KeyN",t[t.KeyO=79]="KeyO",t[t.KeyP=80]="KeyP",t[t.KeyQ=81]="KeyQ",t[t.KeyR=82]="KeyR",t[t.KeyS=83]="KeyS",t[t.KeyT=84]="KeyT",t[t.KeyU=85]="KeyU",t[t.KeyV=86]="KeyV",t[t.KeyW=87]="KeyW",t[t.KeyX=88]="KeyX",t[t.KeyY=89]="KeyY",t[t.KeyZ=90]="KeyZ",t[t.Numpad0=96]="Numpad0",t[t.Numpad1=97]="Numpad1",t[t.Numpad2=98]="Numpad2",t[t.Numpad3=99]="Numpad3",t[t.Numpad4=100]="Numpad4",t[t.Numpad5=101]="Numpad5",t[t.Numpad6=102]="Numpad6",t[t.Numpad7=103]="Numpad7",t[t.Numpad8=104]="Numpad8",t[t.Numpad9=105]="Numpad9",t[t.NumpadMultiply=106]="NumpadMultiply",t[t.NumpadAdd=107]="NumpadAdd",t[t.NumpadSubtract=109]="NumpadSubtract",t[t.NumpadDecimal=110]="NumpadDecimal",t[t.NumpadDivide=111]="NumpadDivide",t[t.F1=112]="F1",t[t.F2=113]="F2",t[t.F3=114]="F3",t[t.F4=115]="F4",t[t.F5=116]="F5",t[t.F6=117]="F6",t[t.F7=118]="F7",t[t.F8=119]="F8",t[t.F9=120]="F9",t[t.F10=121]="F10",t[t.F11=122]="F11",t[t.F12=123]="F12",t[t.NumLock=144]="NumLock",t[t.ScrollLock=145]="ScrollLock",t[t.Semicolon=186]="Semicolon",t[t.Equal=187]="Equal",t[t.Comma=188]="Comma",t[t.Minus=189]="Minus",t[t.Period=190]="Period",t[t.Slash=191]="Slash",t[t.Backquote=192]="Backquote",t[t.BracketLeft=219]="BracketLeft",t[t.Backslash=220]="Backslash",t[t.BracketRight=221]="BracketRight",t[t.Quote=222]="Quote",t))(G||{});var ht=({command:e="/",commands:o=[],cmd:s,ref:n})=>{let[r,u]=useState(-1),[f,p]=useState(false),[h,b]=useState({top:0,left:0}),w=useRef(null),m=x=>{let l=n.current;if(l&&f){let{value:c}=l;(r<0||r>=c.length||c[r]!==e)&&p(false);}},v=x=>{let l=n.current;if(!l)return;let{selectionStart:c}=l;if(x.key===e){u(c||-1);let i=S(l,c||-1);b({top:i.top+20,left:i.left}),p(true);}else x.key==="Escape"&&(x.preventDefault(),x.stopPropagation(),p(false));},g=x=>{let l=n.current;if(l){if(s)s(x,l);else {let{value:c,selectionStart:i}=l,a=c.slice(0,r)+x+c.slice(i||-1);l.value=a,l.setSelectionRange(r+x.length,r+x.length);let M=new Event("input",{bubbles:true});l.dispatchEvent(M);}p(false),l.focus();}},S=(x,l)=>{let c=document.createElement("canvas"),i=c.getContext("2d");if(!i)return {top:0,left:0};let a=window.getComputedStyle(x);i.font=`${a.fontSize} ${a.fontFamily}`;let E=x.value.substring(0,l).split(`
2
+ `),T=E[E.length-1],d=i.measureText(T).width,P=parseFloat(a.lineHeight)||parseFloat(a.fontSize)*1.2,D=(E.length-1)*P,R=parseFloat(a.paddingTop)||0,O=parseFloat(a.paddingLeft)||0,I=x.scrollTop;return c.remove(),{top:D-I+R,left:d+O}};return useEffect(()=>{let x=l=>{n.current&&w.current&&!n.current.contains(l.target)&&!w.current.contains(l.target)&&p(false);};return document.addEventListener("mousedown",x),()=>{document.removeEventListener("mousedown",x);}},[n]),{showDropdown:f,dropdownPosition:h,handleKeyDown:v,handleInput:m,handleCommandSelect:g,parentRef:w}},bt=ht;var Mt=e=>{let{name:o,version:s,meta:n}=e,r=useRef(null),[u,f]=useState(null);useEffect(()=>{let l=indexedDB.open(o,+s.toString().replace(/\./g,""));return l.onupgradeneeded=c=>{let i=c.target.result;n.forEach(a=>{if(!i.objectStoreNames.contains(a.name)){let M=i.createObjectStore(a.name,a.config);a.schema.forEach(E=>{M.createIndex(E.name,E.key||E.name,{unique:E.unique||false});});}});},l.onsuccess=c=>{r.current=c.target.result;},l.onerror=()=>{f("Failed to open database");},()=>r.current?.close()},[o,s]);let p=()=>new Promise((l,c)=>{r.current&&l(r.current);let i=indexedDB.open(o,+s.toString().replace(/\./g,""));i.onsuccess=a=>{r.current=a.target.result,l(r.current);},i.onerror=a=>{c(["Failed to open database",a].join(`
3
+ `));};}),h=(l,c)=>({store:r.current.transaction(l,c).objectStore(l)});return {getAll:l=>new Promise((c,i)=>{p().then(a=>{let{store:M}=h(l,"readonly"),E=M.getAll();E.onsuccess=T=>{T.target.result==null&&i("Record not found"),c(T.target.result);},E.onerror=T=>{i(`SELECT Failed. ${T.target.result}`);};}).catch(a=>{console.log("[getAll]",a),i("Database either corrupted or not initialized");});}),getByID:(l,c)=>new Promise((i,a)=>{p().then(M=>{let{store:E}=h(l,"readonly"),T=E.get(c);T.onsuccess=d=>{d.target.result==null&&a("Record not found"),i(d.target.result);},T.onerror=d=>{a(`SELECT Failed. ${d.target.result}`);};}).catch(M=>{console.log("[getByID]",M),a("Database either corrupted or not initialized");});}),getStore:(l,c)=>new Promise((i,a)=>{p().then(M=>{let{store:E}=h(l,"readonly"),T=E.getAll();T.onsuccess=d=>{d.target.result==null&&a("Record not found"),i(d.target.result);},T.onerror=d=>{a(`SELECT Failed. ${d.target.result}`);};}).catch(M=>{a(M.message||"Database either corrupted or not initialized");});}),insert:(l,c,i)=>new Promise((a,M)=>{p().then(E=>{let{store:T}=h(l,"readwrite"),d=T.add(c,i);d.onsuccess=P=>{a(P.target.result);},d.onerror=P=>{M(`INSERTION Failed. ${P.target.result}`);};}).catch(E=>{M(E.message||"Database either corrupted or not initialized");});}),update:(l,c)=>new Promise((i,a)=>{p().then(M=>{let {store:E}=h(l,"readwrite"),d=E.put(c);d.onsuccess=P=>{i();},d.onerror=P=>{a(`UPDATE Failed. ${P.target.result}`);};}).catch(M=>{a(`UPDATE Failed. ${M}`);});}),update_one:(l,c,i)=>new Promise((a,M)=>{p().then(E=>{let{store:T}=h(l,"readwrite"),d=T.get(i);d.onsuccess=()=>{let P=d.result;if(!P){M(`Record with key ${i} not found.`);return}let D=T.put({...P,...c});D.onsuccess=()=>a(),D.onerror=R=>M(`Update failed. ${R.target.error}`);},d.onerror=P=>{M(`Failed to get existing record. ${P.target.error}`);};}).catch(E=>{M("Database either corrupted or not initialized");});}),remove:(l,c)=>new Promise((i,a)=>{p().then(M=>{let{store:E}=h(l,"readwrite"),T=E.delete(c);T.onsuccess=d=>{i();};}).catch(M=>{console.log(M),a(`Delete failed from ${l} with key: ${c}`);});}),error:u}},St=Mt;var Lt=(e,o,s={})=>{let[n,r]=useState({top:0,left:0}),{offsetX:u=0,offsetY:f=0,overflow:p=true}=s,h=useRef(null),b=useCallback(()=>{let w=0,m=0;if(o)w=o.clientY+f,m=o.clientX+u;else if(e){let v=e.getBoundingClientRect();w=v.bottom+f,m=v.left+u;}if(p&&h.current){let v=h.current.getBoundingClientRect(),{innerWidth:g,innerHeight:S}=window;m+v.width>g&&(m=g-v.width-10),w+v.height>S&&(w=S-v.height-10);}r({top:w,left:m});},[o,e,u,f,p]);return useEffect(()=>(b(),window.addEventListener("resize",b),window.addEventListener("scroll",b),()=>{window.removeEventListener("resize",b),window.removeEventListener("scroll",b);}),[b]),{position:n,targetRef:h}},kt=Lt;var It=e=>e%4===0&&e%100!==0||e%400===0,Ft=(e,o)=>{switch(e){case 1:return It(o)?29:28;case 3:case 5:case 8:case 10:return 30;default:return 31}},et=(e,o)=>e.toLocaleString("default",{weekday:o}),nt=(e,o)=>{let s=new Date;return s.setMonth(e),s.toLocaleString("default",{month:o})},Ot=(e=1,o,s)=>{let[n,r]=useState(new Date),u=()=>{r(m=>{let v=new Date(m);return v.setMonth(m.getMonth()+e),v});},f=()=>{r(m=>{let v=new Date(m);return v.setMonth(v.getMonth()-e),v});},p=Ft(n.getMonth(),n.getFullYear()),h=nt(n.getMonth(),s||"long"),b=et(n,o||"short"),w=Array.from({length:p},(m,v)=>{let g=new Date(n.getFullYear(),n.getMonth(),v+1);return {day:et(g,o||"short"),date:g.getDate(),month:nt(g.getMonth(),s||"long"),year:g.getFullYear()}});return {today:n,daysCount:p,month:h,day:b,days:w,next:u,prev:f}},qt=Ot;var Wt=(e,o)=>{let s=useRef(null);return useCallback((...r)=>{s.current&&clearTimeout(s.current),s.current=setTimeout(()=>{e(...r);},o);},[e,o])},At=Wt;var $t=(e=100)=>{let[o,s]=useState(false);return useEffect(()=>{let n=setTimeout(()=>s(true),e);return ()=>clearTimeout(n)},[e]),o},rt=$t;var Yt=e=>{let[o,s]=useState({width:0,height:0,top:0,left:0,bottom:0,right:0,x:0,y:0}),n=()=>{if(e){let{width:r,height:u,top:f,left:p,bottom:h,right:b,x:w,y:m}=e.getBoundingClientRect();s({width:r,height:u,top:f,left:p,bottom:h,right:b,x:w,y:m});}else s({width:window.innerWidth,height:window.innerHeight,top:0,left:0,bottom:0,right:0,x:0,y:0});};return useEffect(()=>(n(),window.addEventListener("resize",n),()=>window.removeEventListener("resize",n)),[]),o},C=Yt;var Qt=()=>{let e=navigator.userAgent,o=/Mobi|Android/i.test(e),s=/Tablet|iPad/i.test(e),n=C();return useEffect(()=>{},[]),{isMobile:o,isTablet:s,isDesktop:!o&&!s,...n}},Vt=Qt;var _t=(e,o=false)=>(useEffect(()=>{if(e){if(!window.fbq){let u=document.createElement("script");u.async=true,u.src="https://connect.facebook.net/en_US/fbevents.js",document.head.appendChild(u),window._fbq=window._fbq||[],window.fbq=function(){window._fbq.push(arguments);},window.fbq("init",e),o&&window.fbq("set","debug",true);}window.fbq("track","PageView");}},[e,o]),{trackPageView:()=>{e&&window.fbq("track","PageView");},trackEvent:(u,f)=>{e&&window.fbq("track",u,f);},trackCustom:(u,f)=>{e&&window.fbq("trackCustom",u,f);}}),Jt=_t;var Zt=e=>(useEffect(()=>{if(e){if(!window.gtag){let n=document.createElement("script");n.async=true,n.src=`https://www.googletagmanager.com/gtag/js?id=${e}`,document.head.appendChild(n),window.dataLayer=window.dataLayer||[],window.gtag=function(){window.dataLayer.push(arguments);},window.gtag("js",new Date);}window.gtag("config",e);}},[e]),{trackPageView:n=>{e&&window.gtag("config",e,{page_path:n||window.location.pathname});},trackEvent:(n,r)=>{e&&window.gtag("event",n,r);}}),Ct=Zt;var ne=(e,o,s)=>{let[n,r]=useState({loaded:false,error:null}),u=useRef(null);return useEffect(()=>{if(e&&e!==""){var f=new Image;o&&(f.crossOrigin=o),s&&(f.referrerPolicy=s),f.onload=()=>{u.current=f,r({loaded:true,error:null});},f.onerror=()=>{r({loaded:false,error:`Failed to load image at ${e}`});},f.src=e;}},[e]),[u.current?u.current.src:"",n.loaded,n.error]},re=ne;var se=(e,o,s="circle",n=1)=>{let[r,u]=useState(false),[f,p]=useState({x:0,y:0}),[h,b]=useState(n),w=useRef(null),m=useRef(null),v=()=>{let c=m.current,i=c?.getContext("2d"),a=w.current;!c||!i||!a||(c.width=o,c.height=o,i.clearRect(0,0,o,o),i.globalAlpha=.5,i.drawImage(a,f.x,f.y,a.width*h,a.height*h),i.globalAlpha=1,i.save(),s==="circle"&&(i.beginPath(),i.arc(o/2,o/2,o/2,0,Math.PI*2),i.closePath(),i.clip()),i.drawImage(a,f.x,f.y,a.width*h,a.height*h),i.restore());};return useEffect(v,[h]),useEffect(()=>{if(e){let c=new Image;c.onload=()=>{w.current=c,v();},c.src=e;}},[e,f]),{canvasRef:m,crop:()=>{let c=m.current;return c?c.toDataURL("image/png"):null},setScale:b,handleMouseDown:()=>u(true),handleMouseUp:()=>u(false),handleMouseMove:c=>{!r||!w.current||p(i=>({x:i.x+c.movementX,y:i.y+c.movementY}));}}},oe=se;var ce=(e,o={})=>{let[s,n]=useState(e&&e.length>0?new Array(e.length).fill(0):[]);return useEffect(()=>{if(!e||!e.length)return;let r=new IntersectionObserver(u=>{requestAnimationFrame(()=>{n(f=>{let p=[...f],h=false;return u.forEach(b=>{let w=e.findIndex(m=>m.current===b.target);w!==-1&&p[w]!==b.intersectionRatio&&(p[w]=b.intersectionRatio,h=true);}),h?p:f});});},{rootMargin:"200px",threshold:[1],...o});return e.forEach(u=>{u.current&&r.observe(u.current);}),()=>{e.forEach(u=>{u.current&&r.unobserve(u.current);});}},[e,o]),s},ue=ce;var at=(e,o,s,n=20)=>{if(!e||e.length===0||o<=0||s<=0)return "";let r=Math.min(...e.map(g=>g.x)),u=Math.max(...e.map(g=>g.x)),f=Math.min(...e.map(g=>g.y)),p=Math.max(...e.map(g=>g.y)),h=(o-2*n)/(u-r),b=(s-2*n)/(p-f),w=g=>{let S=(g.x-r)*h+n,x=s-((g.y-f)*b+n);return {x:S,y:x}},m=e.map(w),v="";if(m.length>0){v=`M ${m[0].x},${m[0].y}`;for(let g=0;g<m.length-1;g++){let S=m[g],x=m[g+1],l={x:(S.x+x.x)/2,y:S.y},c={x:(S.x+x.x)/2,y:x.y};v+=` C ${l.x},${l.y} ${c.x},${c.y} ${x.x},${x.y}`;}}return v},me=(e,o,s,n=20)=>{if(!e||e.length===0)return "";let r=at(e,o,s,n),u=Math.min(...e.map(m=>m.x)),f=Math.max(...e.map(m=>m.x)),p=(o-2*n)/(f-u),h=(e[0].x-u)*p+n,b=(e[e.length-1].x-u)*p+n,w=s-n;return `${r} L ${b},${w} L ${h},${w} Z`},fe=(e,o={width:600,height:300},s=20)=>{let[n,r]=useState(""),[u,f]=useState("");return useEffect(()=>{let p=at(e,o.width,o.height,s);r(p);let h=me(e,o.width,o.height,s);f(h);},[e,o.width,o.height,s]),{pathD:n,areaPathD:u}},pe=fe;var he=(e,o,s={childList:true,subtree:true})=>{let n=useRef(null);useEffect(()=>{if(e)return n.current=new MutationObserver(o),n.current.observe(e,s),()=>{n.current&&n.current.disconnect();}},[e,o,s]);},tt=he;var xe=()=>{let[e,o]=useState(null),s=()=>{o(navigator.onLine);};return useEffect(()=>(setTimeout(()=>o(navigator.onLine)),window.addEventListener("online",s),window.addEventListener("offline",s),()=>{window.removeEventListener("online",s),window.removeEventListener("offline",s);}),[]),e},ve=xe;var Ee=(e=15)=>{if(e<=0)throw new Error("intervalMinutes must be greater than 0");let o=b=>{let w=new Date(b),m=w.getMinutes(),v=m%e;return v===0?w.setMinutes(m+e):w.setMinutes(m+(e-v)),w.setSeconds(0),w.setMilliseconds(0),w},[s,n]=useState(()=>o(new Date));useEffect(()=>{let b=()=>{let v=o(new Date);v.getTime()!==s.getTime()&&n(v);};b();let w=setInterval(b,1e3);return ()=>clearInterval(w)},[e,s]);let r=new Date,u=Math.max(0,s.getTime()-r.getTime()),f=Math.floor(u/6e4),p=Math.floor(u%6e4/1e3),h=`${f}m ${p.toString().padStart(2,"0")}s`;return {minutes:f,seconds:p,formatted:h,nextBoundary:s}},De=Ee;var Te=e=>{let{vapidPublicKey:o,serviceWorkerPath:s="/sw.js",requestPermissionOnMount:n=false}=e,[r,u]=useState("default"),[f,p]=useState(null),[h,b]=useState(null),[w,m]=useState(null),[v,g]=useState(false),[S,x]=useState(null),[l,c]=useState(false),i=useCallback(async()=>{if(!l)return null;try{let d=await navigator.serviceWorker.register(s,{scope:"/",updateViaCache:"all"});return x(d),d}catch(d){return console.error("Service Worker registration failed:",d),m("Failed to register service worker"),null}},[s,l]),a=useCallback(async d=>{try{let P=await d.pushManager.getSubscription();return p(P),b(P?P.toJSON():null),P}catch(P){return console.error("Failed to get subscription:",P),m("Failed to get subscription"),null}},[]),M=useCallback(async()=>{if(!l||!S)return m("Push not supported or service worker not registered"),null;g(true),m(null);try{let d=await Notification.requestPermission();if(u(d),d!=="granted")return m("Permission not granted for notifications"),g(!1),null;let P=urlBase64ToUint8Array(o),D=await S.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:P});return p(D),b(D.toJSON()),g(!1),D}catch(d){return console.error("Subscription failed:",d),m(d.message||"Failed to subscribe"),g(false),null}},[l,S,o]),E=useCallback(async()=>{if(!f)return true;try{let d=await f.unsubscribe();return d&&(p(null),b(null)),d}catch(d){return console.error("Failed to unsubscribe:",d),false}},[f]),T=useCallback(async()=>{let d=await Notification.requestPermission();return u(d),d},[]);return useEffect(()=>{let d="PushManager"in window&&"serviceWorker"in navigator;if(c(d),!d){m("Push notifications not supported in this browser");return}let P=true;return (async()=>{let R=await i();!R||!P||(u(Notification.permission),await a(R),n&&Notification.permission==="default"&&await T());})(),()=>{P=false;}},[l,i,a,n,T]),useEffect(()=>{if(!("permissions"in navigator))return;let d=false;(async()=>{if(d)return;let D=await navigator.permissions.query({name:"notifications"});D.onchange=()=>{u(Notification.permission),Notification.permission==="denied"&&(d=true,E());};})();},[E]),{permission:r,subscription:f,subscriptionMeta:h,isSupported:l,subscribe:M,unsubscribe:E,requestPermission:T,error:w,isLoading:v}},Le=Te;var Ie=e=>{let[o,s]=useState({width:0,height:0,top:0,left:0});return useEffect(()=>{let n=e instanceof HTMLElement?e:e.current,r=f=>{for(let p of f){let{width:h,height:b,top:w,left:m}=p.contentRect;s({width:h,height:b,top:w,left:m});}},u=new ResizeObserver(r);return n&&u.observe(n),()=>{n&&u.unobserve(n);}},[e]),o},Fe=Ie;var Be=(e,o={})=>{let s=useRef(null),n=useRef(null),r=useRef(null),u=useRef(null),f=useMemo(()=>e??1,[e]),p=useRef(false),h=useRef(false),b=useRef(0),w=useRef(0),m=useRef(0),v=useRef(0),g=useRef(null),S=useCallback(()=>{if(!n.current||!r.current||!u.current)return;let{clientHeight:D,scrollHeight:R,scrollTop:O,clientWidth:I,scrollWidth:A,scrollLeft:q}=n.current,W=Math.max(D/R*D,30),H=D-W,F=O/(R-D)*H;r.current.style.height=`${W}px`,r.current.style.transform=`translateY(${F}px)`,r.current.style.willChange="transform, height";let z=Math.max(I/A*I,30),Q=I-z,pt=q/(A-I)*Q;u.current.style.width=`${z}px`,u.current.style.transform=`translateX(${pt}px)`,u.current.style.willChange="transform, width",R<=D&&s.current?s.current.classList.add("--no-y"):s.current&&s.current.classList.remove("--no-y"),A<=I&&s.current?s.current.classList.add("--no-x"):s.current&&s.current.classList.remove("--no-x");},[]),x=useCallback(()=>{g.current&&cancelAnimationFrame(g.current),g.current=requestAnimationFrame(()=>{if(S(),n.current){let{scrollTop:D,scrollHeight:R,clientHeight:O,scrollLeft:I,scrollWidth:A,clientWidth:q}=n.current,N=D/(R-O)*100,W=I/(A-q)*100;Object.keys(o).forEach(H=>{let F=parseFloat(H);Math.abs(N-F)<1&&o[F]?.(),Math.abs(W-F)<1&&o[F]?.();});}});},[S,o]),l=useCallback(()=>{n.current&&x();},[x]),c=D=>{p.current=true,w.current=D.clientY,m.current=n.current?.scrollTop||0,document.body.style.userSelect="none",s.current&&s.current?.classList.add("--scrolling");},i=D=>{h.current=true,b.current=D.clientX,v.current=n.current?.scrollLeft||0,document.body.style.userSelect="none",s.current&&s.current?.classList.add("--scrolling");},a=useCallback(D=>{if(!n.current||!p.current&&!h.current)return;let{clientHeight:R,scrollHeight:O,clientWidth:I,scrollWidth:A}=n.current;if(p.current){let q=O-R,N=r.current?.clientHeight||30,W=R-N,H=D.clientY-w.current,F=Math.min(Math.max(m.current+H/W*q,0),q);n.current.scrollTop=F;}if(h.current){let q=A-I,N=u.current?.clientWidth||30,W=I-N,H=D.clientX-b.current,F=Math.min(Math.max(v.current+H/W*q,0),q);n.current.scrollLeft=F;}},[]),M=()=>{p.current=false,h.current=false,document.body.style.userSelect="",s.current&&s.current?.classList.remove("--scrolling"),g.current&&cancelAnimationFrame(g.current);},E=()=>n.current?.scrollTo({top:0,behavior:"smooth"}),T=()=>n.current?.scrollTo({top:n.current.scrollHeight,behavior:"smooth"}),d=()=>n.current?.scrollTo({left:0,behavior:"smooth"}),P=()=>n.current?.scrollTo({left:n.current.scrollWidth,behavior:"smooth"});return useEffect(()=>{let D=n.current;if(!D)return;let R=O=>{if(!n.current)return;let{scrollTop:I,scrollHeight:A,clientHeight:q,scrollLeft:N,scrollWidth:W,clientWidth:H}=n.current,F=I,Y=N,z=false;if(Math.abs(O.deltaY)>Math.abs(O.deltaX)){let Q=A-q;F=I+O.deltaY*f,F=Math.max(0,Math.min(F,Q)),F!==I&&(n.current.scrollTop=F,z=true);}else {let Q=W-H;Y=N+O.deltaX*f,Y=Math.max(0,Math.min(Y,Q)),Y!==N&&(n.current.scrollLeft=Y,z=true);}z&&x();};return window.addEventListener("resize",x),D.addEventListener("scroll",l,{passive:true}),D.addEventListener("wheel",R,{passive:true}),document.addEventListener("mousemove",a),document.addEventListener("mouseup",M),x(),()=>{window.removeEventListener("resize",x),D.removeEventListener("scroll",l),D.removeEventListener("wheel",R),document.removeEventListener("mousemove",a),document.removeEventListener("mouseup",M),g.current&&cancelAnimationFrame(g.current);}},[l,a,x,f]),tt(n.current,x),{rootRef:s,containerRef:n,thumbY:r,thumbX:u,scrollToTop:E,scrollToBottom:T,scrollToLeft:d,scrollToRight:P,onScrollY:c,onScrollX:i}},Ne=Be;var He=(e,o)=>{let{lerpFactor:s=.1,x:n,y:r,xMultiplier:u=.25,yMultiplier:f=.25,scale:p,rotate:h}=o,b=useRef(0),w=useRef(0),m=useRef(0),v=useRef(0),g=useRef(performance.now()),S=useRef(null),x=useRef(false),l=useRef(0),c=.2;return useEffect(()=>{if(typeof window>"u")return;let i=()=>{let M=performance.now(),E=(M-g.current)/1e3;g.current=M;let T=v.current-m.current,d=T/E;if(m.current+=T*s,b.current=m.current,w.current=d,l.current+=(d-l.current)*s,e.current){let P=n?b.current*n*u:0,D=r?b.current*r*f:0,R=p?clamp(p.max-Math.abs(l.current)*p.factor,p.min,p.max):1,O=h?w.current*(h.multiplier??1)*(h.direction??1):0;e.current.style.transform=`
4
+ translate3d(${P}px, ${D}px, 0)
5
+ scale(${R})
6
+ rotate(${O}deg)
7
+ `.trim();}Math.abs(T)>c||Math.abs(d)>c?S.current=requestAnimationFrame(i):(x.current=false,S.current=null);},a=()=>{v.current=window.scrollY,x.current||(g.current=performance.now(),S.current=requestAnimationFrame(i),x.current=true);};return window.addEventListener("scroll",a,{passive:true}),()=>{window.removeEventListener("scroll",a),S.current&&cancelAnimationFrame(S.current);}},[s,n,r,u,f,p,h]),{position:b,velocity:w}},ye=He;var Ue=(e,o)=>{useEffect(()=>{let s=n=>{let r=[];n.ctrlKey&&r.push(17),n.shiftKey&&r.push(16),n.altKey&&r.push(18),n.metaKey&&r.push(19),r.push(n.keyCode),e.forEach(({keys:u,callback:f})=>{u.every(p=>r.includes(p))&&((o??true)&&n.preventDefault(),f(n));});};return window.addEventListener("keydown",s),()=>window.removeEventListener("keydown",s)},[e,o]);},Xe=Ue;var Ve=e=>{let{apiUrl:o,onChange:s,onQueFinished:n}=e,r=useRef({que:[],index:-1,speed:0,stamp:null,token:null,status:0}),u=()=>s?.(b()),f=()=>{},p=()=>{r.current.stamp=Date.now();let g=b(),S=new FormData;S.append("ID",g.ID),S.append("dir",g.dir),S.append("server",g.server.ID),S.append("token",g.server.token),S.append("file",g.file),S.append("fs",g.file.size.toString()),r.current.cancelToken=getCancelToken(),withPost(`${r.current.que[r.current.index].server.uri}/receive`,S,86400,true,void 0,x=>{r.current.que[r.current.index].status=2,s?.({...b(),progress:x.progress||0});}).then(x=>{r.current.que[r.current.index].progress=1,r.current.que[r.current.index].status=4,r.current.status=0,u(),m();}).catch(x=>{r.current.que[r.current.index].status=-1,r.current.status=0,u(),m();});},h=g=>{r.current.que[r.current.index].status=1,u(),withPost(`${o}get_server`,{size:b().file.size}).then(S=>{r.current.que[r.current.index].server=S.server,r.current.que[r.current.index].status=2,u(),p();}).catch(S=>{r.current.que[r.current.index].status=-1,r.current.status=0,u(),m();});},b=()=>r.current.que[r.current.index],w=()=>r.current.que,m=()=>{r.current.status==0&&r.current.que.length-1>r.current.index?(r.current.status=2,r.current.index++,r.current.que[r.current.index].status=2,u(),r.current.que[r.current.index].remote?f():h()):n?.();};return {get:()=>r,getQue:w,addToQue:g=>{r.current.que.push({ID:uuid(12),file:g.file,dir:g.dir,remote:g.remote,progress:0,speed:0,eta:0,bytes:0,status:0,server:null}),m();}}},je=Ve;var U=new Map,y=new Map,_=new Map,_e=(e,o)=>{let{onOpen:s,onClose:n,onRawMessage:r,onMessage:u,onError:f,reconnect:p=true}=o||{},[h,b]=useState(false),[w,m]=useState([]),v=c=>_.get(c)??2,g=c=>{let i=v(c),a=Math.min(i*2,60);return _.set(c,a),a*1e3},S=c=>{_.set(c,2);},x=useCallback(()=>{if(U.has(e)){let i=U.get(e);i&&(i.onmessage=a=>{m(E=>[...E,a.data]),r?.(a);let M=JSON.parse(Buffer.isBuffer(a)?a.toString("utf8"):typeof a=="string"?a:a.data);u?.(M),y.get(e)?.forEach(E=>E(a));});return}let c=new WebSocket(e);U.set(e,c),y.set(e,[]),c.onopen=i=>{b(true),S(e),s?.(i);},c.onmessage=i=>{m(M=>[...M,i.data]),r?.(i);let a=JSON.parse(Buffer.isBuffer(i)?i.toString("utf8"):typeof i=="string"?i:i.data);u?.(a),y.get(e)?.forEach(M=>M(i));},c.onerror=i=>{f?.(i);},c.onclose=i=>{if(b(false),n?.(i),U.delete(e),y.delete(e),p&&i.code!==1e3){let a=g(e);console.log(`Reconnecting in ${a/1e3} seconds...`),setTimeout(()=>{U.has(e)||x();},a);}};},[e,s,n,u,f,p]);useEffect(()=>(x(),()=>{y.get(e)?.length===0&&(U.get(e)?.close(),U.delete(e),y.delete(e),_.delete(e));}),[]),useEffect(()=>{let c=i=>m(a=>[...a,i.data]);return y.get(e)?.push(c),()=>{let i=y.get(e)||[];y.set(e,i.filter(a=>a!==c));}},[e]);let l=useCallback(c=>{let i=U.get(e);if(i&&i.readyState===WebSocket.OPEN){let a=typeof c=="string"?c:JSON.stringify(c);i.send(a);}else console.log("WebSocket is not connected.");},[e]);return {isConnected:h,messages:w,sendMessage:l}},Je=_e;export{J as CropShape,G as KeyCode,kt as useAnchorPosition,qt as useCalendar,bt as useCommandActions,St as useDB,At as useDebounce,rt as useDelayed,Vt as useDevice,C as useDimensions,Jt as useFacebookPixel,Ct as useGoogleTagManager,re as useImage,oe as useImageCropper,ue as useIntersectionObserver,pe as useLineChart,rt as useMounted,tt as useMutationObserver,ve as useNetworkStatus,De as useNextInterval,Le as usePushNotifications,Fe as useResizeObserver,ye as useScrollPhysics,Ne as useScrollbar,Xe as useShortcuts,je as useUploader,Je as useWebSocket};
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@zuzjs/hooks",
3
+ "version": "0.1.2",
4
+ "description": "ZuzJS Hooks",
5
+ "keywords": [
6
+ "react",
7
+ "zuz",
8
+ "zuz.js",
9
+ "zuz ui",
10
+ "zuzui"
11
+ ],
12
+ "homepage": "https://hooks.zuz.com.pk",
13
+ "bugs": {
14
+ "url": "https://github.com/zuzpk/zuzjs-hooks/issues"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/zuzpk/zuzjs-hooks.git"
19
+ },
20
+ "license": "MIT",
21
+ "author": "Zuz.js Team <support@zuz.com.pk>",
22
+ "type": "module",
23
+ "main": "./dist/index.cjs",
24
+ "module": "./dist/index.js",
25
+ "types": "./dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.js",
30
+ "require": "./dist/index.cjs"
31
+ }
32
+ },
33
+ "files": [
34
+ "dist"
35
+ ],
36
+ "engines": {
37
+ "node": ">=18.17.0"
38
+ },
39
+ "dependencies": {
40
+ "@types/md5": "^2.3.6",
41
+ "@types/react": "^19.2.10",
42
+ "@types/react-dom": "^19.2.3",
43
+ "@zuzjs/core": "^0.3.2",
44
+ "chokidar": "^5.0.0",
45
+ "commander": "^14.0.2",
46
+ "date-fns": "^4.1.0",
47
+ "hashids": "^2.3.0",
48
+ "js-cookie": "^3.0.5",
49
+ "md5": "^2.3.0",
50
+ "moment": "^2.30.1",
51
+ "nanoid": "^5.1.6",
52
+ "picocolors": "^1.1.1",
53
+ "react": "^19.2.3",
54
+ "react-dom": "^19.2.3"
55
+ },
56
+ "peerDependencies": {
57
+ "react": "^19.2.3",
58
+ "react-dom": "^19.2.3"
59
+ }
60
+ }