@opensite/hooks 0.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 (111) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +102 -0
  3. package/dist/browser/opensite-hooks.umd.cjs +2 -0
  4. package/dist/browser/opensite-hooks.umd.js +2 -0
  5. package/dist/browser/opensite-hooks.umd.js.map +1 -0
  6. package/dist/core/index.cjs +16 -0
  7. package/dist/core/index.d.ts +24 -0
  8. package/dist/core/index.js +16 -0
  9. package/dist/core/useBoolean.cjs +8 -0
  10. package/dist/core/useBoolean.d.ts +8 -0
  11. package/dist/core/useBoolean.js +8 -0
  12. package/dist/core/useCopyToClipboard.cjs +67 -0
  13. package/dist/core/useCopyToClipboard.d.ts +9 -0
  14. package/dist/core/useCopyToClipboard.js +67 -0
  15. package/dist/core/useDebounceCallback.cjs +83 -0
  16. package/dist/core/useDebounceCallback.d.ts +11 -0
  17. package/dist/core/useDebounceCallback.js +83 -0
  18. package/dist/core/useDebounceValue.cjs +13 -0
  19. package/dist/core/useDebounceValue.d.ts +2 -0
  20. package/dist/core/useDebounceValue.js +13 -0
  21. package/dist/core/useEventListener.cjs +40 -0
  22. package/dist/core/useEventListener.d.ts +6 -0
  23. package/dist/core/useEventListener.js +40 -0
  24. package/dist/core/useHover.cjs +14 -0
  25. package/dist/core/useHover.d.ts +1 -0
  26. package/dist/core/useHover.js +14 -0
  27. package/dist/core/useIsClient.cjs +8 -0
  28. package/dist/core/useIsClient.d.ts +1 -0
  29. package/dist/core/useIsClient.js +8 -0
  30. package/dist/core/useIsomorphicLayoutEffect.cjs +2 -0
  31. package/dist/core/useIsomorphicLayoutEffect.d.ts +2 -0
  32. package/dist/core/useIsomorphicLayoutEffect.js +2 -0
  33. package/dist/core/useLocalStorage.cjs +63 -0
  34. package/dist/core/useLocalStorage.d.ts +9 -0
  35. package/dist/core/useLocalStorage.js +63 -0
  36. package/dist/core/useMap.cjs +39 -0
  37. package/dist/core/useMap.d.ts +9 -0
  38. package/dist/core/useMap.js +39 -0
  39. package/dist/core/useMediaQuery.cjs +26 -0
  40. package/dist/core/useMediaQuery.d.ts +4 -0
  41. package/dist/core/useMediaQuery.js +26 -0
  42. package/dist/core/useOnClickOutside.cjs +30 -0
  43. package/dist/core/useOnClickOutside.d.ts +3 -0
  44. package/dist/core/useOnClickOutside.js +30 -0
  45. package/dist/core/usePrevious.cjs +8 -0
  46. package/dist/core/usePrevious.d.ts +1 -0
  47. package/dist/core/usePrevious.js +8 -0
  48. package/dist/core/useResizeObserver.cjs +37 -0
  49. package/dist/core/useResizeObserver.d.ts +3 -0
  50. package/dist/core/useResizeObserver.js +37 -0
  51. package/dist/core/useSessionStorage.cjs +63 -0
  52. package/dist/core/useSessionStorage.d.ts +9 -0
  53. package/dist/core/useSessionStorage.js +63 -0
  54. package/dist/core/useThrottle.cjs +65 -0
  55. package/dist/core/useThrottle.d.ts +5 -0
  56. package/dist/core/useThrottle.js +65 -0
  57. package/dist/hooks/index.cjs +16 -0
  58. package/dist/hooks/index.d.ts +24 -0
  59. package/dist/hooks/index.js +16 -0
  60. package/dist/hooks/useBoolean.cjs +1 -0
  61. package/dist/hooks/useBoolean.d.ts +2 -0
  62. package/dist/hooks/useBoolean.js +1 -0
  63. package/dist/hooks/useCopyToClipboard.cjs +1 -0
  64. package/dist/hooks/useCopyToClipboard.d.ts +2 -0
  65. package/dist/hooks/useCopyToClipboard.js +1 -0
  66. package/dist/hooks/useDebounceCallback.cjs +1 -0
  67. package/dist/hooks/useDebounceCallback.d.ts +2 -0
  68. package/dist/hooks/useDebounceCallback.js +1 -0
  69. package/dist/hooks/useDebounceValue.cjs +1 -0
  70. package/dist/hooks/useDebounceValue.d.ts +2 -0
  71. package/dist/hooks/useDebounceValue.js +1 -0
  72. package/dist/hooks/useEventListener.cjs +1 -0
  73. package/dist/hooks/useEventListener.d.ts +1 -0
  74. package/dist/hooks/useEventListener.js +1 -0
  75. package/dist/hooks/useHover.cjs +1 -0
  76. package/dist/hooks/useHover.d.ts +1 -0
  77. package/dist/hooks/useHover.js +1 -0
  78. package/dist/hooks/useIsClient.cjs +1 -0
  79. package/dist/hooks/useIsClient.d.ts +1 -0
  80. package/dist/hooks/useIsClient.js +1 -0
  81. package/dist/hooks/useIsomorphicLayoutEffect.cjs +1 -0
  82. package/dist/hooks/useIsomorphicLayoutEffect.d.ts +1 -0
  83. package/dist/hooks/useIsomorphicLayoutEffect.js +1 -0
  84. package/dist/hooks/useLocalStorage.cjs +1 -0
  85. package/dist/hooks/useLocalStorage.d.ts +2 -0
  86. package/dist/hooks/useLocalStorage.js +1 -0
  87. package/dist/hooks/useMap.cjs +1 -0
  88. package/dist/hooks/useMap.d.ts +2 -0
  89. package/dist/hooks/useMap.js +1 -0
  90. package/dist/hooks/useMediaQuery.cjs +1 -0
  91. package/dist/hooks/useMediaQuery.d.ts +2 -0
  92. package/dist/hooks/useMediaQuery.js +1 -0
  93. package/dist/hooks/useOnClickOutside.cjs +1 -0
  94. package/dist/hooks/useOnClickOutside.d.ts +1 -0
  95. package/dist/hooks/useOnClickOutside.js +1 -0
  96. package/dist/hooks/usePrevious.cjs +1 -0
  97. package/dist/hooks/usePrevious.d.ts +1 -0
  98. package/dist/hooks/usePrevious.js +1 -0
  99. package/dist/hooks/useResizeObserver.cjs +1 -0
  100. package/dist/hooks/useResizeObserver.d.ts +1 -0
  101. package/dist/hooks/useResizeObserver.js +1 -0
  102. package/dist/hooks/useSessionStorage.cjs +1 -0
  103. package/dist/hooks/useSessionStorage.d.ts +2 -0
  104. package/dist/hooks/useSessionStorage.js +1 -0
  105. package/dist/hooks/useThrottle.cjs +1 -0
  106. package/dist/hooks/useThrottle.d.ts +2 -0
  107. package/dist/hooks/useThrottle.js +1 -0
  108. package/dist/index.cjs +9 -0
  109. package/dist/index.d.ts +9 -0
  110. package/dist/index.js +9 -0
  111. package/package.json +252 -0
package/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2025, OpenSite AI. All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md ADDED
@@ -0,0 +1,102 @@
1
+ ![Opensite AI Utility Hooks](https://octane.cdn.ing/api/v1/images/transform?url=https://cdn.ing/assets/i/r/285728/knsbi168qz1imlat2aq042c10rw8/opensite-react-hooks.png&q=90&f=webp)
2
+
3
+ ---
4
+
5
+ # ⚡ @opensite/hooks
6
+
7
+ Performance-first React hooks for UI state, storage, events, and responsive behavior. Designed to be tree-shakable, SSR-safe, and CDN-ready.
8
+
9
+ [![npm version](https://img.shields.io/npm/v/@opensite/hooks?style=flat-square)](https://www.npmjs.com/package/@opensite/hooks)
10
+ [![npm downloads](https://img.shields.io/npm/dm/@opensite/hooks?style=flat-square)](https://www.npmjs.com/package/@opensite/hooks)
11
+ [![License](https://img.shields.io/npm/l/@opensite/hooks?style=flat-square)](./LICENSE)
12
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue?style=flat-square)](./tsconfig.json)
13
+ [![Tree-Shakeable](https://img.shields.io/badge/Tree%20Shakeable-Yes-brightgreen?style=flat-square)](#tree-shaking)
14
+
15
+ ## Overview
16
+
17
+ `@opensite/hooks` provides a focused set of high-performance React hooks that work across OpenSite and any open-source React project. Every hook is built for minimal bundle size, avoids unnecessary renders, and is safe for SSR.
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ pnpm add @opensite/hooks
23
+ ```
24
+
25
+ Peer deps: `react` and `react-dom` (17+).
26
+
27
+ ## Quick Start
28
+
29
+ ```tsx
30
+ import { useBoolean, useDebounceValue } from "@opensite/hooks";
31
+
32
+ export function SearchBox() {
33
+ const [query, setQuery] = React.useState("");
34
+ const debouncedQuery = useDebounceValue(query, 300);
35
+ const { value: isOpen, setTrue, setFalse } = useBoolean(false);
36
+
37
+ React.useEffect(() => {
38
+ if (debouncedQuery) {
39
+ // fetch results
40
+ }
41
+ }, [debouncedQuery]);
42
+
43
+ return (
44
+ <>
45
+ <button onClick={setTrue}>Open</button>
46
+ {isOpen && (
47
+ <div>
48
+ <input value={query} onChange={(e) => setQuery(e.target.value)} />
49
+ <button onClick={setFalse}>Close</button>
50
+ </div>
51
+ )}
52
+ </>
53
+ );
54
+ }
55
+ ```
56
+
57
+ ## Hooks
58
+
59
+ - `useBoolean` - Boolean state with stable togglers.
60
+ - `useDebounceValue` - Debounced state for inputs and API calls.
61
+ - `useDebounceCallback` - Debounced function wrapper with optional max wait.
62
+ - `useLocalStorage` - Persistent state with SSR-safe hydration.
63
+ - `useSessionStorage` - Session scoped storage state.
64
+ - `useOnClickOutside` - Dismiss components on outside clicks.
65
+ - `useMediaQuery` - Responsive JavaScript behavior.
66
+ - `useEventListener` - Safe event binding with cleanup.
67
+ - `useIsClient` - Hydration-safe client checks.
68
+ - `useCopyToClipboard` - Clipboard helper with fallback.
69
+ - `usePrevious` - Previous value tracking.
70
+ - `useThrottle` - Throttled state for scroll/resize events.
71
+ - `useResizeObserver` - ResizeObserver-based size tracking.
72
+ - `useHover` - Hover state with pointer events.
73
+ - `useIsomorphicLayoutEffect` - SSR-safe layout effect.
74
+ - `useMap` - Immutable Map state helpers.
75
+
76
+ ## Tree Shaking
77
+
78
+ Prefer granular imports to minimize bundle size:
79
+
80
+ ```tsx
81
+ import { useMediaQuery } from "@opensite/hooks/core/useMediaQuery";
82
+ import { useBoolean } from "@opensite/hooks/hooks/useBoolean";
83
+ ```
84
+
85
+ ## CDN / UMD
86
+
87
+ ```html
88
+ <script src="https://cdn.jsdelivr.net/npm/@opensite/hooks@0.1.0/dist/browser/opensite-hooks.umd.js"></script>
89
+ <script>
90
+ const { useBoolean } = window.OpensiteHooks;
91
+ </script>
92
+ ```
93
+
94
+ ## Documentation
95
+
96
+ - [CHANGELOG](./CHANGELOG.md)
97
+ - [CONTRIBUTING](./CONTRIBUTING.md)
98
+ - [DEVELOPMENT](./DEVELOPMENT.md)
99
+
100
+ ## License
101
+
102
+ [BSD 3](./LICENSE) © [OpenSite AI](https://opensite.ai)
@@ -0,0 +1,2 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).OpensiteHooks={},e.React)}(this,function(e,t){"use strict";const n="undefined"!=typeof window?t.useLayoutEffect:t.useEffect;function r(e,r,u={}){const c=t.useRef(e),o=t.useRef(null),s=t.useRef(null),i=t.useRef(null),a=u.leading??!1,l=u.trailing??!0,f=u.maxWait,d=Math.max(0,r);n(()=>{c.current=e},[e]);const p=t.useCallback(()=>{o.current&&(clearTimeout(o.current),o.current=null),s.current&&(clearTimeout(s.current),s.current=null)},[]),m=t.useCallback(()=>{if(!i.current)return;const e=i.current;i.current=null,c.current(...e)},[]),y=t.useCallback((...e)=>{i.current=e;if(a&&null===o.current&&null===s.current&&m(),o.current&&clearTimeout(o.current),l&&(o.current=setTimeout(()=>{o.current=null,i.current&&m(),s.current&&(clearTimeout(s.current),s.current=null)},d)),null!=f&&l&&!s.current){const e=Math.max(0,f);s.current=setTimeout(()=>{s.current=null,o.current&&(clearTimeout(o.current),o.current=null),i.current&&m()},e)}},[m,a,l,f,d]),w=t.useCallback(()=>{p(),i.current=null},[p]),v=t.useCallback(()=>{i.current&&(p(),m())},[p,m]);return t.useEffect(()=>()=>w(),[w]),{debouncedCallback:y,cancel:w,flush:v}}function u(e,r,u,c){const o=t.useRef(r);n(()=>{o.current=r},[r]),t.useEffect(()=>{const t="undefined"!=typeof Window&&u instanceof Window,n="undefined"!=typeof Document&&u instanceof Document,r=void 0===u?"undefined"!=typeof window?window:null:t||n||"undefined"!=typeof HTMLElement&&u instanceof HTMLElement?u:(s=u)&&"object"==typeof s&&"current"in s?u.current:null;var s;if(!(null==r?void 0:r.addEventListener))return;const i=e=>{const t=o.current;"function"==typeof t?t(e):t.handleEvent(e)};return r.addEventListener(e,i,c),()=>{r.removeEventListener(e,i,c)}},[e,u,c])}e.useBoolean=function(e=!1){const[n,r]=t.useState(e),u=t.useCallback(()=>r(!0),[]),c=t.useCallback(()=>r(!1),[]),o=t.useCallback(()=>r(e=>!e),[]);return{value:n,setValue:r,setTrue:u,setFalse:c,toggle:o}},e.useCopyToClipboard=function(e={}){const n=e.resetDelay??2e3,r=t.useRef(null),[u,c]=t.useState(null),o=t.useMemo(()=>!("undefined"==typeof navigator||!navigator.clipboard)||"undefined"!=typeof document&&("function"==typeof document.queryCommandSupported&&document.queryCommandSupported("copy")),[]),s=t.useCallback(()=>{r.current&&clearTimeout(r.current),r.current=setTimeout(()=>{c(null)},n)},[n]),i=t.useCallback(async e=>{if(!o)return!1;const t="undefined"!=typeof navigator&&!!navigator.clipboard;try{if(t)await navigator.clipboard.writeText(e);else if("undefined"!=typeof document){const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="fixed",t.style.left="-9999px",t.style.top="0",document.body.appendChild(t),t.focus(),t.select();const n=document.execCommand("copy");if(document.body.removeChild(t),!n)return!1}return c(e),s(),!0}catch{return!1}},[o,s]);return t.useEffect(()=>()=>{r.current&&clearTimeout(r.current)},[]),{copy:i,copiedText:u,isSupported:o}},e.useDebounceCallback=r,e.useDebounceValue=function(e,n,u){const[c,o]=t.useState(e),{debouncedCallback:s,cancel:i}=r(e=>{o(e)},n,u);return t.useEffect(()=>{s(e)},[s,e]),t.useEffect(()=>()=>i(),[i]),c},e.useEventListener=u,e.useHover=function(e){const[n,r]=t.useState(!1),c=t.useCallback(()=>{r(!0)},[]),o=t.useCallback(()=>{r(!1)},[]);return u("pointerenter",c,e),u("pointerleave",o,e),n},e.useIsClient=function(){const[e,n]=t.useState(!1);return t.useEffect(()=>{n(!0)},[]),e},e.useIsomorphicLayoutEffect=n,e.useLocalStorage=function(e,n,r={}){const{initializeWithValue:u=!0,serialize:c=JSON.stringify,deserialize:o=JSON.parse,listenToStorageChanges:s=!0}=r,i=t.useRef(n),a=t.useCallback(()=>{if("undefined"==typeof window)return i.current;if(!u)return i.current;try{const t=window.localStorage.getItem(e);return t?o(t):i.current}catch{return i.current}},[o,u,e]),[l,f]=t.useState(()=>a()),d=t.useCallback(t=>{f(n=>{const r="function"==typeof t?t(n):t;if("undefined"!=typeof window)try{window.localStorage.setItem(e,c(r))}catch{}return r})},[e,c]);return t.useEffect(()=>{f(a())},[a]),t.useEffect(()=>{if("undefined"==typeof window||!s)return;const t=t=>{if(t.key===e)if(null!==t.newValue)try{f(o(t.newValue))}catch{f(i.current)}else f(i.current)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)},[o,e,s]),[l,d]},e.useMap=function(e){const[n,r]=t.useState(()=>e instanceof Map||Array.isArray(e)?new Map(e):new Map),u=t.useRef(n);t.useEffect(()=>{u.current=n},[n]);const c=t.useMemo(()=>({set:(e,t)=>{r(n=>{const r=new Map(n);return r.set(e,t),r})},setAll:e=>{r((Map,new Map(e)))},remove:e=>{r(t=>{const n=new Map(t);return n.delete(e),n})},clear:()=>r(new Map),get:e=>u.current.get(e),has:e=>u.current.has(e)}),[]);return[n,c]},e.useMediaQuery=function(e,n={}){const[r,u]=t.useState(()=>"undefined"==typeof window||"function"!=typeof window.matchMedia?n.defaultValue??!1:window.matchMedia(e).matches);return t.useEffect(()=>{if("undefined"==typeof window||"function"!=typeof window.matchMedia)return;const t=window.matchMedia(e),n=e=>{u(e.matches)};return u(t.matches),t.addEventListener?(t.addEventListener("change",n),()=>t.removeEventListener("change",n)):(t.addListener(n),()=>t.removeListener(n))},[e]),r},e.useOnClickOutside=function(e,n,r="mousedown",u){const c=t.useRef(n);t.useEffect(()=>{c.current=n},[n]),t.useEffect(()=>{if("undefined"==typeof document)return;const t=Array.isArray(e)?e:[e],n=e=>{const n=e.target;if("undefined"==typeof Node||!(n instanceof Node))return;t.some(e=>{const t=e.current;return!!t&&t.contains(n)})||c.current(e)};return document.addEventListener(r,n,u),()=>{document.removeEventListener(r,n,u)}},[r,u,e])},e.usePrevious=function(e){const n=t.useRef();return t.useEffect(()=>{n.current=e},[e]),n.current},e.useResizeObserver=function(e,r,u){const c=t.useRef(r),o=t.useRef(null),[s,i]=t.useState(null);return n(()=>{c.current=r},[r]),t.useEffect(()=>{if("undefined"==typeof ResizeObserver)return;const t="undefined"!=typeof Element&&e instanceof Element?e:(n=e)&&"object"==typeof n&&"current"in n?e.current:null;var n;if(!t)return;const r=new ResizeObserver(e=>{const t=e[0];o.current=t,c.current?c.current(t):i(t)});return r.observe(t,u),()=>r.disconnect()},[u,e]),c.current?o.current:s},e.useSessionStorage=function(e,n,r={}){const{initializeWithValue:u=!0,serialize:c=JSON.stringify,deserialize:o=JSON.parse,listenToStorageChanges:s=!1}=r,i=t.useRef(n),a=t.useCallback(()=>{if("undefined"==typeof window)return i.current;if(!u)return i.current;try{const t=window.sessionStorage.getItem(e);return t?o(t):i.current}catch{return i.current}},[o,u,e]),[l,f]=t.useState(()=>a()),d=t.useCallback(t=>{f(n=>{const r="function"==typeof t?t(n):t;if("undefined"!=typeof window)try{window.sessionStorage.setItem(e,c(r))}catch{}return r})},[e,c]);return t.useEffect(()=>{f(a())},[a]),t.useEffect(()=>{if("undefined"==typeof window||!s)return;const t=t=>{if(t.key===e)if(null!==t.newValue)try{f(o(t.newValue))}catch{f(i.current)}else f(i.current)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)},[o,e,s]),[l,d]},e.useThrottle=function(e,n,r={}){const u=r.leading??!0,c=r.trailing??!0,o=Math.max(0,n),[s,i]=t.useState(e),a=t.useRef(0),l=t.useRef(null),f=t.useRef(null);return t.useEffect(()=>{if(0===o)return void i(e);const t=Date.now();if(0===a.current)return a.current=t,u?void i(e):void(c&&!l.current&&(f.current=e,l.current=setTimeout(()=>{l.current=null,null!==f.current&&(i(f.current),f.current=null,a.current=Date.now())},o)));const n=t-a.current;if(n>=o&&u)return i(e),a.current=t,void(f.current=null);if(c&&(f.current=e,!l.current)){const e=Math.max(o-n,0);l.current=setTimeout(()=>{l.current=null,null!==f.current&&(i(f.current),f.current=null,a.current=Date.now())},e)}},[u,c,e,o]),t.useEffect(()=>()=>{l.current&&clearTimeout(l.current)},[]),s},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
2
+ //# sourceMappingURL=opensite-hooks.umd.js.map
@@ -0,0 +1,2 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).OpensiteHooks={},e.React)}(this,function(e,t){"use strict";const n="undefined"!=typeof window?t.useLayoutEffect:t.useEffect;function r(e,r,u={}){const c=t.useRef(e),o=t.useRef(null),s=t.useRef(null),i=t.useRef(null),a=u.leading??!1,l=u.trailing??!0,f=u.maxWait,d=Math.max(0,r);n(()=>{c.current=e},[e]);const p=t.useCallback(()=>{o.current&&(clearTimeout(o.current),o.current=null),s.current&&(clearTimeout(s.current),s.current=null)},[]),m=t.useCallback(()=>{if(!i.current)return;const e=i.current;i.current=null,c.current(...e)},[]),y=t.useCallback((...e)=>{i.current=e;if(a&&null===o.current&&null===s.current&&m(),o.current&&clearTimeout(o.current),l&&(o.current=setTimeout(()=>{o.current=null,i.current&&m(),s.current&&(clearTimeout(s.current),s.current=null)},d)),null!=f&&l&&!s.current){const e=Math.max(0,f);s.current=setTimeout(()=>{s.current=null,o.current&&(clearTimeout(o.current),o.current=null),i.current&&m()},e)}},[m,a,l,f,d]),w=t.useCallback(()=>{p(),i.current=null},[p]),v=t.useCallback(()=>{i.current&&(p(),m())},[p,m]);return t.useEffect(()=>()=>w(),[w]),{debouncedCallback:y,cancel:w,flush:v}}function u(e,r,u,c){const o=t.useRef(r);n(()=>{o.current=r},[r]),t.useEffect(()=>{const t="undefined"!=typeof Window&&u instanceof Window,n="undefined"!=typeof Document&&u instanceof Document,r=void 0===u?"undefined"!=typeof window?window:null:t||n||"undefined"!=typeof HTMLElement&&u instanceof HTMLElement?u:(s=u)&&"object"==typeof s&&"current"in s?u.current:null;var s;if(!(null==r?void 0:r.addEventListener))return;const i=e=>{const t=o.current;"function"==typeof t?t(e):t.handleEvent(e)};return r.addEventListener(e,i,c),()=>{r.removeEventListener(e,i,c)}},[e,u,c])}e.useBoolean=function(e=!1){const[n,r]=t.useState(e),u=t.useCallback(()=>r(!0),[]),c=t.useCallback(()=>r(!1),[]),o=t.useCallback(()=>r(e=>!e),[]);return{value:n,setValue:r,setTrue:u,setFalse:c,toggle:o}},e.useCopyToClipboard=function(e={}){const n=e.resetDelay??2e3,r=t.useRef(null),[u,c]=t.useState(null),o=t.useMemo(()=>!("undefined"==typeof navigator||!navigator.clipboard)||"undefined"!=typeof document&&("function"==typeof document.queryCommandSupported&&document.queryCommandSupported("copy")),[]),s=t.useCallback(()=>{r.current&&clearTimeout(r.current),r.current=setTimeout(()=>{c(null)},n)},[n]),i=t.useCallback(async e=>{if(!o)return!1;const t="undefined"!=typeof navigator&&!!navigator.clipboard;try{if(t)await navigator.clipboard.writeText(e);else if("undefined"!=typeof document){const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="fixed",t.style.left="-9999px",t.style.top="0",document.body.appendChild(t),t.focus(),t.select();const n=document.execCommand("copy");if(document.body.removeChild(t),!n)return!1}return c(e),s(),!0}catch{return!1}},[o,s]);return t.useEffect(()=>()=>{r.current&&clearTimeout(r.current)},[]),{copy:i,copiedText:u,isSupported:o}},e.useDebounceCallback=r,e.useDebounceValue=function(e,n,u){const[c,o]=t.useState(e),{debouncedCallback:s,cancel:i}=r(e=>{o(e)},n,u);return t.useEffect(()=>{s(e)},[s,e]),t.useEffect(()=>()=>i(),[i]),c},e.useEventListener=u,e.useHover=function(e){const[n,r]=t.useState(!1),c=t.useCallback(()=>{r(!0)},[]),o=t.useCallback(()=>{r(!1)},[]);return u("pointerenter",c,e),u("pointerleave",o,e),n},e.useIsClient=function(){const[e,n]=t.useState(!1);return t.useEffect(()=>{n(!0)},[]),e},e.useIsomorphicLayoutEffect=n,e.useLocalStorage=function(e,n,r={}){const{initializeWithValue:u=!0,serialize:c=JSON.stringify,deserialize:o=JSON.parse,listenToStorageChanges:s=!0}=r,i=t.useRef(n),a=t.useCallback(()=>{if("undefined"==typeof window)return i.current;if(!u)return i.current;try{const t=window.localStorage.getItem(e);return t?o(t):i.current}catch{return i.current}},[o,u,e]),[l,f]=t.useState(()=>a()),d=t.useCallback(t=>{f(n=>{const r="function"==typeof t?t(n):t;if("undefined"!=typeof window)try{window.localStorage.setItem(e,c(r))}catch{}return r})},[e,c]);return t.useEffect(()=>{f(a())},[a]),t.useEffect(()=>{if("undefined"==typeof window||!s)return;const t=t=>{if(t.key===e)if(null!==t.newValue)try{f(o(t.newValue))}catch{f(i.current)}else f(i.current)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)},[o,e,s]),[l,d]},e.useMap=function(e){const[n,r]=t.useState(()=>e instanceof Map||Array.isArray(e)?new Map(e):new Map),u=t.useRef(n);t.useEffect(()=>{u.current=n},[n]);const c=t.useMemo(()=>({set:(e,t)=>{r(n=>{const r=new Map(n);return r.set(e,t),r})},setAll:e=>{r((Map,new Map(e)))},remove:e=>{r(t=>{const n=new Map(t);return n.delete(e),n})},clear:()=>r(new Map),get:e=>u.current.get(e),has:e=>u.current.has(e)}),[]);return[n,c]},e.useMediaQuery=function(e,n={}){const[r,u]=t.useState(()=>"undefined"==typeof window||"function"!=typeof window.matchMedia?n.defaultValue??!1:window.matchMedia(e).matches);return t.useEffect(()=>{if("undefined"==typeof window||"function"!=typeof window.matchMedia)return;const t=window.matchMedia(e),n=e=>{u(e.matches)};return u(t.matches),t.addEventListener?(t.addEventListener("change",n),()=>t.removeEventListener("change",n)):(t.addListener(n),()=>t.removeListener(n))},[e]),r},e.useOnClickOutside=function(e,n,r="mousedown",u){const c=t.useRef(n);t.useEffect(()=>{c.current=n},[n]),t.useEffect(()=>{if("undefined"==typeof document)return;const t=Array.isArray(e)?e:[e],n=e=>{const n=e.target;if("undefined"==typeof Node||!(n instanceof Node))return;t.some(e=>{const t=e.current;return!!t&&t.contains(n)})||c.current(e)};return document.addEventListener(r,n,u),()=>{document.removeEventListener(r,n,u)}},[r,u,e])},e.usePrevious=function(e){const n=t.useRef();return t.useEffect(()=>{n.current=e},[e]),n.current},e.useResizeObserver=function(e,r,u){const c=t.useRef(r),o=t.useRef(null),[s,i]=t.useState(null);return n(()=>{c.current=r},[r]),t.useEffect(()=>{if("undefined"==typeof ResizeObserver)return;const t="undefined"!=typeof Element&&e instanceof Element?e:(n=e)&&"object"==typeof n&&"current"in n?e.current:null;var n;if(!t)return;const r=new ResizeObserver(e=>{const t=e[0];o.current=t,c.current?c.current(t):i(t)});return r.observe(t,u),()=>r.disconnect()},[u,e]),c.current?o.current:s},e.useSessionStorage=function(e,n,r={}){const{initializeWithValue:u=!0,serialize:c=JSON.stringify,deserialize:o=JSON.parse,listenToStorageChanges:s=!1}=r,i=t.useRef(n),a=t.useCallback(()=>{if("undefined"==typeof window)return i.current;if(!u)return i.current;try{const t=window.sessionStorage.getItem(e);return t?o(t):i.current}catch{return i.current}},[o,u,e]),[l,f]=t.useState(()=>a()),d=t.useCallback(t=>{f(n=>{const r="function"==typeof t?t(n):t;if("undefined"!=typeof window)try{window.sessionStorage.setItem(e,c(r))}catch{}return r})},[e,c]);return t.useEffect(()=>{f(a())},[a]),t.useEffect(()=>{if("undefined"==typeof window||!s)return;const t=t=>{if(t.key===e)if(null!==t.newValue)try{f(o(t.newValue))}catch{f(i.current)}else f(i.current)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)},[o,e,s]),[l,d]},e.useThrottle=function(e,n,r={}){const u=r.leading??!0,c=r.trailing??!0,o=Math.max(0,n),[s,i]=t.useState(e),a=t.useRef(0),l=t.useRef(null),f=t.useRef(null);return t.useEffect(()=>{if(0===o)return void i(e);const t=Date.now();if(0===a.current)return a.current=t,u?void i(e):void(c&&!l.current&&(f.current=e,l.current=setTimeout(()=>{l.current=null,null!==f.current&&(i(f.current),f.current=null,a.current=Date.now())},o)));const n=t-a.current;if(n>=o&&u)return i(e),a.current=t,void(f.current=null);if(c&&(f.current=e,!l.current)){const e=Math.max(o-n,0);l.current=setTimeout(()=>{l.current=null,null!==f.current&&(i(f.current),f.current=null,a.current=Date.now())},e)}},[u,c,e,o]),t.useEffect(()=>()=>{l.current&&clearTimeout(l.current)},[]),s},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
2
+ //# sourceMappingURL=opensite-hooks.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opensite-hooks.umd.js","sources":["../../src/core/useIsomorphicLayoutEffect.ts","../../src/core/useDebounceCallback.ts","../../src/core/useEventListener.ts","../../src/core/useBoolean.ts","../../src/core/useCopyToClipboard.ts","../../src/core/useDebounceValue.ts","../../src/core/useHover.ts","../../src/core/useIsClient.ts","../../src/core/useLocalStorage.ts","../../src/core/useMap.ts","../../src/core/useMediaQuery.ts","../../src/core/useOnClickOutside.ts","../../src/core/usePrevious.ts","../../src/core/useResizeObserver.ts","../../src/core/useSessionStorage.ts","../../src/core/useThrottle.ts"],"sourcesContent":["import { useEffect, useLayoutEffect } from \"react\";\n\nexport const useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n","import { useCallback, useEffect, useRef } from \"react\";\nimport { useIsomorphicLayoutEffect } from \"./useIsomorphicLayoutEffect.js\";\n\nexport interface DebounceOptions {\n leading?: boolean;\n trailing?: boolean;\n maxWait?: number;\n}\n\nexport interface DebouncedCallback<T extends (...args: any[]) => void> {\n debouncedCallback: (...args: Parameters<T>) => void;\n cancel: () => void;\n flush: () => void;\n}\n\nexport function useDebounceCallback<T extends (...args: any[]) => void>(\n callback: T,\n delay: number,\n options: DebounceOptions = {}\n): DebouncedCallback<T> {\n const callbackRef = useRef(callback);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const maxTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const lastArgsRef = useRef<Parameters<T> | null>(null);\n\n const leading = options.leading ?? false;\n const trailing = options.trailing ?? true;\n const maxWait = options.maxWait;\n const wait = Math.max(0, delay);\n\n useIsomorphicLayoutEffect(() => {\n callbackRef.current = callback;\n }, [callback]);\n\n const clearTimers = useCallback(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n if (maxTimeoutRef.current) {\n clearTimeout(maxTimeoutRef.current);\n maxTimeoutRef.current = null;\n }\n }, []);\n\n const invoke = useCallback(() => {\n if (!lastArgsRef.current) {\n return;\n }\n const args = lastArgsRef.current;\n lastArgsRef.current = null;\n callbackRef.current(...args);\n }, []);\n\n const debouncedCallback = useCallback(\n (...args: Parameters<T>) => {\n lastArgsRef.current = args;\n\n const shouldInvokeLeading =\n leading && timeoutRef.current === null && maxTimeoutRef.current === null;\n if (shouldInvokeLeading) {\n invoke();\n }\n\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n\n if (trailing) {\n timeoutRef.current = setTimeout(() => {\n timeoutRef.current = null;\n if (lastArgsRef.current) {\n invoke();\n }\n if (maxTimeoutRef.current) {\n clearTimeout(maxTimeoutRef.current);\n maxTimeoutRef.current = null;\n }\n }, wait);\n }\n\n if (maxWait !== undefined && maxWait !== null && trailing) {\n if (!maxTimeoutRef.current) {\n const maxDelay = Math.max(0, maxWait);\n maxTimeoutRef.current = setTimeout(() => {\n maxTimeoutRef.current = null;\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n if (lastArgsRef.current) {\n invoke();\n }\n }, maxDelay);\n }\n }\n },\n [invoke, leading, trailing, maxWait, wait]\n );\n\n const cancel = useCallback(() => {\n clearTimers();\n lastArgsRef.current = null;\n }, [clearTimers]);\n\n const flush = useCallback(() => {\n if (!lastArgsRef.current) {\n return;\n }\n clearTimers();\n invoke();\n }, [clearTimers, invoke]);\n\n useEffect(() => () => cancel(), [cancel]);\n\n return { debouncedCallback, cancel, flush };\n}\n","import { useEffect, useRef } from \"react\";\nimport { useIsomorphicLayoutEffect } from \"./useIsomorphicLayoutEffect.js\";\n\ntype EventTargetLike = Window | Document | HTMLElement | null;\ntype ElementRef = React.RefObject<HTMLElement>;\n\nconst isRefObject = (value: unknown): value is ElementRef =>\n !!value && typeof value === \"object\" && \"current\" in value;\n\nexport function useEventListener<K extends keyof WindowEventMap>(\n eventName: K,\n handler: (event: WindowEventMap[K]) => void,\n element?: Window,\n options?: AddEventListenerOptions | boolean\n): void;\nexport function useEventListener<K extends keyof DocumentEventMap>(\n eventName: K,\n handler: (event: DocumentEventMap[K]) => void,\n element: Document,\n options?: AddEventListenerOptions | boolean\n): void;\nexport function useEventListener<K extends keyof HTMLElementEventMap>(\n eventName: K,\n handler: (event: HTMLElementEventMap[K]) => void,\n element: ElementRef,\n options?: AddEventListenerOptions | boolean\n): void;\nexport function useEventListener<K extends keyof HTMLElementEventMap>(\n eventName: K,\n handler: (event: HTMLElementEventMap[K]) => void,\n element: HTMLElement,\n options?: AddEventListenerOptions | boolean\n): void;\nexport function useEventListener(\n eventName: string,\n handler: EventListenerOrEventListenerObject,\n element?: EventTargetLike | ElementRef,\n options?: AddEventListenerOptions | boolean\n): void {\n const savedHandler = useRef(handler);\n\n useIsomorphicLayoutEffect(() => {\n savedHandler.current = handler;\n }, [handler]);\n\n useEffect(() => {\n const isWindow =\n typeof Window !== \"undefined\" && element instanceof Window;\n const isDocument =\n typeof Document !== \"undefined\" && element instanceof Document;\n\n const target: EventTargetLike | null =\n element === undefined\n ? typeof window !== \"undefined\"\n ? window\n : null\n : isWindow || isDocument\n ? element\n : typeof HTMLElement !== \"undefined\" && element instanceof HTMLElement\n ? element\n : isRefObject(element)\n ? element.current\n : null;\n\n if (!target?.addEventListener) {\n return;\n }\n\n const listener = (event: Event) => {\n const currentHandler = savedHandler.current;\n if (typeof currentHandler === \"function\") {\n currentHandler(event);\n } else {\n currentHandler.handleEvent(event);\n }\n };\n\n target.addEventListener(eventName, listener, options);\n\n return () => {\n target.removeEventListener(eventName, listener, options);\n };\n }, [eventName, element, options]);\n}\n","import { useCallback, useState } from \"react\";\n\nexport interface UseBooleanResult {\n value: boolean;\n setValue: React.Dispatch<React.SetStateAction<boolean>>;\n setTrue: () => void;\n setFalse: () => void;\n toggle: () => void;\n}\n\nexport function useBoolean(defaultValue = false): UseBooleanResult {\n const [value, setValue] = useState<boolean>(defaultValue);\n\n const setTrue = useCallback(() => setValue(true), []);\n const setFalse = useCallback(() => setValue(false), []);\n const toggle = useCallback(() => setValue((current) => !current), []);\n\n return { value, setValue, setTrue, setFalse, toggle };\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nexport interface UseCopyToClipboardOptions {\n resetDelay?: number;\n}\n\nexport interface CopyToClipboardResult {\n copy: (text: string) => Promise<boolean>;\n copiedText: string | null;\n isSupported: boolean;\n}\n\nexport function useCopyToClipboard(\n options: UseCopyToClipboardOptions = {}\n): CopyToClipboardResult {\n const resetDelay = options.resetDelay ?? 2000;\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [copiedText, setCopiedText] = useState<string | null>(null);\n\n const isSupported = useMemo(() => {\n if (typeof navigator !== \"undefined\" && navigator.clipboard) {\n return true;\n }\n if (typeof document === \"undefined\") {\n return false;\n }\n if (typeof document.queryCommandSupported !== \"function\") {\n return false;\n }\n return document.queryCommandSupported(\"copy\");\n }, []);\n\n const resetCopied = useCallback(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = setTimeout(() => {\n setCopiedText(null);\n }, resetDelay);\n }, [resetDelay]);\n\n const copy = useCallback(\n async (text: string) => {\n if (!isSupported) {\n return false;\n }\n\n const shouldUseClipboardApi =\n typeof navigator !== \"undefined\" && !!navigator.clipboard;\n\n try {\n if (shouldUseClipboardApi) {\n await navigator.clipboard.writeText(text);\n } else if (typeof document !== \"undefined\") {\n const textarea = document.createElement(\"textarea\");\n textarea.value = text;\n textarea.setAttribute(\"readonly\", \"\");\n textarea.style.position = \"fixed\";\n textarea.style.left = \"-9999px\";\n textarea.style.top = \"0\";\n document.body.appendChild(textarea);\n textarea.focus();\n textarea.select();\n const success = document.execCommand(\"copy\");\n document.body.removeChild(textarea);\n if (!success) {\n return false;\n }\n }\n\n setCopiedText(text);\n resetCopied();\n return true;\n } catch {\n return false;\n }\n },\n [isSupported, resetCopied]\n );\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n return { copy, copiedText, isSupported };\n}\n","import { useEffect, useState } from \"react\";\nimport { DebounceOptions, useDebounceCallback } from \"./useDebounceCallback.js\";\n\nexport function useDebounceValue<T>(\n value: T,\n delay: number,\n options?: DebounceOptions\n): T {\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n const { debouncedCallback, cancel } = useDebounceCallback(\n (next: T) => {\n setDebouncedValue(next);\n },\n delay,\n options\n );\n\n useEffect(() => {\n debouncedCallback(value);\n }, [debouncedCallback, value]);\n\n useEffect(() => () => cancel(), [cancel]);\n\n return debouncedValue;\n}\n","import { useCallback, useState } from \"react\";\nimport { useEventListener } from \"./useEventListener.js\";\n\nexport function useHover<T extends HTMLElement>(\n ref: React.RefObject<T>\n): boolean {\n const [isHovered, setIsHovered] = useState(false);\n\n const handleEnter = useCallback(() => {\n setIsHovered(true);\n }, []);\n\n const handleLeave = useCallback(() => {\n setIsHovered(false);\n }, []);\n\n useEventListener(\"pointerenter\", handleEnter, ref);\n useEventListener(\"pointerleave\", handleLeave, ref);\n\n return isHovered;\n}\n","import { useEffect, useState } from \"react\";\n\nexport function useIsClient(): boolean {\n const [isClient, setIsClient] = useState(false);\n\n useEffect(() => {\n setIsClient(true);\n }, []);\n\n return isClient;\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface StorageOptions<T> {\n initializeWithValue?: boolean;\n serialize?: (value: T) => string;\n deserialize?: (value: string) => T;\n listenToStorageChanges?: boolean;\n}\n\ntype StoredSetter<T> = (value: T | ((current: T) => T)) => void;\n\nexport function useLocalStorage<T>(\n key: string,\n initialValue: T,\n options: StorageOptions<T> = {}\n): [T, StoredSetter<T>] {\n const {\n initializeWithValue = true,\n serialize = JSON.stringify,\n deserialize = JSON.parse as (value: string) => T,\n listenToStorageChanges = true,\n } = options;\n\n const initialValueRef = useRef(initialValue);\n\n const readValue = useCallback(() => {\n if (typeof window === \"undefined\") {\n return initialValueRef.current;\n }\n if (!initializeWithValue) {\n return initialValueRef.current;\n }\n try {\n const item = window.localStorage.getItem(key);\n return item ? deserialize(item) : initialValueRef.current;\n } catch {\n return initialValueRef.current;\n }\n }, [deserialize, initializeWithValue, key]);\n\n const [storedValue, setStoredValue] = useState<T>(() => readValue());\n\n const setValue: StoredSetter<T> = useCallback(\n (value) => {\n setStoredValue((current) => {\n const valueToStore =\n typeof value === \"function\"\n ? (value as (current: T) => T)(current)\n : value;\n if (typeof window !== \"undefined\") {\n try {\n window.localStorage.setItem(key, serialize(valueToStore));\n } catch {\n // Ignore write errors (quota/security)\n }\n }\n return valueToStore;\n });\n },\n [key, serialize]\n );\n\n useEffect(() => {\n setStoredValue(readValue());\n }, [readValue]);\n\n useEffect(() => {\n if (typeof window === \"undefined\" || !listenToStorageChanges) {\n return;\n }\n\n const handleStorageChange = (event: StorageEvent) => {\n if (event.key !== key) {\n return;\n }\n if (event.newValue === null) {\n setStoredValue(initialValueRef.current);\n return;\n }\n try {\n setStoredValue(deserialize(event.newValue));\n } catch {\n setStoredValue(initialValueRef.current);\n }\n };\n\n window.addEventListener(\"storage\", handleStorageChange);\n return () => window.removeEventListener(\"storage\", handleStorageChange);\n }, [deserialize, key, listenToStorageChanges]);\n\n return [storedValue, setValue];\n}\n","import { useEffect, useMemo, useRef, useState } from \"react\";\n\nexport interface MapActions<K, V> {\n set: (key: K, value: V) => void;\n setAll: (entries: Map<K, V> | [K, V][]) => void;\n remove: (key: K) => void;\n clear: () => void;\n get: (key: K) => V | undefined;\n has: (key: K) => boolean;\n}\n\nexport function useMap<K, V>(\n initialState?: Map<K, V> | [K, V][]\n): [Map<K, V>, MapActions<K, V>] {\n const [map, setMap] = useState<Map<K, V>>(() => {\n if (initialState instanceof Map) {\n return new Map(initialState);\n }\n if (Array.isArray(initialState)) {\n return new Map(initialState);\n }\n return new Map();\n });\n\n const mapRef = useRef(map);\n\n useEffect(() => {\n mapRef.current = map;\n }, [map]);\n\n const actions = useMemo<MapActions<K, V>>(\n () => ({\n set: (key: K, value: V) => {\n setMap((prev) => {\n const next = new Map(prev);\n next.set(key, value);\n return next;\n });\n },\n setAll: (entries: Map<K, V> | [K, V][]) => {\n setMap(entries instanceof Map ? new Map(entries) : new Map(entries));\n },\n remove: (key: K) => {\n setMap((prev) => {\n const next = new Map(prev);\n next.delete(key);\n return next;\n });\n },\n clear: () => setMap(new Map()),\n get: (key: K) => mapRef.current.get(key),\n has: (key: K) => mapRef.current.has(key),\n }),\n []\n );\n\n return [map, actions];\n}\n","import { useEffect, useState } from \"react\";\n\nexport interface UseMediaQueryOptions {\n defaultValue?: boolean;\n}\n\nexport function useMediaQuery(\n query: string,\n options: UseMediaQueryOptions = {}\n): boolean {\n const [matches, setMatches] = useState<boolean>(() => {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return options.defaultValue ?? false;\n }\n return window.matchMedia(query).matches;\n });\n\n useEffect(() => {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return;\n }\n\n const mediaQueryList = window.matchMedia(query);\n const handler = (event: MediaQueryListEvent) => {\n setMatches(event.matches);\n };\n\n setMatches(mediaQueryList.matches);\n\n if (mediaQueryList.addEventListener) {\n mediaQueryList.addEventListener(\"change\", handler);\n return () => mediaQueryList.removeEventListener(\"change\", handler);\n }\n\n mediaQueryList.addListener(handler);\n return () => mediaQueryList.removeListener(handler);\n }, [query]);\n\n return matches;\n}\n","import { useEffect, useRef } from \"react\";\n\ntype PossibleRef<T extends HTMLElement> = React.RefObject<T>;\n\nexport function useOnClickOutside<T extends HTMLElement>(\n ref: PossibleRef<T> | Array<PossibleRef<T>>,\n handler: (event: MouseEvent | TouchEvent | PointerEvent) => void,\n eventType: \"mousedown\" | \"mouseup\" | \"click\" | \"touchstart\" | \"pointerdown\" =\n \"mousedown\",\n options?: AddEventListenerOptions | boolean\n): void {\n const handlerRef = useRef(handler);\n\n useEffect(() => {\n handlerRef.current = handler;\n }, [handler]);\n\n useEffect(() => {\n if (typeof document === \"undefined\") {\n return;\n }\n\n const refs = Array.isArray(ref) ? ref : [ref];\n const listener = (event: MouseEvent | TouchEvent | PointerEvent) => {\n const target = event.target;\n if (typeof Node === \"undefined\" || !(target instanceof Node)) {\n return;\n }\n\n const clickedInside = refs.some((currentRef) => {\n const node = currentRef.current;\n return node ? node.contains(target) : false;\n });\n\n if (!clickedInside) {\n handlerRef.current(event);\n }\n };\n\n document.addEventListener(eventType, listener, options);\n return () => {\n document.removeEventListener(eventType, listener, options);\n };\n }, [eventType, options, ref]);\n}\n","import { useEffect, useRef } from \"react\";\n\nexport function usePrevious<T>(value: T): T | undefined {\n const ref = useRef<T>();\n\n useEffect(() => {\n ref.current = value;\n }, [value]);\n\n return ref.current;\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { useIsomorphicLayoutEffect } from \"./useIsomorphicLayoutEffect.js\";\n\ntype TargetElement<T extends Element> = React.RefObject<T> | T | null;\n\nconst isRefObject = <T extends Element>(\n value: unknown\n): value is React.RefObject<T> => !!value && typeof value === \"object\" && \"current\" in value;\n\nexport function useResizeObserver<T extends Element>(\n target: TargetElement<T>,\n onResize?: (entry: ResizeObserverEntry) => void,\n options?: ResizeObserverOptions\n): ResizeObserverEntry | null {\n const callbackRef = useRef(onResize);\n const entryRef = useRef<ResizeObserverEntry | null>(null);\n const [entry, setEntry] = useState<ResizeObserverEntry | null>(null);\n\n useIsomorphicLayoutEffect(() => {\n callbackRef.current = onResize;\n }, [onResize]);\n\n useEffect(() => {\n if (typeof ResizeObserver === \"undefined\") {\n return;\n }\n\n const element =\n typeof Element !== \"undefined\" && target instanceof Element\n ? target\n : isRefObject<T>(target)\n ? target.current\n : null;\n if (!element) {\n return;\n }\n\n const observer = new ResizeObserver((entries) => {\n const firstEntry = entries[0];\n entryRef.current = firstEntry;\n if (callbackRef.current) {\n callbackRef.current(firstEntry);\n } else {\n setEntry(firstEntry);\n }\n });\n\n observer.observe(element, options);\n return () => observer.disconnect();\n }, [options, target]);\n\n return callbackRef.current ? entryRef.current : entry;\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface SessionStorageOptions<T> {\n initializeWithValue?: boolean;\n serialize?: (value: T) => string;\n deserialize?: (value: string) => T;\n listenToStorageChanges?: boolean;\n}\n\ntype StoredSetter<T> = (value: T | ((current: T) => T)) => void;\n\nexport function useSessionStorage<T>(\n key: string,\n initialValue: T,\n options: SessionStorageOptions<T> = {}\n): [T, StoredSetter<T>] {\n const {\n initializeWithValue = true,\n serialize = JSON.stringify,\n deserialize = JSON.parse as (value: string) => T,\n listenToStorageChanges = false,\n } = options;\n\n const initialValueRef = useRef(initialValue);\n\n const readValue = useCallback(() => {\n if (typeof window === \"undefined\") {\n return initialValueRef.current;\n }\n if (!initializeWithValue) {\n return initialValueRef.current;\n }\n try {\n const item = window.sessionStorage.getItem(key);\n return item ? deserialize(item) : initialValueRef.current;\n } catch {\n return initialValueRef.current;\n }\n }, [deserialize, initializeWithValue, key]);\n\n const [storedValue, setStoredValue] = useState<T>(() => readValue());\n\n const setValue: StoredSetter<T> = useCallback(\n (value) => {\n setStoredValue((current) => {\n const valueToStore =\n typeof value === \"function\"\n ? (value as (current: T) => T)(current)\n : value;\n if (typeof window !== \"undefined\") {\n try {\n window.sessionStorage.setItem(key, serialize(valueToStore));\n } catch {\n // Ignore write errors (quota/security)\n }\n }\n return valueToStore;\n });\n },\n [key, serialize]\n );\n\n useEffect(() => {\n setStoredValue(readValue());\n }, [readValue]);\n\n useEffect(() => {\n if (typeof window === \"undefined\" || !listenToStorageChanges) {\n return;\n }\n\n const handleStorageChange = (event: StorageEvent) => {\n if (event.key !== key) {\n return;\n }\n if (event.newValue === null) {\n setStoredValue(initialValueRef.current);\n return;\n }\n try {\n setStoredValue(deserialize(event.newValue));\n } catch {\n setStoredValue(initialValueRef.current);\n }\n };\n\n window.addEventListener(\"storage\", handleStorageChange);\n return () => window.removeEventListener(\"storage\", handleStorageChange);\n }, [deserialize, key, listenToStorageChanges]);\n\n return [storedValue, setValue];\n}\n","import { useEffect, useRef, useState } from \"react\";\n\nexport interface ThrottleOptions {\n leading?: boolean;\n trailing?: boolean;\n}\n\nexport function useThrottle<T>(\n value: T,\n interval: number,\n options: ThrottleOptions = {}\n): T {\n const leading = options.leading ?? true;\n const trailing = options.trailing ?? true;\n const wait = Math.max(0, interval);\n\n const [throttledValue, setThrottledValue] = useState<T>(value);\n const lastExecutedRef = useRef<number>(0);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const pendingValueRef = useRef<T | null>(null);\n\n useEffect(() => {\n if (wait === 0) {\n setThrottledValue(value);\n return;\n }\n\n const now = Date.now();\n\n if (lastExecutedRef.current === 0) {\n lastExecutedRef.current = now;\n if (leading) {\n setThrottledValue(value);\n return;\n }\n if (trailing && !timeoutRef.current) {\n pendingValueRef.current = value;\n timeoutRef.current = setTimeout(() => {\n timeoutRef.current = null;\n if (pendingValueRef.current !== null) {\n setThrottledValue(pendingValueRef.current);\n pendingValueRef.current = null;\n lastExecutedRef.current = Date.now();\n }\n }, wait);\n }\n return;\n }\n\n const elapsed = now - lastExecutedRef.current;\n\n if (elapsed >= wait && leading) {\n setThrottledValue(value);\n lastExecutedRef.current = now;\n pendingValueRef.current = null;\n return;\n }\n\n if (trailing) {\n pendingValueRef.current = value;\n if (!timeoutRef.current) {\n const remaining = Math.max(wait - elapsed, 0);\n timeoutRef.current = setTimeout(() => {\n timeoutRef.current = null;\n if (pendingValueRef.current !== null) {\n setThrottledValue(pendingValueRef.current);\n pendingValueRef.current = null;\n lastExecutedRef.current = Date.now();\n }\n }, remaining);\n }\n }\n }, [leading, trailing, value, wait]);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n return throttledValue;\n}\n"],"names":["useIsomorphicLayoutEffect","window","useLayoutEffect","useEffect","useDebounceCallback","callback","delay","options","callbackRef","useRef","timeoutRef","maxTimeoutRef","lastArgsRef","leading","trailing","maxWait","wait","Math","max","current","clearTimers","useCallback","clearTimeout","invoke","args","debouncedCallback","setTimeout","maxDelay","cancel","flush","useEventListener","eventName","handler","element","savedHandler","isWindow","Window","isDocument","Document","target","HTMLElement","value","addEventListener","listener","event","currentHandler","handleEvent","removeEventListener","defaultValue","setValue","useState","setTrue","setFalse","toggle","resetDelay","copiedText","setCopiedText","isSupported","useMemo","navigator","clipboard","document","queryCommandSupported","resetCopied","copy","async","text","shouldUseClipboardApi","writeText","textarea","createElement","setAttribute","style","position","left","top","body","appendChild","focus","select","success","execCommand","removeChild","debouncedValue","setDebouncedValue","next","ref","isHovered","setIsHovered","handleEnter","handleLeave","isClient","setIsClient","key","initialValue","initializeWithValue","serialize","JSON","stringify","deserialize","parse","listenToStorageChanges","initialValueRef","readValue","item","localStorage","getItem","storedValue","setStoredValue","valueToStore","setItem","handleStorageChange","newValue","initialState","map","setMap","Map","Array","isArray","mapRef","actions","set","prev","setAll","entries","remove","delete","clear","get","has","query","matches","setMatches","matchMedia","mediaQueryList","addListener","removeListener","eventType","handlerRef","refs","Node","some","currentRef","node","contains","onResize","entryRef","entry","setEntry","ResizeObserver","Element","observer","firstEntry","observe","disconnect","sessionStorage","interval","throttledValue","setThrottledValue","lastExecutedRef","pendingValueRef","now","Date","elapsed","remaining"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export { useBoolean } from "./useBoolean.js";
2
+ export { useDebounceCallback } from "./useDebounceCallback.js";
3
+ export { useDebounceValue } from "./useDebounceValue.js";
4
+ export { useLocalStorage } from "./useLocalStorage.js";
5
+ export { useSessionStorage } from "./useSessionStorage.js";
6
+ export { useOnClickOutside } from "./useOnClickOutside.js";
7
+ export { useMediaQuery } from "./useMediaQuery.js";
8
+ export { useEventListener } from "./useEventListener.js";
9
+ export { useIsClient } from "./useIsClient.js";
10
+ export { useCopyToClipboard } from "./useCopyToClipboard.js";
11
+ export { usePrevious } from "./usePrevious.js";
12
+ export { useThrottle } from "./useThrottle.js";
13
+ export { useResizeObserver } from "./useResizeObserver.js";
14
+ export { useHover } from "./useHover.js";
15
+ export { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect.js";
16
+ export { useMap } from "./useMap.js";
@@ -0,0 +1,24 @@
1
+ export { useBoolean } from "./useBoolean.js";
2
+ export type { UseBooleanResult } from "./useBoolean.js";
3
+ export { useDebounceCallback } from "./useDebounceCallback.js";
4
+ export type { DebounceOptions, DebouncedCallback } from "./useDebounceCallback.js";
5
+ export { useDebounceValue } from "./useDebounceValue.js";
6
+ export { useLocalStorage } from "./useLocalStorage.js";
7
+ export type { StorageOptions } from "./useLocalStorage.js";
8
+ export { useSessionStorage } from "./useSessionStorage.js";
9
+ export type { SessionStorageOptions } from "./useSessionStorage.js";
10
+ export { useOnClickOutside } from "./useOnClickOutside.js";
11
+ export { useMediaQuery } from "./useMediaQuery.js";
12
+ export type { UseMediaQueryOptions } from "./useMediaQuery.js";
13
+ export { useEventListener } from "./useEventListener.js";
14
+ export { useIsClient } from "./useIsClient.js";
15
+ export { useCopyToClipboard } from "./useCopyToClipboard.js";
16
+ export type { UseCopyToClipboardOptions, CopyToClipboardResult, } from "./useCopyToClipboard.js";
17
+ export { usePrevious } from "./usePrevious.js";
18
+ export { useThrottle } from "./useThrottle.js";
19
+ export type { ThrottleOptions } from "./useThrottle.js";
20
+ export { useResizeObserver } from "./useResizeObserver.js";
21
+ export { useHover } from "./useHover.js";
22
+ export { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect.js";
23
+ export { useMap } from "./useMap.js";
24
+ export type { MapActions } from "./useMap.js";
@@ -0,0 +1,16 @@
1
+ export { useBoolean } from "./useBoolean.js";
2
+ export { useDebounceCallback } from "./useDebounceCallback.js";
3
+ export { useDebounceValue } from "./useDebounceValue.js";
4
+ export { useLocalStorage } from "./useLocalStorage.js";
5
+ export { useSessionStorage } from "./useSessionStorage.js";
6
+ export { useOnClickOutside } from "./useOnClickOutside.js";
7
+ export { useMediaQuery } from "./useMediaQuery.js";
8
+ export { useEventListener } from "./useEventListener.js";
9
+ export { useIsClient } from "./useIsClient.js";
10
+ export { useCopyToClipboard } from "./useCopyToClipboard.js";
11
+ export { usePrevious } from "./usePrevious.js";
12
+ export { useThrottle } from "./useThrottle.js";
13
+ export { useResizeObserver } from "./useResizeObserver.js";
14
+ export { useHover } from "./useHover.js";
15
+ export { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect.js";
16
+ export { useMap } from "./useMap.js";
@@ -0,0 +1,8 @@
1
+ import { useCallback, useState } from "react";
2
+ export function useBoolean(defaultValue = false) {
3
+ const [value, setValue] = useState(defaultValue);
4
+ const setTrue = useCallback(() => setValue(true), []);
5
+ const setFalse = useCallback(() => setValue(false), []);
6
+ const toggle = useCallback(() => setValue((current) => !current), []);
7
+ return { value, setValue, setTrue, setFalse, toggle };
8
+ }
@@ -0,0 +1,8 @@
1
+ export interface UseBooleanResult {
2
+ value: boolean;
3
+ setValue: React.Dispatch<React.SetStateAction<boolean>>;
4
+ setTrue: () => void;
5
+ setFalse: () => void;
6
+ toggle: () => void;
7
+ }
8
+ export declare function useBoolean(defaultValue?: boolean): UseBooleanResult;
@@ -0,0 +1,8 @@
1
+ import { useCallback, useState } from "react";
2
+ export function useBoolean(defaultValue = false) {
3
+ const [value, setValue] = useState(defaultValue);
4
+ const setTrue = useCallback(() => setValue(true), []);
5
+ const setFalse = useCallback(() => setValue(false), []);
6
+ const toggle = useCallback(() => setValue((current) => !current), []);
7
+ return { value, setValue, setTrue, setFalse, toggle };
8
+ }
@@ -0,0 +1,67 @@
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ export function useCopyToClipboard(options = {}) {
3
+ const resetDelay = options.resetDelay ?? 2000;
4
+ const timeoutRef = useRef(null);
5
+ const [copiedText, setCopiedText] = useState(null);
6
+ const isSupported = useMemo(() => {
7
+ if (typeof navigator !== "undefined" && navigator.clipboard) {
8
+ return true;
9
+ }
10
+ if (typeof document === "undefined") {
11
+ return false;
12
+ }
13
+ if (typeof document.queryCommandSupported !== "function") {
14
+ return false;
15
+ }
16
+ return document.queryCommandSupported("copy");
17
+ }, []);
18
+ const resetCopied = useCallback(() => {
19
+ if (timeoutRef.current) {
20
+ clearTimeout(timeoutRef.current);
21
+ }
22
+ timeoutRef.current = setTimeout(() => {
23
+ setCopiedText(null);
24
+ }, resetDelay);
25
+ }, [resetDelay]);
26
+ const copy = useCallback(async (text) => {
27
+ if (!isSupported) {
28
+ return false;
29
+ }
30
+ const shouldUseClipboardApi = typeof navigator !== "undefined" && !!navigator.clipboard;
31
+ try {
32
+ if (shouldUseClipboardApi) {
33
+ await navigator.clipboard.writeText(text);
34
+ }
35
+ else if (typeof document !== "undefined") {
36
+ const textarea = document.createElement("textarea");
37
+ textarea.value = text;
38
+ textarea.setAttribute("readonly", "");
39
+ textarea.style.position = "fixed";
40
+ textarea.style.left = "-9999px";
41
+ textarea.style.top = "0";
42
+ document.body.appendChild(textarea);
43
+ textarea.focus();
44
+ textarea.select();
45
+ const success = document.execCommand("copy");
46
+ document.body.removeChild(textarea);
47
+ if (!success) {
48
+ return false;
49
+ }
50
+ }
51
+ setCopiedText(text);
52
+ resetCopied();
53
+ return true;
54
+ }
55
+ catch {
56
+ return false;
57
+ }
58
+ }, [isSupported, resetCopied]);
59
+ useEffect(() => {
60
+ return () => {
61
+ if (timeoutRef.current) {
62
+ clearTimeout(timeoutRef.current);
63
+ }
64
+ };
65
+ }, []);
66
+ return { copy, copiedText, isSupported };
67
+ }
@@ -0,0 +1,9 @@
1
+ export interface UseCopyToClipboardOptions {
2
+ resetDelay?: number;
3
+ }
4
+ export interface CopyToClipboardResult {
5
+ copy: (text: string) => Promise<boolean>;
6
+ copiedText: string | null;
7
+ isSupported: boolean;
8
+ }
9
+ export declare function useCopyToClipboard(options?: UseCopyToClipboardOptions): CopyToClipboardResult;
@@ -0,0 +1,67 @@
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ export function useCopyToClipboard(options = {}) {
3
+ const resetDelay = options.resetDelay ?? 2000;
4
+ const timeoutRef = useRef(null);
5
+ const [copiedText, setCopiedText] = useState(null);
6
+ const isSupported = useMemo(() => {
7
+ if (typeof navigator !== "undefined" && navigator.clipboard) {
8
+ return true;
9
+ }
10
+ if (typeof document === "undefined") {
11
+ return false;
12
+ }
13
+ if (typeof document.queryCommandSupported !== "function") {
14
+ return false;
15
+ }
16
+ return document.queryCommandSupported("copy");
17
+ }, []);
18
+ const resetCopied = useCallback(() => {
19
+ if (timeoutRef.current) {
20
+ clearTimeout(timeoutRef.current);
21
+ }
22
+ timeoutRef.current = setTimeout(() => {
23
+ setCopiedText(null);
24
+ }, resetDelay);
25
+ }, [resetDelay]);
26
+ const copy = useCallback(async (text) => {
27
+ if (!isSupported) {
28
+ return false;
29
+ }
30
+ const shouldUseClipboardApi = typeof navigator !== "undefined" && !!navigator.clipboard;
31
+ try {
32
+ if (shouldUseClipboardApi) {
33
+ await navigator.clipboard.writeText(text);
34
+ }
35
+ else if (typeof document !== "undefined") {
36
+ const textarea = document.createElement("textarea");
37
+ textarea.value = text;
38
+ textarea.setAttribute("readonly", "");
39
+ textarea.style.position = "fixed";
40
+ textarea.style.left = "-9999px";
41
+ textarea.style.top = "0";
42
+ document.body.appendChild(textarea);
43
+ textarea.focus();
44
+ textarea.select();
45
+ const success = document.execCommand("copy");
46
+ document.body.removeChild(textarea);
47
+ if (!success) {
48
+ return false;
49
+ }
50
+ }
51
+ setCopiedText(text);
52
+ resetCopied();
53
+ return true;
54
+ }
55
+ catch {
56
+ return false;
57
+ }
58
+ }, [isSupported, resetCopied]);
59
+ useEffect(() => {
60
+ return () => {
61
+ if (timeoutRef.current) {
62
+ clearTimeout(timeoutRef.current);
63
+ }
64
+ };
65
+ }, []);
66
+ return { copy, copiedText, isSupported };
67
+ }
@@ -0,0 +1,83 @@
1
+ import { useCallback, useEffect, useRef } from "react";
2
+ import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect.js";
3
+ export function useDebounceCallback(callback, delay, options = {}) {
4
+ const callbackRef = useRef(callback);
5
+ const timeoutRef = useRef(null);
6
+ const maxTimeoutRef = useRef(null);
7
+ const lastArgsRef = useRef(null);
8
+ const leading = options.leading ?? false;
9
+ const trailing = options.trailing ?? true;
10
+ const maxWait = options.maxWait;
11
+ const wait = Math.max(0, delay);
12
+ useIsomorphicLayoutEffect(() => {
13
+ callbackRef.current = callback;
14
+ }, [callback]);
15
+ const clearTimers = useCallback(() => {
16
+ if (timeoutRef.current) {
17
+ clearTimeout(timeoutRef.current);
18
+ timeoutRef.current = null;
19
+ }
20
+ if (maxTimeoutRef.current) {
21
+ clearTimeout(maxTimeoutRef.current);
22
+ maxTimeoutRef.current = null;
23
+ }
24
+ }, []);
25
+ const invoke = useCallback(() => {
26
+ if (!lastArgsRef.current) {
27
+ return;
28
+ }
29
+ const args = lastArgsRef.current;
30
+ lastArgsRef.current = null;
31
+ callbackRef.current(...args);
32
+ }, []);
33
+ const debouncedCallback = useCallback((...args) => {
34
+ lastArgsRef.current = args;
35
+ const shouldInvokeLeading = leading && timeoutRef.current === null && maxTimeoutRef.current === null;
36
+ if (shouldInvokeLeading) {
37
+ invoke();
38
+ }
39
+ if (timeoutRef.current) {
40
+ clearTimeout(timeoutRef.current);
41
+ }
42
+ if (trailing) {
43
+ timeoutRef.current = setTimeout(() => {
44
+ timeoutRef.current = null;
45
+ if (lastArgsRef.current) {
46
+ invoke();
47
+ }
48
+ if (maxTimeoutRef.current) {
49
+ clearTimeout(maxTimeoutRef.current);
50
+ maxTimeoutRef.current = null;
51
+ }
52
+ }, wait);
53
+ }
54
+ if (maxWait !== undefined && maxWait !== null && trailing) {
55
+ if (!maxTimeoutRef.current) {
56
+ const maxDelay = Math.max(0, maxWait);
57
+ maxTimeoutRef.current = setTimeout(() => {
58
+ maxTimeoutRef.current = null;
59
+ if (timeoutRef.current) {
60
+ clearTimeout(timeoutRef.current);
61
+ timeoutRef.current = null;
62
+ }
63
+ if (lastArgsRef.current) {
64
+ invoke();
65
+ }
66
+ }, maxDelay);
67
+ }
68
+ }
69
+ }, [invoke, leading, trailing, maxWait, wait]);
70
+ const cancel = useCallback(() => {
71
+ clearTimers();
72
+ lastArgsRef.current = null;
73
+ }, [clearTimers]);
74
+ const flush = useCallback(() => {
75
+ if (!lastArgsRef.current) {
76
+ return;
77
+ }
78
+ clearTimers();
79
+ invoke();
80
+ }, [clearTimers, invoke]);
81
+ useEffect(() => () => cancel(), [cancel]);
82
+ return { debouncedCallback, cancel, flush };
83
+ }
@@ -0,0 +1,11 @@
1
+ export interface DebounceOptions {
2
+ leading?: boolean;
3
+ trailing?: boolean;
4
+ maxWait?: number;
5
+ }
6
+ export interface DebouncedCallback<T extends (...args: any[]) => void> {
7
+ debouncedCallback: (...args: Parameters<T>) => void;
8
+ cancel: () => void;
9
+ flush: () => void;
10
+ }
11
+ export declare function useDebounceCallback<T extends (...args: any[]) => void>(callback: T, delay: number, options?: DebounceOptions): DebouncedCallback<T>;