intelliwaketssveltekitv25 1.0.81 → 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.
@@ -0,0 +1,114 @@
1
+ import type { StoryObj } from '@storybook/svelte';
2
+ type ModalProps = {
3
+ show: unknown;
4
+ noShowValue?: unknown;
5
+ width?: string;
6
+ cancelButton?: string | false;
7
+ okButton?: string | false;
8
+ okDisabled?: boolean;
9
+ noCloseOnOK?: boolean;
10
+ disable?: boolean;
11
+ okType?: 'submit' | 'button';
12
+ overflowY?: 'auto' | 'visible' | 'hidden';
13
+ borderFooter?: boolean;
14
+ };
15
+ declare const meta: {
16
+ title: string;
17
+ component: import("svelte").Component<{
18
+ header?: import("svelte").Snippet;
19
+ body?: import("svelte").Snippet;
20
+ leftFooter?: import("svelte").Snippet;
21
+ centerFooter?: import("svelte").Snippet;
22
+ rightFooter?: import("svelte").Snippet;
23
+ show: unknown;
24
+ noShowValue?: unknown;
25
+ forceNoShow?: boolean;
26
+ width?: string;
27
+ cancelButton?: string | false;
28
+ okButton?: string | false;
29
+ okFAProps?: import("./Definitions").IFAProps;
30
+ okActionNotOnEnter?: boolean;
31
+ okDisabled?: boolean;
32
+ noCloseOnOK?: boolean;
33
+ overflowY?: "auto" | "visible" | "hidden";
34
+ disable?: boolean;
35
+ okType?: "submit" | "button";
36
+ marginForStickyHeader?: boolean;
37
+ okButtonWrap?: boolean;
38
+ class?: string;
39
+ okColor?: TDefaultColorPalate | null;
40
+ color?: TDefaultColorPalate | null;
41
+ classHeader?: string;
42
+ classBody?: string;
43
+ classFooter?: string;
44
+ classButton?: string;
45
+ borderFooter?: boolean;
46
+ onOK?: () => void;
47
+ onOKPromise?: () => Promise<unknown>;
48
+ onCancel?: () => void;
49
+ onClose?: () => void;
50
+ }, {}, "show">;
51
+ tags: string[];
52
+ argTypes: {
53
+ show: {
54
+ control: "boolean";
55
+ description: string;
56
+ };
57
+ noShowValue: {
58
+ control: "text";
59
+ description: string;
60
+ };
61
+ width: {
62
+ control: "text";
63
+ description: string;
64
+ };
65
+ cancelButton: {
66
+ control: "text";
67
+ description: string;
68
+ };
69
+ okButton: {
70
+ control: "text";
71
+ description: string;
72
+ };
73
+ okDisabled: {
74
+ control: "boolean";
75
+ description: string;
76
+ };
77
+ noCloseOnOK: {
78
+ control: "boolean";
79
+ description: string;
80
+ };
81
+ disable: {
82
+ control: "boolean";
83
+ description: string;
84
+ };
85
+ okType: {
86
+ control: "select";
87
+ options: string[];
88
+ description: string;
89
+ };
90
+ overflowY: {
91
+ control: "select";
92
+ options: string[];
93
+ description: string;
94
+ };
95
+ borderFooter: {
96
+ control: "boolean";
97
+ description: string;
98
+ };
99
+ };
100
+ };
101
+ export default meta;
102
+ type Story = StoryObj<ModalProps>;
103
+ export declare const Default: Story;
104
+ export declare const WideModal: Story;
105
+ export declare const NarrowModal: Story;
106
+ export declare const OnlyOKButton: Story;
107
+ export declare const OnlyCancelButton: Story;
108
+ export declare const NoButtons: Story;
109
+ export declare const OKDisabled: Story;
110
+ export declare const NoCloseOnOK: Story;
111
+ export declare const WithActivityOverlay: Story;
112
+ export declare const FormSubmitType: Story;
113
+ export declare const NoBorderFooter: Story;
114
+ export declare const OverflowVisible: Story;
@@ -0,0 +1,139 @@
1
+ import Modal from './Modal.svelte';
2
+ const meta = {
3
+ title: 'Components/Modal',
4
+ component: Modal,
5
+ tags: ['autodocs'],
6
+ argTypes: {
7
+ show: {
8
+ control: 'boolean',
9
+ description: 'Control visibility: value equal to noShowValue hides modal, any other value shows it'
10
+ },
11
+ noShowValue: {
12
+ control: 'text',
13
+ description: 'The value to compare against show to determine if modal should be hidden'
14
+ },
15
+ width: {
16
+ control: 'text',
17
+ description: 'Modal width (CSS value like "40em", "500px", "80%")'
18
+ },
19
+ cancelButton: {
20
+ control: 'text',
21
+ description: 'Cancel button text, or false to hide'
22
+ },
23
+ okButton: {
24
+ control: 'text',
25
+ description: 'OK button text, or false to hide'
26
+ },
27
+ okDisabled: {
28
+ control: 'boolean',
29
+ description: 'Disable the OK button'
30
+ },
31
+ noCloseOnOK: {
32
+ control: 'boolean',
33
+ description: 'Keep modal open after OK click (useful for form validation)'
34
+ },
35
+ disable: {
36
+ control: 'boolean',
37
+ description: 'Disable all interactions (shows activity overlay)'
38
+ },
39
+ okType: {
40
+ control: 'select',
41
+ options: ['submit', 'button'],
42
+ description: 'Button type for form integration'
43
+ },
44
+ overflowY: {
45
+ control: 'select',
46
+ options: ['auto', 'visible', 'hidden'],
47
+ description: 'Body overflow behavior'
48
+ },
49
+ borderFooter: {
50
+ control: 'boolean',
51
+ description: 'Show border above footer'
52
+ }
53
+ }
54
+ };
55
+ export default meta;
56
+ export const Default = {
57
+ args: {
58
+ show: true,
59
+ cancelButton: 'Cancel',
60
+ okButton: 'OK'
61
+ }
62
+ };
63
+ export const WideModal = {
64
+ args: {
65
+ show: true,
66
+ width: '80%',
67
+ cancelButton: 'Cancel',
68
+ okButton: 'Save'
69
+ }
70
+ };
71
+ export const NarrowModal = {
72
+ args: {
73
+ show: true,
74
+ width: '30em',
75
+ cancelButton: 'Cancel',
76
+ okButton: 'Confirm'
77
+ }
78
+ };
79
+ export const OnlyOKButton = {
80
+ args: {
81
+ show: true,
82
+ cancelButton: false,
83
+ okButton: 'Close'
84
+ }
85
+ };
86
+ export const OnlyCancelButton = {
87
+ args: {
88
+ show: true,
89
+ cancelButton: 'Close',
90
+ okButton: false
91
+ }
92
+ };
93
+ export const NoButtons = {
94
+ args: {
95
+ show: true,
96
+ cancelButton: false,
97
+ okButton: false
98
+ }
99
+ };
100
+ export const OKDisabled = {
101
+ args: {
102
+ show: true,
103
+ okButton: 'Save',
104
+ okDisabled: true
105
+ }
106
+ };
107
+ export const NoCloseOnOK = {
108
+ args: {
109
+ show: true,
110
+ okButton: 'Validate',
111
+ noCloseOnOK: true
112
+ }
113
+ };
114
+ export const WithActivityOverlay = {
115
+ args: {
116
+ show: true,
117
+ okButton: 'Processing...',
118
+ disable: true
119
+ }
120
+ };
121
+ export const FormSubmitType = {
122
+ args: {
123
+ show: true,
124
+ okButton: 'Submit',
125
+ okType: 'submit'
126
+ }
127
+ };
128
+ export const NoBorderFooter = {
129
+ args: {
130
+ show: true,
131
+ borderFooter: false
132
+ }
133
+ };
134
+ export const OverflowVisible = {
135
+ args: {
136
+ show: true,
137
+ overflowY: 'visible'
138
+ }
139
+ };
package/dist/Modal.svelte CHANGED
@@ -1,9 +1,40 @@
1
1
  <!--
2
2
  @component
3
+ Full-featured modal dialog with draggable header, keyboard shortcuts, and flexible content slots.
4
+ Replaces native <dialog> element or custom div overlays.
3
5
 
4
- This component presents a modal window using the HTML5 dialog element
5
- @param {any} show A property that determines if the modal should be shown or not
6
- @param {any} noShowValue A property that, if equal to the show property, will hide the modal, otherwise show the modal
6
+ @example
7
+ ```svelte
8
+ <script>
9
+ import { Modal } from 'intelliwaketssveltekitv25';
10
+ let showModal = $state(false);
11
+ </script>
12
+
13
+ <Modal
14
+ bind:show={showModal}
15
+ okButton="Save"
16
+ cancelButton="Cancel"
17
+ >
18
+ {#snippet header()}
19
+ Edit Settings
20
+ {/snippet}
21
+ {#snippet body()}
22
+ <p>Modal content...</p>
23
+ {/snippet}
24
+ </Modal>
25
+ ```
26
+
27
+ @remarks
28
+ - Uses Svelte 5 $bindable rune for two-way binding of show state
29
+ - Draggable: click and drag header to reposition modal
30
+ - Keyboard shortcuts: Enter triggers OK, Escape cancels
31
+ - Backdrop click closes modal (triggers cancel action)
32
+ - Activity overlay support for async operations
33
+ - Multiple Snippet slots for flexible layouts (header, body, leftFooter, centerFooter, rightFooter)
34
+
35
+ @see ModalFormAction - Specialized modal for SvelteKit form actions
36
+ @see ModalPromptControl - Modal with prompt/confirmation patterns
37
+ @see ActivityOverlay - Loading overlay component (used internally)
7
38
  -->
8
39
 
9
40
  <script lang='ts'>
@@ -37,9 +37,41 @@ type $$ComponentProps = {
37
37
  onClose?: () => void;
38
38
  };
39
39
  /**
40
- * This component presents a modal window using the HTML5 dialog element
41
- * @param {any} show A property that determines if the modal should be shown or not
42
- * @param {any} noShowValue A property that, if equal to the show property, will hide the modal, otherwise show the modal
40
+ * Full-featured modal dialog with draggable header, keyboard shortcuts, and flexible content slots.
41
+ * Replaces native <dialog> element or custom div overlays.
42
+ *
43
+ * @example
44
+ * ```svelte
45
+ * <script>
46
+ * import { Modal } from 'intelliwaketssveltekitv25';
47
+ * let showModal = $state(false);
48
+ * </script>
49
+ *
50
+ * <Modal
51
+ * bind:show={showModal}
52
+ * okButton="Save"
53
+ * cancelButton="Cancel"
54
+ * >
55
+ * {#snippet header()}
56
+ * Edit Settings
57
+ * {/snippet}
58
+ * {#snippet body()}
59
+ * <p>Modal content...</p>
60
+ * {/snippet}
61
+ * </Modal>
62
+ * ```
63
+ *
64
+ * @remarks
65
+ * - Uses Svelte 5 $bindable rune for two-way binding of show state
66
+ * - Draggable: click and drag header to reposition modal
67
+ * - Keyboard shortcuts: Enter triggers OK, Escape cancels
68
+ * - Backdrop click closes modal (triggers cancel action)
69
+ * - Activity overlay support for async operations
70
+ * - Multiple Snippet slots for flexible layouts (header, body, leftFooter, centerFooter, rightFooter)
71
+ *
72
+ * @see ModalFormAction - Specialized modal for SvelteKit form actions
73
+ * @see ModalPromptControl - Modal with prompt/confirmation patterns
74
+ * @see ActivityOverlay - Loading overlay component (used internally)
43
75
  */
44
76
  declare const Modal: import("svelte").Component<$$ComponentProps, {}, "show">;
45
77
  type Modal = ReturnType<typeof Modal>;
@@ -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
+ };