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,288 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import {
3
+ Select,
4
+ SelectContent,
5
+ SelectGroup,
6
+ SelectItem,
7
+ SelectLabel,
8
+ SelectSeparator,
9
+ SelectTrigger,
10
+ SelectValue,
11
+ } from "./Select";
12
+
13
+ /**
14
+ * Select component provides a dropdown selection interface with full keyboard support
15
+ * and accessibility features. Built on Radix UI primitives.
16
+ *
17
+ * ## Features
18
+ * - Keyboard navigation (Arrow keys, Enter, Escape)
19
+ * - Size variants (sm, default)
20
+ * - Grouped options with labels
21
+ * - Scroll indicators for long lists
22
+ * - Portal rendering for proper z-index handling
23
+ * - WCAG 2.1 Level AA compliant
24
+ *
25
+ * ## Usage
26
+ * ```tsx
27
+ * <Select>
28
+ * <SelectTrigger>
29
+ * <SelectValue placeholder="Select option" />
30
+ * </SelectTrigger>
31
+ * <SelectContent>
32
+ * <SelectItem value="option1">Option 1</SelectItem>
33
+ * <SelectItem value="option2">Option 2</SelectItem>
34
+ * </SelectContent>
35
+ * </Select>
36
+ * ```
37
+ *
38
+ * ## Accessibility
39
+ * - Fully keyboard navigable
40
+ * - Screen reader support with proper ARIA attributes
41
+ * - Focus management
42
+ * - Disabled state support
43
+ */
44
+ const meta: Meta<typeof Select> = {
45
+ title: "Primitives/Select",
46
+ component: Select,
47
+ parameters: {
48
+ layout: "centered",
49
+ docs: {
50
+ description: {
51
+ component:
52
+ "A fully accessible select component with keyboard navigation, grouping, and size variants.",
53
+ },
54
+ },
55
+ },
56
+ tags: ["autodocs"],
57
+ };
58
+
59
+ export default meta;
60
+ type Story = StoryObj<typeof Select>;
61
+
62
+ /**
63
+ * Default select with simple options
64
+ */
65
+ export const Default: Story = {
66
+ render: () => (
67
+ <Select>
68
+ <SelectTrigger className="w-[200px]">
69
+ <SelectValue placeholder="Select a fruit" />
70
+ </SelectTrigger>
71
+ <SelectContent>
72
+ <SelectItem value="apple">Apple</SelectItem>
73
+ <SelectItem value="banana">Banana</SelectItem>
74
+ <SelectItem value="orange">Orange</SelectItem>
75
+ <SelectItem value="grape">Grape</SelectItem>
76
+ <SelectItem value="mango">Mango</SelectItem>
77
+ </SelectContent>
78
+ </Select>
79
+ ),
80
+ };
81
+
82
+ /**
83
+ * Small size variant
84
+ */
85
+ export const SmallSize: Story = {
86
+ render: () => (
87
+ <Select>
88
+ <SelectTrigger size="sm" className="w-[180px]">
89
+ <SelectValue placeholder="Select size" />
90
+ </SelectTrigger>
91
+ <SelectContent>
92
+ <SelectItem value="xs">Extra Small</SelectItem>
93
+ <SelectItem value="sm">Small</SelectItem>
94
+ <SelectItem value="md">Medium</SelectItem>
95
+ <SelectItem value="lg">Large</SelectItem>
96
+ <SelectItem value="xl">Extra Large</SelectItem>
97
+ </SelectContent>
98
+ </Select>
99
+ ),
100
+ };
101
+
102
+ /**
103
+ * Grouped options with labels
104
+ */
105
+ export const WithGroups: Story = {
106
+ render: () => (
107
+ <Select>
108
+ <SelectTrigger className="w-[200px]">
109
+ <SelectValue placeholder="Select a framework" />
110
+ </SelectTrigger>
111
+ <SelectContent>
112
+ <SelectGroup>
113
+ <SelectLabel>Frontend</SelectLabel>
114
+ <SelectItem value="react">React</SelectItem>
115
+ <SelectItem value="vue">Vue</SelectItem>
116
+ <SelectItem value="angular">Angular</SelectItem>
117
+ </SelectGroup>
118
+ <SelectSeparator />
119
+ <SelectGroup>
120
+ <SelectLabel>Backend</SelectLabel>
121
+ <SelectItem value="node">Node.js</SelectItem>
122
+ <SelectItem value="python">Python</SelectItem>
123
+ <SelectItem value="go">Go</SelectItem>
124
+ </SelectGroup>
125
+ <SelectSeparator />
126
+ <SelectGroup>
127
+ <SelectLabel>Database</SelectLabel>
128
+ <SelectItem value="postgres">PostgreSQL</SelectItem>
129
+ <SelectItem value="mysql">MySQL</SelectItem>
130
+ <SelectItem value="mongodb">MongoDB</SelectItem>
131
+ </SelectGroup>
132
+ </SelectContent>
133
+ </Select>
134
+ ),
135
+ };
136
+
137
+ /**
138
+ * Long list with scroll indicators
139
+ */
140
+ export const LongList: Story = {
141
+ render: () => (
142
+ <Select>
143
+ <SelectTrigger className="w-[200px]">
144
+ <SelectValue placeholder="Select a country" />
145
+ </SelectTrigger>
146
+ <SelectContent>
147
+ <SelectItem value="us">United States</SelectItem>
148
+ <SelectItem value="ca">Canada</SelectItem>
149
+ <SelectItem value="mx">Mexico</SelectItem>
150
+ <SelectItem value="uk">United Kingdom</SelectItem>
151
+ <SelectItem value="fr">France</SelectItem>
152
+ <SelectItem value="de">Germany</SelectItem>
153
+ <SelectItem value="it">Italy</SelectItem>
154
+ <SelectItem value="es">Spain</SelectItem>
155
+ <SelectItem value="nl">Netherlands</SelectItem>
156
+ <SelectItem value="se">Sweden</SelectItem>
157
+ <SelectItem value="no">Norway</SelectItem>
158
+ <SelectItem value="dk">Denmark</SelectItem>
159
+ <SelectItem value="fi">Finland</SelectItem>
160
+ <SelectItem value="pl">Poland</SelectItem>
161
+ <SelectItem value="cz">Czech Republic</SelectItem>
162
+ <SelectItem value="at">Austria</SelectItem>
163
+ <SelectItem value="ch">Switzerland</SelectItem>
164
+ <SelectItem value="be">Belgium</SelectItem>
165
+ <SelectItem value="ie">Ireland</SelectItem>
166
+ <SelectItem value="pt">Portugal</SelectItem>
167
+ </SelectContent>
168
+ </Select>
169
+ ),
170
+ };
171
+
172
+ /**
173
+ * Disabled select
174
+ */
175
+ export const Disabled: Story = {
176
+ render: () => (
177
+ <Select disabled>
178
+ <SelectTrigger className="w-[200px]">
179
+ <SelectValue placeholder="Disabled select" />
180
+ </SelectTrigger>
181
+ <SelectContent>
182
+ <SelectItem value="1">Option 1</SelectItem>
183
+ <SelectItem value="2">Option 2</SelectItem>
184
+ </SelectContent>
185
+ </Select>
186
+ ),
187
+ };
188
+
189
+ /**
190
+ * Disabled individual items
191
+ */
192
+ export const DisabledItems: Story = {
193
+ render: () => (
194
+ <Select>
195
+ <SelectTrigger className="w-[200px]">
196
+ <SelectValue placeholder="Select subscription" />
197
+ </SelectTrigger>
198
+ <SelectContent>
199
+ <SelectItem value="free">Free Tier</SelectItem>
200
+ <SelectItem value="basic">Basic - $9/mo</SelectItem>
201
+ <SelectItem value="pro">Pro - $29/mo</SelectItem>
202
+ <SelectItem value="enterprise" disabled>
203
+ Enterprise - Contact Sales
204
+ </SelectItem>
205
+ </SelectContent>
206
+ </Select>
207
+ ),
208
+ };
209
+
210
+ /**
211
+ * Controlled select with default value
212
+ */
213
+ export const WithDefaultValue: Story = {
214
+ render: () => (
215
+ <Select defaultValue="react">
216
+ <SelectTrigger className="w-[200px]">
217
+ <SelectValue placeholder="Select a framework" />
218
+ </SelectTrigger>
219
+ <SelectContent>
220
+ <SelectItem value="react">React</SelectItem>
221
+ <SelectItem value="vue">Vue</SelectItem>
222
+ <SelectItem value="angular">Angular</SelectItem>
223
+ <SelectItem value="svelte">Svelte</SelectItem>
224
+ </SelectContent>
225
+ </Select>
226
+ ),
227
+ };
228
+
229
+ /**
230
+ * Form integration example
231
+ */
232
+ export const InForm: Story = {
233
+ render: () => (
234
+ <form className="space-y-4 w-[300px]">
235
+ <div className="space-y-2">
236
+ <label className="text-sm font-medium">Country</label>
237
+ <Select defaultValue="us">
238
+ <SelectTrigger>
239
+ <SelectValue placeholder="Select country" />
240
+ </SelectTrigger>
241
+ <SelectContent>
242
+ <SelectItem value="us">United States</SelectItem>
243
+ <SelectItem value="ca">Canada</SelectItem>
244
+ <SelectItem value="uk">United Kingdom</SelectItem>
245
+ <SelectItem value="au">Australia</SelectItem>
246
+ </SelectContent>
247
+ </Select>
248
+ </div>
249
+ <div className="space-y-2">
250
+ <label className="text-sm font-medium">Language</label>
251
+ <Select defaultValue="en">
252
+ <SelectTrigger>
253
+ <SelectValue placeholder="Select language" />
254
+ </SelectTrigger>
255
+ <SelectContent>
256
+ <SelectItem value="en">English</SelectItem>
257
+ <SelectItem value="es">Spanish</SelectItem>
258
+ <SelectItem value="fr">French</SelectItem>
259
+ <SelectItem value="de">German</SelectItem>
260
+ </SelectContent>
261
+ </Select>
262
+ </div>
263
+ </form>
264
+ ),
265
+ };
266
+
267
+ /**
268
+ * Dark mode support
269
+ */
270
+ export const DarkMode: Story = {
271
+ parameters: {
272
+ backgrounds: { default: "dark" },
273
+ },
274
+ render: () => (
275
+ <div className="dark">
276
+ <Select>
277
+ <SelectTrigger className="w-[200px]">
278
+ <SelectValue placeholder="Select theme" />
279
+ </SelectTrigger>
280
+ <SelectContent>
281
+ <SelectItem value="light">Light</SelectItem>
282
+ <SelectItem value="dark">Dark</SelectItem>
283
+ <SelectItem value="system">System</SelectItem>
284
+ </SelectContent>
285
+ </Select>
286
+ </div>
287
+ ),
288
+ };
@@ -0,0 +1,162 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import {
5
+ Select as ShadcnSelect,
6
+ SelectContent as ShadcnSelectContent,
7
+ SelectGroup as ShadcnSelectGroup,
8
+ SelectItem as ShadcnSelectItem,
9
+ SelectLabel as ShadcnSelectLabel,
10
+ SelectScrollDownButton as ShadcnSelectScrollDownButton,
11
+ SelectScrollUpButton as ShadcnSelectScrollUpButton,
12
+ SelectSeparator as ShadcnSelectSeparator,
13
+ SelectTrigger as ShadcnSelectTrigger,
14
+ SelectValue as ShadcnSelectValue,
15
+ } from "@/components/ui/select";
16
+
17
+ /**
18
+ * Select Primitive
19
+ *
20
+ * A comprehensive select component built on Radix UI with shadcn/ui styling.
21
+ * Provides a fully accessible dropdown select with keyboard navigation.
22
+ *
23
+ * Features:
24
+ * - Keyboard navigation support
25
+ * - Size variants (sm, default)
26
+ * - Grouped options
27
+ * - Scroll buttons for long lists
28
+ * - Separator support
29
+ * - Portal rendering
30
+ * - WCAG 2.1 Level AA compliant
31
+ */
32
+
33
+ export type SelectProps = React.ComponentProps<typeof ShadcnSelect>;
34
+ export type SelectTriggerProps = React.ComponentProps<typeof ShadcnSelectTrigger>;
35
+ export type SelectContentProps = React.ComponentProps<typeof ShadcnSelectContent>;
36
+ export type SelectItemProps = React.ComponentProps<typeof ShadcnSelectItem>;
37
+ export type SelectLabelProps = React.ComponentProps<typeof ShadcnSelectLabel>;
38
+ export type SelectGroupProps = React.ComponentProps<typeof ShadcnSelectGroup>;
39
+ export type SelectValueProps = React.ComponentProps<typeof ShadcnSelectValue>;
40
+ export type SelectSeparatorProps = React.ComponentProps<typeof ShadcnSelectSeparator>;
41
+ export type SelectScrollUpButtonProps = React.ComponentProps<typeof ShadcnSelectScrollUpButton>;
42
+ export type SelectScrollDownButtonProps = React.ComponentProps<typeof ShadcnSelectScrollDownButton>;
43
+
44
+ /**
45
+ * Root Select component - controls the select state
46
+ */
47
+ export const Select = React.memo<SelectProps>(
48
+ React.forwardRef<React.ElementRef<typeof ShadcnSelect>, SelectProps>(
49
+ (props, ref) => {
50
+ return <ShadcnSelect {...props} />;
51
+ }
52
+ )
53
+ );
54
+ Select.displayName = "Select";
55
+
56
+ /**
57
+ * SelectTrigger - The button that opens the select dropdown
58
+ */
59
+ export const SelectTrigger = React.memo<SelectTriggerProps>(
60
+ React.forwardRef<React.ElementRef<typeof ShadcnSelectTrigger>, SelectTriggerProps>(
61
+ (props, ref) => {
62
+ return <ShadcnSelectTrigger ref={ref} {...props} />;
63
+ }
64
+ )
65
+ );
66
+ SelectTrigger.displayName = "SelectTrigger";
67
+
68
+ /**
69
+ * SelectContent - The dropdown content container
70
+ */
71
+ export const SelectContent = React.memo<SelectContentProps>(
72
+ React.forwardRef<React.ElementRef<typeof ShadcnSelectContent>, SelectContentProps>(
73
+ (props, ref) => {
74
+ return <ShadcnSelectContent ref={ref} {...props} />;
75
+ }
76
+ )
77
+ );
78
+ SelectContent.displayName = "SelectContent";
79
+
80
+ /**
81
+ * SelectItem - Individual selectable option
82
+ */
83
+ export const SelectItem = React.memo<SelectItemProps>(
84
+ React.forwardRef<React.ElementRef<typeof ShadcnSelectItem>, SelectItemProps>(
85
+ (props, ref) => {
86
+ return <ShadcnSelectItem ref={ref} {...props} />;
87
+ }
88
+ )
89
+ );
90
+ SelectItem.displayName = "SelectItem";
91
+
92
+ /**
93
+ * SelectLabel - Label for a group of items
94
+ */
95
+ export const SelectLabel = React.memo<SelectLabelProps>(
96
+ React.forwardRef<React.ElementRef<typeof ShadcnSelectLabel>, SelectLabelProps>(
97
+ (props, ref) => {
98
+ return <ShadcnSelectLabel ref={ref} {...props} />;
99
+ }
100
+ )
101
+ );
102
+ SelectLabel.displayName = "SelectLabel";
103
+
104
+ /**
105
+ * SelectGroup - Groups related select items
106
+ */
107
+ export const SelectGroup = React.memo<SelectGroupProps>(
108
+ React.forwardRef<React.ElementRef<typeof ShadcnSelectGroup>, SelectGroupProps>(
109
+ (props, ref) => {
110
+ return <ShadcnSelectGroup {...props} />;
111
+ }
112
+ )
113
+ );
114
+ SelectGroup.displayName = "SelectGroup";
115
+
116
+ /**
117
+ * SelectValue - Displays the selected value
118
+ */
119
+ export const SelectValue = React.memo<SelectValueProps>(
120
+ React.forwardRef<React.ElementRef<typeof ShadcnSelectValue>, SelectValueProps>(
121
+ (props, ref) => {
122
+ return <ShadcnSelectValue {...props} />;
123
+ }
124
+ )
125
+ );
126
+ SelectValue.displayName = "SelectValue";
127
+
128
+ /**
129
+ * SelectSeparator - Visual separator between items
130
+ */
131
+ export const SelectSeparator = React.memo<SelectSeparatorProps>(
132
+ React.forwardRef<React.ElementRef<typeof ShadcnSelectSeparator>, SelectSeparatorProps>(
133
+ (props, ref) => {
134
+ return <ShadcnSelectSeparator ref={ref} {...props} />;
135
+ }
136
+ )
137
+ );
138
+ SelectSeparator.displayName = "SelectSeparator";
139
+
140
+ /**
141
+ * SelectScrollUpButton - Button to scroll up in long lists
142
+ */
143
+ export const SelectScrollUpButton = React.memo<SelectScrollUpButtonProps>(
144
+ React.forwardRef<React.ElementRef<typeof ShadcnSelectScrollUpButton>, SelectScrollUpButtonProps>(
145
+ (props, ref) => {
146
+ return <ShadcnSelectScrollUpButton ref={ref} {...props} />;
147
+ }
148
+ )
149
+ );
150
+ SelectScrollUpButton.displayName = "SelectScrollUpButton";
151
+
152
+ /**
153
+ * SelectScrollDownButton - Button to scroll down in long lists
154
+ */
155
+ export const SelectScrollDownButton = React.memo<SelectScrollDownButtonProps>(
156
+ React.forwardRef<React.ElementRef<typeof ShadcnSelectScrollDownButton>, SelectScrollDownButtonProps>(
157
+ (props, ref) => {
158
+ return <ShadcnSelectScrollDownButton ref={ref} {...props} />;
159
+ }
160
+ )
161
+ );
162
+ SelectScrollDownButton.displayName = "SelectScrollDownButton";
@@ -0,0 +1,22 @@
1
+ export {
2
+ Select,
3
+ SelectContent,
4
+ SelectGroup,
5
+ SelectItem,
6
+ SelectLabel,
7
+ SelectScrollDownButton,
8
+ SelectScrollUpButton,
9
+ SelectSeparator,
10
+ SelectTrigger,
11
+ SelectValue,
12
+ type SelectProps,
13
+ type SelectContentProps,
14
+ type SelectGroupProps,
15
+ type SelectItemProps,
16
+ type SelectLabelProps,
17
+ type SelectScrollDownButtonProps,
18
+ type SelectScrollUpButtonProps,
19
+ type SelectSeparatorProps,
20
+ type SelectTriggerProps,
21
+ type SelectValueProps,
22
+ } from "./Select";