@usefy/use-debounce 0.0.16 → 0.0.18
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 +54 -50
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -80,10 +80,10 @@ This package requires React 18 or 19:
|
|
|
80
80
|
## Quick Start
|
|
81
81
|
|
|
82
82
|
```tsx
|
|
83
|
-
import { useDebounce } from
|
|
83
|
+
import { useDebounce } from "@usefy/use-debounce";
|
|
84
84
|
|
|
85
85
|
function SearchInput() {
|
|
86
|
-
const [query, setQuery] = useState(
|
|
86
|
+
const [query, setQuery] = useState("");
|
|
87
87
|
const debouncedQuery = useDebounce(query, 300);
|
|
88
88
|
|
|
89
89
|
useEffect(() => {
|
|
@@ -113,25 +113,25 @@ A hook that returns a debounced version of the provided value.
|
|
|
113
113
|
|
|
114
114
|
#### Parameters
|
|
115
115
|
|
|
116
|
-
| Parameter | Type
|
|
117
|
-
|
|
118
|
-
| `value`
|
|
119
|
-
| `delay`
|
|
120
|
-
| `options` | `UseDebounceOptions` | `{}`
|
|
116
|
+
| Parameter | Type | Default | Description |
|
|
117
|
+
| --------- | -------------------- | ------- | ---------------------------------- |
|
|
118
|
+
| `value` | `T` | — | The value to debounce |
|
|
119
|
+
| `delay` | `number` | `500` | The debounce delay in milliseconds |
|
|
120
|
+
| `options` | `UseDebounceOptions` | `{}` | Additional configuration options |
|
|
121
121
|
|
|
122
122
|
#### Options
|
|
123
123
|
|
|
124
|
-
| Option
|
|
125
|
-
|
|
126
|
-
| `leading`
|
|
127
|
-
| `trailing` | `boolean` | `true`
|
|
128
|
-
| `maxWait`
|
|
124
|
+
| Option | Type | Default | Description |
|
|
125
|
+
| ---------- | --------- | ------- | --------------------------------------------- |
|
|
126
|
+
| `leading` | `boolean` | `false` | Update on the leading edge (first call) |
|
|
127
|
+
| `trailing` | `boolean` | `true` | Update on the trailing edge (after delay) |
|
|
128
|
+
| `maxWait` | `number` | — | Maximum time to wait before forcing an update |
|
|
129
129
|
|
|
130
130
|
#### Returns
|
|
131
131
|
|
|
132
|
-
| Type | Description
|
|
133
|
-
|
|
134
|
-
| `T`
|
|
132
|
+
| Type | Description |
|
|
133
|
+
| ---- | ------------------- |
|
|
134
|
+
| `T` | The debounced value |
|
|
135
135
|
|
|
136
136
|
---
|
|
137
137
|
|
|
@@ -140,10 +140,10 @@ A hook that returns a debounced version of the provided value.
|
|
|
140
140
|
### Basic Search Input
|
|
141
141
|
|
|
142
142
|
```tsx
|
|
143
|
-
import { useDebounce } from
|
|
143
|
+
import { useDebounce } from "@usefy/use-debounce";
|
|
144
144
|
|
|
145
145
|
function SearchInput() {
|
|
146
|
-
const [query, setQuery] = useState(
|
|
146
|
+
const [query, setQuery] = useState("");
|
|
147
147
|
const debouncedQuery = useDebounce(query, 300);
|
|
148
148
|
const [results, setResults] = useState([]);
|
|
149
149
|
|
|
@@ -179,10 +179,10 @@ function SearchInput() {
|
|
|
179
179
|
### With Leading Edge (Instant First Update)
|
|
180
180
|
|
|
181
181
|
```tsx
|
|
182
|
-
import { useDebounce } from
|
|
182
|
+
import { useDebounce } from "@usefy/use-debounce";
|
|
183
183
|
|
|
184
184
|
function FilterPanel() {
|
|
185
|
-
const [filters, setFilters] = useState({ category:
|
|
185
|
+
const [filters, setFilters] = useState({ category: "all", price: 0 });
|
|
186
186
|
|
|
187
187
|
// Update immediately on first change, then debounce subsequent changes
|
|
188
188
|
const debouncedFilters = useDebounce(filters, 500, { leading: true });
|
|
@@ -195,7 +195,9 @@ function FilterPanel() {
|
|
|
195
195
|
<div>
|
|
196
196
|
<select
|
|
197
197
|
value={filters.category}
|
|
198
|
-
onChange={(e) =>
|
|
198
|
+
onChange={(e) =>
|
|
199
|
+
setFilters((f) => ({ ...f, category: e.target.value }))
|
|
200
|
+
}
|
|
199
201
|
>
|
|
200
202
|
<option value="all">All</option>
|
|
201
203
|
<option value="electronics">Electronics</option>
|
|
@@ -204,7 +206,7 @@ function FilterPanel() {
|
|
|
204
206
|
<input
|
|
205
207
|
type="range"
|
|
206
208
|
value={filters.price}
|
|
207
|
-
onChange={(e) => setFilters(f => ({ ...f, price: +e.target.value }))}
|
|
209
|
+
onChange={(e) => setFilters((f) => ({ ...f, price: +e.target.value }))}
|
|
208
210
|
/>
|
|
209
211
|
</div>
|
|
210
212
|
);
|
|
@@ -214,10 +216,10 @@ function FilterPanel() {
|
|
|
214
216
|
### With maxWait (Guaranteed Updates)
|
|
215
217
|
|
|
216
218
|
```tsx
|
|
217
|
-
import { useDebounce } from
|
|
219
|
+
import { useDebounce } from "@usefy/use-debounce";
|
|
218
220
|
|
|
219
221
|
function AutoSaveEditor() {
|
|
220
|
-
const [content, setContent] = useState(
|
|
222
|
+
const [content, setContent] = useState("");
|
|
221
223
|
|
|
222
224
|
// Debounce for 1 second, but guarantee save every 5 seconds during continuous typing
|
|
223
225
|
const debouncedContent = useDebounce(content, 1000, { maxWait: 5000 });
|
|
@@ -241,22 +243,24 @@ function AutoSaveEditor() {
|
|
|
241
243
|
### Form Validation
|
|
242
244
|
|
|
243
245
|
```tsx
|
|
244
|
-
import { useDebounce } from
|
|
246
|
+
import { useDebounce } from "@usefy/use-debounce";
|
|
245
247
|
|
|
246
248
|
function RegistrationForm() {
|
|
247
|
-
const [username, setUsername] = useState(
|
|
248
|
-
const [error, setError] = useState(
|
|
249
|
+
const [username, setUsername] = useState("");
|
|
250
|
+
const [error, setError] = useState("");
|
|
249
251
|
const debouncedUsername = useDebounce(username, 500);
|
|
250
252
|
|
|
251
253
|
useEffect(() => {
|
|
252
254
|
async function checkAvailability() {
|
|
253
255
|
if (debouncedUsername.length < 3) {
|
|
254
|
-
setError(
|
|
256
|
+
setError("Username must be at least 3 characters");
|
|
255
257
|
return;
|
|
256
258
|
}
|
|
257
|
-
const response = await fetch(
|
|
259
|
+
const response = await fetch(
|
|
260
|
+
`/api/check-username?u=${debouncedUsername}`
|
|
261
|
+
);
|
|
258
262
|
const { available } = await response.json();
|
|
259
|
-
setError(available ?
|
|
263
|
+
setError(available ? "" : "Username is already taken");
|
|
260
264
|
}
|
|
261
265
|
|
|
262
266
|
if (debouncedUsername) {
|
|
@@ -280,13 +284,13 @@ function RegistrationForm() {
|
|
|
280
284
|
### Debouncing Object Values
|
|
281
285
|
|
|
282
286
|
```tsx
|
|
283
|
-
import { useDebounce } from
|
|
287
|
+
import { useDebounce } from "@usefy/use-debounce";
|
|
284
288
|
|
|
285
289
|
function FilteredTable() {
|
|
286
290
|
const [filters, setFilters] = useState({
|
|
287
|
-
search:
|
|
288
|
-
status:
|
|
289
|
-
sortBy:
|
|
291
|
+
search: "",
|
|
292
|
+
status: "all",
|
|
293
|
+
sortBy: "date",
|
|
290
294
|
});
|
|
291
295
|
|
|
292
296
|
const debouncedFilters = useDebounce(filters, 300);
|
|
@@ -299,12 +303,12 @@ function FilteredTable() {
|
|
|
299
303
|
<div>
|
|
300
304
|
<input
|
|
301
305
|
value={filters.search}
|
|
302
|
-
onChange={(e) => setFilters(f => ({ ...f, search: e.target.value }))}
|
|
306
|
+
onChange={(e) => setFilters((f) => ({ ...f, search: e.target.value }))}
|
|
303
307
|
placeholder="Search..."
|
|
304
308
|
/>
|
|
305
309
|
<select
|
|
306
310
|
value={filters.status}
|
|
307
|
-
onChange={(e) => setFilters(f => ({ ...f, status: e.target.value }))}
|
|
311
|
+
onChange={(e) => setFilters((f) => ({ ...f, status: e.target.value }))}
|
|
308
312
|
>
|
|
309
313
|
<option value="all">All</option>
|
|
310
314
|
<option value="active">Active</option>
|
|
@@ -322,11 +326,11 @@ function FilteredTable() {
|
|
|
322
326
|
This hook is written in TypeScript with full generic support.
|
|
323
327
|
|
|
324
328
|
```tsx
|
|
325
|
-
import { useDebounce, type UseDebounceOptions } from
|
|
329
|
+
import { useDebounce, type UseDebounceOptions } from "@usefy/use-debounce";
|
|
326
330
|
|
|
327
331
|
// Generic type inference
|
|
328
|
-
const debouncedString = useDebounce(
|
|
329
|
-
const debouncedNumber = useDebounce(42, 300);
|
|
332
|
+
const debouncedString = useDebounce("hello", 300); // string
|
|
333
|
+
const debouncedNumber = useDebounce(42, 300); // number
|
|
330
334
|
const debouncedObject = useDebounce({ x: 1 }, 300); // { x: number }
|
|
331
335
|
|
|
332
336
|
// Explicit generic type
|
|
@@ -345,12 +349,12 @@ This package maintains comprehensive test coverage to ensure reliability and sta
|
|
|
345
349
|
|
|
346
350
|
### Test Coverage
|
|
347
351
|
|
|
348
|
-
| Category
|
|
349
|
-
|
|
352
|
+
| Category | Coverage |
|
|
353
|
+
| ---------- | -------------- |
|
|
350
354
|
| Statements | 91.01% (81/89) |
|
|
351
|
-
| Branches
|
|
352
|
-
| Functions
|
|
353
|
-
| Lines
|
|
355
|
+
| Branches | 90.47% (38/42) |
|
|
356
|
+
| Functions | 66.66% (14/21) |
|
|
357
|
+
| Lines | 93.02% (80/86) |
|
|
354
358
|
|
|
355
359
|
### Test Categories
|
|
356
360
|
|
|
@@ -402,14 +406,14 @@ pnpm test --coverage
|
|
|
402
406
|
|
|
403
407
|
Explore other hooks in the **@usefy** collection:
|
|
404
408
|
|
|
405
|
-
| Package
|
|
406
|
-
|
|
409
|
+
| Package | Description |
|
|
410
|
+
| ------------------------------------------------------------------------------------------ | ------------------------------------- |
|
|
407
411
|
| [@usefy/use-debounce-callback](https://www.npmjs.com/package/@usefy/use-debounce-callback) | Debounced callbacks with cancel/flush |
|
|
408
|
-
| [@usefy/use-throttle](https://www.npmjs.com/package/@usefy/use-throttle)
|
|
409
|
-
| [@usefy/use-throttle-callback](https://www.npmjs.com/package/@usefy/use-throttle-callback) | Throttled callbacks
|
|
410
|
-
| [@usefy/use-toggle](https://www.npmjs.com/package/@usefy/use-toggle)
|
|
411
|
-
| [@usefy/use-counter](https://www.npmjs.com/package/@usefy/use-counter)
|
|
412
|
-
| [@usefy/use-click-any-where](https://www.npmjs.com/package/@usefy/use-click-any-where)
|
|
412
|
+
| [@usefy/use-throttle](https://www.npmjs.com/package/@usefy/use-throttle) | Value throttling |
|
|
413
|
+
| [@usefy/use-throttle-callback](https://www.npmjs.com/package/@usefy/use-throttle-callback) | Throttled callbacks |
|
|
414
|
+
| [@usefy/use-toggle](https://www.npmjs.com/package/@usefy/use-toggle) | Boolean state management |
|
|
415
|
+
| [@usefy/use-counter](https://www.npmjs.com/package/@usefy/use-counter) | Counter state management |
|
|
416
|
+
| [@usefy/use-click-any-where](https://www.npmjs.com/package/@usefy/use-click-any-where) | Global click detection |
|
|
413
417
|
|
|
414
418
|
---
|
|
415
419
|
|
package/package.json
CHANGED