@finsweet/webflow-apps-utils 1.0.50 → 1.0.52
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/dist/ui/components/index.d.ts +1 -0
- package/dist/ui/components/index.js +1 -0
- package/dist/ui/components/select/Select.stories.d.ts +1 -0
- package/dist/ui/components/select/Select.stories.js +35 -0
- package/dist/ui/components/select/Select.svelte +129 -82
- package/dist/ui/components/select/SelectWithFooterStory.svelte +54 -0
- package/dist/ui/components/select/SelectWithFooterStory.svelte.d.ts +11 -0
- package/dist/ui/components/select/index.d.ts +1 -1
- package/dist/ui/components/select/types.d.ts +8 -0
- package/dist/ui/components/tags/TagsInput.stories.d.ts +103 -0
- package/dist/ui/components/tags/TagsInput.stories.js +435 -0
- package/dist/ui/components/tags/TagsInput.svelte +492 -0
- package/dist/ui/components/tags/TagsInput.svelte.d.ts +4 -0
- package/dist/ui/components/tags/index.d.ts +2 -0
- package/dist/ui/components/tags/index.js +2 -0
- package/dist/ui/components/tags/types.d.ts +123 -0
- package/dist/ui/components/tags/types.js +1 -0
- package/dist/ui/icons/CheckCircleIcon.svelte +1 -1
- package/dist/ui/icons/CheckCircleOutlinedIcon.svelte +1 -1
- package/dist/ui/icons/CloseCircleIcon.svelte +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
import TagsInput from './TagsInput.svelte';
|
|
2
|
+
const meta = {
|
|
3
|
+
title: 'Ui/TagsInput',
|
|
4
|
+
component: TagsInput,
|
|
5
|
+
parameters: {
|
|
6
|
+
layout: 'centered',
|
|
7
|
+
docs: {
|
|
8
|
+
description: {
|
|
9
|
+
component: 'A versatile tags input component with support for various states, validation, and customization. Similar to shadcn tags input but styled for our design system.'
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
args: {
|
|
14
|
+
width: '420px',
|
|
15
|
+
height: '70px'
|
|
16
|
+
},
|
|
17
|
+
tags: ['autodocs'],
|
|
18
|
+
argTypes: {
|
|
19
|
+
value: {
|
|
20
|
+
control: 'object',
|
|
21
|
+
description: 'Array of tag values'
|
|
22
|
+
},
|
|
23
|
+
placeholder: {
|
|
24
|
+
control: 'text',
|
|
25
|
+
description: 'Placeholder text when no tags and input is empty'
|
|
26
|
+
},
|
|
27
|
+
disabled: {
|
|
28
|
+
control: 'boolean',
|
|
29
|
+
description: 'Disables the entire component'
|
|
30
|
+
},
|
|
31
|
+
loading: {
|
|
32
|
+
control: 'boolean',
|
|
33
|
+
description: 'Shows loading state'
|
|
34
|
+
},
|
|
35
|
+
invalid: {
|
|
36
|
+
control: 'boolean',
|
|
37
|
+
description: 'Applies invalid styling'
|
|
38
|
+
},
|
|
39
|
+
readonly: {
|
|
40
|
+
control: 'boolean',
|
|
41
|
+
description: 'Makes tags read-only (no adding/removing)'
|
|
42
|
+
},
|
|
43
|
+
maxTags: {
|
|
44
|
+
control: 'number',
|
|
45
|
+
description: 'Maximum number of tags allowed'
|
|
46
|
+
},
|
|
47
|
+
minTags: {
|
|
48
|
+
control: 'number',
|
|
49
|
+
description: 'Minimum number of tags required'
|
|
50
|
+
},
|
|
51
|
+
maxTagLength: {
|
|
52
|
+
control: 'number',
|
|
53
|
+
description: 'Maximum length of each tag'
|
|
54
|
+
},
|
|
55
|
+
allowDuplicates: {
|
|
56
|
+
control: 'boolean',
|
|
57
|
+
description: 'Whether to allow duplicate tags'
|
|
58
|
+
},
|
|
59
|
+
trimTags: {
|
|
60
|
+
control: 'boolean',
|
|
61
|
+
description: 'Whether to trim whitespace from tags'
|
|
62
|
+
},
|
|
63
|
+
width: {
|
|
64
|
+
control: 'text',
|
|
65
|
+
description: 'Custom width for the component'
|
|
66
|
+
},
|
|
67
|
+
height: {
|
|
68
|
+
control: 'text',
|
|
69
|
+
description: 'Custom height for the component'
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
export default meta;
|
|
74
|
+
// Basic stories
|
|
75
|
+
export const Default = {
|
|
76
|
+
args: {
|
|
77
|
+
placeholder: 'Add tags...'
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
export const WithInitialTags = {
|
|
81
|
+
args: {
|
|
82
|
+
value: ['JavaScript', 'TypeScript', 'Svelte'],
|
|
83
|
+
placeholder: 'Add more tags...'
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
export const WithPlaceholder = {
|
|
87
|
+
args: {
|
|
88
|
+
placeholder: 'Type and press Enter to add tags...'
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
// States
|
|
92
|
+
export const Disabled = {
|
|
93
|
+
args: {
|
|
94
|
+
value: ['Disabled', 'Tag'],
|
|
95
|
+
disabled: true
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
export const Loading = {
|
|
99
|
+
args: {
|
|
100
|
+
value: ['Loading', 'Tags'],
|
|
101
|
+
loading: true
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
export const Invalid = {
|
|
105
|
+
args: {
|
|
106
|
+
value: ['Invalid', 'Input'],
|
|
107
|
+
invalid: true
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
export const ReadOnly = {
|
|
111
|
+
args: {
|
|
112
|
+
value: ['Read', 'Only', 'Tags'],
|
|
113
|
+
readonly: true
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
// Constraints
|
|
117
|
+
export const MaxTags = {
|
|
118
|
+
args: {
|
|
119
|
+
value: ['Tag 1', 'Tag 2', 'Tag 3'],
|
|
120
|
+
maxTags: 3,
|
|
121
|
+
placeholder: 'Max 3 tags reached'
|
|
122
|
+
},
|
|
123
|
+
parameters: {
|
|
124
|
+
docs: {
|
|
125
|
+
description: {
|
|
126
|
+
story: 'Maximum of 3 tags allowed. Input is hidden when limit is reached.'
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
export const MaxTagLength = {
|
|
132
|
+
args: {
|
|
133
|
+
value: ['short'],
|
|
134
|
+
maxTagLength: 10,
|
|
135
|
+
placeholder: 'Max 10 chars per tag...'
|
|
136
|
+
},
|
|
137
|
+
parameters: {
|
|
138
|
+
docs: {
|
|
139
|
+
description: {
|
|
140
|
+
story: 'Tags cannot exceed 10 characters.'
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
export const NoDuplicates = {
|
|
146
|
+
args: {
|
|
147
|
+
value: ['unique', 'tags'],
|
|
148
|
+
allowDuplicates: false,
|
|
149
|
+
placeholder: 'Try adding "unique" again...'
|
|
150
|
+
},
|
|
151
|
+
parameters: {
|
|
152
|
+
docs: {
|
|
153
|
+
description: {
|
|
154
|
+
story: 'Duplicate tags are not allowed (default behavior).'
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
export const AllowDuplicates = {
|
|
160
|
+
args: {
|
|
161
|
+
value: ['duplicate', 'duplicate'],
|
|
162
|
+
allowDuplicates: true,
|
|
163
|
+
placeholder: 'Duplicates allowed here...'
|
|
164
|
+
},
|
|
165
|
+
parameters: {
|
|
166
|
+
docs: {
|
|
167
|
+
description: {
|
|
168
|
+
story: 'Duplicate tags are allowed when allowDuplicates is true.'
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
// Alert states
|
|
174
|
+
export const ErrorAlert = {
|
|
175
|
+
args: {
|
|
176
|
+
value: ['Invalid'],
|
|
177
|
+
invalid: true,
|
|
178
|
+
alert: {
|
|
179
|
+
type: 'error',
|
|
180
|
+
message: 'Please add at least 3 tags'
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
parameters: {
|
|
184
|
+
docs: {
|
|
185
|
+
description: {
|
|
186
|
+
story: 'Tags input with error state. Hover to see the error tooltip.'
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
export const SuccessAlert = {
|
|
192
|
+
args: {
|
|
193
|
+
value: ['Valid', 'Tags', 'Added'],
|
|
194
|
+
alert: {
|
|
195
|
+
type: 'success',
|
|
196
|
+
message: 'Tags are valid!'
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
parameters: {
|
|
200
|
+
docs: {
|
|
201
|
+
description: {
|
|
202
|
+
story: 'Tags input with success state. Hover to see the success tooltip.'
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
export const InfoAlert = {
|
|
208
|
+
args: {
|
|
209
|
+
value: ['Info'],
|
|
210
|
+
alert: {
|
|
211
|
+
type: 'info',
|
|
212
|
+
message: 'Add tags separated by comma or Enter'
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
parameters: {
|
|
216
|
+
docs: {
|
|
217
|
+
description: {
|
|
218
|
+
story: 'Tags input with info state. Hover to see the info tooltip.'
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
export const WarningAlert = {
|
|
224
|
+
args: {
|
|
225
|
+
value: ['Warning', 'Tag'],
|
|
226
|
+
alert: {
|
|
227
|
+
type: 'warning',
|
|
228
|
+
message: 'Some tags may need review'
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
parameters: {
|
|
232
|
+
docs: {
|
|
233
|
+
description: {
|
|
234
|
+
story: 'Tags input with warning state. Hover to see the warning tooltip.'
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
// Sizing
|
|
240
|
+
export const CustomWidth = {
|
|
241
|
+
args: {
|
|
242
|
+
value: ['Custom', 'Width'],
|
|
243
|
+
width: '400px',
|
|
244
|
+
placeholder: 'Wide input...'
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
export const CustomHeight = {
|
|
248
|
+
args: {
|
|
249
|
+
value: ['Custom', 'Height', 'With', 'Multiple', 'Tags'],
|
|
250
|
+
height: '80px',
|
|
251
|
+
placeholder: 'Taller input...'
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
export const FullWidth = {
|
|
255
|
+
args: {
|
|
256
|
+
value: ['Full'],
|
|
257
|
+
width: '100%',
|
|
258
|
+
placeholder: 'Full width input...'
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
// Interactive examples
|
|
262
|
+
export const InteractiveExample = {
|
|
263
|
+
args: {
|
|
264
|
+
value: ['React', 'Vue'],
|
|
265
|
+
placeholder: 'Add a framework...',
|
|
266
|
+
onValueChange: (tags) => console.log('Tags changed:', tags),
|
|
267
|
+
onTagAdd: (tag) => console.log('Tag added:', tag),
|
|
268
|
+
onTagRemove: (tag, index) => console.log('Tag removed:', tag, 'at index', index),
|
|
269
|
+
onInvalidTag: (tag, reason) => console.log('Invalid tag:', tag, 'Reason:', reason)
|
|
270
|
+
},
|
|
271
|
+
parameters: {
|
|
272
|
+
docs: {
|
|
273
|
+
description: {
|
|
274
|
+
story: 'Interactive example with all event handlers. Check the console for events.'
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
// Validation examples
|
|
280
|
+
export const CustomValidation = {
|
|
281
|
+
args: {
|
|
282
|
+
value: ['#valid'],
|
|
283
|
+
placeholder: 'Tags must start with #...',
|
|
284
|
+
validateTag: (tag) => {
|
|
285
|
+
if (!tag.startsWith('#')) {
|
|
286
|
+
return 'Tags must start with #';
|
|
287
|
+
}
|
|
288
|
+
return true;
|
|
289
|
+
},
|
|
290
|
+
onInvalidTag: (tag, reason) => console.log('Invalid:', tag, reason)
|
|
291
|
+
},
|
|
292
|
+
parameters: {
|
|
293
|
+
docs: {
|
|
294
|
+
description: {
|
|
295
|
+
story: 'Custom validation requiring tags to start with #. Try adding a tag without #.'
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
export const EmailValidation = {
|
|
301
|
+
args: {
|
|
302
|
+
value: ['user@example.com'],
|
|
303
|
+
placeholder: 'Add email addresses...',
|
|
304
|
+
validateTag: (tag) => {
|
|
305
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
306
|
+
if (!emailRegex.test(tag)) {
|
|
307
|
+
return 'Please enter a valid email';
|
|
308
|
+
}
|
|
309
|
+
return true;
|
|
310
|
+
},
|
|
311
|
+
onInvalidTag: (tag, reason) => console.log('Invalid:', tag, reason)
|
|
312
|
+
},
|
|
313
|
+
parameters: {
|
|
314
|
+
docs: {
|
|
315
|
+
description: {
|
|
316
|
+
story: 'Email validation example. Only valid email addresses are accepted.'
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
// Real-world examples
|
|
322
|
+
export const CategoryTags = {
|
|
323
|
+
args: {
|
|
324
|
+
value: ['Technology', 'Design', 'Marketing'],
|
|
325
|
+
placeholder: 'Add categories...',
|
|
326
|
+
maxTags: 5
|
|
327
|
+
},
|
|
328
|
+
parameters: {
|
|
329
|
+
docs: {
|
|
330
|
+
description: {
|
|
331
|
+
story: 'Category tagging with a maximum of 5 tags.'
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
export const SkillsTags = {
|
|
337
|
+
args: {
|
|
338
|
+
value: ['JavaScript', 'React', 'Node.js', 'CSS'],
|
|
339
|
+
placeholder: 'Add your skills...',
|
|
340
|
+
maxTagLength: 20
|
|
341
|
+
},
|
|
342
|
+
parameters: {
|
|
343
|
+
docs: {
|
|
344
|
+
description: {
|
|
345
|
+
story: 'Skills input with max tag length of 20 characters.'
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
export const KeywordsTags = {
|
|
351
|
+
args: {
|
|
352
|
+
value: ['seo', 'marketing', 'content'],
|
|
353
|
+
placeholder: 'Add keywords for SEO...',
|
|
354
|
+
maxTags: 10,
|
|
355
|
+
onValueChange: (tags) => console.log('Keywords:', tags)
|
|
356
|
+
},
|
|
357
|
+
parameters: {
|
|
358
|
+
docs: {
|
|
359
|
+
description: {
|
|
360
|
+
story: 'SEO keywords input with up to 10 tags.'
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
export const FormIntegration = {
|
|
366
|
+
args: {
|
|
367
|
+
id: 'form-tags',
|
|
368
|
+
value: ['tag1'],
|
|
369
|
+
placeholder: 'Add tags for form...',
|
|
370
|
+
alert: {
|
|
371
|
+
type: 'info',
|
|
372
|
+
message: 'Tags will be submitted with the form'
|
|
373
|
+
}
|
|
374
|
+
},
|
|
375
|
+
parameters: {
|
|
376
|
+
docs: {
|
|
377
|
+
description: {
|
|
378
|
+
story: 'Example showing tags input in a form context. Compatible with Zod validation schemas.'
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
// Edge cases
|
|
384
|
+
export const ManyTags = {
|
|
385
|
+
args: {
|
|
386
|
+
value: Array.from({ length: 20 }, (_, i) => `Tag ${i + 1}`),
|
|
387
|
+
placeholder: 'Lots of tags...'
|
|
388
|
+
},
|
|
389
|
+
parameters: {
|
|
390
|
+
docs: {
|
|
391
|
+
description: {
|
|
392
|
+
story: 'Performance test with 20 tags.'
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
export const LongTags = {
|
|
398
|
+
args: {
|
|
399
|
+
value: ['This is a very long tag name', 'Another extremely long tag'],
|
|
400
|
+
placeholder: 'Long tags get truncated...'
|
|
401
|
+
},
|
|
402
|
+
parameters: {
|
|
403
|
+
docs: {
|
|
404
|
+
description: {
|
|
405
|
+
story: 'Long tags are truncated with ellipsis.'
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
};
|
|
410
|
+
export const SpecialCharacters = {
|
|
411
|
+
args: {
|
|
412
|
+
value: ['C++', 'C#', '.NET', '@angular', '#svelte'],
|
|
413
|
+
placeholder: 'Special characters work...'
|
|
414
|
+
},
|
|
415
|
+
parameters: {
|
|
416
|
+
docs: {
|
|
417
|
+
description: {
|
|
418
|
+
story: 'Tags with special characters are supported.'
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
export const UnicodeSupport = {
|
|
424
|
+
args: {
|
|
425
|
+
value: ['日本語', '中文', '한국어', '🎉', '✨'],
|
|
426
|
+
placeholder: 'Unicode support...'
|
|
427
|
+
},
|
|
428
|
+
parameters: {
|
|
429
|
+
docs: {
|
|
430
|
+
description: {
|
|
431
|
+
story: 'Full Unicode support including CJK characters and emoji.'
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
};
|