intelliwaketssveltekitv25 1.0.82 → 1.0.84

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.
@@ -0,0 +1,364 @@
1
+ # Svelte 5 Patterns
2
+
3
+ This library extensively uses modern Svelte 5 features including runes, snippets, and TypeScript generics. Understanding these patterns will help you use the library effectively.
4
+
5
+ ## Runes
6
+
7
+ Svelte 5 introduces runes for reactive state management. This library uses them extensively in component examples.
8
+
9
+ ### $state() - Reactive State
10
+
11
+ Creates reactive local state:
12
+
13
+ ```svelte
14
+ <script>
15
+ import { Switch } from 'intelliwaketssveltekitv25';
16
+
17
+ let enabled = $state(false);
18
+ let count = $state(0);
19
+ </script>
20
+
21
+ <Switch bind:checked={enabled}>Enable</Switch>
22
+ <p>Status: {enabled ? 'On' : 'Off'}</p>
23
+ ```
24
+
25
+ ### $derived() - Computed Values
26
+
27
+ Automatically updates when dependencies change:
28
+
29
+ ```svelte
30
+ <script>
31
+ import { InputNumber } from 'intelliwaketssveltekitv25';
32
+
33
+ let price = $state(100);
34
+ let taxRate = $state(0.08);
35
+
36
+ // Computed value
37
+ let total = $derived(price * (1 + taxRate));
38
+ </script>
39
+
40
+ <InputNumber bind:value={price} currency />
41
+ <InputNumber bind:value={taxRate} percent />
42
+ <p>Total: ${total.toFixed(2)}</p>
43
+ ```
44
+
45
+ ### $effect() - Side Effects
46
+
47
+ Runs when dependencies change:
48
+
49
+ ```svelte
50
+ <script>
51
+ import { Switch } from 'intelliwaketssveltekitv25';
52
+
53
+ let darkMode = $state(false);
54
+
55
+ $effect(() => {
56
+ // Runs whenever darkMode changes
57
+ document.body.classList.toggle('dark', darkMode);
58
+ });
59
+ </script>
60
+
61
+ <Switch bind:checked={darkMode}>Dark Mode</Switch>
62
+ ```
63
+
64
+ ### $bindable() - Two-Way Binding Props
65
+
66
+ Used internally by library components for props that support `bind:`:
67
+
68
+ ```svelte
69
+ <script>
70
+ // Inside a component
71
+ let {
72
+ checked = $bindable(false)
73
+ } = $props();
74
+ </script>
75
+
76
+ <!-- Usage -->
77
+ <Switch bind:checked={myValue} />
78
+ ```
79
+
80
+ ## Snippets
81
+
82
+ Svelte 5's snippet system replaces slots for flexible content projection.
83
+
84
+ ### Basic Snippet Usage
85
+
86
+ ```svelte
87
+ <script>
88
+ import { Modal } from 'intelliwaketssveltekitv25';
89
+ let showModal = $state(false);
90
+ </script>
91
+
92
+ <Modal bind:show={showModal}>
93
+ {#snippet header()}
94
+ Modal Title
95
+ {/snippet}
96
+
97
+ {#snippet body()}
98
+ <p>Modal content goes here</p>
99
+ {/snippet}
100
+ </Modal>
101
+ ```
102
+
103
+ ### Snippets with Parameters
104
+
105
+ Some components pass data to snippets:
106
+
107
+ ```typescript
108
+ // Component prop type
109
+ {
110
+ row?: Snippet<[T, number]> // Receives item and index
111
+ }
112
+ ```
113
+
114
+ ```svelte
115
+ <VirtualList items={users}>
116
+ {#snippet row(user, index)}
117
+ <div>
118
+ {index + 1}. {user.name}
119
+ </div>
120
+ {/snippet}
121
+ </VirtualList>
122
+ ```
123
+
124
+ ### Multiple Snippets
125
+
126
+ Components can accept multiple snippets:
127
+
128
+ ```svelte
129
+ <Modal bind:show={showModal}>
130
+ {#snippet header()}
131
+ Header Content
132
+ {/snippet}
133
+
134
+ {#snippet body()}
135
+ Body Content
136
+ {/snippet}
137
+
138
+ {#snippet leftFooter()}
139
+ <button>Cancel</button>
140
+ {/snippet}
141
+
142
+ {#snippet rightFooter()}
143
+ <button>Save</button>
144
+ {/snippet}
145
+ </Modal>
146
+ ```
147
+
148
+ ### Optional Snippets
149
+
150
+ Most snippets are optional. Components check before rendering:
151
+
152
+ ```svelte
153
+ <!-- Component internals -->
154
+ {#if header}
155
+ {@render header()}
156
+ {/if}
157
+ ```
158
+
159
+ ## TypeScript Generics
160
+
161
+ Components like ArrayTable and VirtualList use generics for type safety.
162
+
163
+ ### Generic Component Usage
164
+
165
+ ```svelte
166
+ <script lang="ts">
167
+ import { ArrayTable } from 'intelliwaketssveltekitv25';
168
+ import type { IArrayStructure } from 'intelliwaketssveltekitv25';
169
+
170
+ interface User {
171
+ id: number;
172
+ name: string;
173
+ email: string;
174
+ }
175
+
176
+ let users: User[] = $state([
177
+ { id: 1, name: 'John', email: 'john@example.com' }
178
+ ]);
179
+
180
+ // Type-safe structure definition
181
+ const structure: IArrayStructure<User> = {
182
+ columns: [
183
+ { fieldName: 'id', title: 'ID' }, // TypeScript ensures 'id' exists
184
+ { fieldName: 'name', title: 'Name' }, // on User interface
185
+ { fieldName: 'email', title: 'Email' }
186
+ ]
187
+ };
188
+ </script>
189
+
190
+ <ArrayTable arrayData={users} arrayStructure={structure} />
191
+ ```
192
+
193
+ ### Generic Constraints
194
+
195
+ Some components require specific type shapes:
196
+
197
+ ```typescript
198
+ // MultiSelect requires id or name
199
+ interface TGenericMultiSelect {
200
+ id?: string | number;
201
+ name?: string;
202
+ [key: string]: any;
203
+ }
204
+
205
+ interface Tag extends TGenericMultiSelect {
206
+ id: number;
207
+ name: string;
208
+ color: string;
209
+ }
210
+ ```
211
+
212
+ ### Custom Value Functions
213
+
214
+ Override default generic behavior:
215
+
216
+ ```svelte
217
+ <script lang="ts">
218
+ import { MultiSelect } from 'intelliwaketssveltekitv25';
219
+
220
+ interface CustomItem {
221
+ uuid: string;
222
+ displayName: string;
223
+ }
224
+
225
+ const items: CustomItem[] = [
226
+ { uuid: 'abc123', displayName: 'Item 1' }
227
+ ];
228
+
229
+ let selected = $state<CustomItem[]>([]);
230
+ </script>
231
+
232
+ <MultiSelect
233
+ possibles={items}
234
+ bind:selected={selected}
235
+ idValue={(item) => item.uuid}
236
+ displayValue={(item) => item.displayName}
237
+ />
238
+ ```
239
+
240
+ ## Component Generics Declaration
241
+
242
+ When creating components that use generics:
243
+
244
+ ```svelte
245
+ <script lang="ts" generics="T extends Record<string, any>">
246
+ import type { Snippet } from 'svelte';
247
+
248
+ let {
249
+ items,
250
+ row
251
+ }: {
252
+ items: T[];
253
+ row?: Snippet<[T, number]>;
254
+ } = $props();
255
+ </script>
256
+
257
+ {#each items as item, index}
258
+ {#if row}
259
+ {@render row(item, index)}
260
+ {/if}
261
+ {/each}
262
+ ```
263
+
264
+ ## Action Arrays
265
+
266
+ Components support Svelte actions via the `use` prop:
267
+
268
+ ```typescript
269
+ import type { ActionArray } from 'svelte/action';
270
+ ```
271
+
272
+ ```svelte
273
+ <script>
274
+ import { TextArea } from 'intelliwaketssveltekitv25';
275
+
276
+ function customAction(node: HTMLElement) {
277
+ console.log('Action applied:', node);
278
+ return {
279
+ destroy() {
280
+ console.log('Action destroyed');
281
+ }
282
+ };
283
+ }
284
+
285
+ const actions: ActionArray = [customAction];
286
+ </script>
287
+
288
+ <TextArea bind:value={text} use={actions} />
289
+ ```
290
+
291
+ ## Best Practices
292
+
293
+ ### 1. Always Use Runes in Svelte 5
294
+
295
+ ```svelte
296
+ <!-- ❌ Old Svelte 4 syntax -->
297
+ <script>
298
+ let count = 0; // Not reactive in Svelte 5
299
+ </script>
300
+
301
+ <!-- ✅ Svelte 5 with runes -->
302
+ <script>
303
+ let count = $state(0); // Reactive
304
+ </script>
305
+ ```
306
+
307
+ ### 2. Use TypeScript Generics for Type Safety
308
+
309
+ ```svelte
310
+ <!-- ❌ No type safety -->
311
+ <script>
312
+ const structure = {
313
+ columns: [
314
+ { fieldName: 'naam' } // Typo not caught
315
+ ]
316
+ };
317
+ </script>
318
+
319
+ <!-- ✅ Type-safe with generics -->
320
+ <script lang="ts">
321
+ interface User {
322
+ name: string;
323
+ }
324
+
325
+ const structure: IArrayStructure<User> = {
326
+ columns: [
327
+ { fieldName: 'naam' } // TypeScript error!
328
+ ]
329
+ };
330
+ </script>
331
+ ```
332
+
333
+ ### 3. Always Bind Two-Way Props
334
+
335
+ ```svelte
336
+ <!-- ❌ One-way binding (component state won't update parent) -->
337
+ <Switch checked={enabled} />
338
+
339
+ <!-- ✅ Two-way binding -->
340
+ <Switch bind:checked={enabled} />
341
+ ```
342
+
343
+ ### 4. Use Snippets Instead of Slots
344
+
345
+ ```svelte
346
+ <!-- ❌ Old Svelte 4 slots -->
347
+ <Modal>
348
+ <svelte:fragment slot="header">Title</svelte:fragment>
349
+ </Modal>
350
+
351
+ <!-- ✅ Svelte 5 snippets -->
352
+ <Modal>
353
+ {#snippet header()}
354
+ Title
355
+ {/snippet}
356
+ </Modal>
357
+ ```
358
+
359
+ ## Further Reading
360
+
361
+ - [Official Svelte 5 Documentation](https://svelte.dev)
362
+ - [Svelte 5 Runes Guide](https://svelte.dev/docs/svelte/$state)
363
+ - [Svelte 5 Snippets Guide](https://svelte.dev/docs/svelte/snippet)
364
+ - Component examples in this library's Storybook: `pnpm storybook`
package/docs/Switch.md ADDED
@@ -0,0 +1,107 @@
1
+ # Switch Component
2
+
3
+ **Replaces:** `<input type="checkbox">` for ALL toggle switches and boolean controls
4
+
5
+ **Purpose:** Custom styled toggle switch with smooth animations, accessibility, and two-way data binding
6
+
7
+ **When to Use:**
8
+ - Feature toggles (enable/disable settings)
9
+ - Boolean preferences (notifications on/off)
10
+ - Any on/off state in settings or forms
11
+ - **NOT for multiple selections** (use CheckBox component for that)
12
+
13
+ ## Key Props
14
+
15
+ - `checked?: boolean` ($bindable) - Current checked state, use `bind:checked` for two-way binding
16
+ - `disabled?: boolean` (default: false) - Disables user interaction, grays out the switch
17
+ - `readonly?: boolean` (default: false) - Visual display only, no interaction allowed
18
+ - `name?: string` - Form field name for HTML form submissions
19
+ - `value?: unknown` - Value to submit when checked (default: boolean checked state)
20
+ - `offValue?: unknown` - Value to submit when unchecked (default: undefined)
21
+ - `displayCheckInverse?: boolean` - Inverts visual display (useful for "disabled" semantics)
22
+ - `hidden?: boolean` - Hides the component
23
+ - `class?: string` - Additional CSS classes for the wrapper
24
+ - `oncheck?: (val: boolean) => void` - Callback fired when checked state changes
25
+ - `use?: ActionArray` - Svelte actions array
26
+ - `id?: string` - HTML id attribute
27
+ - `form?: string` - Associate with a specific form by ID
28
+
29
+ ## Snippets
30
+
31
+ - `children?: Snippet` - Label content displayed to the right of the switch
32
+
33
+ ## Usage Examples
34
+
35
+ ```svelte
36
+ <!-- Basic toggle -->
37
+ <script>
38
+ import { Switch } from 'intelliwaketssveltekitv25';
39
+ let notificationsEnabled = $state(false);
40
+ </script>
41
+
42
+ <Switch bind:checked={notificationsEnabled}>
43
+ Enable Email Notifications
44
+ </Switch>
45
+
46
+ <!-- In a form with name attribute -->
47
+ <form method="POST">
48
+ <Switch name="agreeToTerms" bind:checked={agreedToTerms}>
49
+ I agree to the terms and conditions
50
+ </Switch>
51
+ <button type="submit">Submit</button>
52
+ </form>
53
+
54
+ <!-- Disabled state -->
55
+ <Switch checked={true} disabled>
56
+ Premium Feature (Upgrade Required)
57
+ </Switch>
58
+
59
+ <!-- With oncheck callback -->
60
+ <Switch
61
+ bind:checked={darkModeEnabled}
62
+ oncheck={(isChecked) => {
63
+ console.log('Dark mode:', isChecked);
64
+ // Apply theme changes
65
+ }}
66
+ >
67
+ Dark Mode
68
+ </Switch>
69
+
70
+ <!-- Custom value submission -->
71
+ <Switch
72
+ name="subscription"
73
+ bind:checked={isSubscribed}
74
+ value="premium"
75
+ offValue="free"
76
+ >
77
+ Premium Subscription
78
+ </Switch>
79
+
80
+ <!-- Display inverse (show as "on" when feature is disabled) -->
81
+ <Switch bind:checked={disableTracking} displayCheckInverse>
82
+ Disable Tracking
83
+ </Switch>
84
+ ```
85
+
86
+ ## Common Mistakes
87
+
88
+ - ❌ Using `value` prop for binding: `<Switch bind:value={x}>`
89
+ ✅ Correct: `<Switch bind:checked={x}>`
90
+
91
+ - ❌ Forgetting `bind:` directive: `<Switch checked={x}>`
92
+ ✅ Correct: `<Switch bind:checked={x}>` (for two-way binding)
93
+
94
+ - ❌ Wrapping in `<label>`: `<label><Switch /></label>`
95
+ ✅ Correct: `<Switch>Label Text</Switch>` (uses children snippet internally)
96
+
97
+ - ❌ Using Switch for multiple selections from a list
98
+ ✅ Correct: Use `CheckBox` component for multi-select scenarios
99
+
100
+ ## Related Components
101
+
102
+ - `CheckBox` - For custom checkbox styling (not toggle appearance)
103
+ - `SwitchDateNull` - Toggle that sets/clears a date value
104
+
105
+ ## Storybook
106
+
107
+ See `Components/Switch` stories for interactive examples