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,141 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { RefinementPanel } from "./RefinementPanel";
3
+ import type { PromptInputMessage } from "@/components/ai-elements/prompt-input";
4
+ import { useMockRefinementPanel } from "./useRefinementPanel.mock";
5
+ import { inputStateMessages, reviewStateMessages, sampleFileChanges } from "./RefinementPanel.mocks";
6
+ import * as React from "react";
7
+
8
+ const meta: Meta<typeof RefinementPanel> = {
9
+ title: "Features/RefinementPanel",
10
+ component: RefinementPanel,
11
+ parameters: {
12
+ layout: "fullscreen",
13
+ },
14
+ } satisfies Meta<typeof RefinementPanel>;
15
+
16
+ export default meta;
17
+ type Story = StoryObj<typeof meta>;
18
+
19
+ /**
20
+ * Input State - Clean interface for submitting refinement requests
21
+ *
22
+ * Shows:
23
+ * - Conversation history with previous interactions
24
+ * - Prompt input for new refinement requests
25
+ * - Simple, focused layout
26
+ */
27
+ export const InputState: Story = {
28
+ args: {
29
+ messages: inputStateMessages,
30
+ placeholder: "Ask a question or describe a task...",
31
+ onSubmit: (message: PromptInputMessage) => {
32
+ console.log("Submitted:", message);
33
+ alert(`Submitted: ${message.text}`);
34
+ },
35
+ },
36
+ parameters: {
37
+ docs: {
38
+ description: {
39
+ story:
40
+ "Clean input interface for submitting refinement requests with conversation history. The user can type and submit new requests.",
41
+ },
42
+ },
43
+ },
44
+ };
45
+
46
+ /**
47
+ * Input State - Empty conversation
48
+ *
49
+ * Shows the empty state when no messages exist yet
50
+ */
51
+ export const InputStateEmpty: Story = {
52
+ args: {
53
+ messages: [],
54
+ placeholder: "Ask a question or describe a task...",
55
+ onSubmit: (message: PromptInputMessage) => {
56
+ console.log("Submitted:", message);
57
+ },
58
+ },
59
+ };
60
+
61
+ /**
62
+ * Multi-Agent Review State - Full workflow with agents, file changes, and approval
63
+ *
64
+ * Shows:
65
+ * - Agent conversations with orchestrator and specialists
66
+ * - Tool call displays showing agent actions
67
+ * - Sub-agent indicators with status
68
+ * - File change queue with approve/reject buttons
69
+ * - Disabled input (textarea editable, submit blocked)
70
+ */
71
+ export const MultiAgentReviewState: Story = {
72
+ args: {
73
+ messages: reviewStateMessages,
74
+ fileChanges: sampleFileChanges,
75
+ placeholder: "Continue refinement...",
76
+ onSubmit: (message: PromptInputMessage) => {
77
+ console.log("Submit blocked during review:", message);
78
+ },
79
+ onApprove: () => {
80
+ console.log("Approved all changes");
81
+ alert("✅ All changes approved!");
82
+ },
83
+ onReject: () => {
84
+ console.log("Rejected all changes");
85
+ alert("❌ All changes rejected!");
86
+ },
87
+ },
88
+ parameters: {
89
+ docs: {
90
+ description: {
91
+ story:
92
+ "Full multi-agent review interface showing agent conversations, file changes, tool calls, and approval workflow. The input is disabled during review.",
93
+ },
94
+ },
95
+ },
96
+ };
97
+
98
+ /**
99
+ * With State Management - Interactive behavior demonstration
100
+ *
101
+ * Demonstrates the complete refinement workflow with mocked state management:
102
+ * 1. User submits a refinement request
103
+ * 2. System transitions to review state with file changes
104
+ * 3. User approves or rejects changes
105
+ * 4. System returns to input state
106
+ *
107
+ * This story uses the useMockRefinementPanel hook to simulate realistic interaction patterns.
108
+ * Use this mock hook as a reference for implementing real application hooks.
109
+ */
110
+ export const WithStateManagement: Story = {
111
+ render: () => {
112
+ // Use mocked hook for state management
113
+ const { messages, fileChanges, handleSubmit, handleApprove, handleReject } =
114
+ useMockRefinementPanel({
115
+ initialMessages: inputStateMessages,
116
+ reviewMessages: reviewStateMessages,
117
+ reviewFileChanges: sampleFileChanges,
118
+ apiDelay: 800,
119
+ });
120
+
121
+ return (
122
+ <RefinementPanel
123
+ messages={messages}
124
+ fileChanges={fileChanges}
125
+ placeholder="Ask a question or describe a task..."
126
+ onSubmit={handleSubmit}
127
+ onApprove={handleApprove}
128
+ onReject={handleReject}
129
+ />
130
+ );
131
+ },
132
+ parameters: {
133
+ docs: {
134
+ description: {
135
+ story:
136
+ "Interactive demonstration of the complete refinement workflow using the useMockRefinementPanel hook. This story simulates realistic user interactions including submission delays, state transitions, and approval/rejection flows. Use this mock hook as a reference for implementing real application hooks.",
137
+ },
138
+ },
139
+ },
140
+ };
141
+
@@ -0,0 +1,160 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { AIConversation } from "@/components/blocks/AIConversation";
5
+ import { FileChangeQueue } from "@/components/blocks/FileChangeQueue";
6
+ import { PromptInput } from "@/components/composites/PromptInput";
7
+ import type { ToolCall } from "@/components/composites/ToolCallDisplay";
8
+ import type { SubAgent } from "@/components/composites/AgentIndicator";
9
+ import type { FileChangeData } from "@/components/composites/FileQueue";
10
+ import type { PromptInputMessage } from "@/components/ai-elements/prompt-input";
11
+ import type { FormEvent } from "react";
12
+
13
+ /**
14
+ * RefinementPanel Feature
15
+ *
16
+ * A two-state feature component for AI-powered code refinement workflows.
17
+ * Enables users to submit refinement requests and review multi-agent generated changes.
18
+ *
19
+ * States:
20
+ * - input: Clean interface for submitting refinement requests
21
+ * - multi-agent-review: Complex interface showing agent conversations and file changes
22
+ */
23
+
24
+ /**
25
+ * Message data structure for conversation display
26
+ */
27
+ export interface RefinementMessage {
28
+ id: string;
29
+ type: "human" | "ai";
30
+ role: "user" | "orchestrator" | "specialist";
31
+ content: string;
32
+ avatarSrc?: string;
33
+ avatarName?: string;
34
+ toolCalls?: ToolCall[];
35
+ subAgents?: SubAgent[];
36
+ }
37
+
38
+ /**
39
+ * RefinementPanel component props
40
+ */
41
+ export interface RefinementPanelProps {
42
+ /**
43
+ * Conversation messages to display
44
+ */
45
+ messages: RefinementMessage[];
46
+ /**
47
+ * File changes to review
48
+ */
49
+ fileChanges?: FileChangeData[];
50
+ /**
51
+ * Submit handler for user input
52
+ */
53
+ onSubmit: (
54
+ message: PromptInputMessage,
55
+ event: FormEvent<HTMLFormElement>
56
+ ) => void | Promise<void>;
57
+ /**
58
+ * Approve handler for file changes
59
+ */
60
+ onApprove?: () => void;
61
+ /**
62
+ * Reject handler for file changes
63
+ */
64
+ onReject?: () => void;
65
+ /**
66
+ * Placeholder text for input
67
+ */
68
+ placeholder?: string;
69
+ /**
70
+ * Additional CSS classes
71
+ */
72
+ className?: string;
73
+ }
74
+
75
+ /**
76
+ * RefinementPanel component - two-state refinement workflow interface
77
+ */
78
+ export const RefinementPanel = React.memo<RefinementPanelProps>(
79
+ ({
80
+ messages,
81
+ fileChanges = [],
82
+ onSubmit,
83
+ onApprove,
84
+ onReject,
85
+ placeholder = "Ask a question or describe a task...",
86
+ className,
87
+ }) => {
88
+ // File change queue state
89
+ const [fileChangeState, setFileChangeState] = React.useState<
90
+ "approval-requested" | "approval-responded"
91
+ >("approval-requested");
92
+ const [approval, setApproval] = React.useState<
93
+ { approved?: boolean }
94
+ >({});
95
+
96
+ // Handle approve action
97
+ const handleApprove = React.useCallback(() => {
98
+ setFileChangeState("approval-responded");
99
+ setApproval({ approved: true });
100
+ onApprove?.();
101
+ }, [onApprove]);
102
+
103
+ // Handle reject action
104
+ const handleReject = React.useCallback(() => {
105
+ setFileChangeState("approval-responded");
106
+ setApproval({ approved: false });
107
+ onReject?.();
108
+ }, [onReject]);
109
+
110
+ // Reset file change state when fileChanges are cleared
111
+ React.useEffect(() => {
112
+ if (fileChanges.length === 0) {
113
+ setFileChangeState("approval-requested");
114
+ setApproval({});
115
+ }
116
+ }, [fileChanges.length]);
117
+
118
+
119
+
120
+ return (
121
+ <div className={`relative flex h-screen flex-col ${className || ""}`}>
122
+ {/* Conversation Area - Override to prevent double scroll (StickToBottom handles scroll internally) */}
123
+ <AIConversation
124
+ messages={messages}
125
+ showAvatars={true}
126
+ className="relative min-h-0 flex-1 overflow-visible"
127
+ />
128
+
129
+ {/* File Changes Queue (fixed at bottom, constrained height) */}
130
+ {fileChanges.length > 0 && (
131
+ <div className="w-full flex-shrink-0 border-t">
132
+ <div className="max-h-[40vh] overflow-y-auto bg-background">
133
+ <FileChangeQueue
134
+ changes={fileChanges}
135
+ title="Review and approve these file changes"
136
+ state={fileChangeState}
137
+ approval={approval}
138
+ onApprove={handleApprove}
139
+ onReject={handleReject}
140
+ />
141
+ </div>
142
+ </div>
143
+ )}
144
+
145
+ {/* Input Area (visible only when no file changes to review) */}
146
+ {fileChanges.length === 0 && (
147
+ <div className="w-full flex-shrink-0">
148
+ <PromptInput
149
+ placeholder={placeholder}
150
+ onSubmit={onSubmit}
151
+ className="border-t"
152
+ />
153
+ </div>
154
+ )}
155
+ </div>
156
+ );
157
+ }
158
+ );
159
+
160
+ RefinementPanel.displayName = "RefinementPanel";
@@ -0,0 +1,25 @@
1
+ /**
2
+ * RefinementPanel Feature
3
+ *
4
+ * Export point for the RefinementPanel feature component and related utilities.
5
+ *
6
+ * Component:
7
+ * - RefinementPanel: Main feature component for refinement workflows
8
+ *
9
+ * Hook Contract:
10
+ * - useRefinementPanel: Interface definition for application hooks (implement in your app)
11
+ * - UseRefinementPanelReturn: Return type for the hook
12
+ *
13
+ * Mock Utilities (for testing/development):
14
+ * - useMockRefinementPanel: Mock implementation for Storybook
15
+ */
16
+
17
+ export { RefinementPanel } from "./RefinementPanel";
18
+ export type { RefinementPanelProps, RefinementMessage } from "./RefinementPanel";
19
+
20
+ // Hook contract definition (implement in your application)
21
+ export type { UseRefinementPanelReturn } from "./useRefinementPanel";
22
+
23
+ // Mock hook for testing and development
24
+ export { useMockRefinementPanel } from "./useRefinementPanel.mock";
25
+ export type { UseRefinementPanelOptions } from "./useRefinementPanel.mock";
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Hook Contract Definition for RefinementPanel
3
+ *
4
+ * This file defines the interface contract between the design system and consuming applications.
5
+ * It specifies the expected behavior of a real application hook without providing implementation.
6
+ *
7
+ * Applications should implement this interface with real API calls and state management.
8
+ * The design system provides a mock implementation (useRefinementPanel.mock.ts) for Storybook.
9
+ */
10
+
11
+ import type { RefinementMessage } from "./RefinementPanel";
12
+ import type { FileChangeData } from "@/components/composites/FileQueue";
13
+
14
+ /**
15
+ * Return type for the refinement panel hook
16
+ *
17
+ * This interface defines what state and handlers the hook must provide
18
+ * to integrate with the RefinementPanel component.
19
+ */
20
+ export interface UseRefinementPanelReturn {
21
+ /** Current conversation messages */
22
+ messages: RefinementMessage[];
23
+
24
+ /** File changes pending review */
25
+ fileChanges: FileChangeData[];
26
+
27
+ /** Loading state for async operations */
28
+ loading: boolean;
29
+
30
+ /** Handle user submission of refinement requests */
31
+ handleSubmit: () => Promise<void> | void;
32
+
33
+ /** Handle approval of all file changes */
34
+ handleApprove: () => Promise<void> | void;
35
+
36
+ /** Handle rejection of all file changes */
37
+ handleReject: () => Promise<void> | void;
38
+ }
39
+
40
+ /**
41
+ * Hook for managing refinement panel state and interactions
42
+ *
43
+ * Applications should implement this hook to:
44
+ * - Fetch and manage conversation messages
45
+ * - Process user refinement requests via API
46
+ * - Handle file change approval/rejection workflows
47
+ * - Manage loading states during async operations
48
+ *
49
+ * @example
50
+ * ```tsx
51
+ * // Real application implementation
52
+ * export function useRefinementPanel(): UseRefinementPanelReturn {
53
+ * const [messages, setMessages] = useState<RefinementMessage[]>([]);
54
+ * const [fileChanges, setFileChanges] = useState<FileChangeData[]>([]);
55
+ * const [loading, setLoading] = useState(false);
56
+ *
57
+ * const handleSubmit = async () => {
58
+ * setLoading(true);
59
+ * try {
60
+ * const response = await api.submitRefinement(messages);
61
+ * setMessages(response.messages);
62
+ * setFileChanges(response.fileChanges);
63
+ * } finally {
64
+ * setLoading(false);
65
+ * }
66
+ * };
67
+ *
68
+ * // ... implement handleApprove and handleReject
69
+ *
70
+ * return { messages, fileChanges, loading, handleSubmit, handleApprove, handleReject };
71
+ * }
72
+ * ```
73
+ */
74
+ export function useRefinementPanel(): UseRefinementPanelReturn;
@@ -0,0 +1,121 @@
1
+ import { useState, useCallback } from "react";
2
+ import type { RefinementMessage } from "./RefinementPanel";
3
+ import type { FileChangeData } from "@/components/composites/FileQueue";
4
+
5
+ /**
6
+ * Mock hook for RefinementPanel state management
7
+ *
8
+ * This mock simulates the behavior of a real application hook that would:
9
+ * - Manage conversation messages
10
+ * - Handle file changes from agent processing
11
+ * - Process user submissions
12
+ * - Handle approval/rejection workflows
13
+ *
14
+ * Use this as a reference for implementing real application hooks.
15
+ */
16
+ export interface UseRefinementPanelReturn {
17
+ messages: RefinementMessage[];
18
+ fileChanges: FileChangeData[];
19
+ loading: boolean;
20
+ handleSubmit: () => Promise<void>;
21
+ handleApprove: () => Promise<void>;
22
+ handleReject: () => Promise<void>;
23
+ }
24
+
25
+ export interface UseRefinementPanelOptions {
26
+ initialMessages?: RefinementMessage[];
27
+ reviewMessages?: RefinementMessage[];
28
+ reviewFileChanges?: FileChangeData[];
29
+ apiDelay?: number;
30
+ }
31
+
32
+ /**
33
+ * Mock implementation of refinement panel state management
34
+ *
35
+ * @param options - Configuration for mock behavior
36
+ * @returns State and handlers for refinement workflow
37
+ */
38
+ export function useMockRefinementPanel(
39
+ options: UseRefinementPanelOptions = {}
40
+ ): UseRefinementPanelReturn {
41
+ const {
42
+ initialMessages = [],
43
+ reviewMessages = [],
44
+ reviewFileChanges = [],
45
+ apiDelay = 800,
46
+ } = options;
47
+
48
+ const [messages, setMessages] = useState<RefinementMessage[]>(initialMessages);
49
+ const [fileChanges, setFileChanges] = useState<FileChangeData[]>([]);
50
+ const [loading, setLoading] = useState(false);
51
+
52
+ // Simulate submission: transition to review state with agent processing
53
+ const handleSubmit = useCallback(async () => {
54
+ setLoading(true);
55
+
56
+ // Simulate API call delay
57
+ await new Promise((resolve) => setTimeout(resolve, apiDelay));
58
+
59
+ // Transition to review state with agent messages and file changes
60
+ setMessages(reviewMessages);
61
+ setFileChanges(reviewFileChanges);
62
+ setLoading(false);
63
+ }, [reviewMessages, reviewFileChanges, apiDelay]);
64
+
65
+ // Simulate approval: clear file changes and add success message
66
+ const handleApprove = useCallback(async () => {
67
+ setLoading(true);
68
+
69
+ // Simulate API call delay
70
+ await new Promise((resolve) => setTimeout(resolve, apiDelay));
71
+
72
+ // Add success message and clear file changes
73
+ setMessages((prev) => [
74
+ ...prev,
75
+ {
76
+ id: `msg-${Date.now()}`,
77
+ type: "ai",
78
+ role: "orchestrator",
79
+ content: "✅ Changes approved and applied successfully!",
80
+ avatarSrc:
81
+ "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=32&h=32&fit=crop&crop=face",
82
+ avatarName: "Coordinator",
83
+ },
84
+ ]);
85
+ setFileChanges([]);
86
+ setLoading(false);
87
+ }, [apiDelay]);
88
+
89
+ // Simulate rejection: clear file changes and add rejection message
90
+ const handleReject = useCallback(async () => {
91
+ setLoading(true);
92
+
93
+ // Simulate API call delay
94
+ await new Promise((resolve) => setTimeout(resolve, apiDelay));
95
+
96
+ // Add rejection message and clear file changes
97
+ setMessages((prev) => [
98
+ ...prev,
99
+ {
100
+ id: `msg-${Date.now()}`,
101
+ type: "ai",
102
+ role: "orchestrator",
103
+ content: "❌ Changes rejected. Let me know how to improve them.",
104
+ avatarSrc:
105
+ "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=32&h=32&fit=crop&crop=face",
106
+ avatarName: "Coordinator",
107
+ },
108
+ ]);
109
+ setFileChanges([]);
110
+ setLoading(false);
111
+ }, [apiDelay]);
112
+
113
+ return {
114
+ messages,
115
+ fileChanges,
116
+ loading,
117
+ handleSubmit,
118
+ handleApprove,
119
+ handleReject,
120
+ };
121
+ }