intelliwaketssveltekitv25 1.0.82 → 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.
- package/README.md +2 -2
- package/dist/app.css +1 -1
- package/docs/DateRangePicker.md +272 -0
- package/docs/DisplayHTML.md +249 -0
- package/docs/DropDown.md +269 -0
- package/docs/Functions.md +796 -0
- package/docs/Home.md +109 -0
- package/docs/Icon.md +203 -0
- package/docs/Importer.md +328 -0
- package/docs/ImporterAnalysis.md +249 -0
- package/docs/ImporterLoad.md +288 -0
- package/docs/InputNumber.md +159 -0
- package/docs/Integration.md +215 -0
- package/docs/Modal.md +207 -0
- package/docs/MultiSelect.md +304 -0
- package/docs/Paginator.md +332 -0
- package/docs/Search.md +364 -0
- package/docs/SlideDown.md +358 -0
- package/docs/Svelte-5-Patterns.md +364 -0
- package/docs/Switch.md +107 -0
- package/docs/TabHeader.md +333 -0
- package/docs/TabHref.md +370 -0
- package/docs/TextArea.md +118 -0
- package/docs/_Sidebar.md +38 -0
- package/llms.txt +113 -0
- package/package.json +3 -2
- package/llm.txt +0 -1635
|
@@ -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.*
|