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,140 @@
1
+ import * as React from "react"
2
+ import {
3
+ Dialog as ShadcnDialog,
4
+ DialogClose,
5
+ DialogContent,
6
+ DialogDescription,
7
+ DialogFooter,
8
+ DialogHeader,
9
+ DialogOverlay,
10
+ DialogPortal,
11
+ DialogTitle,
12
+ DialogTrigger,
13
+ } from "../../ui/dialog"
14
+
15
+ /**
16
+ * Dialog Primitive
17
+ *
18
+ * A foundational modal dialog component that wraps shadcn/ui Dialog with extensibility for
19
+ * design system-specific enhancements. This primitive provides accessible modal interactions
20
+ * with full keyboard navigation and focus management.
21
+ *
22
+ * Built on Radix UI Dialog primitive with WCAG 2.1 Level AA compliance:
23
+ * - Proper focus trapping and restoration
24
+ * - Keyboard navigation (Escape to close)
25
+ * - Screen reader announcements
26
+ * - Portal rendering for proper layering
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * <Dialog>
31
+ * <DialogTrigger asChild>
32
+ * <Button>Open Dialog</Button>
33
+ * </DialogTrigger>
34
+ * <DialogContent>
35
+ * <DialogHeader>
36
+ * <DialogTitle>Dialog Title</DialogTitle>
37
+ * <DialogDescription>Dialog description text</DialogDescription>
38
+ * </DialogHeader>
39
+ * <div>Dialog body content</div>
40
+ * <DialogFooter>
41
+ * <Button>Action</Button>
42
+ * </DialogFooter>
43
+ * </DialogContent>
44
+ * </Dialog>
45
+ * ```
46
+ *
47
+ * @see https://ui.shadcn.com/docs/components/dialog - shadcn/ui Dialog documentation
48
+ * @see https://www.radix-ui.com/primitives/docs/components/dialog - Radix UI Dialog primitive
49
+ */
50
+
51
+ /**
52
+ * Dialog Root component props
53
+ * Controls the open state and modal behavior
54
+ */
55
+ export type DialogProps = React.ComponentProps<typeof ShadcnDialog>
56
+
57
+ /**
58
+ * DialogContent component props
59
+ * Main content container with optional close button
60
+ */
61
+ export type DialogContentProps = React.ComponentProps<typeof DialogContent>
62
+
63
+ /**
64
+ * DialogTrigger component props
65
+ * Element that opens the dialog
66
+ */
67
+ export type DialogTriggerProps = React.ComponentProps<typeof DialogTrigger>
68
+
69
+ /**
70
+ * DialogHeader component props
71
+ * Header section for title and description
72
+ */
73
+ export type DialogHeaderProps = React.ComponentProps<typeof DialogHeader>
74
+
75
+ /**
76
+ * DialogFooter component props
77
+ * Footer section for action buttons
78
+ */
79
+ export type DialogFooterProps = React.ComponentProps<typeof DialogFooter>
80
+
81
+ /**
82
+ * DialogTitle component props
83
+ * Accessible title for the dialog
84
+ */
85
+ export type DialogTitleProps = React.ComponentProps<typeof DialogTitle>
86
+
87
+ /**
88
+ * DialogDescription component props
89
+ * Accessible description for the dialog
90
+ */
91
+ export type DialogDescriptionProps = React.ComponentProps<typeof DialogDescription>
92
+
93
+ /**
94
+ * Dialog component
95
+ *
96
+ * A modal dialog component built on Radix UI Dialog primitive.
97
+ * Provides accessible modal interactions with full keyboard navigation.
98
+ *
99
+ * Features:
100
+ * - Focus trapping and restoration
101
+ * - Keyboard navigation (Escape to close)
102
+ * - Screen reader announcements
103
+ * - Portal rendering for proper layering
104
+ * - Overlay dismiss support
105
+ * - Dark mode support
106
+ */
107
+ export const Dialog = React.forwardRef<
108
+ React.ElementRef<typeof ShadcnDialog>,
109
+ DialogProps
110
+ >((props, ref) => {
111
+ return <ShadcnDialog {...props} />
112
+ })
113
+
114
+ Dialog.displayName = "Dialog"
115
+
116
+ /**
117
+ * Re-export all Dialog sub-components for composition
118
+ *
119
+ * These components should be used together to build complete dialog experiences:
120
+ * - DialogTrigger: Opens the dialog
121
+ * - DialogContent: Main content container
122
+ * - DialogHeader: Header section with title and description
123
+ * - DialogFooter: Footer section with actions
124
+ * - DialogTitle: Accessible title (required for a11y)
125
+ * - DialogDescription: Accessible description (recommended for a11y)
126
+ * - DialogClose: Explicitly close the dialog (optional, auto close button in DialogContent)
127
+ * - DialogPortal: Advanced portal customization (rarely needed)
128
+ * - DialogOverlay: Advanced overlay customization (rarely needed)
129
+ */
130
+ export {
131
+ DialogClose,
132
+ DialogContent,
133
+ DialogDescription,
134
+ DialogFooter,
135
+ DialogHeader,
136
+ DialogOverlay,
137
+ DialogPortal,
138
+ DialogTitle,
139
+ DialogTrigger,
140
+ }
@@ -0,0 +1,22 @@
1
+ export {
2
+ Dialog,
3
+ DialogClose,
4
+ DialogContent,
5
+ DialogDescription,
6
+ DialogFooter,
7
+ DialogHeader,
8
+ DialogOverlay,
9
+ DialogPortal,
10
+ DialogTitle,
11
+ DialogTrigger,
12
+ } from "./Dialog"
13
+
14
+ export type {
15
+ DialogProps,
16
+ DialogContentProps,
17
+ DialogTriggerProps,
18
+ DialogHeaderProps,
19
+ DialogFooterProps,
20
+ DialogTitleProps,
21
+ DialogDescriptionProps,
22
+ } from "./Dialog"
@@ -0,0 +1,327 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import {
3
+ Drawer,
4
+ DrawerTrigger,
5
+ DrawerContent,
6
+ DrawerHeader,
7
+ DrawerFooter,
8
+ DrawerTitle,
9
+ DrawerDescription,
10
+ DrawerClose,
11
+ } from './Drawer'
12
+ import { Button } from '../Button'
13
+
14
+ /**
15
+ * Drawer Primitive Stories
16
+ *
17
+ * The Drawer component is a foundational primitive for displaying content in a slide-out panel.
18
+ * It extends shadcn/ui's Drawer with design system-specific enhancements and maintains
19
+ * full accessibility compliance (WCAG 2.1 Level AA).
20
+ *
21
+ * ## Features
22
+ * - Slide-out panel from bottom (mobile-first)
23
+ * - Backdrop overlay
24
+ * - Keyboard navigation support
25
+ * - Focus management
26
+ * - Dark mode support
27
+ *
28
+ * ## Accessibility
29
+ * - Proper ARIA attributes for dialog
30
+ * - Focus trap within drawer
31
+ * - Keyboard navigation (Escape to close)
32
+ * - Screen reader announcements
33
+ * - Focus restoration on close
34
+ *
35
+ * ## Usage Guidelines
36
+ *
37
+ * ### Do's
38
+ * - Use for mobile-first slide-up panels
39
+ * - Include DrawerTitle for accessibility
40
+ * - Provide clear close actions
41
+ * - Use for contextual actions and details
42
+ *
43
+ * ### Don'ts
44
+ * - Don't use for critical information
45
+ * - Don't nest drawers
46
+ * - Don't use for complex forms (use Dialog instead)
47
+ * - Don't omit title and description
48
+ */
49
+ const meta = {
50
+ title: 'Primitives/Drawer',
51
+ component: Drawer,
52
+ tags: ['autodocs'],
53
+ parameters: {
54
+ layout: 'centered',
55
+ docs: {
56
+ description: {
57
+ component: 'A drawer component for displaying content in a slide-out panel, built on shadcn/ui foundation.',
58
+ },
59
+ },
60
+ },
61
+ } satisfies Meta<typeof Drawer>
62
+
63
+ export default meta
64
+ type Story = StoryObj<typeof meta>
65
+
66
+ /**
67
+ * Default drawer
68
+ *
69
+ * Basic drawer with trigger, content, header, and footer.
70
+ */
71
+ export const Default: Story = {
72
+ render: () => (
73
+ <Drawer>
74
+ <DrawerTrigger asChild>
75
+ <Button variant="outline">Open Drawer</Button>
76
+ </DrawerTrigger>
77
+ <DrawerContent>
78
+ <DrawerHeader>
79
+ <DrawerTitle>Drawer Title</DrawerTitle>
80
+ <DrawerDescription>This is a drawer description that provides context.</DrawerDescription>
81
+ </DrawerHeader>
82
+ <div style={{ padding: '16px' }}>
83
+ <p>Drawer content goes here. This is a mobile-first slide-up panel.</p>
84
+ </div>
85
+ <DrawerFooter>
86
+ <Button>Submit</Button>
87
+ <DrawerClose asChild>
88
+ <Button variant="outline">Cancel</Button>
89
+ </DrawerClose>
90
+ </DrawerFooter>
91
+ </DrawerContent>
92
+ </Drawer>
93
+ ),
94
+ }
95
+
96
+ /**
97
+ * With Form
98
+ *
99
+ * Drawer containing a simple form.
100
+ */
101
+ export const WithForm: Story = {
102
+ render: () => (
103
+ <Drawer>
104
+ <DrawerTrigger asChild>
105
+ <Button>Edit Profile</Button>
106
+ </DrawerTrigger>
107
+ <DrawerContent>
108
+ <DrawerHeader>
109
+ <DrawerTitle>Edit Profile</DrawerTitle>
110
+ <DrawerDescription>Make changes to your profile here.</DrawerDescription>
111
+ </DrawerHeader>
112
+ <div style={{ padding: '16px', display: 'flex', flexDirection: 'column', gap: '16px' }}>
113
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
114
+ <label htmlFor="name" style={{ fontSize: '14px', fontWeight: 500 }}>
115
+ Name
116
+ </label>
117
+ <input
118
+ id="name"
119
+ defaultValue="John Doe"
120
+ style={{
121
+ padding: '8px 12px',
122
+ border: '1px solid hsl(var(--border))',
123
+ borderRadius: '6px',
124
+ fontSize: '14px',
125
+ }}
126
+ />
127
+ </div>
128
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
129
+ <label htmlFor="email" style={{ fontSize: '14px', fontWeight: 500 }}>
130
+ Email
131
+ </label>
132
+ <input
133
+ id="email"
134
+ type="email"
135
+ defaultValue="john@example.com"
136
+ style={{
137
+ padding: '8px 12px',
138
+ border: '1px solid hsl(var(--border))',
139
+ borderRadius: '6px',
140
+ fontSize: '14px',
141
+ }}
142
+ />
143
+ </div>
144
+ </div>
145
+ <DrawerFooter>
146
+ <Button>Save Changes</Button>
147
+ <DrawerClose asChild>
148
+ <Button variant="outline">Cancel</Button>
149
+ </DrawerClose>
150
+ </DrawerFooter>
151
+ </DrawerContent>
152
+ </Drawer>
153
+ ),
154
+ parameters: {
155
+ docs: {
156
+ description: {
157
+ story: 'Drawers can contain forms for quick edits and data entry.',
158
+ },
159
+ },
160
+ },
161
+ }
162
+
163
+ /**
164
+ * With List
165
+ *
166
+ * Drawer containing a list of items.
167
+ */
168
+ export const WithList: Story = {
169
+ render: () => (
170
+ <Drawer>
171
+ <DrawerTrigger asChild>
172
+ <Button variant="outline">View Options</Button>
173
+ </DrawerTrigger>
174
+ <DrawerContent>
175
+ <DrawerHeader>
176
+ <DrawerTitle>Select an Option</DrawerTitle>
177
+ <DrawerDescription>Choose from the available options below.</DrawerDescription>
178
+ </DrawerHeader>
179
+ <div style={{ padding: '16px' }}>
180
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
181
+ {['Option 1', 'Option 2', 'Option 3', 'Option 4'].map((option) => (
182
+ <button
183
+ key={option}
184
+ style={{
185
+ padding: '12px',
186
+ textAlign: 'left',
187
+ border: '1px solid hsl(var(--border))',
188
+ borderRadius: '6px',
189
+ background: 'transparent',
190
+ cursor: 'pointer',
191
+ fontSize: '14px',
192
+ }}
193
+ >
194
+ {option}
195
+ </button>
196
+ ))}
197
+ </div>
198
+ </div>
199
+ <DrawerFooter>
200
+ <DrawerClose asChild>
201
+ <Button variant="outline">Close</Button>
202
+ </DrawerClose>
203
+ </DrawerFooter>
204
+ </DrawerContent>
205
+ </Drawer>
206
+ ),
207
+ parameters: {
208
+ docs: {
209
+ description: {
210
+ story: 'Drawers work well for displaying lists of options or actions.',
211
+ },
212
+ },
213
+ },
214
+ }
215
+
216
+ /**
217
+ * With Scrollable Content
218
+ *
219
+ * Drawer with content that scrolls.
220
+ */
221
+ export const WithScrollableContent: Story = {
222
+ render: () => (
223
+ <Drawer>
224
+ <DrawerTrigger asChild>
225
+ <Button>View Details</Button>
226
+ </DrawerTrigger>
227
+ <DrawerContent>
228
+ <DrawerHeader>
229
+ <DrawerTitle>Long Content</DrawerTitle>
230
+ <DrawerDescription>This drawer contains scrollable content.</DrawerDescription>
231
+ </DrawerHeader>
232
+ <div style={{ padding: '16px', maxHeight: '300px', overflowY: 'auto' }}>
233
+ {Array.from({ length: 20 }, (_, i) => (
234
+ <p key={i} style={{ marginBottom: '12px', fontSize: '14px' }}>
235
+ This is paragraph {i + 1}. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
236
+ </p>
237
+ ))}
238
+ </div>
239
+ <DrawerFooter>
240
+ <DrawerClose asChild>
241
+ <Button>Close</Button>
242
+ </DrawerClose>
243
+ </DrawerFooter>
244
+ </DrawerContent>
245
+ </Drawer>
246
+ ),
247
+ parameters: {
248
+ docs: {
249
+ description: {
250
+ story: 'Drawers can handle scrollable content for longer information.',
251
+ },
252
+ },
253
+ },
254
+ }
255
+
256
+ /**
257
+ * Without Footer
258
+ *
259
+ * Drawer without a footer section.
260
+ */
261
+ export const WithoutFooter: Story = {
262
+ render: () => (
263
+ <Drawer>
264
+ <DrawerTrigger asChild>
265
+ <Button variant="outline">Open</Button>
266
+ </DrawerTrigger>
267
+ <DrawerContent>
268
+ <DrawerHeader>
269
+ <DrawerTitle>Information</DrawerTitle>
270
+ <DrawerDescription>This drawer has no footer actions.</DrawerDescription>
271
+ </DrawerHeader>
272
+ <div style={{ padding: '16px' }}>
273
+ <p>Content without footer actions. Users can swipe down or tap outside to close.</p>
274
+ </div>
275
+ </DrawerContent>
276
+ </Drawer>
277
+ ),
278
+ parameters: {
279
+ docs: {
280
+ description: {
281
+ story: 'Drawers can omit the footer if no actions are needed.',
282
+ },
283
+ },
284
+ },
285
+ }
286
+
287
+ /**
288
+ * Dark Mode Preview
289
+ *
290
+ * Drawer in dark mode to verify theming compatibility.
291
+ */
292
+ export const DarkMode: Story = {
293
+ render: () => (
294
+ <div className="dark" style={{ padding: '24px', background: 'hsl(222.2 84% 4.9%)', borderRadius: '8px' }}>
295
+ <Drawer>
296
+ <DrawerTrigger asChild>
297
+ <Button>Open Drawer</Button>
298
+ </DrawerTrigger>
299
+ <DrawerContent>
300
+ <DrawerHeader>
301
+ <DrawerTitle>Dark Mode Drawer</DrawerTitle>
302
+ <DrawerDescription>This drawer adapts to dark mode automatically.</DrawerDescription>
303
+ </DrawerHeader>
304
+ <div style={{ padding: '16px' }}>
305
+ <p style={{ color: 'hsl(var(--foreground))' }}>
306
+ Drawer content in dark mode with proper contrast and visibility.
307
+ </p>
308
+ </div>
309
+ <DrawerFooter>
310
+ <Button>Action</Button>
311
+ <DrawerClose asChild>
312
+ <Button variant="outline">Cancel</Button>
313
+ </DrawerClose>
314
+ </DrawerFooter>
315
+ </DrawerContent>
316
+ </Drawer>
317
+ </div>
318
+ ),
319
+ parameters: {
320
+ docs: {
321
+ description: {
322
+ story: 'Drawers automatically adapt to dark mode with appropriate contrast.',
323
+ },
324
+ },
325
+ backgrounds: { disable: true },
326
+ },
327
+ }
@@ -0,0 +1,208 @@
1
+ import * as React from "react"
2
+ import {
3
+ Drawer as ShadcnDrawer,
4
+ DrawerPortal as ShadcnDrawerPortal,
5
+ DrawerOverlay as ShadcnDrawerOverlay,
6
+ DrawerTrigger as ShadcnDrawerTrigger,
7
+ DrawerClose as ShadcnDrawerClose,
8
+ DrawerContent as ShadcnDrawerContent,
9
+ DrawerHeader as ShadcnDrawerHeader,
10
+ DrawerFooter as ShadcnDrawerFooter,
11
+ DrawerTitle as ShadcnDrawerTitle,
12
+ DrawerDescription as ShadcnDrawerDescription,
13
+ } from "../../ui/drawer"
14
+
15
+ /**
16
+ * Drawer Primitive
17
+ *
18
+ * A foundational drawer component that wraps shadcn/ui Drawer with design system
19
+ * enhancements. This primitive serves as the single source of truth for all drawer
20
+ * interactions across the application.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * <Drawer>
25
+ * <DrawerTrigger>Open Drawer</DrawerTrigger>
26
+ * <DrawerContent>
27
+ * <DrawerHeader>
28
+ * <DrawerTitle>Drawer Title</DrawerTitle>
29
+ * <DrawerDescription>Drawer description</DrawerDescription>
30
+ * </DrawerHeader>
31
+ * <div>Drawer content</div>
32
+ * <DrawerFooter>
33
+ * <DrawerClose>Close</DrawerClose>
34
+ * </DrawerFooter>
35
+ * </DrawerContent>
36
+ * </Drawer>
37
+ * ```
38
+ *
39
+ * @see https://ui.shadcn.com/docs/components/drawer - shadcn/ui Drawer documentation
40
+ */
41
+
42
+ /**
43
+ * Drawer component props
44
+ */
45
+ export type DrawerProps = React.ComponentProps<typeof ShadcnDrawer>
46
+
47
+ /**
48
+ * Drawer component
49
+ *
50
+ * A drawer component for displaying content in a slide-out panel, built on shadcn/ui foundation.
51
+ *
52
+ * Features:
53
+ * - Slide-out panel from bottom (mobile-first)
54
+ * - Backdrop overlay
55
+ * - Keyboard navigation support
56
+ * - Focus management
57
+ * - Dark mode support
58
+ */
59
+ export const Drawer = ShadcnDrawer
60
+
61
+ Drawer.displayName = "Drawer"
62
+
63
+ /**
64
+ * DrawerPortal component
65
+ *
66
+ * Portal component for rendering drawer content in a portal.
67
+ */
68
+ export const DrawerPortal = ShadcnDrawerPortal
69
+
70
+ DrawerPortal.displayName = "DrawerPortal"
71
+
72
+ /**
73
+ * DrawerOverlay component props
74
+ */
75
+ export type DrawerOverlayProps = React.ComponentPropsWithoutRef<typeof ShadcnDrawerOverlay>
76
+
77
+ /**
78
+ * DrawerOverlay component
79
+ *
80
+ * Backdrop overlay for the drawer.
81
+ */
82
+ export const DrawerOverlay = React.memo(
83
+ React.forwardRef<
84
+ React.ElementRef<typeof ShadcnDrawerOverlay>,
85
+ DrawerOverlayProps
86
+ >((props, ref) => {
87
+ return <ShadcnDrawerOverlay ref={ref} {...props} />
88
+ })
89
+ )
90
+
91
+ DrawerOverlay.displayName = "DrawerOverlay"
92
+
93
+ /**
94
+ * DrawerTrigger component
95
+ *
96
+ * Button that triggers the drawer to open.
97
+ */
98
+ export const DrawerTrigger = ShadcnDrawerTrigger
99
+
100
+ DrawerTrigger.displayName = "DrawerTrigger"
101
+
102
+ /**
103
+ * DrawerClose component
104
+ *
105
+ * Button that closes the drawer.
106
+ */
107
+ export const DrawerClose = ShadcnDrawerClose
108
+
109
+ DrawerClose.displayName = "DrawerClose"
110
+
111
+ /**
112
+ * DrawerContent component props
113
+ */
114
+ export type DrawerContentProps = React.ComponentPropsWithoutRef<typeof ShadcnDrawerContent>
115
+
116
+ /**
117
+ * DrawerContent component
118
+ *
119
+ * Container for drawer content with proper styling and animations.
120
+ */
121
+ export const DrawerContent = React.memo(
122
+ React.forwardRef<
123
+ React.ElementRef<typeof ShadcnDrawerContent>,
124
+ DrawerContentProps
125
+ >((props, ref) => {
126
+ return <ShadcnDrawerContent ref={ref} {...props} />
127
+ })
128
+ )
129
+
130
+ DrawerContent.displayName = "DrawerContent"
131
+
132
+ /**
133
+ * DrawerHeader component props
134
+ */
135
+ export type DrawerHeaderProps = React.HTMLAttributes<HTMLDivElement>
136
+
137
+ /**
138
+ * DrawerHeader component
139
+ *
140
+ * Header section of the drawer for title and description.
141
+ */
142
+ export const DrawerHeader = React.memo(
143
+ React.forwardRef<HTMLDivElement, DrawerHeaderProps>((props, ref) => {
144
+ return <ShadcnDrawerHeader ref={ref} {...props} />
145
+ })
146
+ )
147
+
148
+ DrawerHeader.displayName = "DrawerHeader"
149
+
150
+ /**
151
+ * DrawerFooter component props
152
+ */
153
+ export type DrawerFooterProps = React.HTMLAttributes<HTMLDivElement>
154
+
155
+ /**
156
+ * DrawerFooter component
157
+ *
158
+ * Footer section of the drawer for actions.
159
+ */
160
+ export const DrawerFooter = React.memo(
161
+ React.forwardRef<HTMLDivElement, DrawerFooterProps>((props, ref) => {
162
+ return <ShadcnDrawerFooter ref={ref} {...props} />
163
+ })
164
+ )
165
+
166
+ DrawerFooter.displayName = "DrawerFooter"
167
+
168
+ /**
169
+ * DrawerTitle component props
170
+ */
171
+ export type DrawerTitleProps = React.ComponentPropsWithoutRef<typeof ShadcnDrawerTitle>
172
+
173
+ /**
174
+ * DrawerTitle component
175
+ *
176
+ * Title of the drawer for accessibility.
177
+ */
178
+ export const DrawerTitle = React.memo(
179
+ React.forwardRef<
180
+ React.ElementRef<typeof ShadcnDrawerTitle>,
181
+ DrawerTitleProps
182
+ >((props, ref) => {
183
+ return <ShadcnDrawerTitle ref={ref} {...props} />
184
+ })
185
+ )
186
+
187
+ DrawerTitle.displayName = "DrawerTitle"
188
+
189
+ /**
190
+ * DrawerDescription component props
191
+ */
192
+ export type DrawerDescriptionProps = React.ComponentPropsWithoutRef<typeof ShadcnDrawerDescription>
193
+
194
+ /**
195
+ * DrawerDescription component
196
+ *
197
+ * Description of the drawer for accessibility.
198
+ */
199
+ export const DrawerDescription = React.memo(
200
+ React.forwardRef<
201
+ React.ElementRef<typeof ShadcnDrawerDescription>,
202
+ DrawerDescriptionProps
203
+ >((props, ref) => {
204
+ return <ShadcnDrawerDescription ref={ref} {...props} />
205
+ })
206
+ )
207
+
208
+ DrawerDescription.displayName = "DrawerDescription"