@websolutespa/bom-mixer-hooks 1.8.10 → 1.9.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @websolutespa/bom-mixer-hooks
2
2
 
3
+ ## 1.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Modified: usePagination
8
+ - Added: useMetaData
9
+
10
+ ## 1.8.11
11
+
12
+ ### Patch Changes
13
+
14
+ - Modified: usePage typings
15
+ - Updated dependencies
16
+ - Updated dependencies
17
+ - @websolutespa/bom-mixer-store@1.8.11
18
+ - @websolutespa/bom-mixer-models@1.8.18
19
+
3
20
  ## 1.8.10
4
21
 
5
22
  ### Patch Changes
package/README.md CHANGED
@@ -9,3 +9,433 @@ Mixer Hooks module of the [BOM Repository](https://github.com/websolutespa/bom)
9
9
  ---
10
10
 
11
11
  ##### *this library is for internal usage and not production ready*
12
+
13
+ # @websolutespa/bom-mixer-hooks Documentation
14
+
15
+ A collection of React hooks for building modern web applications.
16
+
17
+ ## Table of Contents
18
+
19
+ - [Installation](#installation)
20
+ - [API and Networking](#api-and-networking)
21
+ - [UI and Layout](#ui-and-layout)
22
+ - [Form and Input](#form-and-input)
23
+ - [Internationalization](#internationalization)
24
+ - [Scroll and Viewport](#scroll-and-viewport)
25
+ - [State Management](#state-management)
26
+ - [Performance](#performance)
27
+ - [Event Handling](#event-handling)
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ npm install @websolutespa/bom-mixer-hooks
33
+ ```
34
+
35
+ ## API and Networking
36
+
37
+ ### useApi
38
+
39
+ Hook for making RESTful API calls.
40
+
41
+ ```typescript
42
+ import { useApi } from '@websolutespa/bom-mixer-hooks';
43
+
44
+ function MyComponent() {
45
+ const api = useApi();
46
+
47
+ const fetchData = async () => {
48
+ try {
49
+ // GET request
50
+ const data = await api.get('/endpoint');
51
+
52
+ // POST request with payload
53
+ const response = await api.post('/endpoint', {
54
+ name: 'John',
55
+ });
56
+
57
+ // PUT request
58
+ await api.put('/endpoint/1', {
59
+ updated: true,
60
+ });
61
+
62
+ // DELETE request
63
+ await api.delete('/endpoint/1');
64
+ } catch (error) {
65
+ console.error('API error:', error);
66
+ }
67
+ };
68
+ }
69
+ ```
70
+
71
+ ### useCollectionApi
72
+
73
+ Specialized version of useApi for data collections.
74
+
75
+ ```typescript
76
+ import { useCollectionApi, useCollectionApiGet } from '@websolutespa/bom-mixer-hooks';
77
+
78
+ function MyCollection() {
79
+ const [data, loading, error] = useCollectionApiGet('/collection', {
80
+ where: { status: 'active' }
81
+ });
82
+
83
+ if (loading) return <Loading />;
84
+ if (error) return <Error message={error.message} />;
85
+
86
+ return (
87
+ <div>
88
+ {data.map(item => (
89
+ <Item key={item.id} {...item} />
90
+ ))}
91
+ </div>
92
+ );
93
+ }
94
+ ```
95
+
96
+ ## UI and Layout
97
+
98
+ ### useLayout
99
+
100
+ Manages the global application layout.
101
+
102
+ ```typescript
103
+ import { useLayout } from '@websolutespa/bom-mixer-hooks';
104
+
105
+ function Header() {
106
+ const layout = useLayout();
107
+
108
+ return (
109
+ <header>
110
+ <nav>
111
+ {layout.menu.main.items.map(item => (
112
+ <MenuItem key={item.id} {...item} />
113
+ ))}
114
+ </nav>
115
+ </header>
116
+ );
117
+ }
118
+ ```
119
+
120
+ ### useDrawer
121
+
122
+ Manages drawer/sidebar state.
123
+
124
+ ```typescript
125
+ import { useDrawer } from '@websolutespa/bom-mixer-hooks';
126
+
127
+ function Sidebar() {
128
+ const [drawer, openDrawer, closeDrawer] = useDrawer();
129
+
130
+ return (
131
+ <>
132
+ <button onClick={() => openDrawer('main')}>Open Menu</button>
133
+
134
+ <div className={`drawer ${drawer === 'main' ? 'open' : ''}`}>
135
+ <button onClick={closeDrawer}>Close</button>
136
+ {/* Drawer content */}
137
+ </div>
138
+ </>
139
+ );
140
+ }
141
+ ```
142
+
143
+ ### useBreakpoint
144
+
145
+ Handles responsive breakpoints.
146
+
147
+ ```typescript
148
+ import { useBreakpoint } from '@websolutespa/bom-mixer-hooks';
149
+
150
+ function ResponsiveComponent() {
151
+ const breakpoint = useBreakpoint();
152
+
153
+ return (
154
+ <div>
155
+ {breakpoint.key === 'xs' && <MobileView />}
156
+ {breakpoint.key === 'md' && <TabletView />}
157
+ {breakpoint.key === 'lg' && <DesktopView />}
158
+ </div>
159
+ );
160
+ }
161
+ ```
162
+
163
+ ## Form and Input
164
+
165
+ ### useAutosizeTextArea
166
+
167
+ Automatically adjusts textarea height.
168
+
169
+ ```typescript
170
+ import { useAutosizeTextArea } from '@websolutespa/bom-mixer-hooks';
171
+
172
+ function AutoResizingTextarea() {
173
+ const [value, setValue] = useState('');
174
+ const textAreaRef = useRef<HTMLTextAreaElement>(null);
175
+
176
+ useAutosizeTextArea(textAreaRef.current, value);
177
+
178
+ return (
179
+ <textarea
180
+ ref={textAreaRef}
181
+ value={value}
182
+ onChange={(e) => setValue(e.target.value)}
183
+ />
184
+ );
185
+ }
186
+ ```
187
+
188
+ ### useFocusTrap
189
+
190
+ Keeps focus within an element (useful for modals).
191
+
192
+ ```typescript
193
+ import { useFocusTrap } from '@websolutespa/bom-mixer-hooks';
194
+
195
+ function Modal() {
196
+ const modalRef = useRef(null);
197
+ const [isTrapped, setIsTrapped] = useFocusTrap(modalRef);
198
+
199
+ useEffect(() => {
200
+ setIsTrapped(true);
201
+ return () => setIsTrapped(false);
202
+ }, []);
203
+
204
+ return (
205
+ <div ref={modalRef}>
206
+ <input type="text" />
207
+ <button>Action</button>
208
+ <button>Close</button>
209
+ </div>
210
+ );
211
+ }
212
+ ```
213
+
214
+ ## Internationalization
215
+
216
+ ### useLabel
217
+
218
+ Manages translations.
219
+
220
+ ```typescript
221
+ import { useLabel } from '@websolutespa/bom-mixer-hooks';
222
+
223
+ function Translated() {
224
+ const label = useLabel();
225
+
226
+ return (
227
+ <div>
228
+ <h1>{label('welcome.title')}</h1>
229
+ <p>{label('welcome.description', { name: 'John' })}</p>
230
+ </div>
231
+ );
232
+ }
233
+ ```
234
+
235
+ ### useCurrency
236
+
237
+ Formats monetary values.
238
+
239
+ ```typescript
240
+ import { useCurrency } from '@websolutespa/bom-mixer-hooks';
241
+
242
+ function PriceDisplay() {
243
+ const formatCurrency = useCurrency('EUR', 'en-US');
244
+
245
+ return (
246
+ <div>
247
+ <p>Price: {formatCurrency(29.99)}</p> {/* Outputs: €29.99 */}
248
+ </div>
249
+ );
250
+ }
251
+ ```
252
+
253
+ ## Scroll and Viewport
254
+
255
+ ### useIntersectionObserver
256
+
257
+ Observes when elements enter the viewport.
258
+
259
+ ```typescript
260
+ import { useIntersectionObserver } from '@websolutespa/bom-mixer-hooks';
261
+
262
+ function LazyImage() {
263
+ const ref = useRef(null);
264
+ const isVisible = useIntersectionObserver(ref, {
265
+ threshold: 0.1
266
+ });
267
+
268
+ return (
269
+ <div ref={ref}>
270
+ {isVisible && <img src="heavy-image.jpg" alt="Lazy loaded" />}
271
+ </div>
272
+ );
273
+ }
274
+ ```
275
+
276
+ ### useScrollTo
277
+
278
+ Manages smooth scrolling to elements.
279
+
280
+ ```typescript
281
+ import { useScrollTo } from '@websolutespa/bom-mixer-hooks';
282
+
283
+ function ScrollableContent() {
284
+ const scrollTo = useScrollTo(80); // 80px offset
285
+
286
+ return (
287
+ <nav>
288
+ <a href="#section1" onClick={scrollTo}>Go to Section 1</a>
289
+ <div id="section1">
290
+ {/* Content */}
291
+ </div>
292
+ </nav>
293
+ );
294
+ }
295
+ ```
296
+
297
+ ## State Management
298
+
299
+ ### useCurrentState
300
+
301
+ Manages state with current reference.
302
+
303
+ ```typescript
304
+ import { useCurrentState } from '@websolutespa/bom-mixer-hooks';
305
+
306
+ function StateManager() {
307
+ const [value, setValue, valueRef] = useCurrentState(0);
308
+
309
+ useEffect(() => {
310
+ // valueRef.current is always up to date
311
+ const interval = setInterval(() => {
312
+ console.log('Current value:', valueRef.current);
313
+ }, 1000);
314
+
315
+ return () => clearInterval(interval);
316
+ }, []);
317
+
318
+ return (
319
+ <button onClick={() => setValue(v => v + 1)}>
320
+ Count: {value}
321
+ </button>
322
+ );
323
+ }
324
+ ```
325
+
326
+ ## Performance
327
+
328
+ ### useDebounce
329
+
330
+ Delays function execution.
331
+
332
+ ```typescript
333
+ import { useDebounce } from '@websolutespa/bom-mixer-hooks';
334
+
335
+ function SearchInput() {
336
+ const [value, setValue] = useState('');
337
+ const debouncedValue = useDebounce(value, 500);
338
+
339
+ useEffect(() => {
340
+ // API call only after 500ms from last input
341
+ searchAPI(debouncedValue);
342
+ }, [debouncedValue]);
343
+
344
+ return (
345
+ <input
346
+ type="text"
347
+ value={value}
348
+ onChange={(e) => setValue(e.target.value)}
349
+ />
350
+ );
351
+ }
352
+ ```
353
+
354
+ ## Event Handling
355
+
356
+ ### useEventListener
357
+
358
+ Safely manages event listeners.
359
+
360
+ ```typescript
361
+ import { useEventListener } from '@websolutespa/bom-mixer-hooks';
362
+
363
+ function EventHandler() {
364
+ const handleKeyPress = (e: KeyboardEvent) => {
365
+ if (e.key === 'Escape') {
366
+ // Handle escape key
367
+ }
368
+ };
369
+
370
+ useEventListener('keydown', handleKeyPress);
371
+
372
+ return <div>Press ESC to trigger action</div>;
373
+ }
374
+ ```
375
+
376
+ ## Best Practices
377
+
378
+ 1. **Hook Composition**
379
+
380
+ ```typescript
381
+ function ComplexComponent() {
382
+ const layout = useLayout();
383
+ const breakpoint = useBreakpoint();
384
+ const [drawer] = useDrawer();
385
+
386
+ // Combine hooks for advanced functionality
387
+ const isMobileMenuOpen = breakpoint.key === 'xs' && drawer === 'menu';
388
+
389
+ return (
390
+ <div className={isMobileMenuOpen ? 'mobile-menu' : ''}>
391
+ {/* Component content */}
392
+ </div>
393
+ );
394
+ }
395
+ ```
396
+
397
+ 2. **Error Handling**
398
+
399
+ ```typescript
400
+ function DataFetcher() {
401
+ const [data, loading, error] = useCollectionApiGet('/api/data');
402
+
403
+ if (error) {
404
+ return <ErrorBoundary error={error} />;
405
+ }
406
+
407
+ if (loading) {
408
+ return <LoadingSpinner />;
409
+ }
410
+
411
+ return <DataDisplay data={data} />;
412
+ }
413
+ ```
414
+
415
+ 3. **Performance Optimization**
416
+
417
+ ```typescript
418
+ function OptimizedComponent() {
419
+ const debouncedSearch = useDebounceCallback((term: string) => {
420
+ searchAPI(term);
421
+ }, 300);
422
+
423
+ const intersectionRef = useRef(null);
424
+ const isVisible = useIntersectionObserver(intersectionRef);
425
+
426
+ // Load heavy content only when visible
427
+ return (
428
+ <div ref={intersectionRef}>
429
+ {isVisible && <HeavyContent />}
430
+ </div>
431
+ );
432
+ }
433
+ ```
434
+
435
+ ## Contributing
436
+
437
+ Please read our [Contributing Guide](CONTRIBUTING.md) before submitting a Pull Request to the project.
438
+
439
+ ## License
440
+
441
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.