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,321 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Avatar, AvatarFallback, AvatarImage } from "./Avatar";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Avatar component displays a user profile picture with automatic fallback support.
|
|
6
|
+
*
|
|
7
|
+
* ## Features
|
|
8
|
+
* - Automatic image loading with fallback
|
|
9
|
+
* - Circular design (default) or custom shapes
|
|
10
|
+
* - Size customization
|
|
11
|
+
* - Lazy loading support
|
|
12
|
+
* - Accessible with proper alt text
|
|
13
|
+
* - WCAG 2.1 Level AA compliant
|
|
14
|
+
*
|
|
15
|
+
* ## Usage
|
|
16
|
+
* ```tsx
|
|
17
|
+
* <Avatar>
|
|
18
|
+
* <AvatarImage src="/user.jpg" alt="User Name" />
|
|
19
|
+
* <AvatarFallback>UN</AvatarFallback>
|
|
20
|
+
* </Avatar>
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* ## Accessibility
|
|
24
|
+
* - Always provide alt text for AvatarImage
|
|
25
|
+
* - Fallback should contain initials or descriptive text
|
|
26
|
+
* - Support for screen readers
|
|
27
|
+
*/
|
|
28
|
+
const meta: Meta<typeof Avatar> = {
|
|
29
|
+
title: "Primitives/Avatar",
|
|
30
|
+
component: Avatar,
|
|
31
|
+
parameters: {
|
|
32
|
+
layout: "centered",
|
|
33
|
+
docs: {
|
|
34
|
+
description: {
|
|
35
|
+
component:
|
|
36
|
+
"An image element with a fallback for representing a user or entity.",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
tags: ["autodocs"],
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export default meta;
|
|
44
|
+
type Story = StoryObj<typeof Avatar>;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Default avatar with image
|
|
48
|
+
*/
|
|
49
|
+
export const Default: Story = {
|
|
50
|
+
render: () => (
|
|
51
|
+
<Avatar>
|
|
52
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
|
|
53
|
+
<AvatarFallback>CN</AvatarFallback>
|
|
54
|
+
</Avatar>
|
|
55
|
+
),
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Avatar with fallback (when image fails to load)
|
|
60
|
+
*/
|
|
61
|
+
export const WithFallback: Story = {
|
|
62
|
+
render: () => (
|
|
63
|
+
<Avatar>
|
|
64
|
+
<AvatarImage src="/invalid-image-url.jpg" alt="User" />
|
|
65
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
66
|
+
</Avatar>
|
|
67
|
+
),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Different avatar sizes
|
|
72
|
+
*/
|
|
73
|
+
export const Sizes: Story = {
|
|
74
|
+
render: () => (
|
|
75
|
+
<div className="flex items-center gap-4">
|
|
76
|
+
<Avatar className="size-6">
|
|
77
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="Small" />
|
|
78
|
+
<AvatarFallback className="text-xs">XS</AvatarFallback>
|
|
79
|
+
</Avatar>
|
|
80
|
+
|
|
81
|
+
<Avatar className="size-8">
|
|
82
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="Default" />
|
|
83
|
+
<AvatarFallback className="text-sm">SM</AvatarFallback>
|
|
84
|
+
</Avatar>
|
|
85
|
+
|
|
86
|
+
<Avatar className="size-12">
|
|
87
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="Medium" />
|
|
88
|
+
<AvatarFallback>MD</AvatarFallback>
|
|
89
|
+
</Avatar>
|
|
90
|
+
|
|
91
|
+
<Avatar className="size-16">
|
|
92
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="Large" />
|
|
93
|
+
<AvatarFallback className="text-lg">LG</AvatarFallback>
|
|
94
|
+
</Avatar>
|
|
95
|
+
|
|
96
|
+
<Avatar className="size-24">
|
|
97
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="Extra Large" />
|
|
98
|
+
<AvatarFallback className="text-2xl">XL</AvatarFallback>
|
|
99
|
+
</Avatar>
|
|
100
|
+
</div>
|
|
101
|
+
),
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Avatar with initials fallback
|
|
106
|
+
*/
|
|
107
|
+
export const WithInitials: Story = {
|
|
108
|
+
render: () => (
|
|
109
|
+
<div className="flex gap-4">
|
|
110
|
+
<Avatar>
|
|
111
|
+
<AvatarFallback>AB</AvatarFallback>
|
|
112
|
+
</Avatar>
|
|
113
|
+
|
|
114
|
+
<Avatar>
|
|
115
|
+
<AvatarFallback>CD</AvatarFallback>
|
|
116
|
+
</Avatar>
|
|
117
|
+
|
|
118
|
+
<Avatar>
|
|
119
|
+
<AvatarFallback>EF</AvatarFallback>
|
|
120
|
+
</Avatar>
|
|
121
|
+
|
|
122
|
+
<Avatar>
|
|
123
|
+
<AvatarFallback>GH</AvatarFallback>
|
|
124
|
+
</Avatar>
|
|
125
|
+
</div>
|
|
126
|
+
),
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Avatar with colored backgrounds
|
|
131
|
+
*/
|
|
132
|
+
export const ColoredFallbacks: Story = {
|
|
133
|
+
render: () => (
|
|
134
|
+
<div className="flex gap-4">
|
|
135
|
+
<Avatar>
|
|
136
|
+
<AvatarFallback className="bg-red-500 text-white">AB</AvatarFallback>
|
|
137
|
+
</Avatar>
|
|
138
|
+
|
|
139
|
+
<Avatar>
|
|
140
|
+
<AvatarFallback className="bg-blue-500 text-white">CD</AvatarFallback>
|
|
141
|
+
</Avatar>
|
|
142
|
+
|
|
143
|
+
<Avatar>
|
|
144
|
+
<AvatarFallback className="bg-green-500 text-white">EF</AvatarFallback>
|
|
145
|
+
</Avatar>
|
|
146
|
+
|
|
147
|
+
<Avatar>
|
|
148
|
+
<AvatarFallback className="bg-purple-500 text-white">GH</AvatarFallback>
|
|
149
|
+
</Avatar>
|
|
150
|
+
|
|
151
|
+
<Avatar>
|
|
152
|
+
<AvatarFallback className="bg-orange-500 text-white">IJ</AvatarFallback>
|
|
153
|
+
</Avatar>
|
|
154
|
+
</div>
|
|
155
|
+
),
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Avatar with icon fallback
|
|
160
|
+
*/
|
|
161
|
+
export const WithIcon: Story = {
|
|
162
|
+
render: () => (
|
|
163
|
+
<div className="flex gap-4">
|
|
164
|
+
<Avatar>
|
|
165
|
+
<AvatarImage src="/invalid.jpg" alt="User" />
|
|
166
|
+
<AvatarFallback>
|
|
167
|
+
<svg
|
|
168
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
169
|
+
width="20"
|
|
170
|
+
height="20"
|
|
171
|
+
viewBox="0 0 24 24"
|
|
172
|
+
fill="none"
|
|
173
|
+
stroke="currentColor"
|
|
174
|
+
strokeWidth="2"
|
|
175
|
+
strokeLinecap="round"
|
|
176
|
+
strokeLinejoin="round"
|
|
177
|
+
>
|
|
178
|
+
<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" />
|
|
179
|
+
<circle cx="12" cy="7" r="4" />
|
|
180
|
+
</svg>
|
|
181
|
+
</AvatarFallback>
|
|
182
|
+
</Avatar>
|
|
183
|
+
|
|
184
|
+
<Avatar className="size-12">
|
|
185
|
+
<AvatarImage src="/invalid.jpg" alt="User" />
|
|
186
|
+
<AvatarFallback>
|
|
187
|
+
<svg
|
|
188
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
189
|
+
width="24"
|
|
190
|
+
height="24"
|
|
191
|
+
viewBox="0 0 24 24"
|
|
192
|
+
fill="none"
|
|
193
|
+
stroke="currentColor"
|
|
194
|
+
strokeWidth="2"
|
|
195
|
+
strokeLinecap="round"
|
|
196
|
+
strokeLinejoin="round"
|
|
197
|
+
>
|
|
198
|
+
<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" />
|
|
199
|
+
<circle cx="12" cy="7" r="4" />
|
|
200
|
+
</svg>
|
|
201
|
+
</AvatarFallback>
|
|
202
|
+
</Avatar>
|
|
203
|
+
</div>
|
|
204
|
+
),
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Avatar group (stacked avatars)
|
|
209
|
+
*/
|
|
210
|
+
export const AvatarGroup: Story = {
|
|
211
|
+
render: () => (
|
|
212
|
+
<div className="flex -space-x-4">
|
|
213
|
+
<Avatar className="border-2 border-background">
|
|
214
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="User 1" />
|
|
215
|
+
<AvatarFallback>U1</AvatarFallback>
|
|
216
|
+
</Avatar>
|
|
217
|
+
<Avatar className="border-2 border-background">
|
|
218
|
+
<AvatarImage src="https://github.com/vercel.png" alt="User 2" />
|
|
219
|
+
<AvatarFallback>U2</AvatarFallback>
|
|
220
|
+
</Avatar>
|
|
221
|
+
<Avatar className="border-2 border-background">
|
|
222
|
+
<AvatarFallback>U3</AvatarFallback>
|
|
223
|
+
</Avatar>
|
|
224
|
+
<Avatar className="border-2 border-background">
|
|
225
|
+
<AvatarFallback>U4</AvatarFallback>
|
|
226
|
+
</Avatar>
|
|
227
|
+
<Avatar className="border-2 border-background">
|
|
228
|
+
<AvatarFallback className="text-xs">+5</AvatarFallback>
|
|
229
|
+
</Avatar>
|
|
230
|
+
</div>
|
|
231
|
+
),
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Avatar with status indicator
|
|
236
|
+
*/
|
|
237
|
+
export const WithStatus: Story = {
|
|
238
|
+
render: () => (
|
|
239
|
+
<div className="flex gap-4">
|
|
240
|
+
<div className="relative">
|
|
241
|
+
<Avatar>
|
|
242
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="Online user" />
|
|
243
|
+
<AvatarFallback>ON</AvatarFallback>
|
|
244
|
+
</Avatar>
|
|
245
|
+
<span className="absolute bottom-0 right-0 block size-3 rounded-full bg-green-500 ring-2 ring-background" />
|
|
246
|
+
</div>
|
|
247
|
+
|
|
248
|
+
<div className="relative">
|
|
249
|
+
<Avatar>
|
|
250
|
+
<AvatarImage src="https://github.com/vercel.png" alt="Away user" />
|
|
251
|
+
<AvatarFallback>AW</AvatarFallback>
|
|
252
|
+
</Avatar>
|
|
253
|
+
<span className="absolute bottom-0 right-0 block size-3 rounded-full bg-yellow-500 ring-2 ring-background" />
|
|
254
|
+
</div>
|
|
255
|
+
|
|
256
|
+
<div className="relative">
|
|
257
|
+
<Avatar>
|
|
258
|
+
<AvatarFallback>OF</AvatarFallback>
|
|
259
|
+
</Avatar>
|
|
260
|
+
<span className="absolute bottom-0 right-0 block size-3 rounded-full bg-gray-400 ring-2 ring-background" />
|
|
261
|
+
</div>
|
|
262
|
+
|
|
263
|
+
<div className="relative">
|
|
264
|
+
<Avatar>
|
|
265
|
+
<AvatarFallback>DND</AvatarFallback>
|
|
266
|
+
</Avatar>
|
|
267
|
+
<span className="absolute bottom-0 right-0 block size-3 rounded-full bg-red-500 ring-2 ring-background" />
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
),
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Square avatar (custom shape)
|
|
275
|
+
*/
|
|
276
|
+
export const SquareShape: Story = {
|
|
277
|
+
render: () => (
|
|
278
|
+
<div className="flex gap-4">
|
|
279
|
+
<Avatar className="rounded-md">
|
|
280
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="Square avatar" />
|
|
281
|
+
<AvatarFallback>SQ</AvatarFallback>
|
|
282
|
+
</Avatar>
|
|
283
|
+
|
|
284
|
+
<Avatar className="rounded-lg size-12">
|
|
285
|
+
<AvatarImage src="https://github.com/vercel.png" alt="Rounded square" />
|
|
286
|
+
<AvatarFallback>RS</AvatarFallback>
|
|
287
|
+
</Avatar>
|
|
288
|
+
|
|
289
|
+
<Avatar className="rounded-none size-12">
|
|
290
|
+
<AvatarFallback>NS</AvatarFallback>
|
|
291
|
+
</Avatar>
|
|
292
|
+
</div>
|
|
293
|
+
),
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Dark mode support
|
|
298
|
+
*/
|
|
299
|
+
export const DarkMode: Story = {
|
|
300
|
+
parameters: {
|
|
301
|
+
backgrounds: { default: "dark" },
|
|
302
|
+
},
|
|
303
|
+
render: () => (
|
|
304
|
+
<div className="dark flex gap-4">
|
|
305
|
+
<Avatar>
|
|
306
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="Dark mode" />
|
|
307
|
+
<AvatarFallback>DM</AvatarFallback>
|
|
308
|
+
</Avatar>
|
|
309
|
+
|
|
310
|
+
<Avatar>
|
|
311
|
+
<AvatarFallback>AB</AvatarFallback>
|
|
312
|
+
</Avatar>
|
|
313
|
+
|
|
314
|
+
<Avatar>
|
|
315
|
+
<AvatarFallback className="bg-primary text-primary-foreground">
|
|
316
|
+
CD
|
|
317
|
+
</AvatarFallback>
|
|
318
|
+
</Avatar>
|
|
319
|
+
</div>
|
|
320
|
+
),
|
|
321
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import {
|
|
5
|
+
Avatar as ShadcnAvatar,
|
|
6
|
+
AvatarImage as ShadcnAvatarImage,
|
|
7
|
+
AvatarFallback as ShadcnAvatarFallback,
|
|
8
|
+
} from "@/components/ui/avatar";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Avatar Primitive
|
|
12
|
+
*
|
|
13
|
+
* An image element with a fallback for representing a user or entity.
|
|
14
|
+
*
|
|
15
|
+
* Features:
|
|
16
|
+
* - Automatic image loading with fallback
|
|
17
|
+
* - Circular or custom shape support
|
|
18
|
+
* - Size customization via className
|
|
19
|
+
* - Lazy loading support
|
|
20
|
+
* - WCAG 2.1 Level AA compliant
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
export type AvatarProps = React.ComponentProps<typeof ShadcnAvatar>;
|
|
24
|
+
export type AvatarImageProps = React.ComponentProps<typeof ShadcnAvatarImage>;
|
|
25
|
+
export type AvatarFallbackProps = React.ComponentProps<typeof ShadcnAvatarFallback>;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Avatar - Root container for the avatar component
|
|
29
|
+
*/
|
|
30
|
+
export const Avatar = React.memo<AvatarProps>(
|
|
31
|
+
React.forwardRef<React.ElementRef<typeof ShadcnAvatar>, AvatarProps>(
|
|
32
|
+
(props, ref) => {
|
|
33
|
+
return <ShadcnAvatar ref={ref} {...props} />;
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
);
|
|
37
|
+
Avatar.displayName = "Avatar";
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* AvatarImage - The image element
|
|
41
|
+
* Falls back to AvatarFallback if image fails to load
|
|
42
|
+
*/
|
|
43
|
+
export const AvatarImage = React.memo<AvatarImageProps>(
|
|
44
|
+
React.forwardRef<React.ElementRef<typeof ShadcnAvatarImage>, AvatarImageProps>(
|
|
45
|
+
(props, ref) => {
|
|
46
|
+
return <ShadcnAvatarImage ref={ref} {...props} />;
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
);
|
|
50
|
+
AvatarImage.displayName = "AvatarImage";
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* AvatarFallback - Fallback content when image is unavailable
|
|
54
|
+
* Typically displays initials or an icon
|
|
55
|
+
*/
|
|
56
|
+
export const AvatarFallback = React.memo<AvatarFallbackProps>(
|
|
57
|
+
React.forwardRef<React.ElementRef<typeof ShadcnAvatarFallback>, AvatarFallbackProps>(
|
|
58
|
+
(props, ref) => {
|
|
59
|
+
return <ShadcnAvatarFallback ref={ref} {...props} />;
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
);
|
|
63
|
+
AvatarFallback.displayName = "AvatarFallback";
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
import { Badge } from "./Badge"
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: "Primitives/Badge",
|
|
6
|
+
component: Badge,
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: "centered",
|
|
9
|
+
},
|
|
10
|
+
tags: ["autodocs"],
|
|
11
|
+
} satisfies Meta<typeof Badge>
|
|
12
|
+
|
|
13
|
+
export default meta
|
|
14
|
+
type Story = StoryObj<typeof meta>
|
|
15
|
+
|
|
16
|
+
export const Default: Story = {
|
|
17
|
+
render: () => <Badge>Default</Badge>,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const Secondary: Story = {
|
|
21
|
+
render: () => <Badge variant="secondary">Secondary</Badge>,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const Destructive: Story = {
|
|
25
|
+
render: () => <Badge variant="destructive">Destructive</Badge>,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const Outline: Story = {
|
|
29
|
+
render: () => <Badge variant="outline">Outline</Badge>,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const AllVariants: Story = {
|
|
33
|
+
render: () => (
|
|
34
|
+
<div className="flex gap-2 flex-wrap">
|
|
35
|
+
<Badge>Default</Badge>
|
|
36
|
+
<Badge variant="secondary">Secondary</Badge>
|
|
37
|
+
<Badge variant="destructive">Destructive</Badge>
|
|
38
|
+
<Badge variant="outline">Outline</Badge>
|
|
39
|
+
</div>
|
|
40
|
+
),
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const WithIcons: Story = {
|
|
44
|
+
render: () => (
|
|
45
|
+
<div className="flex gap-2 flex-wrap">
|
|
46
|
+
<Badge>
|
|
47
|
+
<span className="size-2 rounded-full bg-green-500" />
|
|
48
|
+
Active
|
|
49
|
+
</Badge>
|
|
50
|
+
<Badge variant="secondary">
|
|
51
|
+
<span className="size-2 rounded-full bg-yellow-500" />
|
|
52
|
+
Pending
|
|
53
|
+
</Badge>
|
|
54
|
+
<Badge variant="destructive">
|
|
55
|
+
<span className="size-2 rounded-full bg-white" />
|
|
56
|
+
Inactive
|
|
57
|
+
</Badge>
|
|
58
|
+
</div>
|
|
59
|
+
),
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const DarkMode: Story = {
|
|
63
|
+
parameters: {
|
|
64
|
+
backgrounds: { default: "dark" },
|
|
65
|
+
},
|
|
66
|
+
render: () => (
|
|
67
|
+
<div className="dark flex gap-2">
|
|
68
|
+
<Badge>Default</Badge>
|
|
69
|
+
<Badge variant="secondary">Secondary</Badge>
|
|
70
|
+
<Badge variant="destructive">Destructive</Badge>
|
|
71
|
+
<Badge variant="outline">Outline</Badge>
|
|
72
|
+
</div>
|
|
73
|
+
),
|
|
74
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Badge as ShadcnBadge, badgeVariants } from "../../ui/badge"
|
|
3
|
+
import type { VariantProps } from "class-variance-authority"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Badge Primitive
|
|
7
|
+
*
|
|
8
|
+
* A small status indicator component for labels, counts, and status.
|
|
9
|
+
* Built with CVA for variant management.
|
|
10
|
+
*
|
|
11
|
+
* @see https://ui.shadcn.com/docs/components/badge
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export type BadgeProps = React.ComponentProps<"span"> &
|
|
15
|
+
VariantProps<typeof badgeVariants> & {
|
|
16
|
+
asChild?: boolean
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Badge component
|
|
21
|
+
*
|
|
22
|
+
* A small status indicator component for labels, counts, and status.
|
|
23
|
+
* Optimized with React.memo for performance in high-frequency rendering scenarios.
|
|
24
|
+
*
|
|
25
|
+
* Features:
|
|
26
|
+
* - Multiple variants for different contexts (default, secondary, destructive, outline)
|
|
27
|
+
* - Flexible sizing and composition
|
|
28
|
+
* - Dark mode support
|
|
29
|
+
* - Can be rendered as a child element using asChild prop
|
|
30
|
+
*/
|
|
31
|
+
export const Badge = React.memo(
|
|
32
|
+
React.forwardRef<HTMLSpanElement, BadgeProps>(
|
|
33
|
+
(props, ref) => {
|
|
34
|
+
return <ShadcnBadge ref={ref} {...props} />
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
Badge.displayName = "Badge"
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Re-export badgeVariants for consumers who need direct access to the variant generator.
|
|
43
|
+
*/
|
|
44
|
+
export { badgeVariants }
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Re-export VariantProps for type inference in consuming components
|
|
48
|
+
*/
|
|
49
|
+
export type { VariantProps }
|