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.
Files changed (290) hide show
  1. package/README.md +307 -0
  2. package/components/ai-elements/actions.tsx +65 -0
  3. package/components/ai-elements/artifact.tsx +147 -0
  4. package/components/ai-elements/branch.tsx +212 -0
  5. package/components/ai-elements/canvas.tsx +24 -0
  6. package/components/ai-elements/chain-of-thought.tsx +228 -0
  7. package/components/ai-elements/code-block.tsx +179 -0
  8. package/components/ai-elements/confirmation.tsx +169 -0
  9. package/components/ai-elements/connection.tsx +28 -0
  10. package/components/ai-elements/context.tsx +408 -0
  11. package/components/ai-elements/controls.tsx +18 -0
  12. package/components/ai-elements/conversation.tsx +97 -0
  13. package/components/ai-elements/edge.tsx +140 -0
  14. package/components/ai-elements/image.tsx +24 -0
  15. package/components/ai-elements/inline-citation.tsx +287 -0
  16. package/components/ai-elements/loader.tsx +96 -0
  17. package/components/ai-elements/message.tsx +80 -0
  18. package/components/ai-elements/node.tsx +71 -0
  19. package/components/ai-elements/open-in-chat.tsx +363 -0
  20. package/components/ai-elements/panel.tsx +15 -0
  21. package/components/ai-elements/plan.tsx +142 -0
  22. package/components/ai-elements/prompt-input.tsx +1352 -0
  23. package/components/ai-elements/queue.tsx +274 -0
  24. package/components/ai-elements/reasoning.tsx +178 -0
  25. package/components/ai-elements/response.tsx +22 -0
  26. package/components/ai-elements/shimmer.tsx +64 -0
  27. package/components/ai-elements/sources.tsx +77 -0
  28. package/components/ai-elements/suggestion.tsx +56 -0
  29. package/components/ai-elements/task.tsx +87 -0
  30. package/components/ai-elements/tool.tsx +179 -0
  31. package/components/ai-elements/toolbar.tsx +16 -0
  32. package/components/ai-elements/web-preview.tsx +263 -0
  33. package/components/blocks/AIConversation/AIConversation.stories.tsx +164 -0
  34. package/components/blocks/AIConversation/AIConversation.tsx +186 -0
  35. package/components/blocks/AIConversation/index.ts +8 -0
  36. package/components/blocks/AppSidebar/AppSidebar.stories.tsx +63 -0
  37. package/components/blocks/AppSidebar/AppSidebar.tsx +87 -0
  38. package/components/blocks/AppSidebar/index.ts +2 -0
  39. package/components/blocks/DocumentEditorWithComments/DocumentEditorWithComments.stories.tsx +341 -0
  40. package/components/blocks/DocumentEditorWithComments/DocumentEditorWithComments.tsx +255 -0
  41. package/components/blocks/DocumentEditorWithComments/index.ts +9 -0
  42. package/components/blocks/FileChangeQueue/FileChangeQueue.stories.tsx +207 -0
  43. package/components/blocks/FileChangeQueue/FileChangeQueue.tsx +143 -0
  44. package/components/blocks/FileChangeQueue/index.ts +7 -0
  45. package/components/blocks/LayoutProvider/LayoutProvider.tsx +34 -0
  46. package/components/blocks/LayoutProvider/index.ts +1 -0
  47. package/components/blocks/index.ts +2 -0
  48. package/components/composites/AgentIndicator/AgentIndicator.stories.tsx +154 -0
  49. package/components/composites/AgentIndicator/AgentIndicator.tsx +102 -0
  50. package/components/composites/AgentIndicator/index.ts +8 -0
  51. package/components/composites/AppHeader/AppHeader.stories.tsx +46 -0
  52. package/components/composites/AppHeader/AppHeader.tsx +24 -0
  53. package/components/composites/AppHeader/index.ts +2 -0
  54. package/components/composites/CommentBox/CommentBox.stories.tsx +192 -0
  55. package/components/composites/CommentBox/CommentBox.tsx +364 -0
  56. package/components/composites/CommentBox/index.ts +8 -0
  57. package/components/composites/Confirmation/Confirmation.stories.tsx +151 -0
  58. package/components/composites/Confirmation/Confirmation.tsx +93 -0
  59. package/components/composites/Confirmation/index.ts +7 -0
  60. package/components/composites/DataTable/DataTable.stories.tsx +35 -0
  61. package/components/composites/DataTable/DataTable.tsx +95 -0
  62. package/components/composites/DataTable/index.ts +2 -0
  63. package/components/composites/DocumentEditor/DocumentEditor.css +106 -0
  64. package/components/composites/DocumentEditor/DocumentEditor.stories.tsx +927 -0
  65. package/components/composites/DocumentEditor/DocumentEditor.tsx +279 -0
  66. package/components/composites/DocumentEditor/index.ts +8 -0
  67. package/components/composites/FileQueue/FileQueue.stories.tsx +175 -0
  68. package/components/composites/FileQueue/FileQueue.tsx +161 -0
  69. package/components/composites/FileQueue/FileStatusBadge.tsx +74 -0
  70. package/components/composites/FileQueue/index.ts +24 -0
  71. package/components/composites/InteractiveChart/InteractiveChart.stories.tsx +49 -0
  72. package/components/composites/InteractiveChart/InteractiveChart.tsx +69 -0
  73. package/components/composites/InteractiveChart/index.ts +2 -0
  74. package/components/composites/ModeToggle/ModeToggle.stories.tsx +212 -0
  75. package/components/composites/ModeToggle/ModeToggle.tsx +100 -0
  76. package/components/composites/ModeToggle/index.ts +7 -0
  77. package/components/composites/NavUser/NavUser.stories.tsx +50 -0
  78. package/components/composites/NavUser/NavUser.tsx +60 -0
  79. package/components/composites/NavUser/index.ts +2 -0
  80. package/components/composites/NavigationList/NavigationList.stories.tsx +46 -0
  81. package/components/composites/NavigationList/NavigationList.tsx +46 -0
  82. package/components/composites/NavigationList/index.ts +2 -0
  83. package/components/composites/OrchestratorMessage/OrchestratorMessage.stories.tsx +188 -0
  84. package/components/composites/OrchestratorMessage/OrchestratorMessage.tsx +72 -0
  85. package/components/composites/OrchestratorMessage/index.ts +8 -0
  86. package/components/composites/PageContainer/PageContainer.stories.tsx +41 -0
  87. package/components/composites/PageContainer/PageContainer.tsx +24 -0
  88. package/components/composites/PageContainer/index.ts +2 -0
  89. package/components/composites/PromptInput/PromptInput.stories.tsx +200 -0
  90. package/components/composites/PromptInput/PromptInput.tsx +129 -0
  91. package/components/composites/PromptInput/index.ts +8 -0
  92. package/components/composites/SpecialistMessage/SpecialistMessage.stories.tsx +286 -0
  93. package/components/composites/SpecialistMessage/SpecialistMessage.tsx +107 -0
  94. package/components/composites/SpecialistMessage/index.ts +8 -0
  95. package/components/composites/StatsCard/StatsCard.stories.tsx +76 -0
  96. package/components/composites/StatsCard/StatsCard.tsx +81 -0
  97. package/components/composites/StatsCard/index.ts +2 -0
  98. package/components/composites/TablePagination/TablePagination.stories.tsx +38 -0
  99. package/components/composites/TablePagination/TablePagination.tsx +119 -0
  100. package/components/composites/TablePagination/index.ts +2 -0
  101. package/components/composites/TableToolbar/TableToolbar.stories.tsx +60 -0
  102. package/components/composites/TableToolbar/TableToolbar.tsx +66 -0
  103. package/components/composites/TableToolbar/index.ts +2 -0
  104. package/components/composites/ThemeSelector/ThemeSelector.stories.tsx +48 -0
  105. package/components/composites/ThemeSelector/ThemeSelector.tsx +79 -0
  106. package/components/composites/ThemeSelector/index.ts +2 -0
  107. package/components/composites/ToolCallDisplay/ToolCallDisplay.stories.tsx +49 -0
  108. package/components/composites/ToolCallDisplay/ToolCallDisplay.tsx +108 -0
  109. package/components/composites/ToolCallDisplay/index.ts +8 -0
  110. package/components/composites/UserMessage/UserMessage.stories.tsx +59 -0
  111. package/components/composites/UserMessage/UserMessage.tsx +52 -0
  112. package/components/composites/UserMessage/index.ts +8 -0
  113. package/components/composites/index.ts +90 -0
  114. package/components/features/AIDocEditor/AIDocEditor.behaviors.stories.tsx +451 -0
  115. package/components/features/AIDocEditor/AIDocEditor.mocks.ts +96 -0
  116. package/components/features/AIDocEditor/AIDocEditor.stories.tsx +140 -0
  117. package/components/features/AIDocEditor/AIDocEditor.tsx +130 -0
  118. package/components/features/AIDocEditor/index.ts +8 -0
  119. package/components/features/AIDocEditor/useAIDocEditor.d.ts +97 -0
  120. package/components/features/AIDocEditor/useAIDocEditor.mock.ts +83 -0
  121. package/components/features/PageLayout/PageLayout.behaviors.stories.tsx +119 -0
  122. package/components/features/PageLayout/PageLayout.mocks.ts +27 -0
  123. package/components/features/PageLayout/PageLayout.stories.tsx +142 -0
  124. package/components/features/PageLayout/PageLayout.tsx +94 -0
  125. package/components/features/PageLayout/index.ts +4 -0
  126. package/components/features/PageLayout/usePageLayout.d.ts +24 -0
  127. package/components/features/PageLayout/usePageLayout.mock.ts +19 -0
  128. package/components/features/RefinementPanel/README.md +189 -0
  129. package/components/features/RefinementPanel/RefinementPanel.behaviors.stories.tsx +475 -0
  130. package/components/features/RefinementPanel/RefinementPanel.mocks.ts +131 -0
  131. package/components/features/RefinementPanel/RefinementPanel.stories.tsx +141 -0
  132. package/components/features/RefinementPanel/RefinementPanel.tsx +160 -0
  133. package/components/features/RefinementPanel/index.ts +25 -0
  134. package/components/features/RefinementPanel/useRefinementPanel.d.ts +74 -0
  135. package/components/features/RefinementPanel/useRefinementPanel.mock.ts +121 -0
  136. package/components/features/SpecNavigator/SpecNavigator.behaviors.stories.tsx +379 -0
  137. package/components/features/SpecNavigator/SpecNavigator.mocks.ts +131 -0
  138. package/components/features/SpecNavigator/SpecNavigator.stories.tsx +122 -0
  139. package/components/features/SpecNavigator/SpecNavigator.tsx +43 -0
  140. package/components/features/SpecNavigator/index.ts +2 -0
  141. package/components/features/SpecNavigator/useSpecNavigator.d.ts +122 -0
  142. package/components/features/SpecNavigator/useSpecNavigator.mock.ts +93 -0
  143. package/components/features/index.ts +18 -0
  144. package/components/index.ts +14 -0
  145. package/components/primitives/Accordion/Accordion.stories.tsx +87 -0
  146. package/components/primitives/Accordion/Accordion.tsx +66 -0
  147. package/components/primitives/Accordion/index.ts +13 -0
  148. package/components/primitives/Alert/Alert.stories.tsx +422 -0
  149. package/components/primitives/Alert/Alert.tsx +61 -0
  150. package/components/primitives/Alert/index.ts +8 -0
  151. package/components/primitives/AlertDialog/AlertDialog.stories.tsx +367 -0
  152. package/components/primitives/AlertDialog/AlertDialog.tsx +182 -0
  153. package/components/primitives/AlertDialog/index.ts +25 -0
  154. package/components/primitives/Avatar/Avatar.stories.tsx +321 -0
  155. package/components/primitives/Avatar/Avatar.tsx +63 -0
  156. package/components/primitives/Avatar/index.ts +8 -0
  157. package/components/primitives/Badge/Badge.stories.tsx +74 -0
  158. package/components/primitives/Badge/Badge.tsx +49 -0
  159. package/components/primitives/Badge/index.ts +2 -0
  160. package/components/primitives/Button/Button.stories.tsx +445 -0
  161. package/components/primitives/Button/Button.tsx +89 -0
  162. package/components/primitives/Button/index.ts +7 -0
  163. package/components/primitives/Card/Card.stories.tsx +831 -0
  164. package/components/primitives/Card/Card.tsx +242 -0
  165. package/components/primitives/Card/index.ts +30 -0
  166. package/components/primitives/Carousel/Carousel.stories.tsx +32 -0
  167. package/components/primitives/Carousel/Carousel.tsx +63 -0
  168. package/components/primitives/Carousel/index.ts +13 -0
  169. package/components/primitives/Chart/Chart.stories.tsx +346 -0
  170. package/components/primitives/Chart/Chart.tsx +117 -0
  171. package/components/primitives/Chart/index.ts +20 -0
  172. package/components/primitives/Checkbox/Checkbox.stories.tsx +87 -0
  173. package/components/primitives/Checkbox/Checkbox.tsx +38 -0
  174. package/components/primitives/Checkbox/index.ts +2 -0
  175. package/components/primitives/Collapsible/Collapsible.stories.tsx +38 -0
  176. package/components/primitives/Collapsible/Collapsible.tsx +39 -0
  177. package/components/primitives/Collapsible/index.ts +8 -0
  178. package/components/primitives/Command/Command.stories.tsx +150 -0
  179. package/components/primitives/Command/Command.tsx +147 -0
  180. package/components/primitives/Command/index.ts +20 -0
  181. package/components/primitives/Dialog/Dialog.stories.tsx +390 -0
  182. package/components/primitives/Dialog/Dialog.tsx +140 -0
  183. package/components/primitives/Dialog/index.ts +22 -0
  184. package/components/primitives/Drawer/Drawer.stories.tsx +327 -0
  185. package/components/primitives/Drawer/Drawer.tsx +208 -0
  186. package/components/primitives/Drawer/index.ts +27 -0
  187. package/components/primitives/DropdownMenu/DropdownMenu.stories.tsx +150 -0
  188. package/components/primitives/DropdownMenu/DropdownMenu.tsx +73 -0
  189. package/components/primitives/DropdownMenu/index.ts +1 -0
  190. package/components/primitives/HoverCard/HoverCard.stories.tsx +26 -0
  191. package/components/primitives/HoverCard/HoverCard.tsx +39 -0
  192. package/components/primitives/HoverCard/index.ts +8 -0
  193. package/components/primitives/Icon/Icon.stories.tsx +281 -0
  194. package/components/primitives/Icon/Icon.tsx +87 -0
  195. package/components/primitives/Icon/index.ts +8 -0
  196. package/components/primitives/Input/Input.stories.tsx +370 -0
  197. package/components/primitives/Input/Input.tsx +88 -0
  198. package/components/primitives/Input/index.ts +7 -0
  199. package/components/primitives/InputGroup/InputGroup.stories.tsx +40 -0
  200. package/components/primitives/InputGroup/InputGroup.tsx +72 -0
  201. package/components/primitives/InputGroup/index.ts +14 -0
  202. package/components/primitives/Label/Label.stories.tsx +227 -0
  203. package/components/primitives/Label/Label.tsx +53 -0
  204. package/components/primitives/Label/index.ts +7 -0
  205. package/components/primitives/Popover/Popover.stories.tsx +42 -0
  206. package/components/primitives/Popover/Popover.tsx +107 -0
  207. package/components/primitives/Popover/index.ts +2 -0
  208. package/components/primitives/Progress/Progress.stories.tsx +340 -0
  209. package/components/primitives/Progress/Progress.tsx +31 -0
  210. package/components/primitives/Progress/index.ts +1 -0
  211. package/components/primitives/ScrollArea/ScrollArea.stories.tsx +26 -0
  212. package/components/primitives/ScrollArea/ScrollArea.tsx +28 -0
  213. package/components/primitives/ScrollArea/index.ts +6 -0
  214. package/components/primitives/Select/Select.stories.tsx +288 -0
  215. package/components/primitives/Select/Select.tsx +162 -0
  216. package/components/primitives/Select/index.ts +22 -0
  217. package/components/primitives/Separator/Separator.stories.tsx +264 -0
  218. package/components/primitives/Separator/Separator.tsx +48 -0
  219. package/components/primitives/Separator/index.ts +7 -0
  220. package/components/primitives/Sidebar/Sidebar.stories.tsx +358 -0
  221. package/components/primitives/Sidebar/Sidebar.tsx +317 -0
  222. package/components/primitives/Sidebar/index.ts +41 -0
  223. package/components/primitives/Table/Table.stories.tsx +389 -0
  224. package/components/primitives/Table/Table.tsx +191 -0
  225. package/components/primitives/Table/index.ts +26 -0
  226. package/components/primitives/Tabs/Tabs.stories.tsx +129 -0
  227. package/components/primitives/Tabs/Tabs.tsx +70 -0
  228. package/components/primitives/Tabs/index.ts +13 -0
  229. package/components/primitives/Textarea/Textarea.stories.tsx +358 -0
  230. package/components/primitives/Textarea/Textarea.tsx +91 -0
  231. package/components/primitives/Textarea/index.ts +7 -0
  232. package/components/primitives/ToggleGroup/ToggleGroup.stories.tsx +87 -0
  233. package/components/primitives/ToggleGroup/ToggleGroup.tsx +52 -0
  234. package/components/primitives/ToggleGroup/index.ts +6 -0
  235. package/components/primitives/Tooltip/Tooltip.stories.tsx +336 -0
  236. package/components/primitives/Tooltip/Tooltip.tsx +78 -0
  237. package/components/primitives/Tooltip/index.ts +10 -0
  238. package/components/primitives/index.ts +34 -0
  239. package/components/ui/accordion.tsx +66 -0
  240. package/components/ui/alert-dialog.tsx +157 -0
  241. package/components/ui/alert.tsx +66 -0
  242. package/components/ui/avatar.tsx +53 -0
  243. package/components/ui/badge.tsx +46 -0
  244. package/components/ui/button.tsx +60 -0
  245. package/components/ui/card.tsx +117 -0
  246. package/components/ui/carousel.tsx +241 -0
  247. package/components/ui/chart.tsx +334 -0
  248. package/components/ui/checkbox.tsx +32 -0
  249. package/components/ui/collapsible.tsx +33 -0
  250. package/components/ui/command.tsx +184 -0
  251. package/components/ui/dialog.tsx +143 -0
  252. package/components/ui/drawer.tsx +118 -0
  253. package/components/ui/dropdown-menu.tsx +257 -0
  254. package/components/ui/hover-card.tsx +44 -0
  255. package/components/ui/input-group.tsx +170 -0
  256. package/components/ui/input.tsx +48 -0
  257. package/components/ui/label.tsx +26 -0
  258. package/components/ui/popover.tsx +33 -0
  259. package/components/ui/progress.tsx +31 -0
  260. package/components/ui/scroll-area.tsx +58 -0
  261. package/components/ui/select.tsx +187 -0
  262. package/components/ui/separator.tsx +31 -0
  263. package/components/ui/sidebar.tsx +577 -0
  264. package/components/ui/table.tsx +120 -0
  265. package/components/ui/tabs.tsx +66 -0
  266. package/components/ui/textarea.tsx +46 -0
  267. package/components/ui/toggle-group.tsx +83 -0
  268. package/components/ui/toggle.tsx +47 -0
  269. package/components/ui/tooltip.tsx +61 -0
  270. package/dist/index.cjs +7389 -0
  271. package/dist/index.cjs.map +1 -0
  272. package/dist/index.css +75 -0
  273. package/dist/index.css.map +1 -0
  274. package/dist/index.js +7160 -0
  275. package/dist/index.js.map +1 -0
  276. package/hooks/useAIDocReviewer.d.ts +0 -0
  277. package/lib/utils.ts +6 -0
  278. package/package.json +140 -0
  279. package/tokens/color/base.json +14 -0
  280. package/tokens/color/dark.json +40 -0
  281. package/tokens/color/green.json +21 -0
  282. package/tokens/color/light.json +52 -0
  283. package/tokens/color/neutral.json +20 -0
  284. package/tokens/color/violet.json +21 -0
  285. package/tokens/spacing.json +22 -0
  286. package/utils/ai-editor/format-date.ts +41 -0
  287. package/utils/ai-editor/index.ts +22 -0
  288. package/utils/ai-editor/type-guards.ts +72 -0
  289. package/utils/ai-editor/validation.ts +130 -0
  290. 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,8 @@
1
+ export {
2
+ Avatar,
3
+ AvatarFallback,
4
+ AvatarImage,
5
+ type AvatarProps,
6
+ type AvatarFallbackProps,
7
+ type AvatarImageProps,
8
+ } from "./Avatar";
@@ -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 }
@@ -0,0 +1,2 @@
1
+ export { Badge, badgeVariants } from "./Badge"
2
+ export type { BadgeProps, VariantProps } from "./Badge"