@getmicdrop/svelte-components 5.0.0 → 5.1.1

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.
Files changed (37) hide show
  1. package/dist/primitives/Button/Button.stories.svelte +46 -79
  2. package/dist/primitives/Button/Button.stories.svelte.d.ts.map +1 -1
  3. package/dist/primitives/Button/Button.svelte +11 -5
  4. package/dist/primitives/Button/Button.svelte.d.ts +2 -0
  5. package/dist/primitives/Button/Button.svelte.d.ts.map +1 -1
  6. package/dist/primitives/Button/ButtonVariantShowcase.svelte +137 -0
  7. package/dist/primitives/Button/ButtonVariantShowcase.svelte.d.ts +27 -0
  8. package/dist/primitives/Button/ButtonVariantShowcase.svelte.d.ts.map +1 -0
  9. package/dist/recipes/SuperLogin/SuperLogin.svelte +5 -5
  10. package/dist/stories/ButtonAuditDashboard.stories.svelte +14 -0
  11. package/dist/stories/ButtonAuditDashboard.stories.svelte.d.ts +28 -0
  12. package/dist/stories/ButtonAuditDashboard.stories.svelte.d.ts.map +1 -0
  13. package/dist/stories/ButtonAuditDashboard.svelte +444 -0
  14. package/dist/stories/ButtonAuditDashboard.svelte.d.ts +7 -0
  15. package/dist/stories/ButtonAuditDashboard.svelte.d.ts.map +1 -0
  16. package/dist/stories/ButtonAuditReview.stories.svelte +14 -0
  17. package/dist/stories/ButtonAuditReview.stories.svelte.d.ts +28 -0
  18. package/dist/stories/ButtonAuditReview.stories.svelte.d.ts.map +1 -0
  19. package/dist/stories/ButtonAuditReview.svelte +463 -0
  20. package/dist/stories/ButtonAuditReview.svelte.d.ts +7 -0
  21. package/dist/stories/ButtonAuditReview.svelte.d.ts.map +1 -0
  22. package/dist/stories/ButtonGridView.stories.svelte +14 -0
  23. package/dist/stories/ButtonGridView.stories.svelte.d.ts +28 -0
  24. package/dist/stories/ButtonGridView.stories.svelte.d.ts.map +1 -0
  25. package/dist/stories/ButtonGridView.svelte +146 -0
  26. package/dist/stories/ButtonGridView.svelte.d.ts +7 -0
  27. package/dist/stories/ButtonGridView.svelte.d.ts.map +1 -0
  28. package/dist/stories/ButtonShowcase.stories.svelte +14 -0
  29. package/dist/stories/ButtonShowcase.stories.svelte.d.ts +28 -0
  30. package/dist/stories/ButtonShowcase.stories.svelte.d.ts.map +1 -0
  31. package/dist/stories/ButtonShowcase.svelte +529 -0
  32. package/dist/stories/ButtonShowcase.svelte.d.ts +7 -0
  33. package/dist/stories/ButtonShowcase.svelte.d.ts.map +1 -0
  34. package/dist/stories/DesignSystemAudit.stories.svelte +4 -12
  35. package/dist/stories/DesignSystemAudit.stories.svelte.d.ts.map +1 -1
  36. package/dist/stories/button-audit-manifest.json +11187 -0
  37. package/package.json +5 -2
@@ -0,0 +1,463 @@
1
+ <script>
2
+ import Button from '../primitives/Button/Button.svelte';
3
+
4
+ // Issue severity levels
5
+ const SEVERITY = {
6
+ HIGH: 'high',
7
+ MEDIUM: 'medium',
8
+ LOW: 'low'
9
+ };
10
+
11
+ // All identified issues
12
+ const issues = [
13
+ // HIGH SEVERITY - Invalid variants that won't render correctly
14
+ {
15
+ id: 1,
16
+ severity: SEVERITY.HIGH,
17
+ category: 'Invalid Variant',
18
+ problem: 'Variant "secondary" is not recognized',
19
+ location: 'CustomDropzone.svelte, widgets/+page.svelte',
20
+ count: 4,
21
+ current: { variant: 'secondary', text: 'Browse files' },
22
+ proposed: { variant: 'alternative', text: 'Browse files' },
23
+ explanation: '"secondary" should map to "alternative" (gray outline style)'
24
+ },
25
+ {
26
+ id: 2,
27
+ severity: SEVERITY.HIGH,
28
+ category: 'Invalid Variant',
29
+ problem: 'Variant "danger" is not recognized',
30
+ location: 'widgets/+page.svelte:309',
31
+ count: 1,
32
+ current: { variant: 'danger', text: 'Delete' },
33
+ proposed: { variant: 'red', text: 'Delete' },
34
+ explanation: '"danger" should be "red" for destructive actions'
35
+ },
36
+ {
37
+ id: 3,
38
+ severity: SEVERITY.HIGH,
39
+ category: 'Invalid Variant',
40
+ problem: 'Variant "text" is not recognized',
41
+ location: 'PromocodeInput.svelte:169',
42
+ count: 1,
43
+ current: { variant: 'text', text: 'Apply' },
44
+ proposed: { variant: 'ghost', text: 'Apply' },
45
+ explanation: '"text" should be "ghost" for text-only buttons'
46
+ },
47
+ {
48
+ id: 4,
49
+ severity: SEVERITY.HIGH,
50
+ category: 'Invalid Variant',
51
+ problem: 'Variant "blue-text" is not recognized',
52
+ location: 'csv-import/results, team/edit-user',
53
+ count: 5,
54
+ current: { variant: 'blue-text', text: 'Add more events' },
55
+ proposed: { variant: 'link', text: 'Add more events' },
56
+ explanation: '"blue-text" should be "link" for link-styled buttons'
57
+ },
58
+ {
59
+ id: 5,
60
+ severity: SEVERITY.HIGH,
61
+ category: 'Invalid Variant',
62
+ problem: 'Variant "gray-solid" is not recognized',
63
+ location: 'payments/+page.svelte',
64
+ count: 2,
65
+ current: { variant: 'gray-solid', text: 'Set Default' },
66
+ proposed: { variant: 'alternative', text: 'Set Default' },
67
+ explanation: '"gray-solid" doesn\'t exist - use "alternative" for gray buttons'
68
+ },
69
+ {
70
+ id: 6,
71
+ severity: SEVERITY.HIGH,
72
+ category: 'Invalid Variant',
73
+ problem: 'Variant "gray" is not recognized',
74
+ location: 'invite/accept/+page.svelte:64',
75
+ count: 1,
76
+ current: { variant: 'gray', text: 'Try Again' },
77
+ proposed: { variant: 'alternative', text: 'Try Again' },
78
+ explanation: '"gray" should be "alternative"'
79
+ },
80
+ {
81
+ id: 7,
82
+ severity: SEVERITY.HIGH,
83
+ category: 'Invalid Variant',
84
+ problem: 'Variant "custom" is not recognized',
85
+ location: 'ProfilePictureSection.svelte:109',
86
+ count: 1,
87
+ current: { variant: 'custom', text: '(icon only)' },
88
+ proposed: { variant: 'icon', text: '' },
89
+ explanation: '"custom" for icon buttons should be "icon" variant'
90
+ },
91
+ {
92
+ id: 8,
93
+ severity: SEVERITY.HIGH,
94
+ category: 'Invalid Variant',
95
+ problem: 'Variant "green-solid" is not recognized',
96
+ location: 'Unknown location',
97
+ count: 1,
98
+ current: { variant: 'green-solid', text: 'Success' },
99
+ proposed: { variant: 'default', text: 'Success', success: true },
100
+ explanation: 'Green success buttons should use success prop, not variant'
101
+ },
102
+
103
+ // MEDIUM SEVERITY - Invalid sizes
104
+ // NOTE: full-md-auto and half are now VALID standard sizes
105
+ // {
106
+ // id: 9,
107
+ // severity: SEVERITY.MEDIUM,
108
+ // category: 'RESOLVED',
109
+ // problem: 'Size "full-md-auto" - NOW A STANDARD SIZE',
110
+ // explanation: 'Added to Button component: full width mobile, auto width md+'
111
+ // },
112
+ // {
113
+ // id: 10,
114
+ // severity: SEVERITY.MEDIUM,
115
+ // category: 'RESOLVED',
116
+ // problem: 'Size "half" - NOW A STANDARD SIZE',
117
+ // explanation: 'Added to Button component: 50% width with medium text'
118
+ // },
119
+ {
120
+ id: 11,
121
+ severity: SEVERITY.MEDIUM,
122
+ category: 'Invalid Size',
123
+ problem: 'Size "small" should be "sm"',
124
+ location: 'Various files',
125
+ count: 3,
126
+ current: { variant: 'blue-solid', size: 'small', text: 'Submit' },
127
+ proposed: { variant: 'default', size: 'sm', text: 'Submit' },
128
+ explanation: 'Standard size name is "sm", not "small"'
129
+ },
130
+
131
+ // LOW SEVERITY - Style consistency
132
+ {
133
+ id: 12,
134
+ severity: SEVERITY.LOW,
135
+ category: 'Legacy Naming',
136
+ problem: '801 buttons use legacy variant names',
137
+ location: 'Throughout codebase',
138
+ count: 801,
139
+ current: { variant: 'blue-solid', text: 'Save' },
140
+ proposed: { variant: 'default', text: 'Save' },
141
+ explanation: 'Consider migrating to Flowbite naming: blue-solid → default'
142
+ },
143
+ {
144
+ id: 13,
145
+ severity: SEVERITY.LOW,
146
+ category: 'Legacy Naming',
147
+ problem: 'gray-outline should be alternative',
148
+ location: 'Throughout codebase',
149
+ count: 128,
150
+ current: { variant: 'gray-outline', text: 'Cancel' },
151
+ proposed: { variant: 'alternative', text: 'Cancel' },
152
+ explanation: 'Flowbite naming: gray-outline → alternative'
153
+ },
154
+ {
155
+ id: 14,
156
+ severity: SEVERITY.LOW,
157
+ category: 'Empty Text',
158
+ problem: 'Non-icon buttons with no visible text',
159
+ location: 'Various components',
160
+ count: 191,
161
+ current: { variant: 'blue-solid', text: '' },
162
+ proposed: { variant: 'icon', text: '' },
163
+ explanation: 'Buttons with only icons should use variant="icon"'
164
+ }
165
+ ];
166
+
167
+ // Group by severity
168
+ const highSeverity = issues.filter(i => i.severity === SEVERITY.HIGH);
169
+ const mediumSeverity = issues.filter(i => i.severity === SEVERITY.MEDIUM);
170
+ const lowSeverity = issues.filter(i => i.severity === SEVERITY.LOW);
171
+
172
+ // Approval state
173
+ let approvals = $state({});
174
+
175
+ function approve(id) {
176
+ approvals[id] = 'approved';
177
+ }
178
+
179
+ function reject(id) {
180
+ approvals[id] = 'rejected';
181
+ }
182
+
183
+ function getStatusClass(id) {
184
+ if (approvals[id] === 'approved') return 'bg-green-100 border-green-500';
185
+ if (approvals[id] === 'rejected') return 'bg-red-100 border-red-500';
186
+ return 'bg-white border-gray-200';
187
+ }
188
+
189
+ function getSeverityColor(severity) {
190
+ if (severity === SEVERITY.HIGH) return 'bg-red-100 text-red-800';
191
+ if (severity === SEVERITY.MEDIUM) return 'bg-yellow-100 text-yellow-800';
192
+ return 'bg-blue-100 text-blue-800';
193
+ }
194
+ </script>
195
+
196
+ <div class="p-6 max-w-7xl mx-auto space-y-8">
197
+ <div class="text-center mb-8">
198
+ <h1 class="text-3xl font-bold text-gray-900 mb-2">Button Audit Review</h1>
199
+ <p class="text-gray-600">Review identified issues and approve/reject proposed fixes</p>
200
+ <div class="flex justify-center gap-4 mt-4 text-sm">
201
+ <span class="px-3 py-1 rounded-full bg-red-100 text-red-800">High: {highSeverity.length} issues</span>
202
+ <span class="px-3 py-1 rounded-full bg-yellow-100 text-yellow-800">Medium: {mediumSeverity.length} issues</span>
203
+ <span class="px-3 py-1 rounded-full bg-blue-100 text-blue-800">Low: {lowSeverity.length} issues</span>
204
+ </div>
205
+ </div>
206
+
207
+ <!-- HIGH SEVERITY -->
208
+ <section>
209
+ <h2 class="text-xl font-bold text-red-700 mb-4 flex items-center gap-2">
210
+ <span class="w-3 h-3 rounded-full bg-red-500"></span>
211
+ High Severity - Invalid Variants ({highSeverity.length})
212
+ </h2>
213
+ <p class="text-gray-600 mb-4">These buttons use variant names that don't exist and may not render correctly.</p>
214
+
215
+ <div class="space-y-4">
216
+ {#each highSeverity as issue}
217
+ <div class="border-2 rounded-lg p-4 {getStatusClass(issue.id)}">
218
+ <div class="flex justify-between items-start mb-4">
219
+ <div>
220
+ <span class="text-xs font-medium px-2 py-1 rounded {getSeverityColor(issue.severity)}">
221
+ {issue.category}
222
+ </span>
223
+ <span class="text-xs text-gray-500 ml-2">{issue.count} occurrence{issue.count > 1 ? 's' : ''}</span>
224
+ </div>
225
+ <div class="flex gap-2">
226
+ <button
227
+ onclick={() => approve(issue.id)}
228
+ class="px-3 py-1 text-sm rounded bg-green-600 text-white hover:bg-green-700"
229
+ >
230
+ Approve
231
+ </button>
232
+ <button
233
+ onclick={() => reject(issue.id)}
234
+ class="px-3 py-1 text-sm rounded bg-red-600 text-white hover:bg-red-700"
235
+ >
236
+ Reject
237
+ </button>
238
+ </div>
239
+ </div>
240
+
241
+ <h3 class="font-semibold text-gray-900 mb-2">{issue.problem}</h3>
242
+ <p class="text-sm text-gray-500 mb-4">Location: {issue.location}</p>
243
+
244
+ <div class="grid grid-cols-2 gap-6">
245
+ <!-- Current State -->
246
+ <div class="space-y-2">
247
+ <div class="text-sm font-medium text-red-600">Current (Problem)</div>
248
+ <div class="p-4 bg-gray-50 rounded-lg flex items-center justify-center min-h-[60px]">
249
+ <Button
250
+ variant={issue.current.variant}
251
+ size={issue.current.size || 'md'}
252
+ >
253
+ {issue.current.text || '(no text)'}
254
+ </Button>
255
+ </div>
256
+ <code class="text-xs bg-gray-100 px-2 py-1 rounded block">
257
+ variant="{issue.current.variant}"
258
+ </code>
259
+ </div>
260
+
261
+ <!-- Proposed Fix -->
262
+ <div class="space-y-2">
263
+ <div class="text-sm font-medium text-green-600">Proposed Fix</div>
264
+ <div class="p-4 bg-green-50 rounded-lg flex items-center justify-center min-h-[60px]">
265
+ <Button
266
+ variant={issue.proposed.variant}
267
+ size={issue.proposed.size || 'md'}
268
+ success={issue.proposed.success || false}
269
+ >
270
+ {issue.proposed.text || '(no text)'}
271
+ </Button>
272
+ </div>
273
+ <code class="text-xs bg-gray-100 px-2 py-1 rounded block">
274
+ variant="{issue.proposed.variant}"
275
+ </code>
276
+ </div>
277
+ </div>
278
+
279
+ <p class="mt-4 text-sm text-gray-700 bg-blue-50 p-3 rounded">
280
+ <strong>Explanation:</strong> {issue.explanation}
281
+ </p>
282
+ </div>
283
+ {/each}
284
+ </div>
285
+ </section>
286
+
287
+ <!-- MEDIUM SEVERITY -->
288
+ <section>
289
+ <h2 class="text-xl font-bold text-yellow-700 mb-4 flex items-center gap-2">
290
+ <span class="w-3 h-3 rounded-full bg-yellow-500"></span>
291
+ Medium Severity - Invalid Sizes ({mediumSeverity.length})
292
+ </h2>
293
+ <p class="text-gray-600 mb-4">These buttons use non-standard size values.</p>
294
+
295
+ <div class="space-y-4">
296
+ {#each mediumSeverity as issue}
297
+ <div class="border-2 rounded-lg p-4 {getStatusClass(issue.id)}">
298
+ <div class="flex justify-between items-start mb-4">
299
+ <div>
300
+ <span class="text-xs font-medium px-2 py-1 rounded {getSeverityColor(issue.severity)}">
301
+ {issue.category}
302
+ </span>
303
+ <span class="text-xs text-gray-500 ml-2">{issue.count} occurrence{issue.count > 1 ? 's' : ''}</span>
304
+ </div>
305
+ <div class="flex gap-2">
306
+ <button
307
+ onclick={() => approve(issue.id)}
308
+ class="px-3 py-1 text-sm rounded bg-green-600 text-white hover:bg-green-700"
309
+ >
310
+ Approve
311
+ </button>
312
+ <button
313
+ onclick={() => reject(issue.id)}
314
+ class="px-3 py-1 text-sm rounded bg-red-600 text-white hover:bg-red-700"
315
+ >
316
+ Reject
317
+ </button>
318
+ </div>
319
+ </div>
320
+
321
+ <h3 class="font-semibold text-gray-900 mb-2">{issue.problem}</h3>
322
+ <p class="text-sm text-gray-500 mb-4">Location: {issue.location}</p>
323
+
324
+ <div class="grid grid-cols-2 gap-6">
325
+ <div class="space-y-2">
326
+ <div class="text-sm font-medium text-red-600">Current (Problem)</div>
327
+ <div class="p-4 bg-gray-50 rounded-lg flex items-center justify-center min-h-[60px]">
328
+ <Button
329
+ variant={issue.current.variant}
330
+ size={issue.current.size || 'md'}
331
+ >
332
+ {issue.current.text}
333
+ </Button>
334
+ </div>
335
+ <code class="text-xs bg-gray-100 px-2 py-1 rounded block">
336
+ size="{issue.current.size}"
337
+ </code>
338
+ </div>
339
+
340
+ <div class="space-y-2">
341
+ <div class="text-sm font-medium text-green-600">Proposed Fix</div>
342
+ <div class="p-4 bg-green-50 rounded-lg flex items-center justify-center min-h-[60px]">
343
+ <Button
344
+ variant={issue.proposed.variant}
345
+ size={issue.proposed.size || 'md'}
346
+ class={issue.proposed.className || ''}
347
+ >
348
+ {issue.proposed.text}
349
+ </Button>
350
+ </div>
351
+ <code class="text-xs bg-gray-100 px-2 py-1 rounded block">
352
+ size="{issue.proposed.size}"{issue.proposed.className ? ` class="${issue.proposed.className}"` : ''}
353
+ </code>
354
+ </div>
355
+ </div>
356
+
357
+ <p class="mt-4 text-sm text-gray-700 bg-blue-50 p-3 rounded">
358
+ <strong>Explanation:</strong> {issue.explanation}
359
+ </p>
360
+ </div>
361
+ {/each}
362
+ </div>
363
+ </section>
364
+
365
+ <!-- LOW SEVERITY -->
366
+ <section>
367
+ <h2 class="text-xl font-bold text-blue-700 mb-4 flex items-center gap-2">
368
+ <span class="w-3 h-3 rounded-full bg-blue-500"></span>
369
+ Low Severity - Style Consistency ({lowSeverity.length})
370
+ </h2>
371
+ <p class="text-gray-600 mb-4">These are style improvements for consistency, not functional issues.</p>
372
+
373
+ <div class="space-y-4">
374
+ {#each lowSeverity as issue}
375
+ <div class="border-2 rounded-lg p-4 {getStatusClass(issue.id)}">
376
+ <div class="flex justify-between items-start mb-4">
377
+ <div>
378
+ <span class="text-xs font-medium px-2 py-1 rounded {getSeverityColor(issue.severity)}">
379
+ {issue.category}
380
+ </span>
381
+ <span class="text-xs text-gray-500 ml-2">{issue.count} occurrence{issue.count > 1 ? 's' : ''}</span>
382
+ </div>
383
+ <div class="flex gap-2">
384
+ <button
385
+ onclick={() => approve(issue.id)}
386
+ class="px-3 py-1 text-sm rounded bg-green-600 text-white hover:bg-green-700"
387
+ >
388
+ Approve
389
+ </button>
390
+ <button
391
+ onclick={() => reject(issue.id)}
392
+ class="px-3 py-1 text-sm rounded bg-red-600 text-white hover:bg-red-700"
393
+ >
394
+ Reject
395
+ </button>
396
+ </div>
397
+ </div>
398
+
399
+ <h3 class="font-semibold text-gray-900 mb-2">{issue.problem}</h3>
400
+ <p class="text-sm text-gray-500 mb-4">Location: {issue.location}</p>
401
+
402
+ <div class="grid grid-cols-2 gap-6">
403
+ <div class="space-y-2">
404
+ <div class="text-sm font-medium text-gray-600">Current</div>
405
+ <div class="p-4 bg-gray-50 rounded-lg flex items-center justify-center min-h-[60px]">
406
+ <Button
407
+ variant={issue.current.variant}
408
+ size={issue.current.size || 'md'}
409
+ >
410
+ {issue.current.text || '(icon)'}
411
+ </Button>
412
+ </div>
413
+ <code class="text-xs bg-gray-100 px-2 py-1 rounded block">
414
+ variant="{issue.current.variant}"
415
+ </code>
416
+ </div>
417
+
418
+ <div class="space-y-2">
419
+ <div class="text-sm font-medium text-green-600">Flowbite Standard</div>
420
+ <div class="p-4 bg-green-50 rounded-lg flex items-center justify-center min-h-[60px]">
421
+ <Button
422
+ variant={issue.proposed.variant}
423
+ size={issue.proposed.size || 'md'}
424
+ >
425
+ {issue.proposed.text || '(icon)'}
426
+ </Button>
427
+ </div>
428
+ <code class="text-xs bg-gray-100 px-2 py-1 rounded block">
429
+ variant="{issue.proposed.variant}"
430
+ </code>
431
+ </div>
432
+ </div>
433
+
434
+ <p class="mt-4 text-sm text-gray-700 bg-blue-50 p-3 rounded">
435
+ <strong>Explanation:</strong> {issue.explanation}
436
+ </p>
437
+ </div>
438
+ {/each}
439
+ </div>
440
+ </section>
441
+
442
+ <!-- Summary -->
443
+ <section class="mt-8 p-6 bg-gray-100 rounded-lg">
444
+ <h2 class="text-xl font-bold mb-4">Summary</h2>
445
+ <div class="grid grid-cols-3 gap-4 text-center">
446
+ <div class="p-4 bg-white rounded-lg">
447
+ <div class="text-3xl font-bold text-red-600">{highSeverity.reduce((sum, i) => sum + i.count, 0)}</div>
448
+ <div class="text-sm text-gray-600">High Severity Buttons</div>
449
+ </div>
450
+ <div class="p-4 bg-white rounded-lg">
451
+ <div class="text-3xl font-bold text-yellow-600">{mediumSeverity.reduce((sum, i) => sum + i.count, 0)}</div>
452
+ <div class="text-sm text-gray-600">Medium Severity Buttons</div>
453
+ </div>
454
+ <div class="p-4 bg-white rounded-lg">
455
+ <div class="text-3xl font-bold text-blue-600">{lowSeverity.reduce((sum, i) => sum + i.count, 0)}</div>
456
+ <div class="text-sm text-gray-600">Low Severity Buttons</div>
457
+ </div>
458
+ </div>
459
+ <p class="mt-4 text-sm text-gray-600">
460
+ Total buttons audited: 916 | Issues found: {issues.length} categories affecting {issues.reduce((sum, i) => sum + i.count, 0)} buttons
461
+ </p>
462
+ </section>
463
+ </div>
@@ -0,0 +1,7 @@
1
+ export default ButtonAuditReview;
2
+ type ButtonAuditReview = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<Record<string, never>>): void;
5
+ };
6
+ declare const ButtonAuditReview: import("svelte").Component<Record<string, never>, {}, "">;
7
+ //# sourceMappingURL=ButtonAuditReview.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ButtonAuditReview.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/stories/ButtonAuditReview.svelte.js"],"names":[],"mappings":";;;;;AAibA,2FAAgE"}
@@ -0,0 +1,14 @@
1
+ <script module>
2
+ import { defineMeta } from "@storybook/addon-svelte-csf";
3
+ import ButtonGridView from "./ButtonGridView.svelte";
4
+
5
+ const { Story } = defineMeta({
6
+ title: "Design System/Button Grid View",
7
+ component: ButtonGridView,
8
+ parameters: {
9
+ layout: 'fullscreen',
10
+ }
11
+ });
12
+ </script>
13
+
14
+ <Story name="All Buttons" />
@@ -0,0 +1,28 @@
1
+ export default ButtonGridView;
2
+ type ButtonGridView = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ declare const ButtonGridView: $$__sveltets_2_IsomorphicComponent<{
10
+ [x: string]: never;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}, {}, string>;
14
+ import ButtonGridView from "./ButtonGridView.svelte";
15
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
16
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
17
+ $$bindings?: Bindings;
18
+ } & Exports;
19
+ (internal: unknown, props: {
20
+ $$events?: Events;
21
+ $$slots?: Slots;
22
+ }): Exports & {
23
+ $set?: any;
24
+ $on?: any;
25
+ };
26
+ z_$$bindings?: Bindings;
27
+ }
28
+ //# sourceMappingURL=ButtonGridView.stories.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ButtonGridView.stories.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/stories/ButtonGridView.stories.svelte.js"],"names":[],"mappings":";;;;;;;;AA4BA;;;;mBAA0H;2BAxB7F,yBAAyB;6CAeT,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,OAAO,OAAO,QAAQ;IAC3L,cAAc,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,WAAW,OAAO,SAAS;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,146 @@
1
+ <script>
2
+ import Button from '../primitives/Button/Button.svelte';
3
+ import manifest from './button-audit-manifest.json';
4
+
5
+ // Flatten all buttons into a single array with source info
6
+ const allButtons = Object.entries(manifest.categories).flatMap(([category, routes]) =>
7
+ routes.flatMap(route =>
8
+ route.buttons.map(button => ({
9
+ ...button,
10
+ category,
11
+ file: route.file,
12
+ fullPath: route.fullPath
13
+ }))
14
+ )
15
+ );
16
+
17
+ // Dark mode
18
+ let isDark = $state(false);
19
+ function toggleDark() {
20
+ isDark = !isDark;
21
+ document.documentElement.classList.toggle('dark', isDark);
22
+ }
23
+
24
+ // Filters
25
+ let variantFilter = $state('all');
26
+ let sizeFilter = $state('all');
27
+ let searchQuery = $state('');
28
+
29
+ const allVariants = [...new Set(allButtons.map(b => b.variant))].sort();
30
+ const allSizes = [...new Set(allButtons.map(b => b.size))].sort();
31
+
32
+ // Filtered buttons
33
+ let filtered = $derived.by(() => {
34
+ return allButtons.filter(b => {
35
+ if (variantFilter !== 'all' && b.variant !== variantFilter) return false;
36
+ if (sizeFilter !== 'all' && b.size !== sizeFilter) return false;
37
+ if (searchQuery) {
38
+ const q = searchQuery.toLowerCase();
39
+ return b.text.toLowerCase().includes(q) ||
40
+ b.file.toLowerCase().includes(q) ||
41
+ b.variant.toLowerCase().includes(q);
42
+ }
43
+ return true;
44
+ });
45
+ });
46
+
47
+ // Get short file name
48
+ function shortFile(file) {
49
+ const parts = file.split('/');
50
+ return parts.slice(-2).join('/');
51
+ }
52
+
53
+ // VS Code link
54
+ function vscodeLink(fullPath, line) {
55
+ return `vscode://file${fullPath}:${line}`;
56
+ }
57
+
58
+ // Variant colors
59
+ function variantColor(variant) {
60
+ const colors = {
61
+ 'blue-solid': 'bg-blue-100 text-blue-700',
62
+ 'gray-outline': 'bg-gray-100 text-gray-700',
63
+ 'blue-outline': 'bg-blue-50 text-blue-600',
64
+ 'gray-text': 'bg-gray-50 text-gray-500',
65
+ 'red-solid': 'bg-red-100 text-red-700',
66
+ 'red-outline': 'bg-red-50 text-red-600',
67
+ 'green-solid': 'bg-green-100 text-green-700',
68
+ 'icon': 'bg-purple-100 text-purple-700',
69
+ 'ghost': 'bg-yellow-100 text-yellow-700'
70
+ };
71
+ return colors[variant] || 'bg-gray-100 text-gray-700';
72
+ }
73
+ </script>
74
+
75
+ <div class="min-h-screen bg-gray-100 dark:bg-gray-900 p-4">
76
+ <!-- Header -->
77
+ <div class="sticky top-0 z-50 bg-white dark:bg-gray-800 rounded-lg shadow-sm p-4 mb-4">
78
+ <div class="flex flex-wrap items-center justify-between gap-4">
79
+ <div>
80
+ <h1 class="text-xl font-bold text-gray-900 dark:text-white">Button Grid View</h1>
81
+ <p class="text-sm text-gray-500 dark:text-gray-400">
82
+ Showing {filtered.length} of {allButtons.length} buttons
83
+ </p>
84
+ </div>
85
+
86
+ <div class="flex flex-wrap items-center gap-3">
87
+ <input
88
+ type="text"
89
+ bind:value={searchQuery}
90
+ placeholder="Search..."
91
+ class="px-3 py-1.5 text-sm rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white w-40"
92
+ />
93
+
94
+ <select bind:value={variantFilter} class="px-2 py-1.5 text-sm rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white">
95
+ <option value="all">All Variants</option>
96
+ {#each allVariants as v}<option value={v}>{v}</option>{/each}
97
+ </select>
98
+
99
+ <select bind:value={sizeFilter} class="px-2 py-1.5 text-sm rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white">
100
+ <option value="all">All Sizes</option>
101
+ {#each allSizes as s}<option value={s}>{s}</option>{/each}
102
+ </select>
103
+
104
+ <button onclick={toggleDark} class="px-3 py-1.5 text-sm rounded {isDark ? 'bg-gray-800 text-white' : 'bg-yellow-500 text-black'}">
105
+ {isDark ? '🌙' : '☀️'}
106
+ </button>
107
+ </div>
108
+ </div>
109
+ </div>
110
+
111
+ <!-- Grid -->
112
+ <div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-8 gap-3">
113
+ {#each filtered as button, i}
114
+ <div class="bg-white dark:bg-gray-800 rounded-lg p-3 border border-gray-200 dark:border-gray-700 flex flex-col">
115
+ <!-- Button Preview -->
116
+ <div class="flex items-center justify-center p-3 bg-gray-50 dark:bg-gray-700 rounded mb-2 min-h-[50px]">
117
+ <Button
118
+ variant={button.variant}
119
+ size={button.size}
120
+ loading={button.loading}
121
+ disabled={button.disabled}
122
+ danger={button.danger}
123
+ deemphasized={button.deemphasized}
124
+ >
125
+ {button.text === '(no text)' ? '' : button.text.slice(0, 20)}{button.text.length > 20 ? '…' : ''}
126
+ </Button>
127
+ </div>
128
+
129
+ <!-- Metadata -->
130
+ <div class="text-xs space-y-1">
131
+ <div class="flex gap-1 flex-wrap">
132
+ <span class="px-1.5 py-0.5 rounded {variantColor(button.variant)}">{button.variant}</span>
133
+ <span class="px-1.5 py-0.5 rounded bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300">{button.size}</span>
134
+ </div>
135
+ <a
136
+ href={vscodeLink(button.fullPath, button.line)}
137
+ class="block text-blue-500 hover:underline truncate"
138
+ title={button.file}
139
+ >
140
+ {shortFile(button.file)}:{button.line}
141
+ </a>
142
+ </div>
143
+ </div>
144
+ {/each}
145
+ </div>
146
+ </div>
@@ -0,0 +1,7 @@
1
+ export default ButtonGridView;
2
+ type ButtonGridView = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<Record<string, never>>): void;
5
+ };
6
+ declare const ButtonGridView: import("svelte").Component<Record<string, never>, {}, "">;
7
+ //# sourceMappingURL=ButtonGridView.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ButtonGridView.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/stories/ButtonGridView.svelte.js"],"names":[],"mappings":";;;;;AA2IA,wFAA6D"}