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.
- package/README.md +307 -0
- package/components/ai-elements/actions.tsx +65 -0
- package/components/ai-elements/artifact.tsx +147 -0
- package/components/ai-elements/branch.tsx +212 -0
- package/components/ai-elements/canvas.tsx +24 -0
- package/components/ai-elements/chain-of-thought.tsx +228 -0
- package/components/ai-elements/code-block.tsx +179 -0
- package/components/ai-elements/confirmation.tsx +169 -0
- package/components/ai-elements/connection.tsx +28 -0
- package/components/ai-elements/context.tsx +408 -0
- package/components/ai-elements/controls.tsx +18 -0
- package/components/ai-elements/conversation.tsx +97 -0
- package/components/ai-elements/edge.tsx +140 -0
- package/components/ai-elements/image.tsx +24 -0
- package/components/ai-elements/inline-citation.tsx +287 -0
- package/components/ai-elements/loader.tsx +96 -0
- package/components/ai-elements/message.tsx +80 -0
- package/components/ai-elements/node.tsx +71 -0
- package/components/ai-elements/open-in-chat.tsx +363 -0
- package/components/ai-elements/panel.tsx +15 -0
- package/components/ai-elements/plan.tsx +142 -0
- package/components/ai-elements/prompt-input.tsx +1352 -0
- package/components/ai-elements/queue.tsx +274 -0
- package/components/ai-elements/reasoning.tsx +178 -0
- package/components/ai-elements/response.tsx +22 -0
- package/components/ai-elements/shimmer.tsx +64 -0
- package/components/ai-elements/sources.tsx +77 -0
- package/components/ai-elements/suggestion.tsx +56 -0
- package/components/ai-elements/task.tsx +87 -0
- package/components/ai-elements/tool.tsx +179 -0
- package/components/ai-elements/toolbar.tsx +16 -0
- package/components/ai-elements/web-preview.tsx +263 -0
- package/components/blocks/AIConversation/AIConversation.stories.tsx +164 -0
- package/components/blocks/AIConversation/AIConversation.tsx +186 -0
- package/components/blocks/AIConversation/index.ts +8 -0
- package/components/blocks/AppSidebar/AppSidebar.stories.tsx +63 -0
- package/components/blocks/AppSidebar/AppSidebar.tsx +87 -0
- package/components/blocks/AppSidebar/index.ts +2 -0
- package/components/blocks/DocumentEditorWithComments/DocumentEditorWithComments.stories.tsx +341 -0
- package/components/blocks/DocumentEditorWithComments/DocumentEditorWithComments.tsx +255 -0
- package/components/blocks/DocumentEditorWithComments/index.ts +9 -0
- package/components/blocks/FileChangeQueue/FileChangeQueue.stories.tsx +207 -0
- package/components/blocks/FileChangeQueue/FileChangeQueue.tsx +143 -0
- package/components/blocks/FileChangeQueue/index.ts +7 -0
- package/components/blocks/LayoutProvider/LayoutProvider.tsx +34 -0
- package/components/blocks/LayoutProvider/index.ts +1 -0
- package/components/blocks/index.ts +2 -0
- package/components/composites/AgentIndicator/AgentIndicator.stories.tsx +154 -0
- package/components/composites/AgentIndicator/AgentIndicator.tsx +102 -0
- package/components/composites/AgentIndicator/index.ts +8 -0
- package/components/composites/AppHeader/AppHeader.stories.tsx +46 -0
- package/components/composites/AppHeader/AppHeader.tsx +24 -0
- package/components/composites/AppHeader/index.ts +2 -0
- package/components/composites/CommentBox/CommentBox.stories.tsx +192 -0
- package/components/composites/CommentBox/CommentBox.tsx +364 -0
- package/components/composites/CommentBox/index.ts +8 -0
- package/components/composites/Confirmation/Confirmation.stories.tsx +151 -0
- package/components/composites/Confirmation/Confirmation.tsx +93 -0
- package/components/composites/Confirmation/index.ts +7 -0
- package/components/composites/DataTable/DataTable.stories.tsx +35 -0
- package/components/composites/DataTable/DataTable.tsx +95 -0
- package/components/composites/DataTable/index.ts +2 -0
- package/components/composites/DocumentEditor/DocumentEditor.css +106 -0
- package/components/composites/DocumentEditor/DocumentEditor.stories.tsx +927 -0
- package/components/composites/DocumentEditor/DocumentEditor.tsx +279 -0
- package/components/composites/DocumentEditor/index.ts +8 -0
- package/components/composites/FileQueue/FileQueue.stories.tsx +175 -0
- package/components/composites/FileQueue/FileQueue.tsx +161 -0
- package/components/composites/FileQueue/FileStatusBadge.tsx +74 -0
- package/components/composites/FileQueue/index.ts +24 -0
- package/components/composites/InteractiveChart/InteractiveChart.stories.tsx +49 -0
- package/components/composites/InteractiveChart/InteractiveChart.tsx +69 -0
- package/components/composites/InteractiveChart/index.ts +2 -0
- package/components/composites/ModeToggle/ModeToggle.stories.tsx +212 -0
- package/components/composites/ModeToggle/ModeToggle.tsx +100 -0
- package/components/composites/ModeToggle/index.ts +7 -0
- package/components/composites/NavUser/NavUser.stories.tsx +50 -0
- package/components/composites/NavUser/NavUser.tsx +60 -0
- package/components/composites/NavUser/index.ts +2 -0
- package/components/composites/NavigationList/NavigationList.stories.tsx +46 -0
- package/components/composites/NavigationList/NavigationList.tsx +46 -0
- package/components/composites/NavigationList/index.ts +2 -0
- package/components/composites/OrchestratorMessage/OrchestratorMessage.stories.tsx +188 -0
- package/components/composites/OrchestratorMessage/OrchestratorMessage.tsx +72 -0
- package/components/composites/OrchestratorMessage/index.ts +8 -0
- package/components/composites/PageContainer/PageContainer.stories.tsx +41 -0
- package/components/composites/PageContainer/PageContainer.tsx +24 -0
- package/components/composites/PageContainer/index.ts +2 -0
- package/components/composites/PromptInput/PromptInput.stories.tsx +200 -0
- package/components/composites/PromptInput/PromptInput.tsx +129 -0
- package/components/composites/PromptInput/index.ts +8 -0
- package/components/composites/SpecialistMessage/SpecialistMessage.stories.tsx +286 -0
- package/components/composites/SpecialistMessage/SpecialistMessage.tsx +107 -0
- package/components/composites/SpecialistMessage/index.ts +8 -0
- package/components/composites/StatsCard/StatsCard.stories.tsx +76 -0
- package/components/composites/StatsCard/StatsCard.tsx +81 -0
- package/components/composites/StatsCard/index.ts +2 -0
- package/components/composites/TablePagination/TablePagination.stories.tsx +38 -0
- package/components/composites/TablePagination/TablePagination.tsx +119 -0
- package/components/composites/TablePagination/index.ts +2 -0
- package/components/composites/TableToolbar/TableToolbar.stories.tsx +60 -0
- package/components/composites/TableToolbar/TableToolbar.tsx +66 -0
- package/components/composites/TableToolbar/index.ts +2 -0
- package/components/composites/ThemeSelector/ThemeSelector.stories.tsx +48 -0
- package/components/composites/ThemeSelector/ThemeSelector.tsx +79 -0
- package/components/composites/ThemeSelector/index.ts +2 -0
- package/components/composites/ToolCallDisplay/ToolCallDisplay.stories.tsx +49 -0
- package/components/composites/ToolCallDisplay/ToolCallDisplay.tsx +108 -0
- package/components/composites/ToolCallDisplay/index.ts +8 -0
- package/components/composites/UserMessage/UserMessage.stories.tsx +59 -0
- package/components/composites/UserMessage/UserMessage.tsx +52 -0
- package/components/composites/UserMessage/index.ts +8 -0
- package/components/composites/index.ts +90 -0
- package/components/features/AIDocEditor/AIDocEditor.behaviors.stories.tsx +451 -0
- package/components/features/AIDocEditor/AIDocEditor.mocks.ts +96 -0
- package/components/features/AIDocEditor/AIDocEditor.stories.tsx +140 -0
- package/components/features/AIDocEditor/AIDocEditor.tsx +130 -0
- package/components/features/AIDocEditor/index.ts +8 -0
- package/components/features/AIDocEditor/useAIDocEditor.d.ts +97 -0
- package/components/features/AIDocEditor/useAIDocEditor.mock.ts +83 -0
- package/components/features/PageLayout/PageLayout.behaviors.stories.tsx +119 -0
- package/components/features/PageLayout/PageLayout.mocks.ts +27 -0
- package/components/features/PageLayout/PageLayout.stories.tsx +142 -0
- package/components/features/PageLayout/PageLayout.tsx +94 -0
- package/components/features/PageLayout/index.ts +4 -0
- package/components/features/PageLayout/usePageLayout.d.ts +24 -0
- package/components/features/PageLayout/usePageLayout.mock.ts +19 -0
- package/components/features/RefinementPanel/README.md +189 -0
- package/components/features/RefinementPanel/RefinementPanel.behaviors.stories.tsx +475 -0
- package/components/features/RefinementPanel/RefinementPanel.mocks.ts +131 -0
- package/components/features/RefinementPanel/RefinementPanel.stories.tsx +141 -0
- package/components/features/RefinementPanel/RefinementPanel.tsx +160 -0
- package/components/features/RefinementPanel/index.ts +25 -0
- package/components/features/RefinementPanel/useRefinementPanel.d.ts +74 -0
- package/components/features/RefinementPanel/useRefinementPanel.mock.ts +121 -0
- package/components/features/SpecNavigator/SpecNavigator.behaviors.stories.tsx +379 -0
- package/components/features/SpecNavigator/SpecNavigator.mocks.ts +131 -0
- package/components/features/SpecNavigator/SpecNavigator.stories.tsx +122 -0
- package/components/features/SpecNavigator/SpecNavigator.tsx +43 -0
- package/components/features/SpecNavigator/index.ts +2 -0
- package/components/features/SpecNavigator/useSpecNavigator.d.ts +122 -0
- package/components/features/SpecNavigator/useSpecNavigator.mock.ts +93 -0
- package/components/features/index.ts +18 -0
- package/components/index.ts +14 -0
- package/components/primitives/Accordion/Accordion.stories.tsx +87 -0
- package/components/primitives/Accordion/Accordion.tsx +66 -0
- package/components/primitives/Accordion/index.ts +13 -0
- package/components/primitives/Alert/Alert.stories.tsx +422 -0
- package/components/primitives/Alert/Alert.tsx +61 -0
- package/components/primitives/Alert/index.ts +8 -0
- package/components/primitives/AlertDialog/AlertDialog.stories.tsx +367 -0
- package/components/primitives/AlertDialog/AlertDialog.tsx +182 -0
- package/components/primitives/AlertDialog/index.ts +25 -0
- package/components/primitives/Avatar/Avatar.stories.tsx +321 -0
- package/components/primitives/Avatar/Avatar.tsx +63 -0
- package/components/primitives/Avatar/index.ts +8 -0
- package/components/primitives/Badge/Badge.stories.tsx +74 -0
- package/components/primitives/Badge/Badge.tsx +49 -0
- package/components/primitives/Badge/index.ts +2 -0
- package/components/primitives/Button/Button.stories.tsx +445 -0
- package/components/primitives/Button/Button.tsx +89 -0
- package/components/primitives/Button/index.ts +7 -0
- package/components/primitives/Card/Card.stories.tsx +831 -0
- package/components/primitives/Card/Card.tsx +242 -0
- package/components/primitives/Card/index.ts +30 -0
- package/components/primitives/Carousel/Carousel.stories.tsx +32 -0
- package/components/primitives/Carousel/Carousel.tsx +63 -0
- package/components/primitives/Carousel/index.ts +13 -0
- package/components/primitives/Chart/Chart.stories.tsx +346 -0
- package/components/primitives/Chart/Chart.tsx +117 -0
- package/components/primitives/Chart/index.ts +20 -0
- package/components/primitives/Checkbox/Checkbox.stories.tsx +87 -0
- package/components/primitives/Checkbox/Checkbox.tsx +38 -0
- package/components/primitives/Checkbox/index.ts +2 -0
- package/components/primitives/Collapsible/Collapsible.stories.tsx +38 -0
- package/components/primitives/Collapsible/Collapsible.tsx +39 -0
- package/components/primitives/Collapsible/index.ts +8 -0
- package/components/primitives/Command/Command.stories.tsx +150 -0
- package/components/primitives/Command/Command.tsx +147 -0
- package/components/primitives/Command/index.ts +20 -0
- package/components/primitives/Dialog/Dialog.stories.tsx +390 -0
- package/components/primitives/Dialog/Dialog.tsx +140 -0
- package/components/primitives/Dialog/index.ts +22 -0
- package/components/primitives/Drawer/Drawer.stories.tsx +327 -0
- package/components/primitives/Drawer/Drawer.tsx +208 -0
- package/components/primitives/Drawer/index.ts +27 -0
- package/components/primitives/DropdownMenu/DropdownMenu.stories.tsx +150 -0
- package/components/primitives/DropdownMenu/DropdownMenu.tsx +73 -0
- package/components/primitives/DropdownMenu/index.ts +1 -0
- package/components/primitives/HoverCard/HoverCard.stories.tsx +26 -0
- package/components/primitives/HoverCard/HoverCard.tsx +39 -0
- package/components/primitives/HoverCard/index.ts +8 -0
- package/components/primitives/Icon/Icon.stories.tsx +281 -0
- package/components/primitives/Icon/Icon.tsx +87 -0
- package/components/primitives/Icon/index.ts +8 -0
- package/components/primitives/Input/Input.stories.tsx +370 -0
- package/components/primitives/Input/Input.tsx +88 -0
- package/components/primitives/Input/index.ts +7 -0
- package/components/primitives/InputGroup/InputGroup.stories.tsx +40 -0
- package/components/primitives/InputGroup/InputGroup.tsx +72 -0
- package/components/primitives/InputGroup/index.ts +14 -0
- package/components/primitives/Label/Label.stories.tsx +227 -0
- package/components/primitives/Label/Label.tsx +53 -0
- package/components/primitives/Label/index.ts +7 -0
- package/components/primitives/Popover/Popover.stories.tsx +42 -0
- package/components/primitives/Popover/Popover.tsx +107 -0
- package/components/primitives/Popover/index.ts +2 -0
- package/components/primitives/Progress/Progress.stories.tsx +340 -0
- package/components/primitives/Progress/Progress.tsx +31 -0
- package/components/primitives/Progress/index.ts +1 -0
- package/components/primitives/ScrollArea/ScrollArea.stories.tsx +26 -0
- package/components/primitives/ScrollArea/ScrollArea.tsx +28 -0
- package/components/primitives/ScrollArea/index.ts +6 -0
- package/components/primitives/Select/Select.stories.tsx +288 -0
- package/components/primitives/Select/Select.tsx +162 -0
- package/components/primitives/Select/index.ts +22 -0
- package/components/primitives/Separator/Separator.stories.tsx +264 -0
- package/components/primitives/Separator/Separator.tsx +48 -0
- package/components/primitives/Separator/index.ts +7 -0
- package/components/primitives/Sidebar/Sidebar.stories.tsx +358 -0
- package/components/primitives/Sidebar/Sidebar.tsx +317 -0
- package/components/primitives/Sidebar/index.ts +41 -0
- package/components/primitives/Table/Table.stories.tsx +389 -0
- package/components/primitives/Table/Table.tsx +191 -0
- package/components/primitives/Table/index.ts +26 -0
- package/components/primitives/Tabs/Tabs.stories.tsx +129 -0
- package/components/primitives/Tabs/Tabs.tsx +70 -0
- package/components/primitives/Tabs/index.ts +13 -0
- package/components/primitives/Textarea/Textarea.stories.tsx +358 -0
- package/components/primitives/Textarea/Textarea.tsx +91 -0
- package/components/primitives/Textarea/index.ts +7 -0
- package/components/primitives/ToggleGroup/ToggleGroup.stories.tsx +87 -0
- package/components/primitives/ToggleGroup/ToggleGroup.tsx +52 -0
- package/components/primitives/ToggleGroup/index.ts +6 -0
- package/components/primitives/Tooltip/Tooltip.stories.tsx +336 -0
- package/components/primitives/Tooltip/Tooltip.tsx +78 -0
- package/components/primitives/Tooltip/index.ts +10 -0
- package/components/primitives/index.ts +34 -0
- package/components/ui/accordion.tsx +66 -0
- package/components/ui/alert-dialog.tsx +157 -0
- package/components/ui/alert.tsx +66 -0
- package/components/ui/avatar.tsx +53 -0
- package/components/ui/badge.tsx +46 -0
- package/components/ui/button.tsx +60 -0
- package/components/ui/card.tsx +117 -0
- package/components/ui/carousel.tsx +241 -0
- package/components/ui/chart.tsx +334 -0
- package/components/ui/checkbox.tsx +32 -0
- package/components/ui/collapsible.tsx +33 -0
- package/components/ui/command.tsx +184 -0
- package/components/ui/dialog.tsx +143 -0
- package/components/ui/drawer.tsx +118 -0
- package/components/ui/dropdown-menu.tsx +257 -0
- package/components/ui/hover-card.tsx +44 -0
- package/components/ui/input-group.tsx +170 -0
- package/components/ui/input.tsx +48 -0
- package/components/ui/label.tsx +26 -0
- package/components/ui/popover.tsx +33 -0
- package/components/ui/progress.tsx +31 -0
- package/components/ui/scroll-area.tsx +58 -0
- package/components/ui/select.tsx +187 -0
- package/components/ui/separator.tsx +31 -0
- package/components/ui/sidebar.tsx +577 -0
- package/components/ui/table.tsx +120 -0
- package/components/ui/tabs.tsx +66 -0
- package/components/ui/textarea.tsx +46 -0
- package/components/ui/toggle-group.tsx +83 -0
- package/components/ui/toggle.tsx +47 -0
- package/components/ui/tooltip.tsx +61 -0
- package/dist/index.cjs +7389 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.css +75 -0
- package/dist/index.css.map +1 -0
- package/dist/index.js +7160 -0
- package/dist/index.js.map +1 -0
- package/hooks/useAIDocReviewer.d.ts +0 -0
- package/lib/utils.ts +6 -0
- package/package.json +140 -0
- package/tokens/color/base.json +14 -0
- package/tokens/color/dark.json +40 -0
- package/tokens/color/green.json +21 -0
- package/tokens/color/light.json +52 -0
- package/tokens/color/neutral.json +20 -0
- package/tokens/color/violet.json +21 -0
- package/tokens/spacing.json +22 -0
- package/utils/ai-editor/format-date.ts +41 -0
- package/utils/ai-editor/index.ts +22 -0
- package/utils/ai-editor/type-guards.ts +72 -0
- package/utils/ai-editor/validation.ts +130 -0
- 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
|
+
}
|