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,188 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { OrchestratorMessage } from './OrchestratorMessage'
3
+ import { SpecialistMessage } from '../SpecialistMessage'
4
+ import { ToolCallDisplay } from '../ToolCallDisplay'
5
+ import { Search, BarChart, FileText } from 'lucide-react'
6
+
7
+ const meta: Meta<typeof OrchestratorMessage> = {
8
+ title: 'Composites/OrchestratorMessage',
9
+ component: OrchestratorMessage,
10
+ parameters: {
11
+ layout: 'padded',
12
+ },
13
+ } satisfies Meta<typeof OrchestratorMessage>
14
+
15
+ export default meta
16
+ type Story = StoryObj<typeof meta>
17
+
18
+ export const Default: Story = {
19
+ args: {
20
+ message: {
21
+ id: '1',
22
+ content: 'I will coordinate the analysis across multiple specialist agents.',
23
+ avatarSrc: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=32&h=32&fit=crop&crop=face',
24
+ avatarName: 'Coordinator',
25
+ },
26
+ showAvatar: true,
27
+ },
28
+ }
29
+
30
+ export const WithoutAvatar: Story = {
31
+ args: {
32
+ message: {
33
+ id: '2',
34
+ content: 'Orchestrating workflow without avatar display...',
35
+ },
36
+ showAvatar: false,
37
+ },
38
+ }
39
+
40
+ export const WithSpecialists: Story = {
41
+ args: {
42
+ message: {
43
+ id: '3',
44
+ content: 'I am delegating tasks to specialized agents for comprehensive analysis.',
45
+ avatarSrc: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=32&h=32&fit=crop&crop=face',
46
+ avatarName: 'Coordinator',
47
+ },
48
+ showAvatar: true,
49
+ children: (
50
+ <>
51
+ <SpecialistMessage
52
+ message={{
53
+ id: 'spec_1',
54
+ name: 'research-agent',
55
+ description: 'Gathering relevant information from multiple sources',
56
+ icon: <Search className="size-4" />,
57
+ content: 'Researching the topic and gathering relevant information...',
58
+ status: 'completed',
59
+ }}
60
+ isNested={true}
61
+ />
62
+ <SpecialistMessage
63
+ message={{
64
+ id: 'spec_2',
65
+ name: 'analysis-agent',
66
+ description: 'Performing comprehensive analysis on research data',
67
+ icon: <BarChart className="size-4" />,
68
+ content: 'Analyzing the collected data and extracting insights...',
69
+ status: 'active',
70
+ }}
71
+ isNested={true}
72
+ />
73
+ <SpecialistMessage
74
+ message={{
75
+ id: 'spec_3',
76
+ name: 'summary-agent',
77
+ description: 'Creating comprehensive summary of findings',
78
+ icon: <FileText className="size-4" />,
79
+ content: 'Preparing comprehensive summary of findings...',
80
+ status: 'pending',
81
+ }}
82
+ isNested={true}
83
+ />
84
+ </>
85
+ ),
86
+ },
87
+ }
88
+
89
+ export const WithToolCalls: Story = {
90
+ args: {
91
+ message: {
92
+ id: '4',
93
+ content: 'Executing direct tool calls before delegating to specialists.',
94
+ avatarSrc: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=32&h=32&fit=crop&crop=face',
95
+ avatarName: 'Coordinator',
96
+ },
97
+ showAvatar: true,
98
+ children: (
99
+ <>
100
+ <ToolCallDisplay
101
+ toolCall={{
102
+ id: 'tool_1',
103
+ name: 'write_file',
104
+ args: { filename: 'plan.md', content: 'Execution plan...' },
105
+ result: 'File created successfully',
106
+ status: 'completed',
107
+ }}
108
+ />
109
+ <ToolCallDisplay
110
+ toolCall={{
111
+ id: 'tool_2',
112
+ name: 'write_todos',
113
+ args: { todos: ['Task 1', 'Task 2', 'Task 3'] },
114
+ result: 'Todo list created',
115
+ status: 'completed',
116
+ }}
117
+ />
118
+ </>
119
+ ),
120
+ },
121
+ }
122
+
123
+ export const CompleteWorkflow: Story = {
124
+ args: {
125
+ message: {
126
+ id: '5',
127
+ content: 'I will manage this complex workflow with both direct tools and specialist agents.',
128
+ avatarSrc: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=32&h=32&fit=crop&crop=face',
129
+ avatarName: 'Coordinator',
130
+ },
131
+ showAvatar: true,
132
+ children: (
133
+ <>
134
+ <ToolCallDisplay
135
+ toolCall={{
136
+ id: 'tool_1',
137
+ name: 'create_plan',
138
+ args: { objective: 'Complete analysis' },
139
+ result: 'Plan created',
140
+ status: 'completed',
141
+ }}
142
+ />
143
+ <SpecialistMessage
144
+ message={{
145
+ id: 'spec_1',
146
+ name: 'data-collector',
147
+ description: 'Collecting data from multiple sources',
148
+ icon: <Search className="size-4" />,
149
+ content: 'Collecting data from multiple sources...',
150
+ status: 'completed',
151
+ toolCalls: [
152
+ {
153
+ id: 'subtool_1',
154
+ name: 'fetch_data',
155
+ args: { source: 'API' },
156
+ result: 'Data fetched',
157
+ status: 'completed',
158
+ },
159
+ ],
160
+ }}
161
+ isNested={true}
162
+ />
163
+ <SpecialistMessage
164
+ message={{
165
+ id: 'spec_2',
166
+ name: 'processor',
167
+ description: 'Processing and transforming the collected data',
168
+ icon: <BarChart className="size-4" />,
169
+ content: 'Processing and transforming the collected data...',
170
+ status: 'active',
171
+ }}
172
+ isNested={true}
173
+ />
174
+ <SpecialistMessage
175
+ message={{
176
+ id: 'spec_3',
177
+ name: 'reporter',
178
+ description: 'Generating final report with visualizations',
179
+ icon: <FileText className="size-4" />,
180
+ content: 'Generating final report with visualizations...',
181
+ status: 'pending',
182
+ }}
183
+ isNested={true}
184
+ />
185
+ </>
186
+ ),
187
+ },
188
+ }
@@ -0,0 +1,72 @@
1
+ import * as React from "react"
2
+ import {
3
+ Message,
4
+ MessageContent,
5
+ MessageAvatar,
6
+ } from "@/components/ai-elements/message"
7
+
8
+ /**
9
+ * OrchestratorMessage Block
10
+ *
11
+ * A block component for displaying orchestrator/coordinator agent messages.
12
+ * Accepts children components (SpecialistMessage and ToolCallDisplay) for composition.
13
+ */
14
+
15
+ export interface OrchestratorMessageData {
16
+ id: string
17
+ content: string
18
+ avatarSrc?: string
19
+ avatarName?: string
20
+ }
21
+
22
+ export interface OrchestratorMessageProps {
23
+ /**
24
+ * Orchestrator message data to display
25
+ */
26
+ message: OrchestratorMessageData
27
+ /**
28
+ * Whether to show avatar
29
+ */
30
+ showAvatar?: boolean
31
+ /**
32
+ * Child components (SpecialistMessage, ToolCallDisplay)
33
+ */
34
+ children?: React.ReactNode
35
+ }
36
+
37
+ /**
38
+ * OrchestratorMessage component - displays coordinator messages with nested specialists and tools
39
+ */
40
+ export const OrchestratorMessage = React.memo<OrchestratorMessageProps>(
41
+ ({ message, showAvatar = true, children }) => {
42
+ const hasContent = React.useMemo(
43
+ () => message.content && message.content.trim() !== "",
44
+ [message.content]
45
+ )
46
+
47
+ return (
48
+ <Message from="assistant">
49
+ {showAvatar && (
50
+ <MessageAvatar
51
+ src={message.avatarSrc || "/coordinator-avatar.png"}
52
+ name={message.avatarName || "Coordinator"}
53
+ />
54
+ )}
55
+
56
+ <div className="flex-1">
57
+ {/* Orchestrator's message content */}
58
+ {hasContent && (
59
+ <MessageContent variant="contained">
60
+ {message.content}
61
+ </MessageContent>
62
+ )}
63
+
64
+ {/* Child components (specialists and tool calls) */}
65
+ {children && <div className="mt-4 space-y-4">{children}</div>}
66
+ </div>
67
+ </Message>
68
+ )
69
+ }
70
+ )
71
+
72
+ OrchestratorMessage.displayName = "OrchestratorMessage"
@@ -0,0 +1,8 @@
1
+ /**
2
+ * OrchestratorMessage Block
3
+ *
4
+ * Central export point for the OrchestratorMessage block component and its related types.
5
+ */
6
+ export { OrchestratorMessage } from './OrchestratorMessage'
7
+
8
+ export type { OrchestratorMessageProps, OrchestratorMessageData } from './OrchestratorMessage'
@@ -0,0 +1,41 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { PageContainer } from './PageContainer'
3
+
4
+ const meta = {
5
+ title: 'Composites/PageContainer',
6
+ component: PageContainer,
7
+ tags: ['autodocs'],
8
+ parameters: {
9
+ layout: 'fullscreen',
10
+ },
11
+ } satisfies Meta<typeof PageContainer>
12
+
13
+ export default meta
14
+ type Story = StoryObj<typeof meta>
15
+
16
+ export const Default: Story = {
17
+ args: {
18
+ children: (
19
+ <div className="p-6">
20
+ <h1 className="text-2xl font-bold">Page Content</h1>
21
+ <p className="mt-4 text-muted-foreground">
22
+ This is the main page content wrapped in PageContainer.
23
+ </p>
24
+ </div>
25
+ ),
26
+ },
27
+ }
28
+
29
+ export const WithCustomClass: Story = {
30
+ args: {
31
+ children: (
32
+ <div className="p-6">
33
+ <h1 className="text-2xl font-bold">Custom Styled Container</h1>
34
+ <p className="mt-4 text-muted-foreground">
35
+ PageContainer with custom className applied.
36
+ </p>
37
+ </div>
38
+ ),
39
+ className: 'bg-muted',
40
+ },
41
+ }
@@ -0,0 +1,24 @@
1
+ import * as React from "react"
2
+ import { SidebarInset } from "@/components/primitives/Sidebar"
3
+
4
+ /**
5
+ * PageContainer Composite
6
+ *
7
+ * Container for page content that works with Sidebar layout.
8
+ * Wraps content with SidebarInset primitive.
9
+ */
10
+
11
+ export interface PageContainerProps {
12
+ children: React.ReactNode
13
+ className?: string
14
+ }
15
+
16
+ export const PageContainer = React.memo<PageContainerProps>(({ children, className }) => {
17
+ return (
18
+ <SidebarInset className={className}>
19
+ {children}
20
+ </SidebarInset>
21
+ )
22
+ })
23
+
24
+ PageContainer.displayName = "PageContainer"
@@ -0,0 +1,2 @@
1
+ export { PageContainer } from './PageContainer'
2
+ export type { PageContainerProps } from './PageContainer'
@@ -0,0 +1,200 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { PromptInput } from "./PromptInput";
3
+ import { useState } from "react";
4
+
5
+ const meta: Meta<typeof PromptInput> = {
6
+ title: "Blocks/PromptInput",
7
+ component: PromptInput,
8
+ parameters: {
9
+ layout: "padded",
10
+ },
11
+ argTypes: {
12
+ disabled: {
13
+ control: "boolean",
14
+ description: "Blocks form submission when true. Textarea remains editable.",
15
+ },
16
+ placeholder: {
17
+ control: "text",
18
+ description: "Placeholder text for the textarea input",
19
+ },
20
+ },
21
+ } satisfies Meta<typeof PromptInput>;
22
+
23
+ export default meta;
24
+ type Story = StoryObj<typeof meta>;
25
+
26
+ /**
27
+ * Default uncontrolled PromptInput
28
+ * The AI element manages its own internal state
29
+ */
30
+ export const Default: Story = {
31
+ args: {
32
+ placeholder: "What would you like to know?",
33
+ onSubmit: (message) => {
34
+ console.log("Submitted:", message);
35
+ alert(`Submitted: ${message.text}`);
36
+ },
37
+ },
38
+ };
39
+
40
+ /**
41
+ * Controlled state example
42
+ * Parent component manages the input value
43
+ */
44
+ export const ControlledState: Story = {
45
+ render: () => {
46
+ const [value, setValue] = useState("");
47
+ const [submittedMessages, setSubmittedMessages] = useState<string[]>([]);
48
+
49
+ return (
50
+ <div className="space-y-4">
51
+ <div className="rounded-md border border-border bg-muted p-4">
52
+ <h3 className="mb-2 font-semibold text-sm">Parent State:</h3>
53
+ <p className="font-mono text-xs">
54
+ Current value: "{value}" ({value.length} chars)
55
+ </p>
56
+ </div>
57
+
58
+ <PromptInput
59
+ value={value}
60
+ onChange={setValue}
61
+ placeholder="Type something (controlled mode)"
62
+ onSubmit={(message) => {
63
+ setSubmittedMessages((prev) => [...prev, message.text || ""]);
64
+ setValue(""); // Clear after submit
65
+ }}
66
+ />
67
+
68
+ {submittedMessages.length > 0 && (
69
+ <div className="rounded-md border border-border bg-muted p-4">
70
+ <h3 className="mb-2 font-semibold text-sm">Submitted Messages:</h3>
71
+ <ul className="space-y-1">
72
+ {submittedMessages.map((msg, i) => (
73
+ <li key={i} className="font-mono text-xs">
74
+ {i + 1}. {msg}
75
+ </li>
76
+ ))}
77
+ </ul>
78
+ </div>
79
+ )}
80
+ </div>
81
+ );
82
+ },
83
+ };
84
+
85
+ /**
86
+ * Disabled state
87
+ * Form submission is blocked, but textarea remains editable for drafts
88
+ */
89
+ export const DisabledState: Story = {
90
+ render: () => {
91
+ const [isDisabled, setIsDisabled] = useState(true);
92
+
93
+ return (
94
+ <div className="space-y-4">
95
+ <div className="rounded-md border border-border bg-muted p-4">
96
+ <label className="flex items-center gap-2">
97
+ <input
98
+ type="checkbox"
99
+ checked={isDisabled}
100
+ onChange={(e) => setIsDisabled(e.target.checked)}
101
+ />
102
+ <span className="text-sm">Disable submission (textarea stays editable)</span>
103
+ </label>
104
+ </div>
105
+
106
+ <PromptInput
107
+ disabled={isDisabled}
108
+ placeholder="Try typing and submitting (disabled mode)"
109
+ onSubmit={(message) => {
110
+ alert(`This should not appear when disabled! Message: ${message.text}`);
111
+ }}
112
+ />
113
+
114
+ <div className="rounded-md border border-border bg-muted p-4">
115
+ <p className="text-muted-foreground text-xs">
116
+ When disabled, the submit button is blocked but you can still type in the textarea.
117
+ This is useful for review workflows where users can draft responses but cannot submit until approval.
118
+ </p>
119
+ </div>
120
+ </div>
121
+ );
122
+ },
123
+ };
124
+
125
+ /**
126
+ * Custom placeholder
127
+ * Different placeholder text for various contexts
128
+ */
129
+ export const CustomPlaceholder: Story = {
130
+ args: {
131
+ placeholder: "Ask a question or describe a task...",
132
+ onSubmit: (message) => {
133
+ console.log("Submitted:", message);
134
+ },
135
+ },
136
+ };
137
+
138
+ /**
139
+ * Custom submit handler
140
+ * Demonstrates async submit handling with loading state
141
+ */
142
+ export const CustomSubmitHandler: Story = {
143
+ render: () => {
144
+ const [isSubmitting, setIsSubmitting] = useState(false);
145
+ const [lastSubmitted, setLastSubmitted] = useState<string>("");
146
+
147
+ return (
148
+ <div className="space-y-4">
149
+ {isSubmitting && (
150
+ <div className="rounded-md border border-border bg-muted p-4">
151
+ <p className="text-sm">Processing your message...</p>
152
+ </div>
153
+ )}
154
+
155
+ {lastSubmitted && (
156
+ <div className="rounded-md border border-border bg-muted p-4">
157
+ <h3 className="mb-2 font-semibold text-sm">Last Submitted:</h3>
158
+ <p className="font-mono text-xs">{lastSubmitted}</p>
159
+ </div>
160
+ )}
161
+
162
+ <PromptInput
163
+ placeholder="Type something and submit (simulates 2s async processing)"
164
+ disabled={isSubmitting}
165
+ onSubmit={async (message) => {
166
+ setIsSubmitting(true);
167
+ // Simulate async processing
168
+ await new Promise((resolve) => setTimeout(resolve, 2000));
169
+ setLastSubmitted(message.text || "");
170
+ setIsSubmitting(false);
171
+ }}
172
+ />
173
+ </div>
174
+ );
175
+ },
176
+ };
177
+
178
+ /**
179
+ * No attachment UI
180
+ * Verifies compositional hiding - no attachment components visible
181
+ */
182
+ export const NoAttachmentUI: Story = {
183
+ args: {
184
+ placeholder: "Text-only input - no attachment options available",
185
+ onSubmit: (message) => {
186
+ console.log("Message with files array:", message);
187
+ alert(
188
+ `Text: ${message.text}\nFiles: ${message.files?.length || 0} (should always be 0)`
189
+ );
190
+ },
191
+ },
192
+ parameters: {
193
+ docs: {
194
+ description: {
195
+ story:
196
+ "The PromptInput block hides all attachment-related UI through compositional hiding. No attachment buttons, dropdowns, or drag-drop functionality is exposed.",
197
+ },
198
+ },
199
+ },
200
+ };
@@ -0,0 +1,129 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import {
5
+ PromptInput as AIPromptInput,
6
+ PromptInputBody,
7
+ PromptInputFooter,
8
+ PromptInputSubmit,
9
+ PromptInputTextarea,
10
+ PromptInputTools,
11
+ PromptInputProvider,
12
+ type PromptInputMessage,
13
+ type PromptInputProps as AIPromptInputProps,
14
+ } from "@/components/ai-elements/prompt-input";
15
+ import type { FormEvent } from "react";
16
+
17
+ /**
18
+ * PromptInput Block
19
+ *
20
+ * A thin wrapper around the PromptInput AI element that hides attachment functionality.
21
+ * This block provides a simplified prompt input interface focused on text-only input.
22
+ *
23
+ * Features:
24
+ * - Controlled and uncontrolled state support
25
+ * - Disabled state (blocks submission, keeps textarea editable)
26
+ * - Custom placeholder text
27
+ * - No attachment UI (compositional hiding)
28
+ */
29
+
30
+ export interface PromptInputBlockProps
31
+ extends Omit<
32
+ AIPromptInputProps,
33
+ "accept" | "multiple" | "maxFiles" | "maxFileSize" | "globalDrop" | "syncHiddenInput" | "onSubmit" | "onChange"
34
+ > {
35
+ /**
36
+ * Blocks form submission when true. Textarea remains editable for drafts.
37
+ */
38
+ disabled?: boolean;
39
+ /**
40
+ * Placeholder text for the textarea input
41
+ */
42
+ placeholder?: string;
43
+ /**
44
+ * Controlled state value (when provided with onChange)
45
+ */
46
+ value?: string;
47
+ /**
48
+ * Controlled state change handler (when provided with value)
49
+ */
50
+ onChange?: (value: string) => void;
51
+ /**
52
+ * Submit handler called when form is submitted
53
+ */
54
+ onSubmit: (
55
+ message: PromptInputMessage,
56
+ event: FormEvent<HTMLFormElement>
57
+ ) => void | Promise<void>;
58
+ }
59
+
60
+ /**
61
+ * PromptInput component - text-only prompt input without attachments
62
+ */
63
+ export const PromptInput = React.memo<PromptInputBlockProps>(
64
+ ({
65
+ disabled = false,
66
+ placeholder,
67
+ value,
68
+ onChange,
69
+ onSubmit,
70
+ ...props
71
+ }) => {
72
+ // Handle form submission with disabled state
73
+ const handleSubmit = React.useCallback(
74
+ (message: PromptInputMessage, event: FormEvent<HTMLFormElement>) => {
75
+ if (disabled) {
76
+ event.preventDefault();
77
+ return;
78
+ }
79
+ onSubmit(message, event);
80
+ },
81
+ [disabled, onSubmit]
82
+ );
83
+
84
+ // Controlled mode: wrap in PromptInputProvider
85
+ const isControlled = value !== undefined && onChange !== undefined;
86
+
87
+ // Handle controlled state change
88
+ const handleControlledChange = React.useCallback(
89
+ (e: React.ChangeEvent<HTMLTextAreaElement>) => {
90
+ if (onChange) {
91
+ onChange(e.target.value);
92
+ }
93
+ },
94
+ [onChange]
95
+ );
96
+
97
+ // Render the prompt input composition
98
+ const promptInputContent = (
99
+ <AIPromptInput onSubmit={handleSubmit} {...props}>
100
+ <PromptInputBody>
101
+ <PromptInputTextarea
102
+ placeholder={placeholder}
103
+ disabled={false} // Keep editable even when form is disabled
104
+ onChange={isControlled ? handleControlledChange : undefined}
105
+ />
106
+ </PromptInputBody>
107
+ <PromptInputFooter>
108
+ <PromptInputTools>
109
+ {/* No attachment menu - compositionally hidden */}
110
+ </PromptInputTools>
111
+ <PromptInputSubmit disabled={disabled} />
112
+ </PromptInputFooter>
113
+ </AIPromptInput>
114
+ );
115
+
116
+ // Wrap in provider for controlled mode
117
+ if (isControlled) {
118
+ return (
119
+ <PromptInputProvider initialInput={value}>
120
+ {promptInputContent}
121
+ </PromptInputProvider>
122
+ );
123
+ }
124
+
125
+ return promptInputContent;
126
+ }
127
+ );
128
+
129
+ PromptInput.displayName = "PromptInput";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * PromptInput Block
3
+ *
4
+ * Central export point for the PromptInput block component and its related types.
5
+ */
6
+ export { PromptInput } from "./PromptInput";
7
+
8
+ export type { PromptInputBlockProps } from "./PromptInput";