@fragments-sdk/ui 0.2.3 → 0.4.0
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/fragments.json +1 -1
- package/package.json +9 -4
- package/src/components/Accordion/Accordion.fragment.tsx +186 -0
- package/src/components/Accordion/Accordion.module.scss +111 -0
- package/src/components/Accordion/index.tsx +271 -0
- package/src/components/Alert/Alert.fragment.tsx +66 -41
- package/src/components/Alert/Alert.module.scss +31 -21
- package/src/components/Alert/index.tsx +202 -73
- package/src/components/AppShell/AppShell.fragment.tsx +315 -0
- package/src/components/AppShell/AppShell.module.scss +213 -0
- package/src/components/AppShell/index.tsx +398 -0
- package/src/components/Avatar/index.tsx +8 -9
- package/src/components/Badge/Badge.module.scss +16 -10
- package/src/components/Badge/index.tsx +20 -6
- package/src/components/Box/Box.fragment.tsx +168 -0
- package/src/components/Box/Box.module.scss +84 -0
- package/src/components/Box/index.tsx +78 -0
- package/src/components/Button/Button.module.scss +42 -0
- package/src/components/Button/index.tsx +67 -33
- package/src/components/ButtonGroup/ButtonGroup.module.scss +37 -0
- package/src/components/ButtonGroup/index.tsx +40 -0
- package/src/components/Card/Card.fragment.tsx +51 -25
- package/src/components/Card/Card.module.scss +52 -5
- package/src/components/Card/index.tsx +154 -53
- package/src/components/Checkbox/Checkbox.module.scss +4 -4
- package/src/components/Checkbox/index.tsx +3 -4
- package/src/components/CodeBlock/CodeBlock.fragment.tsx +201 -0
- package/src/components/CodeBlock/CodeBlock.module.scss +224 -0
- package/src/components/CodeBlock/index.tsx +385 -0
- package/src/components/ColorChip/ColorChip.module.scss +165 -0
- package/src/components/ColorChip/index.tsx +157 -0
- package/src/components/ColorPicker/ColorPicker.module.scss +109 -0
- package/src/components/ColorPicker/index.tsx +107 -0
- package/src/components/Dialog/Dialog.fragment.tsx +9 -0
- package/src/components/Dialog/Dialog.module.scss +26 -7
- package/src/components/Dialog/index.tsx +12 -15
- package/src/components/EmptyState/EmptyState.fragment.tsx +54 -71
- package/src/components/EmptyState/EmptyState.module.scss +9 -9
- package/src/components/EmptyState/index.tsx +104 -69
- package/src/components/Field/Field.fragment.tsx +165 -0
- package/src/components/Field/Field.module.scss +31 -0
- package/src/components/Field/index.tsx +143 -0
- package/src/components/Fieldset/Fieldset.fragment.tsx +166 -0
- package/src/components/Fieldset/Fieldset.module.scss +22 -0
- package/src/components/Fieldset/index.tsx +47 -0
- package/src/components/Form/Form.fragment.tsx +286 -0
- package/src/components/Form/Form.module.scss +8 -0
- package/src/components/Form/index.tsx +53 -0
- package/src/components/Grid/Grid.fragment.tsx +17 -17
- package/src/components/Grid/index.tsx +6 -1
- package/src/components/Header/Header.fragment.tsx +192 -0
- package/src/components/Header/Header.module.scss +209 -0
- package/src/components/Header/index.tsx +363 -0
- package/src/components/Icon/Icon.fragment.tsx +138 -0
- package/src/components/Icon/Icon.module.scss +38 -0
- package/src/components/Icon/index.tsx +58 -0
- package/src/components/Image/Image.fragment.tsx +195 -0
- package/src/components/Image/Image.module.scss +77 -0
- package/src/components/Image/index.tsx +95 -0
- package/src/components/Input/Input.module.scss +75 -2
- package/src/components/Input/index.tsx +60 -21
- package/src/components/Link/Link.fragment.tsx +132 -0
- package/src/components/Link/Link.module.scss +67 -0
- package/src/components/Link/index.tsx +57 -0
- package/src/components/List/List.fragment.tsx +152 -0
- package/src/components/List/List.module.scss +71 -0
- package/src/components/List/index.tsx +106 -0
- package/src/components/Listbox/Listbox.fragment.tsx +191 -0
- package/src/components/Listbox/Listbox.module.scss +97 -0
- package/src/components/Listbox/index.tsx +121 -0
- package/src/components/Menu/Menu.fragment.tsx +9 -0
- package/src/components/Menu/Menu.module.scss +17 -1
- package/src/components/Menu/index.tsx +3 -3
- package/src/components/Popover/Popover.fragment.tsx +9 -0
- package/src/components/Popover/Popover.module.scss +33 -10
- package/src/components/Popover/index.tsx +9 -11
- package/src/components/Progress/Progress.module.scss +11 -11
- package/src/components/Progress/index.tsx +34 -7
- package/src/components/Prompt/Prompt.fragment.tsx +231 -0
- package/src/components/Prompt/Prompt.module.scss +243 -0
- package/src/components/Prompt/index.tsx +439 -0
- package/src/components/RadioGroup/RadioGroup.module.scss +3 -3
- package/src/components/RadioGroup/index.tsx +3 -4
- package/src/components/Select/Select.fragment.tsx +9 -0
- package/src/components/Select/index.tsx +6 -7
- package/src/components/Separator/index.tsx +7 -3
- package/src/components/Sidebar/Sidebar.fragment.tsx +783 -0
- package/src/components/Sidebar/Sidebar.module.scss +586 -0
- package/src/components/Sidebar/index.tsx +1013 -0
- package/src/components/Skeleton/Skeleton.fragment.tsx +5 -5
- package/src/components/Skeleton/Skeleton.module.scss +11 -0
- package/src/components/Slider/Slider.module.scss +87 -0
- package/src/components/Slider/index.tsx +88 -0
- package/src/components/Stack/Stack.module.scss +120 -0
- package/src/components/Stack/index.tsx +148 -0
- package/src/components/Table/Table.fragment.tsx +7 -0
- package/src/components/Table/Table.module.scss +57 -0
- package/src/components/Table/index.tsx +44 -6
- package/src/components/Tabs/Tabs.fragment.tsx +9 -0
- package/src/components/Tabs/Tabs.module.scss +25 -10
- package/src/components/Tabs/index.tsx +11 -8
- package/src/components/Text/Text.module.scss +82 -0
- package/src/components/Text/index.tsx +58 -0
- package/src/components/Textarea/index.tsx +3 -7
- package/src/components/Theme/Theme.fragment.tsx +128 -0
- package/src/components/Theme/ThemeToggle.module.scss +82 -0
- package/src/components/Theme/index.tsx +343 -0
- package/src/components/Toast/Toast.fragment.tsx +5 -5
- package/src/components/Toast/Toast.module.scss +16 -1
- package/src/components/Toast/index.tsx +27 -11
- package/src/components/Toggle/Toggle.module.scss +25 -10
- package/src/components/Toggle/index.tsx +12 -0
- package/src/components/ToggleGroup/ToggleGroup.module.scss +134 -0
- package/src/components/ToggleGroup/index.tsx +144 -0
- package/src/components/Tooltip/Tooltip.module.scss +4 -4
- package/src/components/Tooltip/index.tsx +4 -2
- package/src/components/VisuallyHidden/VisuallyHidden.fragment.tsx +134 -0
- package/src/components/VisuallyHidden/VisuallyHidden.module.scss +13 -0
- package/src/components/VisuallyHidden/index.tsx +29 -0
- package/src/index.ts +241 -3
- package/src/recipes/AppShell.recipe.ts +175 -0
- package/src/recipes/CardGrid.recipe.ts +6 -2
- package/src/recipes/ChatInterface.recipe.ts +87 -0
- package/src/recipes/CodeExamples.recipe.ts +66 -0
- package/src/recipes/DashboardLayout.recipe.ts +46 -12
- package/src/recipes/DashboardNav.recipe.ts +183 -0
- package/src/recipes/LoginForm.recipe.ts +8 -1
- package/src/recipes/SettingsPage.recipe.ts +37 -20
- package/src/styles/globals.scss +31 -0
- package/src/tokens/_index.scss +3 -0
- package/src/tokens/_mixins.scss +54 -1
- package/src/tokens/_variables.scss +429 -64
- package/src/utils/a11y.tsx +439 -0
package/fragments.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.0.0","generatedAt":"2026-01-27T23:06:33.805Z","segments":{"Alert":{"filePath":"src/components/Alert/Alert.fragment.tsx","meta":{"name":"Alert","description":"Contextual feedback messages for user actions or system status. Supports multiple severity levels with optional actions and dismissibility.","category":"feedback","status":"stable","tags":["notification","message","feedback","banner","toast"],"since":"0.1.0"},"usage":{"when":["Communicating the result of a user action (success, error)","Warning about potential issues before they occur","Providing important contextual information inline","System status notifications that require attention"],"whenNot":["Brief status labels (use Badge instead)","Transient notifications (use Toast/Snackbar)","Form-field-level errors (use Input error prop)","Confirmation before destructive actions (use Dialog)"],"guidelines":["Match severity to the actual importance: info for context, warning for potential issues, error for failures","Always provide actionable guidance in error alerts","Use titles for complex messages; skip titles for brief one-liners","Limit to one action per alert to avoid decision paralysis","Dismissible alerts should only be used for non-critical information"],"accessibility":["Uses role=\"alert\" for screen reader announcement","Error and warning alerts are announced immediately by assistive technology","Dismiss button must have an accessible label","Color alone must not convey meaning - icons and text reinforce severity"]},"props":{"children":{"type":"node","description":"Alert message content","required":true},"title":{"type":"string","description":"Optional bold title displayed above the message"},"severity":{"type":"enum","description":"Visual severity level","default":"info","values":["info","success","warning","error"]},"dismissible":{"type":"boolean","description":"Whether the alert shows a dismiss button","default":"false"},"onDismiss":{"type":"function","description":"Callback when the alert is dismissed"},"action":{"type":"custom","description":"Optional action button: { label: string, onClick: () => void }"}},"relations":[{"component":"Badge","relationship":"alternative","note":"Use Badge for compact, inline status labels"},{"component":"Toast","relationship":"alternative","note":"Use Toast for transient notifications that auto-dismiss"},{"component":"Dialog","relationship":"sibling","note":"Use Dialog for blocking confirmations"}],"variants":[{"name":"Info","description":"Informational context for the user","code":"<Alert severity=\"info\">\n Your session will expire in 15 minutes. Save your work to avoid losing changes.\n </Alert>"},{"name":"Success","description":"Positive confirmation of completed action","code":"<Alert severity=\"success\" title=\"Payment processed\">\n Your order #12345 has been confirmed. You will receive a confirmation email shortly.\n </Alert>"},{"name":"Warning","description":"Caution about potential issues","code":"<Alert severity=\"warning\" title=\"Storage almost full\">\n You have used 90% of your storage quota. Consider deleting unused files.\n </Alert>"},{"name":"Error","description":"Error state requiring user attention","code":"<Alert severity=\"error\" title=\"Upload failed\">\n The file could not be uploaded. Check your connection and try again.\n </Alert>"},{"name":"With Action","description":"Alert with an actionable button","code":"<Alert\n severity=\"warning\"\n title=\"Update available\"\n action={{ label: 'Update now', onClick: () => {} }}\n >\n A new version is available with important security fixes.\n </Alert>"},{"name":"Dismissible","description":"Alert that can be closed by the user","code":"<Alert severity=\"info\" dismissible>\n You can customize your notification preferences in Settings.\n </Alert>"}]},"Avatar":{"filePath":"src/components/Avatar/Avatar.fragment.tsx","meta":{"name":"Avatar","description":"Visual representation of a user or entity","category":"data-display","status":"stable","tags":["user","profile","image","identity"]},"usage":{"when":["Displaying user profile pictures","Showing team member lists","Representing entities in lists or cards","User identification in comments or messages"],"whenNot":["Decorative images (use Image)","Logo display (use Logo component)","Large profile headers (use custom layout)"],"guidelines":["Always provide alt text or name for accessibility","Use consistent sizes within the same context","Provide fallback initials when image may not load","Use Avatar.Group for multiple avatars in a row"],"accessibility":["Include meaningful alt text describing the user","Initials should be derived from name for screen readers","Decorative avatars should have empty alt"]},"props":{"src":{"type":"string","description":"Image source URL"},"alt":{"type":"string","description":"Alt text for the image"},"name":{"type":"string","description":"Full name - used to generate initials"},"initials":{"type":"string","description":"Fallback initials (1-2 characters)"},"size":{"type":"enum","description":"Size variant","default":"md","values":["xs","sm","md","lg","xl"]},"shape":{"type":"enum","description":"Shape variant","default":"circle","values":["circle","square"]}},"relations":[{"component":"AvatarGroup","relationship":"parent","note":"Use Avatar.Group for stacked avatar displays"}],"variants":[{"name":"Default","description":"Avatar with image","code":"<Avatar\n src=\"https://i.pravatar.cc/150?u=jane\"\n alt=\"Jane Doe\"\n name=\"Jane Doe\"\n />"},{"name":"With Initials","description":"Fallback when no image is provided","code":"<Avatar name=\"John Smith\" />"},{"name":"Sizes","description":"Available size options","code":"<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n <Avatar name=\"XS\" size=\"xs\" />\n <Avatar name=\"SM\" size=\"sm\" />\n <Avatar name=\"MD\" size=\"md\" />\n <Avatar name=\"LG\" size=\"lg\" />\n <Avatar name=\"XL\" size=\"xl\" />\n </div>"},{"name":"Square Shape","description":"Square variant for app icons or brands","code":"<Avatar name=\"App\" shape=\"square\" />"},{"name":"Group","description":"Multiple avatars stacked together","code":"<Avatar.Group max={3} size=\"md\">\n <Avatar name=\"Alice Johnson\" />\n <Avatar name=\"Bob Smith\" />\n <Avatar name=\"Carol Williams\" />\n <Avatar name=\"David Brown\" />\n <Avatar name=\"Eve Davis\" />\n </Avatar.Group>"}]},"Badge":{"filePath":"src/components/Badge/Badge.fragment.tsx","meta":{"name":"Badge","description":"Compact label for status, counts, or categorization. Draws attention to metadata without dominating the layout.","category":"feedback","status":"stable","tags":["status","label","tag","count","chip"],"since":"0.1.0"},"usage":{"when":["Showing item status (active, pending, archived)","Displaying counts or quantities inline","Categorizing or tagging content","Highlighting new or updated items"],"whenNot":["Conveying critical errors (use Alert instead)","Long-form status messages (use Alert)","Interactive filtering (use chip/toggle group)","Navigation labels (use tabs or links)"],"guidelines":["Keep badge text under 20 characters","Use dot variant for live status indicators","Pair success/error variants with meaningful labels, not just colors","Use onRemove for user-created tags only, not system-generated badges"],"accessibility":["Badge text must be meaningful without relying on color alone","Removable badges must have accessible dismiss button labels","Avoid using badges as the sole indicator of important state changes"]},"props":{"children":{"type":"node","description":"Badge label text","required":true},"variant":{"type":"enum","description":"Visual style indicating severity or category","default":"default","values":["default","success","warning","error","info"]},"size":{"type":"enum","description":"Badge size","default":"md","values":["sm","md"]},"dot":{"type":"boolean","description":"Show a colored dot indicator before the label","default":"false"},"icon":{"type":"node","description":"Optional icon element before the text"},"onRemove":{"type":"function","description":"Makes the badge removable. Called when X is clicked."}},"relations":[{"component":"Alert","relationship":"alternative","note":"Use Alert for prominent, longer messages with actions"},{"component":"Tag","relationship":"sibling","note":"Tag is interactive (clickable/filterable); Badge is display-only"}],"variants":[{"name":"Default","description":"Neutral badge for general labels","code":"<Badge>Default</Badge>"},{"name":"Status Variants","description":"All severity variants for different contexts","code":"<div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>\n <Badge variant=\"default\">Default</Badge>\n <Badge variant=\"success\">Active</Badge>\n <Badge variant=\"warning\">Pending</Badge>\n <Badge variant=\"error\">Failed</Badge>\n <Badge variant=\"info\">New</Badge>\n </div>"},{"name":"With Dot","description":"Live status indicators using dot prefix","code":"<div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>\n <Badge variant=\"success\" dot>Online</Badge>\n <Badge variant=\"warning\" dot>Away</Badge>\n <Badge variant=\"error\" dot>Offline</Badge>\n </div>"},{"name":"Small Size","description":"Compact badges for dense UIs","code":"<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n <Badge size=\"sm\" variant=\"info\">v2.1</Badge>\n <Badge size=\"sm\" variant=\"success\">Stable</Badge>\n <Badge size=\"md\" variant=\"info\">Standard</Badge>\n </div>"},{"name":"Removable","description":"User-created tags that can be dismissed","code":"<div style={{ display: 'flex', gap: '8px' }}>\n <Badge variant=\"info\" onRemove={() => {}}>React</Badge>\n <Badge variant=\"info\" onRemove={() => {}}>TypeScript</Badge>\n <Badge variant=\"info\" onRemove={() => {}}>CSS</Badge>\n </div>"}]},"Button":{"filePath":"src/components/Button/Button.fragment.tsx","meta":{"name":"Button","description":"Interactive element for user actions and form submissions","category":"actions","status":"stable","tags":["action","button","form","interactive"]},"usage":{"when":["Triggering an action (save, submit, delete, etc.)","Form submission","Opening dialogs or menus","Navigation when action context is needed"],"whenNot":["Simple navigation (use Link)","Toggling state (use Switch or Checkbox)","Selecting from options (use Select or RadioGroup)"],"guidelines":["Use Primary for the main action in a context","Only one Primary button per section/form","Use Danger variant for destructive actions","Loading state should disable the button"],"accessibility":["Button text should describe the action","Avoid generic labels like \"Click here\"","Icon-only buttons need aria-label"]},"props":{"children":{"type":"node","description":"Button label content","required":true},"variant":{"type":"enum","description":"Visual style variant","default":"primary","values":["primary","secondary","ghost","danger"],"constraints":["Only one primary button per context"]},"size":{"type":"enum","description":"Button size","default":"md","values":["sm","md","lg"]},"disabled":{"type":"boolean","description":"Whether the button is disabled","default":false},"onClick":{"type":"function","description":"Click handler"},"type":{"type":"enum","description":"HTML button type attribute","default":"button","values":["button","submit","reset"]}},"relations":[{"component":"Link","relationship":"alternative","note":"Use Link for navigation without action context"},{"component":"IconButton","relationship":"alternative","note":"Use IconButton for icon-only actions"},{"component":"ButtonGroup","relationship":"parent","note":"Use ButtonGroup for related action sets"}],"variants":[{"name":"Primary","description":"Default action button for primary actions","code":"<Button variant=\"primary\">Save Changes</Button>"},{"name":"Secondary","description":"Less prominent action button","code":"<Button variant=\"secondary\">Cancel</Button>"},{"name":"Ghost","description":"Minimal visual weight for subtle actions","code":"<Button variant=\"ghost\">Learn More</Button>"},{"name":"Danger","description":"Destructive action requiring attention","code":"<Button variant=\"danger\">Delete Item</Button>"},{"name":"Sizes","description":"Available size options","code":"<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n <Button size=\"sm\">Small</Button>\n <Button size=\"md\">Medium</Button>\n <Button size=\"lg\">Large</Button>\n </div>"},{"name":"Disabled","description":"Non-interactive state","code":"<Button disabled>Cannot Click</Button>"}]},"Card":{"filePath":"src/components/Card/Card.fragment.tsx","meta":{"name":"Card","description":"Container for grouping related content","category":"layout","status":"stable","tags":["container","layout","surface"]},"usage":{"when":["Grouping related pieces of content together","Creating visual separation between content sections","Displaying a preview or summary of an item","Building dashboard widgets or tiles"],"whenNot":["Simple text content that does not need grouping","Modal or dialog content (use Dialog component)","Navigation items (use NavItem or similar)"],"guidelines":["Use consistent card variants within the same context","Cards in a grid should have uniform sizing","Use elevated variant sparingly for emphasis","Interactive cards should have clear hover states"],"accessibility":["Interactive cards should use button or link semantics","Card titles should be appropriate heading levels"]},"props":{"children":{"type":"node","description":"Card content"},"title":{"type":"string","description":"Card header title"},"description":{"type":"string","description":"Card header description/subtitle"},"variant":{"type":"enum","description":"Visual style of the card surface","default":"default","values":["default","outlined","elevated"],"constraints":["Use \"elevated\" sparingly to maintain visual hierarchy"]},"padding":{"type":"enum","description":"Internal padding size","default":"md","values":["none","sm","md","lg"]},"onClick":{"type":"function","description":"Click handler - makes card interactive"}},"relations":[{"component":"CardGrid","relationship":"parent","note":"Use CardGrid for responsive card layouts"},{"component":"ListItem","relationship":"alternative","note":"Use ListItem for linear list layouts"}],"variants":[{"name":"Default","description":"Standard card with subtle shadow","code":"<Card title=\"Card Title\" description=\"A brief description\">\n Card content goes here.\n </Card>"},{"name":"Outlined","description":"Card with border instead of shadow","code":"<Card variant=\"outlined\" title=\"Outlined Card\">\n Content with border.\n </Card>"},{"name":"Elevated","description":"Card with prominent shadow for emphasis","code":"<Card variant=\"elevated\" title=\"Featured Item\">\n Important content.\n </Card>"},{"name":"Interactive","description":"Clickable card","code":"<Card\n title=\"Click Me\"\n description=\"This card is interactive\"\n onClick={() => alert('Card clicked!')}\n >\n Click anywhere on this card.\n </Card>"},{"name":"Content Only","description":"Card without header","code":"<Card>\n Just content, no title or description.\n </Card>"}]},"Checkbox":{"filePath":"src/components/Checkbox/Checkbox.fragment.tsx","meta":{"name":"Checkbox","description":"Binary toggle for form fields. Use for options that require explicit submission, unlike Toggle which takes effect immediately.","category":"forms","status":"stable","tags":["checkbox","form","boolean","selection","input"],"since":"0.1.0"},"usage":{"when":["Form fields requiring explicit submission","Multi-select from a list of options","Terms and conditions acceptance","Filter or preference checklists"],"whenNot":["Immediate effect settings (use Toggle)","Single selection from options (use RadioGroup)","Selecting from many options (use Select)"],"guidelines":["Always include a visible label","Use description for additional context when needed","Group related checkboxes visually","Use indeterminate state for parent/child relationships"],"accessibility":["Proper label association","Keyboard accessible (Space to toggle)","Visible focus indicator","Indeterminate state properly announced"]},"props":{"checked":{"type":"boolean","description":"Controlled checked state"},"defaultChecked":{"type":"boolean","description":"Default checked state (uncontrolled)"},"onCheckedChange":{"type":"function","description":"Called when checked state changes"},"indeterminate":{"type":"boolean","description":"Indeterminate state (partial selection)","default":"false"},"disabled":{"type":"boolean","description":"Disable the checkbox","default":"false"},"label":{"type":"string","description":"Label text"},"description":{"type":"string","description":"Description text below the label"},"size":{"type":"enum","description":"Checkbox size","default":"md","values":["sm","md","lg"]}},"relations":[{"component":"Toggle","relationship":"alternative","note":"Use Toggle for immediate-effect settings"},{"component":"Input","relationship":"sibling","note":"Checkbox handles boolean; Input handles text"}],"variants":[{"name":"Default","description":"Basic checkbox with label","code":"<StatefulCheckbox label=\"Accept terms and conditions\" />"},{"name":"With Description","description":"Checkbox with helper text","code":"<StatefulCheckbox\n label=\"Email notifications\"\n description=\"Receive email updates about your account activity\"\n />"},{"name":"Checked","description":"Pre-checked checkbox","code":"<StatefulCheckbox defaultChecked label=\"Subscribe to newsletter\" />"},{"name":"Indeterminate","description":"Partial selection state","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Checkbox indeterminate label=\"Select all\" />\n <div style={{ marginLeft: '24px', display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <StatefulCheckbox defaultChecked label=\"Option 1\" />\n <StatefulCheckbox label=\"Option 2\" />\n <StatefulCheckbox defaultChecked label=\"Option 3\" />\n </div>\n </div>"},{"name":"Sizes","description":"Available size options","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <StatefulCheckbox size=\"sm\" label=\"Small checkbox\" />\n <StatefulCheckbox size=\"md\" label=\"Medium checkbox\" />\n <StatefulCheckbox size=\"lg\" label=\"Large checkbox\" />\n </div>"},{"name":"Disabled","description":"Non-interactive states","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Checkbox disabled label=\"Disabled unchecked\" />\n <Checkbox disabled checked label=\"Disabled checked\" />\n </div>"}]},"Dialog":{"filePath":"src/components/Dialog/Dialog.fragment.tsx","meta":{"name":"Dialog","description":"Modal overlay for focused user interactions. Use for confirmations, forms, or content requiring full attention.","category":"overlays","status":"stable","tags":["modal","dialog","overlay","popup","confirmation"],"since":"0.1.0"},"usage":{"when":["Confirming destructive actions (delete, discard changes)","Collecting focused input (forms, settings)","Displaying content that requires acknowledgment","Multi-step workflows that need isolation"],"whenNot":["Simple tooltips or hints (use Tooltip)","Contextual menus (use Menu or Popover)","Non-blocking notifications (use Toast or Alert)","Simple confirmation that can be inline (use Alert)"],"guidelines":["Keep dialog content focused on a single task","Provide clear primary and secondary actions","Use descriptive title that explains the purpose","Allow dismissal via backdrop click or close button for non-critical dialogs","Trap focus within the dialog for accessibility"],"accessibility":["Automatically traps focus within the dialog","Closes on Escape key press","Returns focus to trigger element on close","Uses role=\"dialog\" with proper aria attributes"]},"props":{"children":{"type":"node","description":"Dialog content (use Dialog.Content, Dialog.Header, etc.)","required":true},"open":{"type":"boolean","description":"Controlled open state"},"defaultOpen":{"type":"boolean","description":"Default open state (uncontrolled)","default":"false"},"onOpenChange":{"type":"function","description":"Called when open state changes"},"modal":{"type":"boolean","description":"Whether to render as modal (blocks interaction with rest of page)","default":"true"}},"relations":[{"component":"Popover","relationship":"alternative","note":"Use Popover for non-modal contextual content"},{"component":"Menu","relationship":"alternative","note":"Use Menu for action lists"},{"component":"Alert","relationship":"sibling","note":"Use Alert for inline notifications"}],"variants":[{"name":"Default","description":"Basic dialog with header, body, and footer","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button>Open Dialog</Button>\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Close />\n <Dialog.Header>\n <Dialog.Title>Dialog Title</Dialog.Title>\n <Dialog.Description>\n A brief description of what this dialog is for.\n </Dialog.Description>\n </Dialog.Header>\n <Dialog.Body>\n <p>Dialog content goes here. You can include forms, text, or any other content.</p>\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"secondary\">Cancel</Button>\n </Dialog.Close>\n <Button variant=\"primary\">Confirm</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>"},{"name":"Confirmation","description":"Destructive action confirmation","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button variant=\"danger\">Delete Item</Button>\n </Dialog.Trigger>\n <Dialog.Content size=\"sm\">\n <Dialog.Header>\n <Dialog.Title>Delete item?</Dialog.Title>\n <Dialog.Description>\n This action cannot be undone. The item will be permanently removed.\n </Dialog.Description>\n </Dialog.Header>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"secondary\">Cancel</Button>\n </Dialog.Close>\n <Button variant=\"danger\">Delete</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>"},{"name":"Large","description":"Large dialog for complex content","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button>Open Large Dialog</Button>\n </Dialog.Trigger>\n <Dialog.Content size=\"lg\">\n <Dialog.Close />\n <Dialog.Header>\n <Dialog.Title>Settings</Dialog.Title>\n <Dialog.Description>\n Configure your application preferences.\n </Dialog.Description>\n </Dialog.Header>\n <Dialog.Body>\n <p>This dialog has more space for complex forms or content layouts.</p>\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"secondary\">Cancel</Button>\n </Dialog.Close>\n <Button variant=\"primary\">Save Changes</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>"}]},"EmptyState":{"filePath":"src/components/EmptyState/EmptyState.fragment.tsx","meta":{"name":"EmptyState","description":"Placeholder for empty content areas. Provides context, guidance, and actions when no data is available.","category":"feedback","status":"stable","tags":["empty","placeholder","no-data","zero-state","blank-slate"],"since":"0.1.0"},"usage":{"when":["Empty lists, tables, or search results","New user onboarding (no content yet)","Filtered views with no matches","Error states where content failed to load"],"whenNot":["Loading states (use skeleton or spinner)","Error messages with retry (use Alert)","Temporary messages (use Toast)"],"guidelines":["Always explain why the area is empty","Provide a clear action to resolve the empty state","Use appropriate icons to reinforce the message","Keep messaging positive and actionable"],"accessibility":["Empty state content is accessible to screen readers","Action buttons follow button accessibility guidelines"]},"props":{"title":{"type":"string","description":"Main heading text","required":true},"description":{"type":"string","description":"Supporting description text"},"icon":{"type":"node","description":"Optional icon element"},"action":{"type":"object","description":"Primary action button: { label, onClick, variant? }"},"secondaryAction":{"type":"object","description":"Secondary action button: { label, onClick, variant? }"},"size":{"type":"enum","description":"Size variant","default":"md","values":["sm","md","lg"]}},"relations":[{"component":"Alert","relationship":"alternative","note":"Use Alert for error states with retry"},{"component":"Progress","relationship":"alternative","note":"Use Progress/Spinner for loading states"}],"variants":[{"name":"Default","description":"Basic empty state with action","code":"<EmptyState\n icon={<FolderIcon />}\n title=\"No projects yet\"\n description=\"Get started by creating your first project.\"\n action={{\n label: 'Create Project',\n onClick: () => {},\n }}\n />"},{"name":"No Results","description":"Empty search results","code":"<EmptyState\n icon={<SearchIcon />}\n title=\"No results found\"\n description=\"Try adjusting your search terms or filters.\"\n action={{\n label: 'Clear Filters',\n onClick: () => {},\n variant: 'secondary',\n }}\n />"},{"name":"With Secondary Action","description":"Empty state with two actions","code":"<EmptyState\n icon={<InboxIcon />}\n title=\"Inbox is empty\"\n description=\"You have no new messages.\"\n action={{\n label: 'Compose Message',\n onClick: () => {},\n }}\n secondaryAction={{\n label: 'View Archive',\n onClick: () => {},\n }}\n />"},{"name":"Small","description":"Compact empty state for inline use","code":"<EmptyState\n size=\"sm\"\n title=\"No items\"\n description=\"Add items to see them here.\"\n />"},{"name":"Large","description":"Prominent empty state for full-page use","code":"<EmptyState\n size=\"lg\"\n icon={<FolderIcon />}\n title=\"Welcome to your workspace\"\n description=\"This is where your projects will appear. Create your first project to get started.\"\n action={{\n label: 'Create Your First Project',\n onClick: () => {},\n }}\n />"}]},"Grid":{"filePath":"src/components/Grid/Grid.fragment.tsx","meta":{"name":"Grid","description":"Responsive grid layout for arranging items in columns with consistent spacing","category":"layout","status":"stable","tags":["grid","layout","columns","responsive"]},"usage":{"when":["Arranging cards, tiles, or media in a responsive grid","Building form layouts with multi-column fields","Creating dashboard layouts with widgets","Any content that should reflow across breakpoints"],"whenNot":["Single-column stacked content (use a simple flex column or Stack)","Navigation bars or toolbars (use a dedicated nav component)","Content that must not wrap (use inline layout)"],"guidelines":["Use columns=\"auto\" with minChildWidth for grids that adapt without breakpoints","Use responsive object { base: 1, md: 2, lg: 3 } when you need explicit control per breakpoint","Use fixed column counts when exact column control is needed and responsiveness is not required","Use Grid.Item with colSpan to create asymmetric layouts within a fixed grid","Keep gap consistent within a context — md is the default and works for most cases"],"accessibility":["Grid is purely visual — it does not affect reading order or semantics","Ensure logical source order matches visual order for screen readers"]},"props":{"columns":{"type":"union","description":"Number of columns: a number (1-12), a responsive object { base, sm, md, lg, xl }, or \"auto\" for auto-fill","default":1,"constraints":["Use \"auto\" with minChildWidth for fully fluid layouts","Use responsive object for explicit breakpoint control: { base: 1, md: 2, lg: 3 }"]},"minChildWidth":{"type":"string","description":"Minimum width for auto-fill columns (e.g., \"16rem\", \"250px\")","constraints":["Only applies when columns=\"auto\""]},"gap":{"type":"enum","description":"Gap between grid items, mapped to spacing tokens","default":"md","values":["none","xs","sm","md","lg","xl"]},"alignItems":{"type":"enum","description":"Vertical alignment of items within their cells","values":["start","center","end","stretch"]},"justifyItems":{"type":"enum","description":"Horizontal alignment of items within their cells","values":["start","center","end","stretch"]},"padding":{"type":"enum","description":"Internal padding of the grid container","default":"none","values":["none","sm","md","lg"]}},"relations":[{"component":"Card","relationship":"child","note":"Grid commonly contains Card components for dashboard and tile layouts"},{"component":"Separator","relationship":"sibling","note":"Use Separator between grid sections"}],"variants":[{"name":"Default","description":"Basic 3-column grid","code":"<Grid columns={3} gap=\"md\">\n <div style={{ padding: '1rem', background: '#f1f5f9' }}>Item 1</div>\n <div style={{ padding: '1rem', background: '#f1f5f9' }}>Item 2</div>\n <div style={{ padding: '1rem', background: '#f1f5f9' }}>Item 3</div>\n </Grid>"},{"name":"Responsive","description":"1 column on mobile, 2 on tablet, 3 on desktop","code":"<Grid columns={{ base: 1, md: 2, lg: 3 }} gap=\"md\">\n <div style={{ padding: '1rem', background: '#f1f5f9' }}>Card 1</div>\n <div style={{ padding: '1rem', background: '#f1f5f9' }}>Card 2</div>\n <div style={{ padding: '1rem', background: '#f1f5f9' }}>Card 3</div>\n </Grid>"},{"name":"Auto-fill","description":"Responsive grid that auto-fills based on minimum child width","code":"<Grid columns=\"auto\" minChildWidth=\"12rem\" gap=\"md\">\n <div style={{ padding: '1rem', background: '#f1f5f9' }}>Card 1</div>\n <div style={{ padding: '1rem', background: '#f1f5f9' }}>Card 2</div>\n <div style={{ padding: '1rem', background: '#f1f5f9' }}>Card 3</div>\n <div style={{ padding: '1rem', background: '#f1f5f9' }}>Card 4</div>\n </Grid>"},{"name":"With Spanning","description":"Grid items spanning multiple columns","code":"<Grid columns={4} gap=\"md\">\n <Grid.Item colSpan={2}>\n <div style={{ padding: '1rem', background: '#f1f5f9' }}>Spans 2 cols</div>\n </Grid.Item>\n <div style={{ padding: '1rem', background: '#f1f5f9' }}>1 col</div>\n <div style={{ padding: '1rem', background: '#f1f5f9' }}>1 col</div>\n <Grid.Item colSpan=\"full\">\n <div style={{ padding: '1rem', background: '#f1f5f9' }}>Full width</div>\n </Grid.Item>\n </Grid>"},{"name":"Form Layout","description":"Two-column form that collapses to single column on mobile","code":"<Grid columns={{ base: 1, md: 2 }} gap=\"md\">\n <div style={{ padding: '0.5rem', background: '#f1f5f9' }}>First Name</div>\n <div style={{ padding: '0.5rem', background: '#f1f5f9' }}>Last Name</div>\n <Grid.Item colSpan=\"full\">\n <div style={{ padding: '0.5rem', background: '#f1f5f9' }}>Email Address</div>\n </Grid.Item>\n </Grid>"}]},"Input":{"filePath":"src/components/Input/Input.fragment.tsx","meta":{"name":"Input","description":"Text input field for single-line user data entry","category":"forms","status":"stable","tags":["form","input","text"]},"usage":{"when":["Collecting single-line text data from users","Email, password, phone number, or URL input","Search fields","Short form fields (name, title, etc.)"],"whenNot":["Multi-line text (use Textarea)","Selecting from predefined options (use Select)","Boolean input (use Checkbox or Switch)","Date/time input (use DatePicker)"],"guidelines":["Always provide a label for accessibility","Use appropriate input type for data validation","Show validation errors with error prop and helperText","Use placeholder for format hints, not labels"],"accessibility":["Labels must be associated with inputs","Error messages should be announced to screen readers","Required fields should be indicated"]},"props":{"value":{"type":"string","description":"Current input value (controlled)"},"placeholder":{"type":"string","description":"Placeholder text shown when empty","constraints":["Use for format hints only, not as a replacement for labels"]},"type":{"type":"enum","description":"HTML input type for validation and keyboard","default":"text","values":["text","email","password","number","tel","url"]},"disabled":{"type":"boolean","description":"Whether the input is interactive","default":false},"error":{"type":"boolean","description":"Whether to show error styling","default":false},"label":{"type":"string","description":"Label text displayed above input"},"helperText":{"type":"string","description":"Helper or error message below input"},"onChange":{"type":"function","description":"Called with new value on change"}},"relations":[{"component":"Textarea","relationship":"alternative","note":"Use Textarea for multi-line text input"},{"component":"Select","relationship":"alternative","note":"Use Select when choosing from predefined options"},{"component":"FormField","relationship":"parent","note":"Wrap in FormField for consistent form layout"}],"variants":[{"name":"Default","description":"Basic text input","code":"<Input label=\"Name\" placeholder=\"Enter your name\" />"},{"name":"With Value","description":"Input with pre-filled value","code":"<Input label=\"Email\" type=\"email\" value=\"user@example.com\" />"},{"name":"With Helper","description":"Input with helper text","code":"<Input\n label=\"Password\"\n type=\"password\"\n placeholder=\"Create a password\"\n helperText=\"Must be at least 8 characters\"\n />"},{"name":"Error State","description":"Input showing validation error","code":"<Input\n label=\"Email\"\n type=\"email\"\n value=\"invalid-email\"\n error\n helperText=\"Please enter a valid email address\"\n />"},{"name":"Disabled","description":"Non-interactive input","code":"<Input label=\"Username\" value=\"readonly-user\" disabled />"}]},"Menu":{"filePath":"src/components/Menu/Menu.fragment.tsx","meta":{"name":"Menu","description":"Dropdown menu for actions and commands. Use for contextual actions, overflow menus, or grouped commands.","category":"overlays","status":"stable","tags":["menu","dropdown","actions","context-menu","commands"],"since":"0.1.0"},"usage":{"when":["Overflow actions that dont fit in the toolbar","Context menus (right-click)","User account menus","Grouped actions with separators"],"whenNot":["Selecting from options (use Select)","Navigation (use Tabs or navigation components)","Form selection (use Select or RadioGroup)"],"guidelines":["Group related actions with Menu.Group","Use separators to divide action categories","Include keyboard shortcuts where applicable","Use danger variant for destructive actions","Keep menu items under 10-12 for usability"],"accessibility":["Full keyboard navigation with arrow keys","Type-ahead search for items","Focus returns to trigger on close","Proper ARIA menu roles"]},"props":{"children":{"type":"node","description":"Menu trigger and content","required":true},"open":{"type":"boolean","description":"Controlled open state"},"defaultOpen":{"type":"boolean","description":"Default open state (uncontrolled)","default":"false"},"onOpenChange":{"type":"function","description":"Called when open state changes"},"modal":{"type":"boolean","description":"Whether menu is modal","default":"true"}},"relations":[{"component":"Select","relationship":"alternative","note":"Use Select for form field selection"},{"component":"Popover","relationship":"alternative","note":"Use Popover for rich non-action content"}],"variants":[{"name":"Default","description":"Basic dropdown menu","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"secondary\">Actions</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Item onSelect={() => {}}>Edit</Menu.Item>\n <Menu.Item onSelect={() => {}}>Duplicate</Menu.Item>\n <Menu.Separator />\n <Menu.Item danger onSelect={() => {}}>Delete</Menu.Item>\n </Menu.Content>\n </Menu>"},{"name":"With Shortcuts","description":"Menu items with keyboard shortcuts","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"secondary\">Edit</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Item shortcut=\"Ctrl+Z\" onSelect={() => {}}>Undo</Menu.Item>\n <Menu.Item shortcut=\"Ctrl+Y\" onSelect={() => {}}>Redo</Menu.Item>\n <Menu.Separator />\n <Menu.Item shortcut=\"Ctrl+C\" onSelect={() => {}}>Copy</Menu.Item>\n <Menu.Item shortcut=\"Ctrl+V\" onSelect={() => {}}>Paste</Menu.Item>\n </Menu.Content>\n </Menu>"},{"name":"With Groups","description":"Menu with labeled groups","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"secondary\">Options</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Group>\n <Menu.GroupLabel>View</Menu.GroupLabel>\n <Menu.Item onSelect={() => {}}>Zoom In</Menu.Item>\n <Menu.Item onSelect={() => {}}>Zoom Out</Menu.Item>\n </Menu.Group>\n <Menu.Separator />\n <Menu.Group>\n <Menu.GroupLabel>Layout</Menu.GroupLabel>\n <Menu.Item onSelect={() => {}}>Grid View</Menu.Item>\n <Menu.Item onSelect={() => {}}>List View</Menu.Item>\n </Menu.Group>\n </Menu.Content>\n </Menu>"},{"name":"With Checkboxes","description":"Menu with toggleable options","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"secondary\">Display</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.CheckboxItem defaultChecked>Show Grid</Menu.CheckboxItem>\n <Menu.CheckboxItem defaultChecked>Show Rulers</Menu.CheckboxItem>\n <Menu.CheckboxItem>Show Guides</Menu.CheckboxItem>\n </Menu.Content>\n </Menu>"}]},"Popover":{"filePath":"src/components/Popover/Popover.fragment.tsx","meta":{"name":"Popover","description":"Rich content overlay anchored to a trigger element. Use for forms, detailed information, or interactive content that should stay in context.","category":"overlays","status":"stable","tags":["popover","overlay","dropdown","floating","contextual"],"since":"0.1.0"},"usage":{"when":["Inline editing forms","Rich preview content","Filter panels","Date/color pickers","Content that needs more space than a tooltip"],"whenNot":["Simple hints (use Tooltip)","Action lists (use Menu)","Blocking user interaction (use Dialog)","System notifications (use Toast or Alert)"],"guidelines":["Keep popover content focused and minimal","Include a clear way to close (X button or action buttons)","Position to avoid covering important content","Use arrow to visually connect popover to trigger"],"accessibility":["Focus is moved to popover content on open","Closes on Escape key","Focus returns to trigger on close"]},"props":{"children":{"type":"node","description":"Popover trigger and content","required":true},"open":{"type":"boolean","description":"Controlled open state"},"defaultOpen":{"type":"boolean","description":"Default open state (uncontrolled)","default":"false"},"onOpenChange":{"type":"function","description":"Called when open state changes"},"modal":{"type":"boolean","description":"Whether to block page interaction","default":"false"}},"relations":[{"component":"Tooltip","relationship":"alternative","note":"Use Tooltip for brief, non-interactive hints"},{"component":"Menu","relationship":"alternative","note":"Use Menu for action lists"},{"component":"Dialog","relationship":"alternative","note":"Use Dialog for blocking interactions"}],"variants":[{"name":"Default","description":"Basic popover with content","code":"<Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Open Popover</Button>\n </Popover.Trigger>\n <Popover.Content>\n <Popover.Close />\n <Popover.Title>Popover Title</Popover.Title>\n <Popover.Description>\n This is a popover with some content. It can contain text, forms, or other elements.\n </Popover.Description>\n </Popover.Content>\n </Popover>"},{"name":"With Form","description":"Popover containing a form","code":"<Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Edit Name</Button>\n </Popover.Trigger>\n <Popover.Content size=\"sm\">\n <Popover.Close />\n <Popover.Title>Edit Name</Popover.Title>\n <Popover.Body>\n <Input label=\"Display Name\" placeholder=\"Enter name\" />\n </Popover.Body>\n <Popover.Footer>\n <Popover.Close asChild>\n <Button variant=\"secondary\" size=\"sm\">Cancel</Button>\n </Popover.Close>\n <Button variant=\"primary\" size=\"sm\">Save</Button>\n </Popover.Footer>\n </Popover.Content>\n </Popover>"},{"name":"With Arrow","description":"Popover with pointing arrow","code":"<Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Info</Button>\n </Popover.Trigger>\n <Popover.Content arrow>\n <Popover.Title>Quick Tip</Popover.Title>\n <Popover.Description>\n This popover has an arrow pointing to its trigger element.\n </Popover.Description>\n </Popover.Content>\n </Popover>"},{"name":"Positions","description":"Popover on different sides","code":"<div style={{ display: 'flex', gap: '16px', padding: '60px' }}>\n <Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Top</Button>\n </Popover.Trigger>\n <Popover.Content side=\"top\" size=\"sm\">\n <Popover.Description>Popover on top</Popover.Description>\n </Popover.Content>\n </Popover>\n <Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Bottom</Button>\n </Popover.Trigger>\n <Popover.Content side=\"bottom\" size=\"sm\">\n <Popover.Description>Popover on bottom</Popover.Description>\n </Popover.Content>\n </Popover>\n </div>"}]},"Progress":{"filePath":"src/components/Progress/Progress.fragment.tsx","meta":{"name":"Progress","description":"Visual indicator of task completion or loading state. Available in linear and circular variants.","category":"feedback","status":"stable","tags":["progress","loading","indicator","percentage","status"],"since":"0.1.0"},"usage":{"when":["Showing upload/download progress","Displaying task completion percentage","Form completion indicators","Loading states with known duration"],"whenNot":["Unknown loading duration (use Spinner)","Step-based progress (use Stepper)","Status without percentage (use Badge)"],"guidelines":["Use determinate progress when you know the completion percentage","Use indeterminate for unknown durations","Include a label for context when the purpose isnt obvious","Use appropriate color variants for success/warning/danger states"],"accessibility":["Uses role=\"progressbar\" with aria-valuenow","Label is associated with the progress bar","State changes are announced to screen readers"]},"props":{"value":{"type":"number","description":"Current progress value (0-100). Null for indeterminate."},"size":{"type":"enum","description":"Size of the progress bar","default":"md","values":["sm","md","lg"]},"variant":{"type":"enum","description":"Color variant","default":"default","values":["default","success","warning","danger"]},"label":{"type":"string","description":"Label text above the progress bar"},"showValue":{"type":"boolean","description":"Show percentage value","default":"false"}},"relations":[{"component":"Badge","relationship":"alternative","note":"Use Badge for status without percentage"},{"component":"Alert","relationship":"sibling","note":"Use Alert for completion messages"}],"variants":[{"name":"Default","description":"Basic progress bar with percentage","code":"<Progress value={60} label=\"Uploading...\" showValue />"},{"name":"Variants","description":"Different color variants for different states","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', width: '300px' }}>\n <Progress value={75} variant=\"default\" label=\"Processing\" showValue />\n <Progress value={100} variant=\"success\" label=\"Complete\" showValue />\n <Progress value={80} variant=\"warning\" label=\"Almost full\" showValue />\n <Progress value={95} variant=\"danger\" label=\"Storage critical\" showValue />\n </div>"},{"name":"Sizes","description":"Different progress bar sizes","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', width: '300px' }}>\n <Progress value={50} size=\"sm\" label=\"Small\" />\n <Progress value={50} size=\"md\" label=\"Medium\" />\n <Progress value={50} size=\"lg\" label=\"Large\" />\n </div>"},{"name":"Indeterminate","description":"Loading state with unknown duration","code":"<Progress value={null} label=\"Loading...\" />"},{"name":"Circular","description":"Circular progress indicator","code":"<div style={{ display: 'flex', gap: '24px', alignItems: 'center' }}>\n <CircularProgress value={25} size=\"sm\" />\n <CircularProgress value={50} size=\"md\" showValue />\n <CircularProgress value={75} size=\"lg\" showValue variant=\"success\" />\n <CircularProgress value={null} size=\"md\" />\n </div>"}]},"RadioGroup":{"filePath":"src/components/RadioGroup/RadioGroup.fragment.tsx","meta":{"name":"RadioGroup","description":"Single selection from a list of mutually exclusive options","category":"forms","status":"stable","tags":["form","radio","selection","options"]},"usage":{"when":["User must select exactly one option from a small set","Options are mutually exclusive","All options should be visible at once","2-5 options available"],"whenNot":["Multiple selections allowed (use Checkbox group)","Many options (use Select)","Binary on/off choice (use Toggle/Switch)","Options need to be searchable (use Combobox)"],"guidelines":["Always have one option pre-selected when possible","Order options logically (alphabetical, frequency, etc.)","Keep option labels concise","Use descriptions for complex options"],"accessibility":["Group must have an accessible label","Use arrow keys to navigate between options","Selected option should be clearly indicated"]},"props":{"value":{"type":"string","description":"Controlled selected value"},"defaultValue":{"type":"string","description":"Default value (uncontrolled)"},"onValueChange":{"type":"function","description":"Callback when selection changes"},"orientation":{"type":"enum","description":"Layout orientation","default":"vertical","values":["horizontal","vertical"]},"size":{"type":"enum","description":"Size variant","default":"md","values":["sm","md","lg"]},"disabled":{"type":"boolean","description":"Disable all options","default":false},"label":{"type":"string","description":"Group label"},"error":{"type":"string","description":"Error message"}},"relations":[{"component":"Checkbox","relationship":"alternative","note":"Use Checkbox for multiple selections"},{"component":"Select","relationship":"alternative","note":"Use Select for many options or limited space"},{"component":"Toggle","relationship":"alternative","note":"Use Toggle for binary on/off choices"}],"variants":[{"name":"Default","description":"Basic radio group with labels","code":"<RadioGroup defaultValue=\"option1\" label=\"Select an option\">\n <RadioGroup.Item value=\"option1\" label=\"Option 1\" />\n <RadioGroup.Item value=\"option2\" label=\"Option 2\" />\n <RadioGroup.Item value=\"option3\" label=\"Option 3\" />\n </RadioGroup>"},{"name":"With Descriptions","description":"Radio items with additional context","code":"<RadioGroup defaultValue=\"standard\" label=\"Shipping Method\">\n <RadioGroup.Item\n value=\"standard\"\n label=\"Standard\"\n description=\"5-7 business days\"\n />\n <RadioGroup.Item\n value=\"express\"\n label=\"Express\"\n description=\"2-3 business days\"\n />\n <RadioGroup.Item\n value=\"overnight\"\n label=\"Overnight\"\n description=\"Next business day\"\n />\n </RadioGroup>"},{"name":"Horizontal","description":"Side-by-side layout","code":"<RadioGroup orientation=\"horizontal\" defaultValue=\"small\" label=\"Size\">\n <RadioGroup.Item value=\"small\" label=\"S\" />\n <RadioGroup.Item value=\"medium\" label=\"M\" />\n <RadioGroup.Item value=\"large\" label=\"L\" />\n <RadioGroup.Item value=\"xlarge\" label=\"XL\" />\n </RadioGroup>"},{"name":"With Error","description":"Validation error state","code":"<RadioGroup label=\"Required selection\" error=\"Please select an option\">\n <RadioGroup.Item value=\"a\" label=\"Option A\" />\n <RadioGroup.Item value=\"b\" label=\"Option B\" />\n </RadioGroup>"},{"name":"Disabled","description":"Non-interactive state","code":"<RadioGroup disabled defaultValue=\"locked\" label=\"Locked selection\">\n <RadioGroup.Item value=\"locked\" label=\"This is locked\" />\n <RadioGroup.Item value=\"other\" label=\"Cannot select\" />\n </RadioGroup>"}]},"Select":{"filePath":"src/components/Select/Select.fragment.tsx","meta":{"name":"Select","description":"Dropdown for choosing from a list of options. Use when there are more than 4-5 choices that would clutter the UI.","category":"forms","status":"stable","tags":["select","dropdown","form","options","picker"],"since":"0.1.0"},"usage":{"when":["Choosing from a predefined list of options","More than 4-5 options that would clutter UI as radio buttons","Space-constrained forms","When users need to see all options at once"],"whenNot":["Very few options (2-3) - use radio buttons","Users might type custom values - use Combobox","Multiple selections needed - use Checkbox group or MultiSelect","Actions, not selection - use Menu"],"guidelines":["Include a placeholder that explains what to select","Group related options with SelectGroup","Keep option text concise","Order options logically (alphabetical, by frequency, or by category)"],"accessibility":["Full keyboard navigation support","Type-ahead search within options","Proper ARIA roles and attributes"]},"props":{"children":{"type":"node","description":"Select trigger and content","required":true},"value":{"type":"string","description":"Controlled selected value"},"defaultValue":{"type":"string","description":"Default selected value (uncontrolled)"},"onValueChange":{"type":"function","description":"Called when selection changes"},"placeholder":{"type":"string","description":"Placeholder text when no value selected"},"disabled":{"type":"boolean","description":"Disable the select","default":"false"}},"relations":[{"component":"Menu","relationship":"alternative","note":"Use Menu for action-based dropdowns"},{"component":"Input","relationship":"sibling","note":"Use Input for free-form text entry"},{"component":"Checkbox","relationship":"alternative","note":"Use Checkbox group for multiple selections"}],"variants":[{"name":"Default","description":"Basic select dropdown","code":"<StatefulSelect placeholder=\"Select a fruit\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"apple\">Apple</Select.Item>\n <Select.Item value=\"banana\">Banana</Select.Item>\n <Select.Item value=\"orange\">Orange</Select.Item>\n <Select.Item value=\"grape\">Grape</Select.Item>\n </Select.Content>\n </StatefulSelect>"},{"name":"With Groups","description":"Options organized into groups","code":"<StatefulSelect placeholder=\"Select a country\">\n <Select.Trigger />\n <Select.Content>\n <Select.Group>\n <Select.GroupLabel>North America</Select.GroupLabel>\n <Select.Item value=\"us\">United States</Select.Item>\n <Select.Item value=\"ca\">Canada</Select.Item>\n <Select.Item value=\"mx\">Mexico</Select.Item>\n </Select.Group>\n <Select.Group>\n <Select.GroupLabel>Europe</Select.GroupLabel>\n <Select.Item value=\"uk\">United Kingdom</Select.Item>\n <Select.Item value=\"de\">Germany</Select.Item>\n <Select.Item value=\"fr\">France</Select.Item>\n </Select.Group>\n </Select.Content>\n </StatefulSelect>"},{"name":"With Disabled Options","description":"Some options are disabled","code":"<StatefulSelect placeholder=\"Select a plan\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"free\">Free</Select.Item>\n <Select.Item value=\"pro\">Pro</Select.Item>\n <Select.Item value=\"enterprise\" disabled>Enterprise (Contact Sales)</Select.Item>\n </Select.Content>\n </StatefulSelect>"},{"name":"Disabled","description":"Disabled select","code":"<Select disabled placeholder=\"Select an option\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"1\">Option 1</Select.Item>\n </Select.Content>\n </Select>"}]},"Separator":{"filePath":"src/components/Separator/Separator.fragment.tsx","meta":{"name":"Separator","description":"Visual divider between content sections. Use to create clear visual boundaries and improve content organization.","category":"layout","status":"stable","tags":["separator","divider","hr","line","layout"],"since":"0.1.0"},"usage":{"when":["Dividing content sections","Separating groups of related items","Creating visual breathing room","Labeled section breaks"],"whenNot":["Creating grid layouts (use CSS Grid)","Decorative borders (use CSS)","Spacing alone is sufficient"],"guidelines":["Use sparingly - too many separators create visual noise","Consider if spacing alone would work","Use soft variant for subtle separation","Labeled separators work well for major section breaks"],"accessibility":["Uses role=\"separator\" for semantic meaning","Decorative separators should be aria-hidden"]},"props":{"orientation":{"type":"enum","description":"Direction of the separator","default":"horizontal","values":["horizontal","vertical"]},"spacing":{"type":"enum","description":"Margin around the separator","default":"none","values":["none","sm","md","lg"]},"soft":{"type":"boolean","description":"Softer, lighter appearance","default":"false"},"label":{"type":"string","description":"Optional text label (horizontal only)"}},"relations":[{"component":"Card","relationship":"sibling","note":"Cards provide stronger visual grouping"}],"variants":[{"name":"Default","description":"Basic horizontal separator","code":"<div style={{ width: '300px' }}>\n <p>Content above</p>\n <Separator spacing=\"md\" />\n <p>Content below</p>\n </div>"},{"name":"With Label","description":"Labeled section divider","code":"<div style={{ width: '300px' }}>\n <p>First section</p>\n <Separator label=\"Or\" spacing=\"md\" />\n <p>Second section</p>\n </div>"},{"name":"Soft","description":"Subtle separator","code":"<div style={{ width: '300px' }}>\n <p>Content above</p>\n <Separator soft spacing=\"md\" />\n <p>Content below</p>\n </div>"},{"name":"Vertical","description":"Vertical separator between elements","code":"<div style={{ display: 'flex', alignItems: 'center', gap: '16px', height: '40px' }}>\n <span>Item 1</span>\n <Separator orientation=\"vertical\" />\n <span>Item 2</span>\n <Separator orientation=\"vertical\" />\n <span>Item 3</span>\n </div>"},{"name":"Spacing Options","description":"Different spacing sizes","code":"<div style={{ width: '300px' }}>\n <p>No spacing</p>\n <Separator spacing=\"none\" />\n <p>Small spacing</p>\n <Separator spacing=\"sm\" />\n <p>Medium spacing</p>\n <Separator spacing=\"md\" />\n <p>Large spacing</p>\n <Separator spacing=\"lg\" />\n <p>End</p>\n </div>"}]},"Skeleton":{"filePath":"src/components/Skeleton/Skeleton.fragment.tsx","meta":{"name":"Skeleton","description":"Placeholder loading state for content","category":"feedback","status":"stable","tags":["loading","placeholder","skeleton","shimmer"]},"usage":{"when":["Content is loading asynchronously","Preventing layout shift during data fetching","Providing visual feedback that content is coming","Improving perceived performance"],"whenNot":["Short loading times (< 300ms)","When spinner is more appropriate","Background operations without visible impact"],"guidelines":["Match skeleton shape to expected content","Use semantic variants (text, heading, avatar) for consistency","Maintain similar dimensions to loaded content","Avoid too many skeleton elements - simplify complex layouts"],"accessibility":["Skeletons are decorative - use aria-hidden","Announce loading state separately if needed","Ensure sufficient contrast for the animation"]},"props":{"variant":{"type":"enum","description":"Semantic variant that auto-sizes","default":"rect","values":["text","heading","avatar","button","input","rect"]},"size":{"type":"enum","description":"Size for avatar/button variants","default":"md","values":["sm","md","lg"]},"width":{"type":"union","description":"Custom width (string or number)"},"height":{"type":"union","description":"Custom height (string or number)"},"fill":{"type":"boolean","description":"Fill parent container","default":false},"radius":{"type":"enum","description":"Border radius override","values":["none","sm","md","lg","full"]}},"relations":[{"component":"Progress","relationship":"alternative","note":"Use Progress for determinate loading"}],"variants":[{"name":"Default","description":"Basic rectangle skeleton","code":"<Skeleton width={200} height={20} />"},{"name":"Text Lines","description":"Multi-line text placeholder","code":"<Skeleton.Text lines={3} />"},{"name":"Semantic Variants","description":"Pre-configured shapes for common elements","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <Skeleton variant=\"heading\" width={200} />\n <Skeleton variant=\"text\" width=\"100%\" />\n <Skeleton variant=\"text\" width=\"80%\" />\n </div>"},{"name":"Avatar Skeleton","description":"Circular placeholder for avatars","code":"<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n <Skeleton.Circle size=\"sm\" />\n <Skeleton.Circle size=\"md\" />\n <Skeleton.Circle size=\"lg\" />\n </div>"},{"name":"Card Skeleton","description":"Composed skeleton for a card layout","code":"<div style={{ width: 300, padding: 16, border: '1px solid #e5e7eb', borderRadius: 8 }}>\n <Skeleton variant=\"rect\" height={120} radius=\"md\" />\n <div style={{ marginTop: 12 }}>\n <Skeleton variant=\"heading\" width=\"60%\" />\n </div>\n <div style={{ marginTop: 8 }}>\n <Skeleton.Text lines={2} />\n </div>\n </div>"}]},"Table":{"filePath":"src/components/Table/Table.fragment.tsx","meta":{"name":"Table","description":"Data table with sorting and row selection. Use for displaying structured data that needs to be scanned, compared, or acted upon.","category":"data-display","status":"stable","tags":["table","data","grid","list","sorting"],"since":"0.1.0"},"usage":{"when":["Displaying structured, tabular data","Data that users need to scan and compare","Lists with multiple attributes per item","Data that needs sorting or selection"],"whenNot":["Simple lists (use List component)","Card-based layouts (use CardGrid)","Heavily interactive data (consider DataGrid)","Small screens (consider card or list view)"],"guidelines":["Keep columns to a reasonable number (5-7 max)","Use consistent alignment (numbers right, text left)","Provide meaningful empty states","Consider mobile responsiveness"],"accessibility":["Proper table semantics with headers","Sortable columns are keyboard accessible","Row selection is properly announced"]},"props":{"columns":{"type":"array","description":"Column definitions","required":true},"data":{"type":"array","description":"Data rows to display","required":true},"sortable":{"type":"boolean","description":"Enable column sorting","default":"false"},"selectable":{"type":"boolean","description":"Enable row selection","default":"false"},"onRowClick":{"type":"function","description":"Handler for row clicks"},"emptyMessage":{"type":"string","description":"Message when no data","default":"No data available"},"size":{"type":"enum","description":"Table density","default":"md","values":["sm","md"]}},"relations":[{"component":"EmptyState","relationship":"sibling","note":"Use EmptyState for empty table states"},{"component":"Badge","relationship":"sibling","note":"Use Badge for status columns"}],"variants":[{"name":"Default","description":"Basic data table","code":"<Table\n columns={columns}\n data={sampleUsers}\n />"},{"name":"Sortable","description":"Table with sortable columns","code":"<Table\n columns={columns}\n data={sampleUsers}\n sortable\n />"},{"name":"Clickable Rows","description":"Table with clickable rows","code":"<Table\n columns={columns}\n data={sampleUsers}\n onRowClick={(row) => alert(`Clicked: ${row.name}`)}\n />"},{"name":"Compact","description":"Smaller, denser table","code":"<Table\n columns={columns}\n data={sampleUsers}\n size=\"sm\"\n />"},{"name":"Empty State","description":"Table with no data","code":"<Table\n columns={columns}\n data={[]}\n emptyMessage=\"No users found\"\n />"}]},"Tabs":{"filePath":"src/components/Tabs/Tabs.fragment.tsx","meta":{"name":"Tabs","description":"Organize content into switchable panels. Use for related content that benefits from a compact, navigable layout.","category":"navigation","status":"stable","tags":["tabs","navigation","panels","content-switcher"],"since":"0.1.0"},"usage":{"when":["Organizing related content into sections","Reducing page scrolling by grouping content","Settings pages with multiple categories","Dashboard views with different data perspectives"],"whenNot":["Primary navigation (use sidebar or header nav)","Sequential steps (use Stepper or wizard)","Comparing content side-by-side","Very long lists of options (use Select or Menu)"],"guidelines":["Keep tab labels short (1-2 words)","Order tabs by usage frequency or logical sequence","Avoid more than 5-6 tabs; consider sub-navigation for more","Tab content should be roughly equivalent in scope","Use pills variant for contained sections, underline for page-level tabs"],"accessibility":["Keyboard navigation with arrow keys","Tab panels are properly labeled","Focus management follows WAI-ARIA tabs pattern"]},"props":{"children":{"type":"node","description":"Tab list and panels (use Tabs.List, Tabs.Tab, Tabs.Panel)","required":true},"defaultValue":{"type":"string","description":"Initially active tab (uncontrolled)"},"value":{"type":"string","description":"Controlled active tab value"},"onValueChange":{"type":"function","description":"Called when active tab changes"},"orientation":{"type":"enum","description":"Tab list orientation","default":"horizontal","values":["horizontal","vertical"]}},"relations":[{"component":"Select","relationship":"alternative","note":"Use Select for many options in compact space"},{"component":"Menu","relationship":"alternative","note":"Use Menu for action-based navigation"}],"variants":[{"name":"Underline","description":"Default underline style tabs","code":"<Tabs defaultValue=\"overview\">\n <Tabs.List variant=\"underline\">\n <Tabs.Tab value=\"overview\">Overview</Tabs.Tab>\n <Tabs.Tab value=\"analytics\">Analytics</Tabs.Tab>\n <Tabs.Tab value=\"settings\">Settings</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panel value=\"overview\">\n <p>Overview content goes here.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"analytics\">\n <p>Analytics content goes here.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"settings\">\n <p>Settings content goes here.</p>\n </Tabs.Panel>\n </Tabs>"},{"name":"Pills","description":"Pill-style tabs for contained sections","code":"<Tabs defaultValue=\"all\">\n <Tabs.List variant=\"pills\">\n <Tabs.Tab value=\"all\">All</Tabs.Tab>\n <Tabs.Tab value=\"active\">Active</Tabs.Tab>\n <Tabs.Tab value=\"archived\">Archived</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panel value=\"all\">\n <p>Showing all items.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"active\">\n <p>Showing active items only.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"archived\">\n <p>Showing archived items.</p>\n </Tabs.Panel>\n </Tabs>"},{"name":"With Disabled","description":"Tabs with a disabled option","code":"<Tabs defaultValue=\"general\">\n <Tabs.List variant=\"underline\">\n <Tabs.Tab value=\"general\">General</Tabs.Tab>\n <Tabs.Tab value=\"security\">Security</Tabs.Tab>\n <Tabs.Tab value=\"billing\" disabled>Billing</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panel value=\"general\">\n <p>General settings panel.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"security\">\n <p>Security settings panel.</p>\n </Tabs.Panel>\n </Tabs>"}]},"Textarea":{"filePath":"src/components/Textarea/Textarea.fragment.tsx","meta":{"name":"Textarea","description":"Multi-line text input for longer form content","category":"forms","status":"stable","tags":["input","text","form","multiline"]},"usage":{"when":["Collecting multi-line text (comments, descriptions)","Free-form text input that may span multiple lines","Message composition fields","Code or content editing"],"whenNot":["Single-line input (use Input)","Rich text editing (use rich text editor)","Selecting from predefined options (use Select)"],"guidelines":["Set appropriate rows for expected content length","Use placeholder to show example format","Show character count when maxLength is set","Consider auto-resize for better UX"],"accessibility":["Always provide a visible label","Use helperText for format hints","Error messages should be descriptive"]},"props":{"value":{"type":"string","description":"Controlled value"},"placeholder":{"type":"string","description":"Placeholder text"},"rows":{"type":"number","description":"Number of visible text rows","default":3},"label":{"type":"string","description":"Label text above the textarea"},"helperText":{"type":"string","description":"Helper text below the textarea"},"error":{"type":"boolean","description":"Error state","default":false},"disabled":{"type":"boolean","description":"Disabled state","default":false},"resize":{"type":"enum","description":"Resize behavior","default":"vertical","values":["none","vertical","horizontal","both"]},"maxLength":{"type":"number","description":"Maximum character length"}},"relations":[{"component":"Input","relationship":"alternative","note":"Use Input for single-line text"}],"variants":[{"name":"Default","description":"Basic textarea with label","code":"<Textarea\n label=\"Description\"\n placeholder=\"Enter a description...\"\n />"},{"name":"With Helper Text","description":"Textarea with additional guidance","code":"<Textarea\n label=\"Bio\"\n placeholder=\"Tell us about yourself...\"\n helperText=\"Max 500 characters\"\n maxLength={500}\n />"},{"name":"Error State","description":"Textarea showing validation error","code":"<Textarea\n label=\"Comments\"\n placeholder=\"Add your comments...\"\n error\n helperText=\"This field is required\"\n />"},{"name":"Disabled","description":"Non-interactive textarea","code":"<Textarea\n label=\"Notes\"\n placeholder=\"Cannot edit...\"\n disabled\n />"},{"name":"Custom Rows","description":"Textarea with more visible rows","code":"<Textarea\n label=\"Long Description\"\n placeholder=\"Enter detailed information...\"\n rows={6}\n />"}]},"Toast":{"filePath":"src/components/Toast/Toast.fragment.tsx","meta":{"name":"Toast","description":"Brief, non-blocking notification messages","category":"feedback","status":"stable","tags":["notification","alert","message","feedback"]},"usage":{"when":["Providing feedback after an action","Showing success/error status of operations","Non-critical information that doesn't require action","Temporary messages that auto-dismiss"],"whenNot":["Critical errors requiring user action (use Dialog)","Persistent information (use Alert)","Inline validation (use form error states)","System-wide announcements (use Banner)"],"guidelines":["Keep messages brief and actionable","Use appropriate variant for the message type","Auto-dismiss after reasonable duration (3-5s)","Allow manual dismissal for longer messages","Limit number of simultaneous toasts"],"accessibility":["Use role=\"alert\" for important messages","Ensure sufficient display time for reading","Don't rely solely on color for meaning","Provide dismiss button with accessible label"]},"props":{"title":{"type":"string","description":"Toast title"},"description":{"type":"string","description":"Additional message content"},"variant":{"type":"enum","description":"Visual variant indicating message type","default":"default","values":["default","success","error","warning","info"]},"duration":{"type":"number","description":"Auto-dismiss duration in ms (0 = no auto-dismiss)","default":5000},"action":{"type":"object","description":"Optional action button { label, onClick }"}},"relations":[{"component":"Alert","relationship":"alternative","note":"Use Alert for persistent inline messages"},{"component":"Dialog","relationship":"alternative","note":"Use Dialog for messages requiring user action"}],"variants":[{"name":"Default","description":"Interactive toast demo - click buttons to trigger toasts","code":"<ToastDemoWrapper />"},{"name":"Success","description":"Success message variant","code":"<Toast\n title=\"Success!\"\n description=\"Your changes have been saved.\"\n variant=\"success\"\n />"},{"name":"Error","description":"Error message variant","code":"<Toast\n title=\"Error\"\n description=\"Failed to save changes. Please try again.\"\n variant=\"error\"\n />"},{"name":"Warning","description":"Warning message variant","code":"<Toast\n title=\"Warning\"\n description=\"This action cannot be undone.\"\n variant=\"warning\"\n />"},{"name":"Info","description":"Informational message variant","code":"<Toast\n title=\"New Update\"\n description=\"Version 2.0 is now available.\"\n variant=\"info\"\n />"},{"name":"With Action","description":"Toast with an action button","code":"<Toast\n title=\"File deleted\"\n description=\"The file has been moved to trash.\"\n action={{\n label: 'Undo',\n onClick: () => console.log('Undo clicked'),\n }}\n />"}]},"Toggle":{"filePath":"src/components/Toggle/Toggle.fragment.tsx","meta":{"name":"Toggle","description":"Binary on/off switch for settings and preferences. Provides immediate visual feedback and is ideal for options that take effect instantly.","category":"forms","status":"stable","tags":["switch","toggle","boolean","settings","preference"],"since":"0.1.0"},"usage":{"when":["Binary settings that take effect immediately (e.g., dark mode, notifications)","Enabling/disabling features in a settings panel","Options where the result is immediately visible","Mobile-friendly boolean inputs"],"whenNot":["Multiple options in a group (use checkbox group)","Selection requires form submission to take effect (use checkbox)","Yes/No questions in forms (use radio buttons)","Complex multi-state options (use select or radio)"],"guidelines":["Toggle should always have a visible label explaining what it controls","The \"on\" state should be the positive/enabling action","Changes should take effect immediately - no save button needed","Include a description for toggles whose effect isn't obvious from the label","Group related toggles visually in settings panels"],"accessibility":["Uses role=\"switch\" with aria-checked for proper semantics","Must have an accessible label (visible or aria-label)","Focus indicator must be clearly visible","State change must be announced by screen readers"]},"props":{"checked":{"type":"boolean","description":"Whether the toggle is in the on state","default":"false"},"onChange":{"type":"function","description":"Callback with new checked state: (checked: boolean) => void"},"label":{"type":"string","description":"Visible label text"},"description":{"type":"string","description":"Helper text shown below the label"},"disabled":{"type":"boolean","description":"Whether the toggle is non-interactive","default":"false"},"size":{"type":"enum","description":"Toggle track size","default":"md","values":["sm","md"]}},"relations":[{"component":"Input","relationship":"sibling","note":"Input handles text/number entry; Toggle handles boolean state"},{"component":"Checkbox","relationship":"alternative","note":"Use Checkbox when change requires form submission"}],"variants":[{"name":"Default Off","description":"Toggle in the off state","code":"<StatefulToggle label=\"Email notifications\" />","args":{"label":"Email notifications"}},{"name":"Checked","description":"Toggle in the on state","code":"<StatefulToggle checked label=\"Dark mode\" />","args":{"checked":true,"label":"Dark mode"}},{"name":"With Description","description":"Toggle with explanatory helper text","code":"<StatefulToggle\n checked\n label=\"Auto-save\"\n description=\"Automatically save changes as you type\"\n />","args":{"checked":true,"label":"Auto-save","description":"Automatically save changes as you type"}},{"name":"Small Size","description":"Compact toggle for dense settings panels","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <StatefulToggle size=\"sm\" checked label=\"Show line numbers\" />\n <StatefulToggle size=\"sm\" label=\"Word wrap\" />\n <StatefulToggle size=\"sm\" checked label=\"Minimap\" />\n </div>"},{"name":"Disabled States","description":"Non-interactive toggles showing both states","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <Toggle disabled label=\"Premium feature (upgrade required)\" />\n <Toggle disabled checked label=\"System managed (read-only)\" />\n </div>"},{"name":"Settings Panel","description":"Multiple toggles in a realistic settings layout","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '320px' }}>\n <StatefulToggle\n checked\n label=\"Push notifications\"\n description=\"Receive push notifications on your device\"\n />\n <StatefulToggle\n checked\n label=\"Email digest\"\n description=\"Weekly summary of your activity\"\n />\n <StatefulToggle\n label=\"Marketing emails\"\n description=\"Product updates and promotional offers\"\n />\n </div>"}]},"Tooltip":{"filePath":"src/components/Tooltip/Tooltip.fragment.tsx","meta":{"name":"Tooltip","description":"Contextual help text that appears on hover or focus. Perfect for explaining icons, truncated text, or providing additional context.","category":"overlays","status":"stable","tags":["tooltip","hint","help","hover","contextual"],"since":"0.1.0"},"usage":{"when":["Explaining icon-only buttons","Showing full text for truncated content","Providing keyboard shortcuts","Brief contextual help that fits in one line"],"whenNot":["Long-form help content (use Popover)","Critical information users must see (use Alert)","Interactive content (use Popover or Menu)","Mobile-primary interfaces (tooltips require hover)"],"guidelines":["Keep tooltip text concise (under 80 characters)","Use sentence case, no period for single sentences","Avoid duplicating visible label text","Consider mobile users who cannot hover"],"accessibility":["Accessible via focus as well as hover","Uses role=\"tooltip\" with proper aria association","Delay prevents tooltips from appearing during navigation"]},"props":{"children":{"type":"element","description":"The element that triggers the tooltip","required":true},"content":{"type":"node","description":"Content to display in the tooltip","required":true},"side":{"type":"enum","description":"Which side to show the tooltip","default":"top","values":["top","bottom","left","right"]},"align":{"type":"enum","description":"Alignment along the side","default":"center","values":["start","center","end"]},"sideOffset":{"type":"number","description":"Distance from trigger in pixels","default":"6"},"delay":{"type":"number","description":"Delay before showing (ms)","default":"400"},"arrow":{"type":"boolean","description":"Show arrow pointing to trigger","default":"true"},"disabled":{"type":"boolean","description":"Disable the tooltip","default":"false"}},"relations":[{"component":"Popover","relationship":"alternative","note":"Use Popover for interactive or longer content"},{"component":"Alert","relationship":"alternative","note":"Use Alert for critical information that must be visible"}],"variants":[{"name":"Default","description":"Basic tooltip on hover","code":"<Tooltip content=\"Save your changes\">\n <Button>Save</Button>\n </Tooltip>"},{"name":"Positions","description":"Tooltips on different sides","code":"<div style={{ display: 'flex', gap: '16px', padding: '40px' }}>\n <Tooltip content=\"Top tooltip\" side=\"top\">\n <Button variant=\"secondary\">Top</Button>\n </Tooltip>\n <Tooltip content=\"Bottom tooltip\" side=\"bottom\">\n <Button variant=\"secondary\">Bottom</Button>\n </Tooltip>\n <Tooltip content=\"Left tooltip\" side=\"left\">\n <Button variant=\"secondary\">Left</Button>\n </Tooltip>\n <Tooltip content=\"Right tooltip\" side=\"right\">\n <Button variant=\"secondary\">Right</Button>\n </Tooltip>\n </div>"},{"name":"With Shortcut","description":"Tooltip showing keyboard shortcut","code":"<Tooltip content=\"Undo (Ctrl+Z)\">\n <Button variant=\"ghost\">Undo</Button>\n </Tooltip>"},{"name":"No Arrow","description":"Tooltip without arrow","code":"<Tooltip content=\"Clean tooltip\" arrow={false}>\n <Button variant=\"secondary\">Hover me</Button>\n </Tooltip>"}]}},"recipes":{"Card Grid":{"filePath":"src/recipes/CardGrid.recipe.ts","name":"Card Grid","description":"Responsive grid of cards that reflows based on available space","category":"layout","components":["Grid","Card"],"code":"<Grid columns=\"auto\" minChildWidth=\"16rem\" gap=\"md\">\n {items.map(item => (\n <Card key={item.id} title={item.title} description={item.description}>\n {item.content}\n </Card>\n ))}\n</Grid>","tags":["grid","cards","responsive","dashboard","tiles"]},"Confirm Dialog":{"filePath":"src/recipes/ConfirmDialog.recipe.ts","name":"Confirm Dialog","description":"Confirmation dialog with destructive action warning","category":"overlays","components":["Dialog","Button"],"code":"<Dialog open={isOpen} onClose={onClose}>\n <Dialog.Title>{title}</Dialog.Title>\n <Dialog.Description>{description}</Dialog.Description>\n <Dialog.Actions>\n <Button variant=\"secondary\" onClick={onClose}>Cancel</Button>\n <Button variant=\"danger\" onClick={onConfirm}>Confirm</Button>\n </Dialog.Actions>\n</Dialog>","tags":["confirm","dialog","modal","destructive"]},"Dashboard Layout":{"filePath":"src/recipes/DashboardLayout.recipe.ts","name":"Dashboard Layout","description":"Dashboard grid with a featured full-width card and smaller metric cards below","category":"layout","components":["Grid","Card","Badge","Separator"],"code":"<Grid columns={4} gap=\"lg\">\n <Grid.Item colSpan=\"full\">\n <Card title=\"Overview\" description=\"Key metrics for this period\">\n {summaryContent}\n </Card>\n </Grid.Item>\n <Card title=\"Users\" variant=\"outlined\">\n <Badge variant=\"success\">{stats.users}</Badge>\n </Card>\n <Card title=\"Revenue\" variant=\"outlined\">\n <Badge variant=\"info\">{stats.revenue}</Badge>\n </Card>\n <Card title=\"Orders\" variant=\"outlined\">\n <Badge variant=\"warning\">{stats.orders}</Badge>\n </Card>\n <Card title=\"Errors\" variant=\"outlined\">\n <Badge variant=\"danger\">{stats.errors}</Badge>\n </Card>\n <Grid.Item colSpan=\"full\">\n <Separator spacing=\"md\" />\n </Grid.Item>\n <Grid.Item colSpan={2}>\n <Card title=\"Recent Activity\">{activityList}</Card>\n </Grid.Item>\n <Grid.Item colSpan={2}>\n <Card title=\"Notifications\">{notificationList}</Card>\n </Grid.Item>\n</Grid>","tags":["dashboard","layout","metrics","widgets","overview"]},"Form Layout":{"filePath":"src/recipes/FormLayout.recipe.ts","name":"Form Layout","description":"Two-column form with full-width fields where needed, using Grid for alignment","category":"forms","components":["Grid","Input","Textarea","Select","Button"],"code":"<Grid columns={2} gap=\"md\">\n <Input label=\"First Name\" placeholder=\"Jane\" />\n <Input label=\"Last Name\" placeholder=\"Doe\" />\n <Grid.Item colSpan=\"full\">\n <Input label=\"Email\" type=\"email\" placeholder=\"jane@example.com\" />\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Select label=\"Role\">\n <Select.Item value=\"admin\">Admin</Select.Item>\n <Select.Item value=\"editor\">Editor</Select.Item>\n <Select.Item value=\"viewer\">Viewer</Select.Item>\n </Select>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Textarea label=\"Bio\" placeholder=\"Tell us about yourself\" />\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Button type=\"submit\" variant=\"primary\">Save</Button>\n </Grid.Item>\n</Grid>","tags":["form","layout","grid","inputs","settings"]},"Login Form":{"filePath":"src/recipes/LoginForm.recipe.ts","name":"Login Form","description":"Email/password authentication form with validation states","category":"forms","components":["FormField","Input","Button","Alert"],"code":"<FormField label=\"Email\" error={errors.email}>\n <Input type=\"email\" placeholder=\"you@example.com\" />\n</FormField>\n<FormField label=\"Password\" error={errors.password}>\n <Input type=\"password\" />\n</FormField>\n<Button type=\"submit\" variant=\"primary\">Sign in</Button>\n{error && <Alert variant=\"danger\">{error}</Alert>}","tags":["auth","login","form"]},"Settings Page":{"filePath":"src/recipes/SettingsPage.recipe.ts","name":"Settings Page","description":"Settings page with labeled sections using cards, toggles, and a save action","category":"forms","components":["Grid","Card","Toggle","Input","Select","Separator","Button"],"code":"<Grid columns={1} gap=\"lg\">\n <Card title=\"Profile\" description=\"Your public profile information\">\n <Grid columns={2} gap=\"md\">\n <Input label=\"Display Name\" defaultValue={user.name} />\n <Input label=\"Email\" type=\"email\" defaultValue={user.email} />\n <Grid.Item colSpan=\"full\">\n <Input label=\"Website\" type=\"url\" defaultValue={user.website} />\n </Grid.Item>\n </Grid>\n </Card>\n\n <Card title=\"Notifications\" description=\"Choose what you get notified about\">\n <Grid columns={1} gap=\"sm\">\n <Toggle label=\"Email notifications\" checked={prefs.emailNotifs} onChange={onToggle('emailNotifs')} />\n <Toggle label=\"Push notifications\" checked={prefs.pushNotifs} onChange={onToggle('pushNotifs')} />\n <Toggle label=\"Weekly digest\" checked={prefs.digest} onChange={onToggle('digest')} />\n </Grid>\n </Card>\n\n <Card title=\"Appearance\">\n <Select label=\"Theme\" value={prefs.theme} onChange={onThemeChange}>\n <Select.Item value=\"light\">Light</Select.Item>\n <Select.Item value=\"dark\">Dark</Select.Item>\n <Select.Item value=\"system\">System</Select.Item>\n </Select>\n </Card>\n\n <Separator />\n <Button variant=\"primary\" type=\"submit\">Save Changes</Button>\n</Grid>","tags":["settings","preferences","form","toggle","layout"]}}}
|
|
1
|
+
{"version":"1.0.0","generatedAt":"2026-02-02T15:56:01.932Z","packageName":"@fragments-sdk/ui","segments":{"Accordion":{"filePath":"src/components/Accordion/Accordion.fragment.tsx","meta":{"name":"Accordion","description":"Vertically stacked, collapsible content sections. Use for organizing related content that can be progressively disclosed.","category":"layout","status":"stable","tags":["accordion","collapse","expand","disclosure","faq"],"since":"0.2.0"},"usage":{"when":["FAQ pages with multiple questions and answers","Settings panels with grouped options","Long forms that benefit from progressive disclosure","Navigation menus with nested items"],"whenNot":["Primary content that all users need to see","Very short content (just display inline)","Sequential steps (use Stepper or wizard)","Tab-like navigation (use Tabs instead)"],"guidelines":["Keep section headers concise and descriptive","Use single mode when only one section should be open at a time","Use multiple mode when users may need to compare sections","Consider defaulting important sections to open","Avoid nesting accordions more than one level deep"],"accessibility":["Keyboard navigation with Enter/Space to toggle","Arrow keys navigate between accordion headers","Uses proper ARIA expanded/controls attributes","Focus is visible on accordion triggers"]},"props":{"children":{"type":"node","description":"Accordion items (use Accordion.Item with Accordion.Trigger and Accordion.Content)","required":true},"type":{"type":"enum","description":"Whether one or multiple items can be open","default":"single","values":["single","multiple"]},"value":{"type":"string | string[]","description":"Controlled open item(s)"},"defaultValue":{"type":"string | string[]","description":"Initially open item(s) for uncontrolled usage"},"onValueChange":{"type":"function","description":"Called when open items change"},"collapsible":{"type":"boolean","description":"Whether all items can be closed (single mode only)","default":"false"}},"relations":[{"component":"Tabs","relationship":"alternative","note":"Use Tabs for horizontal switching between related views"},{"component":"Dialog","relationship":"alternative","note":"Use Dialog for focused content that interrupts the flow"},{"component":"Card","relationship":"complementary","note":"Accordion items can contain Card-like content"}],"variants":[{"name":"Basic","description":"Single accordion with collapsible sections","code":"<Accordion type=\"single\" collapsible defaultValue=\"item-1\">\n <Accordion.Item value=\"item-1\">\n <Accordion.Trigger>What is Fragments UI?</Accordion.Trigger>\n <Accordion.Content>\n Fragments UI is a modern React component library built on Base UI primitives, providing accessible and customizable components.\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"item-2\">\n <Accordion.Trigger>How do I install it?</Accordion.Trigger>\n <Accordion.Content>\n Install via npm or pnpm: <code>pnpm add @fragments-sdk/ui</code>\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"item-3\">\n <Accordion.Trigger>Is it accessible?</Accordion.Trigger>\n <Accordion.Content>\n Yes! All components follow WAI-ARIA guidelines and support keyboard navigation.\n </Accordion.Content>\n </Accordion.Item>\n </Accordion>"},{"name":"Multiple Open","description":"Allows multiple sections to be open simultaneously","code":"<Accordion type=\"multiple\" defaultValue={['features', 'pricing']}>\n <Accordion.Item value=\"features\">\n <Accordion.Trigger>Features</Accordion.Trigger>\n <Accordion.Content>\n Comprehensive component library with theming support, accessibility built-in, and TypeScript-first development.\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"pricing\">\n <Accordion.Trigger>Pricing</Accordion.Trigger>\n <Accordion.Content>\n Free and open source. MIT licensed for both personal and commercial use.\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"support\">\n <Accordion.Trigger>Support</Accordion.Trigger>\n <Accordion.Content>\n Community support via GitHub issues and discussions.\n </Accordion.Content>\n </Accordion.Item>\n </Accordion>"},{"name":"With Disabled","description":"Accordion with a disabled item","code":"<Accordion type=\"single\" collapsible>\n <Accordion.Item value=\"available\">\n <Accordion.Trigger>Available Section</Accordion.Trigger>\n <Accordion.Content>\n This section can be expanded and collapsed.\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"disabled\" disabled>\n <Accordion.Trigger>Disabled Section</Accordion.Trigger>\n <Accordion.Content>\n This content is not accessible because the item is disabled.\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"another\">\n <Accordion.Trigger>Another Section</Accordion.Trigger>\n <Accordion.Content>\n This section is also available for interaction.\n </Accordion.Content>\n </Accordion.Item>\n </Accordion>"}],"ai":{"compositionPattern":"compound","subComponents":["Item","Trigger","Content"],"requiredChildren":["Item"],"commonPatterns":["<Accordion type=\"single\" collapsible><Accordion.Item value=\"item-1\"><Accordion.Trigger>{title}</Accordion.Trigger><Accordion.Content>{content}</Accordion.Content></Accordion.Item></Accordion>"]}},"Alert":{"filePath":"src/components/Alert/Alert.fragment.tsx","meta":{"name":"Alert","description":"Contextual feedback messages for user actions or system status. Supports multiple severity levels with optional actions and dismissibility.","category":"feedback","status":"stable","tags":["notification","message","feedback","banner","toast"],"since":"0.1.0"},"usage":{"when":["Communicating the result of a user action (success, error)","Warning about potential issues before they occur","Providing important contextual information inline","System status notifications that require attention"],"whenNot":["Brief status labels (use Badge instead)","Transient notifications (use Toast/Snackbar)","Form-field-level errors (use Input error prop)","Confirmation before destructive actions (use Dialog)"],"guidelines":["Match severity to the actual importance: info for context, warning for potential issues, error for failures","Always provide actionable guidance in error alerts","Use Alert.Title for complex messages; skip titles for brief one-liners","Limit to one action per alert to avoid decision paralysis","Use Alert.Close only for non-critical information"],"accessibility":["Uses role=\"alert\" for screen reader announcement","Error and warning alerts are announced immediately by assistive technology","Alert.Close must have an accessible label","Color alone must not convey meaning - icons and text reinforce severity"]},"props":{"children":{"type":"node","description":"Alert content - use Alert.Icon, Alert.Body, Alert.Title, Alert.Content, Alert.Actions, Alert.Close sub-components","required":true},"severity":{"type":"enum","description":"Visual severity level","default":"info","values":["info","success","warning","error"]}},"relations":[{"component":"Badge","relationship":"alternative","note":"Use Badge for compact, inline status labels"},{"component":"Toast","relationship":"alternative","note":"Use Toast for transient notifications that auto-dismiss"},{"component":"Dialog","relationship":"sibling","note":"Use Dialog for blocking confirmations"}],"variants":[{"name":"Info","description":"Informational context for the user","code":"<Alert severity=\"info\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Content>\n Your session will expire in 15 minutes. Save your work to avoid losing changes.\n </Alert.Content>\n </Alert.Body>\n </Alert>"},{"name":"Success","description":"Positive confirmation of completed action","code":"<Alert severity=\"success\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Payment processed</Alert.Title>\n <Alert.Content>\n Your order #12345 has been confirmed. You will receive a confirmation email shortly.\n </Alert.Content>\n </Alert.Body>\n </Alert>"},{"name":"Warning","description":"Caution about potential issues","code":"<Alert severity=\"warning\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Storage almost full</Alert.Title>\n <Alert.Content>\n You have used 90% of your storage quota. Consider deleting unused files.\n </Alert.Content>\n </Alert.Body>\n </Alert>"},{"name":"Error","description":"Error state requiring user attention","code":"<Alert severity=\"error\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Upload failed</Alert.Title>\n <Alert.Content>\n The file could not be uploaded. Check your connection and try again.\n </Alert.Content>\n </Alert.Body>\n </Alert>"},{"name":"With Action","description":"Alert with an actionable button","code":"<Alert severity=\"warning\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Update available</Alert.Title>\n <Alert.Content>\n A new version is available with important security fixes.\n </Alert.Content>\n <Alert.Actions>\n <Alert.Action onClick={() => {}}>Update now</Alert.Action>\n </Alert.Actions>\n </Alert.Body>\n </Alert>"},{"name":"Dismissible","description":"Alert that can be closed by the user","code":"<Alert severity=\"info\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Content>\n You can customize your notification preferences in Settings.\n </Alert.Content>\n </Alert.Body>\n <Alert.Close />\n </Alert>"}],"ai":{"compositionPattern":"compound","subComponents":["Icon","Body","Title","Content","Actions","Action","Close"],"requiredChildren":["Body"],"commonPatterns":["<Alert severity=\"info\"><Alert.Icon /><Alert.Body><Alert.Content>{message}</Alert.Content></Alert.Body></Alert>","<Alert severity=\"warning\"><Alert.Icon /><Alert.Body><Alert.Title>{title}</Alert.Title><Alert.Content>{message}</Alert.Content></Alert.Body></Alert>","<Alert severity=\"error\"><Alert.Icon /><Alert.Body><Alert.Title>{title}</Alert.Title><Alert.Content>{message}</Alert.Content></Alert.Body><Alert.Close /></Alert>"]}},"AppShell":{"filePath":"src/components/AppShell/AppShell.fragment.tsx","meta":{"name":"AppShell","description":"Full layout wrapper integrating sidebar, header, main content, and optional aside panel. Supports two layout modes: stacked (header on top) and sidebar-inset (sidebar full height).","category":"layout","status":"stable","tags":["layout","shell","scaffold","dashboard","app-layout"],"since":"0.5.0"},"usage":{"when":["Building dashboard-style applications","Apps with persistent sidebar navigation","Layouts requiring header, sidebar, and main content areas","Responsive layouts that need mobile drawer behavior"],"whenNot":["Simple marketing pages (use standard layout)","Content-first sites without navigation (use simpler layout)","Single-page apps with minimal UI (use minimal layout)"],"guidelines":["Use layout=\"stacked\" when header should span full width (logo in header)","Use layout=\"sidebar-inset\" when sidebar should be full height (logo in sidebar)","AppShell automatically wraps with SidebarProvider","Use AppShell.Sidebar to configure sidebar width and collapse behavior","Main content responds to sidebar collapsed state","Aside panel is hidden on mobile automatically"],"accessibility":["Main content area has id=\"main-content\" for skip links","Use Header.SkipLink for keyboard navigation","Sidebar drawer has proper focus trap on mobile","Keyboard navigation supported throughout"]},"props":{"children":{"type":"node","description":"Layout content (use AppShell.Header, AppShell.Sidebar, AppShell.Main, AppShell.Aside)","required":true},"layout":{"type":"enum","description":"Layout mode for header/sidebar positioning","default":"stacked","values":["stacked","sidebar-inset","inset"]}},"relations":[{"component":"ThemeProvider","relationship":"parent","note":"AppShell should be wrapped in ThemeProvider"},{"component":"Header","relationship":"child","note":"Header is placed inside AppShell.Header"},{"component":"Sidebar","relationship":"child","note":"Sidebar content goes inside AppShell.Sidebar"}],"variants":[{"name":"Stacked Layout","description":"Header spans full width above sidebar (default). Best when brand/logo should be prominent in header.","code":"<div style={{ height: '400px', position: 'relative', overflow: 'hidden', border: '1px solid var(--fui-border)', borderRadius: '8px' }}>\n <AppShell layout=\"stacked\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Brand>MyApp</Header.Brand>\n <Header.Nav>\n <Header.NavItem active>Dashboard</Header.NavItem>\n <Header.NavItem>Settings</Header.NavItem>\n </Header.Nav>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"200px\" collapsible=\"offcanvas\">\n <Sidebar.Nav>\n <Sidebar.Section label=\"Menu\">\n <Sidebar.Item icon={<HomeIcon />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<GearIcon />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\">\n <h2 style={{ margin: '0 0 8px' }}>Stacked Layout</h2>\n <p style={{ margin: 0, color: 'var(--fui-text-secondary)' }}>\n Header spans full width. Logo is in the header.\n </p>\n </AppShell.Main>\n </AppShell>\n </div>"},{"name":"Sidebar Inset Layout","description":"Sidebar is full height, header sits next to it. Best for documentation sites or when sidebar branding is preferred.","code":"<div style={{ height: '400px', position: 'relative', overflow: 'hidden', border: '1px solid var(--fui-border)', borderRadius: '8px' }}>\n <AppShell layout=\"sidebar-inset\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Search>\n <div style={{ display: 'flex', alignItems: 'center', gap: '8px', padding: '6px 12px', background: 'var(--fui-bg-secondary)', borderRadius: '6px', color: 'var(--fui-text-tertiary)', fontSize: '14px' }}>\n <SearchIcon /> Search...\n </div>\n </Header.Search>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"200px\" collapsible=\"offcanvas\">\n <Sidebar.Header>\n <span style={{ fontWeight: 600 }}>MyApp</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section label=\"Menu\">\n <Sidebar.Item icon={<HomeIcon />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<GearIcon />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>v1.0.0</Sidebar.Footer>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\">\n <h2 style={{ margin: '0 0 8px' }}>Sidebar Inset Layout</h2>\n <p style={{ margin: 0, color: 'var(--fui-text-secondary)' }}>\n Sidebar is full height. Logo is in the sidebar header.\n </p>\n </AppShell.Main>\n </AppShell>\n </div>"},{"name":"With Aside Panel","description":"App shell with optional right panel for additional context or actions","code":"<div style={{ height: '400px', position: 'relative', overflow: 'hidden', border: '1px solid var(--fui-border)', borderRadius: '8px' }}>\n <AppShell layout=\"stacked\">\n <AppShell.Header>\n <Header>\n <Header.Brand>App</Header.Brand>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"180px\" collapsible=\"offcanvas\">\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Stats</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\">\n <h2 style={{ margin: '0 0 8px' }}>Main Content</h2>\n <p style={{ margin: 0 }}>Content with aside panel on the right.</p>\n </AppShell.Main>\n\n <AppShell.Aside width=\"180px\">\n <div style={{ padding: '16px' }}>\n <h3 style={{ margin: '0 0 8px', fontSize: '14px' }}>Aside Panel</h3>\n <p style={{ margin: 0, fontSize: '13px', color: 'var(--fui-text-secondary)' }}>\n Additional context, filters, or quick actions.\n </p>\n </div>\n </AppShell.Aside>\n </AppShell>\n </div>"},{"name":"Collapsible Icon Sidebar","description":"Sidebar that collapses to icons only on desktop","code":"<div style={{ height: '400px', position: 'relative', overflow: 'hidden', border: '1px solid var(--fui-border)', borderRadius: '8px' }}>\n <AppShell layout=\"sidebar-inset\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar collapsible=\"icon\" width=\"200px\" collapsedWidth=\"56px\">\n <Sidebar.Header>\n <span style={{ fontWeight: 600 }}>App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<GearIcon />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Sidebar.CollapseToggle />\n </Sidebar.Footer>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\">\n <p style={{ margin: 0 }}>Click the collapse button in the sidebar footer to toggle between expanded and icon-only modes.</p>\n </AppShell.Main>\n </AppShell>\n </div>"},{"name":"Inset Layout","description":"Modern shadcn-style layout with rounded main content area and visual separation from sidebar.","code":"<div style={{ height: '400px', position: 'relative', overflow: 'hidden', border: '1px solid var(--fui-border)', borderRadius: '8px' }}>\n <AppShell layout=\"inset\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Search>\n <div style={{ display: 'flex', alignItems: 'center', gap: '8px', padding: '6px 12px', background: 'var(--fui-bg-primary)', borderRadius: '6px', color: 'var(--fui-text-tertiary)', fontSize: '14px', border: '1px solid var(--fui-border)' }}>\n <SearchIcon /> Search...\n </div>\n </Header.Search>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"200px\" collapsible=\"offcanvas\">\n <Sidebar.Header>\n <span style={{ fontWeight: 600 }}>MyApp</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section label=\"Menu\">\n <Sidebar.Item icon={<HomeIcon />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<GearIcon />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>v1.0.0</Sidebar.Footer>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\">\n <h2 style={{ margin: '0 0 8px' }}>Inset Layout</h2>\n <p style={{ margin: 0, color: 'var(--fui-text-secondary)' }}>\n Main content has rounded corners and visual separation from the sidebar.\n </p>\n </AppShell.Main>\n </AppShell>\n </div>"}]},"Avatar":{"filePath":"src/components/Avatar/Avatar.fragment.tsx","meta":{"name":"Avatar","description":"Visual representation of a user or entity","category":"data-display","status":"stable","tags":["user","profile","image","identity"]},"usage":{"when":["Displaying user profile pictures","Showing team member lists","Representing entities in lists or cards","User identification in comments or messages"],"whenNot":["Decorative images (use Image)","Logo display (use Logo component)","Large profile headers (use custom layout)"],"guidelines":["Always provide alt text or name for accessibility","Use consistent sizes within the same context","Provide fallback initials when image may not load","Use Avatar.Group for multiple avatars in a row"],"accessibility":["Include meaningful alt text describing the user","Initials should be derived from name for screen readers","Decorative avatars should have empty alt"]},"props":{"src":{"type":"string","description":"Image source URL"},"alt":{"type":"string","description":"Alt text for the image"},"name":{"type":"string","description":"Full name - used to generate initials"},"initials":{"type":"string","description":"Fallback initials (1-2 characters)"},"size":{"type":"enum","description":"Size variant","default":"md","values":["xs","sm","md","lg","xl"]},"shape":{"type":"enum","description":"Shape variant","default":"circle","values":["circle","square"]}},"relations":[{"component":"AvatarGroup","relationship":"parent","note":"Use Avatar.Group for stacked avatar displays"}],"variants":[{"name":"Default","description":"Avatar with image","code":"<Avatar\n src=\"https://i.pravatar.cc/150?u=jane\"\n alt=\"Jane Doe\"\n name=\"Jane Doe\"\n />"},{"name":"With Initials","description":"Fallback when no image is provided","code":"<Avatar name=\"John Smith\" />"},{"name":"Sizes","description":"Available size options","code":"<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n <Avatar name=\"XS\" size=\"xs\" />\n <Avatar name=\"SM\" size=\"sm\" />\n <Avatar name=\"MD\" size=\"md\" />\n <Avatar name=\"LG\" size=\"lg\" />\n <Avatar name=\"XL\" size=\"xl\" />\n </div>"},{"name":"Square Shape","description":"Square variant for app icons or brands","code":"<Avatar name=\"App\" shape=\"square\" />"},{"name":"Group","description":"Multiple avatars stacked together","code":"<Avatar.Group max={3} size=\"md\">\n <Avatar name=\"Alice Johnson\" />\n <Avatar name=\"Bob Smith\" />\n <Avatar name=\"Carol Williams\" />\n <Avatar name=\"David Brown\" />\n <Avatar name=\"Eve Davis\" />\n </Avatar.Group>"}]},"Badge":{"filePath":"src/components/Badge/Badge.fragment.tsx","meta":{"name":"Badge","description":"Compact label for status, counts, or categorization. Draws attention to metadata without dominating the layout.","category":"feedback","status":"stable","tags":["status","label","tag","count","chip"],"since":"0.1.0"},"usage":{"when":["Showing item status (active, pending, archived)","Displaying counts or quantities inline","Categorizing or tagging content","Highlighting new or updated items"],"whenNot":["Conveying critical errors (use Alert instead)","Long-form status messages (use Alert)","Interactive filtering (use chip/toggle group)","Navigation labels (use tabs or links)"],"guidelines":["Keep badge text under 20 characters","Use dot variant for live status indicators","Pair success/error variants with meaningful labels, not just colors","Use onRemove for user-created tags only, not system-generated badges"],"accessibility":["Badge text must be meaningful without relying on color alone","Removable badges must have accessible dismiss button labels","Avoid using badges as the sole indicator of important state changes"]},"props":{"children":{"type":"node","description":"Badge label text","required":true},"variant":{"type":"enum","description":"Visual style indicating severity or category","default":"default","values":["default","success","warning","error","info"]},"size":{"type":"enum","description":"Badge size","default":"md","values":["sm","md"]},"dot":{"type":"boolean","description":"Show a colored dot indicator before the label","default":"false"},"icon":{"type":"node","description":"Optional icon element before the text"},"onRemove":{"type":"function","description":"Makes the badge removable. Called when X is clicked."}},"relations":[{"component":"Alert","relationship":"alternative","note":"Use Alert for prominent, longer messages with actions"},{"component":"Tag","relationship":"sibling","note":"Tag is interactive (clickable/filterable); Badge is display-only"}],"variants":[{"name":"Default","description":"Neutral badge for general labels","code":"<Badge>Default</Badge>"},{"name":"Status Variants","description":"All severity variants for different contexts","code":"<div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>\n <Badge variant=\"default\">Default</Badge>\n <Badge variant=\"success\">Active</Badge>\n <Badge variant=\"warning\">Pending</Badge>\n <Badge variant=\"error\">Failed</Badge>\n <Badge variant=\"info\">New</Badge>\n </div>"},{"name":"With Dot","description":"Live status indicators using dot prefix","code":"<div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>\n <Badge variant=\"success\" dot>Online</Badge>\n <Badge variant=\"warning\" dot>Away</Badge>\n <Badge variant=\"error\" dot>Offline</Badge>\n </div>"},{"name":"Small Size","description":"Compact badges for dense UIs","code":"<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n <Badge size=\"sm\" variant=\"info\">v2.1</Badge>\n <Badge size=\"sm\" variant=\"success\">Stable</Badge>\n <Badge size=\"md\" variant=\"info\">Standard</Badge>\n </div>"},{"name":"Removable","description":"User-created tags that can be dismissed","code":"<div style={{ display: 'flex', gap: '8px' }}>\n <Badge variant=\"info\" onRemove={() => {}}>React</Badge>\n <Badge variant=\"info\" onRemove={() => {}}>TypeScript</Badge>\n <Badge variant=\"info\" onRemove={() => {}}>CSS</Badge>\n </div>"}]},"Box":{"filePath":"src/components/Box/Box.fragment.tsx","meta":{"name":"Box","description":"Primitive layout component for applying spacing, backgrounds, and borders. A flexible container for building custom layouts.","category":"layout","status":"stable","tags":["layout","container","spacing","primitive","box"],"since":"0.1.0"},"usage":{"when":["Applying consistent padding or margin to content sections","Creating bordered or elevated containers","Wrapping content with semantic HTML elements","Building custom layouts not covered by Stack or Grid"],"whenNot":["Horizontal or vertical stacking (use Stack)","Grid-based layouts (use Grid)","Card-like containers with header/body/footer (use Card)","Simple text styling (use Text)"],"guidelines":["Use padding props instead of inline styles for consistency","Choose semantic HTML elements (section, article) where appropriate","Combine with Stack or Grid for complex layouts","Use background variants from the design system, not custom colors"],"accessibility":["Choose semantic as prop values for proper document structure","Avoid div-soup; use meaningful elements like section, article","Ensure proper heading hierarchy within Box containers"]},"props":{"children":{"type":"node","description":"Content to render inside the box"},"as":{"type":"enum","description":"HTML element to render","default":"div","values":["div","section","article","aside","main","header","footer","nav","span"]},"padding":{"type":"enum","description":"Padding on all sides","values":["none","xs","sm","md","lg","xl"]},"paddingX":{"type":"enum","description":"Horizontal padding","values":["none","xs","sm","md","lg","xl"]},"paddingY":{"type":"enum","description":"Vertical padding","values":["none","xs","sm","md","lg","xl"]},"margin":{"type":"enum","description":"Margin on all sides","values":["none","xs","sm","md","lg","xl","auto"]},"marginX":{"type":"enum","description":"Horizontal margin","values":["none","xs","sm","md","lg","xl","auto"]},"marginY":{"type":"enum","description":"Vertical margin","values":["none","xs","sm","md","lg","xl","auto"]},"background":{"type":"enum","description":"Background color","values":["none","primary","secondary","tertiary","elevated"]},"rounded":{"type":"enum","description":"Border radius","values":["none","sm","md","lg","full"]},"border":{"type":"boolean","description":"Show border","default":"false"},"display":{"type":"enum","description":"Display type","values":["block","inline","inline-block","flex","inline-flex","grid","none"]}},"relations":[{"component":"Stack","relationship":"alternative","note":"Use Stack for directional layouts with gap"},{"component":"Grid","relationship":"alternative","note":"Use Grid for column-based layouts"},{"component":"Card","relationship":"alternative","note":"Use Card for content containers with structure"}],"variants":[{"name":"Default","description":"Basic box with padding","code":"<Box padding=\"md\" background=\"secondary\" rounded=\"md\">\n Content with padding and background\n </Box>"},{"name":"With Border","description":"Bordered container","code":"<Box padding=\"lg\" border rounded=\"md\">\n Bordered content area\n </Box>"},{"name":"Directional Padding","description":"Different horizontal and vertical padding","code":"<Box paddingX=\"xl\" paddingY=\"sm\" background=\"tertiary\" rounded=\"sm\">\n Wide horizontal padding, short vertical\n </Box>"},{"name":"Centered with Auto Margin","description":"Centered content using margin auto","code":"<Box padding=\"md\" marginX=\"auto\" background=\"elevated\" rounded=\"lg\" style={{ maxWidth: '300px' }}>\n Centered content\n </Box>"}]},"Button":{"filePath":"src/components/Button/Button.fragment.tsx","meta":{"name":"Button","description":"Interactive element for user actions and form submissions","category":"actions","status":"stable","tags":["action","button","form","interactive"]},"usage":{"when":["Triggering an action (save, submit, delete, etc.)","Form submission","Opening dialogs or menus","Navigation when action context is needed"],"whenNot":["Simple navigation (use Link)","Toggling state (use Switch or Checkbox)","Selecting from options (use Select or RadioGroup)"],"guidelines":["Use Primary for the main action in a context","Only one Primary button per section/form","Use Danger variant for destructive actions","Loading state should disable the button"],"accessibility":["Button text should describe the action","Avoid generic labels like \"Click here\"","Icon-only buttons need aria-label"]},"props":{"children":{"type":"node","description":"Button label content","required":true},"variant":{"type":"enum","description":"Visual style variant","default":"primary","values":["primary","secondary","ghost","danger"],"constraints":["Only one primary button per context"]},"size":{"type":"enum","description":"Button size","default":"md","values":["sm","md","lg"]},"disabled":{"type":"boolean","description":"Whether the button is disabled","default":false},"onClick":{"type":"function","description":"Click handler"},"type":{"type":"enum","description":"HTML button type attribute","default":"button","values":["button","submit","reset"]}},"relations":[{"component":"Link","relationship":"alternative","note":"Use Link for navigation without action context"},{"component":"IconButton","relationship":"alternative","note":"Use IconButton for icon-only actions"},{"component":"ButtonGroup","relationship":"parent","note":"Use ButtonGroup for related action sets"}],"variants":[{"name":"Primary","description":"Default action button for primary actions","code":"<Button variant=\"primary\">Save Changes</Button>"},{"name":"Secondary","description":"Less prominent action button","code":"<Button variant=\"secondary\">Cancel</Button>"},{"name":"Ghost","description":"Minimal visual weight for subtle actions","code":"<Button variant=\"ghost\">Learn More</Button>"},{"name":"Danger","description":"Destructive action requiring attention","code":"<Button variant=\"danger\">Delete Item</Button>"},{"name":"Sizes","description":"Available size options","code":"<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n <Button size=\"sm\">Small</Button>\n <Button size=\"md\">Medium</Button>\n <Button size=\"lg\">Large</Button>\n </div>"},{"name":"Disabled","description":"Non-interactive state","code":"<Button disabled>Cannot Click</Button>"}]},"Card":{"filePath":"src/components/Card/Card.fragment.tsx","meta":{"name":"Card","description":"Container for grouping related content","category":"layout","status":"stable","tags":["container","layout","surface"]},"usage":{"when":["Grouping related pieces of content together","Creating visual separation between content sections","Displaying a preview or summary of an item","Building dashboard widgets or tiles"],"whenNot":["Simple text content that does not need grouping","Modal or dialog content (use Dialog component)","Navigation items (use NavItem or similar)"],"guidelines":["Use consistent card variants within the same context","Cards in a grid should have uniform sizing","Use elevated variant sparingly for emphasis","Interactive cards should have clear hover states"],"accessibility":["Interactive cards should use button or link semantics","Card titles should be appropriate heading levels"]},"props":{"children":{"type":"node","description":"Card content - use Card.Header, Card.Body, Card.Footer sub-components"},"variant":{"type":"enum","description":"Visual style of the card surface","default":"default","values":["default","outlined","elevated"],"constraints":["Use \"elevated\" sparingly to maintain visual hierarchy"]},"padding":{"type":"enum","description":"Internal padding size","default":"md","values":["none","sm","md","lg"]},"onClick":{"type":"function","description":"Click handler - makes card interactive"}},"relations":[{"component":"CardGrid","relationship":"parent","note":"Use CardGrid for responsive card layouts"},{"component":"ListItem","relationship":"alternative","note":"Use ListItem for linear list layouts"}],"variants":[{"name":"Default","description":"Standard card with subtle shadow","code":"<Card>\n <Card.Header>\n <Card.Title>Card Title</Card.Title>\n <Card.Description>A brief description</Card.Description>\n </Card.Header>\n <Card.Body>Card content goes here.</Card.Body>\n </Card>"},{"name":"Outlined","description":"Card with border instead of shadow","code":"<Card variant=\"outlined\">\n <Card.Header>\n <Card.Title>Outlined Card</Card.Title>\n </Card.Header>\n <Card.Body>Content with border.</Card.Body>\n </Card>"},{"name":"Elevated","description":"Card with prominent shadow for emphasis","code":"<Card variant=\"elevated\">\n <Card.Header>\n <Card.Title>Featured Item</Card.Title>\n </Card.Header>\n <Card.Body>Important content.</Card.Body>\n </Card>"},{"name":"Interactive","description":"Clickable card","code":"<Card onClick={() => alert('Card clicked!')}>\n <Card.Header>\n <Card.Title>Click Me</Card.Title>\n <Card.Description>This card is interactive</Card.Description>\n </Card.Header>\n <Card.Body>Click anywhere on this card.</Card.Body>\n </Card>"},{"name":"With Footer","description":"Card with header, body, and footer","code":"<Card>\n <Card.Header>\n <Card.Title>Card with Footer</Card.Title>\n <Card.Description>Complete card layout</Card.Description>\n </Card.Header>\n <Card.Body>Main content area.</Card.Body>\n <Card.Footer>Footer actions go here</Card.Footer>\n </Card>"},{"name":"Content Only","description":"Card with just body content","code":"<Card>\n <Card.Body>Just content, no header or footer.</Card.Body>\n </Card>"}],"ai":{"compositionPattern":"compound","subComponents":["Header","Title","Description","Body","Footer"],"requiredChildren":["Body"],"commonPatterns":["<Card><Card.Body>{content}</Card.Body></Card>","<Card><Card.Header><Card.Title>{title}</Card.Title></Card.Header><Card.Body>{content}</Card.Body></Card>","<Card><Card.Header><Card.Title>{title}</Card.Title><Card.Description>{desc}</Card.Description></Card.Header><Card.Body>{content}</Card.Body><Card.Footer>{actions}</Card.Footer></Card>"]}},"Checkbox":{"filePath":"src/components/Checkbox/Checkbox.fragment.tsx","meta":{"name":"Checkbox","description":"Binary toggle for form fields. Use for options that require explicit submission, unlike Toggle which takes effect immediately.","category":"forms","status":"stable","tags":["checkbox","form","boolean","selection","input"],"since":"0.1.0"},"usage":{"when":["Form fields requiring explicit submission","Multi-select from a list of options","Terms and conditions acceptance","Filter or preference checklists"],"whenNot":["Immediate effect settings (use Toggle)","Single selection from options (use RadioGroup)","Selecting from many options (use Select)"],"guidelines":["Always include a visible label","Use description for additional context when needed","Group related checkboxes visually","Use indeterminate state for parent/child relationships"],"accessibility":["Proper label association","Keyboard accessible (Space to toggle)","Visible focus indicator","Indeterminate state properly announced"]},"props":{"checked":{"type":"boolean","description":"Controlled checked state"},"defaultChecked":{"type":"boolean","description":"Default checked state (uncontrolled)"},"onCheckedChange":{"type":"function","description":"Called when checked state changes"},"indeterminate":{"type":"boolean","description":"Indeterminate state (partial selection)","default":"false"},"disabled":{"type":"boolean","description":"Disable the checkbox","default":"false"},"label":{"type":"string","description":"Label text"},"description":{"type":"string","description":"Description text below the label"},"size":{"type":"enum","description":"Checkbox size","default":"md","values":["sm","md","lg"]}},"relations":[{"component":"Toggle","relationship":"alternative","note":"Use Toggle for immediate-effect settings"},{"component":"Input","relationship":"sibling","note":"Checkbox handles boolean; Input handles text"}],"variants":[{"name":"Default","description":"Basic checkbox with label","code":"<StatefulCheckbox label=\"Accept terms and conditions\" />"},{"name":"With Description","description":"Checkbox with helper text","code":"<StatefulCheckbox\n label=\"Email notifications\"\n description=\"Receive email updates about your account activity\"\n />"},{"name":"Checked","description":"Pre-checked checkbox","code":"<StatefulCheckbox defaultChecked label=\"Subscribe to newsletter\" />"},{"name":"Indeterminate","description":"Partial selection state","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Checkbox indeterminate label=\"Select all\" />\n <div style={{ marginLeft: '24px', display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <StatefulCheckbox defaultChecked label=\"Option 1\" />\n <StatefulCheckbox label=\"Option 2\" />\n <StatefulCheckbox defaultChecked label=\"Option 3\" />\n </div>\n </div>"},{"name":"Sizes","description":"Available size options","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <StatefulCheckbox size=\"sm\" label=\"Small checkbox\" />\n <StatefulCheckbox size=\"md\" label=\"Medium checkbox\" />\n <StatefulCheckbox size=\"lg\" label=\"Large checkbox\" />\n </div>"},{"name":"Disabled","description":"Non-interactive states","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Checkbox disabled label=\"Disabled unchecked\" />\n <Checkbox disabled checked label=\"Disabled checked\" />\n </div>"}]},"CodeBlock":{"filePath":"src/components/CodeBlock/CodeBlock.fragment.tsx","meta":{"name":"CodeBlock","description":"Syntax-highlighted code display with copy functionality","category":"content","status":"stable","tags":["code","syntax","highlighting","documentation","developer"]},"usage":{"when":["Displaying code examples in documentation","Showing installation commands","Presenting configuration snippets","Teaching programming concepts"],"whenNot":["User-editable code (use code editor)","Very short inline code (use <code> element)","Non-code content (use Text or Card)"],"guidelines":["Always specify the correct language for accurate highlighting","Use filename prop to show source file name in header bar","Use title prop for external labels above the code block","Enable line numbers for longer code samples","Use highlightLines to draw attention to key lines","Keep code examples concise and focused"],"accessibility":["Code is presented in a semantic pre/code structure","Copy button has appropriate aria-label","Keyboard accessible copy functionality"]},"props":{"code":{"type":"string","description":"The code string to display","required":true},"language":{"type":"enum","description":"Programming language for syntax highlighting","default":"tsx","values":["tsx","typescript","javascript","bash","css","scss","json","html"]},"showCopy":{"type":"boolean","description":"Whether to show the copy button","default":true},"title":{"type":"string","description":"Optional title displayed above the code block (external label)"},"filename":{"type":"string","description":"Optional filename shown in header bar inside code block"},"showLineNumbers":{"type":"boolean","description":"Whether to display line numbers","default":false},"highlightLines":{"type":"array","description":"Lines to highlight (e.g., [1, 3, \"5-7\"])"},"className":{"type":"string","description":"Additional CSS class name"}},"relations":[{"component":"Card","relationship":"parent","note":"Can be wrapped in Card for additional context"},{"component":"Tabs","relationship":"child","note":"Use in Tabs for showing code in multiple languages"}],"variants":[{"name":"Default","description":"Basic code block with syntax highlighting","code":"<CodeBlock code={`import { Button } from '@fragments-sdk/ui';\n\nfunction App() {\n return <Button>Click me</Button>;\n}`} language=\"tsx\" />"},{"name":"With Filename","description":"Code block with filename in header bar","code":"<CodeBlock filename=\"app.tsx\" code={`import { Button, Card } from '@fragments-sdk/ui';\n\nfunction App() {\n return (\n <Card>\n <Card.Header>Welcome</Card.Header>\n <Card.Content>\n <Button>Get Started</Button>\n </Card.Content>\n </Card>\n );\n}`} language=\"tsx\" />"},{"name":"With Title","description":"Code block with external title label","code":"<CodeBlock title=\"Installation\" code=\"npm install @fragments-sdk/ui\" language=\"bash\" />"},{"name":"With Line Numbers","description":"Shows line numbers for reference","code":"<CodeBlock code={`const greeting = \"Hello\";\nconst name = \"World\";\nconsole.log(\\`\\${greeting}, \\${name}!\\`);`} language=\"typescript\" showLineNumbers />"},{"name":"With Highlighted Lines","description":"Emphasizes specific lines of code","code":"<CodeBlock code={`import { useState } from 'react';\n\nfunction Counter() {\n const [count, setCount] = useState(0);\n\n return (\n <button onClick={() => setCount(c => c + 1)}>\n Count: {count}\n </button>\n );\n}`} language=\"tsx\" showLineNumbers highlightLines={[4, '7-9']} />"},{"name":"JSON","description":"Configuration file example","code":"<CodeBlock title=\"package.json\" code={`{\n \"name\": \"my-app\",\n \"dependencies\": {\n \"@fragments-sdk/ui\": \"^0.3.0\"\n }\n}`} language=\"json\" />"},{"name":"Without Copy Button","description":"Minimal display without copy functionality","code":"<CodeBlock code=\"const simple = true;\" language=\"typescript\" showCopy={false} />"}]},"Dialog":{"filePath":"src/components/Dialog/Dialog.fragment.tsx","meta":{"name":"Dialog","description":"Modal overlay for focused user interactions. Use for confirmations, forms, or content requiring full attention.","category":"overlays","status":"stable","tags":["modal","dialog","overlay","popup","confirmation"],"since":"0.1.0"},"usage":{"when":["Confirming destructive actions (delete, discard changes)","Collecting focused input (forms, settings)","Displaying content that requires acknowledgment","Multi-step workflows that need isolation"],"whenNot":["Simple tooltips or hints (use Tooltip)","Contextual menus (use Menu or Popover)","Non-blocking notifications (use Toast or Alert)","Simple confirmation that can be inline (use Alert)"],"guidelines":["Keep dialog content focused on a single task","Provide clear primary and secondary actions","Use descriptive title that explains the purpose","Allow dismissal via backdrop click or close button for non-critical dialogs","Trap focus within the dialog for accessibility"],"accessibility":["Automatically traps focus within the dialog","Closes on Escape key press","Returns focus to trigger element on close","Uses role=\"dialog\" with proper aria attributes"]},"props":{"children":{"type":"node","description":"Dialog content (use Dialog.Content, Dialog.Header, etc.)","required":true},"open":{"type":"boolean","description":"Controlled open state"},"defaultOpen":{"type":"boolean","description":"Default open state (uncontrolled)","default":"false"},"onOpenChange":{"type":"function","description":"Called when open state changes"},"modal":{"type":"boolean","description":"Whether to render as modal (blocks interaction with rest of page)","default":"true"}},"relations":[{"component":"Popover","relationship":"alternative","note":"Use Popover for non-modal contextual content"},{"component":"Menu","relationship":"alternative","note":"Use Menu for action lists"},{"component":"Alert","relationship":"sibling","note":"Use Alert for inline notifications"}],"variants":[{"name":"Default","description":"Basic dialog with header, body, and footer","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button>Open Dialog</Button>\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Close />\n <Dialog.Header>\n <Dialog.Title>Dialog Title</Dialog.Title>\n <Dialog.Description>\n A brief description of what this dialog is for.\n </Dialog.Description>\n </Dialog.Header>\n <Dialog.Body>\n <p>Dialog content goes here. You can include forms, text, or any other content.</p>\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"secondary\">Cancel</Button>\n </Dialog.Close>\n <Button variant=\"primary\">Confirm</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>"},{"name":"Confirmation","description":"Destructive action confirmation","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button variant=\"danger\">Delete Item</Button>\n </Dialog.Trigger>\n <Dialog.Content size=\"sm\">\n <Dialog.Header>\n <Dialog.Title>Delete item?</Dialog.Title>\n <Dialog.Description>\n This action cannot be undone. The item will be permanently removed.\n </Dialog.Description>\n </Dialog.Header>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"secondary\">Cancel</Button>\n </Dialog.Close>\n <Button variant=\"danger\">Delete</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>"},{"name":"Large","description":"Large dialog for complex content","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button>Open Large Dialog</Button>\n </Dialog.Trigger>\n <Dialog.Content size=\"lg\">\n <Dialog.Close />\n <Dialog.Header>\n <Dialog.Title>Settings</Dialog.Title>\n <Dialog.Description>\n Configure your application preferences.\n </Dialog.Description>\n </Dialog.Header>\n <Dialog.Body>\n <p>This dialog has more space for complex forms or content layouts.</p>\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"secondary\">Cancel</Button>\n </Dialog.Close>\n <Button variant=\"primary\">Save Changes</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>"}],"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Close","Header","Title","Description","Body","Footer"],"requiredChildren":["Content"],"commonPatterns":["<Dialog><Dialog.Trigger><Button>Open</Button></Dialog.Trigger><Dialog.Content><Dialog.Header><Dialog.Title>{title}</Dialog.Title></Dialog.Header><Dialog.Body>{content}</Dialog.Body><Dialog.Footer><Dialog.Close><Button variant=\"secondary\">Cancel</Button></Dialog.Close><Button>Confirm</Button></Dialog.Footer></Dialog.Content></Dialog>"]}},"EmptyState":{"filePath":"src/components/EmptyState/EmptyState.fragment.tsx","meta":{"name":"EmptyState","description":"Placeholder for empty content areas. Provides context, guidance, and actions when no data is available.","category":"feedback","status":"stable","tags":["empty","placeholder","no-data","zero-state","blank-slate"],"since":"0.1.0"},"usage":{"when":["Empty lists, tables, or search results","New user onboarding (no content yet)","Filtered views with no matches","Error states where content failed to load"],"whenNot":["Loading states (use skeleton or spinner)","Error messages with retry (use Alert)","Temporary messages (use Toast)"],"guidelines":["Always explain why the area is empty","Provide a clear action to resolve the empty state","Use appropriate icons to reinforce the message","Keep messaging positive and actionable"],"accessibility":["Empty state content is accessible to screen readers","Action buttons follow button accessibility guidelines"]},"props":{"children":{"type":"node","description":"EmptyState content - use EmptyState.Icon, EmptyState.Title, EmptyState.Description, EmptyState.Actions sub-components"},"size":{"type":"enum","description":"Size variant","default":"md","values":["sm","md","lg"]}},"relations":[{"component":"Alert","relationship":"alternative","note":"Use Alert for error states with retry"},{"component":"Progress","relationship":"alternative","note":"Use Progress/Spinner for loading states"}],"variants":[{"name":"Default","description":"Basic empty state with action","code":"<EmptyState>\n <EmptyState.Icon><FolderIcon /></EmptyState.Icon>\n <EmptyState.Title>No projects yet</EmptyState.Title>\n <EmptyState.Description>Get started by creating your first project.</EmptyState.Description>\n <EmptyState.Actions>\n <Button>Create Project</Button>\n </EmptyState.Actions>\n </EmptyState>"},{"name":"No Results","description":"Empty search results","code":"<EmptyState>\n <EmptyState.Icon><SearchIcon /></EmptyState.Icon>\n <EmptyState.Title>No results found</EmptyState.Title>\n <EmptyState.Description>Try adjusting your search terms or filters.</EmptyState.Description>\n <EmptyState.Actions>\n <Button variant=\"secondary\">Clear Filters</Button>\n </EmptyState.Actions>\n </EmptyState>"},{"name":"With Secondary Action","description":"Empty state with two actions","code":"<EmptyState>\n <EmptyState.Icon><InboxIcon /></EmptyState.Icon>\n <EmptyState.Title>Inbox is empty</EmptyState.Title>\n <EmptyState.Description>You have no new messages.</EmptyState.Description>\n <EmptyState.Actions>\n <Button>Compose Message</Button>\n <Button variant=\"secondary\">View Archive</Button>\n </EmptyState.Actions>\n </EmptyState>"},{"name":"Small","description":"Compact empty state for inline use","code":"<EmptyState size=\"sm\">\n <EmptyState.Title>No items</EmptyState.Title>\n <EmptyState.Description>Add items to see them here.</EmptyState.Description>\n </EmptyState>"},{"name":"Large","description":"Prominent empty state for full-page use","code":"<EmptyState size=\"lg\">\n <EmptyState.Icon><FolderIcon /></EmptyState.Icon>\n <EmptyState.Title>Welcome to your workspace</EmptyState.Title>\n <EmptyState.Description>\n This is where your projects will appear. Create your first project to get started.\n </EmptyState.Description>\n <EmptyState.Actions>\n <Button>Create Your First Project</Button>\n </EmptyState.Actions>\n </EmptyState>"}],"ai":{"compositionPattern":"compound","subComponents":["Icon","Title","Description","Actions"],"requiredChildren":["Title"],"commonPatterns":["<EmptyState><EmptyState.Title>{title}</EmptyState.Title><EmptyState.Description>{description}</EmptyState.Description></EmptyState>","<EmptyState><EmptyState.Icon>{icon}</EmptyState.Icon><EmptyState.Title>{title}</EmptyState.Title><EmptyState.Description>{description}</EmptyState.Description><EmptyState.Actions><Button>{action}</Button></EmptyState.Actions></EmptyState>"]}},"Field":{"filePath":"src/components/Field/Field.fragment.tsx","meta":{"name":"Field","description":"Compositional form field wrapper providing validation, labels, descriptions, and error messages. Use for advanced form needs beyond baked-in Input/Textarea props.","category":"forms","status":"stable","tags":["form","field","validation","label","error","input","accessible"],"since":"0.4.0"},"usage":{"when":["You need granular validation with match-based error messages","Custom form controls need accessible labels and descriptions","Server-side errors need to be distributed to specific fields","You need dirty/touched tracking or custom validation logic"],"whenNot":["Simple inputs with basic label and helper text (use Input with label prop)","Standalone selects or textareas with built-in error display"],"guidelines":["Always provide a Field.Label for accessibility","Wrap any form control in Field.Control to connect it to the field context","Use match prop on Field.Error for granular native validation messages","Wrap in Form to enable server-side error distribution by field name"],"accessibility":["Label automatically linked to control via aria-labelledby","Description linked via aria-describedby","Error messages announced to screen readers","Supports data-disabled and data-invalid attributes for styling"]},"props":{"name":{"type":"string","description":"Field name, used for error distribution from Form"},"disabled":{"type":"boolean","description":"Disables the field and its control"},"invalid":{"type":"boolean","description":"Marks the field as invalid"},"validate":{"type":"function","description":"Custom validation function returning error string(s) or null"},"validationMode":{"type":"enum","description":"When to trigger validation","values":["onSubmit","onBlur","onChange"]},"validationDebounceTime":{"type":"number","description":"Debounce time in ms for onChange validation"},"className":{"type":"string","description":"Additional CSS class"}},"relations":[{"component":"Input","relationship":"alternative","note":"Use Input for simple fields with built-in label/error"},{"component":"Form","relationship":"parent","note":"Wrap in Form for server-side error distribution"},{"component":"Fieldset","relationship":"sibling","note":"Use Fieldset to group related fields"}],"variants":[{"name":"Single field","description":"A single field with label, control, and description","code":"<Field name=\"email\">\n <Field.Label>Email address</Field.Label>\n <Field.Control>\n <Input type=\"email\" placeholder=\"jane@example.com\" />\n </Field.Control>\n <Field.Description>We will never share your email.</Field.Description>\n </Field>"},{"name":"Two-column layout","description":"Fields arranged in a two-column grid","code":"<Grid columns={2} gap=\"md\">\n <Field name=\"firstName\">\n <Field.Label>First Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Jane\" />\n </Field.Control>\n </Field>\n <Field name=\"lastName\">\n <Field.Label>Last Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Doe\" />\n </Field.Control>\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field name=\"email\">\n <Field.Label>Email</Field.Label>\n <Field.Control>\n <Input type=\"email\" placeholder=\"jane@example.com\" />\n </Field.Control>\n <Field.Error match=\"typeMismatch\">Enter a valid email address</Field.Error>\n </Field>\n </Grid.Item>\n </Grid>"},{"name":"Custom validation","description":"Field with custom validate function","code":"<Field\n name=\"age\"\n validate={(value) => {\n const num = Number(value);\n if (isNaN(num) || num < 18) return 'Must be 18 or older';\n return null;\n }}\n validationMode=\"onChange\"\n validationDebounceTime={500}\n >\n <Field.Label>Age</Field.Label>\n <Field.Control>\n <Input type=\"number\" placeholder=\"18\" />\n </Field.Control>\n <Field.Description>You must be at least 18 years old.</Field.Description>\n <Field.Error match=\"customError\" />\n </Field>"}]},"Fieldset":{"filePath":"src/components/Fieldset/Fieldset.fragment.tsx","meta":{"name":"Fieldset","description":"Groups related form fields with an accessible legend. Use to organize forms into logical sections.","category":"forms","status":"stable","tags":["form","fieldset","group","legend","accessible"],"since":"0.4.0"},"usage":{"when":["Grouping related fields in a form (e.g., address, personal info)","Disabling a group of fields together","Providing an accessible group label for screen readers"],"whenNot":["Generic visual grouping (use Card)","Single field wrapping (use Field)"],"guidelines":["Always include a Fieldset.Legend for accessibility","Use disabled prop to disable all fields within the group","Use Grid inside Fieldset for multi-column layouts"],"accessibility":["Renders semantic fieldset element","Legend provides accessible group label","Disabled state propagates to all child fields"]},"props":{"disabled":{"type":"boolean","description":"Disables all fields within the fieldset"},"className":{"type":"string","description":"Additional CSS class"}},"relations":[{"component":"Field","relationship":"sibling","note":"Contains Field components"},{"component":"Form","relationship":"parent","note":"Used within a Form"},{"component":"Card","relationship":"alternative","note":"Use Card for non-form visual grouping"}],"variants":[{"name":"Two-column layout","description":"Fieldset with Grid for side-by-side fields","code":"<Fieldset>\n <Fieldset.Legend>Personal Information</Fieldset.Legend>\n <Grid columns={2} gap=\"md\">\n <Field name=\"firstName\">\n <Field.Label>First Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Jane\" />\n </Field.Control>\n </Field>\n <Field name=\"lastName\">\n <Field.Label>Last Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Doe\" />\n </Field.Control>\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field name=\"email\">\n <Field.Label>Email</Field.Label>\n <Field.Control>\n <Input type=\"email\" placeholder=\"jane@example.com\" />\n </Field.Control>\n </Field>\n </Grid.Item>\n </Grid>\n </Fieldset>"},{"name":"Mixed controls","description":"Fieldset with textarea, select, and checkbox","code":"<Fieldset>\n <Fieldset.Legend>Preferences</Fieldset.Legend>\n <Field name=\"bio\">\n <Field.Label>Bio</Field.Label>\n <Field.Control>\n <Textarea placeholder=\"Tell us about yourself\" rows={3} />\n </Field.Control>\n <Field.Description>Brief description for your profile.</Field.Description>\n </Field>\n <Field name=\"role\">\n <Field.Label>Role</Field.Label>\n <Field.Control>\n <Select placeholder=\"Select a role\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"admin\">Admin</Select.Item>\n <Select.Item value=\"editor\">Editor</Select.Item>\n <Select.Item value=\"viewer\">Viewer</Select.Item>\n </Select.Content>\n </Select>\n </Field.Control>\n </Field>\n <Field name=\"newsletter\">\n <Field.Control>\n <Checkbox label=\"Subscribe to newsletter\" />\n </Field.Control>\n </Field>\n </Fieldset>"},{"name":"Disabled","description":"Disabled fieldset prevents interaction with all children","code":"<Fieldset disabled>\n <Fieldset.Legend>Locked Section</Fieldset.Legend>\n <Grid columns={2} gap=\"md\">\n <Field name=\"lockedFirst\">\n <Field.Label>First Name</Field.Label>\n <Field.Control>\n <Input defaultValue=\"Jane\" />\n </Field.Control>\n </Field>\n <Field name=\"lockedLast\">\n <Field.Label>Last Name</Field.Label>\n <Field.Control>\n <Input defaultValue=\"Doe\" />\n </Field.Control>\n </Field>\n </Grid>\n <Field name=\"lockedCheck\">\n <Field.Control>\n <Checkbox label=\"Cannot toggle\" defaultChecked />\n </Field.Control>\n </Field>\n </Fieldset>"}]},"Form":{"filePath":"src/components/Form/Form.fragment.tsx","meta":{"name":"Form","description":"Form wrapper that handles server-side error distribution to Field components. Pairs with Field for complete form validation.","category":"forms","status":"stable","tags":["form","validation","errors","submit","server"],"since":"0.4.0"},"usage":{"when":["Building forms that need server-side error handling","Distributing validation errors to specific fields by name","Combining client and server validation in one form"],"whenNot":["Simple forms with only client-side validation (use native form or Field alone)","Non-form layouts (use Grid or Card)"],"guidelines":["Pass errors as Record<string, string | string[]> keyed by field name","Use onClearErrors to clear errors when fields are modified","Use onFormSubmit for form submission handling","Field components with matching name prop display errors automatically","Use Grid inside Form or Fieldset for multi-column layouts"],"accessibility":["Renders semantic form element","Error messages linked to fields via aria-describedby"]},"props":{"errors":{"type":"object","description":"Server-side errors keyed by field name"},"onFormSubmit":{"type":"function","description":"Form submission handler"},"onClearErrors":{"type":"function","description":"Called with field name when errors should be cleared"},"className":{"type":"string","description":"Additional CSS class"}},"relations":[{"component":"Field","relationship":"sibling","note":"Contains Field components for error distribution"},{"component":"Fieldset","relationship":"sibling","note":"Use Fieldset to group fields within a Form"},{"component":"Button","relationship":"sibling","note":"Use Button type=\"submit\" for form submission"}],"variants":[{"name":"Sign up","description":"Registration form with two-column name fields","code":"<Form onFormSubmit={(e) => { e.preventDefault(); }}>\n <Grid columns={2} gap=\"md\">\n <Field name=\"firstName\">\n <Field.Label>First Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Jane\" />\n </Field.Control>\n </Field>\n <Field name=\"lastName\">\n <Field.Label>Last Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Doe\" />\n </Field.Control>\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field name=\"email\">\n <Field.Label>Email</Field.Label>\n <Field.Control>\n <Input type=\"email\" placeholder=\"jane@example.com\" />\n </Field.Control>\n <Field.Error match=\"typeMismatch\">Enter a valid email address</Field.Error>\n </Field>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Field name=\"password\">\n <Field.Label>Password</Field.Label>\n <Field.Control>\n <Input type=\"password\" placeholder=\"At least 8 characters\" />\n </Field.Control>\n <Field.Description>Must be at least 8 characters</Field.Description>\n </Field>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Field name=\"terms\">\n <Field.Control>\n <Checkbox label=\"I agree to the terms and conditions\" />\n </Field.Control>\n </Field>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Button type=\"submit\" variant=\"primary\">Create Account</Button>\n </Grid.Item>\n </Grid>\n </Form>"},{"name":"Profile settings","description":"Multi-section form with Fieldsets, toggles, and radio group","code":"<Form onFormSubmit={(e) => { e.preventDefault(); }}>\n <Fieldset>\n <Fieldset.Legend>Profile</Fieldset.Legend>\n <Grid columns={2} gap=\"md\">\n <Field name=\"displayName\">\n <Field.Label>Display Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"How others see you\" />\n </Field.Control>\n </Field>\n <Field name=\"timezone\">\n <Field.Label>Timezone</Field.Label>\n <Field.Control>\n <Select placeholder=\"Select timezone\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"utc\">UTC</Select.Item>\n <Select.Item value=\"est\">Eastern (EST)</Select.Item>\n <Select.Item value=\"pst\">Pacific (PST)</Select.Item>\n <Select.Item value=\"gmt\">GMT</Select.Item>\n </Select.Content>\n </Select>\n </Field.Control>\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field name=\"bio\">\n <Field.Label>Bio</Field.Label>\n <Field.Control>\n <Textarea placeholder=\"Tell us about yourself\" rows={3} maxLength={280} />\n </Field.Control>\n <Field.Description>Max 280 characters</Field.Description>\n </Field>\n </Grid.Item>\n </Grid>\n </Fieldset>\n <Fieldset>\n <Fieldset.Legend>Notifications</Fieldset.Legend>\n <Field name=\"emailNotifs\">\n <Field.Control>\n <Toggle label=\"Email notifications\" />\n </Field.Control>\n </Field>\n <Field name=\"marketingEmails\">\n <Field.Control>\n <Toggle label=\"Marketing emails\" />\n </Field.Control>\n </Field>\n <Field name=\"frequency\">\n <Field.Label>Digest frequency</Field.Label>\n <Field.Control>\n <RadioGroup name=\"frequency\" orientation=\"vertical\">\n <RadioGroup.Item value=\"daily\" label=\"Daily\" />\n <RadioGroup.Item value=\"weekly\" label=\"Weekly\" />\n <RadioGroup.Item value=\"monthly\" label=\"Monthly\" />\n </RadioGroup>\n </Field.Control>\n </Field>\n </Fieldset>\n <Button type=\"submit\" variant=\"primary\">Save Changes</Button>\n </Form>"},{"name":"Contact form","description":"Contact form with select, textarea, and checkbox","code":"<Form onFormSubmit={(e) => { e.preventDefault(); }}>\n <Grid columns={2} gap=\"md\">\n <Field name=\"name\">\n <Field.Label>Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Your name\" />\n </Field.Control>\n </Field>\n <Field name=\"email\">\n <Field.Label>Email</Field.Label>\n <Field.Control>\n <Input type=\"email\" placeholder=\"you@example.com\" />\n </Field.Control>\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field name=\"subject\">\n <Field.Label>Subject</Field.Label>\n <Field.Control>\n <Select placeholder=\"What is this about?\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"general\">General Inquiry</Select.Item>\n <Select.Item value=\"support\">Technical Support</Select.Item>\n <Select.Item value=\"billing\">Billing</Select.Item>\n <Select.Item value=\"feedback\">Feedback</Select.Item>\n </Select.Content>\n </Select>\n </Field.Control>\n </Field>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Field name=\"message\">\n <Field.Label>Message</Field.Label>\n <Field.Control>\n <Textarea placeholder=\"How can we help?\" rows={5} />\n </Field.Control>\n </Field>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Field name=\"copy\">\n <Field.Control>\n <Checkbox label=\"Send me a copy\" />\n </Field.Control>\n </Field>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Button type=\"submit\" variant=\"primary\">Send Message</Button>\n </Grid.Item>\n </Grid>\n </Form>"},{"name":"With server errors","description":"Form displaying server-side validation errors","code":"<Form errors={{ username: 'Username is already taken', email: 'Email is already registered' }}>\n <Grid columns={2} gap=\"md\">\n <Field name=\"username\">\n <Field.Label>Username</Field.Label>\n <Field.Control>\n <Input defaultValue=\"janedoe\" />\n </Field.Control>\n <Field.Error match=\"customError\" />\n </Field>\n <Field name=\"email\">\n <Field.Label>Email</Field.Label>\n <Field.Control>\n <Input type=\"email\" defaultValue=\"jane@example.com\" />\n </Field.Control>\n <Field.Error match=\"customError\" />\n </Field>\n <Grid.Item colSpan=\"full\">\n <Button type=\"submit\" variant=\"primary\">Submit</Button>\n </Grid.Item>\n </Grid>\n </Form>"}]},"Grid":{"filePath":"src/components/Grid/Grid.fragment.tsx","meta":{"name":"Grid","description":"Responsive grid layout for arranging items in columns with consistent spacing","category":"layout","status":"stable","tags":["grid","layout","columns","responsive"]},"usage":{"when":["Arranging cards, tiles, or media in a responsive grid","Building form layouts with multi-column fields","Creating dashboard layouts with widgets","Any content that should reflow across breakpoints"],"whenNot":["Single-column stacked content (use a simple flex column or Stack)","Navigation bars or toolbars (use a dedicated nav component)","Content that must not wrap (use inline layout)"],"guidelines":["Use columns=\"auto\" with minChildWidth for grids that adapt without breakpoints","Use responsive object { base: 1, md: 2, lg: 3 } when you need explicit control per breakpoint","Use fixed column counts when exact column control is needed and responsiveness is not required","Use Grid.Item with colSpan to create asymmetric layouts within a fixed grid","Keep gap consistent within a context — md is the default and works for most cases"],"accessibility":["Grid is purely visual — it does not affect reading order or semantics","Ensure logical source order matches visual order for screen readers"]},"props":{"columns":{"type":"union","description":"Number of columns: a number (1-12), a responsive object { base, sm, md, lg, xl }, or \"auto\" for auto-fill","default":1,"constraints":["Use \"auto\" with minChildWidth for fully fluid layouts","Use responsive object for explicit breakpoint control: { base: 1, md: 2, lg: 3 }"]},"minChildWidth":{"type":"string","description":"Minimum width for auto-fill columns (e.g., \"16rem\", \"250px\")","constraints":["Only applies when columns=\"auto\""]},"gap":{"type":"enum","description":"Gap between grid items, mapped to spacing tokens","default":"md","values":["none","xs","sm","md","lg","xl"]},"alignItems":{"type":"enum","description":"Vertical alignment of items within their cells","values":["start","center","end","stretch"]},"justifyItems":{"type":"enum","description":"Horizontal alignment of items within their cells","values":["start","center","end","stretch"]},"padding":{"type":"enum","description":"Internal padding of the grid container","default":"none","values":["none","sm","md","lg"]}},"relations":[{"component":"Card","relationship":"child","note":"Grid commonly contains Card components for dashboard and tile layouts"},{"component":"Separator","relationship":"sibling","note":"Use Separator between grid sections"}],"variants":[{"name":"Default","description":"Basic 3-column grid","code":"<Grid columns={3} gap=\"md\">\n <div style={{ padding: 'var(--fui-space-2)', background: 'var(--fui-bg-secondary)' }}>Item 1</div>\n <div style={{ padding: 'var(--fui-space-2)', background: 'var(--fui-bg-secondary)' }}>Item 2</div>\n <div style={{ padding: 'var(--fui-space-2)', background: 'var(--fui-bg-secondary)' }}>Item 3</div>\n </Grid>"},{"name":"Responsive","description":"1 column on mobile, 2 on tablet, 3 on desktop","code":"<Grid columns={{ base: 1, md: 2, lg: 3 }} gap=\"md\">\n <div style={{ padding: 'var(--fui-space-2)', background: 'var(--fui-bg-secondary)' }}>Card 1</div>\n <div style={{ padding: 'var(--fui-space-2)', background: 'var(--fui-bg-secondary)' }}>Card 2</div>\n <div style={{ padding: 'var(--fui-space-2)', background: 'var(--fui-bg-secondary)' }}>Card 3</div>\n </Grid>"},{"name":"Auto-fill","description":"Responsive grid that auto-fills based on minimum child width","code":"<Grid columns=\"auto\" minChildWidth=\"12rem\" gap=\"md\">\n <div style={{ padding: 'var(--fui-space-2)', background: 'var(--fui-bg-secondary)' }}>Card 1</div>\n <div style={{ padding: 'var(--fui-space-2)', background: 'var(--fui-bg-secondary)' }}>Card 2</div>\n <div style={{ padding: 'var(--fui-space-2)', background: 'var(--fui-bg-secondary)' }}>Card 3</div>\n <div style={{ padding: 'var(--fui-space-2)', background: 'var(--fui-bg-secondary)' }}>Card 4</div>\n </Grid>"},{"name":"With Spanning","description":"Grid items spanning multiple columns","code":"<Grid columns={4} gap=\"md\">\n <Grid.Item colSpan={2}>\n <div style={{ padding: 'var(--fui-space-2)', background: 'var(--fui-bg-secondary)' }}>Spans 2 cols</div>\n </Grid.Item>\n <div style={{ padding: 'var(--fui-space-2)', background: 'var(--fui-bg-secondary)' }}>1 col</div>\n <div style={{ padding: 'var(--fui-space-2)', background: 'var(--fui-bg-secondary)' }}>1 col</div>\n <Grid.Item colSpan=\"full\">\n <div style={{ padding: 'var(--fui-space-2)', background: 'var(--fui-bg-secondary)' }}>Full width</div>\n </Grid.Item>\n </Grid>"},{"name":"Form Layout","description":"Two-column form that collapses to single column on mobile","code":"<Grid columns={{ base: 1, md: 2 }} gap=\"md\">\n <div style={{ padding: 'var(--fui-space-1)', background: 'var(--fui-bg-secondary)' }}>First Name</div>\n <div style={{ padding: 'var(--fui-space-1)', background: 'var(--fui-bg-secondary)' }}>Last Name</div>\n <Grid.Item colSpan=\"full\">\n <div style={{ padding: 'var(--fui-space-1)', background: 'var(--fui-bg-secondary)' }}>Email Address</div>\n </Grid.Item>\n </Grid>"}]},"Header":{"filePath":"src/components/Header/Header.fragment.tsx","meta":{"name":"Header","description":"Composable header with slots for brand, navigation, search, and actions. Designed for use within AppShell with responsive mobile support.","category":"navigation","status":"stable","tags":["header","navigation","navbar","brand","layout"],"since":"0.5.0"},"usage":{"when":["Primary site or app header inside AppShell","Navigation bar with branding (stacked layout)","Search and actions bar (sidebar-inset layout)","Header with responsive mobile menu trigger"],"whenNot":["Simple page titles (use heading elements)","Footer navigation (use Footer component)","Standalone sidebar navigation (use Sidebar directly)"],"guidelines":["Use Header.SkipLink for accessibility (skip to main content)","In stacked layout: include Header.Brand for logo","In sidebar-inset layout: omit Header.Brand (logo in sidebar)","Header.Trigger integrates with SidebarProvider for mobile menus","Header.Nav is hidden on mobile; use sidebar for mobile navigation","Use Header.Spacer to push items apart"],"accessibility":["Include Header.SkipLink for keyboard users","Navigation has aria-label for screen readers","Active nav items use aria-current=\"page\"","Mobile trigger has aria-expanded state"]},"props":{"children":{"type":"node","description":"Header content (use Header.Brand, Header.Nav, etc.)","required":true},"height":{"type":"string","description":"Header height","default":"56px"},"position":{"type":"enum","description":"Position behavior (usually controlled by AppShell)","default":"static","values":["static","fixed","sticky"]}},"relations":[{"component":"AppShell","relationship":"parent","note":"Header is typically used inside AppShell.Header"},{"component":"Sidebar","relationship":"sibling","note":"Header.Trigger toggles Sidebar on mobile"},{"component":"ThemeToggle","relationship":"child","note":"ThemeToggle is commonly placed in Header.Actions"}],"variants":[{"name":"For Stacked Layout","description":"Header with brand, nav, and actions. Use with AppShell layout=\"stacked\".","code":"<ThemeProvider defaultMode=\"light\">\n <Header>\n <Header.SkipLink />\n <Header.Trigger />\n <Header.Brand href=\"/\">MyApp</Header.Brand>\n <Header.Nav>\n <Header.NavItem href=\"/dashboard\" active>Dashboard</Header.NavItem>\n <Header.NavItem href=\"/projects\">Projects</Header.NavItem>\n <Header.NavItem href=\"/settings\">Settings</Header.NavItem>\n </Header.Nav>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n <Button variant=\"secondary\" size=\"sm\">Sign In</Button>\n </Header.Actions>\n </Header>\n </ThemeProvider>"},{"name":"For Sidebar Inset Layout","description":"Header without brand (logo is in sidebar). Use with AppShell layout=\"sidebar-inset\".","code":"<ThemeProvider defaultMode=\"light\">\n <Header>\n <Header.SkipLink />\n <Header.Trigger />\n <Header.Search>\n <Input placeholder=\"Search...\" style={{ width: '240px' }} />\n </Header.Search>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n </Header.Actions>\n </Header>\n </ThemeProvider>"},{"name":"Minimal","description":"Clean header with just trigger and actions","code":"<ThemeProvider defaultMode=\"light\">\n <Header>\n <Header.Trigger />\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n </Header.Actions>\n </Header>\n </ThemeProvider>"},{"name":"With Search","description":"Header featuring a prominent search input","code":"<ThemeProvider defaultMode=\"light\">\n <Header>\n <Header.Brand>Docs</Header.Brand>\n <Header.Search>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '8px 12px',\n background: 'var(--fui-bg-secondary)',\n borderRadius: '6px',\n color: 'var(--fui-text-tertiary)',\n fontSize: '14px',\n width: '280px'\n }}>\n <SearchIcon /> Search documentation...\n </div>\n </Header.Search>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n </Header.Actions>\n </Header>\n </ThemeProvider>"},{"name":"With Skip Link","description":"Accessible header with skip link for keyboard navigation","code":"<Header>\n <Header.SkipLink href=\"#main-content\">Skip to content</Header.SkipLink>\n <Header.Brand>Accessible App</Header.Brand>\n <Header.Nav>\n <Header.NavItem href=\"/\" active>Home</Header.NavItem>\n <Header.NavItem href=\"/about\">About</Header.NavItem>\n </Header.Nav>\n </Header>"}],"ai":{"compositionPattern":"compound","subComponents":["SkipLink","Trigger","Brand","Nav","NavItem","Search","Spacer","Actions"],"commonPatterns":["<Header><Header.Brand href=\"/\">{appName}</Header.Brand><Header.Nav><Header.NavItem href=\"/home\" active>Home</Header.NavItem></Header.Nav><Header.Spacer /><Header.Actions>{actions}</Header.Actions></Header>"]}},"Icon":{"filePath":"src/components/Icon/Icon.fragment.tsx","meta":{"name":"Icon","description":"Wrapper for Phosphor icons with consistent sizing and semantic colors. Provides standardized icon rendering across the design system.","category":"data-display","status":"stable","tags":["icon","phosphor","visual","symbol","graphic"],"since":"0.1.0"},"usage":{"when":["Displaying UI icons alongside text or in buttons","Indicating status or state visually","Adding visual hierarchy to feature lists","Decorating cards or stats with relevant symbols"],"whenNot":["Large decorative illustrations (use Image or custom SVG)","Logo display (use dedicated Logo component)","Complex graphics with multiple colors","Animated icons (use custom implementation)"],"guidelines":["Use semantic color variants (success, error, warning) for status indication","Pair icons with text labels for accessibility","Match icon weight to surrounding text weight for visual consistency","Use consistent sizes within the same context"],"accessibility":["Icons are decorative by default (aria-hidden)","Always pair with visible or visually-hidden text for meaning","Do not rely on color alone to convey information","Consider using VisuallyHidden for icon-only buttons"]},"props":{"icon":{"type":"component","description":"Phosphor icon component to render","required":true},"size":{"type":"enum","description":"Icon size","default":"md","values":["xs","sm","md","lg","xl"]},"weight":{"type":"enum","description":"Icon stroke weight/style","default":"regular","values":["thin","light","regular","bold","fill","duotone"]},"variant":{"type":"enum","description":"Semantic color variant","default":"default","values":["default","primary","secondary","tertiary","accent","success","warning","error"]}},"relations":[{"component":"Button","relationship":"child","note":"Use inside icon-only buttons with VisuallyHidden label"},{"component":"VisuallyHidden","relationship":"sibling","note":"Pair with VisuallyHidden for accessible icon-only elements"},{"component":"Badge","relationship":"child","note":"Can be used as badge icon prop"}],"variants":[{"name":"Default","description":"Basic icon with default styling","code":"<Icon icon={Heart} />"},{"name":"Sizes","description":"Available size options","code":"<div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>\n <Icon icon={Star} size=\"xs\" />\n <Icon icon={Star} size=\"sm\" />\n <Icon icon={Star} size=\"md\" />\n <Icon icon={Star} size=\"lg\" />\n <Icon icon={Star} size=\"xl\" />\n </div>"},{"name":"Semantic Colors","description":"Status and semantic color variants","code":"<div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>\n <Icon icon={Check} variant=\"success\" />\n <Icon icon={Warning} variant=\"warning\" />\n <Icon icon={Warning} variant=\"error\" />\n <Icon icon={Info} variant=\"accent\" />\n </div>"},{"name":"Weights","description":"Icon weight/style options","code":"<div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>\n <Icon icon={Heart} weight=\"thin\" />\n <Icon icon={Heart} weight=\"light\" />\n <Icon icon={Heart} weight=\"regular\" />\n <Icon icon={Heart} weight=\"bold\" />\n <Icon icon={Heart} weight=\"fill\" />\n <Icon icon={Heart} weight=\"duotone\" />\n </div>"}]},"Image":{"filePath":"src/components/Image/Image.fragment.tsx","meta":{"name":"Image","description":"Responsive image component with aspect ratio control, loading states, and error fallbacks. Handles image display with consistent styling.","category":"data-display","status":"stable","tags":["image","media","photo","picture","visual"],"since":"0.1.0"},"usage":{"when":["Displaying product images in cards or grids","Hero images with specific aspect ratios","User-uploaded content that may fail to load","Thumbnails in lists or galleries"],"whenNot":["User avatars (use Avatar component)","Icons or symbols (use Icon component)","Background images (use CSS background-image)","SVG illustrations (use inline SVG or Image component)"],"guidelines":["Always provide meaningful alt text for accessibility","Use appropriate aspect ratios for consistent layouts","Provide fallback content for failed loads","Use objectFit=\"contain\" for logos to preserve aspect ratio"],"accessibility":["Alt text is required and must describe the image content","Decorative images should have empty alt=\"\"","Avoid text in images; if necessary, describe the text in alt","Ensure sufficient contrast between image and surrounding content"]},"props":{"src":{"type":"string","description":"Image source URL","required":true},"alt":{"type":"string","description":"Alt text for accessibility (required)","required":true},"aspectRatio":{"type":"enum","description":"Aspect ratio of the image container","default":"auto","values":["1:1","4:3","16:9","21:9","auto"]},"objectFit":{"type":"enum","description":"How the image fits within its container","default":"cover","values":["cover","contain","fill","none"]},"width":{"type":"string | number","description":"Width of the image container"},"height":{"type":"string | number","description":"Height of the image container"},"rounded":{"type":"enum","description":"Border radius","default":"none","values":["none","sm","md","lg","full"]},"fallback":{"type":"node","description":"Content to show while loading or on error"}},"relations":[{"component":"Card","relationship":"child","note":"Common pattern to use Image at top of product cards"},{"component":"Avatar","relationship":"alternative","note":"Use Avatar for user profile pictures"}],"variants":[{"name":"Default","description":"Basic image display","code":"<Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=400&h=300&fit=crop\"\n alt=\"Code on a screen\"\n width={300}\n />"},{"name":"Aspect Ratios","description":"Different aspect ratio options","code":"<div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap' }}>\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=200&h=200&fit=crop\"\n alt=\"Square image\"\n aspectRatio=\"1:1\"\n width={100}\n />\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=200&h=150&fit=crop\"\n alt=\"4:3 image\"\n aspectRatio=\"4:3\"\n width={120}\n />\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=320&h=180&fit=crop\"\n alt=\"16:9 image\"\n aspectRatio=\"16:9\"\n width={160}\n />\n </div>"},{"name":"Rounded Corners","description":"Border radius options","code":"<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=100&h=100&fit=crop\"\n alt=\"No rounding\"\n rounded=\"none\"\n width={80}\n height={80}\n />\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=100&h=100&fit=crop\"\n alt=\"Medium rounding\"\n rounded=\"md\"\n width={80}\n height={80}\n />\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=100&h=100&fit=crop\"\n alt=\"Full rounding\"\n rounded=\"full\"\n width={80}\n height={80}\n />\n </div>"},{"name":"With Fallback","description":"Fallback content for loading/error states","code":"<Image\n src=\"https://invalid-url.example/image.jpg\"\n alt=\"Image that will fail\"\n width={200}\n height={150}\n rounded=\"md\"\n fallback={\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', background: 'var(--fui-color-surface-secondary)' }}>\n <span style={{ color: 'var(--fui-color-text-tertiary)' }}>No image</span>\n </div>\n }\n />"}]},"Input":{"filePath":"src/components/Input/Input.fragment.tsx","meta":{"name":"Input","description":"Text input field for single-line user data entry","category":"forms","status":"stable","tags":["form","input","text"]},"usage":{"when":["Collecting single-line text data from users","Email, password, phone number, or URL input","Search fields","Short form fields (name, title, etc.)"],"whenNot":["Multi-line text (use Textarea)","Selecting from predefined options (use Select)","Boolean input (use Checkbox or Switch)","Date/time input (use DatePicker)"],"guidelines":["Always provide a label for accessibility","Use appropriate input type for data validation","Show validation errors with error prop and helperText","Use placeholder for format hints, not labels"],"accessibility":["Labels must be associated with inputs","Error messages should be announced to screen readers","Required fields should be indicated"]},"props":{"value":{"type":"string","description":"Current input value (controlled)"},"placeholder":{"type":"string","description":"Placeholder text shown when empty","constraints":["Use for format hints only, not as a replacement for labels"]},"type":{"type":"enum","description":"HTML input type for validation and keyboard","default":"text","values":["text","email","password","number","tel","url"]},"disabled":{"type":"boolean","description":"Whether the input is interactive","default":false},"error":{"type":"boolean","description":"Whether to show error styling","default":false},"label":{"type":"string","description":"Label text displayed above input"},"helperText":{"type":"string","description":"Helper or error message below input"},"onChange":{"type":"function","description":"Called with new value on change"}},"relations":[{"component":"Textarea","relationship":"alternative","note":"Use Textarea for multi-line text input"},{"component":"Select","relationship":"alternative","note":"Use Select when choosing from predefined options"},{"component":"FormField","relationship":"parent","note":"Wrap in FormField for consistent form layout"}],"variants":[{"name":"Default","description":"Basic text input","code":"<Input label=\"Name\" placeholder=\"Enter your name\" />"},{"name":"With Value","description":"Input with pre-filled value","code":"<Input label=\"Email\" type=\"email\" value=\"user@example.com\" />"},{"name":"With Helper","description":"Input with helper text","code":"<Input\n label=\"Password\"\n type=\"password\"\n placeholder=\"Create a password\"\n helperText=\"Must be at least 8 characters\"\n />"},{"name":"Error State","description":"Input showing validation error","code":"<Input\n label=\"Email\"\n type=\"email\"\n value=\"invalid-email\"\n error\n helperText=\"Please enter a valid email address\"\n />"},{"name":"Disabled","description":"Non-interactive input","code":"<Input label=\"Username\" value=\"readonly-user\" disabled />"}]},"Link":{"filePath":"src/components/Link/Link.fragment.tsx","meta":{"name":"Link","description":"Styled anchor element for navigation. Supports internal and external links with consistent visual treatment.","category":"navigation","status":"stable","tags":["link","anchor","navigation","href","url"],"since":"0.1.0"},"usage":{"when":["Inline text links within paragraphs","Navigation links in footers or sidebars","\"Forgot password?\" or \"Sign up\" links in forms","External links to documentation or resources"],"whenNot":["Primary call-to-action (use Button instead)","Navigation tabs (use Tabs component)","Menu items in dropdowns (use Menu component)","Cards that link to detail pages (use Card with onClick)"],"guidelines":["Link text should describe the destination, not \"click here\"","Use external prop for links that open in new tabs","Use subtle variant for secondary/contextual links","Ensure links are distinguishable from regular text"],"accessibility":["Link text must be descriptive of the destination","External links should indicate they open in new window","Links must have visible focus indicators","Avoid using links that look like buttons without button semantics"]},"props":{"children":{"type":"node","description":"Link text content","required":true},"href":{"type":"string","description":"URL destination"},"variant":{"type":"enum","description":"Visual style variant","default":"default","values":["default","subtle","muted"]},"underline":{"type":"enum","description":"Underline behavior","default":"hover","values":["always","hover","none"]},"external":{"type":"boolean","description":"Opens in new tab with noopener noreferrer","default":"false"}},"relations":[{"component":"Button","relationship":"alternative","note":"Use Button for primary actions, Link for navigation"},{"component":"Text","relationship":"parent","note":"Links often appear within Text components"}],"variants":[{"name":"Default","description":"Standard link with hover underline","code":"<Link href=\"#\">Learn more about our services</Link>"},{"name":"Variants","description":"Visual style options","code":"<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>\n <Link href=\"#\" variant=\"default\">Default</Link>\n <Link href=\"#\" variant=\"subtle\">Subtle</Link>\n <Link href=\"#\" variant=\"muted\">Muted</Link>\n </div>"},{"name":"Underline Styles","description":"Different underline behaviors","code":"<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>\n <Link href=\"#\" underline=\"always\">Always underlined</Link>\n <Link href=\"#\" underline=\"hover\">Underline on hover</Link>\n <Link href=\"#\" underline=\"none\">No underline</Link>\n </div>"},{"name":"External Link","description":"Link that opens in new tab","code":"<Link href=\"https://example.com\" external>\n View documentation ↗\n </Link>"}]},"List":{"filePath":"src/components/List/List.fragment.tsx","meta":{"name":"List","description":"Compound component for rendering ordered or unordered lists with consistent styling. Supports bullet, numbered, and icon-prefixed items.","category":"layout","status":"stable","tags":["list","items","bullet","ordered","unordered"],"since":"0.1.0"},"usage":{"when":["Feature lists with checkmarks or icons","Ordered steps or instructions","Navigation lists in sidebars","Pricing plan feature comparisons"],"whenNot":["Interactive selection lists (use Menu or Select)","Data tables with columns (use Table)","Cards in a grid (use Grid with Card)","Navigation tabs (use Tabs)"],"guidelines":["Use as=\"ol\" for sequential or numbered content","Use variant=\"icon\" with meaningful icons for feature lists","Keep list items concise and parallel in structure","Use consistent icons within a single list"],"accessibility":["Use semantic list elements (ul, ol) for screen reader support","List items are automatically announced with count","Icons are decorative; ensure text conveys meaning","Avoid deeply nested lists (3+ levels)"]},"props":{"children":{"type":"node","description":"List.Item components","required":true},"as":{"type":"enum","description":"List type","default":"ul","values":["ul","ol"]},"variant":{"type":"enum","description":"List style variant","default":"disc","values":["none","disc","decimal","icon"]},"gap":{"type":"enum","description":"Spacing between items","default":"sm","values":["none","xs","sm","md","lg"]}},"relations":[{"component":"Icon","relationship":"child","note":"Use Icon as List.Item icon prop"},{"component":"Stack","relationship":"alternative","note":"Use Stack for non-semantic vertical lists"}],"variants":[{"name":"Bullet List","description":"Default unordered list with bullets","code":"<List variant=\"disc\">\n <List.Item>First item</List.Item>\n <List.Item>Second item</List.Item>\n <List.Item>Third item</List.Item>\n </List>"},{"name":"Numbered List","description":"Ordered list with numbers","code":"<List as=\"ol\" variant=\"decimal\">\n <List.Item>Create your account</List.Item>\n <List.Item>Configure your settings</List.Item>\n <List.Item>Start building</List.Item>\n </List>"},{"name":"Icon List","description":"List with custom icons per item","code":"<List variant=\"icon\">\n <List.Item icon={<Check weight=\"bold\" color=\"var(--fui-color-success)\" />}>\n Unlimited projects\n </List.Item>\n <List.Item icon={<Check weight=\"bold\" color=\"var(--fui-color-success)\" />}>\n Priority support\n </List.Item>\n <List.Item icon={<Check weight=\"bold\" color=\"var(--fui-color-success)\" />}>\n Advanced analytics\n </List.Item>\n </List>"},{"name":"No Style","description":"Plain list without markers","code":"<List variant=\"none\" gap=\"md\">\n <List.Item>Dashboard</List.Item>\n <List.Item>Settings</List.Item>\n <List.Item>Profile</List.Item>\n </List>"}]},"Listbox":{"filePath":"src/components/Listbox/Listbox.fragment.tsx","meta":{"name":"Listbox","description":"Controlled listbox for search results, autocomplete dropdowns, and command menus. Provides Menu-like styling without requiring a trigger.","category":"forms","status":"stable","tags":["listbox","search","autocomplete","combobox","command","dropdown"],"since":"0.3.0"},"usage":{"when":["Search result dropdowns","Autocomplete suggestions","Command palette results","Keyboard-navigable option lists"],"whenNot":["Static lists without selection (use List)","Action menus with trigger button (use Menu)","Form field selection (use Select)","Navigation menus (use Sidebar or Tabs)"],"guidelines":["Control open/close state externally based on input focus or query","Implement keyboard navigation (arrow keys, enter, escape) in parent","Use Listbox.Empty for no results state","Group related items with Listbox.Group when appropriate"],"accessibility":["Uses listbox and option ARIA roles","aria-selected indicates current selection","aria-disabled for non-interactive items","Connect to input with aria-controls for full combobox pattern"]},"props":{"children":{"type":"node","description":"Listbox.Item, Listbox.Group, or Listbox.Empty components","required":true},"className":{"type":"string","description":"Additional CSS class"},"style":{"type":"object","description":"Inline styles"}},"relations":[{"component":"Input","relationship":"sibling","note":"Pair with Input for search/autocomplete patterns"},{"component":"Menu","relationship":"alternative","note":"Use Menu when you need a trigger button"},{"component":"Select","relationship":"alternative","note":"Use Select for form field selection"},{"component":"List","relationship":"alternative","note":"Use List for static, non-interactive lists"}],"variants":[{"name":"Default","description":"Basic listbox with selectable items","code":"<Listbox aria-label=\"Options\">\n <Listbox.Item selected>First option</Listbox.Item>\n <Listbox.Item>Second option</Listbox.Item>\n <Listbox.Item>Third option</Listbox.Item>\n </Listbox>"},{"name":"Search Results","description":"Typical search results pattern with label and metadata","code":"<Listbox aria-label=\"Search results\">\n <Listbox.Item selected>\n <span style={{ fontWeight: 500 }}>Button</span>\n <span style={{ marginLeft: 'auto', fontSize: '0.75rem', color: 'var(--fui-text-tertiary)' }}>Components</span>\n </Listbox.Item>\n <Listbox.Item>\n <span style={{ fontWeight: 500 }}>Badge</span>\n <span style={{ marginLeft: 'auto', fontSize: '0.75rem', color: 'var(--fui-text-tertiary)' }}>Components</span>\n </Listbox.Item>\n <Listbox.Item>\n <span style={{ fontWeight: 500 }}>Box</span>\n <span style={{ marginLeft: 'auto', fontSize: '0.75rem', color: 'var(--fui-text-tertiary)' }}>Layout</span>\n </Listbox.Item>\n </Listbox>"},{"name":"With Groups","description":"Grouped items with labels","code":"<Listbox aria-label=\"Commands\">\n <Listbox.Group label=\"Recent\">\n <Listbox.Item selected>Open file...</Listbox.Item>\n <Listbox.Item>Save as...</Listbox.Item>\n </Listbox.Group>\n <Listbox.Group label=\"Actions\">\n <Listbox.Item>Copy</Listbox.Item>\n <Listbox.Item>Paste</Listbox.Item>\n <Listbox.Item disabled>Cut</Listbox.Item>\n </Listbox.Group>\n </Listbox>"},{"name":"Empty State","description":"No results found message","code":"<Listbox aria-label=\"Search results\">\n <Listbox.Empty>No results found</Listbox.Empty>\n </Listbox>"},{"name":"With Disabled Items","description":"Mix of enabled and disabled items","code":"<Listbox aria-label=\"Options\">\n <Listbox.Item>Available option</Listbox.Item>\n <Listbox.Item disabled>Disabled option</Listbox.Item>\n <Listbox.Item>Another option</Listbox.Item>\n </Listbox>"}],"ai":{"compositionPattern":"compound","subComponents":["Item","Group","Empty"],"requiredChildren":["Item"],"commonPatterns":["<Listbox aria-label=\"Search results\">{results.map(item => <Listbox.Item key={item.id} selected={item.id === selectedId} onClick={() => onSelect(item)}>{item.label}</Listbox.Item>)}</Listbox>"]}},"Menu":{"filePath":"src/components/Menu/Menu.fragment.tsx","meta":{"name":"Menu","description":"Dropdown menu for actions and commands. Use for contextual actions, overflow menus, or grouped commands.","category":"overlays","status":"stable","tags":["menu","dropdown","actions","context-menu","commands"],"since":"0.1.0"},"usage":{"when":["Overflow actions that dont fit in the toolbar","Context menus (right-click)","User account menus","Grouped actions with separators"],"whenNot":["Selecting from options (use Select)","Navigation (use Tabs or navigation components)","Form selection (use Select or RadioGroup)"],"guidelines":["Group related actions with Menu.Group","Use separators to divide action categories","Include keyboard shortcuts where applicable","Use danger variant for destructive actions","Keep menu items under 10-12 for usability"],"accessibility":["Full keyboard navigation with arrow keys","Type-ahead search for items","Focus returns to trigger on close","Proper ARIA menu roles"]},"props":{"children":{"type":"node","description":"Menu trigger and content","required":true},"open":{"type":"boolean","description":"Controlled open state"},"defaultOpen":{"type":"boolean","description":"Default open state (uncontrolled)","default":"false"},"onOpenChange":{"type":"function","description":"Called when open state changes"},"modal":{"type":"boolean","description":"Whether menu is modal","default":"true"}},"relations":[{"component":"Select","relationship":"alternative","note":"Use Select for form field selection"},{"component":"Popover","relationship":"alternative","note":"Use Popover for rich non-action content"}],"variants":[{"name":"Default","description":"Basic dropdown menu","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"secondary\">Actions</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Item onSelect={() => {}}>Edit</Menu.Item>\n <Menu.Item onSelect={() => {}}>Duplicate</Menu.Item>\n <Menu.Separator />\n <Menu.Item danger onSelect={() => {}}>Delete</Menu.Item>\n </Menu.Content>\n </Menu>"},{"name":"With Shortcuts","description":"Menu items with keyboard shortcuts","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"secondary\">Edit</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Item shortcut=\"Ctrl+Z\" onSelect={() => {}}>Undo</Menu.Item>\n <Menu.Item shortcut=\"Ctrl+Y\" onSelect={() => {}}>Redo</Menu.Item>\n <Menu.Separator />\n <Menu.Item shortcut=\"Ctrl+C\" onSelect={() => {}}>Copy</Menu.Item>\n <Menu.Item shortcut=\"Ctrl+V\" onSelect={() => {}}>Paste</Menu.Item>\n </Menu.Content>\n </Menu>"},{"name":"With Groups","description":"Menu with labeled groups","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"secondary\">Options</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Group>\n <Menu.GroupLabel>View</Menu.GroupLabel>\n <Menu.Item onSelect={() => {}}>Zoom In</Menu.Item>\n <Menu.Item onSelect={() => {}}>Zoom Out</Menu.Item>\n </Menu.Group>\n <Menu.Separator />\n <Menu.Group>\n <Menu.GroupLabel>Layout</Menu.GroupLabel>\n <Menu.Item onSelect={() => {}}>Grid View</Menu.Item>\n <Menu.Item onSelect={() => {}}>List View</Menu.Item>\n </Menu.Group>\n </Menu.Content>\n </Menu>"},{"name":"With Checkboxes","description":"Menu with toggleable options","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"secondary\">Display</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.CheckboxItem defaultChecked>Show Grid</Menu.CheckboxItem>\n <Menu.CheckboxItem defaultChecked>Show Rulers</Menu.CheckboxItem>\n <Menu.CheckboxItem>Show Guides</Menu.CheckboxItem>\n </Menu.Content>\n </Menu>"}],"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Item","CheckboxItem","RadioGroup","RadioItem","Group","GroupLabel","Separator"],"requiredChildren":["Trigger","Content"],"commonPatterns":["<Menu><Menu.Trigger asChild><Button>Actions</Button></Menu.Trigger><Menu.Content><Menu.Item>{action1}</Menu.Item><Menu.Separator /><Menu.Item danger>{delete}</Menu.Item></Menu.Content></Menu>"]}},"Popover":{"filePath":"src/components/Popover/Popover.fragment.tsx","meta":{"name":"Popover","description":"Rich content overlay anchored to a trigger element. Use for forms, detailed information, or interactive content that should stay in context.","category":"overlays","status":"stable","tags":["popover","overlay","dropdown","floating","contextual"],"since":"0.1.0"},"usage":{"when":["Inline editing forms","Rich preview content","Filter panels","Date/color pickers","Content that needs more space than a tooltip"],"whenNot":["Simple hints (use Tooltip)","Action lists (use Menu)","Blocking user interaction (use Dialog)","System notifications (use Toast or Alert)"],"guidelines":["Keep popover content focused and minimal","Include a clear way to close (X button or action buttons)","Position to avoid covering important content","Use arrow to visually connect popover to trigger"],"accessibility":["Focus is moved to popover content on open","Closes on Escape key","Focus returns to trigger on close"]},"props":{"children":{"type":"node","description":"Popover trigger and content","required":true},"open":{"type":"boolean","description":"Controlled open state"},"defaultOpen":{"type":"boolean","description":"Default open state (uncontrolled)","default":"false"},"onOpenChange":{"type":"function","description":"Called when open state changes"},"modal":{"type":"boolean","description":"Whether to block page interaction","default":"false"}},"relations":[{"component":"Tooltip","relationship":"alternative","note":"Use Tooltip for brief, non-interactive hints"},{"component":"Menu","relationship":"alternative","note":"Use Menu for action lists"},{"component":"Dialog","relationship":"alternative","note":"Use Dialog for blocking interactions"}],"variants":[{"name":"Default","description":"Basic popover with content","code":"<Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Open Popover</Button>\n </Popover.Trigger>\n <Popover.Content>\n <Popover.Close />\n <Popover.Title>Popover Title</Popover.Title>\n <Popover.Description>\n This is a popover with some content. It can contain text, forms, or other elements.\n </Popover.Description>\n </Popover.Content>\n </Popover>"},{"name":"With Form","description":"Popover containing a form","code":"<Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Edit Name</Button>\n </Popover.Trigger>\n <Popover.Content size=\"sm\">\n <Popover.Close />\n <Popover.Title>Edit Name</Popover.Title>\n <Popover.Body>\n <Input label=\"Display Name\" placeholder=\"Enter name\" />\n </Popover.Body>\n <Popover.Footer>\n <Popover.Close asChild>\n <Button variant=\"secondary\" size=\"sm\">Cancel</Button>\n </Popover.Close>\n <Button variant=\"primary\" size=\"sm\">Save</Button>\n </Popover.Footer>\n </Popover.Content>\n </Popover>"},{"name":"With Arrow","description":"Popover with pointing arrow","code":"<Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Info</Button>\n </Popover.Trigger>\n <Popover.Content arrow>\n <Popover.Title>Quick Tip</Popover.Title>\n <Popover.Description>\n This popover has an arrow pointing to its trigger element.\n </Popover.Description>\n </Popover.Content>\n </Popover>"},{"name":"Positions","description":"Popover on different sides","code":"<div style={{ display: 'flex', gap: '16px', padding: '60px' }}>\n <Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Top</Button>\n </Popover.Trigger>\n <Popover.Content side=\"top\" size=\"sm\">\n <Popover.Description>Popover on top</Popover.Description>\n </Popover.Content>\n </Popover>\n <Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Bottom</Button>\n </Popover.Trigger>\n <Popover.Content side=\"bottom\" size=\"sm\">\n <Popover.Description>Popover on bottom</Popover.Description>\n </Popover.Content>\n </Popover>\n </div>"}],"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Close","Title","Description","Body","Footer"],"requiredChildren":["Trigger","Content"],"commonPatterns":["<Popover><Popover.Trigger asChild><Button>Open</Button></Popover.Trigger><Popover.Content><Popover.Close /><Popover.Title>{title}</Popover.Title><Popover.Description>{description}</Popover.Description></Popover.Content></Popover>"]}},"Progress":{"filePath":"src/components/Progress/Progress.fragment.tsx","meta":{"name":"Progress","description":"Visual indicator of task completion or loading state. Available in linear and circular variants.","category":"feedback","status":"stable","tags":["progress","loading","indicator","percentage","status"],"since":"0.1.0"},"usage":{"when":["Showing upload/download progress","Displaying task completion percentage","Form completion indicators","Loading states with known duration"],"whenNot":["Unknown loading duration (use Spinner)","Step-based progress (use Stepper)","Status without percentage (use Badge)"],"guidelines":["Use determinate progress when you know the completion percentage","Use indeterminate for unknown durations","Include a label for context when the purpose isnt obvious","Use appropriate color variants for success/warning/danger states"],"accessibility":["Uses role=\"progressbar\" with aria-valuenow","Label is associated with the progress bar","State changes are announced to screen readers"]},"props":{"value":{"type":"number","description":"Current progress value (0-100). Null for indeterminate."},"size":{"type":"enum","description":"Size of the progress bar","default":"md","values":["sm","md","lg"]},"variant":{"type":"enum","description":"Color variant","default":"default","values":["default","success","warning","danger"]},"label":{"type":"string","description":"Label text above the progress bar"},"showValue":{"type":"boolean","description":"Show percentage value","default":"false"}},"relations":[{"component":"Badge","relationship":"alternative","note":"Use Badge for status without percentage"},{"component":"Alert","relationship":"sibling","note":"Use Alert for completion messages"}],"variants":[{"name":"Default","description":"Basic progress bar with percentage","code":"<Progress value={60} label=\"Uploading...\" showValue />"},{"name":"Variants","description":"Different color variants for different states","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', width: '300px' }}>\n <Progress value={75} variant=\"default\" label=\"Processing\" showValue />\n <Progress value={100} variant=\"success\" label=\"Complete\" showValue />\n <Progress value={80} variant=\"warning\" label=\"Almost full\" showValue />\n <Progress value={95} variant=\"danger\" label=\"Storage critical\" showValue />\n </div>"},{"name":"Sizes","description":"Different progress bar sizes","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', width: '300px' }}>\n <Progress value={50} size=\"sm\" label=\"Small\" />\n <Progress value={50} size=\"md\" label=\"Medium\" />\n <Progress value={50} size=\"lg\" label=\"Large\" />\n </div>"},{"name":"Indeterminate","description":"Loading state with unknown duration","code":"<Progress value={null} label=\"Loading...\" />"},{"name":"Circular","description":"Circular progress indicator","code":"<div style={{ display: 'flex', gap: '24px', alignItems: 'center' }}>\n <CircularProgress value={25} size=\"sm\" />\n <CircularProgress value={50} size=\"md\" showValue />\n <CircularProgress value={75} size=\"lg\" showValue variant=\"success\" />\n <CircularProgress value={null} size=\"md\" />\n </div>"}]},"Prompt":{"filePath":"src/components/Prompt/Prompt.fragment.tsx","meta":{"name":"Prompt","description":"Multi-line input with toolbar for AI/chat interfaces","category":"forms","status":"stable","tags":["prompt","chat","ai","input","textarea","form"]},"usage":{"when":["Building chat or AI assistant interfaces","Need multi-line input with submit action","Require toolbar with actions like attachments or model selection"],"whenNot":["Simple single-line text input (use Input)","Basic multi-line without toolbar (use Textarea)","Search-only interface (use Input with search variant)"],"guidelines":["Always provide an onSubmit handler","Use loading state during API calls","Consider showing usage/token limits for AI contexts"],"accessibility":["Enter submits, Shift+Enter for newline","Submit button is keyboard accessible","Loading state prevents duplicate submissions"]},"props":{"value":{"type":"string","description":"Controlled input value"},"defaultValue":{"type":"string","description":"Uncontrolled default value"},"onChange":{"type":"function","description":"Called when value changes"},"onSubmit":{"type":"function","description":"Called on form submission"},"placeholder":{"type":"string","description":"Placeholder text for the textarea","default":"\"Ask, Search or Chat...\""},"disabled":{"type":"boolean","description":"Disable the entire prompt","default":"false"},"loading":{"type":"boolean","description":"Show loading state","default":"false"},"minRows":{"type":"number","description":"Minimum number of visible rows","default":"1"},"maxRows":{"type":"number","description":"Maximum number of visible rows","default":"8"},"autoResize":{"type":"boolean","description":"Enable auto-resize based on content","default":"true"},"submitOnEnter":{"type":"boolean","description":"Submit on Enter (Shift+Enter for newline)","default":"true"}},"relations":[{"component":"Input","relationship":"alternative","note":"Use Input for simple single-line text input"},{"component":"Textarea","relationship":"alternative","note":"Use Textarea for multi-line without toolbar"}],"variants":[{"name":"Basic","description":"Simple prompt with submit button","code":"<Prompt onSubmit={(value) => console.log(value)}>\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions />\n <Prompt.Info>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n </Prompt>"},{"name":"With Actions","description":"Prompt with attachment and mode buttons","code":"<Prompt onSubmit={(value) => console.log(value)}>\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Add attachment\">\n +\n </Prompt.ActionButton>\n <Prompt.ModeButton>Auto</Prompt.ModeButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n </Prompt>"},{"name":"With Usage","description":"Shows token usage indicator","code":"<Prompt onSubmit={(value) => console.log(value)}>\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Add attachment\">\n +\n </Prompt.ActionButton>\n <Prompt.ModeButton active>Auto</Prompt.ModeButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Usage>52% used</Prompt.Usage>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n </Prompt>"},{"name":"Loading State","description":"During API submission","code":"<Prompt\n onSubmit={(value) => console.log(value)}\n loading\n defaultValue=\"Tell me about the weather...\"\n >\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Add attachment\">\n +\n </Prompt.ActionButton>\n <Prompt.ModeButton>Auto</Prompt.ModeButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Usage>52% used</Prompt.Usage>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n </Prompt>"},{"name":"Disabled","description":"Non-interactive prompt","code":"<Prompt onSubmit={(value) => console.log(value)} disabled>\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Add attachment\">\n +\n </Prompt.ActionButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n </Prompt>"}]},"RadioGroup":{"filePath":"src/components/RadioGroup/RadioGroup.fragment.tsx","meta":{"name":"RadioGroup","description":"Single selection from a list of mutually exclusive options","category":"forms","status":"stable","tags":["form","radio","selection","options"]},"usage":{"when":["User must select exactly one option from a small set","Options are mutually exclusive","All options should be visible at once","2-5 options available"],"whenNot":["Multiple selections allowed (use Checkbox group)","Many options (use Select)","Binary on/off choice (use Toggle/Switch)","Options need to be searchable (use Combobox)"],"guidelines":["Always have one option pre-selected when possible","Order options logically (alphabetical, frequency, etc.)","Keep option labels concise","Use descriptions for complex options"],"accessibility":["Group must have an accessible label","Use arrow keys to navigate between options","Selected option should be clearly indicated"]},"props":{"value":{"type":"string","description":"Controlled selected value"},"defaultValue":{"type":"string","description":"Default value (uncontrolled)"},"onValueChange":{"type":"function","description":"Callback when selection changes"},"orientation":{"type":"enum","description":"Layout orientation","default":"vertical","values":["horizontal","vertical"]},"size":{"type":"enum","description":"Size variant","default":"md","values":["sm","md","lg"]},"disabled":{"type":"boolean","description":"Disable all options","default":false},"label":{"type":"string","description":"Group label"},"error":{"type":"string","description":"Error message"}},"relations":[{"component":"Checkbox","relationship":"alternative","note":"Use Checkbox for multiple selections"},{"component":"Select","relationship":"alternative","note":"Use Select for many options or limited space"},{"component":"Toggle","relationship":"alternative","note":"Use Toggle for binary on/off choices"}],"variants":[{"name":"Default","description":"Basic radio group with labels","code":"<RadioGroup defaultValue=\"option1\" label=\"Select an option\">\n <RadioGroup.Item value=\"option1\" label=\"Option 1\" />\n <RadioGroup.Item value=\"option2\" label=\"Option 2\" />\n <RadioGroup.Item value=\"option3\" label=\"Option 3\" />\n </RadioGroup>"},{"name":"With Descriptions","description":"Radio items with additional context","code":"<RadioGroup defaultValue=\"standard\" label=\"Shipping Method\">\n <RadioGroup.Item\n value=\"standard\"\n label=\"Standard\"\n description=\"5-7 business days\"\n />\n <RadioGroup.Item\n value=\"express\"\n label=\"Express\"\n description=\"2-3 business days\"\n />\n <RadioGroup.Item\n value=\"overnight\"\n label=\"Overnight\"\n description=\"Next business day\"\n />\n </RadioGroup>"},{"name":"Horizontal","description":"Side-by-side layout","code":"<RadioGroup orientation=\"horizontal\" defaultValue=\"small\" label=\"Size\">\n <RadioGroup.Item value=\"small\" label=\"S\" />\n <RadioGroup.Item value=\"medium\" label=\"M\" />\n <RadioGroup.Item value=\"large\" label=\"L\" />\n <RadioGroup.Item value=\"xlarge\" label=\"XL\" />\n </RadioGroup>"},{"name":"With Error","description":"Validation error state","code":"<RadioGroup label=\"Required selection\" error=\"Please select an option\">\n <RadioGroup.Item value=\"a\" label=\"Option A\" />\n <RadioGroup.Item value=\"b\" label=\"Option B\" />\n </RadioGroup>"},{"name":"Disabled","description":"Non-interactive state","code":"<RadioGroup disabled defaultValue=\"locked\" label=\"Locked selection\">\n <RadioGroup.Item value=\"locked\" label=\"This is locked\" />\n <RadioGroup.Item value=\"other\" label=\"Cannot select\" />\n </RadioGroup>"}]},"Select":{"filePath":"src/components/Select/Select.fragment.tsx","meta":{"name":"Select","description":"Dropdown for choosing from a list of options. Use when there are more than 4-5 choices that would clutter the UI.","category":"forms","status":"stable","tags":["select","dropdown","form","options","picker"],"since":"0.1.0"},"usage":{"when":["Choosing from a predefined list of options","More than 4-5 options that would clutter UI as radio buttons","Space-constrained forms","When users need to see all options at once"],"whenNot":["Very few options (2-3) - use radio buttons","Users might type custom values - use Combobox","Multiple selections needed - use Checkbox group or MultiSelect","Actions, not selection - use Menu"],"guidelines":["Include a placeholder that explains what to select","Group related options with SelectGroup","Keep option text concise","Order options logically (alphabetical, by frequency, or by category)"],"accessibility":["Full keyboard navigation support","Type-ahead search within options","Proper ARIA roles and attributes"]},"props":{"children":{"type":"node","description":"Select trigger and content","required":true},"value":{"type":"string","description":"Controlled selected value"},"defaultValue":{"type":"string","description":"Default selected value (uncontrolled)"},"onValueChange":{"type":"function","description":"Called when selection changes"},"placeholder":{"type":"string","description":"Placeholder text when no value selected"},"disabled":{"type":"boolean","description":"Disable the select","default":"false"}},"relations":[{"component":"Menu","relationship":"alternative","note":"Use Menu for action-based dropdowns"},{"component":"Input","relationship":"sibling","note":"Use Input for free-form text entry"},{"component":"Checkbox","relationship":"alternative","note":"Use Checkbox group for multiple selections"}],"variants":[{"name":"Default","description":"Basic select dropdown","code":"<StatefulSelect placeholder=\"Select a fruit\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"apple\">Apple</Select.Item>\n <Select.Item value=\"banana\">Banana</Select.Item>\n <Select.Item value=\"orange\">Orange</Select.Item>\n <Select.Item value=\"grape\">Grape</Select.Item>\n </Select.Content>\n </StatefulSelect>"},{"name":"With Groups","description":"Options organized into groups","code":"<StatefulSelect placeholder=\"Select a country\">\n <Select.Trigger />\n <Select.Content>\n <Select.Group>\n <Select.GroupLabel>North America</Select.GroupLabel>\n <Select.Item value=\"us\">United States</Select.Item>\n <Select.Item value=\"ca\">Canada</Select.Item>\n <Select.Item value=\"mx\">Mexico</Select.Item>\n </Select.Group>\n <Select.Group>\n <Select.GroupLabel>Europe</Select.GroupLabel>\n <Select.Item value=\"uk\">United Kingdom</Select.Item>\n <Select.Item value=\"de\">Germany</Select.Item>\n <Select.Item value=\"fr\">France</Select.Item>\n </Select.Group>\n </Select.Content>\n </StatefulSelect>"},{"name":"With Disabled Options","description":"Some options are disabled","code":"<StatefulSelect placeholder=\"Select a plan\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"free\">Free</Select.Item>\n <Select.Item value=\"pro\">Pro</Select.Item>\n <Select.Item value=\"enterprise\" disabled>Enterprise (Contact Sales)</Select.Item>\n </Select.Content>\n </StatefulSelect>"},{"name":"Disabled","description":"Disabled select","code":"<Select disabled placeholder=\"Select an option\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"1\">Option 1</Select.Item>\n </Select.Content>\n </Select>"}],"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Item","Group","GroupLabel"],"requiredChildren":["Trigger","Content"],"commonPatterns":["<Select placeholder=\"Select option\"><Select.Trigger /><Select.Content><Select.Item value=\"opt1\">{label1}</Select.Item><Select.Item value=\"opt2\">{label2}</Select.Item></Select.Content></Select>"]}},"Separator":{"filePath":"src/components/Separator/Separator.fragment.tsx","meta":{"name":"Separator","description":"Visual divider between content sections. Use to create clear visual boundaries and improve content organization.","category":"layout","status":"stable","tags":["separator","divider","hr","line","layout"],"since":"0.1.0"},"usage":{"when":["Dividing content sections","Separating groups of related items","Creating visual breathing room","Labeled section breaks"],"whenNot":["Creating grid layouts (use CSS Grid)","Decorative borders (use CSS)","Spacing alone is sufficient"],"guidelines":["Use sparingly - too many separators create visual noise","Consider if spacing alone would work","Use soft variant for subtle separation","Labeled separators work well for major section breaks"],"accessibility":["Uses role=\"separator\" for semantic meaning","Decorative separators should be aria-hidden"]},"props":{"orientation":{"type":"enum","description":"Direction of the separator","default":"horizontal","values":["horizontal","vertical"]},"spacing":{"type":"enum","description":"Margin around the separator","default":"none","values":["none","sm","md","lg"]},"soft":{"type":"boolean","description":"Softer, lighter appearance","default":"false"},"label":{"type":"string","description":"Optional text label (horizontal only)"}},"relations":[{"component":"Card","relationship":"sibling","note":"Cards provide stronger visual grouping"}],"variants":[{"name":"Default","description":"Basic horizontal separator","code":"<div style={{ width: '300px' }}>\n <p>Content above</p>\n <Separator spacing=\"md\" />\n <p>Content below</p>\n </div>"},{"name":"With Label","description":"Labeled section divider","code":"<div style={{ width: '300px' }}>\n <p>First section</p>\n <Separator label=\"Or\" spacing=\"md\" />\n <p>Second section</p>\n </div>"},{"name":"Soft","description":"Subtle separator","code":"<div style={{ width: '300px' }}>\n <p>Content above</p>\n <Separator soft spacing=\"md\" />\n <p>Content below</p>\n </div>"},{"name":"Vertical","description":"Vertical separator between elements","code":"<div style={{ display: 'flex', alignItems: 'center', gap: '16px', height: '40px' }}>\n <span>Item 1</span>\n <Separator orientation=\"vertical\" />\n <span>Item 2</span>\n <Separator orientation=\"vertical\" />\n <span>Item 3</span>\n </div>"},{"name":"Spacing Options","description":"Different spacing sizes","code":"<div style={{ width: '300px' }}>\n <p>No spacing</p>\n <Separator spacing=\"none\" />\n <p>Small spacing</p>\n <Separator spacing=\"sm\" />\n <p>Medium spacing</p>\n <Separator spacing=\"md\" />\n <p>Large spacing</p>\n <Separator spacing=\"lg\" />\n <p>End</p>\n </div>"}]},"Sidebar":{"filePath":"src/components/Sidebar/Sidebar.fragment.tsx","meta":{"name":"Sidebar","description":"Responsive navigation sidebar with collapsible desktop mode and mobile drawer behavior.","category":"navigation","status":"stable","tags":["sidebar","navigation","drawer","menu","layout"],"since":"0.3.0"},"usage":{"when":["Primary app navigation with multiple sections","Dashboard layouts requiring persistent navigation","Admin interfaces with hierarchical menu structure","Apps that need both mobile drawer and desktop sidebar"],"whenNot":["Simple websites with few pages (use header nav)","Content-focused sites where navigation is secondary","Single-page applications with no navigation needs","Mobile-only apps where bottom navigation is preferred"],"guidelines":["Group related items into sections with clear labels","Use icons for all items to support collapsed mode","Limit nesting to 2 levels maximum","Place most frequently used items at the top","Use badges sparingly for notifications or counts","The `active` prop on items should be controlled by your app based on current route","Use `collapsedContent` on Header to show just a logo icon when collapsed","Submenus are hidden when collapsed - use tooltips for navigation hints instead","Use SidebarProvider to enable external triggers and keyboard shortcuts","Use asChild with routing libraries (Next.js Link, React Router NavLink)","Use Sidebar.MenuSkeleton while loading navigation data"],"accessibility":["Uses semantic <nav> element with aria-label","aria-current=\"page\" on active items","aria-expanded on items with submenus","Escape key closes mobile drawer","Cmd/Ctrl+B keyboard shortcut toggles sidebar (when using SidebarProvider)","Focus trap in mobile drawer mode","Minimum 44px touch targets"]},"props":{"children":{"type":"node","description":"Sidebar content (use Sidebar.Header, Sidebar.Nav, Sidebar.Section, etc.)","required":true},"collapsed":{"type":"boolean","description":"Icon-only mode for desktop (controlled)"},"defaultCollapsed":{"type":"boolean","description":"Initial collapsed state (uncontrolled)","default":false},"onCollapsedChange":{"type":"function","description":"Called when collapsed state changes"},"open":{"type":"boolean","description":"Mobile drawer open state (controlled)"},"defaultOpen":{"type":"boolean","description":"Initial open state (uncontrolled)","default":false},"onOpenChange":{"type":"function","description":"Called when open state changes"},"width":{"type":"string","description":"Width of expanded sidebar","default":"240px"},"collapsedWidth":{"type":"string","description":"Width when collapsed","default":"64px"},"position":{"type":"enum","description":"Sidebar position","default":"left","values":["left","right"]},"collapsible":{"type":"enum","description":"Collapse behavior mode","default":"icon","values":["icon","offcanvas","none"]},"asChild":{"type":"boolean","description":"(Sidebar.Item) Render as child element for polymorphic composition","default":false}},"relations":[{"component":"Tabs","relationship":"alternative","note":"Use Tabs for in-page section navigation"},{"component":"Menu","relationship":"composition","note":"Use Menu for contextual actions within sidebar"}],"variants":[{"name":"Default","description":"Standard sidebar with navigation sections. The `active` prop highlights the current page.","code":"<div style={demoContainerStyle}>\n <Sidebar>\n <Sidebar.Header collapsedContent={<LogoIcon size={32} />}>\n <LogoIcon size={32} />\n <span style={{ fontWeight: 600, fontSize: '16px' }}>Acme App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<UsersIcon />}>Team</Sidebar.Item>\n <Sidebar.Item icon={<FolderIcon />}>Projects</Sidebar.Item>\n </Sidebar.Section>\n <Sidebar.Section label=\"Settings\">\n <Sidebar.Item icon={<GearIcon />}>Preferences</Sidebar.Item>\n <Sidebar.Item icon={<HelpIcon />}>Help</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Sidebar.CollapseToggle />\n </Sidebar.Footer>\n </Sidebar>\n <main style={mainContentStyle}>\n Dashboard content goes here\n </main>\n </div>"},{"name":"Collapsed","description":"Icon-only collapsed state. Header shows only logo, tooltips appear on hover.","code":"<CollapsedDemo />"},{"name":"With Badges","description":"Navigation items with notification badges for counts or alerts.","code":"<div style={demoContainerStyle}>\n <Sidebar>\n <Sidebar.Header collapsedContent={<LogoIcon size={32} />}>\n <LogoIcon size={32} />\n <span style={{ fontWeight: 600, fontSize: '16px' }}>Acme App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />} badge=\"3\">Analytics</Sidebar.Item>\n <Sidebar.Item icon={<UsersIcon />} badge=\"12\">Team</Sidebar.Item>\n <Sidebar.Item icon={<FolderIcon />}>Projects</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Sidebar.CollapseToggle />\n </Sidebar.Footer>\n </Sidebar>\n <main style={mainContentStyle}>\n Badges indicate unread items or notifications\n </main>\n </div>"},{"name":"With Submenu","description":"Nested navigation with expandable sections. Use defaultExpanded for initial state without manual state tracking.","code":"<SubmenuDemo />"},{"name":"With Disabled Items","description":"Some navigation items are disabled for permissions or feature flags.","code":"<div style={demoContainerStyle}>\n <Sidebar>\n <Sidebar.Header collapsedContent={<LogoIcon size={32} />}>\n <LogoIcon size={32} />\n <span style={{ fontWeight: 600, fontSize: '16px' }}>Acme App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<UsersIcon />} disabled>Team (Coming Soon)</Sidebar.Item>\n <Sidebar.Item icon={<FolderIcon />} disabled>Projects (Upgrade)</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Sidebar.CollapseToggle />\n </Sidebar.Footer>\n </Sidebar>\n <main style={mainContentStyle}>\n Disabled items cannot be clicked\n </main>\n </div>"},{"name":"With Provider & External Trigger","description":"SidebarProvider enables external triggers and keyboard shortcuts (Cmd/Ctrl+B).","code":"<ProviderDemo />"},{"name":"With asChild (Polymorphic)","description":"Use asChild to render items as custom elements like Next.js Link or React Router NavLink.","code":"<AsChildDemo />"},{"name":"With Section Action","description":"Section headers can include action buttons for quick actions like \"Add Project\".","code":"<SectionActionDemo />"},{"name":"With Loading Skeleton","description":"Show skeleton placeholders while navigation data is loading.","code":"<SkeletonDemo />"},{"name":"With Rail Toggle","description":"Add a Rail component for a subtle drag-handle style toggle at the sidebar edge. Hover to reveal, click to toggle.","code":"<RailDemo />"}],"ai":{"compositionPattern":"compound","subComponents":["Header","Nav","Section","Item","SubItem","Submenu","Footer","CollapseToggle","Rail","MenuSkeleton","SectionAction"],"requiredChildren":["Nav"],"commonPatterns":["<Sidebar><Sidebar.Header>{logo}</Sidebar.Header><Sidebar.Nav><Sidebar.Section><Sidebar.Item icon={icon} active>{label}</Sidebar.Item></Sidebar.Section></Sidebar.Nav><Sidebar.Footer><Sidebar.CollapseToggle /></Sidebar.Footer></Sidebar>"]}},"Skeleton":{"filePath":"src/components/Skeleton/Skeleton.fragment.tsx","meta":{"name":"Skeleton","description":"Placeholder loading state for content","category":"feedback","status":"stable","tags":["loading","placeholder","skeleton","shimmer"]},"usage":{"when":["Content is loading asynchronously","Preventing layout shift during data fetching","Providing visual feedback that content is coming","Improving perceived performance"],"whenNot":["Short loading times (< 300ms)","When spinner is more appropriate","Background operations without visible impact"],"guidelines":["Match skeleton shape to expected content","Use semantic variants (text, heading, avatar) for consistency","Maintain similar dimensions to loaded content","Avoid too many skeleton elements - simplify complex layouts"],"accessibility":["Skeletons are decorative - use aria-hidden","Announce loading state separately if needed","Ensure sufficient contrast for the animation"]},"props":{"variant":{"type":"enum","description":"Semantic variant that auto-sizes","default":"rect","values":["text","heading","avatar","button","input","rect"]},"size":{"type":"enum","description":"Size for avatar/button variants","default":"md","values":["sm","md","lg"]},"width":{"type":"union","description":"Custom width (string or number)"},"height":{"type":"union","description":"Custom height (string or number)"},"fill":{"type":"boolean","description":"Fill parent container","default":false},"radius":{"type":"enum","description":"Border radius override","values":["none","sm","md","lg","full"]}},"relations":[{"component":"Progress","relationship":"alternative","note":"Use Progress for determinate loading"}],"variants":[{"name":"Default","description":"Basic rectangle skeleton","code":"<Skeleton width={200} height={20} />"},{"name":"Text Lines","description":"Multi-line text placeholder","code":"<Skeleton.Text lines={3} />"},{"name":"Semantic Variants","description":"Pre-configured shapes for common elements","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--fui-space-2)' }}>\n <Skeleton variant=\"heading\" width={200} />\n <Skeleton variant=\"text\" width=\"100%\" />\n <Skeleton variant=\"text\" width=\"80%\" />\n </div>"},{"name":"Avatar Skeleton","description":"Circular placeholder for avatars","code":"<div style={{ display: 'flex', gap: 'var(--fui-space-1)', alignItems: 'center' }}>\n <Skeleton.Circle size=\"sm\" />\n <Skeleton.Circle size=\"md\" />\n <Skeleton.Circle size=\"lg\" />\n </div>"},{"name":"Card Skeleton","description":"Composed skeleton for a card layout","code":"<div style={{ width: 300, padding: 'var(--fui-space-2)', border: '1px solid var(--fui-border)', borderRadius: 'var(--fui-radius-lg)' }}>\n <Skeleton variant=\"rect\" height={120} radius=\"md\" />\n <div style={{ marginTop: 'var(--fui-space-2)' }}>\n <Skeleton variant=\"heading\" width=\"60%\" />\n </div>\n <div style={{ marginTop: 'var(--fui-space-1)' }}>\n <Skeleton.Text lines={2} />\n </div>\n </div>"}]},"Table":{"filePath":"src/components/Table/Table.fragment.tsx","meta":{"name":"Table","description":"Data table with sorting and row selection. Use for displaying structured data that needs to be scanned, compared, or acted upon.","category":"data-display","status":"stable","tags":["table","data","grid","list","sorting"],"since":"0.1.0"},"usage":{"when":["Displaying structured, tabular data","Data that users need to scan and compare","Lists with multiple attributes per item","Data that needs sorting or selection"],"whenNot":["Simple lists (use List component)","Card-based layouts (use CardGrid)","Heavily interactive data (consider DataGrid)","Small screens (consider card or list view)"],"guidelines":["Keep columns to a reasonable number (5-7 max)","Use consistent alignment (numbers right, text left)","Provide meaningful empty states","Consider mobile responsiveness"],"accessibility":["Proper table semantics with headers","Sortable columns are keyboard accessible","Row selection is properly announced"]},"props":{"columns":{"type":"array","description":"Column definitions","required":true},"data":{"type":"array","description":"Data rows to display","required":true},"sortable":{"type":"boolean","description":"Enable column sorting","default":"false"},"selectable":{"type":"boolean","description":"Enable row selection","default":"false"},"onRowClick":{"type":"function","description":"Handler for row clicks"},"emptyMessage":{"type":"string","description":"Message when no data","default":"No data available"},"size":{"type":"enum","description":"Table density","default":"md","values":["sm","md"]}},"relations":[{"component":"EmptyState","relationship":"sibling","note":"Use EmptyState for empty table states"},{"component":"Badge","relationship":"sibling","note":"Use Badge for status columns"}],"variants":[{"name":"Default","description":"Basic data table","code":"<Table\n columns={columns}\n data={sampleUsers}\n />"},{"name":"Sortable","description":"Table with sortable columns","code":"<Table\n columns={columns}\n data={sampleUsers}\n sortable\n />"},{"name":"Clickable Rows","description":"Table with clickable rows","code":"<Table\n columns={columns}\n data={sampleUsers}\n onRowClick={(row) => alert(`Clicked: ${row.name}`)}\n />"},{"name":"Compact","description":"Smaller, denser table","code":"<Table\n columns={columns}\n data={sampleUsers}\n size=\"sm\"\n />"},{"name":"Empty State","description":"Table with no data","code":"<Table\n columns={columns}\n data={[]}\n emptyMessage=\"No users found\"\n />"}],"ai":{"compositionPattern":"simple","commonPatterns":["<Table columns={[{header:\"Name\",accessorKey:\"name\"},{header:\"Status\",accessorKey:\"status\"}]} data={[{name:\"Item 1\",status:\"Active\"}]} />"]}},"Tabs":{"filePath":"src/components/Tabs/Tabs.fragment.tsx","meta":{"name":"Tabs","description":"Organize content into switchable panels. Use for related content that benefits from a compact, navigable layout.","category":"navigation","status":"stable","tags":["tabs","navigation","panels","content-switcher"],"since":"0.1.0"},"usage":{"when":["Organizing related content into sections","Reducing page scrolling by grouping content","Settings pages with multiple categories","Dashboard views with different data perspectives"],"whenNot":["Primary navigation (use sidebar or header nav)","Sequential steps (use Stepper or wizard)","Comparing content side-by-side","Very long lists of options (use Select or Menu)"],"guidelines":["Keep tab labels short (1-2 words)","Order tabs by usage frequency or logical sequence","Avoid more than 5-6 tabs; consider sub-navigation for more","Tab content should be roughly equivalent in scope","Use pills variant for contained sections, underline for page-level tabs"],"accessibility":["Keyboard navigation with arrow keys","Tab panels are properly labeled","Focus management follows WAI-ARIA tabs pattern"]},"props":{"children":{"type":"node","description":"Tab list and panels (use Tabs.List, Tabs.Tab, Tabs.Panel)","required":true},"defaultValue":{"type":"string","description":"Initially active tab (uncontrolled)"},"value":{"type":"string","description":"Controlled active tab value"},"onValueChange":{"type":"function","description":"Called when active tab changes"},"orientation":{"type":"enum","description":"Tab list orientation","default":"horizontal","values":["horizontal","vertical"]}},"relations":[{"component":"Select","relationship":"alternative","note":"Use Select for many options in compact space"},{"component":"Menu","relationship":"alternative","note":"Use Menu for action-based navigation"}],"variants":[{"name":"Underline","description":"Default underline style tabs","code":"<Tabs defaultValue=\"overview\">\n <Tabs.List variant=\"underline\">\n <Tabs.Tab value=\"overview\">Overview</Tabs.Tab>\n <Tabs.Tab value=\"analytics\">Analytics</Tabs.Tab>\n <Tabs.Tab value=\"settings\">Settings</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panel value=\"overview\">\n <p>Overview content goes here.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"analytics\">\n <p>Analytics content goes here.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"settings\">\n <p>Settings content goes here.</p>\n </Tabs.Panel>\n </Tabs>"},{"name":"Pills","description":"Pill-style tabs for contained sections","code":"<Tabs defaultValue=\"all\">\n <Tabs.List variant=\"pills\">\n <Tabs.Tab value=\"all\">All</Tabs.Tab>\n <Tabs.Tab value=\"active\">Active</Tabs.Tab>\n <Tabs.Tab value=\"archived\">Archived</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panel value=\"all\">\n <p>Showing all items.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"active\">\n <p>Showing active items only.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"archived\">\n <p>Showing archived items.</p>\n </Tabs.Panel>\n </Tabs>"},{"name":"With Disabled","description":"Tabs with a disabled option","code":"<Tabs defaultValue=\"general\">\n <Tabs.List variant=\"underline\">\n <Tabs.Tab value=\"general\">General</Tabs.Tab>\n <Tabs.Tab value=\"security\">Security</Tabs.Tab>\n <Tabs.Tab value=\"billing\" disabled>Billing</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panel value=\"general\">\n <p>General settings panel.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"security\">\n <p>Security settings panel.</p>\n </Tabs.Panel>\n </Tabs>"}],"ai":{"compositionPattern":"compound","subComponents":["List","Tab","Panel"],"requiredChildren":["List","Panel"],"commonPatterns":["<Tabs defaultValue=\"tab1\"><Tabs.List><Tabs.Tab value=\"tab1\">{label1}</Tabs.Tab><Tabs.Tab value=\"tab2\">{label2}</Tabs.Tab></Tabs.List><Tabs.Panel value=\"tab1\">{content1}</Tabs.Panel><Tabs.Panel value=\"tab2\">{content2}</Tabs.Panel></Tabs>"]}},"Textarea":{"filePath":"src/components/Textarea/Textarea.fragment.tsx","meta":{"name":"Textarea","description":"Multi-line text input for longer form content","category":"forms","status":"stable","tags":["input","text","form","multiline"]},"usage":{"when":["Collecting multi-line text (comments, descriptions)","Free-form text input that may span multiple lines","Message composition fields","Code or content editing"],"whenNot":["Single-line input (use Input)","Rich text editing (use rich text editor)","Selecting from predefined options (use Select)"],"guidelines":["Set appropriate rows for expected content length","Use placeholder to show example format","Show character count when maxLength is set","Consider auto-resize for better UX"],"accessibility":["Always provide a visible label","Use helperText for format hints","Error messages should be descriptive"]},"props":{"value":{"type":"string","description":"Controlled value"},"placeholder":{"type":"string","description":"Placeholder text"},"rows":{"type":"number","description":"Number of visible text rows","default":3},"label":{"type":"string","description":"Label text above the textarea"},"helperText":{"type":"string","description":"Helper text below the textarea"},"error":{"type":"boolean","description":"Error state","default":false},"disabled":{"type":"boolean","description":"Disabled state","default":false},"resize":{"type":"enum","description":"Resize behavior","default":"vertical","values":["none","vertical","horizontal","both"]},"maxLength":{"type":"number","description":"Maximum character length"}},"relations":[{"component":"Input","relationship":"alternative","note":"Use Input for single-line text"}],"variants":[{"name":"Default","description":"Basic textarea with label","code":"<Textarea\n label=\"Description\"\n placeholder=\"Enter a description...\"\n />"},{"name":"With Helper Text","description":"Textarea with additional guidance","code":"<Textarea\n label=\"Bio\"\n placeholder=\"Tell us about yourself...\"\n helperText=\"Max 500 characters\"\n maxLength={500}\n />"},{"name":"Error State","description":"Textarea showing validation error","code":"<Textarea\n label=\"Comments\"\n placeholder=\"Add your comments...\"\n error\n helperText=\"This field is required\"\n />"},{"name":"Disabled","description":"Non-interactive textarea","code":"<Textarea\n label=\"Notes\"\n placeholder=\"Cannot edit...\"\n disabled\n />"},{"name":"Custom Rows","description":"Textarea with more visible rows","code":"<Textarea\n label=\"Long Description\"\n placeholder=\"Enter detailed information...\"\n rows={6}\n />"}]},"Theme":{"filePath":"src/components/Theme/Theme.fragment.tsx","meta":{"name":"Theme","description":"Theme management system with provider, toggle, and hook pattern. Supports light, dark, and system modes with localStorage persistence.","category":"layout","status":"stable","tags":["theme","dark-mode","light-mode","provider","toggle"],"since":"0.5.0"},"usage":{"when":["Providing theme context to an application","Toggling between light and dark modes","Respecting system color scheme preference","Persisting theme preference across sessions"],"whenNot":["Simple one-off color changes (use CSS variables)","Component-level theming (use component props)"],"guidelines":["Wrap your app with ThemeProvider at the root level","Use useTheme hook to access theme state in components","ThemeToggle cycles through light → dark → system","Use storageKey to customize localStorage key","Set attribute=\"class\" if your CSS uses .dark class instead of data-theme"],"accessibility":["ThemeToggle button has accessible label indicating current mode","Theme changes are applied via CSS custom properties for smooth transitions","System preference is detected via prefers-color-scheme media query"]},"props":{"children":{"type":"node","description":"Application content","required":true},"defaultMode":{"type":"enum","description":"Default theme mode for uncontrolled usage","default":"system","values":["light","dark","system"]},"mode":{"type":"enum","description":"Controlled theme mode","values":["light","dark","system"]},"onModeChange":{"type":"function","description":"Callback when mode changes"},"storageKey":{"type":"string","description":"localStorage key for persistence","default":"fui-theme"},"attribute":{"type":"enum","description":"How to apply theme to DOM","default":"data-theme","values":["data-theme","class"]}},"relations":[{"component":"AppShell","relationship":"sibling","note":"ThemeProvider typically wraps AppShell"}],"variants":[{"name":"Default","description":"ThemeProvider with system default","code":"<ThemeProvider defaultMode=\"system\">\n <ThemeDemo />\n </ThemeProvider>"},{"name":"With Toggle","description":"ThemeProvider with toggle button","code":"<ThemeProvider defaultMode=\"light\">\n <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>\n <ThemeToggle />\n <span>Click to cycle themes</span>\n </div>\n </ThemeProvider>"},{"name":"Toggle Sizes","description":"ThemeToggle in different sizes","code":"<ThemeProvider defaultMode=\"light\">\n <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>\n <ThemeToggle size=\"sm\" />\n <ThemeToggle size=\"md\" />\n <ThemeToggle size=\"lg\" />\n </div>\n </ThemeProvider>"}]},"Toast":{"filePath":"src/components/Toast/Toast.fragment.tsx","meta":{"name":"Toast","description":"Brief, non-blocking notification messages","category":"feedback","status":"stable","tags":["notification","alert","message","feedback"]},"usage":{"when":["Providing feedback after an action","Showing success/error status of operations","Non-critical information that doesn't require action","Temporary messages that auto-dismiss"],"whenNot":["Critical errors requiring user action (use Dialog)","Persistent information (use Alert)","Inline validation (use form error states)","System-wide announcements (use Banner)"],"guidelines":["Keep messages brief and actionable","Use appropriate variant for the message type","Auto-dismiss after reasonable duration (3-5s)","Allow manual dismissal for longer messages","Limit number of simultaneous toasts"],"accessibility":["Use role=\"alert\" for important messages","Ensure sufficient display time for reading","Don't rely solely on color for meaning","Provide dismiss button with accessible label"]},"props":{"title":{"type":"string","description":"Toast title"},"description":{"type":"string","description":"Additional message content"},"variant":{"type":"enum","description":"Visual variant indicating message type","default":"default","values":["default","success","error","warning","info"]},"duration":{"type":"number","description":"Auto-dismiss duration in ms (0 = no auto-dismiss)","default":5000},"action":{"type":"object","description":"Optional action button { label, onClick }"}},"relations":[{"component":"Alert","relationship":"alternative","note":"Use Alert for persistent inline messages"},{"component":"Dialog","relationship":"alternative","note":"Use Dialog for messages requiring user action"}],"variants":[{"name":"Default","description":"Interactive toast demo - click buttons to trigger toasts","code":"<ToastDemoWrapper />"},{"name":"Success","description":"Success message variant","code":"<Toast\n title=\"Success!\"\n description=\"Your changes have been saved.\"\n variant=\"success\"\n />"},{"name":"Error","description":"Error message variant","code":"<Toast\n title=\"Error\"\n description=\"Failed to save changes. Please try again.\"\n variant=\"error\"\n />"},{"name":"Warning","description":"Warning message variant","code":"<Toast\n title=\"Warning\"\n description=\"This action cannot be undone.\"\n variant=\"warning\"\n />"},{"name":"Info","description":"Informational message variant","code":"<Toast\n title=\"New Update\"\n description=\"Version 2.0 is now available.\"\n variant=\"info\"\n />"},{"name":"With Action","description":"Toast with an action button","code":"<Toast\n title=\"File deleted\"\n description=\"The file has been moved to trash.\"\n action={{\n label: 'Undo',\n onClick: () => console.log('Undo clicked'),\n }}\n />"}]},"Toggle":{"filePath":"src/components/Toggle/Toggle.fragment.tsx","meta":{"name":"Toggle","description":"Binary on/off switch for settings and preferences. Provides immediate visual feedback and is ideal for options that take effect instantly.","category":"forms","status":"stable","tags":["switch","toggle","boolean","settings","preference"],"since":"0.1.0"},"usage":{"when":["Binary settings that take effect immediately (e.g., dark mode, notifications)","Enabling/disabling features in a settings panel","Options where the result is immediately visible","Mobile-friendly boolean inputs"],"whenNot":["Multiple options in a group (use checkbox group)","Selection requires form submission to take effect (use checkbox)","Yes/No questions in forms (use radio buttons)","Complex multi-state options (use select or radio)"],"guidelines":["Toggle should always have a visible label explaining what it controls","The \"on\" state should be the positive/enabling action","Changes should take effect immediately - no save button needed","Include a description for toggles whose effect isn't obvious from the label","Group related toggles visually in settings panels"],"accessibility":["Uses role=\"switch\" with aria-checked for proper semantics","Must have an accessible label (visible or aria-label)","Focus indicator must be clearly visible","State change must be announced by screen readers"]},"props":{"checked":{"type":"boolean","description":"Whether the toggle is in the on state","default":"false"},"onChange":{"type":"function","description":"Callback with new checked state: (checked: boolean) => void"},"label":{"type":"string","description":"Visible label text"},"description":{"type":"string","description":"Helper text shown below the label"},"disabled":{"type":"boolean","description":"Whether the toggle is non-interactive","default":"false"},"size":{"type":"enum","description":"Toggle track size","default":"md","values":["sm","md"]}},"relations":[{"component":"Input","relationship":"sibling","note":"Input handles text/number entry; Toggle handles boolean state"},{"component":"Checkbox","relationship":"alternative","note":"Use Checkbox when change requires form submission"}],"variants":[{"name":"Default Off","description":"Toggle in the off state","code":"<StatefulToggle label=\"Email notifications\" />","args":{"label":"Email notifications"}},{"name":"Checked","description":"Toggle in the on state","code":"<StatefulToggle checked label=\"Dark mode\" />","args":{"checked":true,"label":"Dark mode"}},{"name":"With Description","description":"Toggle with explanatory helper text","code":"<StatefulToggle\n checked\n label=\"Auto-save\"\n description=\"Automatically save changes as you type\"\n />","args":{"checked":true,"label":"Auto-save","description":"Automatically save changes as you type"}},{"name":"Small Size","description":"Compact toggle for dense settings panels","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <StatefulToggle size=\"sm\" checked label=\"Show line numbers\" />\n <StatefulToggle size=\"sm\" label=\"Word wrap\" />\n <StatefulToggle size=\"sm\" checked label=\"Minimap\" />\n </div>"},{"name":"Disabled States","description":"Non-interactive toggles showing both states","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <Toggle disabled label=\"Premium feature (upgrade required)\" />\n <Toggle disabled checked label=\"System managed (read-only)\" />\n </div>"},{"name":"Settings Panel","description":"Multiple toggles in a realistic settings layout","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '320px' }}>\n <StatefulToggle\n checked\n label=\"Push notifications\"\n description=\"Receive push notifications on your device\"\n />\n <StatefulToggle\n checked\n label=\"Email digest\"\n description=\"Weekly summary of your activity\"\n />\n <StatefulToggle\n label=\"Marketing emails\"\n description=\"Product updates and promotional offers\"\n />\n </div>"}]},"Tooltip":{"filePath":"src/components/Tooltip/Tooltip.fragment.tsx","meta":{"name":"Tooltip","description":"Contextual help text that appears on hover or focus. Perfect for explaining icons, truncated text, or providing additional context.","category":"overlays","status":"stable","tags":["tooltip","hint","help","hover","contextual"],"since":"0.1.0"},"usage":{"when":["Explaining icon-only buttons","Showing full text for truncated content","Providing keyboard shortcuts","Brief contextual help that fits in one line"],"whenNot":["Long-form help content (use Popover)","Critical information users must see (use Alert)","Interactive content (use Popover or Menu)","Mobile-primary interfaces (tooltips require hover)"],"guidelines":["Keep tooltip text concise (under 80 characters)","Use sentence case, no period for single sentences","Avoid duplicating visible label text","Consider mobile users who cannot hover"],"accessibility":["Accessible via focus as well as hover","Uses role=\"tooltip\" with proper aria association","Delay prevents tooltips from appearing during navigation"]},"props":{"children":{"type":"element","description":"The element that triggers the tooltip","required":true},"content":{"type":"node","description":"Content to display in the tooltip","required":true},"side":{"type":"enum","description":"Which side to show the tooltip","default":"top","values":["top","bottom","left","right"]},"align":{"type":"enum","description":"Alignment along the side","default":"center","values":["start","center","end"]},"sideOffset":{"type":"number","description":"Distance from trigger in pixels","default":"6"},"delay":{"type":"number","description":"Delay before showing (ms)","default":"400"},"arrow":{"type":"boolean","description":"Show arrow pointing to trigger","default":"true"},"disabled":{"type":"boolean","description":"Disable the tooltip","default":"false"}},"relations":[{"component":"Popover","relationship":"alternative","note":"Use Popover for interactive or longer content"},{"component":"Alert","relationship":"alternative","note":"Use Alert for critical information that must be visible"}],"variants":[{"name":"Default","description":"Basic tooltip on hover","code":"<Tooltip content=\"Save your changes\">\n <Button>Save</Button>\n </Tooltip>"},{"name":"Positions","description":"Tooltips on different sides","code":"<div style={{ display: 'flex', gap: '16px', padding: '40px' }}>\n <Tooltip content=\"Top tooltip\" side=\"top\">\n <Button variant=\"secondary\">Top</Button>\n </Tooltip>\n <Tooltip content=\"Bottom tooltip\" side=\"bottom\">\n <Button variant=\"secondary\">Bottom</Button>\n </Tooltip>\n <Tooltip content=\"Left tooltip\" side=\"left\">\n <Button variant=\"secondary\">Left</Button>\n </Tooltip>\n <Tooltip content=\"Right tooltip\" side=\"right\">\n <Button variant=\"secondary\">Right</Button>\n </Tooltip>\n </div>"},{"name":"With Shortcut","description":"Tooltip showing keyboard shortcut","code":"<Tooltip content=\"Undo (Ctrl+Z)\">\n <Button variant=\"ghost\">Undo</Button>\n </Tooltip>"},{"name":"No Arrow","description":"Tooltip without arrow","code":"<Tooltip content=\"Clean tooltip\" arrow={false}>\n <Button variant=\"secondary\">Hover me</Button>\n </Tooltip>"}]},"VisuallyHidden":{"filePath":"src/components/VisuallyHidden/VisuallyHidden.fragment.tsx","meta":{"name":"VisuallyHidden","description":"Hides content visually while keeping it accessible to screen readers. Essential for accessible icon-only buttons and supplementary text.","category":"utilities","status":"stable","tags":["accessibility","a11y","screen-reader","hidden","sr-only"],"since":"0.1.0"},"usage":{"when":["Providing accessible labels for icon-only buttons","Adding context that screen readers need but sighted users don't","Hiding decorative content while providing text alternatives","Skip links for keyboard navigation"],"whenNot":["Hiding content from everyone (use display: none or conditional render)","Content that should be visible on focus (use focus-visible styles)","Temporarily hidden content (use proper ARIA attributes)","Lazy-loaded content (use suspense or loading states)"],"guidelines":["Always use with icon-only interactive elements","Keep hidden text concise but descriptive","Test with screen readers to verify announcements","Don't overuse; visible text is often better"],"accessibility":["Content is announced by screen readers","Content is focusable if interactive elements are inside","Essential for WCAG 2.1 compliance with icon-only controls","Must convey equivalent information to visual content"]},"props":{"children":{"type":"node","description":"Content to hide visually","required":true},"as":{"type":"enum","description":"HTML element to render","default":"span","values":["span","div"]}},"relations":[{"component":"Button","relationship":"child","note":"Use inside icon-only buttons for accessible labels"},{"component":"Icon","relationship":"sibling","note":"Pair with icons to provide text alternatives"}],"variants":[{"name":"Icon Button Label","description":"Accessible label for icon-only button","code":"<button style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '40px',\n height: '40px',\n border: '1px solid var(--fui-border-default)',\n borderRadius: '8px',\n background: 'var(--fui-color-surface-primary)',\n cursor: 'pointer'\n }}>\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n <VisuallyHidden>Search</VisuallyHidden>\n </button>"},{"name":"Supplementary Text","description":"Additional context for screen readers","code":"<a href=\"#\" style={{ color: 'var(--fui-color-accent)' }}>\n Read more\n <VisuallyHidden> about our accessibility features</VisuallyHidden>\n </a>"},{"name":"Skip Link","description":"Navigation aid that becomes visible on focus","code":"<div>\n <VisuallyHidden as=\"div\">\n <a\n href=\"#main-content\"\n style={{\n position: 'absolute',\n padding: '8px 16px',\n background: 'var(--fui-color-accent)',\n color: 'white'\n }}\n >\n Skip to main content\n </a>\n </VisuallyHidden>\n <p style={{ color: 'var(--fui-color-text-tertiary)', fontSize: '14px' }}>\n (Screen reader only: \"Skip to main content\" link)\n </p>\n </div>"}]}},"recipes":{"App Shell":{"filePath":"src/recipes/AppShell.recipe.ts","name":"App Shell","description":"Full application layout with sidebar, header, and main content. Supports two layout modes: stacked (header full-width) and sidebar-inset (sidebar full-height).","category":"layout","components":["AppShell","Header","Sidebar","ThemeToggle"],"code":"// App Shell - Stacked Layout (header spans full width)\n// Best for apps where the brand should be prominent in the header\n\nimport { AppShell, Header, Sidebar, ThemeToggle } from '@fragments/ui';\n\nfunction StackedLayout({ children }) {\n return (\n <AppShell layout=\"stacked\">\n <AppShell.Header>\n <Header>\n <Header.SkipLink />\n <Header.Trigger />\n <Header.Brand href=\"/\">MyApp</Header.Brand>\n <Header.Nav>\n <Header.NavItem href=\"/\" active>Dashboard</Header.NavItem>\n <Header.NavItem href=\"/settings\">Settings</Header.NavItem>\n </Header.Nav>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"240px\" collapsible=\"offcanvas\">\n <Sidebar.Nav>\n <Sidebar.Section label=\"Menu\">\n <Sidebar.Item icon={<HomeIcon />} href=\"/\" active>\n Home\n </Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />} href=\"/analytics\">\n Analytics\n </Sidebar.Item>\n <Sidebar.Item icon={<GearIcon />} href=\"/settings\">\n Settings\n </Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"lg\">\n {children}\n </AppShell.Main>\n </AppShell>\n );\n}\n\n// App Shell - Sidebar Inset Layout (sidebar is full height)\n// Best for documentation sites or when sidebar branding is preferred\n\nfunction SidebarInsetLayout({ children }) {\n return (\n <AppShell layout=\"sidebar-inset\">\n <AppShell.Header>\n <Header>\n <Header.SkipLink />\n <Header.Trigger />\n <Header.Search>\n <Input placeholder=\"Search...\" />\n </Header.Search>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"260px\" collapsible=\"offcanvas\">\n <Sidebar.Header>\n <a href=\"/\">MyApp</a>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section label=\"Getting Started\">\n <Sidebar.Item href=\"/docs\" active>Introduction</Sidebar.Item>\n <Sidebar.Item href=\"/docs/install\">Installation</Sidebar.Item>\n </Sidebar.Section>\n <Sidebar.Section label=\"Components\">\n <Sidebar.Item href=\"/components\">Overview</Sidebar.Item>\n <Sidebar.Item href=\"/components/button\">Button</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>v1.0.0</Sidebar.Footer>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"lg\">\n {children}\n </AppShell.Main>\n </AppShell>\n );\n}\n\n// App Shell with Collapsible Icon Sidebar\n// Sidebar collapses to icons only - great for dashboards\n\nfunction CollapsibleLayout({ children }) {\n return (\n <AppShell layout=\"sidebar-inset\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar collapsible=\"icon\" width=\"240px\" collapsedWidth=\"64px\">\n <Sidebar.Header collapsedContent={<Logo />}>\n <Logo /> <span>MyApp</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<GearIcon />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Sidebar.CollapseToggle />\n </Sidebar.Footer>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"lg\">\n {children}\n </AppShell.Main>\n </AppShell>\n );\n}\n\n// App Shell with Aside Panel\n// Optional right panel for additional context\n\nfunction LayoutWithAside({ children, aside }) {\n return (\n <AppShell layout=\"stacked\">\n <AppShell.Header>\n <Header>\n <Header.Brand>MyApp</Header.Brand>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"200px\" collapsible=\"offcanvas\">\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Home</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"lg\">\n {children}\n </AppShell.Main>\n\n <AppShell.Aside width=\"280px\">\n {aside}\n </AppShell.Aside>\n </AppShell>\n );\n}","tags":["layout","app-shell","sidebar","navigation","dashboard"]},"Card Grid":{"filePath":"src/recipes/CardGrid.recipe.ts","name":"Card Grid","description":"Responsive grid of cards that reflows based on available space","category":"layout","components":["Grid","Card"],"code":"<Grid columns=\"auto\" minChildWidth=\"16rem\" gap=\"md\">\n {items.map(item => (\n <Card key={item.id}>\n <Card.Header>\n <Card.Title>{item.title}</Card.Title>\n <Card.Description>{item.description}</Card.Description>\n </Card.Header>\n <Card.Body>{item.content}</Card.Body>\n </Card>\n ))}\n</Grid>","tags":["grid","cards","responsive","dashboard","tiles"]},"Chat Interface":{"filePath":"src/recipes/ChatInterface.recipe.ts","name":"Chat Interface","description":"AI chat interface with message history and prompt input","category":"layout","components":["Prompt","Card","Avatar","Stack"],"code":"import { useState } from 'react';\nimport { Prompt, Card, Avatar, Stack } from '@fragments-sdk/ui';\n\ninterface Message {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n}\n\nfunction ChatInterface() {\n const [messages, setMessages] = useState<Message[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n\n const handleSubmit = async (value: string) => {\n // Add user message\n const userMessage: Message = {\n id: crypto.randomUUID(),\n role: 'user',\n content: value,\n };\n setMessages((prev) => [...prev, userMessage]);\n setIsLoading(true);\n\n try {\n // Simulate API call\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n // Add assistant response\n const assistantMessage: Message = {\n id: crypto.randomUUID(),\n role: 'assistant',\n content: 'This is a simulated response. Replace with your AI API call.',\n };\n setMessages((prev) => [...prev, assistantMessage]);\n } finally {\n setIsLoading(false);\n }\n };\n\n return (\n <Stack gap=\"4\" style={{ height: '100vh', padding: '1rem' }}>\n {/* Messages */}\n <Stack gap=\"3\" style={{ flex: 1, overflow: 'auto' }}>\n {messages.map((msg) => (\n <Card key={msg.id} padding=\"md\">\n <Card.Body>\n <Stack direction=\"row\" gap=\"3\" align=\"start\">\n <Avatar size=\"sm\">\n {msg.role === 'user' ? 'U' : 'AI'}\n </Avatar>\n <div style={{ flex: 1 }}>{msg.content}</div>\n </Stack>\n </Card.Body>\n </Card>\n ))}\n </Stack>\n\n {/* Prompt */}\n <Prompt onSubmit={handleSubmit} loading={isLoading}>\n <Prompt.Textarea placeholder=\"Ask anything...\" />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Attach file\">\n +\n </Prompt.ActionButton>\n <Prompt.ModeButton>Auto</Prompt.ModeButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Usage>52% used</Prompt.Usage>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n </Prompt>\n </Stack>\n );\n}","tags":["chat","ai","assistant","conversation"]},"Code Examples":{"filePath":"src/recipes/CodeExamples.recipe.ts","name":"Code Examples","description":"Patterns for displaying code in documentation with syntax highlighting","category":"documentation","components":["CodeBlock","Tabs","Card"],"code":"// Installation commands with package manager tabs\n<Tabs defaultValue=\"npm\">\n <Tabs.List>\n <Tabs.Tab value=\"npm\">npm</Tabs.Tab>\n <Tabs.Tab value=\"pnpm\">pnpm</Tabs.Tab>\n <Tabs.Tab value=\"yarn\">yarn</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panel value=\"npm\">\n <CodeBlock code=\"npm install @fragments-sdk/ui\" language=\"bash\" />\n </Tabs.Panel>\n <Tabs.Panel value=\"pnpm\">\n <CodeBlock code=\"pnpm add @fragments-sdk/ui\" language=\"bash\" />\n </Tabs.Panel>\n <Tabs.Panel value=\"yarn\">\n <CodeBlock code=\"yarn add @fragments-sdk/ui\" language=\"bash\" />\n </Tabs.Panel>\n</Tabs>\n\n// Usage example with preview\n<Card>\n <Card.Header>\n <Card.Title>Button Example</Card.Title>\n </Card.Header>\n <Card.Body>\n <div className=\"preview\">\n <Button variant=\"primary\">Click me</Button>\n </div>\n <CodeBlock\n code={`<Button variant=\"primary\">Click me</Button>`}\n language=\"tsx\"\n />\n </Card.Body>\n</Card>\n\n// Multi-file example with titles\n<CodeBlock\n title=\"Button.tsx\"\n code={buttonCode}\n language=\"tsx\"\n showLineNumbers\n/>\n<CodeBlock\n title=\"Button.module.scss\"\n code={stylesCode}\n language=\"scss\"\n showLineNumbers\n/>\n\n// Highlighted important lines\n<CodeBlock\n code={exampleCode}\n language=\"tsx\"\n showLineNumbers\n highlightLines={[3, \"7-10\"]}\n/>","tags":["code","documentation","syntax","examples"]},"Confirm Dialog":{"filePath":"src/recipes/ConfirmDialog.recipe.ts","name":"Confirm Dialog","description":"Confirmation dialog with destructive action warning","category":"overlays","components":["Dialog","Button"],"code":"<Dialog open={isOpen} onClose={onClose}>\n <Dialog.Title>{title}</Dialog.Title>\n <Dialog.Description>{description}</Dialog.Description>\n <Dialog.Actions>\n <Button variant=\"secondary\" onClick={onClose}>Cancel</Button>\n <Button variant=\"danger\" onClick={onConfirm}>Confirm</Button>\n </Dialog.Actions>\n</Dialog>","tags":["confirm","dialog","modal","destructive"]},"Dashboard Layout":{"filePath":"src/recipes/DashboardLayout.recipe.ts","name":"Dashboard Layout","description":"Dashboard grid with a featured full-width card and smaller metric cards below","category":"layout","components":["Grid","Card","Badge","Separator"],"code":"<Grid columns={4} gap=\"lg\">\n <Grid.Item colSpan=\"full\">\n <Card>\n <Card.Header>\n <Card.Title>Overview</Card.Title>\n <Card.Description>Key metrics for this period</Card.Description>\n </Card.Header>\n <Card.Body>{summaryContent}</Card.Body>\n </Card>\n </Grid.Item>\n <Card variant=\"outlined\">\n <Card.Header>\n <Card.Title>Users</Card.Title>\n </Card.Header>\n <Card.Body>\n <Badge variant=\"success\">{stats.users}</Badge>\n </Card.Body>\n </Card>\n <Card variant=\"outlined\">\n <Card.Header>\n <Card.Title>Revenue</Card.Title>\n </Card.Header>\n <Card.Body>\n <Badge variant=\"info\">{stats.revenue}</Badge>\n </Card.Body>\n </Card>\n <Card variant=\"outlined\">\n <Card.Header>\n <Card.Title>Orders</Card.Title>\n </Card.Header>\n <Card.Body>\n <Badge variant=\"warning\">{stats.orders}</Badge>\n </Card.Body>\n </Card>\n <Card variant=\"outlined\">\n <Card.Header>\n <Card.Title>Errors</Card.Title>\n </Card.Header>\n <Card.Body>\n <Badge variant=\"danger\">{stats.errors}</Badge>\n </Card.Body>\n </Card>\n <Grid.Item colSpan=\"full\">\n <Separator spacing=\"md\" />\n </Grid.Item>\n <Grid.Item colSpan={2}>\n <Card>\n <Card.Header>\n <Card.Title>Recent Activity</Card.Title>\n </Card.Header>\n <Card.Body>{activityList}</Card.Body>\n </Card>\n </Grid.Item>\n <Grid.Item colSpan={2}>\n <Card>\n <Card.Header>\n <Card.Title>Notifications</Card.Title>\n </Card.Header>\n <Card.Body>{notificationList}</Card.Body>\n </Card>\n </Grid.Item>\n</Grid>","tags":["dashboard","layout","metrics","widgets","overview"]},"Dashboard Navigation":{"filePath":"src/recipes/DashboardNav.recipe.ts","name":"Dashboard Navigation","description":"Sidebar navigation pattern for dashboard applications with user profile, sections, and nested menus","category":"navigation","components":["Sidebar","Avatar"],"code":"// Dashboard Navigation with User Profile\n// A complete sidebar navigation for admin/dashboard interfaces\n\nfunction DashboardNav({ user, currentPath }) {\n const [collapsed, setCollapsed] = React.useState(false);\n const [projectsExpanded, setProjectsExpanded] = React.useState(false);\n\n return (\n <Sidebar\n collapsed={collapsed}\n onCollapsedChange={setCollapsed}\n >\n {/* Brand header */}\n <Sidebar.Header>\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 256 256\" fill=\"var(--fui-color-accent)\">\n <path d=\"M208,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32Zm0,176H48V48H208V208Z\" />\n </svg>\n {!collapsed && (\n <span style={{ fontWeight: 600, fontSize: '16px' }}>Dashboard</span>\n )}\n <Sidebar.CollapseToggle />\n </Sidebar.Header>\n\n {/* Main navigation */}\n <Sidebar.Nav aria-label=\"Dashboard navigation\">\n {/* Primary section */}\n <Sidebar.Section>\n <Sidebar.Item\n icon={<HomeIcon />}\n href=\"/dashboard\"\n active={currentPath === '/dashboard'}\n >\n Overview\n </Sidebar.Item>\n <Sidebar.Item\n icon={<ChartIcon />}\n href=\"/analytics\"\n active={currentPath === '/analytics'}\n badge=\"New\"\n >\n Analytics\n </Sidebar.Item>\n <Sidebar.Item\n icon={<InboxIcon />}\n href=\"/inbox\"\n active={currentPath === '/inbox'}\n badge=\"5\"\n >\n Inbox\n </Sidebar.Item>\n </Sidebar.Section>\n\n {/* Projects section with nested items */}\n <Sidebar.Section label=\"Workspace\">\n <Sidebar.Item\n icon={<FolderIcon />}\n hasSubmenu\n expanded={projectsExpanded}\n onExpandedChange={setProjectsExpanded}\n >\n Projects\n </Sidebar.Item>\n <Sidebar.Submenu>\n <Sidebar.SubItem\n href=\"/projects/website\"\n active={currentPath === '/projects/website'}\n >\n Website Redesign\n </Sidebar.SubItem>\n <Sidebar.SubItem\n href=\"/projects/mobile\"\n active={currentPath === '/projects/mobile'}\n >\n Mobile App\n </Sidebar.SubItem>\n <Sidebar.SubItem\n href=\"/projects/api\"\n active={currentPath === '/projects/api'}\n >\n API Integration\n </Sidebar.SubItem>\n </Sidebar.Submenu>\n <Sidebar.Item\n icon={<UsersIcon />}\n href=\"/team\"\n active={currentPath === '/team'}\n >\n Team Members\n </Sidebar.Item>\n <Sidebar.Item\n icon={<CalendarIcon />}\n href=\"/calendar\"\n active={currentPath === '/calendar'}\n >\n Calendar\n </Sidebar.Item>\n </Sidebar.Section>\n\n {/* Settings section */}\n <Sidebar.Section label=\"Account\">\n <Sidebar.Item\n icon={<GearIcon />}\n href=\"/settings\"\n active={currentPath === '/settings'}\n >\n Settings\n </Sidebar.Item>\n <Sidebar.Item\n icon={<HelpIcon />}\n href=\"/help\"\n active={currentPath === '/help'}\n >\n Help & Support\n </Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n\n {/* Footer with user profile */}\n <Sidebar.Footer>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n padding: collapsed ? '0' : '8px',\n borderRadius: '8px',\n cursor: 'pointer',\n }}>\n <Avatar\n src={user.avatar}\n name={user.name}\n size=\"sm\"\n />\n {!collapsed && (\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{\n fontWeight: 500,\n fontSize: '14px',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}>\n {user.name}\n </div>\n <div style={{\n fontSize: '12px',\n color: 'var(--fui-text-secondary)',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}>\n {user.email}\n </div>\n </div>\n )}\n </div>\n </Sidebar.Footer>\n </Sidebar>\n );\n}\n\n// Usage example:\n// <DashboardNav\n// user={{ name: 'Jane Doe', email: 'jane@example.com', avatar: '/avatar.jpg' }}\n// currentPath=\"/dashboard\"\n// />\n\n// Icon components (use your preferred icon library)\nconst HomeIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 256 256\" fill=\"currentColor\">\n <path d=\"M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8H96a8,8,0,0,0,8-8V160h48v56a8,8,0,0,0,8,8h56a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68Z\" />\n </svg>\n);","tags":["navigation","sidebar","dashboard","admin","menu"]},"Form Layout":{"filePath":"src/recipes/FormLayout.recipe.ts","name":"Form Layout","description":"Two-column form with full-width fields where needed, using Grid for alignment","category":"forms","components":["Grid","Input","Textarea","Select","Button"],"code":"<Grid columns={2} gap=\"md\">\n <Input label=\"First Name\" placeholder=\"Jane\" />\n <Input label=\"Last Name\" placeholder=\"Doe\" />\n <Grid.Item colSpan=\"full\">\n <Input label=\"Email\" type=\"email\" placeholder=\"jane@example.com\" />\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Select label=\"Role\">\n <Select.Item value=\"admin\">Admin</Select.Item>\n <Select.Item value=\"editor\">Editor</Select.Item>\n <Select.Item value=\"viewer\">Viewer</Select.Item>\n </Select>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Textarea label=\"Bio\" placeholder=\"Tell us about yourself\" />\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Button type=\"submit\" variant=\"primary\">Save</Button>\n </Grid.Item>\n</Grid>","tags":["form","layout","grid","inputs","settings"]},"Login Form":{"filePath":"src/recipes/LoginForm.recipe.ts","name":"Login Form","description":"Email/password authentication form with validation states","category":"forms","components":["FormField","Input","Button","Alert"],"code":"<FormField label=\"Email\" error={errors.email}>\n <Input type=\"email\" placeholder=\"you@example.com\" />\n</FormField>\n<FormField label=\"Password\" error={errors.password}>\n <Input type=\"password\" />\n</FormField>\n<Button type=\"submit\" variant=\"primary\">Sign in</Button>\n{error && (\n <Alert severity=\"error\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Content>{error}</Alert.Content>\n </Alert.Body>\n </Alert>\n)}","tags":["auth","login","form"]},"Settings Page":{"filePath":"src/recipes/SettingsPage.recipe.ts","name":"Settings Page","description":"Settings page with labeled sections using cards, toggles, and a save action","category":"forms","components":["Grid","Card","Toggle","Input","Select","Separator","Button"],"code":"<Grid columns={1} gap=\"lg\">\n <Card>\n <Card.Header>\n <Card.Title>Profile</Card.Title>\n <Card.Description>Your public profile information</Card.Description>\n </Card.Header>\n <Card.Body>\n <Grid columns={2} gap=\"md\">\n <Input label=\"Display Name\" defaultValue={user.name} />\n <Input label=\"Email\" type=\"email\" defaultValue={user.email} />\n <Grid.Item colSpan=\"full\">\n <Input label=\"Website\" type=\"url\" defaultValue={user.website} />\n </Grid.Item>\n </Grid>\n </Card.Body>\n </Card>\n\n <Card>\n <Card.Header>\n <Card.Title>Notifications</Card.Title>\n <Card.Description>Choose what you get notified about</Card.Description>\n </Card.Header>\n <Card.Body>\n <Grid columns={1} gap=\"sm\">\n <Toggle label=\"Email notifications\" checked={prefs.emailNotifs} onChange={onToggle('emailNotifs')} />\n <Toggle label=\"Push notifications\" checked={prefs.pushNotifs} onChange={onToggle('pushNotifs')} />\n <Toggle label=\"Weekly digest\" checked={prefs.digest} onChange={onToggle('digest')} />\n </Grid>\n </Card.Body>\n </Card>\n\n <Card>\n <Card.Header>\n <Card.Title>Appearance</Card.Title>\n </Card.Header>\n <Card.Body>\n <Select label=\"Theme\" value={prefs.theme} onChange={onThemeChange}>\n <Select.Item value=\"light\">Light</Select.Item>\n <Select.Item value=\"dark\">Dark</Select.Item>\n <Select.Item value=\"system\">System</Select.Item>\n </Select>\n </Card.Body>\n </Card>\n\n <Separator />\n <Button variant=\"primary\" type=\"submit\">Save Changes</Button>\n</Grid>","tags":["settings","preferences","form","toggle","layout"]}}}
|