react-hook-toolkit 1.0.15 → 1.0.16

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 CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  **react-hook-toolkit** package offers a comprehensive set of hooks to simplify React development. It includes hooks for managing state, handling API requests, optimizing performance, and improving user interactions. Key features include data fetching, form handling, local storage management, debouncing/throttling, window size tracking, event listeners, and more. These hooks are designed to enhance productivity by providing reusable, easy-to-use solutions for common tasks.
3
3
 
4
- **Note : This package is written in TypeScript and offers full support for all modern browsers.**
4
+ **Note : This lightweight and type-safe package is written in TypeScript and offers full support for all hooks across all modern browsers.**
5
5
 
6
6
  ### Installation
7
7
 
@@ -23,12 +23,15 @@ pnpm add react-hook-toolkit
23
23
 
24
24
  ### **Authors**
25
25
 
26
- ![NPM](https://img.shields.io/badge/Author-Shivaji_(React_Expert)_&_Shyamal_(JS_Expert)-red)   ![npm](https://img.shields.io/npm/v/react-hook-toolkit?color=1C939D)   ![npm](https://img.shields.io/npm/dt/react-hook-toolkit)   ![NPM](https://img.shields.io/npm/l/react-hook-toolkit)   ![NPM Unpacked Size](https://img.shields.io/npm/unpacked-size/react-hook-toolkit)
26
+ ![NPM](https://img.shields.io/badge/Author-NPM_Teams-red)   ![npm](https://img.shields.io/npm/v/react-hook-toolkit?color=1C939D)   ![npm](https://img.shields.io/npm/dt/react-hook-toolkit)   ![NPM](https://img.shields.io/npm/l/react-hook-toolkit)   ![NPM Unpacked Size](https://img.shields.io/npm/unpacked-size/react-hook-toolkit)
27
+
27
28
 
28
29
  ## Features
29
30
  Here's the properly structured documentation with clear purpose explanations:
30
31
 
31
- ---------------------------------------------------- **Custom Hooks** ------------------------------------------------
32
+ ------------------------------------------ **Custom Hooks** ------------------------------------------------
33
+
34
+ ### 🌐 **API / Async**
32
35
 
33
36
  📌 **useAxios**
34
37
  A custom hook for making API requests using Axios. It manages request states (`loading`, `error`, `data`) and provides a function (`makeRequest`) to initiate a request.
@@ -39,67 +42,30 @@ useEffect(() => {
39
42
  makeRequest('/users', 'GET');
40
43
  }, []);
41
44
  ```
42
-
43
- 📌 **useDrawer**
44
- A custom hook for managing application drawer state. It provides control over drawer visibility (`drawerOpen`) and active menu selection (`currentMainMenu`), with methods to toggle these states.
45
-
46
- ```tsx
47
- const {
48
- drawerOpen,
49
- currentMainMenu,
50
- openDrawer,
51
- closeDrawer,
52
- setCurrentMainMenu
53
- } = useDrawer();
54
-
55
- // Example usage:
56
- <button onClick={openDrawer}>Open Menu</button>
57
- <button onClick={() => setCurrentMainMenu('settings')}>
58
- Show Settings
59
- </button>
60
- ```
61
-
62
45
  ---
63
-
64
- 📌 **useAdvReducer**
65
- A custom reducer function that takes an `initialState` and an object of actions, returning a new state based on the action type.
46
+ 📌 **useFetch**
47
+ Provides an easy way to fetch data with hooks, managing loading, data, and error states.
66
48
 
67
49
  ```ts
68
- const reducer = useAdvReducer(initialState, {
69
- increment: (state) => ({ count: state.count + 1 }),
70
- });
71
- const [state, dispatch] = useReducer(reducer, initialState);
50
+ const { data, loading, error } = useFetch('/api/data');
72
51
  ```
73
-
74
52
  ---
75
-
76
- 📌 **useFetch**
77
- Fetches data from a given URL and manages the loading, error, and data states.
53
+ 📌 **useFetchRetry**
54
+ Performs an HTTP request with retry logic, retrying a specified number of times upon failure before returning an error.
78
55
 
79
56
  ```ts
80
- const { data, loading, error } = useFetch<User[]>('/api/users');
57
+ const { data, loading, error } = useFetchRetry('/api/user', { method: 'GET' }, 3);
81
58
  ```
82
-
83
59
  ---
84
-
85
- 📌 **useLocalStorage**
86
- A hook to persist state in `localStorage`. It initializes state from `localStorage` and updates it whenever the value changes.
60
+ 📌 **useAsync**
61
+ Handles the state of an asynchronous function, including loading, success, and error states, with the ability to trigger the execution of the async operation.
87
62
 
88
63
  ```ts
89
- const [token, setToken] = useLocalStorage('authToken', '');
90
- ```
91
-
92
- ---
93
-
94
- 📌 **useToggle**
95
- A simple boolean toggle hook that returns a state and a function to toggle its value.
64
+ const { execute, status, value, error } = useAsync(fetchUser);
96
65
 
97
- ```ts
98
- const [isOpen, toggle] = useToggle(false);
66
+ execute(); // ➝ runs the async function
99
67
  ```
100
-
101
68
  ---
102
-
103
69
  📌 **useDebounce**
104
70
  Delays updating the state until after a specified delay, useful for preventing frequent updates (e.g., handling user input).
105
71
 
@@ -108,44 +74,44 @@ const debouncedSearch = useDebounce(searchText, 500);
108
74
  ```
109
75
 
110
76
  ---
111
-
112
- 📌 **useThrottle**
113
- Limits how often a value updates within a given time interval, useful for performance optimization.
77
+ 📌 **useDebouncedCallback**
78
+ Delays the execution of a callback function until after a specified delay, resetting the delay on each call to prevent frequent execution.
114
79
 
115
80
  ```ts
116
- const throttledScroll = useThrottle(scrollValue, 300);
117
- ```
81
+ const debounced = useDebouncedCallback(() => search(input), 300);
118
82
 
83
+ input.onChange = debounced;
84
+ ```
119
85
  ---
120
-
121
- 📌 **usePrevious**
122
- Returns the previous value of a state or prop.
86
+ 📌 **useDebouncedValue**
87
+ Returns a debounced version of a value.
123
88
 
124
89
  ```ts
125
- const prevValue = usePrevious(currentValue);
90
+ const debouncedValue = useDebouncedValue(value, 300);
126
91
  ```
127
-
128
92
  ---
129
-
130
- 📌 **useMediaQuery**
131
- Checks if a media query matches the current viewport size and updates the state accordingly.
93
+ 📌 **useThrottle**
94
+ Limits how often a value updates within a given time interval, useful for performance optimization.
132
95
 
133
96
  ```ts
134
- const isMobile = useMediaQuery('(max-width: 768px)');
97
+ const throttledScroll = useThrottle(scrollValue, 300);
135
98
  ```
136
99
 
137
100
  ---
138
-
139
- 📌 **useClipboard**
140
- Copies text to the clipboard and provides a state to indicate if copying was successful.
101
+ 📌 **useDelay**
102
+ Delays the update of a value for a specified amount of time before reflecting it in the state.
141
103
 
142
104
  ```ts
143
- const [copied, copyToClipboard] = useClipboard();
144
- copyToClipboard('Text to copy');
105
+ const delayedValue = useDelay(value, 500);
145
106
  ```
146
-
147
107
  ---
108
+ 📌 **useTimer**
109
+ Starts a countdown timer that updates the time every second, returning the current time and any errors.
148
110
 
111
+ ```ts
112
+ const { time, error } = useTimer(60); // starts from 60 and counts down
113
+ ```
114
+ ---
149
115
  📌 **useInterval**
150
116
  Runs a callback function at a specified time interval and clears it when the delay is null or the component unmounts.
151
117
 
@@ -154,45 +120,7 @@ useInterval(() => {
154
120
  console.log('Tick');
155
121
  }, 1000);
156
122
  ```
157
-
158
- ---
159
-
160
- 📌 **useWindowSize**
161
- Tracks the width and height of the browser window and updates when resized.
162
-
163
- ```ts
164
- const { width, height } = useWindowSize();
165
- ```
166
-
167
- ---
168
-
169
- 📌 **useKeyPress**
170
- Detects whether a specific key is being pressed or released.
171
-
172
- ```ts
173
- const isEnterPressed = useKeyPress('Enter');
174
- ```
175
-
176
- ---
177
-
178
- 📌 **useOnlineStatus**
179
- Monitors the user's network connection status (online/offline).
180
-
181
- ```ts
182
- const isOnline = useOnlineStatus();
183
- ```
184
-
185
- ---
186
-
187
- 📌 **useScrollPosition**
188
- Tracks the horizontal (x) and vertical (y) scroll positions of the window.
189
-
190
- ```ts
191
- const { x, y } = useScrollPosition();
192
- ```
193
-
194
123
  ---
195
-
196
124
  📌 **useTimeout**
197
125
  Executes a function after a specified delay and cleans up automatically when dependencies change.
198
126
 
@@ -204,14 +132,7 @@ useTimeout(() => {
204
132
 
205
133
  ---
206
134
 
207
- 📌 **useDarkMode**
208
- Detects and toggles dark mode based on the user's system preference.
209
-
210
- ```ts
211
- const [isDarkMode, toggleDarkMode] = useDarkMode();
212
- ```
213
-
214
- ---
135
+ ### 📝 **Form / Validation**
215
136
 
216
137
  📌 **useForm**
217
138
  Manages form state, handles input changes, and performs validation using provided validators.
@@ -226,285 +147,315 @@ validate({
226
147
  email: (val) => (!val.includes('@') ? 'Invalid email' : null),
227
148
  });
228
149
  ```
229
-
230
150
  ---
231
-
232
- 📌 **useArray**
233
- Provides an array state with helper functions to manipulate it, including setting, adding, removing by index, and clearing elements.
151
+ 📌 **useFormSubmit**
152
+ Handles form submission with loading/error states and success callbacks.
234
153
 
235
154
  ```ts
236
- const { array, set, push, removeByIndex, clear } = useArray([1, 2, 3]);
155
+ const { submit, isLoading, error } = useFormSubmit(apiCall, {
156
+ onSuccess: (data) => console.log('Saved!', data)
157
+ });
237
158
 
238
- push(4); // ➝ [1, 2, 3, 4]
239
- removeByIndex(1); // ➝ [1, 3, 4]
240
- clear(); // ➝ []
159
+ // Example
160
+ submit(formData);
241
161
  ```
242
-
243
162
  ---
244
-
245
- 📌 **useStepper**
246
- Manages step-based navigation by keeping track of the current step index and providing functions to move forward, backward, and reset.
163
+ 📌 **useSmartForm**
164
+ Complete form management with validation, submission, and state handling.
247
165
 
248
166
  ```ts
249
- const { activeStep, handleNext, handleBack, handleReset, isFirstStep, isLastStep } = useStepper(5);
167
+ const { register, handleSubmit, errors } = useSmartForm({
168
+ initialValues,
169
+ validationSchema,
170
+ onSubmit: (data) => console.log(data)
171
+ });
250
172
 
251
- handleNext(); // ➝ advances step
252
- handleBack(); // ➝ goes back
253
- handleReset(); // ➝ step 0
173
+ // Example
174
+ <input {...register('email') />
175
+ <button onClick={handleSubmit}>Save</button>
254
176
  ```
255
-
256
177
  ---
257
-
258
- 📌 **useTimeoutFn**
259
- Executes a callback function after a specified delay and provides functions to reset or clear the timeout.
178
+ 📌 **useCrossFieldValidation**
179
+ Handles complex validation rules that depend on multiple fields.
260
180
 
261
181
  ```ts
262
- const { reset, clear } = useTimeoutFn(() => doSomething(), 1000);
182
+ const { errors, validate } = useCrossFieldValidation({
183
+ rules: {
184
+ password: (val, { confirmPassword }) => val === confirmPassword,
185
+ },
186
+ initialValues
187
+ });
263
188
 
264
- reset(); // ➝ restarts timeout
265
- clear(); // clears timeout
189
+ // Example
190
+ validate('password', 'secret123', { confirmPassword: 'secret123' });
266
191
  ```
267
192
 
268
193
  ---
269
194
 
270
- 📌 **useDebouncedCallback**
271
- Delays the execution of a callback function until after a specified delay, resetting the delay on each call to prevent frequent execution.
195
+ 📌 **useFieldArray**
196
+ Manages dynamic arrays of form fields with add/remove/reorder operations.
272
197
 
273
198
  ```ts
274
- const debounced = useDebouncedCallback(() => search(input), 300);
199
+ const { fields, append, remove, move } = useFieldArray(initialItems);
275
200
 
276
- input.onChange = debounced;
201
+ // Example
202
+ append({ name: '', email: '' });
203
+ remove(0); // Remove first item
204
+ move(1, 0); // Move second item to first position
277
205
  ```
278
-
279
206
  ---
280
-
281
- 📌 **useScrollLock**
282
- Locks or unlocks scrolling on the webpage when the `lock` parameter changes.
207
+ 📌 **useFormWizard**
208
+ Manages multi-step forms with navigation between steps.
283
209
 
284
210
  ```ts
285
- useScrollLock(true); // disables body scroll
211
+ const { currentStep, next, prev, goto } = useFormWizard(steps.length);
212
+
213
+ // Example
214
+ next(); // Move to next step
215
+ goto(3); // Jump to step 4
286
216
  ```
287
217
 
288
218
  ---
289
-
290
- 📌 **useResizeObserver**
291
- Observes and returns the dimensions of an HTML element using the `ResizeObserver` API.
219
+ 📌 **usePersistedForm**
220
+ Automatically persists form state to localStorage/sessionStorage and restores it on page reload.
292
221
 
293
222
  ```ts
294
- const size = useResizeObserver(ref);
223
+ const { values, setField, reset } = usePersistedForm('form-key', initialValues);
295
224
 
296
- // size = { width: 200, height: 100 }
225
+ // Example
226
+ setField('username', 'john_doe'); // Auto-saves to storage
227
+ reset(); // Clears storage
297
228
  ```
298
229
 
230
+
299
231
  ---
300
232
 
301
- 📌 **useMousePosition**
302
- Tracks the user's mouse position in real-time and returns the coordinates.
233
+ ### 🎯 **Event / Interaction**
234
+
235
+ 📌 **useEventListener**
236
+ Listens for a specified event on an element or window, and triggers the handler function when the event is fired. It ensures proper cleanup when the component is unmounted.
303
237
 
304
238
  ```ts
305
- const { x, y } = useMousePosition();
239
+ useEventListener('resize', (e) => {
240
+ console.log('Window resized');
241
+ });
306
242
  ```
307
-
308
243
  ---
309
-
310
- 📌 **useScrollDirection**
311
- Determines whether the user is scrolling up or down based on window scroll position changes.
244
+ 📌 **useEventListeners**
245
+ Simplifies adding/removing event listeners.
312
246
 
313
247
  ```ts
314
- const direction = useScrollDirection(); // ➝ 'up' | 'down'
315
- ```
248
+ useEventListeners({
249
+ click: handleClick,
250
+ resize: handleResize
251
+ });
316
252
 
253
+ // Example
254
+ useEventListeners({
255
+ keydown: (e) => console.log(e.key)
256
+ });
257
+ ```
317
258
  ---
318
-
319
- 📌 **useImageLoader**
320
- Loads an image and provides `loaded` and `error` states to track its loading status.
259
+ 📌 **useKeyPress**
260
+ Detects whether a specific key is being pressed or released.
321
261
 
322
262
  ```ts
323
- const { loaded, error } = useImageLoader('/logo.png');
263
+ const isEnterPressed = useKeyPress('Enter');
324
264
  ```
325
-
326
265
  ---
327
-
328
- 📌 **usePersistedState**
329
- Stores and retrieves state from `localStorage` to persist data across page reloads.
266
+ 📌 **useLongPress**
267
+ Detects long press gestures.
330
268
 
331
269
  ```ts
332
- const [theme, setTheme] = usePersistedState('theme', 'light');
333
- ```
270
+ const handlers = useLongPress(() => console.log('Long pressed!'), {
271
+ threshold: 1000
272
+ });
334
273
 
274
+ // Example
275
+ <button {...handlers}>Hold me</button>
276
+ ```
335
277
  ---
336
-
337
- 📌 **useReducedMotion**
338
- Detects if the user has enabled the "Reduce Motion" accessibility setting in their system preferences.
278
+ 📌 **useTouch**
279
+ Tracks touch events on a given DOM element, returning the touch positions for `touchstart`, `touchmove`, and `touchend`.
339
280
 
340
281
  ```ts
341
- const prefersReduced = useReducedMotion(); // ➝ true | false
342
- ```
282
+ const ref = useRef(null);
283
+ const {
284
+ touchStart,
285
+ touchMove,
286
+ touchEnd
287
+ } = useTouch(ref);
343
288
 
289
+ <div ref={ref}>Swipe here</div>
290
+ ```
344
291
  ---
345
-
346
- 📌 **useCookie**
347
- Manages cookies by providing functions to get, set, and delete a specific cookie by its key.
292
+ 📌 **useIdle**
293
+ Detects when user becomes inactive.
348
294
 
349
295
  ```ts
350
- const [token, setToken, deleteToken] = useCookie('token');
296
+ const isIdle = useIdle(30000); // 30s timeout
351
297
 
352
- setToken('abc123');
353
- deleteToken();
298
+ // Example
299
+ {isIdle && <ScreenSaver />}
354
300
  ```
355
-
356
301
  ---
357
-
358
- 📌 **useFetchRetry**
359
- Performs an HTTP request with retry logic, retrying a specified number of times upon failure before returning an error.
302
+ 📌 **useDragReorder**
303
+ Enables drag-and-drop reordering of lists.
360
304
 
361
305
  ```ts
362
- const { data, loading, error } = useFetchRetry('/api/user', { method: 'GET' }, 3);
363
- ```
364
-
365
- ---
366
-
367
- 📌 **useDelay**
368
- Delays the update of a value for a specified amount of time before reflecting it in the state.
306
+ const { items, dragStart, dragOver, drop } = useDragReorder(initialItems);
369
307
 
370
- ```ts
371
- const delayedValue = useDelay(value, 500);
308
+ // Example
309
+ <div
310
+ draggable
311
+ onDragStart={() => dragStart(index)}
312
+ onDragOver={() => dragOver(index)}
313
+ onDrop={drop}
314
+ />
372
315
  ```
373
316
 
374
317
  ---
375
318
 
376
- 📌 **useVisibilityChange**
377
- Tracks the visibility state of the document and returns whether the page is currently visible or hidden.
378
-
379
- ```ts
380
- const isVisible = useVisibilityChange(); // ➝ true | false
381
- ```
319
+ ### 📦 **State / Logic**
382
320
 
383
- ---
384
321
 
385
- 📌 **useDebouncedValue**
386
- Debounces a value to avoid immediate changes, returning the delayed value after a specified delay.
322
+ 📌 **useToggle**
323
+ A simple boolean toggle hook that returns a state and a function to toggle its value.
387
324
 
388
325
  ```ts
389
- const debouncedSearch = useDebouncedValue(input, 300);
326
+ const [isOpen, toggle] = useToggle(false);
390
327
  ```
391
-
392
328
  ---
393
-
394
- 📌 **useAsync**
395
- Handles the state of an asynchronous function, including loading, success, and error states, with the ability to trigger the execution of the async operation.
329
+ 📌 **useArray**
330
+ Provides an array state with helper functions to manipulate it, including setting, adding, removing by index, and clearing elements.
396
331
 
397
332
  ```ts
398
- const { execute, status, value, error } = useAsync(fetchUser);
333
+ const { array, set, push, removeByIndex, clear } = useArray([1, 2, 3]);
399
334
 
400
- execute(); // ➝ runs the async function
335
+ push(4); // ➝ [1, 2, 3, 4]
336
+ removeByIndex(1); // ➝ [1, 3, 4]
337
+ clear(); // ➝ []
401
338
  ```
402
-
403
339
  ---
404
-
405
- 📌 **useScript**
406
- Dynamically loads an external script, managing its loading, ready, and error states, and optionally removes the script on unmount.
340
+ 📌 **useStepper**
341
+ Manages step-based navigation by keeping track of the current step index and providing functions to move forward, backward, and reset.
407
342
 
408
343
  ```ts
409
- const status = useScript('https://js.stripe.com/v3');
344
+ const { activeStep, handleNext, handleBack, handleReset, isFirstStep, isLastStep } = useStepper(5);
410
345
 
411
- // status 'loading' | 'ready' | 'error'
346
+ handleNext(); // ➝ advances step
347
+ handleBack(); // ➝ goes back
348
+ handleReset(); // ➝ step 0
412
349
  ```
413
350
 
414
351
  ---
415
-
416
- 📌 **useIndexedDB**
417
- Fetches data from an IndexedDB store, handling errors and updating the state with the fetched data.
352
+ 📌 **useUndo**
353
+ Provides undo/redo functionality for state changes.
418
354
 
419
355
  ```ts
420
- const { data, error } = useIndexedDB<MyType>('myDB', 'myStore');
421
- ```
422
-
423
- ---
424
-
425
- 📌 **useGeoLocation**
426
- Retrieves the user's current geographic location and returns it along with any error encountered.
356
+ const { state, setState, undo, redo } = useUndo(initialState);
427
357
 
428
- ```ts
429
- const { position, error } = useGeoLocation();
358
+ // Example
359
+ setState({ items: [...] });
360
+ undo(); // Reverts to previous state
430
361
  ```
431
-
432
362
  ---
433
-
434
- 📌 **useTimer**
435
- Starts a countdown timer that updates the time every second, returning the current time and any errors.
363
+ 📌 **useAdvReducer**
364
+ A custom reducer function that takes an `initialState` and an object of actions, returning a new state based on the action type.
436
365
 
437
366
  ```ts
438
- const { time, error } = useTimer(60); // starts from 60 and counts down
367
+ const reducer = useAdvReducer(initialState, {
368
+ increment: (state) => ({ count: state.count + 1 }),
369
+ });
370
+ const [state, dispatch] = useReducer(reducer, initialState);
439
371
  ```
440
-
441
372
  ---
442
-
443
373
  📌 **useIsMounted**
444
374
  Tracks whether the component is mounted or unmounted, returning a boolean value indicating the component's mount status.
445
375
 
446
376
  ```ts
447
377
  const isMounted = useIsMounted();
448
378
  ```
449
-
450
379
  ---
451
-
452
- 📌 **useCss**
453
- Dynamically applies custom CSS to the document and removes it when the component unmounts, handling any errors during the process.
380
+ 📌 **useIsFirstRender**
381
+ Returns true only on component's first render.
454
382
 
455
383
  ```ts
456
- const { error } = useCss('body { background: #f5f5f5; }');
457
- ```
384
+ const isFirst = useIsFirstRender();
458
385
 
386
+ // Example
387
+ useEffect(() => {
388
+ if (!isFirst) console.log('Updated!');
389
+ }, [deps]);
390
+ ```
459
391
  ---
392
+ 📌 **usePrevious**
393
+ Tracks the previous value of a state or prop.
460
394
 
461
- 📌 **useSpeak**
462
- Converts text to speech using the Web Speech API, allowing the text to be spoken and handling errors.
463
395
  ```ts
464
- const { speak, error } = useSpeak('Hello world!');
465
- speak();
396
+ const previousValue = usePrevious(currentValue);
466
397
  ```
398
+ ---
399
+ 📌 **useUpdateEffect**
400
+ Executes a side effect on updates after the initial render, skipping the effect during the first render to avoid unnecessary executions.
467
401
 
402
+ ```ts
403
+ useUpdateEffect(() => {
404
+ console.log("This runs only on updates.");
405
+ }, [value]);
406
+ ```
468
407
  ---
469
408
 
470
- 📌 **useCountUp**
471
- Animates a counter that counts up from 0 to a target value within a specified duration, returning the current count and any errors.
409
+ 📌 **useList**
410
+ Manages array state with utility methods.
472
411
 
473
412
  ```ts
474
- const { count, error } = useCountUp(100, 5000); // counts up to 100 in 5s
413
+ const { list, push, remove, update } = useList(initialItems);
414
+
415
+ // Example
416
+ push(newItem);
417
+ remove(0); // Remove first item
475
418
  ```
476
419
 
477
420
  ---
478
421
 
479
- 📌 **useCountDown**
480
- Counts down from a specified start value to zero, updating every second and returning the current count and any errors.
422
+ ### 🧭 **Browser / Storage**
423
+
424
+ 📌 **useLocalStorage**
425
+ A hook to persist state in `localStorage`. It initializes state from `localStorage` and updates it whenever the value changes.
481
426
 
482
427
  ```ts
483
- const { count, error } = useCountDown(10); // counts down from 10
428
+ const [token, setToken] = useLocalStorage('authToken', '');
484
429
  ```
485
-
486
430
  ---
487
-
488
- 📌 **useBattery**
489
- Monitors the battery status of the device, including level, charging status, and remaining charging or discharging time.
431
+ 📌 **useSessionStorage**
432
+ Stores and retrieves data from the `sessionStorage` API, persisting the data during the session. It provides a getter and setter for session-based data.
490
433
 
491
434
  ```ts
492
- const { level, charging, supported, loading, chargingTime, dischargingTime } = useBattery();
435
+ const [value, setValue] = useSessionStorage("myKey", "default");
436
+
437
+ setValue("newValue");
438
+ console.log(value);
493
439
  ```
494
440
 
495
441
  ---
496
-
497
- 📌 **useEventListener**
498
- Listens for a specified event on an element or window, and triggers the handler function when the event is fired. It ensures proper cleanup when the component is unmounted.
442
+ 📌 **useCookie**
443
+ Manages cookies by providing functions to get, set, and delete a specific cookie by its key.
499
444
 
500
445
  ```ts
501
- useEventListener('resize', (e) => {
502
- console.log('Window resized');
503
- });
504
- ```
446
+ const [token, setToken, deleteToken] = useCookie('token');
505
447
 
448
+ setToken('abc123');
449
+ deleteToken();
450
+ ```
506
451
  ---
452
+ 📌 **usePersistedState**
453
+ Stores and retrieves state from `localStorage` to persist data across page reloads.
507
454
 
455
+ ```ts
456
+ const [theme, setTheme] = usePersistedState('theme', 'light');
457
+ ```
458
+ ---
508
459
  📌 **useHistory**
509
460
  Provides methods to navigate the browser history, including pushing and replacing history states, as well as moving back and forward in the history stack.
510
461
 
@@ -525,332 +476,217 @@ goForward();
525
476
  ```
526
477
 
527
478
  ---
528
-
529
- 📌 **usePreferredLanguage**
530
- Retrieves the user's preferred language and languages from the browser, and checks if the browser supports the language APIs.
479
+ 📌 **useHistoryState**
480
+ Manages state history with undo/redo capabilities.
531
481
 
532
482
  ```ts
533
- const {
534
- language,
535
- languages,
536
- isSupported
537
- } = usePreferredLanguage();
483
+ const { state, setState, undo, redo } = useHistoryState(initialState);
538
484
 
539
- console.log(language); // e.g., "en-US"
485
+ // Example
486
+ setState({...});
487
+ undo(); // Reverts change
540
488
  ```
541
-
542
489
  ---
543
-
544
- 📌 **useSessionStorage**
545
- Stores and retrieves data from the `sessionStorage` API, persisting the data during the session. It provides a getter and setter for session-based data.
490
+ 📌 **useVisibilityChange**
491
+ Tracks the visibility state of the document and returns whether the page is currently visible or hidden.
546
492
 
547
493
  ```ts
548
- const [value, setValue] = useSessionStorage("myKey", "default");
549
-
550
- setValue("newValue");
551
- console.log(value);
494
+ const isVisible = useVisibilityChange(); // ➝ true | false
552
495
  ```
553
-
554
496
  ---
555
-
556
- 📌 **useSound**
557
- Controls the playback of an audio file, including play, pause, and stop functionalities, while also managing the audio volume and handling any errors.
497
+ 📌 **useDarkMode**
498
+ Detects and manages dark mode preferences in the browser.
558
499
 
559
500
  ```ts
560
- const {
561
- play,
562
- pause,
563
- stop,
564
- setVolume,
565
- isPlaying,
566
- error
567
- } = useSound("/sound.mp3");
568
-
569
- play();
570
- pause();
571
- stop();
572
- setVolume(0.5);
501
+ const [isDarkMode, toggleDarkMode] = useDarkMode();
573
502
  ```
574
-
575
503
  ---
576
-
577
- 📌 **useTouch**
578
- Tracks touch events on a given DOM element, returning the touch positions for `touchstart`, `touchmove`, and `touchend`.
504
+ 📌 **usePreferredLanguage**
505
+ Detects the preferred language set in the browser.
579
506
 
580
507
  ```ts
581
- const ref = useRef(null);
582
- const {
583
- touchStart,
584
- touchMove,
585
- touchEnd
586
- } = useTouch(ref);
587
-
588
- <div ref={ref}>Swipe here</div>
508
+ const language = usePreferredLanguage();
589
509
  ```
590
-
591
510
  ---
592
-
593
- 📌 **useUpdateEffect**
594
- Executes a side effect on updates after the initial render, skipping the effect during the first render to avoid unnecessary executions.
511
+ 📌 **useIndexedDB**
512
+ Provides a hook to interact with IndexedDB in the browser, enabling persistent client-side storage.
595
513
 
596
514
  ```ts
597
- useUpdateEffect(() => {
598
- console.log("This runs only on updates.");
599
- }, [value]);
515
+ const { data, setData } = useIndexedDB('dbName');
600
516
  ```
601
-
602
517
  ---
603
518
 
604
- 📌 **usePersistedForm**
605
- Automatically persists form state to localStorage/sessionStorage and restores it on page reload.
519
+ ### 🧱 **DOM / UI**
606
520
 
607
- ```ts
608
- const { values, setField, reset } = usePersistedForm('form-key', initialValues);
521
+ 📌 **useMediaQuery**
522
+ Checks if a media query condition matches the current viewport, useful for responsive design.
609
523
 
610
- // Example
611
- setField('username', 'john_doe'); // Auto-saves to storage
612
- reset(); // Clears storage
524
+ ```ts
525
+ const isMobile = useMediaQuery('(max-width: 768px)');
613
526
  ```
614
-
615
527
  ---
616
-
617
- 📌 **useCrossFieldValidation**
618
- Handles complex validation rules that depend on multiple fields.
528
+ 📌 **useWindowSize**
529
+ Returns the current window size (width and height).
619
530
 
620
531
  ```ts
621
- const { errors, validate } = useCrossFieldValidation({
622
- rules: {
623
- password: (val, { confirmPassword }) => val === confirmPassword,
624
- },
625
- initialValues
626
- });
627
-
628
- // Example
629
- validate('password', 'secret123', { confirmPassword: 'secret123' });
532
+ const { width, height } = useWindowSize();
630
533
  ```
631
-
632
534
  ---
633
-
634
- 📌 **useFieldArray**
635
- Manages dynamic arrays of form fields with add/remove/reorder operations.
535
+ 📌 **useResizeObserver**
536
+ Observes and returns the dimensions of an HTML element using the `ResizeObserver` API.
636
537
 
637
538
  ```ts
638
- const { fields, append, remove, move } = useFieldArray(initialItems);
539
+ const size = useResizeObserver(ref);
639
540
 
640
- // Example
641
- append({ name: '', email: '' });
642
- remove(0); // Remove first item
643
- move(1, 0); // Move second item to first position
541
+ // size = { width: 200, height: 100 }
644
542
  ```
645
-
646
543
  ---
647
-
648
- 📌 **useFormSubmit**
649
- Handles form submission with loading/error states and success callbacks.
544
+ 📌 **useScrollPosition**
545
+ Tracks the horizontal (x) and vertical (y) scroll positions of the window.
650
546
 
651
547
  ```ts
652
- const { submit, isLoading, error } = useFormSubmit(apiCall, {
653
- onSuccess: (data) => console.log('Saved!', data)
654
- });
655
-
656
- // Example
657
- submit(formData);
548
+ const { x, y } = useScrollPosition();
658
549
  ```
659
-
660
550
  ---
661
-
662
- 📌 **useSmartForm**
663
- Complete form management with validation, submission, and state handling.
551
+ 📌 **useScrollDirection**
552
+ Determines whether the user is scrolling up or down based on window scroll position changes.
664
553
 
665
554
  ```ts
666
- const { register, handleSubmit, errors } = useSmartForm({
667
- initialValues,
668
- validationSchema,
669
- onSubmit: (data) => console.log(data)
670
- });
671
-
672
- // Example
673
- <input {...register('email') />
674
- <button onClick={handleSubmit}>Save</button>
555
+ const direction = useScrollDirection(); // 'up' | 'down'
675
556
  ```
676
557
 
677
- ---
678
-
679
- 📌 **useUndo**
680
- Provides undo/redo functionality for state changes.
558
+ 📌 **useScrollLock**
559
+ Locks or unlocks scrolling on the page.
681
560
 
682
561
  ```ts
683
- const { state, setState, undo, redo } = useUndo(initialState);
684
-
685
- // Example
686
- setState({ items: [...] });
687
- undo(); // Reverts to previous state
562
+ useScrollLock(true); // Lock scrolling
563
+ useScrollLock(false); // Unlock scrolling
688
564
  ```
689
-
690
565
  ---
691
-
692
- 📌 **useFormWizard**
693
- Manages multi-step forms with navigation between steps.
566
+ 📌 **useLockBodyScroll**
567
+ Prevents scrolling on the body element, useful for modals or off-canvas menus.
694
568
 
695
569
  ```ts
696
- const { currentStep, next, prev, goto } = useFormWizard(steps.length);
697
-
698
- // Example
699
- next(); // Move to next step
700
- goto(3); // Jump to step 4
570
+ useLockBodyScroll(true);
701
571
  ```
702
-
703
572
  ---
704
-
705
- 📌 **useWebSocket**
706
- Manages WebSocket connections with auto-reconnect.
573
+ 📌 **useCss**
574
+ Allows injecting dynamic CSS rules into the document.
707
575
 
708
576
  ```ts
709
- const { send, message, status } = useWebSocket('ws://api.example.com');
710
-
711
- // Example
712
- send(JSON.stringify({ action: 'ping' }));
577
+ useCss('.class { color: red; }');
713
578
  ```
714
-
715
579
  ---
716
-
717
- 📌 **useDragReorder**
718
- Enables drag-and-drop reordering of lists.
580
+ 📌 **useReducedMotion**
581
+ Detects whether the user has reduced motion settings in their OS preferences.
719
582
 
720
583
  ```ts
721
- const { items, dragStart, dragOver, drop } = useDragReorder(initialItems);
722
-
723
- // Example
724
- <div
725
- draggable
726
- onDragStart={() => dragStart(index)}
727
- onDragOver={() => dragOver(index)}
728
- onDrop={drop}
729
- />
584
+ const prefersReducedMotion = useReducedMotion();
730
585
  ```
731
-
732
586
  ---
733
-
734
- 📌 **useInfiniteScroll**
735
- Implements infinite scroll pagination.
587
+ 📌 **useImageLoader**
588
+ Provides a way to load and display images in a way that improves performance and loading behavior.
736
589
 
737
590
  ```ts
738
- const { items, loadMore, isLoading } = useInfiniteScroll(fetchCallback);
739
-
740
- // Example
741
- <div onScroll={loadMore}>...</div>
591
+ const { isLoading, image } = useImageLoader('imageURL');
742
592
  ```
743
593
 
744
594
  ---
745
595
 
746
- 📌 **useEventListeners**
747
- Simplifies adding/removing event listeners.
596
+ ### 📱 **Device / Sensors**
748
597
 
749
- ```ts
750
- useEventListeners({
751
- click: handleClick,
752
- resize: handleResize
753
- });
598
+ 📌 **useBattery**
599
+ Monitors the battery status of the device, including level, charging status, and remaining charging or discharging time.
754
600
 
755
- // Example
756
- useEventListeners({
757
- keydown: (e) => console.log(e.key)
758
- });
601
+ ```ts
602
+ const { level, charging, supported, loading, chargingTime, dischargingTime } = useBattery();
759
603
  ```
760
-
761
604
  ---
762
-
763
- 📌 **useHistoryState**
764
- Manages state history with undo/redo capabilities.
605
+ 📌 **useGeoLocation**
606
+ Retrieves the user's current geographic location and returns it along with any error encountered.
765
607
 
766
608
  ```ts
767
- const { state, setState, undo, redo } = useHistoryState(initialState);
768
-
769
- // Example
770
- setState({...});
771
- undo(); // Reverts change
609
+ const { position, error } = useGeoLocation();
772
610
  ```
773
-
774
611
  ---
775
-
776
- 📌 **useIdle**
777
- Detects when user becomes inactive.
612
+ 📌 **useMousePosition**
613
+ Tracks the user's mouse position in real-time and returns the coordinates.
778
614
 
779
615
  ```ts
780
- const isIdle = useIdle(30000); // 30s timeout
781
-
782
- // Example
783
- {isIdle && <ScreenSaver />}
616
+ const { x, y } = useMousePosition();
784
617
  ```
785
618
 
786
619
  ---
787
-
788
- 📌 **useIsFirstRender**
789
- Returns true only on component's first render.
620
+ 📌 **useOnlineStatus**
621
+ Monitors the user's network connection status (online/offline).
790
622
 
791
623
  ```ts
792
- const isFirst = useIsFirstRender();
793
-
794
- // Example
795
- useEffect(() => {
796
- if (!isFirst) console.log('Updated!');
797
- }, [deps]);
624
+ const isOnline = useOnlineStatus();
798
625
  ```
799
626
 
800
627
  ---
801
628
 
802
- 📌 **useList**
803
- Manages array state with utility methods.
629
+ ### 🎵 **Media / Audio / Visual**
630
+
631
+ 📌 **useSound**
632
+ Controls the playback of an audio file, including play, pause, and stop functionalities, while also managing the audio volume and handling any errors.
804
633
 
805
634
  ```ts
806
- const { list, push, remove, update } = useList(initialItems);
635
+ const {
636
+ play,
637
+ pause,
638
+ stop,
639
+ setVolume,
640
+ isPlaying,
641
+ error
642
+ } = useSound("/sound.mp3");
807
643
 
808
- // Example
809
- push(newItem);
810
- remove(0); // Remove first item
644
+ play();
645
+ pause();
646
+ stop();
647
+ setVolume(0.5);
811
648
  ```
812
-
813
649
  ---
814
-
815
- 📌 **useLockBodyScroll**
816
- Locks scrolling on the document body.
817
-
650
+ 📌 **useSpeak**
651
+ Converts text to speech using the Web Speech API, allowing the text to be spoken and handling errors.
818
652
  ```ts
819
- useLockBodyScroll(true); // Enable lock
653
+ const { speak, error } = useSpeak('Hello world!');
654
+ speak();
655
+ ```
656
+ ---
657
+ 📌 **useCountUp**
658
+ Animates a counter that counts up from 0 to a target value within a specified duration, returning the current count and any errors.
820
659
 
821
- // Example
822
- useLockBodyScroll(modalIsOpen);
660
+ ```ts
661
+ const { count, error } = useCountUp(100, 5000); // counts up to 100 in 5s
823
662
  ```
824
663
 
825
664
  ---
826
-
827
- 📌 **useLongPress**
828
- Detects long press gestures.
665
+ 📌 **useCountDown**
666
+ Counts down from a specified start value to zero, updating every second and returning the current count and any errors.
829
667
 
830
668
  ```ts
831
- const handlers = useLongPress(() => console.log('Long pressed!'), {
832
- threshold: 1000
833
- });
834
-
835
- // Example
836
- <button {...handlers}>Hold me</button>
669
+ const { count, error } = useCountDown(10); // counts down from 10
837
670
  ```
838
671
 
839
672
  ---
840
673
 
841
- 📌 **createOptimizedContext**
842
- Creates optimized React context with selector support.
674
+ ### 🔄 **Networking / Real-time**
675
+
676
+ 📌 **useWebSocket**
677
+ Manages WebSocket connections with auto-reconnect.
843
678
 
844
679
  ```ts
845
- const { Provider, useStore } = createOptimizedContext(initialState);
680
+ const { send, message, status } = useWebSocket('ws://api.example.com');
846
681
 
847
682
  // Example
848
- const user = useStore(state => state.user);
683
+ send(JSON.stringify({ action: 'ping' }));
849
684
  ```
850
-
851
685
  ---
852
686
 
853
- ------------------------------------------------ **Custom Components** --------------------------------------------
687
+ Let me know if you'd like more information or changes!
688
+
689
+ ------------------------------------- **Custom Components** --------------------------------------------
854
690
 
855
691
  ✅ **DynamicLoader**
856
692
  A Higher-Order Component (HOC) that dynamically loads a React component using `React.lazy()` with `Suspense`, while wrapping it in an `ErrorBoundary` to handle potential errors gracefully. It ensures that the component is loaded only when needed, reducing the initial bundle size and improving performance.
@@ -1006,4 +842,4 @@ Displays a skeleton placeholder for a pie chart inside a card layout. Includes a
1006
842
 
1007
843
  **License**
1008
844
 
1009
- [MIT](https://opensource.org/licenses)
845
+ [MIT](https://www.npmjs.com/products/teams) © (2022-2024)
@@ -69,6 +69,19 @@ export declare const useStepper: (totalSteps: number) => {
69
69
  isLastStep: boolean;
70
70
  isProccesing: boolean;
71
71
  setIsProccesing: import("react").Dispatch<import("react").SetStateAction<boolean>>;
72
+ goto: (step: number) => void;
73
+ };
74
+ export declare const useSteps: (totalSteps: number) => {
75
+ activeStep: number;
76
+ handleNext: () => void;
77
+ handleBack: () => void;
78
+ handleReset: () => void;
79
+ goto: (step: number) => void;
80
+ totalSteps: number;
81
+ isFirstStep: boolean;
82
+ isLastStep: boolean;
83
+ isProcessing: boolean;
84
+ setIsProcessing: import("react").Dispatch<import("react").SetStateAction<boolean>>;
72
85
  };
73
86
  export declare function useTimeoutFn(callback: () => void, delay: number | null): {
74
87
  reset: () => void;
@@ -431,6 +431,14 @@ export var useStepper = function (totalSteps) {
431
431
  var handleReset = function () {
432
432
  setActiveStep(0);
433
433
  };
434
+ var goto = function (step) {
435
+ if (step >= 0 && step < totalSteps) {
436
+ setActiveStep(step);
437
+ }
438
+ else {
439
+ console.warn("Step ".concat(step, " is out of bounds (0-").concat(totalSteps - 1, ")"));
440
+ }
441
+ };
434
442
  return {
435
443
  activeStep: activeStep,
436
444
  handleNext: handleNext,
@@ -441,6 +449,44 @@ export var useStepper = function (totalSteps) {
441
449
  isLastStep: activeStep === totalSteps - 1,
442
450
  isProccesing: isProccesing,
443
451
  setIsProccesing: setIsProccesing,
452
+ goto: goto
453
+ };
454
+ };
455
+ export var useSteps = function (totalSteps) {
456
+ var _a = useState(0), activeStep = _a[0], setActiveStep = _a[1];
457
+ var _b = useState(false), isProcessing = _b[0], setIsProcessing = _b[1];
458
+ var handleNext = function () {
459
+ if (activeStep < totalSteps - 1) {
460
+ setActiveStep(function (prev) { return prev + 1; });
461
+ }
462
+ };
463
+ var handleBack = function () {
464
+ if (activeStep > 0) {
465
+ setActiveStep(function (prev) { return prev - 1; });
466
+ }
467
+ };
468
+ var handleReset = function () {
469
+ setActiveStep(0);
470
+ };
471
+ var goto = function (step) {
472
+ if (step >= 0 && step < totalSteps) {
473
+ setActiveStep(step);
474
+ }
475
+ else {
476
+ console.warn("Step ".concat(step, " is out of bounds (0-").concat(totalSteps - 1, ")"));
477
+ }
478
+ };
479
+ return {
480
+ activeStep: activeStep,
481
+ handleNext: handleNext,
482
+ handleBack: handleBack,
483
+ handleReset: handleReset,
484
+ goto: goto,
485
+ totalSteps: totalSteps,
486
+ isFirstStep: activeStep === 0,
487
+ isLastStep: activeStep === totalSteps - 1,
488
+ isProcessing: isProcessing,
489
+ setIsProcessing: setIsProcessing,
444
490
  };
445
491
  };
446
492
  export function useTimeoutFn(callback, delay) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-hook-toolkit",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "description": "Ultimate package for React developers, offering a powerful collection of hooks and components to enhance their development experience.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",