ai-design-system 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (290) hide show
  1. package/README.md +307 -0
  2. package/components/ai-elements/actions.tsx +65 -0
  3. package/components/ai-elements/artifact.tsx +147 -0
  4. package/components/ai-elements/branch.tsx +212 -0
  5. package/components/ai-elements/canvas.tsx +24 -0
  6. package/components/ai-elements/chain-of-thought.tsx +228 -0
  7. package/components/ai-elements/code-block.tsx +179 -0
  8. package/components/ai-elements/confirmation.tsx +169 -0
  9. package/components/ai-elements/connection.tsx +28 -0
  10. package/components/ai-elements/context.tsx +408 -0
  11. package/components/ai-elements/controls.tsx +18 -0
  12. package/components/ai-elements/conversation.tsx +97 -0
  13. package/components/ai-elements/edge.tsx +140 -0
  14. package/components/ai-elements/image.tsx +24 -0
  15. package/components/ai-elements/inline-citation.tsx +287 -0
  16. package/components/ai-elements/loader.tsx +96 -0
  17. package/components/ai-elements/message.tsx +80 -0
  18. package/components/ai-elements/node.tsx +71 -0
  19. package/components/ai-elements/open-in-chat.tsx +363 -0
  20. package/components/ai-elements/panel.tsx +15 -0
  21. package/components/ai-elements/plan.tsx +142 -0
  22. package/components/ai-elements/prompt-input.tsx +1352 -0
  23. package/components/ai-elements/queue.tsx +274 -0
  24. package/components/ai-elements/reasoning.tsx +178 -0
  25. package/components/ai-elements/response.tsx +22 -0
  26. package/components/ai-elements/shimmer.tsx +64 -0
  27. package/components/ai-elements/sources.tsx +77 -0
  28. package/components/ai-elements/suggestion.tsx +56 -0
  29. package/components/ai-elements/task.tsx +87 -0
  30. package/components/ai-elements/tool.tsx +179 -0
  31. package/components/ai-elements/toolbar.tsx +16 -0
  32. package/components/ai-elements/web-preview.tsx +263 -0
  33. package/components/blocks/AIConversation/AIConversation.stories.tsx +164 -0
  34. package/components/blocks/AIConversation/AIConversation.tsx +186 -0
  35. package/components/blocks/AIConversation/index.ts +8 -0
  36. package/components/blocks/AppSidebar/AppSidebar.stories.tsx +63 -0
  37. package/components/blocks/AppSidebar/AppSidebar.tsx +87 -0
  38. package/components/blocks/AppSidebar/index.ts +2 -0
  39. package/components/blocks/DocumentEditorWithComments/DocumentEditorWithComments.stories.tsx +341 -0
  40. package/components/blocks/DocumentEditorWithComments/DocumentEditorWithComments.tsx +255 -0
  41. package/components/blocks/DocumentEditorWithComments/index.ts +9 -0
  42. package/components/blocks/FileChangeQueue/FileChangeQueue.stories.tsx +207 -0
  43. package/components/blocks/FileChangeQueue/FileChangeQueue.tsx +143 -0
  44. package/components/blocks/FileChangeQueue/index.ts +7 -0
  45. package/components/blocks/LayoutProvider/LayoutProvider.tsx +34 -0
  46. package/components/blocks/LayoutProvider/index.ts +1 -0
  47. package/components/blocks/index.ts +2 -0
  48. package/components/composites/AgentIndicator/AgentIndicator.stories.tsx +154 -0
  49. package/components/composites/AgentIndicator/AgentIndicator.tsx +102 -0
  50. package/components/composites/AgentIndicator/index.ts +8 -0
  51. package/components/composites/AppHeader/AppHeader.stories.tsx +46 -0
  52. package/components/composites/AppHeader/AppHeader.tsx +24 -0
  53. package/components/composites/AppHeader/index.ts +2 -0
  54. package/components/composites/CommentBox/CommentBox.stories.tsx +192 -0
  55. package/components/composites/CommentBox/CommentBox.tsx +364 -0
  56. package/components/composites/CommentBox/index.ts +8 -0
  57. package/components/composites/Confirmation/Confirmation.stories.tsx +151 -0
  58. package/components/composites/Confirmation/Confirmation.tsx +93 -0
  59. package/components/composites/Confirmation/index.ts +7 -0
  60. package/components/composites/DataTable/DataTable.stories.tsx +35 -0
  61. package/components/composites/DataTable/DataTable.tsx +95 -0
  62. package/components/composites/DataTable/index.ts +2 -0
  63. package/components/composites/DocumentEditor/DocumentEditor.css +106 -0
  64. package/components/composites/DocumentEditor/DocumentEditor.stories.tsx +927 -0
  65. package/components/composites/DocumentEditor/DocumentEditor.tsx +279 -0
  66. package/components/composites/DocumentEditor/index.ts +8 -0
  67. package/components/composites/FileQueue/FileQueue.stories.tsx +175 -0
  68. package/components/composites/FileQueue/FileQueue.tsx +161 -0
  69. package/components/composites/FileQueue/FileStatusBadge.tsx +74 -0
  70. package/components/composites/FileQueue/index.ts +24 -0
  71. package/components/composites/InteractiveChart/InteractiveChart.stories.tsx +49 -0
  72. package/components/composites/InteractiveChart/InteractiveChart.tsx +69 -0
  73. package/components/composites/InteractiveChart/index.ts +2 -0
  74. package/components/composites/ModeToggle/ModeToggle.stories.tsx +212 -0
  75. package/components/composites/ModeToggle/ModeToggle.tsx +100 -0
  76. package/components/composites/ModeToggle/index.ts +7 -0
  77. package/components/composites/NavUser/NavUser.stories.tsx +50 -0
  78. package/components/composites/NavUser/NavUser.tsx +60 -0
  79. package/components/composites/NavUser/index.ts +2 -0
  80. package/components/composites/NavigationList/NavigationList.stories.tsx +46 -0
  81. package/components/composites/NavigationList/NavigationList.tsx +46 -0
  82. package/components/composites/NavigationList/index.ts +2 -0
  83. package/components/composites/OrchestratorMessage/OrchestratorMessage.stories.tsx +188 -0
  84. package/components/composites/OrchestratorMessage/OrchestratorMessage.tsx +72 -0
  85. package/components/composites/OrchestratorMessage/index.ts +8 -0
  86. package/components/composites/PageContainer/PageContainer.stories.tsx +41 -0
  87. package/components/composites/PageContainer/PageContainer.tsx +24 -0
  88. package/components/composites/PageContainer/index.ts +2 -0
  89. package/components/composites/PromptInput/PromptInput.stories.tsx +200 -0
  90. package/components/composites/PromptInput/PromptInput.tsx +129 -0
  91. package/components/composites/PromptInput/index.ts +8 -0
  92. package/components/composites/SpecialistMessage/SpecialistMessage.stories.tsx +286 -0
  93. package/components/composites/SpecialistMessage/SpecialistMessage.tsx +107 -0
  94. package/components/composites/SpecialistMessage/index.ts +8 -0
  95. package/components/composites/StatsCard/StatsCard.stories.tsx +76 -0
  96. package/components/composites/StatsCard/StatsCard.tsx +81 -0
  97. package/components/composites/StatsCard/index.ts +2 -0
  98. package/components/composites/TablePagination/TablePagination.stories.tsx +38 -0
  99. package/components/composites/TablePagination/TablePagination.tsx +119 -0
  100. package/components/composites/TablePagination/index.ts +2 -0
  101. package/components/composites/TableToolbar/TableToolbar.stories.tsx +60 -0
  102. package/components/composites/TableToolbar/TableToolbar.tsx +66 -0
  103. package/components/composites/TableToolbar/index.ts +2 -0
  104. package/components/composites/ThemeSelector/ThemeSelector.stories.tsx +48 -0
  105. package/components/composites/ThemeSelector/ThemeSelector.tsx +79 -0
  106. package/components/composites/ThemeSelector/index.ts +2 -0
  107. package/components/composites/ToolCallDisplay/ToolCallDisplay.stories.tsx +49 -0
  108. package/components/composites/ToolCallDisplay/ToolCallDisplay.tsx +108 -0
  109. package/components/composites/ToolCallDisplay/index.ts +8 -0
  110. package/components/composites/UserMessage/UserMessage.stories.tsx +59 -0
  111. package/components/composites/UserMessage/UserMessage.tsx +52 -0
  112. package/components/composites/UserMessage/index.ts +8 -0
  113. package/components/composites/index.ts +90 -0
  114. package/components/features/AIDocEditor/AIDocEditor.behaviors.stories.tsx +451 -0
  115. package/components/features/AIDocEditor/AIDocEditor.mocks.ts +96 -0
  116. package/components/features/AIDocEditor/AIDocEditor.stories.tsx +140 -0
  117. package/components/features/AIDocEditor/AIDocEditor.tsx +130 -0
  118. package/components/features/AIDocEditor/index.ts +8 -0
  119. package/components/features/AIDocEditor/useAIDocEditor.d.ts +97 -0
  120. package/components/features/AIDocEditor/useAIDocEditor.mock.ts +83 -0
  121. package/components/features/PageLayout/PageLayout.behaviors.stories.tsx +119 -0
  122. package/components/features/PageLayout/PageLayout.mocks.ts +27 -0
  123. package/components/features/PageLayout/PageLayout.stories.tsx +142 -0
  124. package/components/features/PageLayout/PageLayout.tsx +94 -0
  125. package/components/features/PageLayout/index.ts +4 -0
  126. package/components/features/PageLayout/usePageLayout.d.ts +24 -0
  127. package/components/features/PageLayout/usePageLayout.mock.ts +19 -0
  128. package/components/features/RefinementPanel/README.md +189 -0
  129. package/components/features/RefinementPanel/RefinementPanel.behaviors.stories.tsx +475 -0
  130. package/components/features/RefinementPanel/RefinementPanel.mocks.ts +131 -0
  131. package/components/features/RefinementPanel/RefinementPanel.stories.tsx +141 -0
  132. package/components/features/RefinementPanel/RefinementPanel.tsx +160 -0
  133. package/components/features/RefinementPanel/index.ts +25 -0
  134. package/components/features/RefinementPanel/useRefinementPanel.d.ts +74 -0
  135. package/components/features/RefinementPanel/useRefinementPanel.mock.ts +121 -0
  136. package/components/features/SpecNavigator/SpecNavigator.behaviors.stories.tsx +379 -0
  137. package/components/features/SpecNavigator/SpecNavigator.mocks.ts +131 -0
  138. package/components/features/SpecNavigator/SpecNavigator.stories.tsx +122 -0
  139. package/components/features/SpecNavigator/SpecNavigator.tsx +43 -0
  140. package/components/features/SpecNavigator/index.ts +2 -0
  141. package/components/features/SpecNavigator/useSpecNavigator.d.ts +122 -0
  142. package/components/features/SpecNavigator/useSpecNavigator.mock.ts +93 -0
  143. package/components/features/index.ts +18 -0
  144. package/components/index.ts +14 -0
  145. package/components/primitives/Accordion/Accordion.stories.tsx +87 -0
  146. package/components/primitives/Accordion/Accordion.tsx +66 -0
  147. package/components/primitives/Accordion/index.ts +13 -0
  148. package/components/primitives/Alert/Alert.stories.tsx +422 -0
  149. package/components/primitives/Alert/Alert.tsx +61 -0
  150. package/components/primitives/Alert/index.ts +8 -0
  151. package/components/primitives/AlertDialog/AlertDialog.stories.tsx +367 -0
  152. package/components/primitives/AlertDialog/AlertDialog.tsx +182 -0
  153. package/components/primitives/AlertDialog/index.ts +25 -0
  154. package/components/primitives/Avatar/Avatar.stories.tsx +321 -0
  155. package/components/primitives/Avatar/Avatar.tsx +63 -0
  156. package/components/primitives/Avatar/index.ts +8 -0
  157. package/components/primitives/Badge/Badge.stories.tsx +74 -0
  158. package/components/primitives/Badge/Badge.tsx +49 -0
  159. package/components/primitives/Badge/index.ts +2 -0
  160. package/components/primitives/Button/Button.stories.tsx +445 -0
  161. package/components/primitives/Button/Button.tsx +89 -0
  162. package/components/primitives/Button/index.ts +7 -0
  163. package/components/primitives/Card/Card.stories.tsx +831 -0
  164. package/components/primitives/Card/Card.tsx +242 -0
  165. package/components/primitives/Card/index.ts +30 -0
  166. package/components/primitives/Carousel/Carousel.stories.tsx +32 -0
  167. package/components/primitives/Carousel/Carousel.tsx +63 -0
  168. package/components/primitives/Carousel/index.ts +13 -0
  169. package/components/primitives/Chart/Chart.stories.tsx +346 -0
  170. package/components/primitives/Chart/Chart.tsx +117 -0
  171. package/components/primitives/Chart/index.ts +20 -0
  172. package/components/primitives/Checkbox/Checkbox.stories.tsx +87 -0
  173. package/components/primitives/Checkbox/Checkbox.tsx +38 -0
  174. package/components/primitives/Checkbox/index.ts +2 -0
  175. package/components/primitives/Collapsible/Collapsible.stories.tsx +38 -0
  176. package/components/primitives/Collapsible/Collapsible.tsx +39 -0
  177. package/components/primitives/Collapsible/index.ts +8 -0
  178. package/components/primitives/Command/Command.stories.tsx +150 -0
  179. package/components/primitives/Command/Command.tsx +147 -0
  180. package/components/primitives/Command/index.ts +20 -0
  181. package/components/primitives/Dialog/Dialog.stories.tsx +390 -0
  182. package/components/primitives/Dialog/Dialog.tsx +140 -0
  183. package/components/primitives/Dialog/index.ts +22 -0
  184. package/components/primitives/Drawer/Drawer.stories.tsx +327 -0
  185. package/components/primitives/Drawer/Drawer.tsx +208 -0
  186. package/components/primitives/Drawer/index.ts +27 -0
  187. package/components/primitives/DropdownMenu/DropdownMenu.stories.tsx +150 -0
  188. package/components/primitives/DropdownMenu/DropdownMenu.tsx +73 -0
  189. package/components/primitives/DropdownMenu/index.ts +1 -0
  190. package/components/primitives/HoverCard/HoverCard.stories.tsx +26 -0
  191. package/components/primitives/HoverCard/HoverCard.tsx +39 -0
  192. package/components/primitives/HoverCard/index.ts +8 -0
  193. package/components/primitives/Icon/Icon.stories.tsx +281 -0
  194. package/components/primitives/Icon/Icon.tsx +87 -0
  195. package/components/primitives/Icon/index.ts +8 -0
  196. package/components/primitives/Input/Input.stories.tsx +370 -0
  197. package/components/primitives/Input/Input.tsx +88 -0
  198. package/components/primitives/Input/index.ts +7 -0
  199. package/components/primitives/InputGroup/InputGroup.stories.tsx +40 -0
  200. package/components/primitives/InputGroup/InputGroup.tsx +72 -0
  201. package/components/primitives/InputGroup/index.ts +14 -0
  202. package/components/primitives/Label/Label.stories.tsx +227 -0
  203. package/components/primitives/Label/Label.tsx +53 -0
  204. package/components/primitives/Label/index.ts +7 -0
  205. package/components/primitives/Popover/Popover.stories.tsx +42 -0
  206. package/components/primitives/Popover/Popover.tsx +107 -0
  207. package/components/primitives/Popover/index.ts +2 -0
  208. package/components/primitives/Progress/Progress.stories.tsx +340 -0
  209. package/components/primitives/Progress/Progress.tsx +31 -0
  210. package/components/primitives/Progress/index.ts +1 -0
  211. package/components/primitives/ScrollArea/ScrollArea.stories.tsx +26 -0
  212. package/components/primitives/ScrollArea/ScrollArea.tsx +28 -0
  213. package/components/primitives/ScrollArea/index.ts +6 -0
  214. package/components/primitives/Select/Select.stories.tsx +288 -0
  215. package/components/primitives/Select/Select.tsx +162 -0
  216. package/components/primitives/Select/index.ts +22 -0
  217. package/components/primitives/Separator/Separator.stories.tsx +264 -0
  218. package/components/primitives/Separator/Separator.tsx +48 -0
  219. package/components/primitives/Separator/index.ts +7 -0
  220. package/components/primitives/Sidebar/Sidebar.stories.tsx +358 -0
  221. package/components/primitives/Sidebar/Sidebar.tsx +317 -0
  222. package/components/primitives/Sidebar/index.ts +41 -0
  223. package/components/primitives/Table/Table.stories.tsx +389 -0
  224. package/components/primitives/Table/Table.tsx +191 -0
  225. package/components/primitives/Table/index.ts +26 -0
  226. package/components/primitives/Tabs/Tabs.stories.tsx +129 -0
  227. package/components/primitives/Tabs/Tabs.tsx +70 -0
  228. package/components/primitives/Tabs/index.ts +13 -0
  229. package/components/primitives/Textarea/Textarea.stories.tsx +358 -0
  230. package/components/primitives/Textarea/Textarea.tsx +91 -0
  231. package/components/primitives/Textarea/index.ts +7 -0
  232. package/components/primitives/ToggleGroup/ToggleGroup.stories.tsx +87 -0
  233. package/components/primitives/ToggleGroup/ToggleGroup.tsx +52 -0
  234. package/components/primitives/ToggleGroup/index.ts +6 -0
  235. package/components/primitives/Tooltip/Tooltip.stories.tsx +336 -0
  236. package/components/primitives/Tooltip/Tooltip.tsx +78 -0
  237. package/components/primitives/Tooltip/index.ts +10 -0
  238. package/components/primitives/index.ts +34 -0
  239. package/components/ui/accordion.tsx +66 -0
  240. package/components/ui/alert-dialog.tsx +157 -0
  241. package/components/ui/alert.tsx +66 -0
  242. package/components/ui/avatar.tsx +53 -0
  243. package/components/ui/badge.tsx +46 -0
  244. package/components/ui/button.tsx +60 -0
  245. package/components/ui/card.tsx +117 -0
  246. package/components/ui/carousel.tsx +241 -0
  247. package/components/ui/chart.tsx +334 -0
  248. package/components/ui/checkbox.tsx +32 -0
  249. package/components/ui/collapsible.tsx +33 -0
  250. package/components/ui/command.tsx +184 -0
  251. package/components/ui/dialog.tsx +143 -0
  252. package/components/ui/drawer.tsx +118 -0
  253. package/components/ui/dropdown-menu.tsx +257 -0
  254. package/components/ui/hover-card.tsx +44 -0
  255. package/components/ui/input-group.tsx +170 -0
  256. package/components/ui/input.tsx +48 -0
  257. package/components/ui/label.tsx +26 -0
  258. package/components/ui/popover.tsx +33 -0
  259. package/components/ui/progress.tsx +31 -0
  260. package/components/ui/scroll-area.tsx +58 -0
  261. package/components/ui/select.tsx +187 -0
  262. package/components/ui/separator.tsx +31 -0
  263. package/components/ui/sidebar.tsx +577 -0
  264. package/components/ui/table.tsx +120 -0
  265. package/components/ui/tabs.tsx +66 -0
  266. package/components/ui/textarea.tsx +46 -0
  267. package/components/ui/toggle-group.tsx +83 -0
  268. package/components/ui/toggle.tsx +47 -0
  269. package/components/ui/tooltip.tsx +61 -0
  270. package/dist/index.cjs +7389 -0
  271. package/dist/index.cjs.map +1 -0
  272. package/dist/index.css +75 -0
  273. package/dist/index.css.map +1 -0
  274. package/dist/index.js +7160 -0
  275. package/dist/index.js.map +1 -0
  276. package/hooks/useAIDocReviewer.d.ts +0 -0
  277. package/lib/utils.ts +6 -0
  278. package/package.json +140 -0
  279. package/tokens/color/base.json +14 -0
  280. package/tokens/color/dark.json +40 -0
  281. package/tokens/color/green.json +21 -0
  282. package/tokens/color/light.json +52 -0
  283. package/tokens/color/neutral.json +20 -0
  284. package/tokens/color/violet.json +21 -0
  285. package/tokens/spacing.json +22 -0
  286. package/utils/ai-editor/format-date.ts +41 -0
  287. package/utils/ai-editor/index.ts +22 -0
  288. package/utils/ai-editor/type-guards.ts +72 -0
  289. package/utils/ai-editor/validation.ts +130 -0
  290. package/utils/editor-annotations.ts +122 -0
@@ -0,0 +1,140 @@
1
+ import {
2
+ BaseEdge,
3
+ type EdgeProps,
4
+ getBezierPath,
5
+ getSimpleBezierPath,
6
+ type InternalNode,
7
+ type Node,
8
+ Position,
9
+ useInternalNode,
10
+ } from "@xyflow/react";
11
+
12
+ const Temporary = ({
13
+ id,
14
+ sourceX,
15
+ sourceY,
16
+ targetX,
17
+ targetY,
18
+ sourcePosition,
19
+ targetPosition,
20
+ }: EdgeProps) => {
21
+ const [edgePath] = getSimpleBezierPath({
22
+ sourceX,
23
+ sourceY,
24
+ sourcePosition,
25
+ targetX,
26
+ targetY,
27
+ targetPosition,
28
+ });
29
+
30
+ return (
31
+ <BaseEdge
32
+ className="stroke-1 stroke-ring"
33
+ id={id}
34
+ path={edgePath}
35
+ style={{
36
+ strokeDasharray: "5, 5",
37
+ }}
38
+ />
39
+ );
40
+ };
41
+
42
+ const getHandleCoordsByPosition = (
43
+ node: InternalNode<Node>,
44
+ handlePosition: Position
45
+ ) => {
46
+ // Choose the handle type based on position - Left is for target, Right is for source
47
+ const handleType = handlePosition === Position.Left ? "target" : "source";
48
+
49
+ const handle = node.internals.handleBounds?.[handleType]?.find(
50
+ (h) => h.position === handlePosition
51
+ );
52
+
53
+ if (!handle) {
54
+ return [0, 0] as const;
55
+ }
56
+
57
+ let offsetX = handle.width / 2;
58
+ let offsetY = handle.height / 2;
59
+
60
+ // this is a tiny detail to make the markerEnd of an edge visible.
61
+ // The handle position that gets calculated has the origin top-left, so depending which side we are using, we add a little offset
62
+ // when the handlePosition is Position.Right for example, we need to add an offset as big as the handle itself in order to get the correct position
63
+ switch (handlePosition) {
64
+ case Position.Left:
65
+ offsetX = 0;
66
+ break;
67
+ case Position.Right:
68
+ offsetX = handle.width;
69
+ break;
70
+ case Position.Top:
71
+ offsetY = 0;
72
+ break;
73
+ case Position.Bottom:
74
+ offsetY = handle.height;
75
+ break;
76
+ default:
77
+ throw new Error(`Invalid handle position: ${handlePosition}`);
78
+ }
79
+
80
+ const x = node.internals.positionAbsolute.x + handle.x + offsetX;
81
+ const y = node.internals.positionAbsolute.y + handle.y + offsetY;
82
+
83
+ return [x, y] as const;
84
+ };
85
+
86
+ const getEdgeParams = (
87
+ source: InternalNode<Node>,
88
+ target: InternalNode<Node>
89
+ ) => {
90
+ const sourcePos = Position.Right;
91
+ const [sx, sy] = getHandleCoordsByPosition(source, sourcePos);
92
+ const targetPos = Position.Left;
93
+ const [tx, ty] = getHandleCoordsByPosition(target, targetPos);
94
+
95
+ return {
96
+ sx,
97
+ sy,
98
+ tx,
99
+ ty,
100
+ sourcePos,
101
+ targetPos,
102
+ };
103
+ };
104
+
105
+ const Animated = ({ id, source, target, markerEnd, style }: EdgeProps) => {
106
+ const sourceNode = useInternalNode(source);
107
+ const targetNode = useInternalNode(target);
108
+
109
+ if (!(sourceNode && targetNode)) {
110
+ return null;
111
+ }
112
+
113
+ const { sx, sy, tx, ty, sourcePos, targetPos } = getEdgeParams(
114
+ sourceNode,
115
+ targetNode
116
+ );
117
+
118
+ const [edgePath] = getBezierPath({
119
+ sourceX: sx,
120
+ sourceY: sy,
121
+ sourcePosition: sourcePos,
122
+ targetX: tx,
123
+ targetY: ty,
124
+ targetPosition: targetPos,
125
+ });
126
+
127
+ return (
128
+ <>
129
+ <BaseEdge id={id} markerEnd={markerEnd} path={edgePath} style={style} />
130
+ <circle fill="var(--primary)" r="4">
131
+ <animateMotion dur="2s" path={edgePath} repeatCount="indefinite" />
132
+ </circle>
133
+ </>
134
+ );
135
+ };
136
+
137
+ export const Edge = {
138
+ Temporary,
139
+ Animated,
140
+ };
@@ -0,0 +1,24 @@
1
+ import { cn } from "@/lib/utils";
2
+ import type { Experimental_GeneratedImage } from "ai";
3
+
4
+ export type ImageProps = Experimental_GeneratedImage & {
5
+ className?: string;
6
+ alt?: string;
7
+ };
8
+
9
+ export const Image = ({
10
+ base64,
11
+ uint8Array,
12
+ mediaType,
13
+ ...props
14
+ }: ImageProps) => (
15
+ <img
16
+ {...props}
17
+ alt={props.alt}
18
+ className={cn(
19
+ "h-auto max-w-full overflow-hidden rounded-md",
20
+ props.className
21
+ )}
22
+ src={`data:${mediaType};base64,${base64}`}
23
+ />
24
+ );
@@ -0,0 +1,287 @@
1
+ "use client";
2
+
3
+ import { Badge } from "@/components/ui/badge";
4
+ import {
5
+ Carousel,
6
+ type CarouselApi,
7
+ CarouselContent,
8
+ CarouselItem,
9
+ } from "@/components/ui/carousel";
10
+ import {
11
+ HoverCard,
12
+ HoverCardContent,
13
+ HoverCardTrigger,
14
+ } from "@/components/ui/hover-card";
15
+ import { cn } from "@/lib/utils";
16
+ import { ArrowLeftIcon, ArrowRightIcon } from "lucide-react";
17
+ import {
18
+ type ComponentProps,
19
+ createContext,
20
+ useCallback,
21
+ useContext,
22
+ useEffect,
23
+ useState,
24
+ } from "react";
25
+
26
+ export type InlineCitationProps = ComponentProps<"span">;
27
+
28
+ export const InlineCitation = ({
29
+ className,
30
+ ...props
31
+ }: InlineCitationProps) => (
32
+ <span
33
+ className={cn("group inline items-center gap-1", className)}
34
+ {...props}
35
+ />
36
+ );
37
+
38
+ export type InlineCitationTextProps = ComponentProps<"span">;
39
+
40
+ export const InlineCitationText = ({
41
+ className,
42
+ ...props
43
+ }: InlineCitationTextProps) => (
44
+ <span
45
+ className={cn("transition-colors group-hover:bg-accent", className)}
46
+ {...props}
47
+ />
48
+ );
49
+
50
+ export type InlineCitationCardProps = ComponentProps<typeof HoverCard>;
51
+
52
+ export const InlineCitationCard = (props: InlineCitationCardProps) => (
53
+ <HoverCard closeDelay={0} openDelay={0} {...props} />
54
+ );
55
+
56
+ export type InlineCitationCardTriggerProps = ComponentProps<typeof Badge> & {
57
+ sources: string[];
58
+ };
59
+
60
+ export const InlineCitationCardTrigger = ({
61
+ sources,
62
+ className,
63
+ ...props
64
+ }: InlineCitationCardTriggerProps) => (
65
+ <HoverCardTrigger asChild>
66
+ <Badge
67
+ className={cn("ml-1 rounded-full", className)}
68
+ variant="secondary"
69
+ {...props}
70
+ >
71
+ {sources[0] ? (
72
+ <>
73
+ {new URL(sources[0]).hostname}{" "}
74
+ {sources.length > 1 && `+${sources.length - 1}`}
75
+ </>
76
+ ) : (
77
+ "unknown"
78
+ )}
79
+ </Badge>
80
+ </HoverCardTrigger>
81
+ );
82
+
83
+ export type InlineCitationCardBodyProps = ComponentProps<"div">;
84
+
85
+ export const InlineCitationCardBody = ({
86
+ className,
87
+ ...props
88
+ }: InlineCitationCardBodyProps) => (
89
+ <HoverCardContent className={cn("relative w-80 p-0", className)} {...props} />
90
+ );
91
+
92
+ const CarouselApiContext = createContext<CarouselApi | undefined>(undefined);
93
+
94
+ const useCarouselApi = () => {
95
+ const context = useContext(CarouselApiContext);
96
+ return context;
97
+ };
98
+
99
+ export type InlineCitationCarouselProps = ComponentProps<typeof Carousel>;
100
+
101
+ export const InlineCitationCarousel = ({
102
+ className,
103
+ children,
104
+ ...props
105
+ }: InlineCitationCarouselProps) => {
106
+ const [api, setApi] = useState<CarouselApi>();
107
+
108
+ return (
109
+ <CarouselApiContext.Provider value={api}>
110
+ <Carousel className={cn("w-full", className)} setApi={setApi} {...props}>
111
+ {children}
112
+ </Carousel>
113
+ </CarouselApiContext.Provider>
114
+ );
115
+ };
116
+
117
+ export type InlineCitationCarouselContentProps = ComponentProps<"div">;
118
+
119
+ export const InlineCitationCarouselContent = (
120
+ props: InlineCitationCarouselContentProps
121
+ ) => <CarouselContent {...props} />;
122
+
123
+ export type InlineCitationCarouselItemProps = ComponentProps<"div">;
124
+
125
+ export const InlineCitationCarouselItem = ({
126
+ className,
127
+ ...props
128
+ }: InlineCitationCarouselItemProps) => (
129
+ <CarouselItem
130
+ className={cn("w-full space-y-2 p-4 pl-8", className)}
131
+ {...props}
132
+ />
133
+ );
134
+
135
+ export type InlineCitationCarouselHeaderProps = ComponentProps<"div">;
136
+
137
+ export const InlineCitationCarouselHeader = ({
138
+ className,
139
+ ...props
140
+ }: InlineCitationCarouselHeaderProps) => (
141
+ <div
142
+ className={cn(
143
+ "flex items-center justify-between gap-2 rounded-t-md bg-secondary p-2",
144
+ className
145
+ )}
146
+ {...props}
147
+ />
148
+ );
149
+
150
+ export type InlineCitationCarouselIndexProps = ComponentProps<"div">;
151
+
152
+ export const InlineCitationCarouselIndex = ({
153
+ children,
154
+ className,
155
+ ...props
156
+ }: InlineCitationCarouselIndexProps) => {
157
+ const api = useCarouselApi();
158
+ const [current, setCurrent] = useState(0);
159
+ const [count, setCount] = useState(0);
160
+
161
+ useEffect(() => {
162
+ if (!api) {
163
+ return;
164
+ }
165
+
166
+ setCount(api.scrollSnapList().length);
167
+ setCurrent(api.selectedScrollSnap() + 1);
168
+
169
+ api.on("select", () => {
170
+ setCurrent(api.selectedScrollSnap() + 1);
171
+ });
172
+ }, [api]);
173
+
174
+ return (
175
+ <div
176
+ className={cn(
177
+ "flex flex-1 items-center justify-end px-3 py-1 text-muted-foreground text-xs",
178
+ className
179
+ )}
180
+ {...props}
181
+ >
182
+ {children ?? `${current}/${count}`}
183
+ </div>
184
+ );
185
+ };
186
+
187
+ export type InlineCitationCarouselPrevProps = ComponentProps<"button">;
188
+
189
+ export const InlineCitationCarouselPrev = ({
190
+ className,
191
+ ...props
192
+ }: InlineCitationCarouselPrevProps) => {
193
+ const api = useCarouselApi();
194
+
195
+ const handleClick = useCallback(() => {
196
+ if (api) {
197
+ api.scrollPrev();
198
+ }
199
+ }, [api]);
200
+
201
+ return (
202
+ <button
203
+ aria-label="Previous"
204
+ className={cn("shrink-0", className)}
205
+ onClick={handleClick}
206
+ type="button"
207
+ {...props}
208
+ >
209
+ <ArrowLeftIcon className="size-4 text-muted-foreground" />
210
+ </button>
211
+ );
212
+ };
213
+
214
+ export type InlineCitationCarouselNextProps = ComponentProps<"button">;
215
+
216
+ export const InlineCitationCarouselNext = ({
217
+ className,
218
+ ...props
219
+ }: InlineCitationCarouselNextProps) => {
220
+ const api = useCarouselApi();
221
+
222
+ const handleClick = useCallback(() => {
223
+ if (api) {
224
+ api.scrollNext();
225
+ }
226
+ }, [api]);
227
+
228
+ return (
229
+ <button
230
+ aria-label="Next"
231
+ className={cn("shrink-0", className)}
232
+ onClick={handleClick}
233
+ type="button"
234
+ {...props}
235
+ >
236
+ <ArrowRightIcon className="size-4 text-muted-foreground" />
237
+ </button>
238
+ );
239
+ };
240
+
241
+ export type InlineCitationSourceProps = ComponentProps<"div"> & {
242
+ title?: string;
243
+ url?: string;
244
+ description?: string;
245
+ };
246
+
247
+ export const InlineCitationSource = ({
248
+ title,
249
+ url,
250
+ description,
251
+ className,
252
+ children,
253
+ ...props
254
+ }: InlineCitationSourceProps) => (
255
+ <div className={cn("space-y-1", className)} {...props}>
256
+ {title && (
257
+ <h4 className="truncate font-medium text-sm leading-tight">{title}</h4>
258
+ )}
259
+ {url && (
260
+ <p className="truncate break-all text-muted-foreground text-xs">{url}</p>
261
+ )}
262
+ {description && (
263
+ <p className="line-clamp-3 text-muted-foreground text-sm leading-relaxed">
264
+ {description}
265
+ </p>
266
+ )}
267
+ {children}
268
+ </div>
269
+ );
270
+
271
+ export type InlineCitationQuoteProps = ComponentProps<"blockquote">;
272
+
273
+ export const InlineCitationQuote = ({
274
+ children,
275
+ className,
276
+ ...props
277
+ }: InlineCitationQuoteProps) => (
278
+ <blockquote
279
+ className={cn(
280
+ "border-muted border-l-2 pl-3 text-muted-foreground text-sm italic",
281
+ className
282
+ )}
283
+ {...props}
284
+ >
285
+ {children}
286
+ </blockquote>
287
+ );
@@ -0,0 +1,96 @@
1
+ import { cn } from "@/lib/utils";
2
+ import type { HTMLAttributes } from "react";
3
+
4
+ type LoaderIconProps = {
5
+ size?: number;
6
+ };
7
+
8
+ const LoaderIcon = ({ size = 16 }: LoaderIconProps) => (
9
+ <svg
10
+ height={size}
11
+ strokeLinejoin="round"
12
+ style={{ color: "currentcolor" }}
13
+ viewBox="0 0 16 16"
14
+ width={size}
15
+ >
16
+ <title>Loader</title>
17
+ <g clipPath="url(#clip0_2393_1490)">
18
+ <path d="M8 0V4" stroke="currentColor" strokeWidth="1.5" />
19
+ <path
20
+ d="M8 16V12"
21
+ opacity="0.5"
22
+ stroke="currentColor"
23
+ strokeWidth="1.5"
24
+ />
25
+ <path
26
+ d="M3.29773 1.52783L5.64887 4.7639"
27
+ opacity="0.9"
28
+ stroke="currentColor"
29
+ strokeWidth="1.5"
30
+ />
31
+ <path
32
+ d="M12.7023 1.52783L10.3511 4.7639"
33
+ opacity="0.1"
34
+ stroke="currentColor"
35
+ strokeWidth="1.5"
36
+ />
37
+ <path
38
+ d="M12.7023 14.472L10.3511 11.236"
39
+ opacity="0.4"
40
+ stroke="currentColor"
41
+ strokeWidth="1.5"
42
+ />
43
+ <path
44
+ d="M3.29773 14.472L5.64887 11.236"
45
+ opacity="0.6"
46
+ stroke="currentColor"
47
+ strokeWidth="1.5"
48
+ />
49
+ <path
50
+ d="M15.6085 5.52783L11.8043 6.7639"
51
+ opacity="0.2"
52
+ stroke="currentColor"
53
+ strokeWidth="1.5"
54
+ />
55
+ <path
56
+ d="M0.391602 10.472L4.19583 9.23598"
57
+ opacity="0.7"
58
+ stroke="currentColor"
59
+ strokeWidth="1.5"
60
+ />
61
+ <path
62
+ d="M15.6085 10.4722L11.8043 9.2361"
63
+ opacity="0.3"
64
+ stroke="currentColor"
65
+ strokeWidth="1.5"
66
+ />
67
+ <path
68
+ d="M0.391602 5.52783L4.19583 6.7639"
69
+ opacity="0.8"
70
+ stroke="currentColor"
71
+ strokeWidth="1.5"
72
+ />
73
+ </g>
74
+ <defs>
75
+ <clipPath id="clip0_2393_1490">
76
+ <rect fill="white" height="16" width="16" />
77
+ </clipPath>
78
+ </defs>
79
+ </svg>
80
+ );
81
+
82
+ export type LoaderProps = HTMLAttributes<HTMLDivElement> & {
83
+ size?: number;
84
+ };
85
+
86
+ export const Loader = ({ className, size = 16, ...props }: LoaderProps) => (
87
+ <div
88
+ className={cn(
89
+ "inline-flex animate-spin items-center justify-center",
90
+ className
91
+ )}
92
+ {...props}
93
+ >
94
+ <LoaderIcon size={size} />
95
+ </div>
96
+ );
@@ -0,0 +1,80 @@
1
+ import {
2
+ Avatar,
3
+ AvatarFallback,
4
+ AvatarImage,
5
+ } from "@/components/ui/avatar";
6
+ import { cn } from "@/lib/utils";
7
+ import type { UIMessage } from "ai";
8
+ import { cva, type VariantProps } from "class-variance-authority";
9
+ import type { ComponentProps, HTMLAttributes } from "react";
10
+
11
+ export type MessageProps = HTMLAttributes<HTMLDivElement> & {
12
+ from: UIMessage["role"];
13
+ };
14
+
15
+ export const Message = ({ className, from, ...props }: MessageProps) => (
16
+ <div
17
+ className={cn(
18
+ "group flex w-full items-start gap-2 py-2",
19
+ from === "user" ? "is-user flex-row-reverse" : "is-assistant bg-muted/50 -mx-4 px-4",
20
+ className
21
+ )}
22
+ {...props}
23
+ />
24
+ );
25
+
26
+ const messageContentVariants = cva(
27
+ "is-user:dark flex flex-col gap-2 overflow-hidden rounded-lg text-sm group-[.is-user]:ml-auto",
28
+ {
29
+ variants: {
30
+ variant: {
31
+ contained: [
32
+ "max-w-[80%] px-4 py-3",
33
+ "group-[.is-user]:bg-primary group-[.is-user]:text-primary-foreground",
34
+ "group-[.is-assistant]:bg-secondary group-[.is-assistant]:text-foreground",
35
+ ],
36
+ flat: [
37
+ "group-[.is-user]:max-w-[80%] group-[.is-user]:bg-secondary group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-foreground",
38
+ "group-[.is-assistant]:text-foreground",
39
+ ],
40
+ },
41
+ },
42
+ defaultVariants: {
43
+ variant: "contained",
44
+ },
45
+ }
46
+ );
47
+
48
+ export type MessageContentProps = HTMLAttributes<HTMLDivElement> &
49
+ VariantProps<typeof messageContentVariants>;
50
+
51
+ export const MessageContent = ({
52
+ children,
53
+ className,
54
+ variant,
55
+ ...props
56
+ }: MessageContentProps) => (
57
+ <div
58
+ className={cn(messageContentVariants({ variant, className }))}
59
+ {...props}
60
+ >
61
+ {children}
62
+ </div>
63
+ );
64
+
65
+ export type MessageAvatarProps = ComponentProps<typeof Avatar> & {
66
+ src: string;
67
+ name?: string;
68
+ };
69
+
70
+ export const MessageAvatar = ({
71
+ src,
72
+ name,
73
+ className,
74
+ ...props
75
+ }: MessageAvatarProps) => (
76
+ <Avatar className={cn("size-8 ring-1 ring-border", className)} {...props}>
77
+ <AvatarImage alt="" className="mt-0 mb-0" src={src} />
78
+ <AvatarFallback>{name?.slice(0, 2) || "ME"}</AvatarFallback>
79
+ </Avatar>
80
+ );
@@ -0,0 +1,71 @@
1
+ import {
2
+ Card,
3
+ CardAction,
4
+ CardContent,
5
+ CardDescription,
6
+ CardFooter,
7
+ CardHeader,
8
+ CardTitle,
9
+ } from "@/components/ui/card";
10
+ import { cn } from "@/lib/utils";
11
+ import { Handle, Position } from "@xyflow/react";
12
+ import type { ComponentProps } from "react";
13
+
14
+ export type NodeProps = ComponentProps<typeof Card> & {
15
+ handles: {
16
+ target: boolean;
17
+ source: boolean;
18
+ };
19
+ };
20
+
21
+ export const Node = ({ handles, className, ...props }: NodeProps) => (
22
+ <Card
23
+ className={cn(
24
+ "node-container relative size-full h-auto w-sm gap-0 rounded-md p-0",
25
+ className
26
+ )}
27
+ {...props}
28
+ >
29
+ {handles.target && <Handle position={Position.Left} type="target" />}
30
+ {handles.source && <Handle position={Position.Right} type="source" />}
31
+ {props.children}
32
+ </Card>
33
+ );
34
+
35
+ export type NodeHeaderProps = ComponentProps<typeof CardHeader>;
36
+
37
+ export const NodeHeader = ({ className, ...props }: NodeHeaderProps) => (
38
+ <CardHeader
39
+ className={cn("gap-0.5 rounded-t-md border-b bg-secondary p-3!", className)}
40
+ {...props}
41
+ />
42
+ );
43
+
44
+ export type NodeTitleProps = ComponentProps<typeof CardTitle>;
45
+
46
+ export const NodeTitle = (props: NodeTitleProps) => <CardTitle {...props} />;
47
+
48
+ export type NodeDescriptionProps = ComponentProps<typeof CardDescription>;
49
+
50
+ export const NodeDescription = (props: NodeDescriptionProps) => (
51
+ <CardDescription {...props} />
52
+ );
53
+
54
+ export type NodeActionProps = ComponentProps<typeof CardAction>;
55
+
56
+ export const NodeAction = (props: NodeActionProps) => <CardAction {...props} />;
57
+
58
+ export type NodeContentProps = ComponentProps<typeof CardContent>;
59
+
60
+ export const NodeContent = ({ className, ...props }: NodeContentProps) => (
61
+ <CardContent className={cn("p-3", className)} {...props} />
62
+ );
63
+
64
+ export type NodeFooterProps = ComponentProps<typeof CardFooter>;
65
+
66
+ export const NodeFooter = ({ className, ...props }: NodeFooterProps) => (
67
+ <CardFooter
68
+ className={cn("rounded-b-md border-t bg-secondary p-3!", className)}
69
+ {...props}
70
+ />
71
+ );