workflow-agent-cli 1.1.2

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,611 @@
1
+ # Component Library
2
+
3
+ > **Purpose**: This document is the **single source of truth** for all UI components in ProjectHub. Before creating or modifying any UI element, consult this guide.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [Quick Reference](#quick-reference)
10
+ 2. [Decision Tree](#decision-tree)
11
+ 3. [Design Tokens](#design-tokens)
12
+ 4. [UI Primitives](#ui-primitives)
13
+ 5. [Feature Components](#feature-components)
14
+ 6. [Component Audit Checklist](#component-audit-checklist)
15
+ 7. [Testing Requirements](#testing-requirements)
16
+ 8. [Feature Flags](#feature-flags)
17
+ 9. [Storybook](#storybook)
18
+
19
+ ---
20
+
21
+ ## Quick Reference
22
+
23
+ ### When to Use What
24
+
25
+ | Need | Component | Storybook Path |
26
+ | ------------------- | -------------------- | ---------------------------------------- |
27
+ | Status indicator | `StatusBadge` | `/story/statusbadge--default` |
28
+ | Priority indicator | `PriorityBadge` | `/story/prioritybadge--default` |
29
+ | Loading spinner | `Spinner` | `/story/ui-spinner--default` |
30
+ | Empty data state | `EmptyState` | `/story/emptystate--default` |
31
+ | Confirmation prompt | `ConfirmationDialog` | `/story/ui-confirmation-dialog--default` |
32
+ | Form in modal | `FormDialog` | `/story/formdialog--default` |
33
+ | Data list | `DataTable` | `/story/datatable--default` |
34
+ | Page title | `PageHeader` | `/story/pageheader--default` |
35
+ | User avatar + name | `MemberCard` | `/story/membercard--default` |
36
+
37
+ ---
38
+
39
+ ## Decision Tree
40
+
41
+ ```
42
+ Need to render UI?
43
+
44
+ ├─► Does a component exist in components/ui/?
45
+ │ ├─► YES: Use it with existing variants
46
+ │ │ └─► Need different behavior?
47
+ │ │ ├─► Can be achieved with props? → Use props
48
+ │ │ └─► Cannot? → Add variant, update Storybook + tests
49
+ │ │
50
+ │ └─► NO: Check Feature Components below
51
+ │ ├─► Exists? → Use it
52
+ │ └─► Doesn't exist?
53
+ │ │
54
+ │ ├─► Is it a one-off? → Ask: "Will this be used again?"
55
+ │ │ ├─► YES → Create new component with:
56
+ │ │ │ • Feature flag
57
+ │ │ │ • Storybook story
58
+ │ │ │ • Unit tests + snapshots
59
+ │ │ │
60
+ │ │ └─► NO → Implement inline (rare, justify in PR)
61
+ │ │
62
+ │ └─► Create new component (follow Component Creation Workflow)
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Design Tokens
68
+
69
+ All design tokens are centralized in `lib/design-tokens.ts`. **Never hardcode colors or sizes.**
70
+
71
+ ### Usage
72
+
73
+ ```typescript
74
+ import {
75
+ statusColors,
76
+ priorityColors,
77
+ getAvatarGradient,
78
+ badgeSizes,
79
+ spinnerSizes
80
+ } from "@/lib/design-tokens";
81
+
82
+ // Status colors
83
+ <Badge className={statusColors["in-progress"]}>In Progress</Badge>
84
+
85
+ // Priority colors
86
+ <Badge className={priorityColors.high}>High</Badge>
87
+
88
+ // Avatar gradient (deterministic by name)
89
+ <Avatar className={getAvatarGradient(user.name)}>
90
+ {initials}
91
+ </Avatar>
92
+
93
+ // Sizes
94
+ <div className={badgeSizes.md}>...</div>
95
+ <div className={spinnerSizes.lg}>...</div>
96
+ ```
97
+
98
+ ### Available Tokens
99
+
100
+ | Token | Values | Purpose |
101
+ | ------------------------ | ------------------------------- | ------------------------- |
102
+ | `statusColors` | todo, in-progress, review, done | Task status badge colors |
103
+ | `statusLabels` | Human-readable status names | Display labels |
104
+ | `statusIcons` | Lucide icon names | Icons for each status |
105
+ | `priorityColors` | low, medium, high, critical | Priority badge colors |
106
+ | `priorityLabels` | Human-readable priority names | Display labels |
107
+ | `priorityIcons` | Lucide icon names | Icons for each priority |
108
+ | `avatarGradients` | 5 vibrant gradients | User avatar backgrounds |
109
+ | `avatarGradientsNeutral` | 5 neutral gradients | Subtle avatar backgrounds |
110
+ | `badgeSizes` | sm, md, lg | Badge padding/text sizes |
111
+ | `iconSizes` | sm, md, lg | Icon dimensions |
112
+ | `spinnerSizes` | xs, sm, md, lg, xl | Spinner dimensions |
113
+ | `focusRing` | default, inset, none | Focus state styles |
114
+
115
+ ---
116
+
117
+ ## UI Primitives
118
+
119
+ Located in `components/ui/`. These are the building blocks.
120
+
121
+ ### Layout & Structure
122
+
123
+ | Component | Purpose | Variants | Test File |
124
+ | ----------------- | ---------------------- | ------------------------------------------- | --------- |
125
+ | `card.tsx` | Content container | Header, Title, Description, Content, Footer | - |
126
+ | `dialog.tsx` | Modal dialogs | Default, with close button | - |
127
+ | `sheet.tsx` | Side panels | Positions: top, right, bottom, left | - |
128
+ | `drawer.tsx` | Bottom drawer (mobile) | Default | - |
129
+ | `tabs.tsx` | Tab navigation | Default | - |
130
+ | `separator.tsx` | Visual dividers | Horizontal, vertical | - |
131
+ | `scroll-area.tsx` | Scrollable containers | Default | - |
132
+ | `resizable.tsx` | Resizable panels | Default | - |
133
+ | `collapsible.tsx` | Expandable sections | Default | - |
134
+ | `accordion.tsx` | Multiple collapsibles | Default | - |
135
+ | `sidebar.tsx` | Layout sidebar | Collapsible states | - |
136
+
137
+ ### Form Elements
138
+
139
+ | Component | Purpose | Variants | Test File |
140
+ | ------------------ | --------------------- | ----------------------------------------------------------------------------------- | --------- |
141
+ | `button.tsx` | Actions | default, destructive, outline, secondary, ghost, link; Sizes: default, sm, lg, icon | - |
142
+ | `input.tsx` | Text input | Default | - |
143
+ | `textarea.tsx` | Multi-line input | Default | - |
144
+ | `select.tsx` | Dropdown select | Size: sm, default | - |
145
+ | `multi-select.tsx` | Multi-select dropdown | Default | - |
146
+ | `checkbox.tsx` | Checkbox input | Default | - |
147
+ | `switch.tsx` | Toggle switch | Default | - |
148
+ | `radio-group.tsx` | Radio options | Default | - |
149
+ | `slider.tsx` | Range slider | Default | - |
150
+ | `calendar.tsx` | Date picker | Default | - |
151
+ | `input-otp.tsx` | OTP input | Default | - |
152
+ | `form.tsx` | Form primitives | FormField, FormItem, FormLabel, FormControl, FormMessage | - |
153
+ | `label.tsx` | Form labels | Default | - |
154
+
155
+ ### Feedback & Display
156
+
157
+ | Component | Purpose | Variants | Feature Flag | Test File |
158
+ | ------------------------- | -------------------- | ---------------------------------------- | --------------------- | ------------------------------ |
159
+ | `badge.tsx` | Status labels | default, secondary, destructive, outline | - | - |
160
+ | `alert.tsx` | Alert messages | default, destructive | - | - |
161
+ | `alert-dialog.tsx` | Confirmation modals | Default | - | - |
162
+ | `skeleton.tsx` | Loading placeholders | Default | - | - |
163
+ | `progress.tsx` | Progress bar | Default | - | - |
164
+ | `spinner.tsx` | Loading spinner | xs, sm, md, lg, xl | `SPINNER` | `spinner.test.tsx` |
165
+ | `confirmation-dialog.tsx` | Standardized confirm | default, destructive | `CONFIRMATION_DIALOG` | `confirmation-dialog.test.tsx` |
166
+ | `sonner.tsx` | Toast notifications | Default | - | - |
167
+ | `tooltip.tsx` | Tooltips | Default | - | - |
168
+ | `hover-card.tsx` | Hover tooltips | Default | - | - |
169
+ | `popover.tsx` | Popovers | Default | - | - |
170
+
171
+ ### Navigation
172
+
173
+ | Component | Purpose | Variants | Test File |
174
+ | --------------------- | ----------------- | -------- | --------- |
175
+ | `dropdown-menu.tsx` | Dropdown menus | Default | - |
176
+ | `context-menu.tsx` | Right-click menus | Default | - |
177
+ | `menubar.tsx` | Menu bar | Default | - |
178
+ | `navigation-menu.tsx` | Navigation | Default | - |
179
+ | `breadcrumb.tsx` | Breadcrumbs | Default | - |
180
+ | `command.tsx` | Command palette | Default | - |
181
+ | `pagination.tsx` | Page navigation | Default | - |
182
+
183
+ ### Data Display
184
+
185
+ | Component | Purpose | Variants | Test File |
186
+ | ------------------ | ---------------------- | ------------------------------- | --------- |
187
+ | `table.tsx` | Data tables | Header, Body, Row, Cell, Footer | - |
188
+ | `avatar.tsx` | User avatars | Image + fallback | - |
189
+ | `chart.tsx` | Data visualization | Recharts wrapper | - |
190
+ | `carousel.tsx` | Content carousel | Default | - |
191
+ | `aspect-ratio.tsx` | Aspect ratio container | Default | - |
192
+
193
+ ### Toggles & Groups
194
+
195
+ | Component | Purpose | Variants | Test File |
196
+ | ------------------ | ------------------- | -------- | --------- |
197
+ | `toggle.tsx` | Toggle button | Default | - |
198
+ | `toggle-group.tsx` | Toggle button group | Default | - |
199
+
200
+ ---
201
+
202
+ ## Feature Components
203
+
204
+ Located in `components/`. These are composed from UI primitives.
205
+
206
+ ### Badges & Indicators
207
+
208
+ | Component | Purpose | Feature Flag | Storybook | Test File |
209
+ | ------------------- | ------------------ | -------------- | ------------------------------- | ---------------------- |
210
+ | `PriorityBadge.tsx` | Priority indicator | - | `/story/prioritybadge--default` | - |
211
+ | `StatusBadge.tsx` | Status indicator | `STATUS_BADGE` | `/story/statusbadge--default` | `StatusBadge.test.tsx` |
212
+
213
+ ### Layout Components
214
+
215
+ | Component | Purpose | Feature Flag | Storybook | Test File |
216
+ | ---------------- | -------------------- | ------------- | ---------------------------- | --------------------- |
217
+ | `EmptyState.tsx` | Empty data display | `EMPTY_STATE` | `/story/emptystate--default` | `EmptyState.test.tsx` |
218
+ | `PageHeader.tsx` | Page title + actions | `PAGE_HEADER` | `/story/pageheader--default` | `PageHeader.test.tsx` |
219
+ | `MemberCard.tsx` | User avatar + info | `MEMBER_CARD` | `/story/membercard--default` | `MemberCard.test.tsx` |
220
+
221
+ ### Data Components
222
+
223
+ | Component | Purpose | Feature Flag | Storybook | Test File |
224
+ | --------------- | --------------------------------- | ------------ | --------------------------- | -------------------- |
225
+ | `DataTable.tsx` | Table with sort/filter/pagination | `DATA_TABLE` | `/story/datatable--default` | `DataTable.test.tsx` |
226
+
227
+ ### Form Components
228
+
229
+ | Component | Purpose | Feature Flag | Storybook | Test File |
230
+ | ------------------------ | --------------------------- | --------------------- | ------------------------------------ | ----------------------------- |
231
+ | `FormDialog.tsx` | Dialog with form | `FORM_DIALOG` | `/story/formdialog--default` | `FormDialog.test.tsx` |
232
+ | `ConfirmationDialog.tsx` | Confirm destructive actions | `CONFIRMATION_DIALOG` | `/story/confirmationdialog--default` | `ConfirmationDialog.test.tsx` |
233
+ | `Spinner.tsx` | Loading indicator | `SPINNER` | `/story/spinner--default` | `Spinner.test.tsx` |
234
+
235
+ ### Existing Feature Components (No Flag)
236
+
237
+ | Component | Purpose | Location |
238
+ | ----------------------- | ----------------------- | ------------- |
239
+ | `TaskCard.tsx` | Kanban task card | `components/` |
240
+ | `TaskDialog.tsx` | Task create/edit dialog | `components/` |
241
+ | `SprintDialog.tsx` | Sprint create/edit | `components/` |
242
+ | `BoardDialog.tsx` | Board create/edit | `components/` |
243
+ | `ColumnDialog.tsx` | Column create/edit | `components/` |
244
+ | `WorkspaceDialog.tsx` | Workspace create/edit | `components/` |
245
+ | `Header.tsx` | App header | `components/` |
246
+ | `Sidebar.tsx` | App sidebar | `components/` |
247
+ | `NotificationPanel.tsx` | Notifications list | `components/` |
248
+
249
+ ---
250
+
251
+ ## Dialog Patterns
252
+
253
+ All form dialogs should follow consistent patterns for user experience.
254
+
255
+ ### When to Use Each Dialog Component
256
+
257
+ | Use Case | Component | Example |
258
+ | --------------------------------- | ------------------------------- | --------------------------- |
259
+ | Form with multiple fields | `FormDialog` | Create Sprint, Create Board |
260
+ | Destructive confirmation | `ConfirmationDialog` | Delete Task, Remove Member |
261
+ | Simple confirmation | `ConfirmationDialog` | Confirm Action |
262
+ | Complex form (many tabs/sections) | Custom with `Dialog` primitives | TaskDialog |
263
+
264
+ ### FormDialog Usage
265
+
266
+ ```tsx
267
+ import {
268
+ FormDialog,
269
+ FormDialogSection,
270
+ FormDialogField,
271
+ useFormDialog,
272
+ } from '@/components/FormDialog';
273
+
274
+ function CreateSprintDialog() {
275
+ const { isOpen, isSubmitting, setIsSubmitting, open, close } = useFormDialog();
276
+ const [name, setName] = useState('');
277
+
278
+ const handleSubmit = async (e: React.FormEvent) => {
279
+ e.preventDefault();
280
+ setIsSubmitting(true);
281
+ try {
282
+ await createSprint({ name });
283
+ close();
284
+ } finally {
285
+ setIsSubmitting(false);
286
+ }
287
+ };
288
+
289
+ return (
290
+ <>
291
+ <Button onClick={open}>Create Sprint</Button>
292
+ <FormDialog
293
+ open={isOpen}
294
+ onOpenChange={(open) => !open && close()}
295
+ title="Create Sprint"
296
+ description="Add a new sprint to your project"
297
+ onSubmit={handleSubmit}
298
+ isSubmitting={isSubmitting}
299
+ submitText="Create"
300
+ gradientTitle // Use gradient for creation dialogs
301
+ size="md"
302
+ >
303
+ <FormDialogField label="Name" required htmlFor="sprint-name">
304
+ <Input
305
+ id="sprint-name"
306
+ value={name}
307
+ onChange={(e) => setName(e.target.value)}
308
+ placeholder="Sprint 1"
309
+ />
310
+ </FormDialogField>
311
+ </FormDialog>
312
+ </>
313
+ );
314
+ }
315
+ ```
316
+
317
+ ### Dialog Size Guidelines
318
+
319
+ | Size | Max Width | Use For |
320
+ | ------ | --------- | --------------------------------- |
321
+ | `sm` | 400px | Simple confirmation, single field |
322
+ | `md` | 500px | Standard forms (2-5 fields) |
323
+ | `lg` | 600px | Larger forms with sections |
324
+ | `xl` | 800px | Complex forms, data tables |
325
+ | `full` | 90vw | Very large content, multi-step |
326
+
327
+ ### Title Styling
328
+
329
+ | Style | Use For | Prop |
330
+ | -------- | ------------------------------------------- | --------------------------------- |
331
+ | Gradient | Creation dialogs (Create Sprint, New Board) | `gradientTitle={true}` |
332
+ | Plain | Edit dialogs, Settings | `gradientTitle={false}` (default) |
333
+
334
+ ### FormDialogSection
335
+
336
+ Use sections to group related fields:
337
+
338
+ ```tsx
339
+ <FormDialog {...props}>
340
+ <FormDialogSection title="Basic Info">
341
+ <FormDialogField label="Name" required>
342
+ <Input {...nameProps} />
343
+ </FormDialogField>
344
+ <FormDialogField label="Description">
345
+ <Textarea {...descProps} />
346
+ </FormDialogField>
347
+ </FormDialogSection>
348
+
349
+ <FormDialogSection title="Options">
350
+ <FormDialogField label="Active">
351
+ <Switch {...activeProps} />
352
+ </FormDialogField>
353
+ </FormDialogSection>
354
+ </FormDialog>
355
+ ```
356
+
357
+ ### Error Handling
358
+
359
+ Use `FormDialogField` error prop for validation:
360
+
361
+ ```tsx
362
+ <FormDialogField label="Email" required error={errors.email?.message} htmlFor="email">
363
+ <Input id="email" {...register('email')} />
364
+ </FormDialogField>
365
+ ```
366
+
367
+ ---
368
+
369
+ ## Component Audit Checklist
370
+
371
+ Before creating or modifying a component, complete this checklist:
372
+
373
+ ### Pre-Work Audit
374
+
375
+ - [ ] Checked `components/ui/` for existing primitive
376
+ - [ ] Checked Feature Components list above
377
+ - [ ] Checked Storybook for visual examples
378
+ - [ ] Verified no existing component meets the need
379
+ - [ ] If modifying: reviewed current tests and stories
380
+
381
+ ### New Component Requirements
382
+
383
+ - [ ] Component file created: `components/[Name].tsx` or `components/ui/[name].tsx`
384
+ - [ ] Uses design tokens from `lib/design-tokens.ts`
385
+ - [ ] Has clear prop interface with JSDoc
386
+ - [ ] Has feature flag (if applicable)
387
+ - [ ] Storybook story created: `[Name].stories.tsx`
388
+ - [ ] Unit tests created: `[Name].test.tsx`
389
+ - [ ] Snapshot tests for each variant
390
+ - [ ] Added to this document (COMPONENT_LIBRARY.md)
391
+
392
+ ### Variant Addition Requirements
393
+
394
+ - [ ] Existing tests still pass
395
+ - [ ] New variant has Storybook story
396
+ - [ ] New variant has snapshot test
397
+ - [ ] This document updated if needed
398
+
399
+ ---
400
+
401
+ ## Testing Requirements
402
+
403
+ Every component in the library must have comprehensive tests.
404
+
405
+ ### Test File Structure
406
+
407
+ ```
408
+ components/
409
+ ├── StatusBadge.tsx
410
+ ├── StatusBadge.stories.tsx
411
+ ├── StatusBadge.test.tsx
412
+ └── __snapshots__/
413
+ └── StatusBadge.test.tsx.snap
414
+ ```
415
+
416
+ ### Required Test Coverage
417
+
418
+ #### Behavioral Tests
419
+
420
+ ```typescript
421
+ describe('StatusBadge', () => {
422
+ it('should render without crashing', () => {});
423
+ it('should render all status variants', () => {});
424
+ it('should apply correct colors for each status', () => {});
425
+ it('should respect size prop', () => {});
426
+ it('should apply custom className', () => {});
427
+ it('should handle feature flag disabled state', () => {});
428
+ it('should handle feature flag enabled state', () => {});
429
+ });
430
+ ```
431
+
432
+ #### Snapshot Tests
433
+
434
+ ```typescript
435
+ describe("Snapshots", () => {
436
+ it.each(["todo", "in-progress", "review", "done"])
437
+ ("should match snapshot for status: %s", (status) => {
438
+ const { container } = render(<StatusBadge status={status} />);
439
+ expect(container).toMatchSnapshot();
440
+ });
441
+
442
+ it.each(["sm", "md", "lg"])
443
+ ("should match snapshot for size: %s", (size) => {
444
+ const { container } = render(<StatusBadge status="todo" size={size} />);
445
+ expect(container).toMatchSnapshot();
446
+ });
447
+ });
448
+ ```
449
+
450
+ ### Running Tests
451
+
452
+ ```bash
453
+ # Run all component tests
454
+ pnpm test:components
455
+
456
+ # Watch mode
457
+ pnpm test:components:watch
458
+
459
+ # Update snapshots (after intentional visual changes)
460
+ pnpm test:update-snapshots
461
+ ```
462
+
463
+ ---
464
+
465
+ ## Feature Flags
466
+
467
+ Components under development use feature flags for controlled rollout.
468
+
469
+ ### Available Flags
470
+
471
+ | Flag | Component | Default |
472
+ | --------------------- | ---------------------- | ------- |
473
+ | `STATUS_BADGE` | StatusBadge | `false` |
474
+ | `SPINNER` | Spinner | `false` |
475
+ | `CONFIRMATION_DIALOG` | ConfirmationDialog | `false` |
476
+ | `EMPTY_STATE` | EmptyState | `false` |
477
+ | `FORM_DIALOG` | FormDialog | `false` |
478
+ | `DATA_TABLE` | DataTable | `false` |
479
+ | `PAGE_HEADER` | PageHeader | `false` |
480
+ | `MEMBER_CARD` | MemberCard | `false` |
481
+ | `DESIGN_TOKENS` | Design token migration | `false` |
482
+
483
+ ### Enabling Flags
484
+
485
+ Add to `.env.local`:
486
+
487
+ ```bash
488
+ NEXT_PUBLIC_FEATURE_STATUS_BADGE=true
489
+ NEXT_PUBLIC_FEATURE_SPINNER=true
490
+ ```
491
+
492
+ ### Using Flags in Code
493
+
494
+ ```typescript
495
+ import { isFeatureEnabled, FeatureFlag } from "@/lib/feature-flags";
496
+
497
+ function TaskRow({ task }) {
498
+ return (
499
+ <div>
500
+ {isFeatureEnabled(FeatureFlag.STATUS_BADGE) ? (
501
+ <StatusBadge status={task.status} />
502
+ ) : (
503
+ <LegacyStatusDisplay status={task.status} />
504
+ )}
505
+ </div>
506
+ );
507
+ }
508
+ ```
509
+
510
+ ### Testing with Flags
511
+
512
+ ```typescript
513
+ import { mockFeatureFlag, clearFeatureFlagMocks } from '@/lib/feature-flags';
514
+
515
+ describe('Component with feature flag', () => {
516
+ afterEach(() => {
517
+ clearFeatureFlagMocks();
518
+ });
519
+
520
+ it('should render new component when flag enabled', () => {
521
+ mockFeatureFlag(FeatureFlag.STATUS_BADGE, true);
522
+ // test new behavior
523
+ });
524
+
525
+ it('should render fallback when flag disabled', () => {
526
+ mockFeatureFlag(FeatureFlag.STATUS_BADGE, false);
527
+ // test fallback behavior
528
+ });
529
+ });
530
+ ```
531
+
532
+ ---
533
+
534
+ ## Storybook
535
+
536
+ Local Storybook for visual documentation and testing.
537
+
538
+ ### Running Storybook
539
+
540
+ ```bash
541
+ pnpm storybook
542
+ ```
543
+
544
+ Opens at http://localhost:6006
545
+
546
+ ### Story Structure
547
+
548
+ ```typescript
549
+ // StatusBadge.stories.tsx
550
+ import type { Meta, StoryObj } from "@storybook/react";
551
+ import { StatusBadge } from "./StatusBadge";
552
+
553
+ const meta: Meta<typeof StatusBadge> = {
554
+ title: "Components/StatusBadge",
555
+ component: StatusBadge,
556
+ tags: ["autodocs"],
557
+ argTypes: {
558
+ status: {
559
+ control: "select",
560
+ options: ["todo", "in-progress", "review", "done"],
561
+ },
562
+ size: {
563
+ control: "select",
564
+ options: ["sm", "md", "lg"],
565
+ },
566
+ },
567
+ };
568
+
569
+ export default meta;
570
+ type Story = StoryObj<typeof StatusBadge>;
571
+
572
+ export const Default: Story = {
573
+ args: {
574
+ status: "todo",
575
+ size: "md",
576
+ },
577
+ };
578
+
579
+ // Additional stories for specific states
580
+ export const InProgress: Story = {
581
+ args: {
582
+ status: "in-progress",
583
+ },
584
+ };
585
+
586
+ export const AllSizes: Story = {
587
+ render: () => (
588
+ <div className="flex gap-4">
589
+ <StatusBadge status="todo" size="sm" />
590
+ <StatusBadge status="todo" size="md" />
591
+ <StatusBadge status="todo" size="lg" />
592
+ </div>
593
+ ),
594
+ };
595
+ ```
596
+
597
+ ### Story Guidelines
598
+
599
+ 1. **Keep stories minimal** - rely on Controls addon for testing variants
600
+ 2. **One default story** per component with all props controllable
601
+ 3. **Additional stories** only for complex compositions or states
602
+ 4. **Use `tags: ["autodocs"]`** for auto-generated documentation
603
+ 5. **Provide meaningful argTypes** with control types
604
+
605
+ ---
606
+
607
+ ## Changelog
608
+
609
+ | Date | Change |
610
+ | ---------- | ----------------------------------------------- |
611
+ | 2026-01-10 | Initial component library documentation created |