intelliwaketssveltekitv25 1.0.81 → 1.0.83

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.
Files changed (53) hide show
  1. package/INTEGRATION.md +574 -0
  2. package/README.md +199 -45
  3. package/dist/ArrayTable.stories.js +215 -0
  4. package/dist/ArrayTable.svelte +46 -0
  5. package/dist/ArrayTable.svelte.d.ts +44 -0
  6. package/dist/DropDown.stories.d.ts +96 -0
  7. package/dist/DropDown.stories.js +192 -0
  8. package/dist/DropDown.svelte +32 -0
  9. package/dist/DropDown.svelte.d.ts +30 -0
  10. package/dist/InputNumber.stories.d.ts +122 -0
  11. package/dist/InputNumber.stories.js +186 -0
  12. package/dist/InputNumber.svelte +52 -0
  13. package/dist/InputNumber.svelte.d.ts +27 -0
  14. package/dist/Modal.stories.d.ts +114 -0
  15. package/dist/Modal.stories.js +139 -0
  16. package/dist/Modal.svelte +34 -3
  17. package/dist/Modal.svelte.d.ts +35 -3
  18. package/dist/MultiSelect.stories.js +338 -0
  19. package/dist/MultiSelect.svelte +81 -0
  20. package/dist/MultiSelect.svelte.d.ts +38 -0
  21. package/dist/Switch.stories.d.ts +81 -0
  22. package/dist/Switch.stories.js +99 -0
  23. package/dist/Switch.svelte +40 -0
  24. package/dist/Switch.svelte.d.ts +26 -0
  25. package/dist/TextArea.stories.d.ts +180 -0
  26. package/dist/TextArea.stories.js +216 -0
  27. package/dist/TextArea.svelte +32 -0
  28. package/dist/TextArea.svelte.d.ts +24 -0
  29. package/dist/app.css +1 -1
  30. package/docs/DateRangePicker.md +272 -0
  31. package/docs/DisplayHTML.md +249 -0
  32. package/docs/DropDown.md +269 -0
  33. package/docs/Functions.md +796 -0
  34. package/docs/Home.md +109 -0
  35. package/docs/Icon.md +203 -0
  36. package/docs/Importer.md +328 -0
  37. package/docs/ImporterAnalysis.md +249 -0
  38. package/docs/ImporterLoad.md +288 -0
  39. package/docs/InputNumber.md +159 -0
  40. package/docs/Integration.md +215 -0
  41. package/docs/Modal.md +207 -0
  42. package/docs/MultiSelect.md +304 -0
  43. package/docs/Paginator.md +332 -0
  44. package/docs/Search.md +364 -0
  45. package/docs/SlideDown.md +358 -0
  46. package/docs/Svelte-5-Patterns.md +364 -0
  47. package/docs/Switch.md +107 -0
  48. package/docs/TabHeader.md +333 -0
  49. package/docs/TabHref.md +370 -0
  50. package/docs/TextArea.md +118 -0
  51. package/docs/_Sidebar.md +38 -0
  52. package/llms.txt +113 -0
  53. package/package.json +7 -2
@@ -0,0 +1,796 @@
1
+ # Functions - Utility Functions & Svelte Actions
2
+
3
+ **Module:** `Functions.ts`
4
+ **Category:** Core Utilities
5
+ **Use Cases:** Browser utilities, keyboard handling, Svelte use: actions, form enhancement, navigation, data export
6
+
7
+ ## Overview
8
+
9
+ The `Functions` module provides 20+ utility functions and Svelte actions for common browser operations, keyboard navigation, form enhancement, and data manipulation. It includes keyboard constants, GPS capture, clipboard operations, file downloads, and specialized Svelte use: actions for interactive behavior.
10
+
11
+ ## Module Structure
12
+
13
+ ### 1. Keyboard Constants
14
+ ### 2. Browser Utilities
15
+ ### 3. Data Export Functions
16
+ ### 4. Svelte Use Actions
17
+ ### 5. Type Definitions
18
+
19
+ ---
20
+
21
+ ## 1. Keyboard Constants
22
+
23
+ Pre-defined key codes and key strings for event handling.
24
+
25
+ ### Key Code Constants (Legacy)
26
+
27
+ ```typescript
28
+ export const KEY_UP_ARROW = 38
29
+ export const KEY_DOWN_ARROW = 40
30
+ export const KEY_LEFT_ARROW = 37
31
+ export const KEY_RIGHT_ARROW = 39
32
+ export const KEY_SPACE = 32
33
+ export const KEY_ENTER = 13
34
+ export const KEY_TAB = 9
35
+ export const KEY_BACKSPACE = 8
36
+ export const KEY_ESCAPE = 27
37
+ ```
38
+
39
+ ### Key String Constants (Modern)
40
+
41
+ ```typescript
42
+ export const KEY_STRING_ENTER = 'Enter'
43
+ export const KEY_STRING_SPACE = 'Space'
44
+ export const KEY_STRING_DOWN_ARROW = 'ArrowDown'
45
+ export const KEY_STRING_UP_ARROW = 'ArrowUp'
46
+ export const KEY_STRING_LEFT_ARROW = 'ArrowLeft'
47
+ export const KEY_STRING_RIGHT_ARROW = 'ArrowRight'
48
+ export const KEY_STRING_TAB = 'Tab'
49
+ export const KEY_STRING_BACKSPACE = 'Backspace'
50
+ export const KEY_STRING_ESCAPE = 'Escape'
51
+ ```
52
+
53
+ ### IsMetaKey(e: KeyboardEvent): boolean
54
+
55
+ Checks if a keyboard event is a meta/control key (Ctrl, Alt, Meta, or navigation keys).
56
+
57
+ ```svelte
58
+ <script>
59
+ import { IsMetaKey } from 'intelliwaketssveltekitv25'
60
+
61
+ function handleKeyDown(e: KeyboardEvent) {
62
+ if (!IsMetaKey(e)) {
63
+ // Handle regular character input
64
+ }
65
+ }
66
+ </script>
67
+ ```
68
+
69
+ **Returns:** `true` if Ctrl, Alt, Meta, or navigation key (arrows, Enter, Tab, Escape, Backspace)
70
+
71
+ ---
72
+
73
+ ## 2. Browser Utilities
74
+
75
+ ### CaptureGPS(options?: PositionOptions): Promise<GeolocationPosition | null>
76
+
77
+ Captures the device's GPS location using the Geolocation API.
78
+
79
+ ```svelte
80
+ <script>
81
+ import { CaptureGPS } from 'intelliwaketssveltekitv25'
82
+
83
+ async function getLocation() {
84
+ const position = await CaptureGPS({ timeout: 5000 })
85
+ if (position) {
86
+ console.log('Lat:', position.coords.latitude)
87
+ console.log('Lng:', position.coords.longitude)
88
+ }
89
+ }
90
+ </script>
91
+ ```
92
+
93
+ **Parameters:**
94
+ - `options` - Standard PositionOptions (timeout defaults to 10s, maximumAge to 15min)
95
+
96
+ **Returns:** `GeolocationPosition` or `null` if unavailable/denied
97
+
98
+ ---
99
+
100
+ ### CopyRefToClipboard(ref: HTMLElement, tryFormatted?: boolean): boolean
101
+
102
+ Copies an HTML element's content to the clipboard with optional formatting preservation.
103
+
104
+ ```svelte
105
+ <script>
106
+ import { CopyRefToClipboard } from 'intelliwaketssveltekitv25'
107
+
108
+ let contentRef: HTMLElement
109
+
110
+ function copyContent() {
111
+ const success = CopyRefToClipboard(contentRef, true)
112
+ if (success) alert('Copied!')
113
+ }
114
+ </script>
115
+
116
+ <div bind:this={contentRef}>
117
+ <p>Content to copy</p>
118
+ <span class="noCopy">This won't be copied</span>
119
+ <span class="onlyCopy">Only visible when copying</span>
120
+ </div>
121
+ ```
122
+
123
+ **Special Classes:**
124
+ - `.noCopy` - Elements excluded from clipboard
125
+ - `.onlyCopy` - Elements only visible during copy operation
126
+
127
+ **Parameters:**
128
+ - `ref` - HTML element to copy
129
+ - `tryFormatted` - Preserve formatting (default: true)
130
+
131
+ **Returns:** `true` if successful
132
+
133
+ ---
134
+
135
+ ### setSearchParam(key: string, value: string | number | null): Promise<void>
136
+
137
+ Updates a URL search parameter and navigates without page reload.
138
+
139
+ ```svelte
140
+ <script>
141
+ import { setSearchParam } from 'intelliwaketssveltekitv25'
142
+
143
+ function filterByCategory(category: string) {
144
+ setSearchParam('category', category) // ?category=books
145
+ }
146
+
147
+ function clearFilter() {
148
+ setSearchParam('category', null) // Removes ?category
149
+ }
150
+ </script>
151
+ ```
152
+
153
+ **Parameters:**
154
+ - `key` - Search parameter name
155
+ - `value` - Value to set (null/undefined removes the param)
156
+
157
+ **Navigation:** Uses SvelteKit's `goto()` with `replaceState: true`
158
+
159
+ ---
160
+
161
+ ### IsMobileOrTablet(): boolean
162
+
163
+ Detects if the current device is mobile or tablet based on user agent.
164
+
165
+ ```svelte
166
+ <script>
167
+ import { IsMobileOrTablet } from 'intelliwaketssveltekitv25'
168
+
169
+ const isMobile = IsMobileOrTablet()
170
+ </script>
171
+
172
+ {#if isMobile}
173
+ <MobileNav />
174
+ {:else}
175
+ <DesktopNav />
176
+ {/if}
177
+ ```
178
+
179
+ **Detection:** Matches user agents for Android, iOS, BlackBerry, Opera Mini, etc.
180
+
181
+ ---
182
+
183
+ ### DoIDsMatch(a: any, b: any): boolean
184
+
185
+ Compares two objects by value or their `id` properties.
186
+
187
+ ```typescript
188
+ import { DoIDsMatch } from 'intelliwaketssveltekitv25'
189
+
190
+ DoIDsMatch(5, 5) // true
191
+ DoIDsMatch({ id: 5 }, 5) // true
192
+ DoIDsMatch({ id: 5 }, { id: 5 }) // true
193
+ ```
194
+
195
+ **Use Case:** Comparing records from different sources with consistent ID matching
196
+
197
+ ---
198
+
199
+ ### ErrorMessageStack(e: any): TErrorMessageStack
200
+
201
+ Extracts error message and stack trace from various error formats.
202
+
203
+ ```typescript
204
+ import { ErrorMessageStack } from 'intelliwaketssveltekitv25'
205
+
206
+ try {
207
+ throw new Error('Failed')
208
+ } catch (e) {
209
+ const { message, stack } = ErrorMessageStack(e)
210
+ console.error(message) // "Failed"
211
+ console.log(stack) // Full stack trace
212
+ }
213
+ ```
214
+
215
+ **Returns:** `{ message: string, stack: string }`
216
+
217
+ ---
218
+
219
+ ### PageAdvanceSize(pageCount: number): number | null
220
+
221
+ Calculates optimal pagination jump size for large page counts.
222
+
223
+ ```typescript
224
+ import { PageAdvanceSize } from 'intelliwaketssveltekitv25'
225
+
226
+ PageAdvanceSize(500) // 10 (jump by 10 pages)
227
+ PageAdvanceSize(5000) // 100 (jump by 100 pages)
228
+ PageAdvanceSize(30) // null (no jump needed)
229
+ ```
230
+
231
+ **Logic:** Returns powers of 10 based on magnitude (e.g., 10 for hundreds, 100 for thousands)
232
+
233
+ ---
234
+
235
+ ## 3. Data Export Functions
236
+
237
+ ### DownloadBase64Data(fileName: string, base64: string): void
238
+
239
+ Downloads base64-encoded data as a file.
240
+
241
+ ```typescript
242
+ import { DownloadBase64Data } from 'intelliwaketssveltekitv25'
243
+
244
+ const base64Image = 'data:image/png;base64,iVBORw0KG...'
245
+ DownloadBase64Data('chart.png', base64Image)
246
+ ```
247
+
248
+ ---
249
+
250
+ ### DownloadString(filename: string, text: string): void
251
+
252
+ Downloads a string as a text file.
253
+
254
+ ```typescript
255
+ import { DownloadString } from 'intelliwaketssveltekitv25'
256
+
257
+ const csvData = 'Name,Age\nJohn,30\nJane,25'
258
+ DownloadString('users.csv', csvData)
259
+ ```
260
+
261
+ ---
262
+
263
+ ### DownloadURL(url: string, filename?: string): void
264
+
265
+ Triggers download from a URL.
266
+
267
+ ```typescript
268
+ import { DownloadURL } from 'intelliwaketssveltekitv25'
269
+
270
+ DownloadURL('/api/report.pdf', 'monthly-report.pdf')
271
+ ```
272
+
273
+ ---
274
+
275
+ ### TableIDToExcel(tableID: string, fileName?: string, appendDateTime?: boolean): void
276
+
277
+ Exports an HTML table to Excel format.
278
+
279
+ ```svelte
280
+ <script>
281
+ import { TableIDToExcel } from 'intelliwaketssveltekitv25'
282
+ </script>
283
+
284
+ <table id="dataTable">
285
+ <tr><th>Name</th><th>Value</th></tr>
286
+ <tr><td>Item 1</td><td>100</td></tr>
287
+ </table>
288
+
289
+ <button onclick={() => TableIDToExcel('dataTable', 'export')}>
290
+ Export to Excel
291
+ </button>
292
+ ```
293
+
294
+ **Parameters:**
295
+ - `tableID` - HTML table element ID
296
+ - `fileName` - Output filename (defaults to tableID)
297
+ - `appendDateTime` - Add timestamp to filename (default: true)
298
+
299
+ **Output Format:** `.xls` file with timestamp
300
+
301
+ ---
302
+
303
+ ## 4. Svelte Use Actions
304
+
305
+ ### autoFocus(el: HTMLElement, enabled?: boolean)
306
+
307
+ Automatically focuses an element when mounted or when `enabled` changes.
308
+
309
+ ```svelte
310
+ <script>
311
+ import { autoFocus } from 'intelliwaketssveltekitv25'
312
+
313
+ let showInput = $state(false)
314
+ </script>
315
+
316
+ {#if showInput}
317
+ <input use:autoFocus placeholder="Auto-focused" />
318
+ {/if}
319
+ ```
320
+
321
+ **With Conditional Enabling:**
322
+
323
+ ```svelte
324
+ <input use:autoFocus={isEditMode} />
325
+ ```
326
+
327
+ **Features:**
328
+ - Waits for DOM tick and animation frame
329
+ - Cancels if element detaches
330
+ - Respects modal/transition timing
331
+
332
+ ---
333
+
334
+ ### autoGrow(node: HTMLTextAreaElement, value?: string | null)
335
+
336
+ Auto-expands textarea height to fit content, with manual resize detection.
337
+
338
+ ```svelte
339
+ <script>
340
+ import { autoGrow } from 'intelliwaketssveltekitv25'
341
+
342
+ let text = $state('')
343
+ </script>
344
+
345
+ <textarea use:autoGrow bind:value={text} />
346
+ ```
347
+
348
+ **Features:**
349
+ - Dynamically adjusts height based on content
350
+ - Detects manual user resize and locks auto-grow
351
+ - Sets `data-autogrow-locked="true"` when manually resized
352
+ - Prevents scrollbars during auto-growth
353
+
354
+ **Manual Resize Detection:** Once user manually resizes, auto-grow stops permanently
355
+
356
+ ---
357
+
358
+ ### scrollToBottom(el: HTMLElement, toggleUpdate?: any)
359
+
360
+ Scrolls element to bottom on mount or when `toggleUpdate` changes.
361
+
362
+ ```svelte
363
+ <script>
364
+ import { scrollToBottom } from 'intelliwaketssveltekitv25'
365
+
366
+ let messages = $state([])
367
+ </script>
368
+
369
+ <div use:scrollToBottom={messages.length} class="h-96 overflow-y-auto">
370
+ {#each messages as msg}
371
+ <p>{msg}</p>
372
+ {/each}
373
+ </div>
374
+ ```
375
+
376
+ **Use Case:** Chat interfaces, log viewers, real-time feeds
377
+
378
+ ---
379
+
380
+ ### upDownArrows(el: HTMLElement, options?: TUpDownArrowOptions)
381
+
382
+ Adds Up/Down arrow key navigation between elements with ID pattern `{id}_{field}`.
383
+
384
+ ```svelte
385
+ <script>
386
+ import { upDownArrows } from 'intelliwaketssveltekitv25'
387
+
388
+ const items = [{ id: 1 }, { id: 2 }, { id: 3 }]
389
+ </script>
390
+
391
+ {#each items as item}
392
+ <input
393
+ id="{item.id}_name"
394
+ use:upDownArrows={{ list: items }}
395
+ />
396
+ {/each}
397
+ ```
398
+
399
+ **Options:**
400
+ ```typescript
401
+ type TUpDownArrowOptions = {
402
+ preID?: number | string // Override previous ID
403
+ postID?: number | string // Override next ID
404
+ list?: { id: number }[] // Auto-derive pre/post from list
405
+ enterDown?: boolean // Treat Enter as Down arrow
406
+ }
407
+ ```
408
+
409
+ **Behavior:**
410
+ - ↑ focuses previous element (wraps to end)
411
+ - ↓ focuses next element (wraps to start)
412
+ - Enter acts as ↓ if `enterDown: true`
413
+
414
+ **ID Pattern Required:** Element IDs must be `{id}_{fieldName}` (e.g., `1_name`, `2_name`)
415
+
416
+ ---
417
+
418
+ ### nextPrevArrows(el: HTMLElement, options?: TNextPrevArrowsOptions)
419
+
420
+ Adds Left/Right arrow key navigation between fields with ID pattern `{id}_{field}`.
421
+
422
+ ```svelte
423
+ <script>
424
+ import { nextPrevArrows } from 'intelliwaketssveltekitv25'
425
+
426
+ const fields = ['name', 'email', 'phone']
427
+ const items = [{ id: 1 }, { id: 2 }]
428
+ </script>
429
+
430
+ {#each items as item}
431
+ {#each fields as field}
432
+ <input
433
+ id="{item.id}_{field}"
434
+ use:nextPrevArrows={{ fieldList: fields }}
435
+ />
436
+ {/each}
437
+ {/each}
438
+ ```
439
+
440
+ **Options:**
441
+ ```typescript
442
+ type TNextPrevArrowsOptions = {
443
+ preField?: string // Override previous field
444
+ postField?: string // Override next field
445
+ fieldList?: string[] // Auto-derive pre/post from list
446
+ }
447
+ ```
448
+
449
+ **Behavior:**
450
+ - ← focuses previous field (wraps to end)
451
+ - → focuses next field (wraps to start)
452
+
453
+ **Use Case:** Spreadsheet-like navigation, grid editing
454
+
455
+ ---
456
+
457
+ ### textAreaAltEnter(el: HTMLTextAreaElement)
458
+
459
+ Enables Alt+Enter to insert line breaks while Enter submits the form.
460
+
461
+ ```svelte
462
+ <script>
463
+ import { textAreaAltEnter } from 'intelliwaketssveltekitv25'
464
+ </script>
465
+
466
+ <form onsubmit={handleSubmit}>
467
+ <textarea
468
+ use:textAreaAltEnter
469
+ placeholder="Enter submits, Alt+Enter adds line"
470
+ />
471
+ </form>
472
+ ```
473
+
474
+ **Behavior:**
475
+ - **Enter** - Submits parent form
476
+ - **Alt+Enter** - Inserts `\r\n` at cursor
477
+
478
+ **Use Case:** Chat interfaces, comment forms
479
+
480
+ ---
481
+
482
+ ### selectOnFocus(el: HTMLInputElement | HTMLTextAreaElement)
483
+
484
+ Selects all text when input gains focus.
485
+
486
+ ```svelte
487
+ <script>
488
+ import { selectOnFocus } from 'intelliwaketssveltekitv25'
489
+ </script>
490
+
491
+ <input use:selectOnFocus value="Click to select all" />
492
+ ```
493
+
494
+ **Timing:** Waits 50ms after focus to ensure value is rendered
495
+
496
+ **Use Case:** Forms where users typically replace entire value
497
+
498
+ ---
499
+
500
+ ### clickSubmitOnChange(el: HTMLElement)
501
+
502
+ Auto-submits form when any child input changes.
503
+
504
+ ```svelte
505
+ <script>
506
+ import { clickSubmitOnChange } from 'intelliwaketssveltekitv25'
507
+ </script>
508
+
509
+ <form use:clickSubmitOnChange>
510
+ <select>
511
+ <option>Option 1</option>
512
+ <option>Option 2</option>
513
+ </select>
514
+ <button type="submit">Submit</button>
515
+ </form>
516
+ ```
517
+
518
+ **Behavior:**
519
+ - Clicks `<button type="submit">` or first `<button>` in form
520
+ - Falls back to `requestSubmit()` if no button found
521
+ - Prevents double-submission on Enter key
522
+
523
+ ---
524
+
525
+ ### clickSubmitOnFocusOut(el: HTMLElement)
526
+
527
+ Auto-submits form when focus leaves the form.
528
+
529
+ ```svelte
530
+ <form use:clickSubmitOnFocusOut>
531
+ <input placeholder="Auto-saves on blur" />
532
+ </form>
533
+ ```
534
+
535
+ **Use Case:** Inline editing, auto-save forms
536
+
537
+ ---
538
+
539
+ ## 5. Type Definitions
540
+
541
+ ### TUpDownArrowOptions
542
+
543
+ ```typescript
544
+ type TUpDownArrowOptions = {
545
+ preID?: number | string | null
546
+ postID?: number | string | null
547
+ list?: ({ id: number } & Record<string, any>)[]
548
+ enterDown?: boolean
549
+ }
550
+ ```
551
+
552
+ ---
553
+
554
+ ### TNextPrevArrowsOptions
555
+
556
+ ```typescript
557
+ type TNextPrevArrowsOptions = {
558
+ preField?: string | null
559
+ postField?: string | null
560
+ fieldList?: string[]
561
+ }
562
+ ```
563
+
564
+ ---
565
+
566
+ ### TErrorMessageStack
567
+
568
+ ```typescript
569
+ type TErrorMessageStack = {
570
+ message: string
571
+ stack: string
572
+ }
573
+ ```
574
+
575
+ ---
576
+
577
+ ### TInputNumberAttributes
578
+
579
+ ```typescript
580
+ type TInputNumberAttributes = Omit<
581
+ HTMLInputAttributes,
582
+ 'value' | 'this' | 'onchange' | 'use'
583
+ > & {
584
+ value: number | null
585
+ onchange?: (value: number | null) => void
586
+ widthNumbers?: number
587
+ inputClass?: string
588
+ allowNegative?: boolean
589
+ delayChange?: boolean | number | 'blur'
590
+ use?: ActionArray
591
+ thisRef?: HTMLInputElement
592
+ } & TNumberStringOptions
593
+ ```
594
+
595
+ ---
596
+
597
+ ### HandleKeyDownNumerics(event: KeyboardEvent, allowDecimals?: boolean, allowNegative?: boolean)
598
+
599
+ Validates numeric keyboard input, preventing non-numeric characters.
600
+
601
+ ```svelte
602
+ <script>
603
+ import { HandleKeyDownNumerics } from 'intelliwaketssveltekitv25'
604
+ </script>
605
+
606
+ <input
607
+ type="text"
608
+ onkeydown={(e) => HandleKeyDownNumerics(e, true, false)}
609
+ placeholder="Positive decimals only"
610
+ />
611
+ ```
612
+
613
+ **Parameters:**
614
+ - `allowDecimals` - Allow `.` and `,` (default: true)
615
+ - `allowNegative` - Allow `-` (default: false)
616
+
617
+ **Allowed Keys:** Digits, navigation keys, Ctrl+A/C/V/X, decimal/negative if enabled
618
+
619
+ ---
620
+
621
+ ## Common Patterns
622
+
623
+ ### Multi-Row Grid Navigation
624
+
625
+ Combine `upDownArrows` and `nextPrevArrows` for full grid navigation:
626
+
627
+ ```svelte
628
+ <script>
629
+ import { upDownArrows, nextPrevArrows } from 'intelliwaketssveltekitv25'
630
+ import { useActions } from 'intelliwaketssveltekitv25'
631
+
632
+ const rows = [{ id: 1 }, { id: 2 }, { id: 3 }]
633
+ const fields = ['name', 'email', 'phone']
634
+ </script>
635
+
636
+ {#each rows as row}
637
+ {#each fields as field}
638
+ <input
639
+ id="{row.id}_{field}"
640
+ use:useActions={[
641
+ [upDownArrows, { list: rows }],
642
+ [nextPrevArrows, { fieldList: fields }]
643
+ ]}
644
+ />
645
+ {/each}
646
+ {/each}
647
+ ```
648
+
649
+ **Result:** Arrow keys navigate in all directions with wraparound
650
+
651
+ ---
652
+
653
+ ### Auto-Save Form with Focus Tracking
654
+
655
+ ```svelte
656
+ <script>
657
+ import { clickSubmitOnFocusOut, autoFocus } from 'intelliwaketssveltekitv25'
658
+
659
+ let isEditing = $state(false)
660
+ </script>
661
+
662
+ {#if isEditing}
663
+ <form use:clickSubmitOnFocusOut>
664
+ <input use:autoFocus />
665
+ </form>
666
+ {/if}
667
+ ```
668
+
669
+ ---
670
+
671
+ ### Export with Loading State
672
+
673
+ ```svelte
674
+ <script>
675
+ import { TableIDToExcel } from 'intelliwaketssveltekitv25'
676
+
677
+ let isExporting = $state(false)
678
+
679
+ async function exportData() {
680
+ isExporting = true
681
+ await tick() // Ensure table is rendered
682
+ TableIDToExcel('reportTable', 'Q4-Report')
683
+ isExporting = false
684
+ }
685
+ </script>
686
+
687
+ <table id="reportTable">...</table>
688
+ <button onclick={exportData} disabled={isExporting}>
689
+ {isExporting ? 'Exporting...' : 'Export to Excel'}
690
+ </button>
691
+ ```
692
+
693
+ ---
694
+
695
+ ## Best Practices
696
+
697
+ ### 1. Action Composition
698
+
699
+ Use `useActions` for multiple actions on one element:
700
+
701
+ ```svelte
702
+ <textarea
703
+ use:useActions={[
704
+ [autoGrow],
705
+ [textAreaAltEnter],
706
+ [selectOnFocus]
707
+ ]}
708
+ />
709
+ ```
710
+
711
+ ---
712
+
713
+ ### 2. Error Handling
714
+
715
+ Always handle promise rejections with GPS and navigation:
716
+
717
+ ```typescript
718
+ const position = await CaptureGPS().catch(() => null)
719
+ if (!position) {
720
+ // Handle denial/error
721
+ }
722
+ ```
723
+
724
+ ---
725
+
726
+ ### 3. ID Patterns
727
+
728
+ For navigation actions, use consistent ID patterns:
729
+
730
+ ```svelte
731
+ <!-- Good: {id}_{field} -->
732
+ <input id="1_name" />
733
+ <input id="2_name" />
734
+
735
+ <!-- Bad: Inconsistent -->
736
+ <input id="name-1" />
737
+ <input id="2_name" />
738
+ ```
739
+
740
+ ---
741
+
742
+ ### 4. Mobile Detection
743
+
744
+ Combine with CSS for responsive behavior:
745
+
746
+ ```svelte
747
+ <script>
748
+ import { IsMobileOrTablet } from 'intelliwaketssveltekitv25'
749
+ const isMobile = IsMobileOrTablet()
750
+ </script>
751
+
752
+ <div class:mobile-layout={isMobile}>
753
+ ...
754
+ </div>
755
+ ```
756
+
757
+ ---
758
+
759
+ ## Related Documentation
760
+
761
+ - **[InputNumber](InputNumber)** - Uses `HandleKeyDownNumerics` internally
762
+ - **[TextArea](TextArea)** - Uses `autoGrow` internally
763
+ - **[useActions](Home)** - Compose multiple use: actions
764
+ - **[Integration Guide](Integration)** - Browser vs. server utilities
765
+
766
+ ---
767
+
768
+ ## Technical Notes
769
+
770
+ ### Browser-Only Functions
771
+
772
+ These functions require browser environment:
773
+ - `CaptureGPS` - Geolocation API
774
+ - `CopyRefToClipboard` - Clipboard API
775
+ - `IsMobileOrTablet` - Navigator API
776
+ - `setSearchParam` - SvelteKit navigation
777
+ - All download functions - DOM manipulation
778
+ - All Svelte actions - DOM events
779
+
780
+ **Server-Side Usage:** Import only when needed in client components, or use dynamic imports.
781
+
782
+ ### Performance Considerations
783
+
784
+ - **autoGrow** - Uses ResizeObserver, debounce for high-frequency updates
785
+ - **upDownArrows/nextPrevArrows** - Implements 100ms debounce to prevent rapid navigation
786
+ - **CopyRefToClipboard** - Temporarily modifies DOM, immediately restores
787
+
788
+ ### Browser Compatibility
789
+
790
+ - **Geolocation API** - Requires HTTPS in production
791
+ - **Clipboard API** - Modern browsers only (uses deprecated `document.execCommand`)
792
+ - **ResizeObserver** - Modern browsers (no IE11)
793
+
794
+ ---
795
+
796
+ *For implementation examples, see Storybook stories or component tests in the package repository.*