intelliwaketssveltekitv25 1.0.80 → 1.0.82
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/INTEGRATION.md +574 -0
- package/README.md +199 -45
- package/dist/ArrayTable.stories.js +215 -0
- package/dist/ArrayTable.svelte +46 -0
- package/dist/ArrayTable.svelte.d.ts +44 -0
- package/dist/ButtonGroup.stories.js +127 -0
- package/dist/DropDown.stories.d.ts +96 -0
- package/dist/DropDown.stories.js +192 -0
- package/dist/DropDown.svelte +32 -0
- package/dist/DropDown.svelte.d.ts +30 -0
- package/dist/Functions.d.ts +1 -0
- package/dist/Functions.js +3 -2
- package/dist/InputNumber.stories.d.ts +122 -0
- package/dist/InputNumber.stories.js +186 -0
- package/dist/InputNumber.svelte +52 -0
- package/dist/InputNumber.svelte.d.ts +27 -0
- package/dist/Modal.stories.d.ts +114 -0
- package/dist/Modal.stories.js +139 -0
- package/dist/Modal.svelte +34 -3
- package/dist/Modal.svelte.d.ts +35 -3
- package/dist/MultiSelect.stories.js +338 -0
- package/dist/MultiSelect.svelte +81 -0
- package/dist/MultiSelect.svelte.d.ts +38 -0
- package/dist/Switch.stories.d.ts +81 -0
- package/dist/Switch.stories.js +99 -0
- package/dist/Switch.svelte +40 -0
- package/dist/Switch.svelte.d.ts +26 -0
- package/dist/TextArea.stories.d.ts +180 -0
- package/dist/TextArea.stories.js +216 -0
- package/dist/TextArea.svelte +32 -0
- package/dist/TextArea.svelte.d.ts +24 -0
- package/dist/app.css +1 -1
- package/llm.txt +1635 -0
- package/package.json +20 -15
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import MultiSelect from './MultiSelect.svelte';
|
|
2
|
+
const sampleTags = [
|
|
3
|
+
{ id: 1, name: 'JavaScript' },
|
|
4
|
+
{ id: 2, name: 'TypeScript' },
|
|
5
|
+
{ id: 3, name: 'Python' },
|
|
6
|
+
{ id: 4, name: 'Java' },
|
|
7
|
+
{ id: 5, name: 'C++' },
|
|
8
|
+
{ id: 6, name: 'Ruby' },
|
|
9
|
+
{ id: 7, name: 'Go' },
|
|
10
|
+
{ id: 8, name: 'Rust' },
|
|
11
|
+
{ id: 9, name: 'PHP' },
|
|
12
|
+
{ id: 10, name: 'Swift' }
|
|
13
|
+
];
|
|
14
|
+
const groupedTags = [
|
|
15
|
+
{ id: 1, name: 'JavaScript', header: 'Frontend' },
|
|
16
|
+
{ id: 2, name: 'TypeScript', header: 'Frontend' },
|
|
17
|
+
{ id: 3, name: 'React', header: 'Frontend' },
|
|
18
|
+
{ id: 4, name: 'Vue', header: 'Frontend' },
|
|
19
|
+
{ id: 5, name: 'Node.js', header: 'Backend' },
|
|
20
|
+
{ id: 6, name: 'Python', header: 'Backend' },
|
|
21
|
+
{ id: 7, name: 'Go', header: 'Backend' },
|
|
22
|
+
{ id: 8, name: 'MySQL', header: 'Database' },
|
|
23
|
+
{ id: 9, name: 'PostgreSQL', header: 'Database' },
|
|
24
|
+
{ id: 10, name: 'MongoDB', header: 'Database' }
|
|
25
|
+
];
|
|
26
|
+
const meta = {
|
|
27
|
+
title: 'Components/MultiSelect',
|
|
28
|
+
component: MultiSelect,
|
|
29
|
+
tags: ['autodocs'],
|
|
30
|
+
argTypes: {
|
|
31
|
+
possibles: {
|
|
32
|
+
control: 'object',
|
|
33
|
+
description: 'Array of all available items to select from',
|
|
34
|
+
table: {
|
|
35
|
+
type: { summary: 'T[]' }
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
selected: {
|
|
39
|
+
control: 'object',
|
|
40
|
+
description: 'Currently selected items (two-way bindable)',
|
|
41
|
+
table: {
|
|
42
|
+
type: { summary: 'T[]' },
|
|
43
|
+
defaultValue: { summary: '[]' }
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
selectedIDs: {
|
|
47
|
+
control: 'object',
|
|
48
|
+
description: 'IDs of selected items (two-way bindable, alternative to selected)',
|
|
49
|
+
table: {
|
|
50
|
+
type: { summary: '(number | string)[] | undefined' },
|
|
51
|
+
defaultValue: { summary: 'undefined' }
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
placeholder: {
|
|
55
|
+
control: 'text',
|
|
56
|
+
description: 'Placeholder text shown when no items selected',
|
|
57
|
+
table: {
|
|
58
|
+
type: { summary: 'string' },
|
|
59
|
+
defaultValue: { summary: '""' }
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
disabled: {
|
|
63
|
+
control: 'boolean',
|
|
64
|
+
description: 'Disable user interaction',
|
|
65
|
+
table: {
|
|
66
|
+
type: { summary: 'boolean' },
|
|
67
|
+
defaultValue: { summary: 'false' }
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
readonly: {
|
|
71
|
+
control: 'boolean',
|
|
72
|
+
description: 'Display in readonly mode (no interaction allowed)',
|
|
73
|
+
table: {
|
|
74
|
+
type: { summary: 'boolean' },
|
|
75
|
+
defaultValue: { summary: 'false' }
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
required: {
|
|
79
|
+
control: 'boolean',
|
|
80
|
+
description: 'Mark as required (shows invalid state if empty)',
|
|
81
|
+
table: {
|
|
82
|
+
type: { summary: 'boolean' },
|
|
83
|
+
defaultValue: { summary: 'false' }
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
isMulti: {
|
|
87
|
+
control: 'boolean',
|
|
88
|
+
description: 'Allow multiple selections (false = single-select mode)',
|
|
89
|
+
table: {
|
|
90
|
+
type: { summary: 'boolean' },
|
|
91
|
+
defaultValue: { summary: 'true' }
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
allowClearAll: {
|
|
95
|
+
control: 'boolean',
|
|
96
|
+
description: 'Show clear all button when items are selected',
|
|
97
|
+
table: {
|
|
98
|
+
type: { summary: 'boolean' },
|
|
99
|
+
defaultValue: { summary: 'true' }
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
createPrefix: {
|
|
103
|
+
control: 'text',
|
|
104
|
+
description: 'Text prefix shown before new item name in create option',
|
|
105
|
+
table: {
|
|
106
|
+
type: { summary: 'string' },
|
|
107
|
+
defaultValue: { summary: '"Create:"' }
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
autoFocus: {
|
|
111
|
+
control: 'boolean',
|
|
112
|
+
description: 'Auto-focus input on mount',
|
|
113
|
+
table: {
|
|
114
|
+
type: { summary: 'boolean' },
|
|
115
|
+
defaultValue: { summary: 'false' }
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
export default meta;
|
|
121
|
+
/**
|
|
122
|
+
* Default multi-select with no initial selection.
|
|
123
|
+
* Users can select multiple items from the dropdown.
|
|
124
|
+
*/
|
|
125
|
+
export const Default = {
|
|
126
|
+
args: {
|
|
127
|
+
possibles: sampleTags,
|
|
128
|
+
selected: [],
|
|
129
|
+
placeholder: 'Select programming languages...'
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Multi-select with pre-selected items.
|
|
134
|
+
* Demonstrates binding to existing selections.
|
|
135
|
+
*/
|
|
136
|
+
export const PreSelected = {
|
|
137
|
+
args: {
|
|
138
|
+
possibles: sampleTags,
|
|
139
|
+
selected: [sampleTags[0], sampleTags[1]], // JavaScript and TypeScript
|
|
140
|
+
placeholder: 'Select programming languages...'
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Single-select mode (isMulti=false).
|
|
145
|
+
* Only one item can be selected at a time - acts like a searchable dropdown.
|
|
146
|
+
*/
|
|
147
|
+
export const SingleSelect = {
|
|
148
|
+
args: {
|
|
149
|
+
possibles: sampleTags,
|
|
150
|
+
selected: [],
|
|
151
|
+
isMulti: false,
|
|
152
|
+
placeholder: 'Select one language...'
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Enable dynamic item creation with the create function.
|
|
157
|
+
* Type a name that doesn't exist and press Enter to create a new item.
|
|
158
|
+
*/
|
|
159
|
+
export const WithCreation = {
|
|
160
|
+
args: {
|
|
161
|
+
possibles: sampleTags,
|
|
162
|
+
selected: [],
|
|
163
|
+
placeholder: 'Select or create languages...',
|
|
164
|
+
create: (value) => ({ id: Date.now(), name: value }),
|
|
165
|
+
createPrefix: 'Create new:'
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* Creation with validation.
|
|
170
|
+
* Prevents creating items that don't meet validation criteria.
|
|
171
|
+
*/
|
|
172
|
+
export const WithValidation = {
|
|
173
|
+
args: {
|
|
174
|
+
possibles: sampleTags,
|
|
175
|
+
selected: [],
|
|
176
|
+
placeholder: 'Select or create (min 3 chars)...',
|
|
177
|
+
create: (value) => ({ id: Date.now(), name: value }),
|
|
178
|
+
createValid: (value) => {
|
|
179
|
+
if (value.length < 3) {
|
|
180
|
+
return 'Language name must be at least 3 characters';
|
|
181
|
+
}
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* Searchable dropdown with filtering.
|
|
188
|
+
* Type to filter the list of available items.
|
|
189
|
+
*/
|
|
190
|
+
export const Searchable = {
|
|
191
|
+
args: {
|
|
192
|
+
possibles: sampleTags,
|
|
193
|
+
selected: [],
|
|
194
|
+
placeholder: 'Type to search languages...'
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* Grouped items with headers.
|
|
199
|
+
* Items are organized into sections using the headerValue function.
|
|
200
|
+
*/
|
|
201
|
+
export const WithHeaders = {
|
|
202
|
+
args: {
|
|
203
|
+
possibles: groupedTags,
|
|
204
|
+
selected: [],
|
|
205
|
+
placeholder: 'Select technologies...'
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
/**
|
|
209
|
+
* Disabled state prevents all interaction.
|
|
210
|
+
*/
|
|
211
|
+
export const Disabled = {
|
|
212
|
+
args: {
|
|
213
|
+
possibles: sampleTags,
|
|
214
|
+
selected: [sampleTags[0]],
|
|
215
|
+
disabled: true,
|
|
216
|
+
placeholder: 'Disabled...'
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
* Readonly state displays selections but prevents changes.
|
|
221
|
+
*/
|
|
222
|
+
export const Readonly = {
|
|
223
|
+
args: {
|
|
224
|
+
possibles: sampleTags,
|
|
225
|
+
selected: [sampleTags[0], sampleTags[1]],
|
|
226
|
+
readonly: true,
|
|
227
|
+
placeholder: 'Readonly...'
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* Without clear all button.
|
|
232
|
+
* Users must remove items individually.
|
|
233
|
+
*/
|
|
234
|
+
export const NoClearAll = {
|
|
235
|
+
args: {
|
|
236
|
+
possibles: sampleTags,
|
|
237
|
+
selected: [sampleTags[0], sampleTags[1], sampleTags[2]],
|
|
238
|
+
allowClearAll: false,
|
|
239
|
+
placeholder: 'Select languages...'
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
243
|
+
* Required field validation.
|
|
244
|
+
* Shows invalid state when no items are selected.
|
|
245
|
+
*/
|
|
246
|
+
export const Required = {
|
|
247
|
+
args: {
|
|
248
|
+
possibles: sampleTags,
|
|
249
|
+
selected: [],
|
|
250
|
+
required: true,
|
|
251
|
+
placeholder: 'At least one language required'
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
/**
|
|
255
|
+
* Form integration with hidden inputs.
|
|
256
|
+
* Selected item IDs are submitted with the form using the name attribute.
|
|
257
|
+
*/
|
|
258
|
+
export const FormIntegration = {
|
|
259
|
+
args: {
|
|
260
|
+
possibles: sampleTags,
|
|
261
|
+
selected: [sampleTags[0]],
|
|
262
|
+
name: 'languages',
|
|
263
|
+
placeholder: 'Select languages for form...'
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
/**
|
|
267
|
+
* Using selectedIDs for binding instead of selected array.
|
|
268
|
+
* Useful when working with IDs directly.
|
|
269
|
+
*/
|
|
270
|
+
export const BindToIDs = {
|
|
271
|
+
args: {
|
|
272
|
+
possibles: sampleTags,
|
|
273
|
+
selectedIDs: [1, 2], // IDs of JavaScript and TypeScript
|
|
274
|
+
placeholder: 'Bound to IDs...'
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
/**
|
|
278
|
+
* Track created vs existing items.
|
|
279
|
+
* The created and existing bindable props separate new items from existing ones.
|
|
280
|
+
*/
|
|
281
|
+
export const TrackCreated = {
|
|
282
|
+
args: {
|
|
283
|
+
possibles: sampleTags,
|
|
284
|
+
selected: [],
|
|
285
|
+
placeholder: 'Select or create languages...',
|
|
286
|
+
create: (value) => ({ id: Date.now(), name: value }),
|
|
287
|
+
createPrefix: 'Add new:'
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
/**
|
|
291
|
+
* Large dataset with many items.
|
|
292
|
+
* Demonstrates search performance with lots of options.
|
|
293
|
+
*/
|
|
294
|
+
export const LargeDataset = {
|
|
295
|
+
args: {
|
|
296
|
+
possibles: Array.from({ length: 100 }, (_, i) => ({
|
|
297
|
+
id: i + 1,
|
|
298
|
+
name: `Language ${i + 1}`
|
|
299
|
+
})),
|
|
300
|
+
selected: [],
|
|
301
|
+
placeholder: 'Search 100+ items...'
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
/**
|
|
305
|
+
* Empty possibles array.
|
|
306
|
+
* Shows "No items found" message.
|
|
307
|
+
*/
|
|
308
|
+
export const EmptyList = {
|
|
309
|
+
args: {
|
|
310
|
+
possibles: [],
|
|
311
|
+
selected: [],
|
|
312
|
+
placeholder: 'No items available...'
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
/**
|
|
316
|
+
* Auto-focus on mount.
|
|
317
|
+
* Input is automatically focused when component renders.
|
|
318
|
+
*/
|
|
319
|
+
export const AutoFocus = {
|
|
320
|
+
args: {
|
|
321
|
+
possibles: sampleTags,
|
|
322
|
+
selected: [],
|
|
323
|
+
autoFocus: true,
|
|
324
|
+
placeholder: 'Auto-focused input...'
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
/**
|
|
328
|
+
* Custom styling with CSS classes.
|
|
329
|
+
*/
|
|
330
|
+
export const CustomStyling = {
|
|
331
|
+
args: {
|
|
332
|
+
possibles: sampleTags,
|
|
333
|
+
selected: [],
|
|
334
|
+
placeholder: 'Custom styled...',
|
|
335
|
+
controlClass: 'border-2 border-primary-main',
|
|
336
|
+
inputClass: 'text-primary-main font-bold'
|
|
337
|
+
}
|
|
338
|
+
};
|
package/dist/MultiSelect.svelte
CHANGED
|
@@ -1,3 +1,43 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
@component
|
|
3
|
+
Type-safe, searchable multi-select dropdown with dynamic item creation and keyboard navigation.
|
|
4
|
+
Replaces native <select multiple> with advanced features.
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
```svelte
|
|
8
|
+
<script lang="ts">
|
|
9
|
+
import { MultiSelect } from 'intelliwaketssveltekitv25';
|
|
10
|
+
|
|
11
|
+
interface Tag {
|
|
12
|
+
id: number;
|
|
13
|
+
name: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const tags: Tag[] = [
|
|
17
|
+
{ id: 1, name: 'JavaScript' },
|
|
18
|
+
{ id: 2, name: 'TypeScript' }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
let selected = $state<Tag[]>([]);
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<MultiSelect possibles={tags} bind:selected={selected} placeholder="Select tags..." />
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
@remarks
|
|
28
|
+
- Uses TypeScript generics for type-safe selections: <T extends TGenericMultiSelect>
|
|
29
|
+
- Svelte 5 $bindable runes for two-way binding (selected, selectedIDs, created, existing)
|
|
30
|
+
- Keyboard navigation: Arrow keys, Enter, Backspace
|
|
31
|
+
- Searchable with automatic filtering
|
|
32
|
+
- Dynamic item creation with validation
|
|
33
|
+
- Supports single-select mode (isMulti=false)
|
|
34
|
+
- Custom display and ID functions for flexible data structures
|
|
35
|
+
- Grouping/headers support via headerValue function
|
|
36
|
+
|
|
37
|
+
@see DropDown - For single action/selection without search
|
|
38
|
+
@see DropDownControl - Lower-level dropdown control (used internally)
|
|
39
|
+
-->
|
|
40
|
+
|
|
1
41
|
<!--suppress JSDeprecatedSymbols -->
|
|
2
42
|
<script lang='ts' generics="T extends TGenericMultiSelect">
|
|
3
43
|
import { DeepEqual, SearchRows } from '@solidbasisventures/intelliwaketsfoundation'
|
|
@@ -8,46 +48,87 @@
|
|
|
8
48
|
import { type ActionArray, useActions } from './useActions'
|
|
9
49
|
|
|
10
50
|
let {
|
|
51
|
+
/** HTML id attribute for the input element */
|
|
11
52
|
id = undefined,
|
|
53
|
+
/** Controls dropdown visibility (two-way bindable) */
|
|
12
54
|
show = $bindable(false),
|
|
55
|
+
/** Svelte actions array */
|
|
13
56
|
use = [],
|
|
57
|
+
/** Array of all available items to select from */
|
|
14
58
|
possibles,
|
|
59
|
+
/** Currently selected items (two-way bindable) */
|
|
15
60
|
selected = $bindable([]),
|
|
61
|
+
/** IDs of selected items (two-way bindable, alternative to selected) */
|
|
16
62
|
selectedIDs = $bindable(undefined),
|
|
63
|
+
/** Newly created items (two-way bindable, subset of selected that don't exist in possibles) */
|
|
17
64
|
created = $bindable([]),
|
|
65
|
+
/** Existing items (two-way bindable, subset of selected that exist in possibles) */
|
|
18
66
|
existing = $bindable([]),
|
|
67
|
+
/** Form input name for hidden inputs (enables form submission) */
|
|
19
68
|
name = null,
|
|
69
|
+
/** Placeholder text shown when no items selected */
|
|
20
70
|
placeholder = '',
|
|
71
|
+
/** Disable user interaction */
|
|
21
72
|
disabled = false,
|
|
73
|
+
/** Display in readonly mode (no interaction allowed) */
|
|
22
74
|
readonly = false,
|
|
75
|
+
/** Mark as required (shows invalid state if empty) */
|
|
23
76
|
required = false,
|
|
77
|
+
/** Mark as invalid (shows error styling) */
|
|
24
78
|
invalid = false,
|
|
79
|
+
/** Allow multiple selections (false = single-select mode) */
|
|
25
80
|
isMulti = true,
|
|
81
|
+
/** Show clear all button when items are selected */
|
|
26
82
|
allowClearAll = true,
|
|
83
|
+
/** Text prefix shown before new item name in create option */
|
|
27
84
|
createPrefix = 'Create:',
|
|
85
|
+
/** Function to create new items from search string (enables dynamic creation) */
|
|
28
86
|
create = undefined,
|
|
87
|
+
/** Validation function for new items (returns true or error message string) */
|
|
29
88
|
createValid = undefined,
|
|
89
|
+
/** Tab index for keyboard navigation */
|
|
30
90
|
tabindex = 0,
|
|
91
|
+
/** Function to extract display text from item */
|
|
31
92
|
displayValue = (item: T) => item.name ?? item.id ?? '',
|
|
93
|
+
/** Function to extract unique identifier from item */
|
|
32
94
|
idValue = (item: T) => item.id ?? displayValue(item),
|
|
95
|
+
/** Function to compute key for each statements (defaults to idValue) */
|
|
33
96
|
keyValue = (item: T) => idValue(item),
|
|
97
|
+
/** Function to compute value for hidden form inputs */
|
|
34
98
|
inputValue = (item: T) => idValue(item),
|
|
99
|
+
/** Function to extract header/group text from item (for grouping) */
|
|
35
100
|
headerValue = (item: T | null | undefined) => item?.header,
|
|
101
|
+
/** Match dropdown width to toggle button width */
|
|
36
102
|
sameSize = true,
|
|
103
|
+
/** Timestamp to trigger dropdown resize recalculation */
|
|
37
104
|
resizeTS = 1,
|
|
105
|
+
/** Auto-focus input on mount */
|
|
38
106
|
autoFocus = false,
|
|
107
|
+
/** Z-index for dropdown positioning */
|
|
39
108
|
zIndex = 50,
|
|
109
|
+
/** Additional CSS classes for dropdown body */
|
|
40
110
|
bodyClass = '',
|
|
111
|
+
/** Additional CSS classes for toggle button */
|
|
41
112
|
toggleClass = '',
|
|
113
|
+
/** Additional CSS classes for dropdown control wrapper */
|
|
42
114
|
controlClass = '',
|
|
115
|
+
/** Additional CSS classes for search input */
|
|
43
116
|
inputClass = '',
|
|
117
|
+
/** Parent div element reference (for focus management) */
|
|
44
118
|
parentDivElement = null,
|
|
119
|
+
/** Associate with a form by ID */
|
|
45
120
|
form = undefined,
|
|
121
|
+
/** Callback when item is added (passes item ID) */
|
|
46
122
|
onadd,
|
|
123
|
+
/** Callback when existing item is selected (passes item ID) */
|
|
47
124
|
onselect,
|
|
125
|
+
/** Callback when new item is created (passes item ID) */
|
|
48
126
|
oncreate,
|
|
127
|
+
/** Callback when selection changes (passes array of selected items) */
|
|
49
128
|
onchange,
|
|
129
|
+
/** Callback when item is cleared (passes item ID) */
|
|
50
130
|
onclear,
|
|
131
|
+
/** Callback when all items are cleared */
|
|
51
132
|
onclearall
|
|
52
133
|
}: {
|
|
53
134
|
id?: string
|
|
@@ -64,6 +64,44 @@ interface $$IsomorphicComponent {
|
|
|
64
64
|
<T extends TGenericMultiSelect>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
65
65
|
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
66
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Type-safe, searchable multi-select dropdown with dynamic item creation and keyboard navigation.
|
|
69
|
+
* Replaces native <select multiple> with advanced features.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```svelte
|
|
73
|
+
* <script lang="ts">
|
|
74
|
+
* import { MultiSelect } from 'intelliwaketssveltekitv25';
|
|
75
|
+
*
|
|
76
|
+
* interface Tag {
|
|
77
|
+
* id: number;
|
|
78
|
+
* name: string;
|
|
79
|
+
* }
|
|
80
|
+
*
|
|
81
|
+
* const tags: Tag[] = [
|
|
82
|
+
* { id: 1, name: 'JavaScript' },
|
|
83
|
+
* { id: 2, name: 'TypeScript' }
|
|
84
|
+
* ];
|
|
85
|
+
*
|
|
86
|
+
* let selected = $state<Tag[]>([]);
|
|
87
|
+
* </script>
|
|
88
|
+
*
|
|
89
|
+
* <MultiSelect possibles={tags} bind:selected={selected} placeholder="Select tags..." />
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* @remarks
|
|
93
|
+
* - Uses TypeScript generics for type-safe selections: <T extends TGenericMultiSelect>
|
|
94
|
+
* - Svelte 5 $bindable runes for two-way binding (selected, selectedIDs, created, existing)
|
|
95
|
+
* - Keyboard navigation: Arrow keys, Enter, Backspace
|
|
96
|
+
* - Searchable with automatic filtering
|
|
97
|
+
* - Dynamic item creation with validation
|
|
98
|
+
* - Supports single-select mode (isMulti=false)
|
|
99
|
+
* - Custom display and ID functions for flexible data structures
|
|
100
|
+
* - Grouping/headers support via headerValue function
|
|
101
|
+
*
|
|
102
|
+
* @see DropDown - For single action/selection without search
|
|
103
|
+
* @see DropDownControl - Lower-level dropdown control (used internally)
|
|
104
|
+
*/
|
|
67
105
|
declare const MultiSelect: $$IsomorphicComponent;
|
|
68
106
|
type MultiSelect<T extends TGenericMultiSelect> = InstanceType<typeof MultiSelect<T>>;
|
|
69
107
|
export default MultiSelect;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/svelte';
|
|
2
|
+
type SwitchProps = {
|
|
3
|
+
checked?: boolean;
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
readonly?: boolean;
|
|
6
|
+
name?: string;
|
|
7
|
+
value?: unknown;
|
|
8
|
+
offValue?: unknown;
|
|
9
|
+
displayCheckInverse?: boolean;
|
|
10
|
+
hidden?: boolean;
|
|
11
|
+
class?: string;
|
|
12
|
+
};
|
|
13
|
+
declare const meta: {
|
|
14
|
+
title: string;
|
|
15
|
+
component: import("svelte").Component<{
|
|
16
|
+
id?: string | undefined;
|
|
17
|
+
use?: import("./useActions").ActionArray;
|
|
18
|
+
checked?: boolean;
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
readonly?: boolean;
|
|
21
|
+
name?: string | undefined;
|
|
22
|
+
form?: string | undefined;
|
|
23
|
+
value?: unknown | undefined;
|
|
24
|
+
offValue?: unknown | undefined;
|
|
25
|
+
hidden?: boolean;
|
|
26
|
+
displayCheckInverse?: boolean;
|
|
27
|
+
class?: string;
|
|
28
|
+
oncheck?: (val: boolean) => void;
|
|
29
|
+
children?: import("svelte").Snippet;
|
|
30
|
+
}, {}, "checked">;
|
|
31
|
+
tags: string[];
|
|
32
|
+
argTypes: {
|
|
33
|
+
checked: {
|
|
34
|
+
control: "boolean";
|
|
35
|
+
description: string;
|
|
36
|
+
};
|
|
37
|
+
disabled: {
|
|
38
|
+
control: "boolean";
|
|
39
|
+
description: string;
|
|
40
|
+
};
|
|
41
|
+
readonly: {
|
|
42
|
+
control: "boolean";
|
|
43
|
+
description: string;
|
|
44
|
+
};
|
|
45
|
+
name: {
|
|
46
|
+
control: "text";
|
|
47
|
+
description: string;
|
|
48
|
+
};
|
|
49
|
+
value: {
|
|
50
|
+
control: "text";
|
|
51
|
+
description: string;
|
|
52
|
+
};
|
|
53
|
+
offValue: {
|
|
54
|
+
control: "text";
|
|
55
|
+
description: string;
|
|
56
|
+
};
|
|
57
|
+
displayCheckInverse: {
|
|
58
|
+
control: "boolean";
|
|
59
|
+
description: string;
|
|
60
|
+
};
|
|
61
|
+
hidden: {
|
|
62
|
+
control: "boolean";
|
|
63
|
+
description: string;
|
|
64
|
+
};
|
|
65
|
+
class: {
|
|
66
|
+
control: "text";
|
|
67
|
+
description: string;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
export default meta;
|
|
72
|
+
type Story = StoryObj<SwitchProps>;
|
|
73
|
+
export declare const Default: Story;
|
|
74
|
+
export declare const Checked: Story;
|
|
75
|
+
export declare const Disabled: Story;
|
|
76
|
+
export declare const DisabledChecked: Story;
|
|
77
|
+
export declare const Readonly: Story;
|
|
78
|
+
export declare const WithFormName: Story;
|
|
79
|
+
export declare const WithCustomValues: Story;
|
|
80
|
+
export declare const DisplayInverse: Story;
|
|
81
|
+
export declare const DisplayInverseChecked: Story;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import Switch from './Switch.svelte';
|
|
2
|
+
const meta = {
|
|
3
|
+
title: 'Components/Switch',
|
|
4
|
+
component: Switch,
|
|
5
|
+
tags: ['autodocs'],
|
|
6
|
+
argTypes: {
|
|
7
|
+
checked: {
|
|
8
|
+
control: 'boolean',
|
|
9
|
+
description: 'Current checked state (two-way bindable)'
|
|
10
|
+
},
|
|
11
|
+
disabled: {
|
|
12
|
+
control: 'boolean',
|
|
13
|
+
description: 'Disables user interaction'
|
|
14
|
+
},
|
|
15
|
+
readonly: {
|
|
16
|
+
control: 'boolean',
|
|
17
|
+
description: 'Visual display only, no interaction'
|
|
18
|
+
},
|
|
19
|
+
name: {
|
|
20
|
+
control: 'text',
|
|
21
|
+
description: 'Form field name for submissions'
|
|
22
|
+
},
|
|
23
|
+
value: {
|
|
24
|
+
control: 'text',
|
|
25
|
+
description: 'Value to submit when checked'
|
|
26
|
+
},
|
|
27
|
+
offValue: {
|
|
28
|
+
control: 'text',
|
|
29
|
+
description: 'Value to submit when unchecked'
|
|
30
|
+
},
|
|
31
|
+
displayCheckInverse: {
|
|
32
|
+
control: 'boolean',
|
|
33
|
+
description: 'Invert visual display (useful for "disabled" semantics)'
|
|
34
|
+
},
|
|
35
|
+
hidden: {
|
|
36
|
+
control: 'boolean',
|
|
37
|
+
description: 'Hide the component'
|
|
38
|
+
},
|
|
39
|
+
class: {
|
|
40
|
+
control: 'text',
|
|
41
|
+
description: 'Additional CSS classes'
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
export default meta;
|
|
46
|
+
export const Default = {
|
|
47
|
+
args: {
|
|
48
|
+
checked: false
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
export const Checked = {
|
|
52
|
+
args: {
|
|
53
|
+
checked: true
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
export const Disabled = {
|
|
57
|
+
args: {
|
|
58
|
+
checked: false,
|
|
59
|
+
disabled: true
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
export const DisabledChecked = {
|
|
63
|
+
args: {
|
|
64
|
+
checked: true,
|
|
65
|
+
disabled: true
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
export const Readonly = {
|
|
69
|
+
args: {
|
|
70
|
+
checked: true,
|
|
71
|
+
readonly: true
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
export const WithFormName = {
|
|
75
|
+
args: {
|
|
76
|
+
checked: true,
|
|
77
|
+
name: 'agreeToTerms'
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
export const WithCustomValues = {
|
|
81
|
+
args: {
|
|
82
|
+
checked: true,
|
|
83
|
+
name: 'subscription',
|
|
84
|
+
value: 'premium',
|
|
85
|
+
offValue: 'free'
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
export const DisplayInverse = {
|
|
89
|
+
args: {
|
|
90
|
+
checked: false,
|
|
91
|
+
displayCheckInverse: true
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
export const DisplayInverseChecked = {
|
|
95
|
+
args: {
|
|
96
|
+
checked: true,
|
|
97
|
+
displayCheckInverse: true
|
|
98
|
+
}
|
|
99
|
+
};
|