@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 +436 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
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\";\
|
|
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":[]}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/useThrottle.ts"],"sourcesContent":["import { useDebounce, type UseDebounceOptions } from \"@usefy/use-debounce\";\
|
|
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.
|
|
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.
|
|
20
|
+
"@usefy/use-debounce": "0.0.10"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
23
|
"react": "^18.0.0 || ^19.0.0"
|