@alessiofrittoli/react-hooks 1.0.0 → 1.1.0

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.
Files changed (42) hide show
  1. package/README.md +10 -0
  2. package/dist/browser-api/index.js +1 -1
  3. package/dist/browser-api/index.mjs +1 -1
  4. package/dist/browser-api/storage/index.js +1 -1
  5. package/dist/browser-api/storage/index.mjs +1 -1
  6. package/dist/browser-api/storage/useLocalStorage.js +1 -1
  7. package/dist/browser-api/storage/useLocalStorage.mjs +1 -1
  8. package/dist/browser-api/storage/useSessionStorage.js +1 -1
  9. package/dist/browser-api/storage/useSessionStorage.mjs +1 -1
  10. package/dist/browser-api/storage/useStorage.js +1 -1
  11. package/dist/browser-api/storage/useStorage.mjs +1 -1
  12. package/dist/browser-api/useIsPortrait.js +1 -1
  13. package/dist/browser-api/useIsPortrait.mjs +1 -1
  14. package/dist/browser-api/useMediaQuery.js +1 -1
  15. package/dist/browser-api/useMediaQuery.mjs +1 -1
  16. package/dist/dom-api/index.js +1 -1
  17. package/dist/dom-api/index.mjs +1 -1
  18. package/dist/dom-api/useFocusTrap.js +1 -1
  19. package/dist/dom-api/useFocusTrap.mjs +1 -1
  20. package/dist/dom-api/useScrollBlock.js +1 -1
  21. package/dist/dom-api/useScrollBlock.mjs +1 -1
  22. package/dist/eslint.js +1 -1
  23. package/dist/eslint.mjs +1 -1
  24. package/dist/index.js +1 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/index.mjs +1 -1
  27. package/dist/index.mjs.map +1 -1
  28. package/dist/misc/index.js +1 -1
  29. package/dist/misc/index.mjs +1 -1
  30. package/dist/misc/useIsClient.js +1 -1
  31. package/dist/misc/useIsClient.mjs +1 -1
  32. package/dist/misc/useIsFirstRender.js +1 -1
  33. package/dist/misc/useIsFirstRender.mjs +1 -1
  34. package/dist/misc/usePagination.d.mts +12 -0
  35. package/dist/misc/usePagination.d.ts +12 -0
  36. package/dist/misc/usePagination.js +2 -0
  37. package/dist/misc/usePagination.js.map +1 -0
  38. package/dist/misc/usePagination.mjs +2 -0
  39. package/dist/misc/usePagination.mjs.map +1 -0
  40. package/dist/misc/useUpdateEffect.js +1 -1
  41. package/dist/misc/useUpdateEffect.mjs +1 -1
  42. package/package.json +4 -2
package/README.md CHANGED
@@ -726,6 +726,16 @@ export const ClientComponent: React.FC = () => {
726
726
 
727
727
  ---
728
728
 
729
+ ##### `usePagination`
730
+
731
+ Get pagination informations based on the given options.
732
+
733
+ This hook memoize the returned result of the [`paginate`](https://github.com/alessiofrittoli/math-utils/blob/master/docs/helpers/README.md#paginate) function imported from [`@alessiofrittoli/math-utils`](https://npmjs.com/package/@alessiofrittoli/math-utils).
734
+
735
+ See [`paginate`](https://github.com/alessiofrittoli/math-utils/blob/master/docs/helpers/README.md#paginate) function Documentation for more information about it.
736
+
737
+ ---
738
+
729
739
  ### Development
730
740
 
731
741
  #### Install depenendencies
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react'),LocalStorage=require('@alessiofrittoli/web-utils/storage/LocalStorage'),SessionStorage=require('@alessiofrittoli/web-utils/storage/SessionStorage'),browserApi=require('@alessiofrittoli/web-utils/browser-api'),device=require('@alessiofrittoli/web-utils/device');var a=(e,t,r="local")=>{let o=react.useCallback(()=>(r==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).get(e)??t,[r,e,t]),[s,c]=react.useState(t),g=react.useCallback(n=>{c(p=>{let i=n instanceof Function?n(p):n;return (typeof window<"u"&&r==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).set(e,i),i});},[r,e]);return react.useEffect(()=>{c(o());},[o]),[s,g]};var b=(e,t)=>a(e,t,"local");var A=(e,t)=>a(e,t,"session");var d=e=>{let[t,r]=react.useState(browserApi.getMediaMatches(e)),o=react.useCallback(()=>r(browserApi.getMediaMatches(e)),[e]);return react.useEffect(()=>{let s=window.matchMedia(e);return o(),s.addEventListener("change",o),()=>{s.removeEventListener("change",o);}},[e,o]),t};var z=()=>d(device.portraitMediaQuery);exports.useIsPortrait=z;exports.useLocalStorage=b;exports.useMediaQuery=d;exports.useSessionStorage=A;exports.useStorage=a;//# sourceMappingURL=index.js.map
1
+ 'use strict';var react=require('react'),LocalStorage=require('@alessiofrittoli/web-utils/storage/LocalStorage'),SessionStorage=require('@alessiofrittoli/web-utils/storage/SessionStorage'),browserApi=require('@alessiofrittoli/web-utils/browser-api'),device=require('@alessiofrittoli/web-utils/device');var n=(e,t,r="local")=>{let o=react.useCallback(()=>(r==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).get(e)??t,[r,e,t]),[a,i]=react.useState(t),p=react.useCallback(c=>{i(S=>{let u=c instanceof Function?c(S):c;return (typeof window<"u"&&r==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).set(e,u),u});},[r,e]);return react.useEffect(()=>{i(o());},[o]),[a,p]};var R=(e,t)=>n(e,t,"local");var H=(e,t)=>n(e,t,"session");var g=e=>{let[t,r]=react.useState(browserApi.getMediaMatches(e)),o=react.useCallback(()=>r(browserApi.getMediaMatches(e)),[e]);return react.useEffect(()=>{let a=window.matchMedia(e);return o(),a.addEventListener("change",o),()=>{a.removeEventListener("change",o);}},[e,o]),t};var N=()=>g(device.portraitMediaQuery);exports.useIsPortrait=N;exports.useLocalStorage=R;exports.useMediaQuery=g;exports.useSessionStorage=H;exports.useStorage=n;//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map
@@ -1,2 +1,2 @@
1
- import {useCallback,useState,useEffect}from'react';import {LocalStorage}from'@alessiofrittoli/web-utils/storage/LocalStorage';import {SessionStorage}from'@alessiofrittoli/web-utils/storage/SessionStorage';import {getMediaMatches}from'@alessiofrittoli/web-utils/browser-api';import {portraitMediaQuery}from'@alessiofrittoli/web-utils/device';var a=(e,t,r="local")=>{let o=useCallback(()=>(r==="local"?LocalStorage:SessionStorage).get(e)??t,[r,e,t]),[s,c]=useState(t),g=useCallback(n=>{c(p=>{let i=n instanceof Function?n(p):n;return (typeof window<"u"&&r==="local"?LocalStorage:SessionStorage).set(e,i),i});},[r,e]);return useEffect(()=>{c(o());},[o]),[s,g]};var b=(e,t)=>a(e,t,"local");var A=(e,t)=>a(e,t,"session");var d=e=>{let[t,r]=useState(getMediaMatches(e)),o=useCallback(()=>r(getMediaMatches(e)),[e]);return useEffect(()=>{let s=window.matchMedia(e);return o(),s.addEventListener("change",o),()=>{s.removeEventListener("change",o);}},[e,o]),t};var z=()=>d(portraitMediaQuery);export{z as useIsPortrait,b as useLocalStorage,d as useMediaQuery,A as useSessionStorage,a as useStorage};//# sourceMappingURL=index.mjs.map
1
+ import {useCallback,useState,useEffect}from'react';import {LocalStorage}from'@alessiofrittoli/web-utils/storage/LocalStorage';import {SessionStorage}from'@alessiofrittoli/web-utils/storage/SessionStorage';import {getMediaMatches}from'@alessiofrittoli/web-utils/browser-api';import {portraitMediaQuery}from'@alessiofrittoli/web-utils/device';var c=(e,t,r="local")=>{let o=useCallback(()=>(r==="local"?LocalStorage:SessionStorage).get(e)??t,[r,e,t]),[n,u]=useState(t),S=useCallback(i=>{u(T=>{let l=i instanceof Function?i(T):i;return (typeof window<"u"&&r==="local"?LocalStorage:SessionStorage).set(e,l),l});},[r,e]);return useEffect(()=>{u(o());},[o]),[n,S]};var A=(e,t)=>c(e,t,"local");var I=(e,t)=>c(e,t,"session");var p=e=>{let[t,r]=useState(getMediaMatches(e)),o=useCallback(()=>r(getMediaMatches(e)),[e]);return useEffect(()=>{let n=window.matchMedia(e);return o(),n.addEventListener("change",o),()=>{n.removeEventListener("change",o);}},[e,o]),t};var O=()=>p(portraitMediaQuery);export{O as useIsPortrait,A as useLocalStorage,p as useMediaQuery,I as useSessionStorage,c as useStorage};//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react'),LocalStorage=require('@alessiofrittoli/web-utils/storage/LocalStorage'),SessionStorage=require('@alessiofrittoli/web-utils/storage/SessionStorage');var r=(e,o,t="local")=>{let a=react.useCallback(()=>(t==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).get(e)??o,[t,e,o]),[i,n]=react.useState(o),T=react.useCallback(s=>{n(f=>{let l=s instanceof Function?s(f):s;return (typeof window<"u"&&t==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).set(e,l),l});},[t,e]);return react.useEffect(()=>{n(a());},[a]),[i,T]};var L=(e,o)=>r(e,o,"local");var h=(e,o)=>r(e,o,"session");exports.useLocalStorage=L;exports.useSessionStorage=h;exports.useStorage=r;//# sourceMappingURL=index.js.map
1
+ 'use strict';var react=require('react'),LocalStorage=require('@alessiofrittoli/web-utils/storage/LocalStorage'),SessionStorage=require('@alessiofrittoli/web-utils/storage/SessionStorage');var r=(e,o,t="local")=>{let n=react.useCallback(()=>(t==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).get(e)??o,[t,e,o]),[T,l]=react.useState(o),f=react.useCallback(s=>{l(g=>{let u=s instanceof Function?s(g):s;return (typeof window<"u"&&t==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).set(e,u),u});},[t,e]);return react.useEffect(()=>{l(n());},[n]),[T,f]};var b=(e,o)=>r(e,o,"local");var D=(e,o)=>r(e,o,"session");exports.useLocalStorage=b;exports.useSessionStorage=D;exports.useStorage=r;//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map
@@ -1,2 +1,2 @@
1
- import {useCallback,useState,useEffect}from'react';import {LocalStorage}from'@alessiofrittoli/web-utils/storage/LocalStorage';import {SessionStorage}from'@alessiofrittoli/web-utils/storage/SessionStorage';var r=(e,o,t="local")=>{let a=useCallback(()=>(t==="local"?LocalStorage:SessionStorage).get(e)??o,[t,e,o]),[i,n]=useState(o),T=useCallback(s=>{n(f=>{let l=s instanceof Function?s(f):s;return (typeof window<"u"&&t==="local"?LocalStorage:SessionStorage).set(e,l),l});},[t,e]);return useEffect(()=>{n(a());},[a]),[i,T]};var L=(e,o)=>r(e,o,"local");var h=(e,o)=>r(e,o,"session");export{L as useLocalStorage,h as useSessionStorage,r as useStorage};//# sourceMappingURL=index.mjs.map
1
+ import {useCallback,useState,useEffect}from'react';import {LocalStorage}from'@alessiofrittoli/web-utils/storage/LocalStorage';import {SessionStorage}from'@alessiofrittoli/web-utils/storage/SessionStorage';var r=(e,o,t="local")=>{let l=useCallback(()=>(t==="local"?LocalStorage:SessionStorage).get(e)??o,[t,e,o]),[f,u]=useState(o),g=useCallback(s=>{u(m=>{let c=s instanceof Function?s(m):s;return (typeof window<"u"&&t==="local"?LocalStorage:SessionStorage).set(e,c),c});},[t,e]);return useEffect(()=>{u(l());},[l]),[f,g]};var h=(e,o)=>r(e,o,"local");var E=(e,o)=>r(e,o,"session");export{h as useLocalStorage,E as useSessionStorage,r as useStorage};//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react'),LocalStorage=require('@alessiofrittoli/web-utils/storage/LocalStorage'),SessionStorage=require('@alessiofrittoli/web-utils/storage/SessionStorage');var S=(e,t,o="local")=>{let r=react.useCallback(()=>(o==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).get(e)??t,[o,e,t]),[T,s]=react.useState(t),i=react.useCallback(a=>{s(f=>{let l=a instanceof Function?a(f):a;return (typeof window<"u"&&o==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).set(e,l),l});},[o,e]);return react.useEffect(()=>{s(r());},[r]),[T,i]};var L=(e,t)=>S(e,t,"local");exports.useLocalStorage=L;//# sourceMappingURL=useLocalStorage.js.map
1
+ 'use strict';var react=require('react'),LocalStorage=require('@alessiofrittoli/web-utils/storage/LocalStorage'),SessionStorage=require('@alessiofrittoli/web-utils/storage/SessionStorage');var S=(e,t,o="local")=>{let r=react.useCallback(()=>(o==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).get(e)??t,[o,e,t]),[T,s]=react.useState(t),i=react.useCallback(a=>{s(f=>{let l=a instanceof Function?a(f):a;return (typeof window<"u"&&o==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).set(e,l),l});},[o,e]);return react.useEffect(()=>{s(r());},[r]),[T,i]};var b=(e,t)=>S(e,t,"local");exports.useLocalStorage=b;//# sourceMappingURL=useLocalStorage.js.map
2
2
  //# sourceMappingURL=useLocalStorage.js.map
@@ -1,2 +1,2 @@
1
- import {useCallback,useState,useEffect}from'react';import {LocalStorage}from'@alessiofrittoli/web-utils/storage/LocalStorage';import {SessionStorage}from'@alessiofrittoli/web-utils/storage/SessionStorage';var S=(e,t,o="local")=>{let r=useCallback(()=>(o==="local"?LocalStorage:SessionStorage).get(e)??t,[o,e,t]),[T,s]=useState(t),i=useCallback(a=>{s(f=>{let l=a instanceof Function?a(f):a;return (typeof window<"u"&&o==="local"?LocalStorage:SessionStorage).set(e,l),l});},[o,e]);return useEffect(()=>{s(r());},[r]),[T,i]};var L=(e,t)=>S(e,t,"local");export{L as useLocalStorage};//# sourceMappingURL=useLocalStorage.mjs.map
1
+ import {useCallback,useState,useEffect}from'react';import {LocalStorage}from'@alessiofrittoli/web-utils/storage/LocalStorage';import {SessionStorage}from'@alessiofrittoli/web-utils/storage/SessionStorage';var S=(e,t,o="local")=>{let r=useCallback(()=>(o==="local"?LocalStorage:SessionStorage).get(e)??t,[o,e,t]),[T,s]=useState(t),i=useCallback(a=>{s(f=>{let l=a instanceof Function?a(f):a;return (typeof window<"u"&&o==="local"?LocalStorage:SessionStorage).set(e,l),l});},[o,e]);return useEffect(()=>{s(r());},[r]),[T,i]};var h=(e,t)=>S(e,t,"local");export{h as useLocalStorage};//# sourceMappingURL=useLocalStorage.mjs.map
2
2
  //# sourceMappingURL=useLocalStorage.mjs.map
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react'),LocalStorage=require('@alessiofrittoli/web-utils/storage/LocalStorage'),SessionStorage=require('@alessiofrittoli/web-utils/storage/SessionStorage');var S=(e,t,o="local")=>{let r=react.useCallback(()=>(o==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).get(e)??t,[o,e,t]),[T,a]=react.useState(t),i=react.useCallback(s=>{a(f=>{let n=s instanceof Function?s(f):s;return (typeof window<"u"&&o==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).set(e,n),n});},[o,e]);return react.useEffect(()=>{a(r());},[r]),[T,i]};var R=(e,t)=>S(e,t,"session");exports.useSessionStorage=R;//# sourceMappingURL=useSessionStorage.js.map
1
+ 'use strict';var react=require('react'),LocalStorage=require('@alessiofrittoli/web-utils/storage/LocalStorage'),SessionStorage=require('@alessiofrittoli/web-utils/storage/SessionStorage');var S=(e,t,o="local")=>{let r=react.useCallback(()=>(o==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).get(e)??t,[o,e,t]),[T,a]=react.useState(t),i=react.useCallback(s=>{a(f=>{let n=s instanceof Function?s(f):s;return (typeof window<"u"&&o==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).set(e,n),n});},[o,e]);return react.useEffect(()=>{a(r());},[r]),[T,i]};var h=(e,t)=>S(e,t,"session");exports.useSessionStorage=h;//# sourceMappingURL=useSessionStorage.js.map
2
2
  //# sourceMappingURL=useSessionStorage.js.map
@@ -1,2 +1,2 @@
1
- import {useCallback,useState,useEffect}from'react';import {LocalStorage}from'@alessiofrittoli/web-utils/storage/LocalStorage';import {SessionStorage}from'@alessiofrittoli/web-utils/storage/SessionStorage';var S=(e,t,o="local")=>{let r=useCallback(()=>(o==="local"?LocalStorage:SessionStorage).get(e)??t,[o,e,t]),[T,a]=useState(t),i=useCallback(s=>{a(f=>{let n=s instanceof Function?s(f):s;return (typeof window<"u"&&o==="local"?LocalStorage:SessionStorage).set(e,n),n});},[o,e]);return useEffect(()=>{a(r());},[r]),[T,i]};var R=(e,t)=>S(e,t,"session");export{R as useSessionStorage};//# sourceMappingURL=useSessionStorage.mjs.map
1
+ import {useCallback,useState,useEffect}from'react';import {LocalStorage}from'@alessiofrittoli/web-utils/storage/LocalStorage';import {SessionStorage}from'@alessiofrittoli/web-utils/storage/SessionStorage';var S=(e,t,o="local")=>{let r=useCallback(()=>(o==="local"?LocalStorage:SessionStorage).get(e)??t,[o,e,t]),[T,a]=useState(t),i=useCallback(s=>{a(f=>{let n=s instanceof Function?s(f):s;return (typeof window<"u"&&o==="local"?LocalStorage:SessionStorage).set(e,n),n});},[o,e]);return useEffect(()=>{a(r());},[r]),[T,i]};var A=(e,t)=>S(e,t,"session");export{A as useSessionStorage};//# sourceMappingURL=useSessionStorage.mjs.map
2
2
  //# sourceMappingURL=useSessionStorage.mjs.map
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react'),LocalStorage=require('@alessiofrittoli/web-utils/storage/LocalStorage'),SessionStorage=require('@alessiofrittoli/web-utils/storage/SessionStorage');var p=(e,o,t="local")=>{let s=react.useCallback(()=>(t==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).get(e)??o,[t,e,o]),[S,l]=react.useState(o),T=react.useCallback(a=>{l(V=>{let n=a instanceof Function?a(V):a;return (typeof window<"u"&&t==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).set(e,n),n});},[t,e]);return react.useEffect(()=>{l(s());},[s]),[S,T]};exports.useStorage=p;//# sourceMappingURL=useStorage.js.map
1
+ 'use strict';var react=require('react'),LocalStorage=require('@alessiofrittoli/web-utils/storage/LocalStorage'),SessionStorage=require('@alessiofrittoli/web-utils/storage/SessionStorage');var w=(e,o,t="local")=>{let s=react.useCallback(()=>(t==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).get(e)??o,[t,e,o]),[S,l]=react.useState(o),T=react.useCallback(a=>{l(V=>{let n=a instanceof Function?a(V):a;return (typeof window<"u"&&t==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).set(e,n),n});},[t,e]);return react.useEffect(()=>{l(s());},[s]),[S,T]};exports.useStorage=w;//# sourceMappingURL=useStorage.js.map
2
2
  //# sourceMappingURL=useStorage.js.map
@@ -1,2 +1,2 @@
1
- import {useCallback,useState,useEffect}from'react';import {LocalStorage}from'@alessiofrittoli/web-utils/storage/LocalStorage';import {SessionStorage}from'@alessiofrittoli/web-utils/storage/SessionStorage';var p=(e,o,t="local")=>{let s=useCallback(()=>(t==="local"?LocalStorage:SessionStorage).get(e)??o,[t,e,o]),[S,l]=useState(o),T=useCallback(a=>{l(V=>{let n=a instanceof Function?a(V):a;return (typeof window<"u"&&t==="local"?LocalStorage:SessionStorage).set(e,n),n});},[t,e]);return useEffect(()=>{l(s());},[s]),[S,T]};export{p as useStorage};//# sourceMappingURL=useStorage.mjs.map
1
+ import {useCallback,useState,useEffect}from'react';import {LocalStorage}from'@alessiofrittoli/web-utils/storage/LocalStorage';import {SessionStorage}from'@alessiofrittoli/web-utils/storage/SessionStorage';var R=(e,o,t="local")=>{let s=useCallback(()=>(t==="local"?LocalStorage:SessionStorage).get(e)??o,[t,e,o]),[S,l]=useState(o),T=useCallback(a=>{l(V=>{let n=a instanceof Function?a(V):a;return (typeof window<"u"&&t==="local"?LocalStorage:SessionStorage).set(e,n),n});},[t,e]);return useEffect(()=>{l(s());},[s]),[S,T]};export{R as useStorage};//# sourceMappingURL=useStorage.mjs.map
2
2
  //# sourceMappingURL=useStorage.mjs.map
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react'),browserApi=require('@alessiofrittoli/web-utils/browser-api'),device=require('@alessiofrittoli/web-utils/device');var o=e=>{let[s,i]=react.useState(browserApi.getMediaMatches(e)),t=react.useCallback(()=>i(browserApi.getMediaMatches(e)),[e]);return react.useEffect(()=>{let a=window.matchMedia(e);return t(),a.addEventListener("change",t),()=>{a.removeEventListener("change",t);}},[e,t]),s};var g=()=>o(device.portraitMediaQuery);exports.useIsPortrait=g;//# sourceMappingURL=useIsPortrait.js.map
1
+ 'use strict';var react=require('react'),browserApi=require('@alessiofrittoli/web-utils/browser-api'),device=require('@alessiofrittoli/web-utils/device');var o=e=>{let[s,i]=react.useState(browserApi.getMediaMatches(e)),t=react.useCallback(()=>i(browserApi.getMediaMatches(e)),[e]);return react.useEffect(()=>{let a=window.matchMedia(e);return t(),a.addEventListener("change",t),()=>{a.removeEventListener("change",t);}},[e,t]),s};var v=()=>o(device.portraitMediaQuery);exports.useIsPortrait=v;//# sourceMappingURL=useIsPortrait.js.map
2
2
  //# sourceMappingURL=useIsPortrait.js.map
@@ -1,2 +1,2 @@
1
- import {useState,useCallback,useEffect}from'react';import {getMediaMatches}from'@alessiofrittoli/web-utils/browser-api';import {portraitMediaQuery}from'@alessiofrittoli/web-utils/device';var o=e=>{let[s,i]=useState(getMediaMatches(e)),t=useCallback(()=>i(getMediaMatches(e)),[e]);return useEffect(()=>{let a=window.matchMedia(e);return t(),a.addEventListener("change",t),()=>{a.removeEventListener("change",t);}},[e,t]),s};var g=()=>o(portraitMediaQuery);export{g as useIsPortrait};//# sourceMappingURL=useIsPortrait.mjs.map
1
+ import {useState,useCallback,useEffect}from'react';import {getMediaMatches}from'@alessiofrittoli/web-utils/browser-api';import {portraitMediaQuery}from'@alessiofrittoli/web-utils/device';var o=e=>{let[s,i]=useState(getMediaMatches(e)),t=useCallback(()=>i(getMediaMatches(e)),[e]);return useEffect(()=>{let a=window.matchMedia(e);return t(),a.addEventListener("change",t),()=>{a.removeEventListener("change",t);}},[e,t]),s};var E=()=>o(portraitMediaQuery);export{E as useIsPortrait};//# sourceMappingURL=useIsPortrait.mjs.map
2
2
  //# sourceMappingURL=useIsPortrait.mjs.map
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react'),browserApi=require('@alessiofrittoli/web-utils/browser-api');var m=e=>{let[s,c]=react.useState(browserApi.getMediaMatches(e)),t=react.useCallback(()=>c(browserApi.getMediaMatches(e)),[e]);return react.useEffect(()=>{let a=window.matchMedia(e);return t(),a.addEventListener("change",t),()=>{a.removeEventListener("change",t);}},[e,t]),s};exports.useMediaQuery=m;//# sourceMappingURL=useMediaQuery.js.map
1
+ 'use strict';var react=require('react'),browserApi=require('@alessiofrittoli/web-utils/browser-api');var M=e=>{let[s,c]=react.useState(browserApi.getMediaMatches(e)),t=react.useCallback(()=>c(browserApi.getMediaMatches(e)),[e]);return react.useEffect(()=>{let a=window.matchMedia(e);return t(),a.addEventListener("change",t),()=>{a.removeEventListener("change",t);}},[e,t]),s};exports.useMediaQuery=M;//# sourceMappingURL=useMediaQuery.js.map
2
2
  //# sourceMappingURL=useMediaQuery.js.map
@@ -1,2 +1,2 @@
1
- import {useState,useCallback,useEffect}from'react';import {getMediaMatches}from'@alessiofrittoli/web-utils/browser-api';var m=e=>{let[s,c]=useState(getMediaMatches(e)),t=useCallback(()=>c(getMediaMatches(e)),[e]);return useEffect(()=>{let a=window.matchMedia(e);return t(),a.addEventListener("change",t),()=>{a.removeEventListener("change",t);}},[e,t]),s};export{m as useMediaQuery};//# sourceMappingURL=useMediaQuery.mjs.map
1
+ import {useState,useCallback,useEffect}from'react';import {getMediaMatches}from'@alessiofrittoli/web-utils/browser-api';var g=e=>{let[s,c]=useState(getMediaMatches(e)),t=useCallback(()=>c(getMediaMatches(e)),[e]);return useEffect(()=>{let a=window.matchMedia(e);return t(),a.addEventListener("change",t),()=>{a.removeEventListener("change",t);}},[e,t]),s};export{g as useMediaQuery};//# sourceMappingURL=useMediaQuery.mjs.map
2
2
  //# sourceMappingURL=useMediaQuery.mjs.map
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react'),dom=require('@alessiofrittoli/web-utils/dom');var E=["input","select","textarea","button","[href]",'[tabindex]:not([tabindex="-1"])'].join(", "),y=e=>{let[r,o]=react.useState(false),c=react.useRef(null),m=react.useCallback(n=>{c.current=document.activeElement;let t=n||e?.current||false;if(t)return o(t)},[e]),i=react.useCallback(()=>{c.current?.focus(),o(false);},[]);return react.useEffect(()=>{if(!r)return;let n=t=>{if(t.key!=="Tab")return;let s=Array.from(r.querySelectorAll(E)),l=s.at(0),u=s.at(-1);if(!t.shiftKey){document.activeElement===u&&(t.preventDefault(),l?.focus());return}document.activeElement===l&&(t.preventDefault(),u?.focus());};return document.addEventListener("keydown",n),()=>{document.removeEventListener("keydown",n);}},[r]),[m,i]};var L=e=>{let r=react.useCallback(()=>dom.blockScroll(e?.current||void 0),[e]),o=react.useCallback(()=>dom.restoreScroll(e?.current||void 0),[e]);return [r,o]};exports.useFocusTrap=y;exports.useScrollBlock=L;//# sourceMappingURL=index.js.map
1
+ 'use strict';var react=require('react'),dom=require('@alessiofrittoli/web-utils/dom');var b=["input","select","textarea","button","[href]",'[tabindex]:not([tabindex="-1"])'].join(", "),k=e=>{let[r,o]=react.useState(false),c=react.useRef(null),i=react.useCallback(n=>{c.current=document.activeElement;let t=n||e?.current||false;if(t)return o(t)},[e]),p=react.useCallback(()=>{c.current?.focus(),o(false);},[]);return react.useEffect(()=>{if(!r)return;let n=t=>{if(t.key!=="Tab")return;let s=Array.from(r.querySelectorAll(b)),l=s.at(0),u=s.at(-1);if(!t.shiftKey){document.activeElement===u&&(t.preventDefault(),l?.focus());return}document.activeElement===l&&(t.preventDefault(),u?.focus());};return document.addEventListener("keydown",n),()=>{document.removeEventListener("keydown",n);}},[r]),[i,p]};var x=e=>{let r=react.useCallback(()=>dom.blockScroll(e?.current||void 0),[e]),o=react.useCallback(()=>dom.restoreScroll(e?.current||void 0),[e]);return [r,o]};exports.useFocusTrap=k;exports.useScrollBlock=x;//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map
@@ -1,2 +1,2 @@
1
- import {useState,useRef,useCallback,useEffect}from'react';import {blockScroll,restoreScroll}from'@alessiofrittoli/web-utils/dom';var E=["input","select","textarea","button","[href]",'[tabindex]:not([tabindex="-1"])'].join(", "),y=e=>{let[r,o]=useState(false),c=useRef(null),m=useCallback(n=>{c.current=document.activeElement;let t=n||e?.current||false;if(t)return o(t)},[e]),i=useCallback(()=>{c.current?.focus(),o(false);},[]);return useEffect(()=>{if(!r)return;let n=t=>{if(t.key!=="Tab")return;let s=Array.from(r.querySelectorAll(E)),l=s.at(0),u=s.at(-1);if(!t.shiftKey){document.activeElement===u&&(t.preventDefault(),l?.focus());return}document.activeElement===l&&(t.preventDefault(),u?.focus());};return document.addEventListener("keydown",n),()=>{document.removeEventListener("keydown",n);}},[r]),[m,i]};var L=e=>{let r=useCallback(()=>blockScroll(e?.current||void 0),[e]),o=useCallback(()=>restoreScroll(e?.current||void 0),[e]);return [r,o]};export{y as useFocusTrap,L as useScrollBlock};//# sourceMappingURL=index.mjs.map
1
+ import {useState,useRef,useCallback,useEffect}from'react';import {blockScroll,restoreScroll}from'@alessiofrittoli/web-utils/dom';var S=["input","select","textarea","button","[href]",'[tabindex]:not([tabindex="-1"])'].join(", "),H=e=>{let[r,o]=useState(false),c=useRef(null),p=useCallback(n=>{c.current=document.activeElement;let t=n||e?.current||false;if(t)return o(t)},[e]),d=useCallback(()=>{c.current?.focus(),o(false);},[]);return useEffect(()=>{if(!r)return;let n=t=>{if(t.key!=="Tab")return;let s=Array.from(r.querySelectorAll(S)),l=s.at(0),u=s.at(-1);if(!t.shiftKey){document.activeElement===u&&(t.preventDefault(),l?.focus());return}document.activeElement===l&&(t.preventDefault(),u?.focus());};return document.addEventListener("keydown",n),()=>{document.removeEventListener("keydown",n);}},[r]),[p,d]};var M=e=>{let r=useCallback(()=>blockScroll(e?.current||void 0),[e]),o=useCallback(()=>restoreScroll(e?.current||void 0),[e]);return [r,o]};export{H as useFocusTrap,M as useScrollBlock};//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react');var E=["input","select","textarea","button","[href]",'[tabindex]:not([tabindex="-1"])'].join(", "),F=n=>{let[r,o]=react.useState(false),s=react.useRef(null),f=react.useCallback(t=>{s.current=document.activeElement;let e=t||n?.current||false;if(e)return o(e)},[n]),i=react.useCallback(()=>{s.current?.focus(),o(false);},[]);return react.useEffect(()=>{if(!r)return;let t=e=>{if(e.key!=="Tab")return;let c=Array.from(r.querySelectorAll(E)),u=c.at(0),a=c.at(-1);if(!e.shiftKey){document.activeElement===a&&(e.preventDefault(),u?.focus());return}document.activeElement===u&&(e.preventDefault(),a?.focus());};return document.addEventListener("keydown",t),()=>{document.removeEventListener("keydown",t);}},[r]),[f,i]};exports.useFocusTrap=F;//# sourceMappingURL=useFocusTrap.js.map
1
+ 'use strict';var react=require('react');var E=["input","select","textarea","button","[href]",'[tabindex]:not([tabindex="-1"])'].join(", "),b=n=>{let[r,o]=react.useState(false),s=react.useRef(null),f=react.useCallback(t=>{s.current=document.activeElement;let e=t||n?.current||false;if(e)return o(e)},[n]),i=react.useCallback(()=>{s.current?.focus(),o(false);},[]);return react.useEffect(()=>{if(!r)return;let t=e=>{if(e.key!=="Tab")return;let c=Array.from(r.querySelectorAll(E)),u=c.at(0),a=c.at(-1);if(!e.shiftKey){document.activeElement===a&&(e.preventDefault(),u?.focus());return}document.activeElement===u&&(e.preventDefault(),a?.focus());};return document.addEventListener("keydown",t),()=>{document.removeEventListener("keydown",t);}},[r]),[f,i]};exports.useFocusTrap=b;//# sourceMappingURL=useFocusTrap.js.map
2
2
  //# sourceMappingURL=useFocusTrap.js.map
@@ -1,2 +1,2 @@
1
- import {useState,useRef,useCallback,useEffect}from'react';var E=["input","select","textarea","button","[href]",'[tabindex]:not([tabindex="-1"])'].join(", "),F=n=>{let[r,o]=useState(false),s=useRef(null),f=useCallback(t=>{s.current=document.activeElement;let e=t||n?.current||false;if(e)return o(e)},[n]),i=useCallback(()=>{s.current?.focus(),o(false);},[]);return useEffect(()=>{if(!r)return;let t=e=>{if(e.key!=="Tab")return;let c=Array.from(r.querySelectorAll(E)),u=c.at(0),a=c.at(-1);if(!e.shiftKey){document.activeElement===a&&(e.preventDefault(),u?.focus());return}document.activeElement===u&&(e.preventDefault(),a?.focus());};return document.addEventListener("keydown",t),()=>{document.removeEventListener("keydown",t);}},[r]),[f,i]};export{F as useFocusTrap};//# sourceMappingURL=useFocusTrap.mjs.map
1
+ import {useState,useRef,useCallback,useEffect}from'react';var E=["input","select","textarea","button","[href]",'[tabindex]:not([tabindex="-1"])'].join(", "),y=n=>{let[r,o]=useState(false),s=useRef(null),f=useCallback(t=>{s.current=document.activeElement;let e=t||n?.current||false;if(e)return o(e)},[n]),i=useCallback(()=>{s.current?.focus(),o(false);},[]);return useEffect(()=>{if(!r)return;let t=e=>{if(e.key!=="Tab")return;let c=Array.from(r.querySelectorAll(E)),u=c.at(0),a=c.at(-1);if(!e.shiftKey){document.activeElement===a&&(e.preventDefault(),u?.focus());return}document.activeElement===u&&(e.preventDefault(),a?.focus());};return document.addEventListener("keydown",t),()=>{document.removeEventListener("keydown",t);}},[r]),[f,i]};export{y as useFocusTrap};//# sourceMappingURL=useFocusTrap.mjs.map
2
2
  //# sourceMappingURL=useFocusTrap.mjs.map
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react'),dom=require('@alessiofrittoli/web-utils/dom');var u=l=>{let r=react.useCallback(()=>dom.blockScroll(l?.current||void 0),[l]),c=react.useCallback(()=>dom.restoreScroll(l?.current||void 0),[l]);return [r,c]};exports.useScrollBlock=u;//# sourceMappingURL=useScrollBlock.js.map
1
+ 'use strict';var react=require('react'),dom=require('@alessiofrittoli/web-utils/dom');var S=l=>{let r=react.useCallback(()=>dom.blockScroll(l?.current||void 0),[l]),c=react.useCallback(()=>dom.restoreScroll(l?.current||void 0),[l]);return [r,c]};exports.useScrollBlock=S;//# sourceMappingURL=useScrollBlock.js.map
2
2
  //# sourceMappingURL=useScrollBlock.js.map
@@ -1,2 +1,2 @@
1
- import {useCallback}from'react';import {blockScroll,restoreScroll}from'@alessiofrittoli/web-utils/dom';var u=l=>{let r=useCallback(()=>blockScroll(l?.current||void 0),[l]),c=useCallback(()=>restoreScroll(l?.current||void 0),[l]);return [r,c]};export{u as useScrollBlock};//# sourceMappingURL=useScrollBlock.mjs.map
1
+ import {useCallback}from'react';import {blockScroll,restoreScroll}from'@alessiofrittoli/web-utils/dom';var d=l=>{let r=useCallback(()=>blockScroll(l?.current||void 0),[l]),c=useCallback(()=>restoreScroll(l?.current||void 0),[l]);return [r,c]};export{d as useScrollBlock};//# sourceMappingURL=useScrollBlock.mjs.map
2
2
  //# sourceMappingURL=useScrollBlock.mjs.map
package/dist/eslint.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var e={recommended:[{rules:{"react-hooks/exhaustive-deps":["warn",{additionalHooks:"(useUpdateEffect)"}]}}]};exports.config=e;//# sourceMappingURL=eslint.js.map
1
+ 'use strict';var n={recommended:[{rules:{"react-hooks/exhaustive-deps":["warn",{additionalHooks:"(useUpdateEffect)"}]}}]};exports.config=n;//# sourceMappingURL=eslint.js.map
2
2
  //# sourceMappingURL=eslint.js.map
package/dist/eslint.mjs CHANGED
@@ -1,2 +1,2 @@
1
- var e={recommended:[{rules:{"react-hooks/exhaustive-deps":["warn",{additionalHooks:"(useUpdateEffect)"}]}}]};export{e as config};//# sourceMappingURL=eslint.mjs.map
1
+ var o={recommended:[{rules:{"react-hooks/exhaustive-deps":["warn",{additionalHooks:"(useUpdateEffect)"}]}}]};export{o as config};//# sourceMappingURL=eslint.mjs.map
2
2
  //# sourceMappingURL=eslint.mjs.map
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react'),LocalStorage=require('@alessiofrittoli/web-utils/storage/LocalStorage'),SessionStorage=require('@alessiofrittoli/web-utils/storage/SessionStorage'),browserApi=require('@alessiofrittoli/web-utils/browser-api'),device=require('@alessiofrittoli/web-utils/device'),dom=require('@alessiofrittoli/web-utils/dom');var i=(e,t,r="local")=>{let s=react.useCallback(()=>(r==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).get(e)??t,[r,e,t]),[n,u]=react.useState(t),c=react.useCallback(o=>{u(l=>{let a=o instanceof Function?o(l):o;return (typeof window<"u"&&r==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).set(e,a),a});},[r,e]);return react.useEffect(()=>{u(s());},[s]),[n,c]};var P=(e,t)=>i(e,t,"local");var G=(e,t)=>i(e,t,"session");var S=e=>{let[t,r]=react.useState(browserApi.getMediaMatches(e)),s=react.useCallback(()=>r(browserApi.getMediaMatches(e)),[e]);return react.useEffect(()=>{let n=window.matchMedia(e);return s(),n.addEventListener("change",s),()=>{n.removeEventListener("change",s);}},[e,s]),t};var _=()=>S(device.portraitMediaQuery);var V=["input","select","textarea","button","[href]",'[tabindex]:not([tabindex="-1"])'].join(", "),ee=e=>{let[t,r]=react.useState(false),s=react.useRef(null),n=react.useCallback(c=>{s.current=document.activeElement;let o=c||e?.current||false;if(o)return r(o)},[e]),u=react.useCallback(()=>{s.current?.focus(),r(false);},[]);return react.useEffect(()=>{if(!t)return;let c=o=>{if(o.key!=="Tab")return;let l=Array.from(t.querySelectorAll(V)),a=l.at(0),f=l.at(-1);if(!o.shiftKey){document.activeElement===f&&(o.preventDefault(),a?.focus());return}document.activeElement===a&&(o.preventDefault(),f?.focus());};return document.addEventListener("keydown",c),()=>{document.removeEventListener("keydown",c);}},[t]),[n,u]};var se=e=>{let t=react.useCallback(()=>dom.blockScroll(e?.current||void 0),[e]),r=react.useCallback(()=>dom.restoreScroll(e?.current||void 0),[e]);return [t,r]};var ae=()=>{let[e,t]=react.useState(false);return react.useEffect(()=>t(true),[]),e};var F=()=>{let e=react.useRef(true);return e.current?(e.current=false,true):e.current};var pe=(e,t)=>{let r=F();react.useEffect(()=>{if(!r)return e()},t);};exports.useFocusTrap=ee;exports.useIsClient=ae;exports.useIsFirstRender=F;exports.useIsPortrait=_;exports.useLocalStorage=P;exports.useMediaQuery=S;exports.useScrollBlock=se;exports.useSessionStorage=G;exports.useStorage=i;exports.useUpdateEffect=pe;//# sourceMappingURL=index.js.map
1
+ 'use strict';var react=require('react'),LocalStorage=require('@alessiofrittoli/web-utils/storage/LocalStorage'),SessionStorage=require('@alessiofrittoli/web-utils/storage/SessionStorage'),browserApi=require('@alessiofrittoli/web-utils/browser-api'),device=require('@alessiofrittoli/web-utils/device'),dom=require('@alessiofrittoli/web-utils/dom');var f=(e,t,r="local")=>{let s=react.useCallback(()=>(r==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).get(e)??t,[r,e,t]),[c,l]=react.useState(t),a=react.useCallback(o=>{l(i=>{let u=o instanceof Function?o(i):o;return (typeof window<"u"&&r==="local"?LocalStorage.LocalStorage:SessionStorage.SessionStorage).set(e,u),u});},[r,e]);return react.useEffect(()=>{l(s());},[s]),[c,a]};var z=(e,t)=>f(e,t,"local");var W=(e,t)=>f(e,t,"session");var E=e=>{let[t,r]=react.useState(browserApi.getMediaMatches(e)),s=react.useCallback(()=>r(browserApi.getMediaMatches(e)),[e]);return react.useEffect(()=>{let c=window.matchMedia(e);return s(),c.addEventListener("change",s),()=>{c.removeEventListener("change",s);}},[e,s]),t};var re=()=>E(device.portraitMediaQuery);var C=["input","select","textarea","button","[href]",'[tabindex]:not([tabindex="-1"])'].join(", "),ce=e=>{let[t,r]=react.useState(false),s=react.useRef(null),c=react.useCallback(a=>{s.current=document.activeElement;let o=a||e?.current||false;if(o)return r(o)},[e]),l=react.useCallback(()=>{s.current?.focus(),r(false);},[]);return react.useEffect(()=>{if(!t)return;let a=o=>{if(o.key!=="Tab")return;let i=Array.from(t.querySelectorAll(C)),u=i.at(0),m=i.at(-1);if(!o.shiftKey){document.activeElement===m&&(o.preventDefault(),u?.focus());return}document.activeElement===u&&(o.preventDefault(),m?.focus());};return document.addEventListener("keydown",a),()=>{document.removeEventListener("keydown",a);}},[t]),[c,l]};var fe=e=>{let t=react.useCallback(()=>dom.blockScroll(e?.current||void 0),[e]),r=react.useCallback(()=>dom.restoreScroll(e?.current||void 0),[e]);return [t,r]};var Te=()=>{let[e,t]=react.useState(false);return react.useEffect(()=>t(true),[]),e};var g=()=>{let e=react.useRef(true);return e.current?(e.current=false,true):e.current};var Re=(e,t)=>{let r=g();react.useEffect(()=>{if(!r)return e()},t);};exports.useFocusTrap=ce;exports.useIsClient=Te;exports.useIsFirstRender=g;exports.useIsPortrait=re;exports.useLocalStorage=z;exports.useMediaQuery=E;exports.useScrollBlock=fe;exports.useSessionStorage=W;exports.useStorage=f;exports.useUpdateEffect=Re;//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/browser-api/storage/useStorage.ts","../src/browser-api/storage/useLocalStorage.ts","../src/browser-api/storage/useSessionStorage.ts","../src/browser-api/useMediaQuery.ts","../src/browser-api/useIsPortrait.ts","../src/dom-api/useFocusTrap.ts","../src/dom-api/useScrollBlock.ts","../src/misc/useIsClient.ts","../src/misc/useIsFirstRender.ts","../src/misc/useUpdateEffect.ts"],"names":["useStorage","key","initialValue","type","readValue","useCallback","LocalStorage","SessionStorage","storedValue","setStoredValue","useState","setValue","value","valueToStore","useEffect","useLocalStorage","useSessionStorage","useMediaQuery","query","matches","setMatches","getMediaMatches","matchMediaChangeHandler","matchMedia","useIsPortrait","portraitMediaQuery","focusableSelector","useFocusTrap","target","focusTrap","setFocusTrapDispatch","lastActiveElement","useRef","setFocusTrap","onDemandTarget","restoreFocusTrap","keyDownHandler","event","focusableElements","firstFocusableElement","lastFocusableElement","useScrollBlock","blockScroll","blockScrollHandler","restoreScroll","restoreScrollHandler","useIsClient","isClient","setClient","useIsFirstRender","isFirst","useUpdateEffect","effect","deps"],"mappings":"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","file":"index.js","sourcesContent":["import { useCallback, useEffect, useState } from 'react'\nimport { LocalStorage } from '@alessiofrittoli/web-utils/storage/LocalStorage'\nimport { SessionStorage } from '@alessiofrittoli/web-utils/storage/SessionStorage'\n\ntype Value<T>\t\t= T | undefined | null\ntype SetValue<T>\t= React.Dispatch<React.SetStateAction<T>>\n\n/**\n * Easly handle Local or Session Storage State.\n * \n * @param\tkey\t\t\t\tThe storage item key.\n * @param\tinitialValue\tThe storage item initial value.\n * @param\ttype\t\t\t( Optional ) The storage API to use. Default: `local`.\n */\nexport const useStorage = <T = string>(\n\tkey\t\t\t\t: string,\n\tinitialValue?\t: T,\n\ttype\t\t\t: 'local' | 'session' = 'local'\n): [ Value<T>, SetValue<Value<T>> ] => {\n\n\tconst readValue = useCallback( () => (\n\t\t( type === 'local' ? LocalStorage : SessionStorage )\n\t\t\t.get<T>( key ) ?? initialValue\n\t), [ type, key, initialValue ] )\n\n\n\t/**\n\t * State to store our value.\n\t * Pass initial state function to useState so logic is only executed once.\n\t * \n\t */\n\tconst [ storedValue, setStoredValue ] = useState<Value<T>>( initialValue )\n\n\t/**\n\t * Return a wrapped version of useState's setter function that\n\t * persists the new value to localStorage | sessionStorage.\n\t * \n\t * @param value The SetStateAction value.\n\t */\n\tconst setValue = useCallback<SetValue<Value<T>>>( value => {\n\n\t\tsetStoredValue( storedValue => {\n\t\t\tconst valueToStore = value instanceof Function ? value( storedValue ) : value\n\t\n\t\t\t;(\n\t\t\t\ttypeof window !== 'undefined' &&\n\t\t\t\ttype === 'local' ? LocalStorage : SessionStorage\n\t\t\t).set( key, valueToStore )\n\n\t\t\treturn valueToStore\n\t\t} )\n\n\n\t}, [ type, key ] )\n\n\tuseEffect( () => {\n\t\tsetStoredValue( readValue() )\n\t}, [ readValue ] )\n\n\treturn [ storedValue, setValue ]\n}","import { useStorage } from './useStorage'\n\n/**\n * useLocalStorage hook.\n * \n * @param\tkey\t\t\t\tThe local storage item key.\n * @param\tinitialValue\tThe local storage item initial value.\n */\nexport const useLocalStorage = <T = string>(\n\tkey\t\t\t\t: string,\n\tinitialValue?\t: T\n) => useStorage( key, initialValue, 'local' )","import { useStorage } from './useStorage'\n\n/**\n * useSessionStorage hook.\n * \n * @param\tkey\t\t\t\tThe session item key.\n * @param\tinitialValue\tThe session item initial value.\n */\nexport const useSessionStorage = <T = string>(\n\tkey\t\t\t\t: string,\n\tinitialValue?\t: T\n) => useStorage( key, initialValue, 'session' )","import { useCallback, useEffect, useState } from 'react'\nimport { getMediaMatches } from '@alessiofrittoli/web-utils/browser-api'\n\n\n/**\n * Get Document Media matches and listen for changes.\n *\n * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia)\n *\n * @param\tquery A string specifying the media query to parse into a `MediaQueryList`.\n * @returns\tA boolean value that returns `true` if the document currently matches the media query list, or `false` if not.\n */\nexport const useMediaQuery = ( query: string ) => {\n\n\tconst [ matches, setMatches ]\t= useState( getMediaMatches( query ) )\n\tconst matchMediaChangeHandler\t= useCallback( () => setMatches( getMediaMatches( query ) ), [ query ] )\n\n\n\tuseEffect( () => {\n\n\t\tconst matchMedia = window.matchMedia( query )\n\t\t// Triggered at the first client-side load\n\t\tmatchMediaChangeHandler()\n\t\t// Listen matchMedia\n\t\tmatchMedia.addEventListener( 'change', matchMediaChangeHandler )\n\n\t\treturn () => {\n\t\t\tmatchMedia.removeEventListener( 'change', matchMediaChangeHandler )\n\t\t}\n\n\t}, [ query, matchMediaChangeHandler ] )\n\n\treturn matches\n\t\n}","import { useMediaQuery } from './useMediaQuery'\nimport { portraitMediaQuery } from '@alessiofrittoli/web-utils/device'\n\n/**\n * Check if device is portrait oriented.\n * \n * State get updated when device orientation changes.\n *\n * @returns\t`true` if the device is portrait oriented, `false` otherwise.\n */\nexport const useIsPortrait = () => useMediaQuery( portraitMediaQuery )","import { useCallback, useEffect, useRef, useState } from 'react'\n\ntype SetFocusTrap = ( target?: HTMLElement ) => void\ntype RestoreFocusTrap = () => void\n\nconst focusableSelector = [\n\t'input', 'select', 'textarea',\n\t'button', '[href]', '[tabindex]:not([tabindex=\"-1\"])',\n].join( ', ' )\n\n\n/**\n * Trap focus inside the given HTML Element.\n * \n * @param target (Optional) The target HTMLElement React RefObject to trap focus within.\n * \t\t\t\t\tIf no target is given, you must provide the target HTMLElement when calling `setFocusTrap`.\n * \n * @returns A tuple containing:\n * - `setFocusTrap`: A function to enable the focus trap. Optionally accept an HTMLElement as target.\n * - `restoreFocusTrap`: A function to restore the previous focus state.\n */\nexport const useFocusTrap = (\n\ttarget?: React.RefObject<HTMLElement | null>\n): readonly [ SetFocusTrap, RestoreFocusTrap ] => {\n\n\tconst [ focusTrap, setFocusTrapDispatch ] = (\n\t\tuseState<HTMLElement | false>( false )\n\t)\n\n\tconst lastActiveElement = useRef<HTMLElement>( null )\n\t\n\t/**\n\t * Enable the focus trap.\n\t * \n\t */\n\tconst setFocusTrap = useCallback<SetFocusTrap>( onDemandTarget => {\n\n\t\tlastActiveElement.current\t= document.activeElement as HTMLElement\n\t\tconst focusTrap\t\t\t\t= onDemandTarget || target?.current || false\n\t\t\n\t\tif ( ! focusTrap ) return\n\n\t\treturn setFocusTrapDispatch( focusTrap )\n\t\n\t}, [ target ] )\n\n\n\t/**\n\t * Restore the focus to the latest Document active Element.\n\t */\n\tconst restoreFocusTrap = useCallback<RestoreFocusTrap>( () => {\n\n\t\tlastActiveElement.current?.focus()\n\t\tsetFocusTrapDispatch( false )\n\t\n\t}, [] )\n\n\t\n\tuseEffect( () => {\n\n\t\tif ( ! focusTrap ) return\n\n\t\tconst keyDownHandler = ( event: KeyboardEvent ) => {\n\n\t\t\tif ( event.key !== 'Tab' ) return\n\n\t\t\tconst focusableElements\t\t= Array.from( focusTrap.querySelectorAll<HTMLElement>( focusableSelector ) ),\n\t\t\t\tfirstFocusableElement\t= focusableElements.at( 0 ),\n\t\t\t\tlastFocusableElement\t= focusableElements.at( -1 );\n\n\t\t\tif ( ! event.shiftKey ) {\n\t\t\t\t/**\n\t\t\t\t * Focust the firs element if\n\t\t\t\t * focusing forward and the current focused element is the last one.\n\t\t\t\t */\n\t\t\t\tif ( document.activeElement === lastFocusableElement ) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tfirstFocusableElement?.focus()\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\n\t\t\t/**\n\t\t\t * Focus the last focusable element if\n\t\t\t * focusing backward and the current focused element is the first one.\n\t\t\t * \n\t\t\t */\n\t\t\tif ( document.activeElement === firstFocusableElement ) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tlastFocusableElement?.focus()\n\t\t\t}\n\n\t\t}\n\n\t\tdocument.addEventListener( 'keydown', keyDownHandler );\n\t\n\t\treturn () => {\n\t\t\tdocument.removeEventListener( 'keydown', keyDownHandler );\n\t\t}\n\n\t}, [ focusTrap ] )\n\n\treturn [ setFocusTrap, restoreFocusTrap ]\n\n}","import { useCallback } from 'react'\nimport {\n\tblockScroll as blockScrollHandler,\n\trestoreScroll as restoreScrollHandler\n} from '@alessiofrittoli/web-utils/dom'\n\n\n/**\n * Prevent Element overflow.\n * \n * @param target (Optional) The React RefObject target HTMLElement. Default: `Document.documentElement`.\n */\nexport const useScrollBlock = ( target?: React.RefObject<HTMLElement | null> ) => {\n\t\n\t/**\n\t * Block scroll.\n\t * \n\t */\n\tconst blockScroll = useCallback(\n\t\t() => blockScrollHandler( target?.current || undefined ), [ target ]\n\t)\n\n\n\t/**\n\t * Restore scroll.\n\t * \n\t */\n\tconst restoreScroll = useCallback(\n\t\t() => restoreScrollHandler( target?.current || undefined ), [ target ]\n\t)\n\n\t\n\treturn [ blockScroll, restoreScroll ] as const\n\n}","import { useEffect, useState } from 'react'\n\n/**\n * Check if the React Hook or Component where this hook is executed is running in a browser environment.\n * \n * @returns `true` if the React Hook or Component is running in a browser environment, `false` otherwise.\n */\nexport const useIsClient = () => {\n\n\tconst [ isClient, setClient ] = useState( false )\n\n\tuseEffect( () => setClient( true ), [] )\n\n\treturn isClient\n\n}","import { useRef } from 'react'\n\n/**\n * Check if is first React Hook/Component render.\n * \n * @returns `true` at the mount time, then always `false`.\n * - Note that if the React Hook/Component has no state updates, `useIsFirstRender` will always return `true`.\n */\nexport const useIsFirstRender = () => {\n\n\tconst isFirst = useRef( true )\n\n\tif ( isFirst.current ) {\n\t\tisFirst.current = false\n\n\t\treturn true\n\t}\n\n\treturn isFirst.current\n\t\n}","import { useEffect } from 'react'\nimport { useIsFirstRender } from './useIsFirstRender'\n\n\n/**\n * Modified version of `useEffect` that skips the first render.\n *\n * @param\teffect\tImperative function that can return a cleanup function.\n * @param\tdeps\tIf present, effect will only activate if the values in the list change.\n */\nexport const useUpdateEffect = (\n\teffect\t: React.EffectCallback,\n\tdeps?\t: React.DependencyList,\n) => {\n\n\tconst isFirst = useIsFirstRender()\n\n\tuseEffect( () => {\n\t\tif ( ! isFirst ) return effect()\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, deps )\n\t\n}"]}
1
+ {"version":3,"sources":["../src/browser-api/storage/useStorage.ts","../src/browser-api/storage/useLocalStorage.ts","../src/browser-api/storage/useSessionStorage.ts","../src/browser-api/useMediaQuery.ts","../src/browser-api/useIsPortrait.ts","../src/dom-api/useFocusTrap.ts","../src/dom-api/useScrollBlock.ts","../src/misc/useIsClient.ts","../src/misc/useIsFirstRender.ts","../src/misc/useUpdateEffect.ts"],"names":["useStorage","key","initialValue","type","readValue","useCallback","LocalStorage","SessionStorage","storedValue","setStoredValue","useState","setValue","value","valueToStore","useEffect","useLocalStorage","useSessionStorage","useMediaQuery","query","matches","setMatches","getMediaMatches","matchMediaChangeHandler","matchMedia","useIsPortrait","portraitMediaQuery","focusableSelector","useFocusTrap","target","focusTrap","setFocusTrapDispatch","lastActiveElement","useRef","setFocusTrap","onDemandTarget","restoreFocusTrap","keyDownHandler","event","focusableElements","firstFocusableElement","lastFocusableElement","useScrollBlock","blockScroll","blockScrollHandler","restoreScroll","restoreScrollHandler","useIsClient","isClient","setClient","useIsFirstRender","isFirst","useUpdateEffect","effect","deps"],"mappings":"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","file":"index.js","sourcesContent":["import { useCallback, useEffect, useState } from 'react'\nimport { LocalStorage } from '@alessiofrittoli/web-utils/storage/LocalStorage'\nimport { SessionStorage } from '@alessiofrittoli/web-utils/storage/SessionStorage'\n\ntype Value<T>\t\t= T | undefined | null\ntype SetValue<T>\t= React.Dispatch<React.SetStateAction<T>>\n\n/**\n * Easly handle Local or Session Storage State.\n * \n * @param\tkey\t\t\t\tThe storage item key.\n * @param\tinitialValue\tThe storage item initial value.\n * @param\ttype\t\t\t( Optional ) The storage API to use. Default: `local`.\n */\nexport const useStorage = <T = string>(\n\tkey\t\t\t\t: string,\n\tinitialValue?\t: T,\n\ttype\t\t\t: 'local' | 'session' = 'local'\n): [ Value<T>, SetValue<Value<T>> ] => {\n\n\tconst readValue = useCallback( () => (\n\t\t( type === 'local' ? LocalStorage : SessionStorage )\n\t\t\t.get<T>( key ) ?? initialValue\n\t), [ type, key, initialValue ] )\n\n\n\t/**\n\t * State to store our value.\n\t * Pass initial state function to useState so logic is only executed once.\n\t * \n\t */\n\tconst [ storedValue, setStoredValue ] = useState<Value<T>>( initialValue )\n\n\t/**\n\t * Return a wrapped version of useState's setter function that\n\t * persists the new value to localStorage | sessionStorage.\n\t * \n\t * @param value The SetStateAction value.\n\t */\n\tconst setValue = useCallback<SetValue<Value<T>>>( value => {\n\n\t\tsetStoredValue( storedValue => {\n\t\t\tconst valueToStore = value instanceof Function ? value( storedValue ) : value\n\t\n\t\t\t;(\n\t\t\t\ttypeof window !== 'undefined' &&\n\t\t\t\ttype === 'local' ? LocalStorage : SessionStorage\n\t\t\t).set( key, valueToStore )\n\n\t\t\treturn valueToStore\n\t\t} )\n\n\n\t}, [ type, key ] )\n\n\tuseEffect( () => {\n\t\tsetStoredValue( readValue() )\n\t}, [ readValue ] )\n\n\treturn [ storedValue, setValue ]\n}","import { useStorage } from './useStorage'\n\n/**\n * useLocalStorage hook.\n * \n * @param\tkey\t\t\t\tThe local storage item key.\n * @param\tinitialValue\tThe local storage item initial value.\n */\nexport const useLocalStorage = <T = string>(\n\tkey\t\t\t\t: string,\n\tinitialValue?\t: T\n) => useStorage( key, initialValue, 'local' )","import { useStorage } from './useStorage'\n\n/**\n * useSessionStorage hook.\n * \n * @param\tkey\t\t\t\tThe session item key.\n * @param\tinitialValue\tThe session item initial value.\n */\nexport const useSessionStorage = <T = string>(\n\tkey\t\t\t\t: string,\n\tinitialValue?\t: T\n) => useStorage( key, initialValue, 'session' )","import { useCallback, useEffect, useState } from 'react'\nimport { getMediaMatches } from '@alessiofrittoli/web-utils/browser-api'\n\n\n/**\n * Get Document Media matches and listen for changes.\n *\n * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia)\n *\n * @param\tquery A string specifying the media query to parse into a `MediaQueryList`.\n * @returns\tA boolean value that returns `true` if the document currently matches the media query list, or `false` if not.\n */\nexport const useMediaQuery = ( query: string ) => {\n\n\tconst [ matches, setMatches ]\t= useState( getMediaMatches( query ) )\n\tconst matchMediaChangeHandler\t= useCallback( () => setMatches( getMediaMatches( query ) ), [ query ] )\n\n\n\tuseEffect( () => {\n\n\t\tconst matchMedia = window.matchMedia( query )\n\t\t// Triggered at the first client-side load\n\t\tmatchMediaChangeHandler()\n\t\t// Listen matchMedia\n\t\tmatchMedia.addEventListener( 'change', matchMediaChangeHandler )\n\n\t\treturn () => {\n\t\t\tmatchMedia.removeEventListener( 'change', matchMediaChangeHandler )\n\t\t}\n\n\t}, [ query, matchMediaChangeHandler ] )\n\n\treturn matches\n\t\n}","import { useMediaQuery } from './useMediaQuery'\nimport { portraitMediaQuery } from '@alessiofrittoli/web-utils/device'\n\n/**\n * Check if device is portrait oriented.\n * \n * State get updated when device orientation changes.\n *\n * @returns\t`true` if the device is portrait oriented, `false` otherwise.\n */\nexport const useIsPortrait = () => useMediaQuery( portraitMediaQuery )","import { useCallback, useEffect, useRef, useState } from 'react'\n\ntype SetFocusTrap = ( target?: HTMLElement ) => void\ntype RestoreFocusTrap = () => void\n\nconst focusableSelector = [\n\t'input', 'select', 'textarea',\n\t'button', '[href]', '[tabindex]:not([tabindex=\"-1\"])',\n].join( ', ' )\n\n\n/**\n * Trap focus inside the given HTML Element.\n * \n * @param target (Optional) The target HTMLElement React RefObject to trap focus within.\n * \t\t\t\t\tIf no target is given, you must provide the target HTMLElement when calling `setFocusTrap`.\n * \n * @returns A tuple containing:\n * - `setFocusTrap`: A function to enable the focus trap. Optionally accept an HTMLElement as target.\n * - `restoreFocusTrap`: A function to restore the previous focus state.\n */\nexport const useFocusTrap = (\n\ttarget?: React.RefObject<HTMLElement | null>\n): readonly [ SetFocusTrap, RestoreFocusTrap ] => {\n\n\tconst [ focusTrap, setFocusTrapDispatch ] = (\n\t\tuseState<HTMLElement | false>( false )\n\t)\n\n\tconst lastActiveElement = useRef<HTMLElement>( null )\n\t\n\t/**\n\t * Enable the focus trap.\n\t * \n\t */\n\tconst setFocusTrap = useCallback<SetFocusTrap>( onDemandTarget => {\n\n\t\tlastActiveElement.current\t= document.activeElement as HTMLElement\n\t\tconst focusTrap\t\t\t\t= onDemandTarget || target?.current || false\n\t\t\n\t\tif ( ! focusTrap ) return\n\n\t\treturn setFocusTrapDispatch( focusTrap )\n\t\n\t}, [ target ] )\n\n\n\t/**\n\t * Restore the focus to the latest Document active Element.\n\t */\n\tconst restoreFocusTrap = useCallback<RestoreFocusTrap>( () => {\n\n\t\tlastActiveElement.current?.focus()\n\t\tsetFocusTrapDispatch( false )\n\t\n\t}, [] )\n\n\t\n\tuseEffect( () => {\n\n\t\tif ( ! focusTrap ) return\n\n\t\tconst keyDownHandler = ( event: KeyboardEvent ) => {\n\n\t\t\tif ( event.key !== 'Tab' ) return\n\n\t\t\tconst focusableElements\t\t= Array.from( focusTrap.querySelectorAll<HTMLElement>( focusableSelector ) ),\n\t\t\t\tfirstFocusableElement\t= focusableElements.at( 0 ),\n\t\t\t\tlastFocusableElement\t= focusableElements.at( -1 );\n\n\t\t\tif ( ! event.shiftKey ) {\n\t\t\t\t/**\n\t\t\t\t * Focust the firs element if\n\t\t\t\t * focusing forward and the current focused element is the last one.\n\t\t\t\t */\n\t\t\t\tif ( document.activeElement === lastFocusableElement ) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tfirstFocusableElement?.focus()\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\n\t\t\t/**\n\t\t\t * Focus the last focusable element if\n\t\t\t * focusing backward and the current focused element is the first one.\n\t\t\t * \n\t\t\t */\n\t\t\tif ( document.activeElement === firstFocusableElement ) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tlastFocusableElement?.focus()\n\t\t\t}\n\n\t\t}\n\n\t\tdocument.addEventListener( 'keydown', keyDownHandler );\n\t\n\t\treturn () => {\n\t\t\tdocument.removeEventListener( 'keydown', keyDownHandler );\n\t\t}\n\n\t}, [ focusTrap ] )\n\n\treturn [ setFocusTrap, restoreFocusTrap ]\n\n}","import { useCallback } from 'react'\nimport {\n\tblockScroll as blockScrollHandler,\n\trestoreScroll as restoreScrollHandler\n} from '@alessiofrittoli/web-utils/dom'\n\n\n/**\n * Prevent Element overflow.\n * \n * @param target (Optional) The React RefObject target HTMLElement. Default: `Document.documentElement`.\n */\nexport const useScrollBlock = ( target?: React.RefObject<HTMLElement | null> ) => {\n\t\n\t/**\n\t * Block scroll.\n\t * \n\t */\n\tconst blockScroll = useCallback(\n\t\t() => blockScrollHandler( target?.current || undefined ), [ target ]\n\t)\n\n\n\t/**\n\t * Restore scroll.\n\t * \n\t */\n\tconst restoreScroll = useCallback(\n\t\t() => restoreScrollHandler( target?.current || undefined ), [ target ]\n\t)\n\n\t\n\treturn [ blockScroll, restoreScroll ] as const\n\n}","import { useEffect, useState } from 'react'\n\n/**\n * Check if the React Hook or Component where this hook is executed is running in a browser environment.\n * \n * @returns `true` if the React Hook or Component is running in a browser environment, `false` otherwise.\n */\nexport const useIsClient = () => {\n\n\tconst [ isClient, setClient ] = useState( false )\n\n\tuseEffect( () => setClient( true ), [] )\n\n\treturn isClient\n\n}","import { useRef } from 'react'\n\n/**\n * Check if is first React Hook/Component render.\n * \n * @returns `true` at the mount time, then always `false`.\n * - Note that if the React Hook/Component has no state updates, `useIsFirstRender` will always return `true`.\n */\nexport const useIsFirstRender = () => {\n\n\tconst isFirst = useRef( true )\n\n\tif ( isFirst.current ) {\n\t\tisFirst.current = false\n\n\t\treturn true\n\t}\n\n\treturn isFirst.current\n\t\n}","import { useEffect } from 'react'\nimport { useIsFirstRender } from './useIsFirstRender'\n\n\n/**\n * Modified version of `useEffect` that skips the first render.\n *\n * @param\teffect\tImperative function that can return a cleanup function.\n * @param\tdeps\tIf present, effect will only activate if the values in the list change.\n */\nexport const useUpdateEffect = (\n\teffect\t: React.EffectCallback,\n\tdeps?\t: React.DependencyList,\n) => {\n\n\tconst isFirst = useIsFirstRender()\n\n\tuseEffect( () => {\n\t\tif ( ! isFirst ) return effect()\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, deps )\n\t\n}"]}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import {useCallback,useState,useEffect,useRef}from'react';import {LocalStorage}from'@alessiofrittoli/web-utils/storage/LocalStorage';import {SessionStorage}from'@alessiofrittoli/web-utils/storage/SessionStorage';import {getMediaMatches}from'@alessiofrittoli/web-utils/browser-api';import {portraitMediaQuery}from'@alessiofrittoli/web-utils/device';import {blockScroll,restoreScroll}from'@alessiofrittoli/web-utils/dom';var i=(e,t,r="local")=>{let s=useCallback(()=>(r==="local"?LocalStorage:SessionStorage).get(e)??t,[r,e,t]),[n,u]=useState(t),c=useCallback(o=>{u(l=>{let a=o instanceof Function?o(l):o;return (typeof window<"u"&&r==="local"?LocalStorage:SessionStorage).set(e,a),a});},[r,e]);return useEffect(()=>{u(s());},[s]),[n,c]};var P=(e,t)=>i(e,t,"local");var G=(e,t)=>i(e,t,"session");var S=e=>{let[t,r]=useState(getMediaMatches(e)),s=useCallback(()=>r(getMediaMatches(e)),[e]);return useEffect(()=>{let n=window.matchMedia(e);return s(),n.addEventListener("change",s),()=>{n.removeEventListener("change",s);}},[e,s]),t};var _=()=>S(portraitMediaQuery);var V=["input","select","textarea","button","[href]",'[tabindex]:not([tabindex="-1"])'].join(", "),ee=e=>{let[t,r]=useState(false),s=useRef(null),n=useCallback(c=>{s.current=document.activeElement;let o=c||e?.current||false;if(o)return r(o)},[e]),u=useCallback(()=>{s.current?.focus(),r(false);},[]);return useEffect(()=>{if(!t)return;let c=o=>{if(o.key!=="Tab")return;let l=Array.from(t.querySelectorAll(V)),a=l.at(0),f=l.at(-1);if(!o.shiftKey){document.activeElement===f&&(o.preventDefault(),a?.focus());return}document.activeElement===a&&(o.preventDefault(),f?.focus());};return document.addEventListener("keydown",c),()=>{document.removeEventListener("keydown",c);}},[t]),[n,u]};var se=e=>{let t=useCallback(()=>blockScroll(e?.current||void 0),[e]),r=useCallback(()=>restoreScroll(e?.current||void 0),[e]);return [t,r]};var ae=()=>{let[e,t]=useState(false);return useEffect(()=>t(true),[]),e};var F=()=>{let e=useRef(true);return e.current?(e.current=false,true):e.current};var pe=(e,t)=>{let r=F();useEffect(()=>{if(!r)return e()},t);};export{ee as useFocusTrap,ae as useIsClient,F as useIsFirstRender,_ as useIsPortrait,P as useLocalStorage,S as useMediaQuery,se as useScrollBlock,G as useSessionStorage,i as useStorage,pe as useUpdateEffect};//# sourceMappingURL=index.mjs.map
1
+ import {useCallback,useState,useEffect,useRef}from'react';import {LocalStorage}from'@alessiofrittoli/web-utils/storage/LocalStorage';import {SessionStorage}from'@alessiofrittoli/web-utils/storage/SessionStorage';import {getMediaMatches}from'@alessiofrittoli/web-utils/browser-api';import {portraitMediaQuery}from'@alessiofrittoli/web-utils/device';import {blockScroll,restoreScroll}from'@alessiofrittoli/web-utils/dom';var m=(e,t,r="local")=>{let s=useCallback(()=>(r==="local"?LocalStorage:SessionStorage).get(e)??t,[r,e,t]),[a,i]=useState(t),u=useCallback(o=>{i(f=>{let l=o instanceof Function?o(f):o;return (typeof window<"u"&&r==="local"?LocalStorage:SessionStorage).set(e,l),l});},[r,e]);return useEffect(()=>{i(s());},[s]),[a,u]};var G=(e,t)=>m(e,t,"local");var X=(e,t)=>m(e,t,"session");var b=e=>{let[t,r]=useState(getMediaMatches(e)),s=useCallback(()=>r(getMediaMatches(e)),[e]);return useEffect(()=>{let a=window.matchMedia(e);return s(),a.addEventListener("change",s),()=>{a.removeEventListener("change",s);}},[e,s]),t};var oe=()=>b(portraitMediaQuery);var y=["input","select","textarea","button","[href]",'[tabindex]:not([tabindex="-1"])'].join(", "),ae=e=>{let[t,r]=useState(false),s=useRef(null),a=useCallback(u=>{s.current=document.activeElement;let o=u||e?.current||false;if(o)return r(o)},[e]),i=useCallback(()=>{s.current?.focus(),r(false);},[]);return useEffect(()=>{if(!t)return;let u=o=>{if(o.key!=="Tab")return;let f=Array.from(t.querySelectorAll(y)),l=f.at(0),p=f.at(-1);if(!o.shiftKey){document.activeElement===p&&(o.preventDefault(),l?.focus());return}document.activeElement===l&&(o.preventDefault(),p?.focus());};return document.addEventListener("keydown",u),()=>{document.removeEventListener("keydown",u);}},[t]),[a,i]};var me=e=>{let t=useCallback(()=>blockScroll(e?.current||void 0),[e]),r=useCallback(()=>restoreScroll(e?.current||void 0),[e]);return [t,r]};var Se=()=>{let[e,t]=useState(false);return useEffect(()=>t(true),[]),e};var x=()=>{let e=useRef(true);return e.current?(e.current=false,true):e.current};var Le=(e,t)=>{let r=x();useEffect(()=>{if(!r)return e()},t);};export{ae as useFocusTrap,Se as useIsClient,x as useIsFirstRender,oe as useIsPortrait,G as useLocalStorage,b as useMediaQuery,me as useScrollBlock,X as useSessionStorage,m as useStorage,Le as useUpdateEffect};//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/browser-api/storage/useStorage.ts","../src/browser-api/storage/useLocalStorage.ts","../src/browser-api/storage/useSessionStorage.ts","../src/browser-api/useMediaQuery.ts","../src/browser-api/useIsPortrait.ts","../src/dom-api/useFocusTrap.ts","../src/dom-api/useScrollBlock.ts","../src/misc/useIsClient.ts","../src/misc/useIsFirstRender.ts","../src/misc/useUpdateEffect.ts"],"names":["useStorage","key","initialValue","type","readValue","useCallback","LocalStorage","SessionStorage","storedValue","setStoredValue","useState","setValue","value","valueToStore","useEffect","useLocalStorage","useSessionStorage","useMediaQuery","query","matches","setMatches","getMediaMatches","matchMediaChangeHandler","matchMedia","useIsPortrait","portraitMediaQuery","focusableSelector","useFocusTrap","target","focusTrap","setFocusTrapDispatch","lastActiveElement","useRef","setFocusTrap","onDemandTarget","restoreFocusTrap","keyDownHandler","event","focusableElements","firstFocusableElement","lastFocusableElement","useScrollBlock","blockScroll","blockScrollHandler","restoreScroll","restoreScrollHandler","useIsClient","isClient","setClient","useIsFirstRender","isFirst","useUpdateEffect","effect","deps"],"mappings":"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","file":"index.mjs","sourcesContent":["import { useCallback, useEffect, useState } from 'react'\nimport { LocalStorage } from '@alessiofrittoli/web-utils/storage/LocalStorage'\nimport { SessionStorage } from '@alessiofrittoli/web-utils/storage/SessionStorage'\n\ntype Value<T>\t\t= T | undefined | null\ntype SetValue<T>\t= React.Dispatch<React.SetStateAction<T>>\n\n/**\n * Easly handle Local or Session Storage State.\n * \n * @param\tkey\t\t\t\tThe storage item key.\n * @param\tinitialValue\tThe storage item initial value.\n * @param\ttype\t\t\t( Optional ) The storage API to use. Default: `local`.\n */\nexport const useStorage = <T = string>(\n\tkey\t\t\t\t: string,\n\tinitialValue?\t: T,\n\ttype\t\t\t: 'local' | 'session' = 'local'\n): [ Value<T>, SetValue<Value<T>> ] => {\n\n\tconst readValue = useCallback( () => (\n\t\t( type === 'local' ? LocalStorage : SessionStorage )\n\t\t\t.get<T>( key ) ?? initialValue\n\t), [ type, key, initialValue ] )\n\n\n\t/**\n\t * State to store our value.\n\t * Pass initial state function to useState so logic is only executed once.\n\t * \n\t */\n\tconst [ storedValue, setStoredValue ] = useState<Value<T>>( initialValue )\n\n\t/**\n\t * Return a wrapped version of useState's setter function that\n\t * persists the new value to localStorage | sessionStorage.\n\t * \n\t * @param value The SetStateAction value.\n\t */\n\tconst setValue = useCallback<SetValue<Value<T>>>( value => {\n\n\t\tsetStoredValue( storedValue => {\n\t\t\tconst valueToStore = value instanceof Function ? value( storedValue ) : value\n\t\n\t\t\t;(\n\t\t\t\ttypeof window !== 'undefined' &&\n\t\t\t\ttype === 'local' ? LocalStorage : SessionStorage\n\t\t\t).set( key, valueToStore )\n\n\t\t\treturn valueToStore\n\t\t} )\n\n\n\t}, [ type, key ] )\n\n\tuseEffect( () => {\n\t\tsetStoredValue( readValue() )\n\t}, [ readValue ] )\n\n\treturn [ storedValue, setValue ]\n}","import { useStorage } from './useStorage'\n\n/**\n * useLocalStorage hook.\n * \n * @param\tkey\t\t\t\tThe local storage item key.\n * @param\tinitialValue\tThe local storage item initial value.\n */\nexport const useLocalStorage = <T = string>(\n\tkey\t\t\t\t: string,\n\tinitialValue?\t: T\n) => useStorage( key, initialValue, 'local' )","import { useStorage } from './useStorage'\n\n/**\n * useSessionStorage hook.\n * \n * @param\tkey\t\t\t\tThe session item key.\n * @param\tinitialValue\tThe session item initial value.\n */\nexport const useSessionStorage = <T = string>(\n\tkey\t\t\t\t: string,\n\tinitialValue?\t: T\n) => useStorage( key, initialValue, 'session' )","import { useCallback, useEffect, useState } from 'react'\nimport { getMediaMatches } from '@alessiofrittoli/web-utils/browser-api'\n\n\n/**\n * Get Document Media matches and listen for changes.\n *\n * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia)\n *\n * @param\tquery A string specifying the media query to parse into a `MediaQueryList`.\n * @returns\tA boolean value that returns `true` if the document currently matches the media query list, or `false` if not.\n */\nexport const useMediaQuery = ( query: string ) => {\n\n\tconst [ matches, setMatches ]\t= useState( getMediaMatches( query ) )\n\tconst matchMediaChangeHandler\t= useCallback( () => setMatches( getMediaMatches( query ) ), [ query ] )\n\n\n\tuseEffect( () => {\n\n\t\tconst matchMedia = window.matchMedia( query )\n\t\t// Triggered at the first client-side load\n\t\tmatchMediaChangeHandler()\n\t\t// Listen matchMedia\n\t\tmatchMedia.addEventListener( 'change', matchMediaChangeHandler )\n\n\t\treturn () => {\n\t\t\tmatchMedia.removeEventListener( 'change', matchMediaChangeHandler )\n\t\t}\n\n\t}, [ query, matchMediaChangeHandler ] )\n\n\treturn matches\n\t\n}","import { useMediaQuery } from './useMediaQuery'\nimport { portraitMediaQuery } from '@alessiofrittoli/web-utils/device'\n\n/**\n * Check if device is portrait oriented.\n * \n * State get updated when device orientation changes.\n *\n * @returns\t`true` if the device is portrait oriented, `false` otherwise.\n */\nexport const useIsPortrait = () => useMediaQuery( portraitMediaQuery )","import { useCallback, useEffect, useRef, useState } from 'react'\n\ntype SetFocusTrap = ( target?: HTMLElement ) => void\ntype RestoreFocusTrap = () => void\n\nconst focusableSelector = [\n\t'input', 'select', 'textarea',\n\t'button', '[href]', '[tabindex]:not([tabindex=\"-1\"])',\n].join( ', ' )\n\n\n/**\n * Trap focus inside the given HTML Element.\n * \n * @param target (Optional) The target HTMLElement React RefObject to trap focus within.\n * \t\t\t\t\tIf no target is given, you must provide the target HTMLElement when calling `setFocusTrap`.\n * \n * @returns A tuple containing:\n * - `setFocusTrap`: A function to enable the focus trap. Optionally accept an HTMLElement as target.\n * - `restoreFocusTrap`: A function to restore the previous focus state.\n */\nexport const useFocusTrap = (\n\ttarget?: React.RefObject<HTMLElement | null>\n): readonly [ SetFocusTrap, RestoreFocusTrap ] => {\n\n\tconst [ focusTrap, setFocusTrapDispatch ] = (\n\t\tuseState<HTMLElement | false>( false )\n\t)\n\n\tconst lastActiveElement = useRef<HTMLElement>( null )\n\t\n\t/**\n\t * Enable the focus trap.\n\t * \n\t */\n\tconst setFocusTrap = useCallback<SetFocusTrap>( onDemandTarget => {\n\n\t\tlastActiveElement.current\t= document.activeElement as HTMLElement\n\t\tconst focusTrap\t\t\t\t= onDemandTarget || target?.current || false\n\t\t\n\t\tif ( ! focusTrap ) return\n\n\t\treturn setFocusTrapDispatch( focusTrap )\n\t\n\t}, [ target ] )\n\n\n\t/**\n\t * Restore the focus to the latest Document active Element.\n\t */\n\tconst restoreFocusTrap = useCallback<RestoreFocusTrap>( () => {\n\n\t\tlastActiveElement.current?.focus()\n\t\tsetFocusTrapDispatch( false )\n\t\n\t}, [] )\n\n\t\n\tuseEffect( () => {\n\n\t\tif ( ! focusTrap ) return\n\n\t\tconst keyDownHandler = ( event: KeyboardEvent ) => {\n\n\t\t\tif ( event.key !== 'Tab' ) return\n\n\t\t\tconst focusableElements\t\t= Array.from( focusTrap.querySelectorAll<HTMLElement>( focusableSelector ) ),\n\t\t\t\tfirstFocusableElement\t= focusableElements.at( 0 ),\n\t\t\t\tlastFocusableElement\t= focusableElements.at( -1 );\n\n\t\t\tif ( ! event.shiftKey ) {\n\t\t\t\t/**\n\t\t\t\t * Focust the firs element if\n\t\t\t\t * focusing forward and the current focused element is the last one.\n\t\t\t\t */\n\t\t\t\tif ( document.activeElement === lastFocusableElement ) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tfirstFocusableElement?.focus()\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\n\t\t\t/**\n\t\t\t * Focus the last focusable element if\n\t\t\t * focusing backward and the current focused element is the first one.\n\t\t\t * \n\t\t\t */\n\t\t\tif ( document.activeElement === firstFocusableElement ) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tlastFocusableElement?.focus()\n\t\t\t}\n\n\t\t}\n\n\t\tdocument.addEventListener( 'keydown', keyDownHandler );\n\t\n\t\treturn () => {\n\t\t\tdocument.removeEventListener( 'keydown', keyDownHandler );\n\t\t}\n\n\t}, [ focusTrap ] )\n\n\treturn [ setFocusTrap, restoreFocusTrap ]\n\n}","import { useCallback } from 'react'\nimport {\n\tblockScroll as blockScrollHandler,\n\trestoreScroll as restoreScrollHandler\n} from '@alessiofrittoli/web-utils/dom'\n\n\n/**\n * Prevent Element overflow.\n * \n * @param target (Optional) The React RefObject target HTMLElement. Default: `Document.documentElement`.\n */\nexport const useScrollBlock = ( target?: React.RefObject<HTMLElement | null> ) => {\n\t\n\t/**\n\t * Block scroll.\n\t * \n\t */\n\tconst blockScroll = useCallback(\n\t\t() => blockScrollHandler( target?.current || undefined ), [ target ]\n\t)\n\n\n\t/**\n\t * Restore scroll.\n\t * \n\t */\n\tconst restoreScroll = useCallback(\n\t\t() => restoreScrollHandler( target?.current || undefined ), [ target ]\n\t)\n\n\t\n\treturn [ blockScroll, restoreScroll ] as const\n\n}","import { useEffect, useState } from 'react'\n\n/**\n * Check if the React Hook or Component where this hook is executed is running in a browser environment.\n * \n * @returns `true` if the React Hook or Component is running in a browser environment, `false` otherwise.\n */\nexport const useIsClient = () => {\n\n\tconst [ isClient, setClient ] = useState( false )\n\n\tuseEffect( () => setClient( true ), [] )\n\n\treturn isClient\n\n}","import { useRef } from 'react'\n\n/**\n * Check if is first React Hook/Component render.\n * \n * @returns `true` at the mount time, then always `false`.\n * - Note that if the React Hook/Component has no state updates, `useIsFirstRender` will always return `true`.\n */\nexport const useIsFirstRender = () => {\n\n\tconst isFirst = useRef( true )\n\n\tif ( isFirst.current ) {\n\t\tisFirst.current = false\n\n\t\treturn true\n\t}\n\n\treturn isFirst.current\n\t\n}","import { useEffect } from 'react'\nimport { useIsFirstRender } from './useIsFirstRender'\n\n\n/**\n * Modified version of `useEffect` that skips the first render.\n *\n * @param\teffect\tImperative function that can return a cleanup function.\n * @param\tdeps\tIf present, effect will only activate if the values in the list change.\n */\nexport const useUpdateEffect = (\n\teffect\t: React.EffectCallback,\n\tdeps?\t: React.DependencyList,\n) => {\n\n\tconst isFirst = useIsFirstRender()\n\n\tuseEffect( () => {\n\t\tif ( ! isFirst ) return effect()\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, deps )\n\t\n}"]}
1
+ {"version":3,"sources":["../src/browser-api/storage/useStorage.ts","../src/browser-api/storage/useLocalStorage.ts","../src/browser-api/storage/useSessionStorage.ts","../src/browser-api/useMediaQuery.ts","../src/browser-api/useIsPortrait.ts","../src/dom-api/useFocusTrap.ts","../src/dom-api/useScrollBlock.ts","../src/misc/useIsClient.ts","../src/misc/useIsFirstRender.ts","../src/misc/useUpdateEffect.ts"],"names":["useStorage","key","initialValue","type","readValue","useCallback","LocalStorage","SessionStorage","storedValue","setStoredValue","useState","setValue","value","valueToStore","useEffect","useLocalStorage","useSessionStorage","useMediaQuery","query","matches","setMatches","getMediaMatches","matchMediaChangeHandler","matchMedia","useIsPortrait","portraitMediaQuery","focusableSelector","useFocusTrap","target","focusTrap","setFocusTrapDispatch","lastActiveElement","useRef","setFocusTrap","onDemandTarget","restoreFocusTrap","keyDownHandler","event","focusableElements","firstFocusableElement","lastFocusableElement","useScrollBlock","blockScroll","blockScrollHandler","restoreScroll","restoreScrollHandler","useIsClient","isClient","setClient","useIsFirstRender","isFirst","useUpdateEffect","effect","deps"],"mappings":"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","file":"index.mjs","sourcesContent":["import { useCallback, useEffect, useState } from 'react'\nimport { LocalStorage } from '@alessiofrittoli/web-utils/storage/LocalStorage'\nimport { SessionStorage } from '@alessiofrittoli/web-utils/storage/SessionStorage'\n\ntype Value<T>\t\t= T | undefined | null\ntype SetValue<T>\t= React.Dispatch<React.SetStateAction<T>>\n\n/**\n * Easly handle Local or Session Storage State.\n * \n * @param\tkey\t\t\t\tThe storage item key.\n * @param\tinitialValue\tThe storage item initial value.\n * @param\ttype\t\t\t( Optional ) The storage API to use. Default: `local`.\n */\nexport const useStorage = <T = string>(\n\tkey\t\t\t\t: string,\n\tinitialValue?\t: T,\n\ttype\t\t\t: 'local' | 'session' = 'local'\n): [ Value<T>, SetValue<Value<T>> ] => {\n\n\tconst readValue = useCallback( () => (\n\t\t( type === 'local' ? LocalStorage : SessionStorage )\n\t\t\t.get<T>( key ) ?? initialValue\n\t), [ type, key, initialValue ] )\n\n\n\t/**\n\t * State to store our value.\n\t * Pass initial state function to useState so logic is only executed once.\n\t * \n\t */\n\tconst [ storedValue, setStoredValue ] = useState<Value<T>>( initialValue )\n\n\t/**\n\t * Return a wrapped version of useState's setter function that\n\t * persists the new value to localStorage | sessionStorage.\n\t * \n\t * @param value The SetStateAction value.\n\t */\n\tconst setValue = useCallback<SetValue<Value<T>>>( value => {\n\n\t\tsetStoredValue( storedValue => {\n\t\t\tconst valueToStore = value instanceof Function ? value( storedValue ) : value\n\t\n\t\t\t;(\n\t\t\t\ttypeof window !== 'undefined' &&\n\t\t\t\ttype === 'local' ? LocalStorage : SessionStorage\n\t\t\t).set( key, valueToStore )\n\n\t\t\treturn valueToStore\n\t\t} )\n\n\n\t}, [ type, key ] )\n\n\tuseEffect( () => {\n\t\tsetStoredValue( readValue() )\n\t}, [ readValue ] )\n\n\treturn [ storedValue, setValue ]\n}","import { useStorage } from './useStorage'\n\n/**\n * useLocalStorage hook.\n * \n * @param\tkey\t\t\t\tThe local storage item key.\n * @param\tinitialValue\tThe local storage item initial value.\n */\nexport const useLocalStorage = <T = string>(\n\tkey\t\t\t\t: string,\n\tinitialValue?\t: T\n) => useStorage( key, initialValue, 'local' )","import { useStorage } from './useStorage'\n\n/**\n * useSessionStorage hook.\n * \n * @param\tkey\t\t\t\tThe session item key.\n * @param\tinitialValue\tThe session item initial value.\n */\nexport const useSessionStorage = <T = string>(\n\tkey\t\t\t\t: string,\n\tinitialValue?\t: T\n) => useStorage( key, initialValue, 'session' )","import { useCallback, useEffect, useState } from 'react'\nimport { getMediaMatches } from '@alessiofrittoli/web-utils/browser-api'\n\n\n/**\n * Get Document Media matches and listen for changes.\n *\n * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia)\n *\n * @param\tquery A string specifying the media query to parse into a `MediaQueryList`.\n * @returns\tA boolean value that returns `true` if the document currently matches the media query list, or `false` if not.\n */\nexport const useMediaQuery = ( query: string ) => {\n\n\tconst [ matches, setMatches ]\t= useState( getMediaMatches( query ) )\n\tconst matchMediaChangeHandler\t= useCallback( () => setMatches( getMediaMatches( query ) ), [ query ] )\n\n\n\tuseEffect( () => {\n\n\t\tconst matchMedia = window.matchMedia( query )\n\t\t// Triggered at the first client-side load\n\t\tmatchMediaChangeHandler()\n\t\t// Listen matchMedia\n\t\tmatchMedia.addEventListener( 'change', matchMediaChangeHandler )\n\n\t\treturn () => {\n\t\t\tmatchMedia.removeEventListener( 'change', matchMediaChangeHandler )\n\t\t}\n\n\t}, [ query, matchMediaChangeHandler ] )\n\n\treturn matches\n\t\n}","import { useMediaQuery } from './useMediaQuery'\nimport { portraitMediaQuery } from '@alessiofrittoli/web-utils/device'\n\n/**\n * Check if device is portrait oriented.\n * \n * State get updated when device orientation changes.\n *\n * @returns\t`true` if the device is portrait oriented, `false` otherwise.\n */\nexport const useIsPortrait = () => useMediaQuery( portraitMediaQuery )","import { useCallback, useEffect, useRef, useState } from 'react'\n\ntype SetFocusTrap = ( target?: HTMLElement ) => void\ntype RestoreFocusTrap = () => void\n\nconst focusableSelector = [\n\t'input', 'select', 'textarea',\n\t'button', '[href]', '[tabindex]:not([tabindex=\"-1\"])',\n].join( ', ' )\n\n\n/**\n * Trap focus inside the given HTML Element.\n * \n * @param target (Optional) The target HTMLElement React RefObject to trap focus within.\n * \t\t\t\t\tIf no target is given, you must provide the target HTMLElement when calling `setFocusTrap`.\n * \n * @returns A tuple containing:\n * - `setFocusTrap`: A function to enable the focus trap. Optionally accept an HTMLElement as target.\n * - `restoreFocusTrap`: A function to restore the previous focus state.\n */\nexport const useFocusTrap = (\n\ttarget?: React.RefObject<HTMLElement | null>\n): readonly [ SetFocusTrap, RestoreFocusTrap ] => {\n\n\tconst [ focusTrap, setFocusTrapDispatch ] = (\n\t\tuseState<HTMLElement | false>( false )\n\t)\n\n\tconst lastActiveElement = useRef<HTMLElement>( null )\n\t\n\t/**\n\t * Enable the focus trap.\n\t * \n\t */\n\tconst setFocusTrap = useCallback<SetFocusTrap>( onDemandTarget => {\n\n\t\tlastActiveElement.current\t= document.activeElement as HTMLElement\n\t\tconst focusTrap\t\t\t\t= onDemandTarget || target?.current || false\n\t\t\n\t\tif ( ! focusTrap ) return\n\n\t\treturn setFocusTrapDispatch( focusTrap )\n\t\n\t}, [ target ] )\n\n\n\t/**\n\t * Restore the focus to the latest Document active Element.\n\t */\n\tconst restoreFocusTrap = useCallback<RestoreFocusTrap>( () => {\n\n\t\tlastActiveElement.current?.focus()\n\t\tsetFocusTrapDispatch( false )\n\t\n\t}, [] )\n\n\t\n\tuseEffect( () => {\n\n\t\tif ( ! focusTrap ) return\n\n\t\tconst keyDownHandler = ( event: KeyboardEvent ) => {\n\n\t\t\tif ( event.key !== 'Tab' ) return\n\n\t\t\tconst focusableElements\t\t= Array.from( focusTrap.querySelectorAll<HTMLElement>( focusableSelector ) ),\n\t\t\t\tfirstFocusableElement\t= focusableElements.at( 0 ),\n\t\t\t\tlastFocusableElement\t= focusableElements.at( -1 );\n\n\t\t\tif ( ! event.shiftKey ) {\n\t\t\t\t/**\n\t\t\t\t * Focust the firs element if\n\t\t\t\t * focusing forward and the current focused element is the last one.\n\t\t\t\t */\n\t\t\t\tif ( document.activeElement === lastFocusableElement ) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tfirstFocusableElement?.focus()\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\n\t\t\t/**\n\t\t\t * Focus the last focusable element if\n\t\t\t * focusing backward and the current focused element is the first one.\n\t\t\t * \n\t\t\t */\n\t\t\tif ( document.activeElement === firstFocusableElement ) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tlastFocusableElement?.focus()\n\t\t\t}\n\n\t\t}\n\n\t\tdocument.addEventListener( 'keydown', keyDownHandler );\n\t\n\t\treturn () => {\n\t\t\tdocument.removeEventListener( 'keydown', keyDownHandler );\n\t\t}\n\n\t}, [ focusTrap ] )\n\n\treturn [ setFocusTrap, restoreFocusTrap ]\n\n}","import { useCallback } from 'react'\nimport {\n\tblockScroll as blockScrollHandler,\n\trestoreScroll as restoreScrollHandler\n} from '@alessiofrittoli/web-utils/dom'\n\n\n/**\n * Prevent Element overflow.\n * \n * @param target (Optional) The React RefObject target HTMLElement. Default: `Document.documentElement`.\n */\nexport const useScrollBlock = ( target?: React.RefObject<HTMLElement | null> ) => {\n\t\n\t/**\n\t * Block scroll.\n\t * \n\t */\n\tconst blockScroll = useCallback(\n\t\t() => blockScrollHandler( target?.current || undefined ), [ target ]\n\t)\n\n\n\t/**\n\t * Restore scroll.\n\t * \n\t */\n\tconst restoreScroll = useCallback(\n\t\t() => restoreScrollHandler( target?.current || undefined ), [ target ]\n\t)\n\n\t\n\treturn [ blockScroll, restoreScroll ] as const\n\n}","import { useEffect, useState } from 'react'\n\n/**\n * Check if the React Hook or Component where this hook is executed is running in a browser environment.\n * \n * @returns `true` if the React Hook or Component is running in a browser environment, `false` otherwise.\n */\nexport const useIsClient = () => {\n\n\tconst [ isClient, setClient ] = useState( false )\n\n\tuseEffect( () => setClient( true ), [] )\n\n\treturn isClient\n\n}","import { useRef } from 'react'\n\n/**\n * Check if is first React Hook/Component render.\n * \n * @returns `true` at the mount time, then always `false`.\n * - Note that if the React Hook/Component has no state updates, `useIsFirstRender` will always return `true`.\n */\nexport const useIsFirstRender = () => {\n\n\tconst isFirst = useRef( true )\n\n\tif ( isFirst.current ) {\n\t\tisFirst.current = false\n\n\t\treturn true\n\t}\n\n\treturn isFirst.current\n\t\n}","import { useEffect } from 'react'\nimport { useIsFirstRender } from './useIsFirstRender'\n\n\n/**\n * Modified version of `useEffect` that skips the first render.\n *\n * @param\teffect\tImperative function that can return a cleanup function.\n * @param\tdeps\tIf present, effect will only activate if the values in the list change.\n */\nexport const useUpdateEffect = (\n\teffect\t: React.EffectCallback,\n\tdeps?\t: React.DependencyList,\n) => {\n\n\tconst isFirst = useIsFirstRender()\n\n\tuseEffect( () => {\n\t\tif ( ! isFirst ) return effect()\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, deps )\n\t\n}"]}
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react');var i=()=>{let[e,t]=react.useState(false);return react.useEffect(()=>t(true),[]),e};var r=()=>{let e=react.useRef(true);return e.current?(e.current=false,true):e.current};var R=(e,t)=>{let s=r();react.useEffect(()=>{if(!s)return e()},t);};exports.useIsClient=i;exports.useIsFirstRender=r;exports.useUpdateEffect=R;//# sourceMappingURL=index.js.map
1
+ 'use strict';var react=require('react');var p=()=>{let[e,t]=react.useState(false);return react.useEffect(()=>t(true),[]),e};var s=()=>{let e=react.useRef(true);return e.current?(e.current=false,true):e.current};var E=(e,t)=>{let o=s();react.useEffect(()=>{if(!o)return e()},t);};exports.useIsClient=p;exports.useIsFirstRender=s;exports.useUpdateEffect=E;//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map
@@ -1,2 +1,2 @@
1
- import {useState,useEffect,useRef}from'react';var i=()=>{let[e,t]=useState(false);return useEffect(()=>t(true),[]),e};var r=()=>{let e=useRef(true);return e.current?(e.current=false,true):e.current};var R=(e,t)=>{let s=r();useEffect(()=>{if(!s)return e()},t);};export{i as useIsClient,r as useIsFirstRender,R as useUpdateEffect};//# sourceMappingURL=index.mjs.map
1
+ import {useState,useEffect,useRef}from'react';var m=()=>{let[e,t]=useState(false);return useEffect(()=>t(true),[]),e};var o=()=>{let e=useRef(true);return e.current?(e.current=false,true):e.current};var F=(e,t)=>{let f=o();useEffect(()=>{if(!f)return e()},t);};export{m as useIsClient,o as useIsFirstRender,F as useUpdateEffect};//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react');var i=()=>{let[e,t]=react.useState(false);return react.useEffect(()=>t(true),[]),e};exports.useIsClient=i;//# sourceMappingURL=useIsClient.js.map
1
+ 'use strict';var react=require('react');var o=()=>{let[e,t]=react.useState(false);return react.useEffect(()=>t(true),[]),e};exports.useIsClient=o;//# sourceMappingURL=useIsClient.js.map
2
2
  //# sourceMappingURL=useIsClient.js.map
@@ -1,2 +1,2 @@
1
- import {useState,useEffect}from'react';var i=()=>{let[e,t]=useState(false);return useEffect(()=>t(true),[]),e};export{i as useIsClient};//# sourceMappingURL=useIsClient.mjs.map
1
+ import {useState,useEffect}from'react';var u=()=>{let[e,t]=useState(false);return useEffect(()=>t(true),[]),e};export{u as useIsClient};//# sourceMappingURL=useIsClient.mjs.map
2
2
  //# sourceMappingURL=useIsClient.mjs.map
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react');var s=()=>{let r=react.useRef(true);return r.current?(r.current=false,true):r.current};exports.useIsFirstRender=s;//# sourceMappingURL=useIsFirstRender.js.map
1
+ 'use strict';var react=require('react');var u=()=>{let r=react.useRef(true);return r.current?(r.current=false,true):r.current};exports.useIsFirstRender=u;//# sourceMappingURL=useIsFirstRender.js.map
2
2
  //# sourceMappingURL=useIsFirstRender.js.map
@@ -1,2 +1,2 @@
1
- import {useRef}from'react';var s=()=>{let r=useRef(true);return r.current?(r.current=false,true):r.current};export{s as useIsFirstRender};//# sourceMappingURL=useIsFirstRender.mjs.map
1
+ import {useRef}from'react';var n=()=>{let r=useRef(true);return r.current?(r.current=false,true):r.current};export{n as useIsFirstRender};//# sourceMappingURL=useIsFirstRender.mjs.map
2
2
  //# sourceMappingURL=useIsFirstRender.mjs.map
@@ -0,0 +1,12 @@
1
+ import * as _alessiofrittoli_math_utils_helpers from '@alessiofrittoli/math-utils/helpers';
2
+ import { PaginateOptions } from '@alessiofrittoli/math-utils/helpers';
3
+
4
+ /**
5
+ * Get pagination informations based on the given options.
6
+ *
7
+ * @param options An object defining pagination input data. See {@link PaginateOptions} for more information.
8
+ * @returns A memoized object containing pagination informations based on the given options.
9
+ */
10
+ declare const usePagination: (options?: PaginateOptions) => _alessiofrittoli_math_utils_helpers.Pagination;
11
+
12
+ export { usePagination };
@@ -0,0 +1,12 @@
1
+ import * as _alessiofrittoli_math_utils_helpers from '@alessiofrittoli/math-utils/helpers';
2
+ import { PaginateOptions } from '@alessiofrittoli/math-utils/helpers';
3
+
4
+ /**
5
+ * Get pagination informations based on the given options.
6
+ *
7
+ * @param options An object defining pagination input data. See {@link PaginateOptions} for more information.
8
+ * @returns A memoized object containing pagination informations based on the given options.
9
+ */
10
+ declare const usePagination: (options?: PaginateOptions) => _alessiofrittoli_math_utils_helpers.Pagination;
11
+
12
+ export { usePagination };
@@ -0,0 +1,2 @@
1
+ 'use strict';var react=require('react'),helpers=require('@alessiofrittoli/math-utils/helpers');var p=(t={})=>react.useMemo(()=>helpers.paginate(t),[t]);exports.usePagination=p;//# sourceMappingURL=usePagination.js.map
2
+ //# sourceMappingURL=usePagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/misc/usePagination.ts"],"names":["usePagination","options","useMemo","paginate"],"mappings":"mGASaA,CAAgB,CAAA,CAAEC,EAA2B,EAAC,GAC1DC,cAAS,IAAMC,gBAAAA,CAAUF,CAAQ,CAAG,CAAA,CAAEA,CAAQ,CAAE","file":"usePagination.js","sourcesContent":["import { useMemo } from 'react'\nimport { paginate, type PaginateOptions } from '@alessiofrittoli/math-utils/helpers'\n\n/**\n * Get pagination informations based on the given options.\n *\n * @param options An object defining pagination input data. See {@link PaginateOptions} for more information.\n * @returns A memoized object containing pagination informations based on the given options.\n */\nexport const usePagination = ( options: PaginateOptions = {} ) => (\n\tuseMemo( () => paginate( options ), [ options ] )\n)"]}
@@ -0,0 +1,2 @@
1
+ import {useMemo}from'react';import {paginate}from'@alessiofrittoli/math-utils/helpers';var m=(t={})=>useMemo(()=>paginate(t),[t]);export{m as usePagination};//# sourceMappingURL=usePagination.mjs.map
2
+ //# sourceMappingURL=usePagination.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/misc/usePagination.ts"],"names":["usePagination","options","useMemo","paginate"],"mappings":"2FASaA,CAAgB,CAAA,CAAEC,EAA2B,EAAC,GAC1DC,QAAS,IAAMC,QAAAA,CAAUF,CAAQ,CAAG,CAAA,CAAEA,CAAQ,CAAE","file":"usePagination.mjs","sourcesContent":["import { useMemo } from 'react'\nimport { paginate, type PaginateOptions } from '@alessiofrittoli/math-utils/helpers'\n\n/**\n * Get pagination informations based on the given options.\n *\n * @param options An object defining pagination input data. See {@link PaginateOptions} for more information.\n * @returns A memoized object containing pagination informations based on the given options.\n */\nexport const usePagination = ( options: PaginateOptions = {} ) => (\n\tuseMemo( () => paginate( options ), [ options ] )\n)"]}
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react');var r=()=>{let e=react.useRef(true);return e.current?(e.current=false,true):e.current};var p=(e,t)=>{let s=r();react.useEffect(()=>{if(!s)return e()},t);};exports.useUpdateEffect=p;//# sourceMappingURL=useUpdateEffect.js.map
1
+ 'use strict';var react=require('react');var r=()=>{let e=react.useRef(true);return e.current?(e.current=false,true):e.current};var m=(e,t)=>{let s=r();react.useEffect(()=>{if(!s)return e()},t);};exports.useUpdateEffect=m;//# sourceMappingURL=useUpdateEffect.js.map
2
2
  //# sourceMappingURL=useUpdateEffect.js.map
@@ -1,2 +1,2 @@
1
- import {useEffect,useRef}from'react';var r=()=>{let e=useRef(true);return e.current?(e.current=false,true):e.current};var p=(e,t)=>{let s=r();useEffect(()=>{if(!s)return e()},t);};export{p as useUpdateEffect};//# sourceMappingURL=useUpdateEffect.mjs.map
1
+ import {useEffect,useRef}from'react';var r=()=>{let e=useRef(true);return e.current?(e.current=false,true):e.current};var R=(e,t)=>{let s=r();useEffect(()=>{if(!s)return e()},t);};export{R as useUpdateEffect};//# sourceMappingURL=useUpdateEffect.mjs.map
2
2
  //# sourceMappingURL=useUpdateEffect.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alessiofrittoli/react-hooks",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "TypeScript React utility Hooks",
5
5
  "author": {
6
6
  "name": "Alessio Frittoli",
@@ -112,7 +112,7 @@
112
112
  "@testing-library/react": "^16.3.0",
113
113
  "@testing-library/user-event": "^14.6.1",
114
114
  "@types/jest": "^29.5.14",
115
- "@types/node": "^22.14.1",
115
+ "@types/node": "^22.15.2",
116
116
  "@types/react": "^19.1.2",
117
117
  "@types/react-dom": "^19.1.2",
118
118
  "concurrently": "^9.1.2",
@@ -133,6 +133,8 @@
133
133
  "typescript-eslint": "^8.31.0"
134
134
  },
135
135
  "dependencies": {
136
+ "@alessiofrittoli/math-utils": "^1.12.0",
137
+ "@alessiofrittoli/type-utils": "^1.7.0",
136
138
  "@alessiofrittoli/web-utils": "^1.9.1"
137
139
  },
138
140
  "peerDependencies": {