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,119 @@
1
+ import * as React from "react"
2
+ import { Button } from "@/components/primitives/Button"
3
+ import {
4
+ Select,
5
+ SelectContent,
6
+ SelectItem,
7
+ SelectTrigger,
8
+ SelectValue,
9
+ } from "@/components/primitives/Select"
10
+ import { Label } from "@/components/primitives/Label"
11
+ import type { Table } from "@tanstack/react-table"
12
+
13
+ /**
14
+ * TablePagination Composite
15
+ *
16
+ * Reusable pagination controls for tables with TanStack Table integration.
17
+ * Composes Button, Select, and Label primitives.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * <TablePagination table={table} />
22
+ * ```
23
+ */
24
+
25
+ export interface TablePaginationProps {
26
+ /**
27
+ * TanStack Table instance
28
+ */
29
+ table: Table<any>
30
+ /**
31
+ * Available page size options
32
+ */
33
+ pageSizeOptions?: number[]
34
+ /**
35
+ * Additional CSS classes
36
+ */
37
+ className?: string
38
+ }
39
+
40
+ /**
41
+ * TablePagination component
42
+ *
43
+ * Provides pagination controls including page size selection and navigation buttons.
44
+ */
45
+ export const TablePagination = React.memo<TablePaginationProps>(
46
+ ({ table, pageSizeOptions = [10, 20, 30, 40, 50], className }) => {
47
+ return (
48
+ <div className={`flex items-center justify-between px-4 py-2 ${className || ""}`}>
49
+ <div className="text-sm text-muted-foreground">
50
+ {table.getFilteredSelectedRowModel().rows.length} of{" "}
51
+ {table.getFilteredRowModel().rows.length} row(s) selected
52
+ </div>
53
+ <div className="flex items-center gap-8">
54
+ <div className="flex items-center gap-2">
55
+ <Label htmlFor="rows-per-page" className="text-sm">
56
+ Rows per page
57
+ </Label>
58
+ <Select
59
+ value={`${table.getState().pagination.pageSize}`}
60
+ onValueChange={(value) => table.setPageSize(Number(value))}
61
+ >
62
+ <SelectTrigger id="rows-per-page" className="h-8 w-[70px]">
63
+ <SelectValue placeholder={table.getState().pagination.pageSize} />
64
+ </SelectTrigger>
65
+ <SelectContent side="top">
66
+ {pageSizeOptions.map((pageSize) => (
67
+ <SelectItem key={pageSize} value={`${pageSize}`}>
68
+ {pageSize}
69
+ </SelectItem>
70
+ ))}
71
+ </SelectContent>
72
+ </Select>
73
+ </div>
74
+ <div className="flex items-center gap-2">
75
+ <div className="text-sm font-medium">
76
+ Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount()}
77
+ </div>
78
+ <div className="flex items-center gap-1">
79
+ <Button
80
+ variant="outline"
81
+ size="sm"
82
+ onClick={() => table.setPageIndex(0)}
83
+ disabled={!table.getCanPreviousPage()}
84
+ >
85
+ First
86
+ </Button>
87
+ <Button
88
+ variant="outline"
89
+ size="sm"
90
+ onClick={() => table.previousPage()}
91
+ disabled={!table.getCanPreviousPage()}
92
+ >
93
+ Previous
94
+ </Button>
95
+ <Button
96
+ variant="outline"
97
+ size="sm"
98
+ onClick={() => table.nextPage()}
99
+ disabled={!table.getCanNextPage()}
100
+ >
101
+ Next
102
+ </Button>
103
+ <Button
104
+ variant="outline"
105
+ size="sm"
106
+ onClick={() => table.setPageIndex(table.getPageCount() - 1)}
107
+ disabled={!table.getCanNextPage()}
108
+ >
109
+ Last
110
+ </Button>
111
+ </div>
112
+ </div>
113
+ </div>
114
+ </div>
115
+ )
116
+ }
117
+ )
118
+
119
+ TablePagination.displayName = "TablePagination"
@@ -0,0 +1,2 @@
1
+ export { TablePagination } from './TablePagination'
2
+ export type { TablePaginationProps } from './TablePagination'
@@ -0,0 +1,60 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { TableToolbar } from './TableToolbar'
3
+ import { useReactTable, getCoreRowModel, getFilteredRowModel, createColumnHelper } from '@tanstack/react-table'
4
+ import { Button } from '@/components/primitives/Button'
5
+
6
+ const meta = {
7
+ title: 'Composites/TableToolbar',
8
+ component: TableToolbar,
9
+ tags: ['autodocs'],
10
+ parameters: { layout: 'padded' },
11
+ } satisfies Meta<typeof TableToolbar>
12
+
13
+ export default meta
14
+ type Story = StoryObj<typeof meta>
15
+
16
+ type Person = { id: number; name: string; email: string }
17
+ const data: Person[] = [{ id: 1, name: 'John', email: 'john@example.com' }]
18
+ const columnHelper = createColumnHelper<Person>()
19
+
20
+ export const Default: Story = {
21
+ render: () => {
22
+ const columns = [
23
+ columnHelper.accessor('name', { header: 'Name' }),
24
+ columnHelper.accessor('email', { header: 'Email' }),
25
+ ]
26
+ const table = useReactTable({
27
+ data,
28
+ columns,
29
+ getCoreRowModel: getCoreRowModel(),
30
+ getFilteredRowModel: getFilteredRowModel(),
31
+ })
32
+ return <TableToolbar table={table} searchColumn="name" />
33
+ },
34
+ }
35
+
36
+ export const WithActions: Story = {
37
+ render: () => {
38
+ const columns = [
39
+ columnHelper.accessor('name', { header: 'Name' }),
40
+ columnHelper.accessor('email', { header: 'Email' }),
41
+ ]
42
+ const table = useReactTable({
43
+ data,
44
+ columns,
45
+ getCoreRowModel: getCoreRowModel(),
46
+ getFilteredRowModel: getFilteredRowModel(),
47
+ })
48
+ return (
49
+ <TableToolbar
50
+ table={table}
51
+ searchColumn="name"
52
+ actions={
53
+ <Button size="sm" variant="default">
54
+ Add New
55
+ </Button>
56
+ }
57
+ />
58
+ )
59
+ },
60
+ }
@@ -0,0 +1,66 @@
1
+ import * as React from "react"
2
+ import { Input } from "@/components/primitives/Input"
3
+ import { Button } from "@/components/primitives/Button"
4
+ import {
5
+ DropdownMenu,
6
+ DropdownMenuCheckboxItem,
7
+ DropdownMenuContent,
8
+ DropdownMenuTrigger,
9
+ } from "@/components/primitives/DropdownMenu"
10
+ import { Icon } from "@/components/primitives/Icon"
11
+ import type { Table } from "@tanstack/react-table"
12
+
13
+ export interface TableToolbarProps {
14
+ table: Table<any>
15
+ searchPlaceholder?: string
16
+ searchColumn?: string
17
+ actions?: React.ReactNode
18
+ className?: string
19
+ }
20
+
21
+ export const TableToolbar = React.memo<TableToolbarProps>(
22
+ ({ table, searchPlaceholder = "Search...", searchColumn, actions, className }) => {
23
+ return (
24
+ <div className={`flex items-center justify-between px-4 py-2 ${className || ""}`}>
25
+ <div className="flex flex-1 items-center gap-2">
26
+ <Input
27
+ placeholder={searchPlaceholder}
28
+ value={(searchColumn && (table.getColumn(searchColumn)?.getFilterValue() as string)) ?? ""}
29
+ onChange={(e) => searchColumn && table.getColumn(searchColumn)?.setFilterValue(e.target.value)}
30
+ className="h-8 w-[150px] lg:w-[250px]"
31
+ />
32
+ </div>
33
+ <div className="flex items-center gap-2">
34
+ <DropdownMenu>
35
+ <DropdownMenuTrigger asChild>
36
+ <Button variant="outline" size="sm" className="ml-auto">
37
+ <Icon name="settings-2" className="mr-2 h-4 w-4" />
38
+ Columns
39
+ </Button>
40
+ </DropdownMenuTrigger>
41
+ <DropdownMenuContent align="end">
42
+ {table
43
+ .getAllColumns()
44
+ .filter((column) => column.getCanHide())
45
+ .map((column) => {
46
+ return (
47
+ <DropdownMenuCheckboxItem
48
+ key={column.id}
49
+ className="capitalize"
50
+ checked={column.getIsVisible()}
51
+ onCheckedChange={(value) => column.toggleVisibility(!!value)}
52
+ >
53
+ {column.id}
54
+ </DropdownMenuCheckboxItem>
55
+ )
56
+ })}
57
+ </DropdownMenuContent>
58
+ </DropdownMenu>
59
+ {actions}
60
+ </div>
61
+ </div>
62
+ )
63
+ }
64
+ )
65
+
66
+ TableToolbar.displayName = "TableToolbar"
@@ -0,0 +1,2 @@
1
+ export { TableToolbar } from './TableToolbar'
2
+ export type { TableToolbarProps } from './TableToolbar'
@@ -0,0 +1,48 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { ThemeSelector } from './ThemeSelector'
3
+ import { useState } from 'react'
4
+
5
+ const meta = {
6
+ title: 'Composites/ThemeSelector',
7
+ component: ThemeSelector,
8
+ tags: ['autodocs'],
9
+ parameters: {
10
+ layout: 'centered',
11
+ },
12
+ } satisfies Meta<typeof ThemeSelector>
13
+
14
+ export default meta
15
+ type Story = StoryObj<typeof meta>
16
+
17
+ const themes = [
18
+ { label: 'Default', value: 'default' },
19
+ { label: 'Ocean', value: 'ocean' },
20
+ { label: 'Forest', value: 'forest' },
21
+ { label: 'Sunset', value: 'sunset' },
22
+ ]
23
+
24
+ export const Default: Story = {
25
+ args: {
26
+ themes,
27
+ placeholder: 'Select theme',
28
+ },
29
+ }
30
+
31
+ export const WithValue: Story = {
32
+ args: {
33
+ themes,
34
+ value: 'ocean',
35
+ },
36
+ }
37
+
38
+ export const Interactive: Story = {
39
+ render: () => {
40
+ const [value, setValue] = useState('default')
41
+ return (
42
+ <div style={{ minWidth: '200px' }}>
43
+ <ThemeSelector themes={themes} value={value} onValueChange={setValue} />
44
+ <p style={{ marginTop: '16px', fontSize: '14px' }}>Selected: {value}</p>
45
+ </div>
46
+ )
47
+ },
48
+ }
@@ -0,0 +1,79 @@
1
+ import * as React from "react"
2
+ import {
3
+ Select,
4
+ SelectContent,
5
+ SelectItem,
6
+ SelectTrigger,
7
+ SelectValue,
8
+ } from "@/components/primitives/Select"
9
+
10
+ /**
11
+ * ThemeSelector Composite
12
+ *
13
+ * A theme variant selector component that allows users to choose from multiple theme options.
14
+ * Composes Select primitive.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * const themes = [
19
+ * { label: "Default", value: "default" },
20
+ * { label: "Ocean", value: "ocean" },
21
+ * { label: "Forest", value: "forest" },
22
+ * ]
23
+ * <ThemeSelector themes={themes} value="default" onValueChange={setTheme} />
24
+ * ```
25
+ */
26
+
27
+ export interface Theme {
28
+ label: string
29
+ value: string
30
+ }
31
+
32
+ export interface ThemeSelectorProps {
33
+ /**
34
+ * Available theme options
35
+ */
36
+ themes: Theme[]
37
+ /**
38
+ * Currently selected theme value
39
+ */
40
+ value?: string
41
+ /**
42
+ * Callback when theme selection changes
43
+ */
44
+ onValueChange?: (value: string) => void
45
+ /**
46
+ * Placeholder text when no theme is selected
47
+ */
48
+ placeholder?: string
49
+ /**
50
+ * Additional CSS classes
51
+ */
52
+ className?: string
53
+ }
54
+
55
+ /**
56
+ * ThemeSelector component
57
+ *
58
+ * Provides a select dropdown to choose from multiple theme variants.
59
+ */
60
+ export const ThemeSelector = React.memo<ThemeSelectorProps>(
61
+ ({ themes, value, onValueChange, placeholder = "Select theme", className }) => {
62
+ return (
63
+ <Select value={value} onValueChange={onValueChange}>
64
+ <SelectTrigger className={className}>
65
+ <SelectValue placeholder={placeholder} />
66
+ </SelectTrigger>
67
+ <SelectContent>
68
+ {themes.map((theme) => (
69
+ <SelectItem key={theme.value} value={theme.value}>
70
+ {theme.label}
71
+ </SelectItem>
72
+ ))}
73
+ </SelectContent>
74
+ </Select>
75
+ )
76
+ }
77
+ )
78
+
79
+ ThemeSelector.displayName = "ThemeSelector"
@@ -0,0 +1,2 @@
1
+ export { ThemeSelector } from './ThemeSelector'
2
+ export type { ThemeSelectorProps, Theme } from './ThemeSelector'
@@ -0,0 +1,49 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { ToolCallDisplay } from './ToolCallDisplay'
3
+
4
+ const meta: Meta<typeof ToolCallDisplay> = {
5
+ title: 'Composites/ToolCallDisplay',
6
+ component: ToolCallDisplay,
7
+ parameters: {
8
+ layout: 'padded',
9
+ },
10
+ } satisfies Meta<typeof ToolCallDisplay>
11
+
12
+ export default meta
13
+ type Story = StoryObj<typeof meta>
14
+
15
+ export const Default: Story = {
16
+ args: {
17
+ toolCall: {
18
+ id: 'tool_1',
19
+ name: 'write_file',
20
+ args: { filename: 'research.md', content: 'Research content here...' },
21
+ result: 'File created successfully',
22
+ status: 'completed',
23
+ },
24
+ },
25
+ }
26
+
27
+ export const Pending: Story = {
28
+ args: {
29
+ toolCall: {
30
+ id: 'tool_2',
31
+ name: 'analyze_data',
32
+ args: { dataset: 'user_metrics', filters: ['active_users', 'retention'] },
33
+ result: null,
34
+ status: 'pending',
35
+ },
36
+ },
37
+ }
38
+
39
+ export const Error: Story = {
40
+ args: {
41
+ toolCall: {
42
+ id: 'tool_3',
43
+ name: 'fetch_data',
44
+ args: { url: 'https://api.example.com/data' },
45
+ result: 'Connection timeout after 30 seconds',
46
+ status: 'error',
47
+ },
48
+ },
49
+ }
@@ -0,0 +1,108 @@
1
+ import * as React from "react"
2
+ import {
3
+ Tool,
4
+ ToolHeader,
5
+ ToolContent,
6
+ ToolInput,
7
+ ToolOutput,
8
+ } from "@/components/ai-elements/tool"
9
+
10
+ /**
11
+ * ToolCallDisplay Block
12
+ *
13
+ * A block component that extends the Tool AI element to display tool execution details
14
+ * with expandable input parameters and output results. Copied logic from reference implementation.
15
+ */
16
+
17
+ export interface ToolCall {
18
+ id: string
19
+ name: string
20
+ args: Record<string, unknown>
21
+ result?: string
22
+ status: "pending" | "completed" | "error"
23
+ }
24
+
25
+ export interface ToolCallDisplayProps {
26
+ /**
27
+ * Tool call data to display
28
+ */
29
+ toolCall: ToolCall
30
+ /**
31
+ * Whether the tool call is initially expanded
32
+ */
33
+ defaultExpanded?: boolean
34
+ }
35
+
36
+ /**
37
+ * ToolCallDisplay component - displays tool execution with expandable details
38
+ */
39
+ export const ToolCallDisplay = React.memo<ToolCallDisplayProps>(
40
+ ({ toolCall, defaultExpanded = false }) => {
41
+ const [isExpanded, setIsExpanded] = React.useState(defaultExpanded)
42
+
43
+ const { name, args, result, status } = React.useMemo(() => {
44
+ const toolName = toolCall.name || "Unknown Tool"
45
+ const toolArgs = toolCall.args || {}
46
+ let parsedArgs: Record<string, unknown> = {}
47
+ try {
48
+ parsedArgs = typeof toolArgs === "string" ? JSON.parse(toolArgs) : toolArgs
49
+ } catch {
50
+ parsedArgs = { raw: toolArgs }
51
+ }
52
+ const toolResult = toolCall.result || null
53
+ const toolStatus = toolCall.status || "completed"
54
+
55
+ return {
56
+ name: toolName,
57
+ args: parsedArgs,
58
+ result: toolResult,
59
+ status: toolStatus,
60
+ }
61
+ }, [toolCall])
62
+
63
+ const toggleExpanded = React.useCallback(() => {
64
+ setIsExpanded((prev) => !prev)
65
+ }, [])
66
+
67
+ const hasContent = React.useMemo(() => {
68
+ return result !== null || Object.keys(args).length > 0
69
+ }, [result, args])
70
+
71
+ // Map our status to Tool AI element status
72
+ const toolState = React.useMemo(() => {
73
+ switch (status) {
74
+ case "pending":
75
+ return "input-available" as const
76
+ case "completed":
77
+ return "output-available" as const
78
+ case "error":
79
+ return "output-error" as const
80
+ default:
81
+ return "output-available" as const
82
+ }
83
+ }, [status])
84
+
85
+ return (
86
+ <Tool defaultOpen={isExpanded}>
87
+ <ToolHeader
88
+ title={name}
89
+ type={`tool-${name}` as const}
90
+ state={toolState}
91
+ />
92
+ <ToolContent>
93
+ {Object.keys(args).length > 0 && (
94
+ <ToolInput input={args} />
95
+ )}
96
+ {result && (
97
+ <ToolOutput
98
+ output={result}
99
+ errorText={status === "error" ? result : undefined}
100
+ />
101
+ )}
102
+ </ToolContent>
103
+ </Tool>
104
+ )
105
+ }
106
+ )
107
+
108
+ ToolCallDisplay.displayName = "ToolCallDisplay"
@@ -0,0 +1,8 @@
1
+ /**
2
+ * ToolCallDisplay Block
3
+ *
4
+ * Central export point for the ToolCallDisplay block component and its related types.
5
+ */
6
+ export { ToolCallDisplay } from './ToolCallDisplay'
7
+
8
+ export type { ToolCallDisplayProps, ToolCall } from './ToolCallDisplay'
@@ -0,0 +1,59 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { UserMessage } from './UserMessage'
3
+
4
+ const meta: Meta<typeof UserMessage> = {
5
+ title: 'Composites/UserMessage',
6
+ component: UserMessage,
7
+ parameters: {
8
+ layout: 'padded',
9
+ },
10
+ } satisfies Meta<typeof UserMessage>
11
+
12
+ export default meta
13
+ type Story = StoryObj<typeof meta>
14
+
15
+ export const Default: Story = {
16
+ args: {
17
+ message: {
18
+ id: '1',
19
+ content: 'Hello, I need help with something',
20
+ avatarSrc: 'https://images.unsplash.com/photo-1494790108755-2616b612b786?w=32&h=32&fit=crop&crop=face',
21
+ avatarName: 'User',
22
+ },
23
+ showAvatar: true,
24
+ },
25
+ }
26
+
27
+ export const WithoutAvatar: Story = {
28
+ args: {
29
+ message: {
30
+ id: '2',
31
+ content: 'This is a user message without an avatar',
32
+ },
33
+ showAvatar: false,
34
+ },
35
+ }
36
+
37
+ export const LongMessage: Story = {
38
+ args: {
39
+ message: {
40
+ id: '3',
41
+ content: 'This is a much longer user message that contains multiple sentences. It demonstrates how the component handles longer text content and how it wraps appropriately within the message bubble. The text should remain readable and properly formatted even when it spans multiple lines.',
42
+ avatarSrc: 'https://images.unsplash.com/photo-1494790108755-2616b612b786?w=32&h=32&fit=crop&crop=face',
43
+ avatarName: 'User',
44
+ },
45
+ showAvatar: true,
46
+ },
47
+ }
48
+
49
+ export const ShortQuestion: Story = {
50
+ args: {
51
+ message: {
52
+ id: '4',
53
+ content: 'Why?',
54
+ avatarSrc: 'https://images.unsplash.com/photo-1494790108755-2616b612b786?w=32&h=32&fit=crop&crop=face',
55
+ avatarName: 'User',
56
+ },
57
+ showAvatar: true,
58
+ },
59
+ }
@@ -0,0 +1,52 @@
1
+ import * as React from "react"
2
+ import {
3
+ Message,
4
+ MessageContent,
5
+ MessageAvatar,
6
+ } from "@/components/ai-elements/message"
7
+
8
+ /**
9
+ * UserMessage Block
10
+ *
11
+ * A simple block component for displaying user messages.
12
+ * Uses Message AI element with right-alignment.
13
+ */
14
+
15
+ export interface UserMessageData {
16
+ id: string
17
+ content: string
18
+ avatarSrc?: string
19
+ avatarName?: string
20
+ }
21
+
22
+ export interface UserMessageProps {
23
+ /**
24
+ * User message data to display
25
+ */
26
+ message: UserMessageData
27
+ /**
28
+ * Whether to show avatar
29
+ */
30
+ showAvatar?: boolean
31
+ }
32
+
33
+ /**
34
+ * UserMessage component - displays user messages with right alignment
35
+ */
36
+ export const UserMessage = React.memo<UserMessageProps>(
37
+ ({ message, showAvatar = true }) => {
38
+ return (
39
+ <Message from="user">
40
+ {showAvatar && (
41
+ <MessageAvatar
42
+ src={message.avatarSrc || "/user-avatar.png"}
43
+ name={message.avatarName || "User"}
44
+ />
45
+ )}
46
+ <MessageContent variant="contained">{message.content}</MessageContent>
47
+ </Message>
48
+ )
49
+ }
50
+ )
51
+
52
+ UserMessage.displayName = "UserMessage"
@@ -0,0 +1,8 @@
1
+ /**
2
+ * UserMessage Block
3
+ *
4
+ * Central export point for the UserMessage block component and its related types.
5
+ */
6
+ export { UserMessage } from './UserMessage'
7
+
8
+ export type { UserMessageProps, UserMessageData } from './UserMessage'