ai-design-system 0.1.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/README.md +307 -0
- package/components/ai-elements/actions.tsx +65 -0
- package/components/ai-elements/artifact.tsx +147 -0
- package/components/ai-elements/branch.tsx +212 -0
- package/components/ai-elements/canvas.tsx +24 -0
- package/components/ai-elements/chain-of-thought.tsx +228 -0
- package/components/ai-elements/code-block.tsx +179 -0
- package/components/ai-elements/confirmation.tsx +169 -0
- package/components/ai-elements/connection.tsx +28 -0
- package/components/ai-elements/context.tsx +408 -0
- package/components/ai-elements/controls.tsx +18 -0
- package/components/ai-elements/conversation.tsx +97 -0
- package/components/ai-elements/edge.tsx +140 -0
- package/components/ai-elements/image.tsx +24 -0
- package/components/ai-elements/inline-citation.tsx +287 -0
- package/components/ai-elements/loader.tsx +96 -0
- package/components/ai-elements/message.tsx +80 -0
- package/components/ai-elements/node.tsx +71 -0
- package/components/ai-elements/open-in-chat.tsx +363 -0
- package/components/ai-elements/panel.tsx +15 -0
- package/components/ai-elements/plan.tsx +142 -0
- package/components/ai-elements/prompt-input.tsx +1352 -0
- package/components/ai-elements/queue.tsx +274 -0
- package/components/ai-elements/reasoning.tsx +178 -0
- package/components/ai-elements/response.tsx +22 -0
- package/components/ai-elements/shimmer.tsx +64 -0
- package/components/ai-elements/sources.tsx +77 -0
- package/components/ai-elements/suggestion.tsx +56 -0
- package/components/ai-elements/task.tsx +87 -0
- package/components/ai-elements/tool.tsx +179 -0
- package/components/ai-elements/toolbar.tsx +16 -0
- package/components/ai-elements/web-preview.tsx +263 -0
- package/components/blocks/AIConversation/AIConversation.stories.tsx +164 -0
- package/components/blocks/AIConversation/AIConversation.tsx +186 -0
- package/components/blocks/AIConversation/index.ts +8 -0
- package/components/blocks/AppSidebar/AppSidebar.stories.tsx +63 -0
- package/components/blocks/AppSidebar/AppSidebar.tsx +87 -0
- package/components/blocks/AppSidebar/index.ts +2 -0
- package/components/blocks/DocumentEditorWithComments/DocumentEditorWithComments.stories.tsx +341 -0
- package/components/blocks/DocumentEditorWithComments/DocumentEditorWithComments.tsx +255 -0
- package/components/blocks/DocumentEditorWithComments/index.ts +9 -0
- package/components/blocks/FileChangeQueue/FileChangeQueue.stories.tsx +207 -0
- package/components/blocks/FileChangeQueue/FileChangeQueue.tsx +143 -0
- package/components/blocks/FileChangeQueue/index.ts +7 -0
- package/components/blocks/LayoutProvider/LayoutProvider.tsx +34 -0
- package/components/blocks/LayoutProvider/index.ts +1 -0
- package/components/blocks/index.ts +2 -0
- package/components/composites/AgentIndicator/AgentIndicator.stories.tsx +154 -0
- package/components/composites/AgentIndicator/AgentIndicator.tsx +102 -0
- package/components/composites/AgentIndicator/index.ts +8 -0
- package/components/composites/AppHeader/AppHeader.stories.tsx +46 -0
- package/components/composites/AppHeader/AppHeader.tsx +24 -0
- package/components/composites/AppHeader/index.ts +2 -0
- package/components/composites/CommentBox/CommentBox.stories.tsx +192 -0
- package/components/composites/CommentBox/CommentBox.tsx +364 -0
- package/components/composites/CommentBox/index.ts +8 -0
- package/components/composites/Confirmation/Confirmation.stories.tsx +151 -0
- package/components/composites/Confirmation/Confirmation.tsx +93 -0
- package/components/composites/Confirmation/index.ts +7 -0
- package/components/composites/DataTable/DataTable.stories.tsx +35 -0
- package/components/composites/DataTable/DataTable.tsx +95 -0
- package/components/composites/DataTable/index.ts +2 -0
- package/components/composites/DocumentEditor/DocumentEditor.css +106 -0
- package/components/composites/DocumentEditor/DocumentEditor.stories.tsx +927 -0
- package/components/composites/DocumentEditor/DocumentEditor.tsx +279 -0
- package/components/composites/DocumentEditor/index.ts +8 -0
- package/components/composites/FileQueue/FileQueue.stories.tsx +175 -0
- package/components/composites/FileQueue/FileQueue.tsx +161 -0
- package/components/composites/FileQueue/FileStatusBadge.tsx +74 -0
- package/components/composites/FileQueue/index.ts +24 -0
- package/components/composites/InteractiveChart/InteractiveChart.stories.tsx +49 -0
- package/components/composites/InteractiveChart/InteractiveChart.tsx +69 -0
- package/components/composites/InteractiveChart/index.ts +2 -0
- package/components/composites/ModeToggle/ModeToggle.stories.tsx +212 -0
- package/components/composites/ModeToggle/ModeToggle.tsx +100 -0
- package/components/composites/ModeToggle/index.ts +7 -0
- package/components/composites/NavUser/NavUser.stories.tsx +50 -0
- package/components/composites/NavUser/NavUser.tsx +60 -0
- package/components/composites/NavUser/index.ts +2 -0
- package/components/composites/NavigationList/NavigationList.stories.tsx +46 -0
- package/components/composites/NavigationList/NavigationList.tsx +46 -0
- package/components/composites/NavigationList/index.ts +2 -0
- package/components/composites/OrchestratorMessage/OrchestratorMessage.stories.tsx +188 -0
- package/components/composites/OrchestratorMessage/OrchestratorMessage.tsx +72 -0
- package/components/composites/OrchestratorMessage/index.ts +8 -0
- package/components/composites/PageContainer/PageContainer.stories.tsx +41 -0
- package/components/composites/PageContainer/PageContainer.tsx +24 -0
- package/components/composites/PageContainer/index.ts +2 -0
- package/components/composites/PromptInput/PromptInput.stories.tsx +200 -0
- package/components/composites/PromptInput/PromptInput.tsx +129 -0
- package/components/composites/PromptInput/index.ts +8 -0
- package/components/composites/SpecialistMessage/SpecialistMessage.stories.tsx +286 -0
- package/components/composites/SpecialistMessage/SpecialistMessage.tsx +107 -0
- package/components/composites/SpecialistMessage/index.ts +8 -0
- package/components/composites/StatsCard/StatsCard.stories.tsx +76 -0
- package/components/composites/StatsCard/StatsCard.tsx +81 -0
- package/components/composites/StatsCard/index.ts +2 -0
- package/components/composites/TablePagination/TablePagination.stories.tsx +38 -0
- package/components/composites/TablePagination/TablePagination.tsx +119 -0
- package/components/composites/TablePagination/index.ts +2 -0
- package/components/composites/TableToolbar/TableToolbar.stories.tsx +60 -0
- package/components/composites/TableToolbar/TableToolbar.tsx +66 -0
- package/components/composites/TableToolbar/index.ts +2 -0
- package/components/composites/ThemeSelector/ThemeSelector.stories.tsx +48 -0
- package/components/composites/ThemeSelector/ThemeSelector.tsx +79 -0
- package/components/composites/ThemeSelector/index.ts +2 -0
- package/components/composites/ToolCallDisplay/ToolCallDisplay.stories.tsx +49 -0
- package/components/composites/ToolCallDisplay/ToolCallDisplay.tsx +108 -0
- package/components/composites/ToolCallDisplay/index.ts +8 -0
- package/components/composites/UserMessage/UserMessage.stories.tsx +59 -0
- package/components/composites/UserMessage/UserMessage.tsx +52 -0
- package/components/composites/UserMessage/index.ts +8 -0
- package/components/composites/index.ts +90 -0
- package/components/features/AIDocEditor/AIDocEditor.behaviors.stories.tsx +451 -0
- package/components/features/AIDocEditor/AIDocEditor.mocks.ts +96 -0
- package/components/features/AIDocEditor/AIDocEditor.stories.tsx +140 -0
- package/components/features/AIDocEditor/AIDocEditor.tsx +130 -0
- package/components/features/AIDocEditor/index.ts +8 -0
- package/components/features/AIDocEditor/useAIDocEditor.d.ts +97 -0
- package/components/features/AIDocEditor/useAIDocEditor.mock.ts +83 -0
- package/components/features/PageLayout/PageLayout.behaviors.stories.tsx +119 -0
- package/components/features/PageLayout/PageLayout.mocks.ts +27 -0
- package/components/features/PageLayout/PageLayout.stories.tsx +142 -0
- package/components/features/PageLayout/PageLayout.tsx +94 -0
- package/components/features/PageLayout/index.ts +4 -0
- package/components/features/PageLayout/usePageLayout.d.ts +24 -0
- package/components/features/PageLayout/usePageLayout.mock.ts +19 -0
- package/components/features/RefinementPanel/README.md +189 -0
- package/components/features/RefinementPanel/RefinementPanel.behaviors.stories.tsx +475 -0
- package/components/features/RefinementPanel/RefinementPanel.mocks.ts +131 -0
- package/components/features/RefinementPanel/RefinementPanel.stories.tsx +141 -0
- package/components/features/RefinementPanel/RefinementPanel.tsx +160 -0
- package/components/features/RefinementPanel/index.ts +25 -0
- package/components/features/RefinementPanel/useRefinementPanel.d.ts +74 -0
- package/components/features/RefinementPanel/useRefinementPanel.mock.ts +121 -0
- package/components/features/SpecNavigator/SpecNavigator.behaviors.stories.tsx +379 -0
- package/components/features/SpecNavigator/SpecNavigator.mocks.ts +131 -0
- package/components/features/SpecNavigator/SpecNavigator.stories.tsx +122 -0
- package/components/features/SpecNavigator/SpecNavigator.tsx +43 -0
- package/components/features/SpecNavigator/index.ts +2 -0
- package/components/features/SpecNavigator/useSpecNavigator.d.ts +122 -0
- package/components/features/SpecNavigator/useSpecNavigator.mock.ts +93 -0
- package/components/features/index.ts +18 -0
- package/components/index.ts +14 -0
- package/components/primitives/Accordion/Accordion.stories.tsx +87 -0
- package/components/primitives/Accordion/Accordion.tsx +66 -0
- package/components/primitives/Accordion/index.ts +13 -0
- package/components/primitives/Alert/Alert.stories.tsx +422 -0
- package/components/primitives/Alert/Alert.tsx +61 -0
- package/components/primitives/Alert/index.ts +8 -0
- package/components/primitives/AlertDialog/AlertDialog.stories.tsx +367 -0
- package/components/primitives/AlertDialog/AlertDialog.tsx +182 -0
- package/components/primitives/AlertDialog/index.ts +25 -0
- package/components/primitives/Avatar/Avatar.stories.tsx +321 -0
- package/components/primitives/Avatar/Avatar.tsx +63 -0
- package/components/primitives/Avatar/index.ts +8 -0
- package/components/primitives/Badge/Badge.stories.tsx +74 -0
- package/components/primitives/Badge/Badge.tsx +49 -0
- package/components/primitives/Badge/index.ts +2 -0
- package/components/primitives/Button/Button.stories.tsx +445 -0
- package/components/primitives/Button/Button.tsx +89 -0
- package/components/primitives/Button/index.ts +7 -0
- package/components/primitives/Card/Card.stories.tsx +831 -0
- package/components/primitives/Card/Card.tsx +242 -0
- package/components/primitives/Card/index.ts +30 -0
- package/components/primitives/Carousel/Carousel.stories.tsx +32 -0
- package/components/primitives/Carousel/Carousel.tsx +63 -0
- package/components/primitives/Carousel/index.ts +13 -0
- package/components/primitives/Chart/Chart.stories.tsx +346 -0
- package/components/primitives/Chart/Chart.tsx +117 -0
- package/components/primitives/Chart/index.ts +20 -0
- package/components/primitives/Checkbox/Checkbox.stories.tsx +87 -0
- package/components/primitives/Checkbox/Checkbox.tsx +38 -0
- package/components/primitives/Checkbox/index.ts +2 -0
- package/components/primitives/Collapsible/Collapsible.stories.tsx +38 -0
- package/components/primitives/Collapsible/Collapsible.tsx +39 -0
- package/components/primitives/Collapsible/index.ts +8 -0
- package/components/primitives/Command/Command.stories.tsx +150 -0
- package/components/primitives/Command/Command.tsx +147 -0
- package/components/primitives/Command/index.ts +20 -0
- package/components/primitives/Dialog/Dialog.stories.tsx +390 -0
- package/components/primitives/Dialog/Dialog.tsx +140 -0
- package/components/primitives/Dialog/index.ts +22 -0
- package/components/primitives/Drawer/Drawer.stories.tsx +327 -0
- package/components/primitives/Drawer/Drawer.tsx +208 -0
- package/components/primitives/Drawer/index.ts +27 -0
- package/components/primitives/DropdownMenu/DropdownMenu.stories.tsx +150 -0
- package/components/primitives/DropdownMenu/DropdownMenu.tsx +73 -0
- package/components/primitives/DropdownMenu/index.ts +1 -0
- package/components/primitives/HoverCard/HoverCard.stories.tsx +26 -0
- package/components/primitives/HoverCard/HoverCard.tsx +39 -0
- package/components/primitives/HoverCard/index.ts +8 -0
- package/components/primitives/Icon/Icon.stories.tsx +281 -0
- package/components/primitives/Icon/Icon.tsx +87 -0
- package/components/primitives/Icon/index.ts +8 -0
- package/components/primitives/Input/Input.stories.tsx +370 -0
- package/components/primitives/Input/Input.tsx +88 -0
- package/components/primitives/Input/index.ts +7 -0
- package/components/primitives/InputGroup/InputGroup.stories.tsx +40 -0
- package/components/primitives/InputGroup/InputGroup.tsx +72 -0
- package/components/primitives/InputGroup/index.ts +14 -0
- package/components/primitives/Label/Label.stories.tsx +227 -0
- package/components/primitives/Label/Label.tsx +53 -0
- package/components/primitives/Label/index.ts +7 -0
- package/components/primitives/Popover/Popover.stories.tsx +42 -0
- package/components/primitives/Popover/Popover.tsx +107 -0
- package/components/primitives/Popover/index.ts +2 -0
- package/components/primitives/Progress/Progress.stories.tsx +340 -0
- package/components/primitives/Progress/Progress.tsx +31 -0
- package/components/primitives/Progress/index.ts +1 -0
- package/components/primitives/ScrollArea/ScrollArea.stories.tsx +26 -0
- package/components/primitives/ScrollArea/ScrollArea.tsx +28 -0
- package/components/primitives/ScrollArea/index.ts +6 -0
- package/components/primitives/Select/Select.stories.tsx +288 -0
- package/components/primitives/Select/Select.tsx +162 -0
- package/components/primitives/Select/index.ts +22 -0
- package/components/primitives/Separator/Separator.stories.tsx +264 -0
- package/components/primitives/Separator/Separator.tsx +48 -0
- package/components/primitives/Separator/index.ts +7 -0
- package/components/primitives/Sidebar/Sidebar.stories.tsx +358 -0
- package/components/primitives/Sidebar/Sidebar.tsx +317 -0
- package/components/primitives/Sidebar/index.ts +41 -0
- package/components/primitives/Table/Table.stories.tsx +389 -0
- package/components/primitives/Table/Table.tsx +191 -0
- package/components/primitives/Table/index.ts +26 -0
- package/components/primitives/Tabs/Tabs.stories.tsx +129 -0
- package/components/primitives/Tabs/Tabs.tsx +70 -0
- package/components/primitives/Tabs/index.ts +13 -0
- package/components/primitives/Textarea/Textarea.stories.tsx +358 -0
- package/components/primitives/Textarea/Textarea.tsx +91 -0
- package/components/primitives/Textarea/index.ts +7 -0
- package/components/primitives/ToggleGroup/ToggleGroup.stories.tsx +87 -0
- package/components/primitives/ToggleGroup/ToggleGroup.tsx +52 -0
- package/components/primitives/ToggleGroup/index.ts +6 -0
- package/components/primitives/Tooltip/Tooltip.stories.tsx +336 -0
- package/components/primitives/Tooltip/Tooltip.tsx +78 -0
- package/components/primitives/Tooltip/index.ts +10 -0
- package/components/primitives/index.ts +34 -0
- package/components/ui/accordion.tsx +66 -0
- package/components/ui/alert-dialog.tsx +157 -0
- package/components/ui/alert.tsx +66 -0
- package/components/ui/avatar.tsx +53 -0
- package/components/ui/badge.tsx +46 -0
- package/components/ui/button.tsx +60 -0
- package/components/ui/card.tsx +117 -0
- package/components/ui/carousel.tsx +241 -0
- package/components/ui/chart.tsx +334 -0
- package/components/ui/checkbox.tsx +32 -0
- package/components/ui/collapsible.tsx +33 -0
- package/components/ui/command.tsx +184 -0
- package/components/ui/dialog.tsx +143 -0
- package/components/ui/drawer.tsx +118 -0
- package/components/ui/dropdown-menu.tsx +257 -0
- package/components/ui/hover-card.tsx +44 -0
- package/components/ui/input-group.tsx +170 -0
- package/components/ui/input.tsx +48 -0
- package/components/ui/label.tsx +26 -0
- package/components/ui/popover.tsx +33 -0
- package/components/ui/progress.tsx +31 -0
- package/components/ui/scroll-area.tsx +58 -0
- package/components/ui/select.tsx +187 -0
- package/components/ui/separator.tsx +31 -0
- package/components/ui/sidebar.tsx +577 -0
- package/components/ui/table.tsx +120 -0
- package/components/ui/tabs.tsx +66 -0
- package/components/ui/textarea.tsx +46 -0
- package/components/ui/toggle-group.tsx +83 -0
- package/components/ui/toggle.tsx +47 -0
- package/components/ui/tooltip.tsx +61 -0
- package/dist/index.cjs +7389 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.css +75 -0
- package/dist/index.css.map +1 -0
- package/dist/index.js +7160 -0
- package/dist/index.js.map +1 -0
- package/hooks/useAIDocReviewer.d.ts +0 -0
- package/lib/utils.ts +6 -0
- package/package.json +140 -0
- package/tokens/color/base.json +14 -0
- package/tokens/color/dark.json +40 -0
- package/tokens/color/green.json +21 -0
- package/tokens/color/light.json +52 -0
- package/tokens/color/neutral.json +20 -0
- package/tokens/color/violet.json +21 -0
- package/tokens/spacing.json +22 -0
- package/utils/ai-editor/format-date.ts +41 -0
- package/utils/ai-editor/index.ts +22 -0
- package/utils/ai-editor/type-guards.ts +72 -0
- package/utils/ai-editor/validation.ts +130 -0
- package/utils/editor-annotations.ts +122 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { Label } from './Label'
|
|
3
|
+
import { Input } from '../Input'
|
|
4
|
+
import { Checkbox } from '../Checkbox'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Label Primitive Stories
|
|
8
|
+
*
|
|
9
|
+
* The Label component is a foundational primitive for labeling form controls.
|
|
10
|
+
* It extends shadcn/ui's Label with design system-specific enhancements and maintains
|
|
11
|
+
* full accessibility compliance (WCAG 2.1 Level AA).
|
|
12
|
+
*
|
|
13
|
+
* ## Features
|
|
14
|
+
* - Semantic HTML label element
|
|
15
|
+
* - Proper association with form controls via htmlFor
|
|
16
|
+
* - Consistent typography and spacing
|
|
17
|
+
* - Dark mode support
|
|
18
|
+
* - Disabled state styling via peer selectors
|
|
19
|
+
*
|
|
20
|
+
* ## Accessibility
|
|
21
|
+
* - Uses semantic `<label>` element
|
|
22
|
+
* - Properly associates with form controls via htmlFor attribute
|
|
23
|
+
* - Disabled state is visually indicated and announced to screen readers
|
|
24
|
+
* - Maintains proper color contrast ratios
|
|
25
|
+
*
|
|
26
|
+
* ## Usage Guidelines
|
|
27
|
+
*
|
|
28
|
+
* ### Do's
|
|
29
|
+
* - Always associate labels with form controls using htmlFor
|
|
30
|
+
* - Use clear, concise label text
|
|
31
|
+
* - Place labels above or to the left of form controls
|
|
32
|
+
* - Include required field indicators when appropriate
|
|
33
|
+
*
|
|
34
|
+
* ### Don'ts
|
|
35
|
+
* - Don't use labels without associated form controls
|
|
36
|
+
* - Don't rely on placeholder text as a replacement for labels
|
|
37
|
+
* - Don't use overly technical or ambiguous label text
|
|
38
|
+
*/
|
|
39
|
+
const meta = {
|
|
40
|
+
title: 'Primitives/Label',
|
|
41
|
+
component: Label,
|
|
42
|
+
tags: ['autodocs'],
|
|
43
|
+
argTypes: {
|
|
44
|
+
htmlFor: {
|
|
45
|
+
control: 'text',
|
|
46
|
+
description: 'ID of the form control this label is associated with',
|
|
47
|
+
table: {
|
|
48
|
+
type: { summary: 'string' },
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
parameters: {
|
|
53
|
+
layout: 'centered',
|
|
54
|
+
docs: {
|
|
55
|
+
description: {
|
|
56
|
+
component: 'An accessible label component for form inputs, built on shadcn/ui foundation.',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
} satisfies Meta<typeof Label>
|
|
61
|
+
|
|
62
|
+
export default meta
|
|
63
|
+
type Story = StoryObj<typeof meta>
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Default label
|
|
67
|
+
*
|
|
68
|
+
* Basic label with text content.
|
|
69
|
+
*/
|
|
70
|
+
export const Default: Story = {
|
|
71
|
+
args: {
|
|
72
|
+
children: 'Email Address',
|
|
73
|
+
},
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* With Input
|
|
78
|
+
*
|
|
79
|
+
* Label properly associated with an input field.
|
|
80
|
+
* Clicking the label focuses the input.
|
|
81
|
+
*/
|
|
82
|
+
export const WithInput: Story = {
|
|
83
|
+
render: () => (
|
|
84
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px', minWidth: '300px' }}>
|
|
85
|
+
<Label htmlFor="email">Email Address</Label>
|
|
86
|
+
<Input id="email" type="email" placeholder="Enter your email" />
|
|
87
|
+
</div>
|
|
88
|
+
),
|
|
89
|
+
parameters: {
|
|
90
|
+
docs: {
|
|
91
|
+
description: {
|
|
92
|
+
story: 'The htmlFor attribute creates a proper association between the label and input.',
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* With Checkbox
|
|
100
|
+
*
|
|
101
|
+
* Label associated with a checkbox control.
|
|
102
|
+
*/
|
|
103
|
+
export const WithCheckbox: Story = {
|
|
104
|
+
render: () => (
|
|
105
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
106
|
+
<Checkbox id="terms" />
|
|
107
|
+
<Label htmlFor="terms">Accept terms and conditions</Label>
|
|
108
|
+
</div>
|
|
109
|
+
),
|
|
110
|
+
parameters: {
|
|
111
|
+
docs: {
|
|
112
|
+
description: {
|
|
113
|
+
story: 'Labels can be used with checkboxes for better clickable areas.',
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Required Field
|
|
121
|
+
*
|
|
122
|
+
* Label with required field indicator.
|
|
123
|
+
*/
|
|
124
|
+
export const RequiredField: Story = {
|
|
125
|
+
render: () => (
|
|
126
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px', minWidth: '300px' }}>
|
|
127
|
+
<Label htmlFor="username">
|
|
128
|
+
Username <span style={{ color: 'hsl(var(--destructive))' }}>*</span>
|
|
129
|
+
</Label>
|
|
130
|
+
<Input id="username" type="text" placeholder="Enter username" required />
|
|
131
|
+
</div>
|
|
132
|
+
),
|
|
133
|
+
parameters: {
|
|
134
|
+
docs: {
|
|
135
|
+
description: {
|
|
136
|
+
story: 'Required fields should be clearly indicated with an asterisk or other visual marker.',
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Disabled State
|
|
144
|
+
*
|
|
145
|
+
* Label associated with a disabled input.
|
|
146
|
+
* The label automatically inherits disabled styling via peer selectors.
|
|
147
|
+
*/
|
|
148
|
+
export const DisabledState: Story = {
|
|
149
|
+
render: () => (
|
|
150
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px', minWidth: '300px' }}>
|
|
151
|
+
<Label htmlFor="disabled-input">Disabled Field</Label>
|
|
152
|
+
<Input id="disabled-input" type="text" placeholder="Cannot edit" disabled />
|
|
153
|
+
</div>
|
|
154
|
+
),
|
|
155
|
+
parameters: {
|
|
156
|
+
docs: {
|
|
157
|
+
description: {
|
|
158
|
+
story: 'Labels automatically adjust their appearance when associated with disabled controls.',
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Form Layout Example
|
|
166
|
+
*
|
|
167
|
+
* Multiple labels in a typical form layout.
|
|
168
|
+
*/
|
|
169
|
+
export const FormLayout: Story = {
|
|
170
|
+
render: () => (
|
|
171
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', minWidth: '300px' }}>
|
|
172
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
173
|
+
<Label htmlFor="first-name">First Name</Label>
|
|
174
|
+
<Input id="first-name" type="text" placeholder="John" />
|
|
175
|
+
</div>
|
|
176
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
177
|
+
<Label htmlFor="last-name">Last Name</Label>
|
|
178
|
+
<Input id="last-name" type="text" placeholder="Doe" />
|
|
179
|
+
</div>
|
|
180
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
181
|
+
<Label htmlFor="email-form">Email</Label>
|
|
182
|
+
<Input id="email-form" type="email" placeholder="john.doe@example.com" />
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
),
|
|
186
|
+
parameters: {
|
|
187
|
+
docs: {
|
|
188
|
+
description: {
|
|
189
|
+
story: 'Common form layout pattern with consistent label and input spacing.',
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Dark Mode Preview
|
|
197
|
+
*
|
|
198
|
+
* Labels in dark mode to verify theming compatibility.
|
|
199
|
+
*/
|
|
200
|
+
export const DarkMode: Story = {
|
|
201
|
+
render: () => (
|
|
202
|
+
<div className="dark" style={{ padding: '24px', background: 'hsl(222.2 84% 4.9%)', borderRadius: '8px' }}>
|
|
203
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', minWidth: '300px' }}>
|
|
204
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
205
|
+
<Label htmlFor="dark-email">Email Address</Label>
|
|
206
|
+
<Input id="dark-email" type="email" placeholder="Enter your email" />
|
|
207
|
+
</div>
|
|
208
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
209
|
+
<Label htmlFor="dark-disabled">Disabled Field</Label>
|
|
210
|
+
<Input id="dark-disabled" type="text" placeholder="Cannot edit" disabled />
|
|
211
|
+
</div>
|
|
212
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
213
|
+
<Checkbox id="dark-terms" />
|
|
214
|
+
<Label htmlFor="dark-terms">Accept terms and conditions</Label>
|
|
215
|
+
</div>
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
),
|
|
219
|
+
parameters: {
|
|
220
|
+
docs: {
|
|
221
|
+
description: {
|
|
222
|
+
story: 'Labels automatically adapt to dark mode with appropriate contrast and visibility.',
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
backgrounds: { disable: true },
|
|
226
|
+
},
|
|
227
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Label as ShadcnLabel } from "../../ui/label"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Label Primitive
|
|
6
|
+
*
|
|
7
|
+
* A foundational label component that wraps shadcn/ui Label with design system
|
|
8
|
+
* enhancements. This primitive serves as the single source of truth for all form
|
|
9
|
+
* labels across the application.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <Label htmlFor="email">Email Address</Label>
|
|
14
|
+
* <Input id="email" type="email" />
|
|
15
|
+
*
|
|
16
|
+
* <Label htmlFor="terms">
|
|
17
|
+
* Accept terms and conditions
|
|
18
|
+
* </Label>
|
|
19
|
+
* <Checkbox id="terms" />
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @see https://ui.shadcn.com/docs/components/label - shadcn/ui Label documentation
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Label component props
|
|
27
|
+
* Extends the native label element props
|
|
28
|
+
*/
|
|
29
|
+
export type LabelProps = React.ComponentPropsWithoutRef<typeof ShadcnLabel>
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Label component
|
|
33
|
+
*
|
|
34
|
+
* An accessible label component for form inputs, built on shadcn/ui foundation.
|
|
35
|
+
* Optimized with React.memo for performance in high-frequency rendering scenarios.
|
|
36
|
+
*
|
|
37
|
+
* Features:
|
|
38
|
+
* - Semantic HTML label element
|
|
39
|
+
* - Proper association with form controls via htmlFor
|
|
40
|
+
* - Consistent typography and spacing
|
|
41
|
+
* - Dark mode support
|
|
42
|
+
* - Disabled state styling via peer selectors
|
|
43
|
+
*/
|
|
44
|
+
export const Label = React.memo(
|
|
45
|
+
React.forwardRef<
|
|
46
|
+
React.ElementRef<typeof ShadcnLabel>,
|
|
47
|
+
LabelProps
|
|
48
|
+
>((props, ref) => {
|
|
49
|
+
return <ShadcnLabel ref={ref} {...props} />
|
|
50
|
+
})
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
Label.displayName = "Label"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Popover Stories
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates the Popover primitive component
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
8
|
+
import { Popover, PopoverTrigger, PopoverContent } from './Popover'
|
|
9
|
+
import { Button } from '@/components/primitives/Button'
|
|
10
|
+
|
|
11
|
+
const meta: Meta<typeof Popover> = {
|
|
12
|
+
title: 'Primitives/Popover',
|
|
13
|
+
component: Popover,
|
|
14
|
+
parameters: {
|
|
15
|
+
layout: 'centered',
|
|
16
|
+
},
|
|
17
|
+
tags: ['autodocs'],
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default meta
|
|
21
|
+
type Story = StoryObj<typeof Popover>
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Default popover with button trigger
|
|
25
|
+
*/
|
|
26
|
+
export const Default: Story = {
|
|
27
|
+
render: () => (
|
|
28
|
+
<Popover>
|
|
29
|
+
<PopoverTrigger asChild>
|
|
30
|
+
<Button variant="outline">Open Popover</Button>
|
|
31
|
+
</PopoverTrigger>
|
|
32
|
+
<PopoverContent>
|
|
33
|
+
<div className="space-y-2">
|
|
34
|
+
<h4 className="font-medium">Popover Content</h4>
|
|
35
|
+
<p className="text-sm text-muted-foreground">
|
|
36
|
+
This is a popover with some content inside.
|
|
37
|
+
</p>
|
|
38
|
+
</div>
|
|
39
|
+
</PopoverContent>
|
|
40
|
+
</Popover>
|
|
41
|
+
),
|
|
42
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import {
|
|
3
|
+
Popover as ShadcnPopover,
|
|
4
|
+
PopoverAnchor,
|
|
5
|
+
PopoverContent,
|
|
6
|
+
PopoverTrigger,
|
|
7
|
+
} from "../../ui/popover"
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Popover Primitive
|
|
11
|
+
*
|
|
12
|
+
* A foundational popover component that wraps shadcn/ui Popover with extensibility for
|
|
13
|
+
* design system-specific enhancements. This primitive provides accessible floating content
|
|
14
|
+
* that appears near a trigger element or anchor point.
|
|
15
|
+
*
|
|
16
|
+
* Built on Radix UI Popover primitive with WCAG 2.1 Level AA compliance:
|
|
17
|
+
* - Proper focus management
|
|
18
|
+
* - Keyboard navigation (Escape to close)
|
|
19
|
+
* - Screen reader announcements
|
|
20
|
+
* - Portal rendering for proper layering
|
|
21
|
+
* - Flexible positioning
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```tsx
|
|
25
|
+
* <Popover>
|
|
26
|
+
* <PopoverTrigger asChild>
|
|
27
|
+
* <Button>Open Popover</Button>
|
|
28
|
+
* </PopoverTrigger>
|
|
29
|
+
* <PopoverContent>
|
|
30
|
+
* <div>Popover content</div>
|
|
31
|
+
* </PopoverContent>
|
|
32
|
+
* </Popover>
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @example With anchor positioning
|
|
36
|
+
* ```tsx
|
|
37
|
+
* <Popover>
|
|
38
|
+
* <PopoverAnchor asChild>
|
|
39
|
+
* <div ref={anchorRef}>Anchor element</div>
|
|
40
|
+
* </PopoverAnchor>
|
|
41
|
+
* <PopoverContent>
|
|
42
|
+
* <div>Positioned near anchor</div>
|
|
43
|
+
* </PopoverContent>
|
|
44
|
+
* </Popover>
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @see https://ui.shadcn.com/docs/components/popover - shadcn/ui Popover documentation
|
|
48
|
+
* @see https://www.radix-ui.com/primitives/docs/components/popover - Radix UI Popover primitive
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Popover Root component props
|
|
53
|
+
* Controls the open state and positioning behavior
|
|
54
|
+
*/
|
|
55
|
+
export type PopoverProps = React.ComponentProps<typeof ShadcnPopover>
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* PopoverContent component props
|
|
59
|
+
* Main content container with positioning options
|
|
60
|
+
*/
|
|
61
|
+
export type PopoverContentProps = React.ComponentProps<typeof PopoverContent>
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* PopoverTrigger component props
|
|
65
|
+
* Element that opens the popover
|
|
66
|
+
*/
|
|
67
|
+
export type PopoverTriggerProps = React.ComponentProps<typeof PopoverTrigger>
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* PopoverAnchor component props
|
|
71
|
+
* Element to position the popover near (alternative to trigger)
|
|
72
|
+
*/
|
|
73
|
+
export type PopoverAnchorProps = React.ComponentProps<typeof PopoverAnchor>
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Popover component
|
|
77
|
+
*
|
|
78
|
+
* A popover component built on Radix UI Popover primitive.
|
|
79
|
+
* Provides accessible floating content with flexible positioning.
|
|
80
|
+
*
|
|
81
|
+
* Features:
|
|
82
|
+
* - Focus management
|
|
83
|
+
* - Keyboard navigation (Escape to close)
|
|
84
|
+
* - Screen reader announcements
|
|
85
|
+
* - Portal rendering for proper layering
|
|
86
|
+
* - Flexible positioning (top, right, bottom, left)
|
|
87
|
+
* - Anchor-based positioning
|
|
88
|
+
* - Dark mode support
|
|
89
|
+
*/
|
|
90
|
+
export const Popover = React.forwardRef<
|
|
91
|
+
React.ElementRef<typeof ShadcnPopover>,
|
|
92
|
+
PopoverProps
|
|
93
|
+
>((props, ref) => {
|
|
94
|
+
return <ShadcnPopover {...props} />
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
Popover.displayName = "Popover"
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Re-export all Popover sub-components for composition
|
|
101
|
+
*
|
|
102
|
+
* These components should be used together to build complete popover experiences:
|
|
103
|
+
* - PopoverTrigger: Opens the popover (optional if using anchor)
|
|
104
|
+
* - PopoverAnchor: Element to position near (alternative to trigger)
|
|
105
|
+
* - PopoverContent: Main content container with positioning
|
|
106
|
+
*/
|
|
107
|
+
export { PopoverAnchor, PopoverContent, PopoverTrigger }
|