@usefy/use-throttle 0.0.11 → 0.0.13
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 +60 -66
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
|
|
52
52
|
### Throttle vs Debounce
|
|
53
53
|
|
|
54
|
-
| Feature
|
|
55
|
-
|
|
56
|
-
| First update
|
|
57
|
-
| During rapid changes | Regular intervals
|
|
58
|
-
| Best for
|
|
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
59
|
|
|
60
60
|
---
|
|
61
61
|
|
|
@@ -93,7 +93,7 @@ This package uses [@usefy/use-debounce](https://www.npmjs.com/package/@usefy/use
|
|
|
93
93
|
## Quick Start
|
|
94
94
|
|
|
95
95
|
```tsx
|
|
96
|
-
import { useThrottle } from
|
|
96
|
+
import { useThrottle } from "@usefy/use-throttle";
|
|
97
97
|
|
|
98
98
|
function ScrollTracker() {
|
|
99
99
|
const [scrollY, setScrollY] = useState(0);
|
|
@@ -101,8 +101,8 @@ function ScrollTracker() {
|
|
|
101
101
|
|
|
102
102
|
useEffect(() => {
|
|
103
103
|
const handleScroll = () => setScrollY(window.scrollY);
|
|
104
|
-
window.addEventListener(
|
|
105
|
-
return () => window.removeEventListener(
|
|
104
|
+
window.addEventListener("scroll", handleScroll);
|
|
105
|
+
return () => window.removeEventListener("scroll", handleScroll);
|
|
106
106
|
}, []);
|
|
107
107
|
|
|
108
108
|
return <div>Scroll position: {throttledScrollY}px</div>;
|
|
@@ -119,24 +119,24 @@ A hook that returns a throttled version of the provided value, limiting updates
|
|
|
119
119
|
|
|
120
120
|
#### Parameters
|
|
121
121
|
|
|
122
|
-
| Parameter | Type
|
|
123
|
-
|
|
124
|
-
| `value`
|
|
125
|
-
| `delay`
|
|
126
|
-
| `options` | `UseThrottleOptions` | `{}`
|
|
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
127
|
|
|
128
128
|
#### Options
|
|
129
129
|
|
|
130
|
-
| Option
|
|
131
|
-
|
|
132
|
-
| `leading`
|
|
133
|
-
| `trailing` | `boolean` | `true`
|
|
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
134
|
|
|
135
135
|
#### Returns
|
|
136
136
|
|
|
137
|
-
| Type | Description
|
|
138
|
-
|
|
139
|
-
| `T`
|
|
137
|
+
| Type | Description |
|
|
138
|
+
| ---- | ------------------- |
|
|
139
|
+
| `T` | The throttled value |
|
|
140
140
|
|
|
141
141
|
---
|
|
142
142
|
|
|
@@ -145,7 +145,7 @@ A hook that returns a throttled version of the provided value, limiting updates
|
|
|
145
145
|
### Scroll Position Tracking
|
|
146
146
|
|
|
147
147
|
```tsx
|
|
148
|
-
import { useThrottle } from
|
|
148
|
+
import { useThrottle } from "@usefy/use-throttle";
|
|
149
149
|
|
|
150
150
|
function ScrollProgress() {
|
|
151
151
|
const [scrollY, setScrollY] = useState(0);
|
|
@@ -153,25 +153,24 @@ function ScrollProgress() {
|
|
|
153
153
|
|
|
154
154
|
useEffect(() => {
|
|
155
155
|
const handleScroll = () => setScrollY(window.scrollY);
|
|
156
|
-
window.addEventListener(
|
|
157
|
-
return () => window.removeEventListener(
|
|
156
|
+
window.addEventListener("scroll", handleScroll, { passive: true });
|
|
157
|
+
return () => window.removeEventListener("scroll", handleScroll);
|
|
158
158
|
}, []);
|
|
159
159
|
|
|
160
160
|
const progress = Math.min(
|
|
161
|
-
(throttledScrollY / (document.body.scrollHeight - window.innerHeight)) *
|
|
161
|
+
(throttledScrollY / (document.body.scrollHeight - window.innerHeight)) *
|
|
162
|
+
100,
|
|
162
163
|
100
|
|
163
164
|
);
|
|
164
165
|
|
|
165
|
-
return
|
|
166
|
-
<div className="progress-bar" style={{ width: `${progress}%` }} />
|
|
167
|
-
);
|
|
166
|
+
return <div className="progress-bar" style={{ width: `${progress}%` }} />;
|
|
168
167
|
}
|
|
169
168
|
```
|
|
170
169
|
|
|
171
170
|
### Mouse Position Tracker
|
|
172
171
|
|
|
173
172
|
```tsx
|
|
174
|
-
import { useThrottle } from
|
|
173
|
+
import { useThrottle } from "@usefy/use-throttle";
|
|
175
174
|
|
|
176
175
|
function MouseTracker() {
|
|
177
176
|
const [position, setPosition] = useState({ x: 0, y: 0 });
|
|
@@ -181,14 +180,17 @@ function MouseTracker() {
|
|
|
181
180
|
const handleMouseMove = (e: MouseEvent) => {
|
|
182
181
|
setPosition({ x: e.clientX, y: e.clientY });
|
|
183
182
|
};
|
|
184
|
-
window.addEventListener(
|
|
185
|
-
return () => window.removeEventListener(
|
|
183
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
184
|
+
return () => window.removeEventListener("mousemove", handleMouseMove);
|
|
186
185
|
}, []);
|
|
187
186
|
|
|
188
187
|
return (
|
|
189
|
-
<div
|
|
190
|
-
|
|
191
|
-
|
|
188
|
+
<div
|
|
189
|
+
className="cursor-follower"
|
|
190
|
+
style={{
|
|
191
|
+
transform: `translate(${throttledPosition.x}px, ${throttledPosition.y}px)`,
|
|
192
|
+
}}
|
|
193
|
+
/>
|
|
192
194
|
);
|
|
193
195
|
}
|
|
194
196
|
```
|
|
@@ -196,7 +198,7 @@ function MouseTracker() {
|
|
|
196
198
|
### Window Resize Handler
|
|
197
199
|
|
|
198
200
|
```tsx
|
|
199
|
-
import { useThrottle } from
|
|
201
|
+
import { useThrottle } from "@usefy/use-throttle";
|
|
200
202
|
|
|
201
203
|
function ResponsiveLayout() {
|
|
202
204
|
const [windowSize, setWindowSize] = useState({
|
|
@@ -212,11 +214,11 @@ function ResponsiveLayout() {
|
|
|
212
214
|
height: window.innerHeight,
|
|
213
215
|
});
|
|
214
216
|
};
|
|
215
|
-
window.addEventListener(
|
|
216
|
-
return () => window.removeEventListener(
|
|
217
|
+
window.addEventListener("resize", handleResize);
|
|
218
|
+
return () => window.removeEventListener("resize", handleResize);
|
|
217
219
|
}, []);
|
|
218
220
|
|
|
219
|
-
const layout = throttledSize.width >= 768 ?
|
|
221
|
+
const layout = throttledSize.width >= 768 ? "desktop" : "mobile";
|
|
220
222
|
|
|
221
223
|
return (
|
|
222
224
|
<div className={`layout-${layout}`}>
|
|
@@ -229,7 +231,7 @@ function ResponsiveLayout() {
|
|
|
229
231
|
### Input Value with Frequent Updates
|
|
230
232
|
|
|
231
233
|
```tsx
|
|
232
|
-
import { useThrottle } from
|
|
234
|
+
import { useThrottle } from "@usefy/use-throttle";
|
|
233
235
|
|
|
234
236
|
function RangeSlider() {
|
|
235
237
|
const [value, setValue] = useState(50);
|
|
@@ -258,7 +260,7 @@ function RangeSlider() {
|
|
|
258
260
|
### Leading Edge Only
|
|
259
261
|
|
|
260
262
|
```tsx
|
|
261
|
-
import { useThrottle } from
|
|
263
|
+
import { useThrottle } from "@usefy/use-throttle";
|
|
262
264
|
|
|
263
265
|
function InstantFeedback() {
|
|
264
266
|
const [clicks, setClicks] = useState(0);
|
|
@@ -270,7 +272,7 @@ function InstantFeedback() {
|
|
|
270
272
|
});
|
|
271
273
|
|
|
272
274
|
return (
|
|
273
|
-
<button onClick={() => setClicks(c => c + 1)}>
|
|
275
|
+
<button onClick={() => setClicks((c) => c + 1)}>
|
|
274
276
|
Clicks: {throttledClicks}
|
|
275
277
|
</button>
|
|
276
278
|
);
|
|
@@ -280,10 +282,10 @@ function InstantFeedback() {
|
|
|
280
282
|
### Trailing Edge Only
|
|
281
283
|
|
|
282
284
|
```tsx
|
|
283
|
-
import { useThrottle } from
|
|
285
|
+
import { useThrottle } from "@usefy/use-throttle";
|
|
284
286
|
|
|
285
287
|
function DelayedUpdate() {
|
|
286
|
-
const [value, setValue] = useState(
|
|
288
|
+
const [value, setValue] = useState("");
|
|
287
289
|
|
|
288
290
|
// Only update after the interval passes
|
|
289
291
|
const throttledValue = useThrottle(value, 300, {
|
|
@@ -307,11 +309,11 @@ function DelayedUpdate() {
|
|
|
307
309
|
This hook is written in TypeScript with full generic support.
|
|
308
310
|
|
|
309
311
|
```tsx
|
|
310
|
-
import { useThrottle, type UseThrottleOptions } from
|
|
312
|
+
import { useThrottle, type UseThrottleOptions } from "@usefy/use-throttle";
|
|
311
313
|
|
|
312
314
|
// Generic type inference
|
|
313
|
-
const throttledString = useThrottle(
|
|
314
|
-
const throttledNumber = useThrottle(42, 300);
|
|
315
|
+
const throttledString = useThrottle("hello", 300); // string
|
|
316
|
+
const throttledNumber = useThrottle(42, 300); // number
|
|
315
317
|
const throttledObject = useThrottle({ x: 1 }, 300); // { x: number }
|
|
316
318
|
|
|
317
319
|
// Options type
|
|
@@ -329,20 +331,12 @@ This package maintains comprehensive test coverage to ensure reliability and sta
|
|
|
329
331
|
|
|
330
332
|
### Test Coverage
|
|
331
333
|
|
|
332
|
-
| Category
|
|
333
|
-
|
|
334
|
-
|
|
|
335
|
-
|
|
|
336
|
-
|
|
|
337
|
-
|
|
|
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%** |
|
|
334
|
+
| Category | Coverage |
|
|
335
|
+
| ---------- | ---------- |
|
|
336
|
+
| Statements | 100% (2/2) |
|
|
337
|
+
| Branches | 100% (4/4) |
|
|
338
|
+
| Functions | 100% (1/1) |
|
|
339
|
+
| Lines | 100% (2/2) |
|
|
346
340
|
|
|
347
341
|
### Test Categories
|
|
348
342
|
|
|
@@ -392,14 +386,14 @@ pnpm test --coverage
|
|
|
392
386
|
|
|
393
387
|
Explore other hooks in the **@usefy** collection:
|
|
394
388
|
|
|
395
|
-
| Package
|
|
396
|
-
|
|
389
|
+
| Package | Description |
|
|
390
|
+
| ------------------------------------------------------------------------------------------ | ------------------------------------- |
|
|
397
391
|
| [@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)
|
|
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)
|
|
401
|
-
| [@usefy/use-counter](https://www.npmjs.com/package/@usefy/use-counter)
|
|
402
|
-
| [@usefy/use-click-any-where](https://www.npmjs.com/package/@usefy/use-click-any-where)
|
|
392
|
+
| [@usefy/use-debounce](https://www.npmjs.com/package/@usefy/use-debounce) | Value debouncing |
|
|
393
|
+
| [@usefy/use-debounce-callback](https://www.npmjs.com/package/@usefy/use-debounce-callback) | Debounced callbacks |
|
|
394
|
+
| [@usefy/use-toggle](https://www.npmjs.com/package/@usefy/use-toggle) | Boolean state management |
|
|
395
|
+
| [@usefy/use-counter](https://www.npmjs.com/package/@usefy/use-counter) | Counter state management |
|
|
396
|
+
| [@usefy/use-click-any-where](https://www.npmjs.com/package/@usefy/use-click-any-where) | Global click detection |
|
|
403
397
|
|
|
404
398
|
---
|
|
405
399
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usefy/use-throttle",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
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.13"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
23
|
"react": "^18.0.0 || ^19.0.0"
|