reactives-hooks 0.1.0 → 0.1.1
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 +384 -46
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,70 +41,408 @@ function App() {
|
|
|
41
41
|
## Hooks
|
|
42
42
|
|
|
43
43
|
### State
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
|
|
45
|
+
#### [`useToggle`](./docs/state/useToggle.md)
|
|
46
|
+
|
|
47
|
+
Toggles a boolean value.
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
const [isOpen, toggle] = useToggle(false)
|
|
51
|
+
toggle() // true
|
|
52
|
+
toggle(false) // false
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### [`useBoolean`](./docs/state/useBoolean.md)
|
|
56
|
+
|
|
57
|
+
Provides explicit boolean control methods.
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
const { value: isOpen, setTrue: open, setFalse: close, toggle } = useBoolean(false)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### [`useCounter`](./docs/state/useCounter.md)
|
|
64
|
+
|
|
65
|
+
Numeric counter with min/max bounds.
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
const [count, { increment, decrement, reset }] = useCounter(0, { min: 0, max: 100 })
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### [`useMap`](./docs/state/useMap.md)
|
|
72
|
+
|
|
73
|
+
Manages Map data structure state.
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
const [map, { set, delete: remove, clear }] = useMap<string, string>([['key', 'value']])
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### [`useSet`](./docs/state/useSet.md)
|
|
80
|
+
|
|
81
|
+
Manages Set data structure state.
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
const [set, { add, toggle, clear }] = useSet<string>(['react'])
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
#### [`usePrevious`](./docs/state/usePrevious.md)
|
|
88
|
+
|
|
89
|
+
Returns the value from the previous render.
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
const prevCount = usePrevious(count) // undefined on first render
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### [`useStateHistory`](./docs/state/useStateHistory.md)
|
|
96
|
+
|
|
97
|
+
State management with undo/redo support.
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
const { value, set, undo, redo, canUndo, canRedo } = useStateHistory('')
|
|
101
|
+
```
|
|
51
102
|
|
|
52
103
|
### Storage
|
|
53
|
-
|
|
54
|
-
|
|
104
|
+
|
|
105
|
+
#### [`useLocalStorage`](./docs/storage/useLocalStorage.md)
|
|
106
|
+
|
|
107
|
+
Manages state synced with localStorage.
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
const [theme, setTheme, removeTheme] = useLocalStorage('theme', 'light')
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### [`useSessionStorage`](./docs/storage/useSessionStorage.md)
|
|
114
|
+
|
|
115
|
+
Manages state synced with sessionStorage.
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
const [draft, setDraft, clearDraft] = useSessionStorage('form-draft', '')
|
|
119
|
+
```
|
|
55
120
|
|
|
56
121
|
### DOM
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
122
|
+
|
|
123
|
+
#### [`useEventListener`](./docs/dom/useEventListener.md)
|
|
124
|
+
|
|
125
|
+
Registers a type-safe event listener.
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
useEventListener('keydown', (e) => console.log(e.key))
|
|
129
|
+
useEventListener('click', handler, elementRef)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### [`useClickOutside`](./docs/dom/useClickOutside.md)
|
|
133
|
+
|
|
134
|
+
Detects clicks outside an element.
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
const ref = useClickOutside<HTMLDivElement>(() => setIsOpen(false))
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### [`useHover`](./docs/dom/useHover.md)
|
|
141
|
+
|
|
142
|
+
Tracks hover state of an element.
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
const [hoverRef, isHovered] = useHover<HTMLDivElement>()
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### [`useIntersectionObserver`](./docs/dom/useIntersectionObserver.md)
|
|
149
|
+
|
|
150
|
+
Detects viewport intersection of an element.
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
const { ref, isIntersecting } = useIntersectionObserver({ freezeOnceVisible: true })
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
#### [`useResizeObserver`](./docs/dom/useResizeObserver.md)
|
|
157
|
+
|
|
158
|
+
Detects element size changes.
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
const [ref, { width, height }] = useResizeObserver<HTMLDivElement>()
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
#### [`useMutationObserver`](./docs/dom/useMutationObserver.md)
|
|
165
|
+
|
|
166
|
+
Detects DOM mutations.
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
const ref = useMutationObserver((mutations) => { /* ... */ })
|
|
170
|
+
```
|
|
63
171
|
|
|
64
172
|
### Sensor
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
173
|
+
|
|
174
|
+
#### [`useMediaQuery`](./docs/sensor/useMediaQuery.md)
|
|
175
|
+
|
|
176
|
+
Tracks CSS media query match state.
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
const isMobile = useMediaQuery('(max-width: 768px)')
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
#### [`useWindowSize`](./docs/sensor/useWindowSize.md)
|
|
183
|
+
|
|
184
|
+
Tracks browser window dimensions.
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
const { width, height } = useWindowSize()
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### [`useScroll`](./docs/sensor/useScroll.md)
|
|
191
|
+
|
|
192
|
+
Tracks scroll position.
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
const { x, y } = useScroll()
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
#### [`useMouse`](./docs/sensor/useMouse.md)
|
|
199
|
+
|
|
200
|
+
Tracks mouse cursor position.
|
|
201
|
+
|
|
202
|
+
```tsx
|
|
203
|
+
const { x, y } = useMouse()
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
#### [`useNetwork`](./docs/sensor/useNetwork.md)
|
|
207
|
+
|
|
208
|
+
Tracks network status and connection info.
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
const { online, effectiveType, downlink } = useNetwork()
|
|
212
|
+
```
|
|
70
213
|
|
|
71
214
|
### Performance
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
215
|
+
|
|
216
|
+
#### [`useDebounceValue`](./docs/performance/useDebounceValue.md)
|
|
217
|
+
|
|
218
|
+
Debounces a value update.
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
const debouncedSearch = useDebounceValue(search, 300)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
#### [`useDebounceCallback`](./docs/performance/useDebounceCallback.md)
|
|
225
|
+
|
|
226
|
+
Debounces a callback function.
|
|
227
|
+
|
|
228
|
+
```tsx
|
|
229
|
+
const save = useDebounceCallback((content: string) => api.save(content), 1000)
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
#### [`useThrottleValue`](./docs/performance/useThrottleValue.md)
|
|
233
|
+
|
|
234
|
+
Throttles a value update.
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
const throttledY = useThrottleValue(scrollY, 100)
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
#### [`useThrottleCallback`](./docs/performance/useThrottleCallback.md)
|
|
241
|
+
|
|
242
|
+
Throttles a callback function.
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
const track = useThrottleCallback((x, y) => analytics.track(x, y), 200)
|
|
246
|
+
```
|
|
76
247
|
|
|
77
248
|
### Lifecycle
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
249
|
+
|
|
250
|
+
#### [`useMount`](./docs/lifecycle/useMount.md)
|
|
251
|
+
|
|
252
|
+
Runs a callback on component mount.
|
|
253
|
+
|
|
254
|
+
```tsx
|
|
255
|
+
useMount(() => analytics.pageView())
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
#### [`useUnmount`](./docs/lifecycle/useUnmount.md)
|
|
259
|
+
|
|
260
|
+
Runs a callback on component unmount.
|
|
261
|
+
|
|
262
|
+
```tsx
|
|
263
|
+
useUnmount(() => clearInterval(timer))
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
#### [`useUpdateEffect`](./docs/lifecycle/useUpdateEffect.md)
|
|
267
|
+
|
|
268
|
+
A useEffect that skips the first render.
|
|
269
|
+
|
|
270
|
+
```tsx
|
|
271
|
+
useUpdateEffect(() => {
|
|
272
|
+
fetchResults(query)
|
|
273
|
+
}, [query])
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
#### [`useIsMounted`](./docs/lifecycle/useIsMounted.md)
|
|
277
|
+
|
|
278
|
+
Checks component mount status.
|
|
279
|
+
|
|
280
|
+
```tsx
|
|
281
|
+
const isMounted = useIsMounted()
|
|
282
|
+
if (isMounted()) setData(result)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
#### [`useIsomorphicLayoutEffect`](./docs/lifecycle/useIsomorphicLayoutEffect.md)
|
|
286
|
+
|
|
287
|
+
SSR-safe useLayoutEffect.
|
|
288
|
+
|
|
289
|
+
```tsx
|
|
290
|
+
useIsomorphicLayoutEffect(() => {
|
|
291
|
+
// useLayoutEffect on browser, useEffect on server
|
|
292
|
+
}, [])
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
#### [`useDeepCompareEffect`](./docs/lifecycle/useDeepCompareEffect.md)
|
|
296
|
+
|
|
297
|
+
A useEffect with deep comparison of dependencies.
|
|
298
|
+
|
|
299
|
+
```tsx
|
|
300
|
+
useDeepCompareEffect(() => {
|
|
301
|
+
fetchUsers(filters)
|
|
302
|
+
}, [filters])
|
|
303
|
+
```
|
|
84
304
|
|
|
85
305
|
### UI
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
306
|
+
|
|
307
|
+
#### [`useScrollLock`](./docs/ui/useScrollLock.md)
|
|
308
|
+
|
|
309
|
+
Locks body scroll.
|
|
310
|
+
|
|
311
|
+
```tsx
|
|
312
|
+
useScrollLock(isModalOpen)
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### [`useDarkMode`](./docs/ui/useDarkMode.md)
|
|
316
|
+
|
|
317
|
+
Manages dark mode with system preference support.
|
|
318
|
+
|
|
319
|
+
```tsx
|
|
320
|
+
const { isDark, theme, setTheme, toggle } = useDarkMode('system')
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
#### [`useFullscreen`](./docs/ui/useFullscreen.md)
|
|
324
|
+
|
|
325
|
+
Wraps the Fullscreen API.
|
|
326
|
+
|
|
327
|
+
```tsx
|
|
328
|
+
const { ref, isFullscreen, toggle } = useFullscreen()
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
#### [`useCopyToClipboard`](./docs/ui/useCopyToClipboard.md)
|
|
332
|
+
|
|
333
|
+
Copies text to the clipboard.
|
|
334
|
+
|
|
335
|
+
```tsx
|
|
336
|
+
const { copiedText, copy } = useCopyToClipboard()
|
|
337
|
+
await copy('Hello!')
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
#### [`useHotkeys`](./docs/ui/useHotkeys.md)
|
|
341
|
+
|
|
342
|
+
Binds keyboard shortcuts.
|
|
343
|
+
|
|
344
|
+
```tsx
|
|
345
|
+
useHotkeys('ctrl+s', () => save())
|
|
346
|
+
useHotkeys('cmd+k', () => openPalette())
|
|
347
|
+
```
|
|
91
348
|
|
|
92
349
|
### Data
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
350
|
+
|
|
351
|
+
#### [`useAsync`](./docs/data/useAsync.md)
|
|
352
|
+
|
|
353
|
+
Wraps an async function with loading/error states.
|
|
354
|
+
|
|
355
|
+
```tsx
|
|
356
|
+
const { data, loading, error, execute } = useAsync(() => fetchUser(id))
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
#### [`useFetch`](./docs/data/useFetch.md)
|
|
360
|
+
|
|
361
|
+
Fetch wrapper with abort support.
|
|
362
|
+
|
|
363
|
+
```tsx
|
|
364
|
+
const { data, loading, error, refetch } = useFetch<Post[]>('/api/posts')
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
#### [`useInfiniteScroll`](./docs/data/useInfiniteScroll.md)
|
|
368
|
+
|
|
369
|
+
IntersectionObserver-based infinite scroll.
|
|
370
|
+
|
|
371
|
+
```tsx
|
|
372
|
+
const { sentinelRef, loading } = useInfiniteScroll(loadMore, hasMore)
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
#### [`usePagination`](./docs/data/usePagination.md)
|
|
376
|
+
|
|
377
|
+
Manages pagination logic.
|
|
378
|
+
|
|
379
|
+
```tsx
|
|
380
|
+
const { page, totalPages, next, prev, hasNext } = usePagination({
|
|
381
|
+
totalItems: 100,
|
|
382
|
+
pageSize: 20,
|
|
383
|
+
})
|
|
384
|
+
```
|
|
97
385
|
|
|
98
386
|
### Next.js (`reactives-hooks/next`)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
-
|
|
387
|
+
|
|
388
|
+
#### [`useQueryParams`](./docs/next/useQueryParams.md)
|
|
389
|
+
|
|
390
|
+
Manages type-safe URL query parameters.
|
|
391
|
+
|
|
392
|
+
```tsx
|
|
393
|
+
const { params, set, delete: remove } = useQueryParams<{ q: string; sort: string }>()
|
|
394
|
+
set('q', 'react')
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
#### [`useRouteChange`](./docs/next/useRouteChange.md)
|
|
398
|
+
|
|
399
|
+
Detects route changes.
|
|
400
|
+
|
|
401
|
+
```tsx
|
|
402
|
+
useRouteChange({ onComplete: (url) => analytics.pageView(url) })
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
#### [`useSafeAction`](./docs/next/useSafeAction.md)
|
|
406
|
+
|
|
407
|
+
Safely executes Server Actions.
|
|
408
|
+
|
|
409
|
+
```tsx
|
|
410
|
+
const { execute, data, loading, error } = useSafeAction(createPost)
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
#### [`useIsServer`](./docs/next/useIsServer.md)
|
|
414
|
+
|
|
415
|
+
Detects server/client rendering environment.
|
|
416
|
+
|
|
417
|
+
```tsx
|
|
418
|
+
const isServer = useIsServer() // true on server, false on client
|
|
419
|
+
```
|
|
103
420
|
|
|
104
421
|
### Utils (`reactives-hooks/utils`)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
422
|
+
|
|
423
|
+
#### [`cn`](./docs/utils/cn.md)
|
|
424
|
+
|
|
425
|
+
Conditionally merges Tailwind CSS classes.
|
|
426
|
+
|
|
427
|
+
```tsx
|
|
428
|
+
cn('px-2 py-1', isActive && 'bg-blue-500', className)
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
#### [`formatDate`](./docs/utils/formatDate.md)
|
|
432
|
+
|
|
433
|
+
Formats a date with locale support.
|
|
434
|
+
|
|
435
|
+
```tsx
|
|
436
|
+
formatDate(new Date(), { year: 'numeric', month: 'long', day: 'numeric' }, 'ko-KR')
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
#### [`sleep`](./docs/utils/sleep.md)
|
|
440
|
+
|
|
441
|
+
Promise-based delay function.
|
|
442
|
+
|
|
443
|
+
```tsx
|
|
444
|
+
await sleep(1000) // Wait 1 second
|
|
445
|
+
```
|
|
108
446
|
|
|
109
447
|
## License
|
|
110
448
|
|