@usefy/use-throttle 0.0.7 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,436 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/geon0529/usefy/master/assets/logo.png" alt="usefy logo" width="120" />
3
+ </p>
4
+
5
+ <h1 align="center">@usefy/use-throttle</h1>
6
+
7
+ <p align="center">
8
+ <strong>A high-performance React hook for throttling values with leading/trailing edge support</strong>
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/@usefy/use-throttle">
13
+ <img src="https://img.shields.io/npm/v/@usefy/use-throttle.svg?style=flat-square&color=007acc" alt="npm version" />
14
+ </a>
15
+ <a href="https://www.npmjs.com/package/@usefy/use-throttle">
16
+ <img src="https://img.shields.io/npm/dm/@usefy/use-throttle.svg?style=flat-square&color=007acc" alt="npm downloads" />
17
+ </a>
18
+ <a href="https://bundlephobia.com/package/@usefy/use-throttle">
19
+ <img src="https://img.shields.io/bundlephobia/minzip/@usefy/use-throttle?style=flat-square&color=007acc" alt="bundle size" />
20
+ </a>
21
+ <a href="https://github.com/geon0529/usefy/blob/master/LICENSE">
22
+ <img src="https://img.shields.io/npm/l/@usefy/use-throttle.svg?style=flat-square&color=007acc" alt="license" />
23
+ </a>
24
+ </p>
25
+
26
+ <p align="center">
27
+ <a href="#installation">Installation</a> •
28
+ <a href="#quick-start">Quick Start</a> •
29
+ <a href="#api-reference">API Reference</a> •
30
+ <a href="#examples">Examples</a> •
31
+ <a href="#license">License</a>
32
+ </p>
33
+
34
+ ---
35
+
36
+ ## Overview
37
+
38
+ `@usefy/use-throttle` limits value updates to at most once per specified interval, making it perfect for scroll events, resize handlers, mouse movements, and any high-frequency updates that need rate-limiting. Unlike debounce, throttle guarantees regular updates during continuous changes.
39
+
40
+ **Part of the [@usefy](https://www.npmjs.com/org/usefy) ecosystem** — a collection of production-ready React hooks designed for modern applications.
41
+
42
+ ### Why use-throttle?
43
+
44
+ - **Zero Dependencies** — Pure React implementation (uses @usefy/use-debounce internally)
45
+ - **TypeScript First** — Full type safety with generics and exported interfaces
46
+ - **Flexible Options** — Leading edge and trailing edge support
47
+ - **Guaranteed Updates** — Regular updates during continuous changes (unlike debounce)
48
+ - **SSR Compatible** — Works seamlessly with Next.js, Remix, and other SSR frameworks
49
+ - **Lightweight** — Minimal bundle footprint (~200B minified + gzipped)
50
+ - **Well Tested** — Comprehensive test coverage with Vitest
51
+
52
+ ### Throttle vs Debounce
53
+
54
+ | Feature | Throttle | Debounce |
55
+ |---------|----------|----------|
56
+ | First update | Immediate (leading: true) | After delay |
57
+ | During rapid changes | Regular intervals | Waits for pause |
58
+ | Best for | Scroll, resize, mouse move | Search input, form validation |
59
+
60
+ ---
61
+
62
+ ## Installation
63
+
64
+ ```bash
65
+ # npm
66
+ npm install @usefy/use-throttle
67
+
68
+ # yarn
69
+ yarn add @usefy/use-throttle
70
+
71
+ # pnpm
72
+ pnpm add @usefy/use-throttle
73
+ ```
74
+
75
+ ### Peer Dependencies
76
+
77
+ This package requires React 18 or 19:
78
+
79
+ ```json
80
+ {
81
+ "peerDependencies": {
82
+ "react": "^18.0.0 || ^19.0.0"
83
+ }
84
+ }
85
+ ```
86
+
87
+ ### Internal Dependencies
88
+
89
+ This package uses [@usefy/use-debounce](https://www.npmjs.com/package/@usefy/use-debounce) internally with `maxWait` set to achieve throttle behavior.
90
+
91
+ ---
92
+
93
+ ## Quick Start
94
+
95
+ ```tsx
96
+ import { useThrottle } from '@usefy/use-throttle';
97
+
98
+ function ScrollTracker() {
99
+ const [scrollY, setScrollY] = useState(0);
100
+ const throttledScrollY = useThrottle(scrollY, 100);
101
+
102
+ useEffect(() => {
103
+ const handleScroll = () => setScrollY(window.scrollY);
104
+ window.addEventListener('scroll', handleScroll);
105
+ return () => window.removeEventListener('scroll', handleScroll);
106
+ }, []);
107
+
108
+ return <div>Scroll position: {throttledScrollY}px</div>;
109
+ }
110
+ ```
111
+
112
+ ---
113
+
114
+ ## API Reference
115
+
116
+ ### `useThrottle<T>(value, delay?, options?)`
117
+
118
+ A hook that returns a throttled version of the provided value, limiting updates to at most once per interval.
119
+
120
+ #### Parameters
121
+
122
+ | Parameter | Type | Default | Description |
123
+ |-----------|------|---------|-------------|
124
+ | `value` | `T` | — | The value to throttle |
125
+ | `delay` | `number` | `500` | The throttle interval in milliseconds |
126
+ | `options` | `UseThrottleOptions` | `{}` | Additional configuration options |
127
+
128
+ #### Options
129
+
130
+ | Option | Type | Default | Description |
131
+ |--------|------|---------|-------------|
132
+ | `leading` | `boolean` | `true` | Update on the leading edge (first change) |
133
+ | `trailing` | `boolean` | `true` | Update on the trailing edge (after interval) |
134
+
135
+ #### Returns
136
+
137
+ | Type | Description |
138
+ |------|-------------|
139
+ | `T` | The throttled value |
140
+
141
+ ---
142
+
143
+ ## Examples
144
+
145
+ ### Scroll Position Tracking
146
+
147
+ ```tsx
148
+ import { useThrottle } from '@usefy/use-throttle';
149
+
150
+ function ScrollProgress() {
151
+ const [scrollY, setScrollY] = useState(0);
152
+ const throttledScrollY = useThrottle(scrollY, 100);
153
+
154
+ useEffect(() => {
155
+ const handleScroll = () => setScrollY(window.scrollY);
156
+ window.addEventListener('scroll', handleScroll, { passive: true });
157
+ return () => window.removeEventListener('scroll', handleScroll);
158
+ }, []);
159
+
160
+ const progress = Math.min(
161
+ (throttledScrollY / (document.body.scrollHeight - window.innerHeight)) * 100,
162
+ 100
163
+ );
164
+
165
+ return (
166
+ <div className="progress-bar" style={{ width: `${progress}%` }} />
167
+ );
168
+ }
169
+ ```
170
+
171
+ ### Mouse Position Tracker
172
+
173
+ ```tsx
174
+ import { useThrottle } from '@usefy/use-throttle';
175
+
176
+ function MouseTracker() {
177
+ const [position, setPosition] = useState({ x: 0, y: 0 });
178
+ const throttledPosition = useThrottle(position, 50);
179
+
180
+ useEffect(() => {
181
+ const handleMouseMove = (e: MouseEvent) => {
182
+ setPosition({ x: e.clientX, y: e.clientY });
183
+ };
184
+ window.addEventListener('mousemove', handleMouseMove);
185
+ return () => window.removeEventListener('mousemove', handleMouseMove);
186
+ }, []);
187
+
188
+ return (
189
+ <div className="cursor-follower" style={{
190
+ transform: `translate(${throttledPosition.x}px, ${throttledPosition.y}px)`
191
+ }} />
192
+ );
193
+ }
194
+ ```
195
+
196
+ ### Window Resize Handler
197
+
198
+ ```tsx
199
+ import { useThrottle } from '@usefy/use-throttle';
200
+
201
+ function ResponsiveLayout() {
202
+ const [windowSize, setWindowSize] = useState({
203
+ width: window.innerWidth,
204
+ height: window.innerHeight,
205
+ });
206
+ const throttledSize = useThrottle(windowSize, 200);
207
+
208
+ useEffect(() => {
209
+ const handleResize = () => {
210
+ setWindowSize({
211
+ width: window.innerWidth,
212
+ height: window.innerHeight,
213
+ });
214
+ };
215
+ window.addEventListener('resize', handleResize);
216
+ return () => window.removeEventListener('resize', handleResize);
217
+ }, []);
218
+
219
+ const layout = throttledSize.width >= 768 ? 'desktop' : 'mobile';
220
+
221
+ return (
222
+ <div className={`layout-${layout}`}>
223
+ Window: {throttledSize.width} x {throttledSize.height}
224
+ </div>
225
+ );
226
+ }
227
+ ```
228
+
229
+ ### Input Value with Frequent Updates
230
+
231
+ ```tsx
232
+ import { useThrottle } from '@usefy/use-throttle';
233
+
234
+ function RangeSlider() {
235
+ const [value, setValue] = useState(50);
236
+ const throttledValue = useThrottle(value, 200);
237
+
238
+ // API call only happens at most every 200ms
239
+ useEffect(() => {
240
+ updateServerValue(throttledValue);
241
+ }, [throttledValue]);
242
+
243
+ return (
244
+ <div>
245
+ <input
246
+ type="range"
247
+ min="0"
248
+ max="100"
249
+ value={value}
250
+ onChange={(e) => setValue(+e.target.value)}
251
+ />
252
+ <span>Value: {throttledValue}</span>
253
+ </div>
254
+ );
255
+ }
256
+ ```
257
+
258
+ ### Leading Edge Only
259
+
260
+ ```tsx
261
+ import { useThrottle } from '@usefy/use-throttle';
262
+
263
+ function InstantFeedback() {
264
+ const [clicks, setClicks] = useState(0);
265
+
266
+ // Update immediately on first click, ignore subsequent clicks for 500ms
267
+ const throttledClicks = useThrottle(clicks, 500, {
268
+ leading: true,
269
+ trailing: false,
270
+ });
271
+
272
+ return (
273
+ <button onClick={() => setClicks(c => c + 1)}>
274
+ Clicks: {throttledClicks}
275
+ </button>
276
+ );
277
+ }
278
+ ```
279
+
280
+ ### Trailing Edge Only
281
+
282
+ ```tsx
283
+ import { useThrottle } from '@usefy/use-throttle';
284
+
285
+ function DelayedUpdate() {
286
+ const [value, setValue] = useState('');
287
+
288
+ // Only update after the interval passes
289
+ const throttledValue = useThrottle(value, 300, {
290
+ leading: false,
291
+ trailing: true,
292
+ });
293
+
294
+ return (
295
+ <div>
296
+ <input value={value} onChange={(e) => setValue(e.target.value)} />
297
+ <p>Throttled: {throttledValue}</p>
298
+ </div>
299
+ );
300
+ }
301
+ ```
302
+
303
+ ---
304
+
305
+ ## TypeScript
306
+
307
+ This hook is written in TypeScript with full generic support.
308
+
309
+ ```tsx
310
+ import { useThrottle, type UseThrottleOptions } from '@usefy/use-throttle';
311
+
312
+ // Generic type inference
313
+ const throttledString = useThrottle('hello', 300); // string
314
+ const throttledNumber = useThrottle(42, 300); // number
315
+ const throttledObject = useThrottle({ x: 1 }, 300); // { x: number }
316
+
317
+ // Options type
318
+ const options: UseThrottleOptions = {
319
+ leading: true,
320
+ trailing: false,
321
+ };
322
+ ```
323
+
324
+ ---
325
+
326
+ ## Testing
327
+
328
+ This package maintains comprehensive test coverage to ensure reliability and stability.
329
+
330
+ ### Test Coverage
331
+
332
+ | Category | Tests | Coverage |
333
+ |----------|-------|----------|
334
+ | Initialization | 6 | 100% |
335
+ | Basic Throttling | 4 | 100% |
336
+ | Leading Edge | 3 | 100% |
337
+ | Trailing Edge | 2 | 100% |
338
+ | maxWait Behavior | 2 | 100% |
339
+ | Complex Scenarios | 5 | 100% |
340
+ | Option Changes | 3 | 100% |
341
+ | Cleanup | 1 | 100% |
342
+ | Edge Cases | 5 | 100% |
343
+ | Type Safety | 5 | 100% |
344
+ | Multiple Instances | 2 | 100% |
345
+ | **Total** | **38** | **100%** |
346
+
347
+ ### Test Categories
348
+
349
+ <details>
350
+ <summary><strong>Initialization Tests</strong></summary>
351
+
352
+ - Initialize with string, number, boolean, object, array values
353
+ - Use default delay of 500ms when not specified
354
+
355
+ </details>
356
+
357
+ <details>
358
+ <summary><strong>Throttling Behavior Tests</strong></summary>
359
+
360
+ - Update immediately on first change (leading edge)
361
+ - Throttle rapid updates after leading edge
362
+ - Update at most once per interval during continuous changes
363
+ - Allow new leading edge after interval passes
364
+
365
+ </details>
366
+
367
+ <details>
368
+ <summary><strong>Leading/Trailing Edge Tests</strong></summary>
369
+
370
+ - Update immediately with leading: true (default)
371
+ - No immediate update with leading: false
372
+ - Update on trailing edge with trailing: true (default)
373
+
374
+ </details>
375
+
376
+ ### Running Tests
377
+
378
+ ```bash
379
+ # Run all tests
380
+ pnpm test
381
+
382
+ # Run tests in watch mode
383
+ pnpm test:watch
384
+
385
+ # Run tests with coverage report
386
+ pnpm test --coverage
387
+ ```
388
+
389
+ ---
390
+
391
+ ## Related Packages
392
+
393
+ Explore other hooks in the **@usefy** collection:
394
+
395
+ | Package | Description |
396
+ |---------|-------------|
397
+ | [@usefy/use-throttle-callback](https://www.npmjs.com/package/@usefy/use-throttle-callback) | Throttled callbacks with cancel/flush |
398
+ | [@usefy/use-debounce](https://www.npmjs.com/package/@usefy/use-debounce) | Value debouncing |
399
+ | [@usefy/use-debounce-callback](https://www.npmjs.com/package/@usefy/use-debounce-callback) | Debounced callbacks |
400
+ | [@usefy/use-toggle](https://www.npmjs.com/package/@usefy/use-toggle) | Boolean state management |
401
+ | [@usefy/use-counter](https://www.npmjs.com/package/@usefy/use-counter) | Counter state management |
402
+ | [@usefy/use-click-any-where](https://www.npmjs.com/package/@usefy/use-click-any-where) | Global click detection |
403
+
404
+ ---
405
+
406
+ ## Contributing
407
+
408
+ We welcome contributions! Please see our [Contributing Guide](https://github.com/geon0529/usefy/blob/master/CONTRIBUTING.md) for details.
409
+
410
+ ```bash
411
+ # Clone the repository
412
+ git clone https://github.com/geon0529/usefy.git
413
+
414
+ # Install dependencies
415
+ pnpm install
416
+
417
+ # Run tests
418
+ pnpm test
419
+
420
+ # Build
421
+ pnpm build
422
+ ```
423
+
424
+ ---
425
+
426
+ ## License
427
+
428
+ MIT © [mirunamu](https://github.com/geon0529)
429
+
430
+ This package is part of the [usefy](https://github.com/geon0529/usefy) monorepo.
431
+
432
+ ---
433
+
434
+ <p align="center">
435
+ <sub>Built with care by the usefy team</sub>
436
+ </p>
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/useThrottle.ts"],"sourcesContent":["export { useThrottle, type UseThrottleOptions } from \"./useThrottle\";\r\n","import { useDebounce, type UseDebounceOptions } from \"@usefy/use-debounce\";\r\n\r\n/**\r\n * Options for useThrottle hook\r\n */\r\nexport interface UseThrottleOptions {\r\n /**\r\n * Whether to update the throttled value on the leading edge\r\n * @default true\r\n */\r\n leading?: boolean;\r\n /**\r\n * Whether to update the throttled value on the trailing edge\r\n * @default true\r\n */\r\n trailing?: boolean;\r\n}\r\n\r\n/**\r\n * Throttles a value by limiting updates to at most once per specified interval.\r\n * This is implemented using useDebounce with maxWait set to the interval.\r\n * Useful for scroll events and resize handlers.\r\n *\r\n * @template T - The type of the value to throttle\r\n * @param value - The value to throttle\r\n * @param delay - The interval in milliseconds (default: 500ms)\r\n * @param options - Additional options for controlling throttle behavior\r\n * @returns The throttled value\r\n *\r\n * @example\r\n * ```tsx\r\n * function ScrollComponent() {\r\n * const [scrollY, setScrollY] = useState(0);\r\n * const throttledScrollY = useThrottle(scrollY, 100);\r\n *\r\n * useEffect(() => {\r\n * const handleScroll = () => setScrollY(window.scrollY);\r\n * window.addEventListener(\"scroll\", handleScroll);\r\n * return () => window.removeEventListener(\"scroll\", handleScroll);\r\n * }, []);\r\n *\r\n * return <div>Scroll Y: {throttledScrollY}</div>;\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```tsx\r\n * // With leading edge only\r\n * const throttledValue = useThrottle(value, 300, { leading: true, trailing: false });\r\n * ```\r\n *\r\n * @example\r\n * ```tsx\r\n * // With trailing edge only\r\n * const throttledValue = useThrottle(value, 300, { leading: false, trailing: true });\r\n * ```\r\n */\r\nexport function useThrottle<T>(\r\n value: T,\r\n delay: number = 500,\r\n options: UseThrottleOptions = {}\r\n): T {\r\n const { leading = true, trailing = true } = options;\r\n\r\n // Throttle is implemented using debounce with maxWait set to delay\r\n return useDebounce(value, delay, {\r\n leading,\r\n maxWait: delay,\r\n trailing,\r\n });\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,0BAAqD;AAyD9C,SAAS,YACd,OACA,QAAgB,KAChB,UAA8B,CAAC,GAC5B;AACH,QAAM,EAAE,UAAU,MAAM,WAAW,KAAK,IAAI;AAG5C,aAAO,iCAAY,OAAO,OAAO;AAAA,IAC/B;AAAA,IACA,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/useThrottle.ts"],"sourcesContent":["export { useThrottle, type UseThrottleOptions } from \"./useThrottle\";\n","import { useDebounce, type UseDebounceOptions } from \"@usefy/use-debounce\";\n\n/**\n * Options for useThrottle hook\n */\nexport interface UseThrottleOptions {\n /**\n * Whether to update the throttled value on the leading edge\n * @default true\n */\n leading?: boolean;\n /**\n * Whether to update the throttled value on the trailing edge\n * @default true\n */\n trailing?: boolean;\n}\n\n/**\n * Throttles a value by limiting updates to at most once per specified interval.\n * This is implemented using useDebounce with maxWait set to the interval.\n * Useful for scroll events and resize handlers.\n *\n * @template T - The type of the value to throttle\n * @param value - The value to throttle\n * @param delay - The interval in milliseconds (default: 500ms)\n * @param options - Additional options for controlling throttle behavior\n * @returns The throttled value\n *\n * @example\n * ```tsx\n * function ScrollComponent() {\n * const [scrollY, setScrollY] = useState(0);\n * const throttledScrollY = useThrottle(scrollY, 100);\n *\n * useEffect(() => {\n * const handleScroll = () => setScrollY(window.scrollY);\n * window.addEventListener(\"scroll\", handleScroll);\n * return () => window.removeEventListener(\"scroll\", handleScroll);\n * }, []);\n *\n * return <div>Scroll Y: {throttledScrollY}</div>;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With leading edge only\n * const throttledValue = useThrottle(value, 300, { leading: true, trailing: false });\n * ```\n *\n * @example\n * ```tsx\n * // With trailing edge only\n * const throttledValue = useThrottle(value, 300, { leading: false, trailing: true });\n * ```\n */\nexport function useThrottle<T>(\n value: T,\n delay: number = 500,\n options: UseThrottleOptions = {}\n): T {\n const { leading = true, trailing = true } = options;\n\n // Throttle is implemented using debounce with maxWait set to delay\n return useDebounce(value, delay, {\n leading,\n maxWait: delay,\n trailing,\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,0BAAqD;AAyD9C,SAAS,YACd,OACA,QAAgB,KAChB,UAA8B,CAAC,GAC5B;AACH,QAAM,EAAE,UAAU,MAAM,WAAW,KAAK,IAAI;AAG5C,aAAO,iCAAY,OAAO,OAAO;AAAA,IAC/B;AAAA,IACA,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AACH;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/useThrottle.ts"],"sourcesContent":["import { useDebounce, type UseDebounceOptions } from \"@usefy/use-debounce\";\r\n\r\n/**\r\n * Options for useThrottle hook\r\n */\r\nexport interface UseThrottleOptions {\r\n /**\r\n * Whether to update the throttled value on the leading edge\r\n * @default true\r\n */\r\n leading?: boolean;\r\n /**\r\n * Whether to update the throttled value on the trailing edge\r\n * @default true\r\n */\r\n trailing?: boolean;\r\n}\r\n\r\n/**\r\n * Throttles a value by limiting updates to at most once per specified interval.\r\n * This is implemented using useDebounce with maxWait set to the interval.\r\n * Useful for scroll events and resize handlers.\r\n *\r\n * @template T - The type of the value to throttle\r\n * @param value - The value to throttle\r\n * @param delay - The interval in milliseconds (default: 500ms)\r\n * @param options - Additional options for controlling throttle behavior\r\n * @returns The throttled value\r\n *\r\n * @example\r\n * ```tsx\r\n * function ScrollComponent() {\r\n * const [scrollY, setScrollY] = useState(0);\r\n * const throttledScrollY = useThrottle(scrollY, 100);\r\n *\r\n * useEffect(() => {\r\n * const handleScroll = () => setScrollY(window.scrollY);\r\n * window.addEventListener(\"scroll\", handleScroll);\r\n * return () => window.removeEventListener(\"scroll\", handleScroll);\r\n * }, []);\r\n *\r\n * return <div>Scroll Y: {throttledScrollY}</div>;\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```tsx\r\n * // With leading edge only\r\n * const throttledValue = useThrottle(value, 300, { leading: true, trailing: false });\r\n * ```\r\n *\r\n * @example\r\n * ```tsx\r\n * // With trailing edge only\r\n * const throttledValue = useThrottle(value, 300, { leading: false, trailing: true });\r\n * ```\r\n */\r\nexport function useThrottle<T>(\r\n value: T,\r\n delay: number = 500,\r\n options: UseThrottleOptions = {}\r\n): T {\r\n const { leading = true, trailing = true } = options;\r\n\r\n // Throttle is implemented using debounce with maxWait set to delay\r\n return useDebounce(value, delay, {\r\n leading,\r\n maxWait: delay,\r\n trailing,\r\n });\r\n}\r\n"],"mappings":";AAAA,SAAS,mBAA4C;AAyD9C,SAAS,YACd,OACA,QAAgB,KAChB,UAA8B,CAAC,GAC5B;AACH,QAAM,EAAE,UAAU,MAAM,WAAW,KAAK,IAAI;AAG5C,SAAO,YAAY,OAAO,OAAO;AAAA,IAC/B;AAAA,IACA,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../src/useThrottle.ts"],"sourcesContent":["import { useDebounce, type UseDebounceOptions } from \"@usefy/use-debounce\";\n\n/**\n * Options for useThrottle hook\n */\nexport interface UseThrottleOptions {\n /**\n * Whether to update the throttled value on the leading edge\n * @default true\n */\n leading?: boolean;\n /**\n * Whether to update the throttled value on the trailing edge\n * @default true\n */\n trailing?: boolean;\n}\n\n/**\n * Throttles a value by limiting updates to at most once per specified interval.\n * This is implemented using useDebounce with maxWait set to the interval.\n * Useful for scroll events and resize handlers.\n *\n * @template T - The type of the value to throttle\n * @param value - The value to throttle\n * @param delay - The interval in milliseconds (default: 500ms)\n * @param options - Additional options for controlling throttle behavior\n * @returns The throttled value\n *\n * @example\n * ```tsx\n * function ScrollComponent() {\n * const [scrollY, setScrollY] = useState(0);\n * const throttledScrollY = useThrottle(scrollY, 100);\n *\n * useEffect(() => {\n * const handleScroll = () => setScrollY(window.scrollY);\n * window.addEventListener(\"scroll\", handleScroll);\n * return () => window.removeEventListener(\"scroll\", handleScroll);\n * }, []);\n *\n * return <div>Scroll Y: {throttledScrollY}</div>;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With leading edge only\n * const throttledValue = useThrottle(value, 300, { leading: true, trailing: false });\n * ```\n *\n * @example\n * ```tsx\n * // With trailing edge only\n * const throttledValue = useThrottle(value, 300, { leading: false, trailing: true });\n * ```\n */\nexport function useThrottle<T>(\n value: T,\n delay: number = 500,\n options: UseThrottleOptions = {}\n): T {\n const { leading = true, trailing = true } = options;\n\n // Throttle is implemented using debounce with maxWait set to delay\n return useDebounce(value, delay, {\n leading,\n maxWait: delay,\n trailing,\n });\n}\n"],"mappings":";AAAA,SAAS,mBAA4C;AAyD9C,SAAS,YACd,OACA,QAAgB,KAChB,UAA8B,CAAC,GAC5B;AACH,QAAM,EAAE,UAAU,MAAM,WAAW,KAAK,IAAI;AAG5C,SAAO,YAAY,OAAO,OAAO;AAAA,IAC/B;AAAA,IACA,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AACH;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usefy/use-throttle",
3
- "version": "0.0.7",
3
+ "version": "0.0.10",
4
4
  "description": "A React hook for throttling values",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -17,7 +17,7 @@
17
17
  ],
18
18
  "sideEffects": false,
19
19
  "dependencies": {
20
- "@usefy/use-debounce": "0.0.7"
20
+ "@usefy/use-debounce": "0.0.10"
21
21
  },
22
22
  "peerDependencies": {
23
23
  "react": "^18.0.0 || ^19.0.0"