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,445 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { Button } from './Button'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Button Primitive Stories
|
|
6
|
+
*
|
|
7
|
+
* The Button component is a foundational primitive for triggering actions and navigation.
|
|
8
|
+
* It extends shadcn/ui's Button with design system-specific enhancements and maintains
|
|
9
|
+
* full accessibility compliance (WCAG 2.1 Level AA).
|
|
10
|
+
*
|
|
11
|
+
* ## Features
|
|
12
|
+
* - Multiple visual variants for different contexts
|
|
13
|
+
* - Flexible sizing options including icon-only buttons
|
|
14
|
+
* - Full keyboard navigation support
|
|
15
|
+
* - ARIA attributes for screen readers
|
|
16
|
+
* - Dark mode support
|
|
17
|
+
* - Composition via asChild prop (Radix Slot)
|
|
18
|
+
*
|
|
19
|
+
* ## Accessibility
|
|
20
|
+
* - Semantic `<button>` element by default
|
|
21
|
+
* - Proper focus management with visible focus indicators
|
|
22
|
+
* - Disabled state prevents interaction and is announced to screen readers
|
|
23
|
+
* - Loading states should include aria-busy and descriptive text
|
|
24
|
+
*
|
|
25
|
+
* ## Usage Guidelines
|
|
26
|
+
*
|
|
27
|
+
* ### Do's
|
|
28
|
+
* - Use descriptive button text that clearly indicates the action
|
|
29
|
+
* - Use the `default` variant for primary actions
|
|
30
|
+
* - Use `destructive` variant for irreversible or dangerous actions
|
|
31
|
+
* - Use `outline` or `ghost` for secondary actions
|
|
32
|
+
* - Provide adequate touch target size (minimum 44x44px)
|
|
33
|
+
*
|
|
34
|
+
* ### Don'ts
|
|
35
|
+
* - Don't use buttons for navigation (use links with asChild instead)
|
|
36
|
+
* - Don't rely on color alone to convey meaning
|
|
37
|
+
* - Don't disable buttons without explanation (consider tooltip)
|
|
38
|
+
* - Don't use icon-only buttons without accessible labels
|
|
39
|
+
*/
|
|
40
|
+
const meta = {
|
|
41
|
+
title: 'Primitives/Button',
|
|
42
|
+
component: Button,
|
|
43
|
+
tags: ['autodocs'],
|
|
44
|
+
argTypes: {
|
|
45
|
+
variant: {
|
|
46
|
+
control: 'select',
|
|
47
|
+
options: ['default', 'destructive', 'outline', 'secondary', 'ghost', 'link'],
|
|
48
|
+
description: 'Visual style variant of the button',
|
|
49
|
+
table: {
|
|
50
|
+
type: { summary: 'string' },
|
|
51
|
+
defaultValue: { summary: 'default' },
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
size: {
|
|
55
|
+
control: 'select',
|
|
56
|
+
options: ['default', 'sm', 'lg', 'icon', 'icon-sm', 'icon-lg'],
|
|
57
|
+
description: 'Size variant of the button',
|
|
58
|
+
table: {
|
|
59
|
+
type: { summary: 'string' },
|
|
60
|
+
defaultValue: { summary: 'default' },
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
disabled: {
|
|
64
|
+
control: 'boolean',
|
|
65
|
+
description: 'Disables the button and prevents interaction',
|
|
66
|
+
table: {
|
|
67
|
+
type: { summary: 'boolean' },
|
|
68
|
+
defaultValue: { summary: 'false' },
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
asChild: {
|
|
72
|
+
control: 'boolean',
|
|
73
|
+
description: 'Renders as a child element using Radix Slot',
|
|
74
|
+
table: {
|
|
75
|
+
type: { summary: 'boolean' },
|
|
76
|
+
defaultValue: { summary: 'false' },
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
parameters: {
|
|
81
|
+
layout: 'centered',
|
|
82
|
+
docs: {
|
|
83
|
+
description: {
|
|
84
|
+
component: 'A versatile button component with multiple variants and sizes, built on shadcn/ui foundation.',
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
} satisfies Meta<typeof Button>
|
|
89
|
+
|
|
90
|
+
export default meta
|
|
91
|
+
type Story = StoryObj<typeof meta>
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Default button variant
|
|
95
|
+
*
|
|
96
|
+
* The default variant is used for primary actions that are most important
|
|
97
|
+
* on the current screen. Use sparingly to maintain visual hierarchy.
|
|
98
|
+
*/
|
|
99
|
+
export const Default: Story = {
|
|
100
|
+
args: {
|
|
101
|
+
children: 'Button',
|
|
102
|
+
variant: 'default',
|
|
103
|
+
size: 'default',
|
|
104
|
+
},
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Destructive variant
|
|
109
|
+
*
|
|
110
|
+
* Used for dangerous or irreversible actions like deletions.
|
|
111
|
+
* The red color signals caution to users before proceeding.
|
|
112
|
+
*/
|
|
113
|
+
export const Destructive: Story = {
|
|
114
|
+
args: {
|
|
115
|
+
children: 'Delete',
|
|
116
|
+
variant: 'destructive',
|
|
117
|
+
size: 'default',
|
|
118
|
+
},
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Outline variant
|
|
123
|
+
*
|
|
124
|
+
* Used for secondary actions that are less important than the primary action.
|
|
125
|
+
* Provides clear boundaries with a lighter visual weight.
|
|
126
|
+
*/
|
|
127
|
+
export const Outline: Story = {
|
|
128
|
+
args: {
|
|
129
|
+
children: 'Outline',
|
|
130
|
+
variant: 'outline',
|
|
131
|
+
size: 'default',
|
|
132
|
+
},
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Secondary variant
|
|
137
|
+
*
|
|
138
|
+
* Used for alternative actions that complement the primary action.
|
|
139
|
+
* Provides a middle ground between default and ghost variants.
|
|
140
|
+
*/
|
|
141
|
+
export const Secondary: Story = {
|
|
142
|
+
args: {
|
|
143
|
+
children: 'Secondary',
|
|
144
|
+
variant: 'secondary',
|
|
145
|
+
size: 'default',
|
|
146
|
+
},
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Ghost variant
|
|
151
|
+
*
|
|
152
|
+
* Used for tertiary actions with minimal visual weight.
|
|
153
|
+
* Appears on hover to reduce visual clutter.
|
|
154
|
+
*/
|
|
155
|
+
export const Ghost: Story = {
|
|
156
|
+
args: {
|
|
157
|
+
children: 'Ghost',
|
|
158
|
+
variant: 'ghost',
|
|
159
|
+
size: 'default',
|
|
160
|
+
},
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Link variant
|
|
165
|
+
*
|
|
166
|
+
* Styled to look like a hyperlink while maintaining button semantics.
|
|
167
|
+
* Use for actions that feel more like navigation.
|
|
168
|
+
*/
|
|
169
|
+
export const Link: Story = {
|
|
170
|
+
args: {
|
|
171
|
+
children: 'Link',
|
|
172
|
+
variant: 'link',
|
|
173
|
+
size: 'default',
|
|
174
|
+
},
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Small size
|
|
179
|
+
*
|
|
180
|
+
* Compact button for tight spaces or less important actions.
|
|
181
|
+
*/
|
|
182
|
+
export const Small: Story = {
|
|
183
|
+
args: {
|
|
184
|
+
children: 'Small Button',
|
|
185
|
+
variant: 'default',
|
|
186
|
+
size: 'sm',
|
|
187
|
+
},
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Large size
|
|
192
|
+
*
|
|
193
|
+
* Prominent button for important calls to action.
|
|
194
|
+
* Provides larger touch targets for better mobile accessibility.
|
|
195
|
+
*/
|
|
196
|
+
export const Large: Story = {
|
|
197
|
+
args: {
|
|
198
|
+
children: 'Large Button',
|
|
199
|
+
variant: 'default',
|
|
200
|
+
size: 'lg',
|
|
201
|
+
},
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Icon size (default)
|
|
206
|
+
*
|
|
207
|
+
* Square button sized for a single icon.
|
|
208
|
+
* Note: This example uses text for demonstration. In production,
|
|
209
|
+
* use the Icon component from the icon registry when available.
|
|
210
|
+
*/
|
|
211
|
+
export const IconSize: Story = {
|
|
212
|
+
args: {
|
|
213
|
+
children: '✓',
|
|
214
|
+
variant: 'default',
|
|
215
|
+
size: 'icon',
|
|
216
|
+
'aria-label': 'Confirm',
|
|
217
|
+
},
|
|
218
|
+
parameters: {
|
|
219
|
+
docs: {
|
|
220
|
+
description: {
|
|
221
|
+
story: 'Icon-only buttons require an accessible label via aria-label prop.',
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Small icon size
|
|
229
|
+
*
|
|
230
|
+
* Compact square button for icon-only actions in dense UIs.
|
|
231
|
+
*/
|
|
232
|
+
export const IconSmall: Story = {
|
|
233
|
+
args: {
|
|
234
|
+
children: '✓',
|
|
235
|
+
variant: 'outline',
|
|
236
|
+
size: 'icon-sm',
|
|
237
|
+
'aria-label': 'Confirm',
|
|
238
|
+
},
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Large icon size
|
|
243
|
+
*
|
|
244
|
+
* Prominent square button for icon-only primary actions.
|
|
245
|
+
*/
|
|
246
|
+
export const IconLarge: Story = {
|
|
247
|
+
args: {
|
|
248
|
+
children: '✓',
|
|
249
|
+
variant: 'default',
|
|
250
|
+
size: 'icon-lg',
|
|
251
|
+
'aria-label': 'Confirm',
|
|
252
|
+
},
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Disabled state
|
|
257
|
+
*
|
|
258
|
+
* Disabled buttons cannot be interacted with and are visually dimmed.
|
|
259
|
+
* Consider providing context about why the button is disabled via tooltip.
|
|
260
|
+
*/
|
|
261
|
+
export const Disabled: Story = {
|
|
262
|
+
args: {
|
|
263
|
+
children: 'Disabled Button',
|
|
264
|
+
variant: 'default',
|
|
265
|
+
size: 'default',
|
|
266
|
+
disabled: true,
|
|
267
|
+
},
|
|
268
|
+
parameters: {
|
|
269
|
+
docs: {
|
|
270
|
+
description: {
|
|
271
|
+
story: 'Disabled buttons should include context about why they are disabled, typically via a tooltip.',
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Disabled destructive
|
|
279
|
+
*
|
|
280
|
+
* Shows how the destructive variant appears when disabled.
|
|
281
|
+
*/
|
|
282
|
+
export const DisabledDestructive: Story = {
|
|
283
|
+
args: {
|
|
284
|
+
children: 'Disabled Delete',
|
|
285
|
+
variant: 'destructive',
|
|
286
|
+
size: 'default',
|
|
287
|
+
disabled: true,
|
|
288
|
+
},
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* All Variants Showcase
|
|
293
|
+
*
|
|
294
|
+
* Displays all button variants side by side for quick comparison.
|
|
295
|
+
* Demonstrates the visual hierarchy and relative prominence of each variant.
|
|
296
|
+
*/
|
|
297
|
+
export const AllVariants: Story = {
|
|
298
|
+
render: () => (
|
|
299
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '24px', alignItems: 'flex-start' }}>
|
|
300
|
+
<div>
|
|
301
|
+
<h3 style={{ marginBottom: '12px', fontSize: '14px', fontWeight: 600 }}>Variants</h3>
|
|
302
|
+
<div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap' }}>
|
|
303
|
+
<Button variant="default">Default</Button>
|
|
304
|
+
<Button variant="destructive">Destructive</Button>
|
|
305
|
+
<Button variant="outline">Outline</Button>
|
|
306
|
+
<Button variant="secondary">Secondary</Button>
|
|
307
|
+
<Button variant="ghost">Ghost</Button>
|
|
308
|
+
<Button variant="link">Link</Button>
|
|
309
|
+
</div>
|
|
310
|
+
</div>
|
|
311
|
+
|
|
312
|
+
<div>
|
|
313
|
+
<h3 style={{ marginBottom: '12px', fontSize: '14px', fontWeight: 600 }}>Sizes</h3>
|
|
314
|
+
<div style={{ display: 'flex', gap: '12px', alignItems: 'center', flexWrap: 'wrap' }}>
|
|
315
|
+
<Button size="sm">Small</Button>
|
|
316
|
+
<Button size="default">Default</Button>
|
|
317
|
+
<Button size="lg">Large</Button>
|
|
318
|
+
</div>
|
|
319
|
+
</div>
|
|
320
|
+
|
|
321
|
+
<div>
|
|
322
|
+
<h3 style={{ marginBottom: '12px', fontSize: '14px', fontWeight: 600 }}>Icon Sizes</h3>
|
|
323
|
+
<div style={{ display: 'flex', gap: '12px', alignItems: 'center', flexWrap: 'wrap' }}>
|
|
324
|
+
<Button size="icon-sm" variant="outline" aria-label="Small icon button">
|
|
325
|
+
✓
|
|
326
|
+
</Button>
|
|
327
|
+
<Button size="icon" variant="outline" aria-label="Default icon button">
|
|
328
|
+
✓
|
|
329
|
+
</Button>
|
|
330
|
+
<Button size="icon-lg" variant="outline" aria-label="Large icon button">
|
|
331
|
+
✓
|
|
332
|
+
</Button>
|
|
333
|
+
</div>
|
|
334
|
+
</div>
|
|
335
|
+
|
|
336
|
+
<div>
|
|
337
|
+
<h3 style={{ marginBottom: '12px', fontSize: '14px', fontWeight: 600 }}>States</h3>
|
|
338
|
+
<div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap' }}>
|
|
339
|
+
<Button>Normal</Button>
|
|
340
|
+
<Button disabled>Disabled</Button>
|
|
341
|
+
</div>
|
|
342
|
+
</div>
|
|
343
|
+
|
|
344
|
+
<div>
|
|
345
|
+
<h3 style={{ marginBottom: '12px', fontSize: '14px', fontWeight: 600 }}>Destructive Variants</h3>
|
|
346
|
+
<div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap' }}>
|
|
347
|
+
<Button variant="destructive">Delete</Button>
|
|
348
|
+
<Button variant="destructive" disabled>
|
|
349
|
+
Delete Disabled
|
|
350
|
+
</Button>
|
|
351
|
+
</div>
|
|
352
|
+
</div>
|
|
353
|
+
</div>
|
|
354
|
+
),
|
|
355
|
+
parameters: {
|
|
356
|
+
docs: {
|
|
357
|
+
description: {
|
|
358
|
+
story: 'Complete showcase of all button variants, sizes, and states available in the design system.',
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
},
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* With Long Text
|
|
366
|
+
*
|
|
367
|
+
* Demonstrates how buttons handle longer text content.
|
|
368
|
+
* The button automatically adjusts width to accommodate content.
|
|
369
|
+
*/
|
|
370
|
+
export const WithLongText: Story = {
|
|
371
|
+
args: {
|
|
372
|
+
children: 'Button with longer text content',
|
|
373
|
+
variant: 'default',
|
|
374
|
+
size: 'default',
|
|
375
|
+
},
|
|
376
|
+
parameters: {
|
|
377
|
+
docs: {
|
|
378
|
+
description: {
|
|
379
|
+
story: 'Buttons automatically expand to fit their content while maintaining consistent padding.',
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
},
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Responsive Layout Example
|
|
387
|
+
*
|
|
388
|
+
* Shows buttons in a typical action layout pattern.
|
|
389
|
+
* Demonstrates proper spacing and alignment for multiple buttons.
|
|
390
|
+
*/
|
|
391
|
+
export const ResponsiveLayout: Story = {
|
|
392
|
+
render: () => (
|
|
393
|
+
<div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap' }}>
|
|
394
|
+
<Button variant="default">Save</Button>
|
|
395
|
+
<Button variant="outline">Cancel</Button>
|
|
396
|
+
<Button variant="ghost">Reset</Button>
|
|
397
|
+
</div>
|
|
398
|
+
),
|
|
399
|
+
parameters: {
|
|
400
|
+
docs: {
|
|
401
|
+
description: {
|
|
402
|
+
story: 'Common layout pattern for form actions or dialog buttons.',
|
|
403
|
+
},
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Dark Mode Preview
|
|
410
|
+
*
|
|
411
|
+
* All variants in dark mode to verify theming compatibility.
|
|
412
|
+
* The Button component automatically adapts to dark mode via Tailwind's dark: variants.
|
|
413
|
+
*/
|
|
414
|
+
export const DarkMode: Story = {
|
|
415
|
+
render: () => (
|
|
416
|
+
<div className="dark" style={{ padding: '24px', background: 'hsl(222.2 84% 4.9%)', borderRadius: '8px' }}>
|
|
417
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
418
|
+
<div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap' }}>
|
|
419
|
+
<Button variant="default">Default</Button>
|
|
420
|
+
<Button variant="destructive">Destructive</Button>
|
|
421
|
+
<Button variant="outline">Outline</Button>
|
|
422
|
+
<Button variant="secondary">Secondary</Button>
|
|
423
|
+
<Button variant="ghost">Ghost</Button>
|
|
424
|
+
<Button variant="link">Link</Button>
|
|
425
|
+
</div>
|
|
426
|
+
<div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap' }}>
|
|
427
|
+
<Button variant="default" disabled>
|
|
428
|
+
Disabled
|
|
429
|
+
</Button>
|
|
430
|
+
<Button variant="outline" disabled>
|
|
431
|
+
Disabled
|
|
432
|
+
</Button>
|
|
433
|
+
</div>
|
|
434
|
+
</div>
|
|
435
|
+
</div>
|
|
436
|
+
),
|
|
437
|
+
parameters: {
|
|
438
|
+
docs: {
|
|
439
|
+
description: {
|
|
440
|
+
story: 'All button variants automatically adapt to dark mode with appropriate contrast and visibility.',
|
|
441
|
+
},
|
|
442
|
+
},
|
|
443
|
+
backgrounds: { disable: true },
|
|
444
|
+
},
|
|
445
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import {
|
|
3
|
+
Button as ShadcnButton,
|
|
4
|
+
buttonVariants,
|
|
5
|
+
} from "../../ui/button"
|
|
6
|
+
import type { VariantProps } from "class-variance-authority"
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Button Primitive
|
|
10
|
+
*
|
|
11
|
+
* A foundational button component that wraps shadcn/ui Button with design system
|
|
12
|
+
* enhancements. This primitive serves as the single source of truth for all button
|
|
13
|
+
* interactions across the application.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* <Button variant="default" size="default">
|
|
18
|
+
* Click me
|
|
19
|
+
* </Button>
|
|
20
|
+
*
|
|
21
|
+
* <Button variant="destructive" size="sm">
|
|
22
|
+
* Delete
|
|
23
|
+
* </Button>
|
|
24
|
+
*
|
|
25
|
+
* <Button variant="outline" size="lg" asChild>
|
|
26
|
+
* <Link href="/home">Go Home</Link>
|
|
27
|
+
* </Button>
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @see https://ui.shadcn.com/docs/components/button - shadcn/ui Button documentation
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Button component props
|
|
35
|
+
* Extends the native button element props with variant and size options
|
|
36
|
+
*/
|
|
37
|
+
export type ButtonProps = React.ComponentProps<"button"> &
|
|
38
|
+
VariantProps<typeof buttonVariants> & {
|
|
39
|
+
/**
|
|
40
|
+
* Renders the button as a child element using Radix Slot.
|
|
41
|
+
* Useful for rendering buttons as links or other custom elements.
|
|
42
|
+
* @default false
|
|
43
|
+
*/
|
|
44
|
+
asChild?: boolean
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Button component
|
|
49
|
+
*
|
|
50
|
+
* A versatile button component with multiple variants and sizes, built on shadcn/ui foundation.
|
|
51
|
+
* Optimized with React.memo for performance in high-frequency rendering scenarios.
|
|
52
|
+
*
|
|
53
|
+
* Features:
|
|
54
|
+
* - Multiple visual variants for different contexts
|
|
55
|
+
* - Flexible sizing options including icon-only buttons
|
|
56
|
+
* - Full keyboard navigation support
|
|
57
|
+
* - ARIA attributes for screen readers
|
|
58
|
+
* - Dark mode support
|
|
59
|
+
* - Composition via asChild prop (Radix Slot)
|
|
60
|
+
*/
|
|
61
|
+
export const Button = React.memo(
|
|
62
|
+
React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
63
|
+
(props, ref) => {
|
|
64
|
+
return <ShadcnButton ref={ref} {...props} />
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
Button.displayName = "Button"
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Re-export buttonVariants for consumers who need direct access to the variant generator.
|
|
73
|
+
* This is useful for creating custom button-like components that need consistent styling.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```tsx
|
|
77
|
+
* import { buttonVariants } from './Button'
|
|
78
|
+
*
|
|
79
|
+
* <div className={buttonVariants({ variant: "outline", size: "sm" })}>
|
|
80
|
+
* Custom button-like div
|
|
81
|
+
* </div>
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export { buttonVariants }
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Re-export VariantProps for type inference in consuming components
|
|
88
|
+
*/
|
|
89
|
+
export type { VariantProps }
|