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,129 @@
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+ import * as React from "react"
3
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "./Tabs"
4
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../Card"
5
+
6
+ /**
7
+ * Tabs Primitive Stories
8
+ *
9
+ * The Tabs component organizes content into switchable panels with accessible keyboard navigation.
10
+ *
11
+ * ## Accessibility Features
12
+ * - Arrow keys navigate between tabs
13
+ * - Home/End keys jump to first/last tab
14
+ * - Tab key moves focus in/out of tab list
15
+ * - Proper ARIA roles and attributes
16
+ *
17
+ * ## Usage Guidelines
18
+ * - Use for content that naturally divides into categories
19
+ * - Keep tab labels short and descriptive
20
+ * - Ensure content in each tab is independent
21
+ * - Don't nest tabs within tabs
22
+ */
23
+ const meta = {
24
+ title: "Primitives/Tabs",
25
+ component: Tabs,
26
+ parameters: {
27
+ layout: "padded",
28
+ },
29
+ tags: ["autodocs"],
30
+ } satisfies Meta<typeof Tabs>
31
+
32
+ export default meta
33
+ type Story = StoryObj<typeof meta>
34
+
35
+ export const Default: Story = {
36
+ render: () => (
37
+ <Tabs defaultValue="account" className="w-[400px]">
38
+ <TabsList>
39
+ <TabsTrigger value="account">Account</TabsTrigger>
40
+ <TabsTrigger value="password">Password</TabsTrigger>
41
+ </TabsList>
42
+ <TabsContent value="account">
43
+ <p className="text-sm">Make changes to your account here.</p>
44
+ </TabsContent>
45
+ <TabsContent value="password">
46
+ <p className="text-sm">Change your password here.</p>
47
+ </TabsContent>
48
+ </Tabs>
49
+ ),
50
+ }
51
+
52
+ export const WithCards: Story = {
53
+ render: () => (
54
+ <Tabs defaultValue="overview" className="w-[600px]">
55
+ <TabsList>
56
+ <TabsTrigger value="overview">Overview</TabsTrigger>
57
+ <TabsTrigger value="analytics">Analytics</TabsTrigger>
58
+ <TabsTrigger value="reports">Reports</TabsTrigger>
59
+ <TabsTrigger value="notifications">Notifications</TabsTrigger>
60
+ </TabsList>
61
+ <TabsContent value="overview">
62
+ <Card>
63
+ <CardHeader>
64
+ <CardTitle>Overview</CardTitle>
65
+ <CardDescription>Your account overview</CardDescription>
66
+ </CardHeader>
67
+ <CardContent>
68
+ <p className="text-sm">View your account summary and recent activity.</p>
69
+ </CardContent>
70
+ </Card>
71
+ </TabsContent>
72
+ <TabsContent value="analytics">
73
+ <Card>
74
+ <CardHeader>
75
+ <CardTitle>Analytics</CardTitle>
76
+ <CardDescription>Performance metrics</CardDescription>
77
+ </CardHeader>
78
+ <CardContent>
79
+ <p className="text-sm">Track your performance and engagement.</p>
80
+ </CardContent>
81
+ </Card>
82
+ </TabsContent>
83
+ <TabsContent value="reports">
84
+ <Card>
85
+ <CardHeader>
86
+ <CardTitle>Reports</CardTitle>
87
+ <CardDescription>Generated reports</CardDescription>
88
+ </CardHeader>
89
+ <CardContent>
90
+ <p className="text-sm">Access your generated reports.</p>
91
+ </CardContent>
92
+ </Card>
93
+ </TabsContent>
94
+ <TabsContent value="notifications">
95
+ <Card>
96
+ <CardHeader>
97
+ <CardTitle>Notifications</CardTitle>
98
+ <CardDescription>Manage notifications</CardDescription>
99
+ </CardHeader>
100
+ <CardContent>
101
+ <p className="text-sm">Configure your notification preferences.</p>
102
+ </CardContent>
103
+ </Card>
104
+ </TabsContent>
105
+ </Tabs>
106
+ ),
107
+ }
108
+
109
+ export const DarkMode: Story = {
110
+ parameters: {
111
+ backgrounds: { default: "dark" },
112
+ },
113
+ render: () => (
114
+ <div className="dark">
115
+ <Tabs defaultValue="account" className="w-[400px]">
116
+ <TabsList>
117
+ <TabsTrigger value="account">Account</TabsTrigger>
118
+ <TabsTrigger value="password">Password</TabsTrigger>
119
+ </TabsList>
120
+ <TabsContent value="account">
121
+ <p className="text-sm">Make changes to your account here.</p>
122
+ </TabsContent>
123
+ <TabsContent value="password">
124
+ <p className="text-sm">Change your password here.</p>
125
+ </TabsContent>
126
+ </Tabs>
127
+ </div>
128
+ ),
129
+ }
@@ -0,0 +1,70 @@
1
+ import * as React from "react"
2
+ import {
3
+ Tabs as ShadcnTabs,
4
+ TabsContent,
5
+ TabsList,
6
+ TabsTrigger,
7
+ } from "../../ui/tabs"
8
+
9
+ /**
10
+ * Tabs Primitive
11
+ *
12
+ * A foundational tabs component for organizing content into switchable panels.
13
+ * Built on Radix UI Tabs primitive with WCAG 2.1 Level AA compliance.
14
+ *
15
+ * ## Accessibility Features
16
+ * - Arrow key navigation between tabs
17
+ * - Home/End keys for first/last tab
18
+ * - Automatic ARIA attributes (role="tablist", "tab", "tabpanel")
19
+ * - Focus management and keyboard support
20
+ * - Screen reader announcements
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * <Tabs defaultValue="tab1">
25
+ * <TabsList>
26
+ * <TabsTrigger value="tab1">Tab 1</TabsTrigger>
27
+ * <TabsTrigger value="tab2">Tab 2</TabsTrigger>
28
+ * </TabsList>
29
+ * <TabsContent value="tab1">Content 1</TabsContent>
30
+ * <TabsContent value="tab2">Content 2</TabsContent>
31
+ * </Tabs>
32
+ * ```
33
+ *
34
+ * @see https://ui.shadcn.com/docs/components/tabs
35
+ * @see https://www.radix-ui.com/primitives/docs/components/tabs
36
+ */
37
+
38
+ export type TabsProps = React.ComponentProps<typeof ShadcnTabs>
39
+ export type TabsListProps = React.ComponentProps<typeof TabsList>
40
+ export type TabsTriggerProps = React.ComponentProps<typeof TabsTrigger>
41
+ export type TabsContentProps = React.ComponentProps<typeof TabsContent>
42
+
43
+ /**
44
+ * Tabs component
45
+ *
46
+ * A tabs component for organizing content into switchable panels.
47
+ * Built on Radix UI Tabs primitive with full accessibility support.
48
+ *
49
+ * Features:
50
+ * - Arrow key navigation between tabs
51
+ * - Home/End keys for first/last tab
52
+ * - Automatic ARIA attributes
53
+ * - Focus management
54
+ * - Screen reader support
55
+ * - Horizontal and vertical orientation
56
+ * - Dark mode support
57
+ */
58
+ export const Tabs = React.forwardRef<
59
+ React.ElementRef<typeof ShadcnTabs>,
60
+ TabsProps
61
+ >((props, ref) => {
62
+ return <ShadcnTabs {...props} />
63
+ })
64
+
65
+ Tabs.displayName = "Tabs"
66
+
67
+ /**
68
+ * Re-export Tabs sub-components for composition
69
+ */
70
+ export { TabsContent, TabsList, TabsTrigger }
@@ -0,0 +1,13 @@
1
+ export {
2
+ Tabs,
3
+ TabsContent,
4
+ TabsList,
5
+ TabsTrigger,
6
+ } from "./Tabs"
7
+
8
+ export type {
9
+ TabsProps,
10
+ TabsListProps,
11
+ TabsTriggerProps,
12
+ TabsContentProps,
13
+ } from "./Tabs"
@@ -0,0 +1,358 @@
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+ import { Textarea } from "./Textarea"
3
+
4
+ /**
5
+ * Textarea Primitive Stories
6
+ *
7
+ * The Textarea primitive provides a consistent multi-line text input experience across the application.
8
+ * It supports validation states, accessibility features, and automatic content-based resizing.
9
+ */
10
+
11
+ const meta = {
12
+ title: "Primitives/Textarea",
13
+ component: Textarea,
14
+ parameters: {
15
+ layout: "centered",
16
+ docs: {
17
+ description: {
18
+ component:
19
+ "A foundational textarea component built on shadcn/ui Textarea. Supports multi-line text input, validation states, and accessibility features including ARIA attributes for error states. Features field-sizing-content for automatic height adjustment.",
20
+ },
21
+ },
22
+ },
23
+ tags: ["autodocs"],
24
+ argTypes: {
25
+ size: {
26
+ control: "select",
27
+ options: ["sm", "default", "lg"],
28
+ description: "Size variant of the textarea",
29
+ table: {
30
+ defaultValue: { summary: "default" },
31
+ },
32
+ },
33
+ state: {
34
+ control: "select",
35
+ options: ["default", "error", "success", "warning"],
36
+ description: "Visual state of the textarea",
37
+ table: {
38
+ defaultValue: { summary: "default" },
39
+ },
40
+ },
41
+ placeholder: {
42
+ control: "text",
43
+ description: "Placeholder text displayed when textarea is empty",
44
+ },
45
+ rows: {
46
+ control: "number",
47
+ description: "Number of visible text lines",
48
+ table: {
49
+ defaultValue: { summary: "undefined (auto-size)" },
50
+ },
51
+ },
52
+ disabled: {
53
+ control: "boolean",
54
+ description: "Whether the textarea is disabled",
55
+ table: {
56
+ defaultValue: { summary: false },
57
+ },
58
+ },
59
+ "aria-invalid": {
60
+ control: "boolean",
61
+ description: "Indicates whether the textarea value is invalid",
62
+ table: {
63
+ defaultValue: { summary: false },
64
+ },
65
+ },
66
+ },
67
+ } satisfies Meta<typeof Textarea>
68
+
69
+ export default meta
70
+ type Story = StoryObj<typeof meta>
71
+
72
+ /**
73
+ * Default textarea with automatic height adjustment
74
+ */
75
+ export const Default: Story = {
76
+ args: {
77
+ placeholder: "Enter your message...",
78
+ },
79
+ }
80
+
81
+ /**
82
+ * Textarea with fixed number of rows
83
+ */
84
+ export const WithRows: Story = {
85
+ args: {
86
+ placeholder: "Enter description...",
87
+ rows: 5,
88
+ },
89
+ }
90
+
91
+ /**
92
+ * Small textarea for brief comments
93
+ */
94
+ export const Small: Story = {
95
+ args: {
96
+ placeholder: "Brief comment...",
97
+ rows: 3,
98
+ },
99
+ }
100
+
101
+ /**
102
+ * Large textarea for longer content
103
+ */
104
+ export const Large: Story = {
105
+ args: {
106
+ placeholder: "Enter detailed description...",
107
+ rows: 10,
108
+ },
109
+ }
110
+
111
+ /**
112
+ * Disabled textarea that cannot be interacted with
113
+ */
114
+ export const Disabled: Story = {
115
+ args: {
116
+ placeholder: "Disabled textarea",
117
+ disabled: true,
118
+ },
119
+ }
120
+
121
+ /**
122
+ * Textarea with pre-filled value
123
+ */
124
+ export const WithValue: Story = {
125
+ args: {
126
+ defaultValue:
127
+ "This is some pre-filled text content.\nIt spans multiple lines.\nYou can edit this text.",
128
+ rows: 5,
129
+ },
130
+ }
131
+
132
+ /**
133
+ * Invalid textarea showing error state
134
+ */
135
+ export const Invalid: Story = {
136
+ args: {
137
+ placeholder: "Enter valid text...",
138
+ defaultValue: "This text contains errors",
139
+ "aria-invalid": true,
140
+ rows: 4,
141
+ },
142
+ }
143
+
144
+ /**
145
+ * Textarea with maximum length constraint
146
+ */
147
+ export const WithMaxLength: Story = {
148
+ args: {
149
+ placeholder: "Maximum 200 characters...",
150
+ maxLength: 200,
151
+ rows: 4,
152
+ },
153
+ }
154
+
155
+ /**
156
+ * Read-only textarea for displaying content
157
+ */
158
+ export const ReadOnly: Story = {
159
+ args: {
160
+ defaultValue:
161
+ "This is read-only content.\nIt cannot be edited but can be selected and copied.",
162
+ readOnly: true,
163
+ rows: 4,
164
+ },
165
+ }
166
+
167
+ /**
168
+ * Small textarea size
169
+ */
170
+ export const SmallSize: Story = {
171
+ args: {
172
+ placeholder: "Small textarea",
173
+ size: "sm",
174
+ rows: 4,
175
+ },
176
+ }
177
+
178
+ /**
179
+ * Large textarea size
180
+ */
181
+ export const LargeSize: Story = {
182
+ args: {
183
+ placeholder: "Large textarea",
184
+ size: "lg",
185
+ rows: 4,
186
+ },
187
+ }
188
+
189
+ /**
190
+ * Error state textarea
191
+ */
192
+ export const ErrorState: Story = {
193
+ args: {
194
+ placeholder: "Enter valid text...",
195
+ defaultValue: "This text contains errors",
196
+ state: "error",
197
+ rows: 4,
198
+ },
199
+ }
200
+
201
+ /**
202
+ * Success state textarea
203
+ */
204
+ export const SuccessState: Story = {
205
+ args: {
206
+ placeholder: "Enter text...",
207
+ defaultValue: "This text is valid",
208
+ state: "success",
209
+ rows: 4,
210
+ },
211
+ }
212
+
213
+ /**
214
+ * Warning state textarea
215
+ */
216
+ export const WarningState: Story = {
217
+ args: {
218
+ placeholder: "Enter text...",
219
+ defaultValue: "This text might need attention",
220
+ state: "warning",
221
+ rows: 4,
222
+ },
223
+ }
224
+
225
+ /**
226
+ * Size variants showcase
227
+ */
228
+ export const SizeVariants: Story = {
229
+ render: () => (
230
+ <div className="flex flex-col gap-4 w-96">
231
+ <div>
232
+ <label className="text-sm font-medium mb-1 block">Small</label>
233
+ <Textarea placeholder="Small textarea..." size="sm" rows={3} />
234
+ </div>
235
+ <div>
236
+ <label className="text-sm font-medium mb-1 block">Default</label>
237
+ <Textarea placeholder="Default textarea..." size="default" rows={3} />
238
+ </div>
239
+ <div>
240
+ <label className="text-sm font-medium mb-1 block">Large</label>
241
+ <Textarea placeholder="Large textarea..." size="lg" rows={3} />
242
+ </div>
243
+ </div>
244
+ ),
245
+ }
246
+
247
+ /**
248
+ * State variants showcase
249
+ */
250
+ export const StateVariants: Story = {
251
+ render: () => (
252
+ <div className="flex flex-col gap-4 w-96">
253
+ <div>
254
+ <label className="text-sm font-medium mb-1 block">Default State</label>
255
+ <Textarea placeholder="Default state..." state="default" rows={3} />
256
+ </div>
257
+ <div>
258
+ <label className="text-sm font-medium mb-1 block">Error State</label>
259
+ <Textarea placeholder="Error state..." state="error" defaultValue="Invalid content" rows={3} />
260
+ </div>
261
+ <div>
262
+ <label className="text-sm font-medium mb-1 block">Success State</label>
263
+ <Textarea placeholder="Success state..." state="success" defaultValue="Valid content" rows={3} />
264
+ </div>
265
+ <div>
266
+ <label className="text-sm font-medium mb-1 block">Warning State</label>
267
+ <Textarea placeholder="Warning state..." state="warning" defaultValue="Needs attention" rows={3} />
268
+ </div>
269
+ </div>
270
+ ),
271
+ }
272
+
273
+ /**
274
+ * Combined variants showcase
275
+ */
276
+ export const CombinedVariants: Story = {
277
+ render: () => (
278
+ <div className="flex flex-col gap-4 w-96">
279
+ <div>
280
+ <label className="text-sm font-medium mb-1 block">Small Error</label>
281
+ <Textarea placeholder="Small error..." size="sm" state="error" rows={3} />
282
+ </div>
283
+ <div>
284
+ <label className="text-sm font-medium mb-1 block">Default Success</label>
285
+ <Textarea placeholder="Default success..." size="default" state="success" rows={3} />
286
+ </div>
287
+ <div>
288
+ <label className="text-sm font-medium mb-1 block">Large Warning</label>
289
+ <Textarea placeholder="Large warning..." size="lg" state="warning" rows={3} />
290
+ </div>
291
+ </div>
292
+ ),
293
+ }
294
+
295
+ /**
296
+ * All textarea variants and states showcased together
297
+ */
298
+ export const AllVariants: Story = {
299
+ render: () => (
300
+ <div className="flex flex-col gap-4 w-96">
301
+ <div>
302
+ <label className="text-sm font-medium mb-1 block">Default (Auto-size)</label>
303
+ <Textarea placeholder="Enter your message..." />
304
+ </div>
305
+
306
+ <div>
307
+ <label className="text-sm font-medium mb-1 block">Small (3 rows)</label>
308
+ <Textarea placeholder="Brief comment..." rows={3} />
309
+ </div>
310
+
311
+ <div>
312
+ <label className="text-sm font-medium mb-1 block">Medium (5 rows)</label>
313
+ <Textarea placeholder="Enter description..." rows={5} />
314
+ </div>
315
+
316
+ <div>
317
+ <label className="text-sm font-medium mb-1 block">With Value</label>
318
+ <Textarea
319
+ defaultValue="This is some pre-filled text content.&#10;It spans multiple lines.&#10;You can edit this text."
320
+ rows={4}
321
+ />
322
+ </div>
323
+
324
+ <div>
325
+ <label className="text-sm font-medium mb-1 block">Disabled</label>
326
+ <Textarea placeholder="Disabled textarea" disabled rows={3} />
327
+ </div>
328
+
329
+ <div>
330
+ <label className="text-sm font-medium mb-1 block">Invalid</label>
331
+ <Textarea
332
+ placeholder="Enter valid text..."
333
+ defaultValue="This text contains errors"
334
+ aria-invalid
335
+ rows={3}
336
+ />
337
+ </div>
338
+
339
+ <div>
340
+ <label className="text-sm font-medium mb-1 block">With Max Length (200)</label>
341
+ <Textarea
342
+ placeholder="Maximum 200 characters..."
343
+ maxLength={200}
344
+ rows={3}
345
+ />
346
+ </div>
347
+
348
+ <div>
349
+ <label className="text-sm font-medium mb-1 block">Read Only</label>
350
+ <Textarea
351
+ defaultValue="This is read-only content.&#10;It cannot be edited but can be selected and copied."
352
+ readOnly
353
+ rows={3}
354
+ />
355
+ </div>
356
+ </div>
357
+ ),
358
+ }
@@ -0,0 +1,91 @@
1
+ import * as React from "react"
2
+ import {
3
+ Textarea as ShadcnTextarea,
4
+ textareaVariants,
5
+ } from "../../ui/textarea"
6
+ import type { VariantProps } from "class-variance-authority"
7
+
8
+ /**
9
+ * Textarea Primitive
10
+ *
11
+ * A foundational textarea component that wraps shadcn/ui Textarea with design system
12
+ * enhancements. This primitive serves as the single source of truth for all multi-line
13
+ * text input interactions across the application.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * <Textarea placeholder="Enter your message..." />
18
+ *
19
+ * <Textarea
20
+ * placeholder="Description"
21
+ * rows={5}
22
+ * size="sm"
23
+ * />
24
+ *
25
+ * <Textarea
26
+ * placeholder="Enter comment"
27
+ * state="error"
28
+ * />
29
+ *
30
+ * <Textarea
31
+ * placeholder="Success state"
32
+ * state="success"
33
+ * size="lg"
34
+ * />
35
+ * ```
36
+ *
37
+ * @see https://ui.shadcn.com/docs/components/textarea - shadcn/ui Textarea documentation
38
+ */
39
+
40
+ /**
41
+ * Textarea component props
42
+ * Extends the native textarea element props with variant options
43
+ */
44
+ export type TextareaProps = React.ComponentProps<"textarea"> &
45
+ VariantProps<typeof textareaVariants>
46
+
47
+ /**
48
+ * Textarea component
49
+ *
50
+ * A versatile multi-line text input component built on shadcn/ui foundation.
51
+ * Optimized with React.memo for performance in high-frequency rendering scenarios.
52
+ *
53
+ * Features:
54
+ * - Full WCAG 2.1 Level AA compliance
55
+ * - Size variants (sm, default, lg) for different contexts
56
+ * - State variants (default, error, success, warning) for visual feedback
57
+ * - Customizable row height
58
+ * - Validation state styling via aria-invalid
59
+ * - Dark mode support
60
+ * - Placeholder and disabled states
61
+ * - Auto-resize capabilities
62
+ */
63
+ export const Textarea = React.memo(
64
+ React.forwardRef<HTMLTextAreaElement, TextareaProps>(
65
+ (props, ref) => {
66
+ return <ShadcnTextarea ref={ref} {...props} />
67
+ }
68
+ )
69
+ )
70
+
71
+ Textarea.displayName = "Textarea"
72
+
73
+ /**
74
+ * Re-export textareaVariants for consumers who need direct access to the variant generator.
75
+ * This is useful for creating custom textarea-like components that need consistent styling.
76
+ *
77
+ * @example
78
+ * ```tsx
79
+ * import { textareaVariants } from './Textarea'
80
+ *
81
+ * <div className={textareaVariants({ size: "sm", state: "error" })}>
82
+ * Custom textarea-like div
83
+ * </div>
84
+ * ```
85
+ */
86
+ export { textareaVariants }
87
+
88
+ /**
89
+ * Re-export VariantProps for type inference in consuming components
90
+ */
91
+ export type { VariantProps }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Textarea Primitive
3
+ *
4
+ * Central export point for the Textarea primitive component and its related types.
5
+ */
6
+ export { Textarea, textareaVariants } from "./Textarea"
7
+ export type { TextareaProps, VariantProps } from "./Textarea"