@slexn/codecenter-ui 1.0.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 (472) hide show
  1. package/LICENSE +34 -0
  2. package/README.md +148 -0
  3. package/components.json +20 -0
  4. package/dist/codecenter-ui.cjs +10 -0
  5. package/dist/codecenter-ui.js +17995 -0
  6. package/dist/components/ui/accordion/Accordion.vue.d.ts +28 -0
  7. package/dist/components/ui/accordion/AccordionContent.vue.d.ts +22 -0
  8. package/dist/components/ui/accordion/AccordionItem.vue.d.ts +24 -0
  9. package/dist/components/ui/accordion/AccordionTrigger.vue.d.ts +22 -0
  10. package/dist/components/ui/accordion/index.d.ts +4 -0
  11. package/dist/components/ui/alert/Alert.vue.d.ts +32 -0
  12. package/dist/components/ui/alert/AlertDescription.vue.d.ts +24 -0
  13. package/dist/components/ui/alert/AlertTitle.vue.d.ts +24 -0
  14. package/dist/components/ui/alert/index.d.ts +4 -0
  15. package/dist/components/ui/alert/variants.d.ts +5 -0
  16. package/dist/components/ui/button/Button.vue.d.ts +27 -0
  17. package/dist/components/ui/button/index.d.ts +2 -0
  18. package/dist/components/ui/button/variants.d.ts +6 -0
  19. package/dist/components/ui/button-group/ButtonGroup.vue.d.ts +25 -0
  20. package/dist/components/ui/button-group/index.d.ts +2 -0
  21. package/dist/components/ui/card/Card.vue.d.ts +21 -0
  22. package/dist/components/ui/card/CardContent.vue.d.ts +21 -0
  23. package/dist/components/ui/card/CardDescription.vue.d.ts +21 -0
  24. package/dist/components/ui/card/CardFooter.vue.d.ts +21 -0
  25. package/dist/components/ui/card/CardHeader.vue.d.ts +21 -0
  26. package/dist/components/ui/card/CardTitle.vue.d.ts +21 -0
  27. package/dist/components/ui/card/index.d.ts +6 -0
  28. package/dist/components/ui/chart/Chart.vue.d.ts +92 -0
  29. package/dist/components/ui/chart/index.d.ts +2 -0
  30. package/dist/components/ui/chat/Chat.vue.d.ts +190 -0
  31. package/dist/components/ui/chat/ChatAttachments.vue.d.ts +11 -0
  32. package/dist/components/ui/chat/ChatCodeBlock.vue.d.ts +16 -0
  33. package/dist/components/ui/chat/code-block.d.ts +27 -0
  34. package/dist/components/ui/chat/index.d.ts +6 -0
  35. package/dist/components/ui/chat/types.d.ts +15 -0
  36. package/dist/components/ui/checkbox/Checkbox.vue.d.ts +29 -0
  37. package/dist/components/ui/checkbox/index.d.ts +1 -0
  38. package/dist/components/ui/commit/Commit.vue.d.ts +62 -0
  39. package/dist/components/ui/commit/index.d.ts +2 -0
  40. package/dist/components/ui/contribution-graph/ContributionGraph.vue.d.ts +87 -0
  41. package/dist/components/ui/contribution-graph/index.d.ts +2 -0
  42. package/dist/components/ui/data-table/DataTable.vue.d.ts +109 -0
  43. package/dist/components/ui/data-table/index.d.ts +2 -0
  44. package/dist/components/ui/date-picker/DatePicker.vue.d.ts +37 -0
  45. package/dist/components/ui/date-picker/index.d.ts +2 -0
  46. package/dist/components/ui/dialog/Dialog.vue.d.ts +25 -0
  47. package/dist/components/ui/dialog/DialogClose.vue.d.ts +18 -0
  48. package/dist/components/ui/dialog/DialogContent.vue.d.ts +39 -0
  49. package/dist/components/ui/dialog/DialogDescription.vue.d.ts +22 -0
  50. package/dist/components/ui/dialog/DialogFooter.vue.d.ts +21 -0
  51. package/dist/components/ui/dialog/DialogHeader.vue.d.ts +21 -0
  52. package/dist/components/ui/dialog/DialogOverlay.vue.d.ts +22 -0
  53. package/dist/components/ui/dialog/DialogScrollContent.vue.d.ts +36 -0
  54. package/dist/components/ui/dialog/DialogTitle.vue.d.ts +22 -0
  55. package/dist/components/ui/dialog/DialogTrigger.vue.d.ts +18 -0
  56. package/dist/components/ui/dialog/index.d.ts +10 -0
  57. package/dist/components/ui/diff/DiffTool.vue.d.ts +21 -0
  58. package/dist/components/ui/diff/diff-parser.d.ts +30 -0
  59. package/dist/components/ui/diff/diff-tool.d.ts +36 -0
  60. package/dist/components/ui/diff/index.d.ts +2 -0
  61. package/dist/components/ui/dropdown-menu/DropdownMenu.vue.d.ts +24 -0
  62. package/dist/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue.d.ts +29 -0
  63. package/dist/components/ui/dropdown-menu/DropdownMenuContent.vue.d.ts +36 -0
  64. package/dist/components/ui/dropdown-menu/DropdownMenuGroup.vue.d.ts +18 -0
  65. package/dist/components/ui/dropdown-menu/DropdownMenuItem.vue.d.ts +26 -0
  66. package/dist/components/ui/dropdown-menu/DropdownMenuLabel.vue.d.ts +23 -0
  67. package/dist/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue.d.ts +22 -0
  68. package/dist/components/ui/dropdown-menu/DropdownMenuRadioItem.vue.d.ts +27 -0
  69. package/dist/components/ui/dropdown-menu/DropdownMenuSeparator.vue.d.ts +7 -0
  70. package/dist/components/ui/dropdown-menu/DropdownMenuShortcut.vue.d.ts +21 -0
  71. package/dist/components/ui/dropdown-menu/DropdownMenuSub.vue.d.ts +22 -0
  72. package/dist/components/ui/dropdown-menu/DropdownMenuSubContent.vue.d.ts +38 -0
  73. package/dist/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue.d.ts +23 -0
  74. package/dist/components/ui/dropdown-menu/DropdownMenuTrigger.vue.d.ts +18 -0
  75. package/dist/components/ui/dropdown-menu/index.d.ts +15 -0
  76. package/dist/components/ui/gauge/Gauge.vue.d.ts +62 -0
  77. package/dist/components/ui/gauge/index.d.ts +2 -0
  78. package/dist/components/ui/git-graph/GitGraph.vue.d.ts +59 -0
  79. package/dist/components/ui/git-graph/index.d.ts +2 -0
  80. package/dist/components/ui/incident-timeline/IncidentTimeline.vue.d.ts +50 -0
  81. package/dist/components/ui/incident-timeline/index.d.ts +2 -0
  82. package/dist/components/ui/input/Input.vue.d.ts +14 -0
  83. package/dist/components/ui/input/InputControl.vue.d.ts +14 -0
  84. package/dist/components/ui/input/InputFieldGroup.vue.d.ts +21 -0
  85. package/dist/components/ui/input/index.d.ts +4 -0
  86. package/dist/components/ui/input/types.d.ts +31 -0
  87. package/dist/components/ui/kpi-card/KpiCard.vue.d.ts +46 -0
  88. package/dist/components/ui/kpi-card/index.d.ts +2 -0
  89. package/dist/components/ui/kpi-line-card/KpiLineCard.vue.d.ts +66 -0
  90. package/dist/components/ui/kpi-line-card/index.d.ts +2 -0
  91. package/dist/components/ui/model-selector/ModelSelector.vue.d.ts +41 -0
  92. package/dist/components/ui/model-selector/index.d.ts +2 -0
  93. package/dist/components/ui/model-selector/types.d.ts +12 -0
  94. package/dist/components/ui/network-graph/NetworkGraph.vue.d.ts +75 -0
  95. package/dist/components/ui/network-graph/index.d.ts +2 -0
  96. package/dist/components/ui/pagination/Pagination.vue.d.ts +29 -0
  97. package/dist/components/ui/pagination/PaginationContent.vue.d.ts +29 -0
  98. package/dist/components/ui/pagination/PaginationEllipsis.vue.d.ts +22 -0
  99. package/dist/components/ui/pagination/PaginationFirst.vue.d.ts +26 -0
  100. package/dist/components/ui/pagination/PaginationItem.vue.d.ts +28 -0
  101. package/dist/components/ui/pagination/PaginationLast.vue.d.ts +26 -0
  102. package/dist/components/ui/pagination/PaginationNext.vue.d.ts +26 -0
  103. package/dist/components/ui/pagination/PaginationPrevious.vue.d.ts +26 -0
  104. package/dist/components/ui/pagination/index.d.ts +8 -0
  105. package/dist/components/ui/profile/Profile.vue.d.ts +30 -0
  106. package/dist/components/ui/profile/ProfileGroup.vue.d.ts +37 -0
  107. package/dist/components/ui/profile/index.d.ts +4 -0
  108. package/dist/components/ui/progress/Progress.vue.d.ts +36 -0
  109. package/dist/components/ui/progress/index.d.ts +2 -0
  110. package/dist/components/ui/prompt-input/PromptInput.vue.d.ts +150 -0
  111. package/dist/components/ui/prompt-input/index.d.ts +2 -0
  112. package/dist/components/ui/prompt-input/types.d.ts +61 -0
  113. package/dist/components/ui/radio-group/RadioGroup.vue.d.ts +30 -0
  114. package/dist/components/ui/radio-group/RadioGroupItem.vue.d.ts +12 -0
  115. package/dist/components/ui/radio-group/RadioGroupOption.vue.d.ts +28 -0
  116. package/dist/components/ui/radio-group/index.d.ts +3 -0
  117. package/dist/components/ui/reasoning/Reasoning.vue.d.ts +40 -0
  118. package/dist/components/ui/reasoning/index.d.ts +2 -0
  119. package/dist/components/ui/reasoning/types.d.ts +26 -0
  120. package/dist/components/ui/select/Select.vue.d.ts +28 -0
  121. package/dist/components/ui/select/SelectContent.vue.d.ts +46 -0
  122. package/dist/components/ui/select/SelectGroup.vue.d.ts +18 -0
  123. package/dist/components/ui/select/SelectItem.vue.d.ts +26 -0
  124. package/dist/components/ui/select/SelectItemText.vue.d.ts +18 -0
  125. package/dist/components/ui/select/SelectLabel.vue.d.ts +22 -0
  126. package/dist/components/ui/select/SelectScrollDownButton.vue.d.ts +22 -0
  127. package/dist/components/ui/select/SelectScrollUpButton.vue.d.ts +22 -0
  128. package/dist/components/ui/select/SelectSeparator.vue.d.ts +7 -0
  129. package/dist/components/ui/select/SelectTrigger.vue.d.ts +25 -0
  130. package/dist/components/ui/select/SelectValue.vue.d.ts +18 -0
  131. package/dist/components/ui/select/index.d.ts +11 -0
  132. package/dist/components/ui/select/search.d.ts +18 -0
  133. package/dist/components/ui/separator/Separator.vue.d.ts +6 -0
  134. package/dist/components/ui/separator/index.d.ts +2 -0
  135. package/dist/components/ui/separator/types.d.ts +7 -0
  136. package/dist/components/ui/shimmer/Shimmer.vue.d.ts +37 -0
  137. package/dist/components/ui/shimmer/index.d.ts +2 -0
  138. package/dist/components/ui/sidebar/Sidebar.vue.d.ts +24 -0
  139. package/dist/components/ui/sidebar/SidebarContent.vue.d.ts +21 -0
  140. package/dist/components/ui/sidebar/SidebarFooter.vue.d.ts +21 -0
  141. package/dist/components/ui/sidebar/SidebarGroup.vue.d.ts +21 -0
  142. package/dist/components/ui/sidebar/SidebarGroupAction.vue.d.ts +24 -0
  143. package/dist/components/ui/sidebar/SidebarGroupContent.vue.d.ts +21 -0
  144. package/dist/components/ui/sidebar/SidebarGroupLabel.vue.d.ts +24 -0
  145. package/dist/components/ui/sidebar/SidebarHeader.vue.d.ts +21 -0
  146. package/dist/components/ui/sidebar/SidebarInput.vue.d.ts +6 -0
  147. package/dist/components/ui/sidebar/SidebarInset.vue.d.ts +21 -0
  148. package/dist/components/ui/sidebar/SidebarMenu.vue.d.ts +21 -0
  149. package/dist/components/ui/sidebar/SidebarMenuAction.vue.d.ts +25 -0
  150. package/dist/components/ui/sidebar/SidebarMenuBadge.vue.d.ts +21 -0
  151. package/dist/components/ui/sidebar/SidebarMenuButton.vue.d.ts +25 -0
  152. package/dist/components/ui/sidebar/SidebarMenuButtonChild.vue.d.ts +30 -0
  153. package/dist/components/ui/sidebar/SidebarMenuItem.vue.d.ts +21 -0
  154. package/dist/components/ui/sidebar/SidebarMenuSub.vue.d.ts +21 -0
  155. package/dist/components/ui/sidebar/SidebarMenuSubButton.vue.d.ts +27 -0
  156. package/dist/components/ui/sidebar/SidebarMenuSubItem.vue.d.ts +21 -0
  157. package/dist/components/ui/sidebar/SidebarProvider.vue.d.ts +36 -0
  158. package/dist/components/ui/sidebar/SidebarRail.vue.d.ts +21 -0
  159. package/dist/components/ui/sidebar/SidebarSeparator.vue.d.ts +6 -0
  160. package/dist/components/ui/sidebar/SidebarTrigger.vue.d.ts +6 -0
  161. package/dist/components/ui/sidebar/context.d.ts +19 -0
  162. package/dist/components/ui/sidebar/index.d.ts +26 -0
  163. package/dist/components/ui/sidebar/types.d.ts +11 -0
  164. package/dist/components/ui/sidebar/variants.d.ts +6 -0
  165. package/dist/components/ui/skeleton/Skeleton.vue.d.ts +18 -0
  166. package/dist/components/ui/skeleton/index.d.ts +2 -0
  167. package/dist/components/ui/sonner/Sonner.vue.d.ts +5 -0
  168. package/dist/components/ui/sonner/index.d.ts +2 -0
  169. package/dist/components/ui/spinner/Spinner.vue.d.ts +11 -0
  170. package/dist/components/ui/spinner/index.d.ts +1 -0
  171. package/dist/components/ui/stepper/Stepper.vue.d.ts +38 -0
  172. package/dist/components/ui/stepper/StepperDescription.vue.d.ts +22 -0
  173. package/dist/components/ui/stepper/StepperIndicator.vue.d.ts +30 -0
  174. package/dist/components/ui/stepper/StepperItem.vue.d.ts +24 -0
  175. package/dist/components/ui/stepper/StepperSeparator.vue.d.ts +7 -0
  176. package/dist/components/ui/stepper/StepperTitle.vue.d.ts +22 -0
  177. package/dist/components/ui/stepper/StepperTrigger.vue.d.ts +22 -0
  178. package/dist/components/ui/stepper/index.d.ts +7 -0
  179. package/dist/components/ui/switch/Switch.vue.d.ts +12 -0
  180. package/dist/components/ui/switch/index.d.ts +1 -0
  181. package/dist/components/ui/table/Table.vue.d.ts +22 -0
  182. package/dist/components/ui/table/TableBody.vue.d.ts +21 -0
  183. package/dist/components/ui/table/TableCaption.vue.d.ts +21 -0
  184. package/dist/components/ui/table/TableCell.vue.d.ts +22 -0
  185. package/dist/components/ui/table/TableEmpty.vue.d.ts +24 -0
  186. package/dist/components/ui/table/TableFooter.vue.d.ts +21 -0
  187. package/dist/components/ui/table/TableHead.vue.d.ts +21 -0
  188. package/dist/components/ui/table/TableHeader.vue.d.ts +21 -0
  189. package/dist/components/ui/table/TableRow.vue.d.ts +21 -0
  190. package/dist/components/ui/table/index.d.ts +9 -0
  191. package/dist/components/ui/tabs/Tabs.vue.d.ts +28 -0
  192. package/dist/components/ui/tabs/TabsContent.vue.d.ts +22 -0
  193. package/dist/components/ui/tabs/TabsList.vue.d.ts +22 -0
  194. package/dist/components/ui/tabs/TabsTrigger.vue.d.ts +22 -0
  195. package/dist/components/ui/tabs/index.d.ts +4 -0
  196. package/dist/components/ui/tag/Tag.vue.d.ts +35 -0
  197. package/dist/components/ui/tag/index.d.ts +2 -0
  198. package/dist/components/ui/tag/variants.d.ts +6 -0
  199. package/dist/components/ui/textarea/Textarea.vue.d.ts +14 -0
  200. package/dist/components/ui/textarea/TextareaControl.vue.d.ts +14 -0
  201. package/dist/components/ui/textarea/TextareaFieldGroup.vue.d.ts +21 -0
  202. package/dist/components/ui/textarea/index.d.ts +4 -0
  203. package/dist/components/ui/textarea/types.d.ts +32 -0
  204. package/dist/components/ui/tool/Tool.vue.d.ts +61 -0
  205. package/dist/components/ui/tool/index.d.ts +2 -0
  206. package/dist/components/ui/tooltip/Tooltip.vue.d.ts +24 -0
  207. package/dist/components/ui/tooltip/TooltipContent.vue.d.ts +32 -0
  208. package/dist/components/ui/tooltip/TooltipProvider.vue.d.ts +20 -0
  209. package/dist/components/ui/tooltip/TooltipTrigger.vue.d.ts +18 -0
  210. package/dist/components/ui/tooltip/index.d.ts +4 -0
  211. package/dist/docs/component-docs.d.ts +18 -0
  212. package/dist/docs/markdown.d.ts +27 -0
  213. package/dist/index.d.ts +45 -0
  214. package/dist/lib/code-highlight.d.ts +11 -0
  215. package/dist/lib/utils.d.ts +2 -0
  216. package/dist/styles.css +3 -0
  217. package/package.json +76 -0
  218. package/public/r/accordion.json +52 -0
  219. package/public/r/alert.json +51 -0
  220. package/public/r/button-group.json +31 -0
  221. package/public/r/button.json +39 -0
  222. package/public/r/card.json +61 -0
  223. package/public/r/chart.json +31 -0
  224. package/public/r/chat.json +186 -0
  225. package/public/r/checkbox.json +34 -0
  226. package/public/r/commit.json +32 -0
  227. package/public/r/contribution-graph.json +63 -0
  228. package/public/r/data-table.json +197 -0
  229. package/public/r/date-picker.json +33 -0
  230. package/public/r/dialog.json +88 -0
  231. package/public/r/diff.json +71 -0
  232. package/public/r/dropdown-menu.json +112 -0
  233. package/public/r/gauge.json +31 -0
  234. package/public/r/git-graph.json +32 -0
  235. package/public/r/incident-timeline.json +64 -0
  236. package/public/r/input.json +49 -0
  237. package/public/r/kpi-card.json +32 -0
  238. package/public/r/kpi-line-card.json +32 -0
  239. package/public/r/model-selector.json +148 -0
  240. package/public/r/network-graph.json +33 -0
  241. package/public/r/pagination.json +95 -0
  242. package/public/r/profile.json +37 -0
  243. package/public/r/progress.json +31 -0
  244. package/public/r/prompt-input.json +293 -0
  245. package/public/r/radio-group.json +45 -0
  246. package/public/r/reasoning.json +38 -0
  247. package/public/r/registry.json +2512 -0
  248. package/public/r/select.json +100 -0
  249. package/public/r/separator.json +37 -0
  250. package/public/r/shimmer.json +31 -0
  251. package/public/r/sidebar.json +221 -0
  252. package/public/r/skeleton.json +31 -0
  253. package/public/r/sonner.json +33 -0
  254. package/public/r/spinner.json +31 -0
  255. package/public/r/stepper.json +70 -0
  256. package/public/r/switch.json +33 -0
  257. package/public/r/table.json +79 -0
  258. package/public/r/tabs.json +51 -0
  259. package/public/r/tag.json +39 -0
  260. package/public/r/textarea.json +49 -0
  261. package/public/r/tool.json +32 -0
  262. package/public/r/tooltip.json +51 -0
  263. package/registry.json +2512 -0
  264. package/src/components/docs/MarkdownContent.vue +106 -0
  265. package/src/components/ui/accordion/Accordion.vue +24 -0
  266. package/src/components/ui/accordion/AccordionContent.vue +62 -0
  267. package/src/components/ui/accordion/AccordionItem.vue +23 -0
  268. package/src/components/ui/accordion/AccordionTrigger.vue +38 -0
  269. package/src/components/ui/accordion/index.ts +4 -0
  270. package/src/components/ui/alert/Alert.vue +40 -0
  271. package/src/components/ui/alert/AlertDescription.vue +24 -0
  272. package/src/components/ui/alert/AlertTitle.vue +24 -0
  273. package/src/components/ui/alert/index.ts +4 -0
  274. package/src/components/ui/alert/variants.ts +19 -0
  275. package/src/components/ui/button/Button.vue +27 -0
  276. package/src/components/ui/button/index.ts +2 -0
  277. package/src/components/ui/button/variants.ts +32 -0
  278. package/src/components/ui/button-group/ButtonGroup.vue +31 -0
  279. package/src/components/ui/button-group/index.ts +2 -0
  280. package/src/components/ui/card/Card.vue +17 -0
  281. package/src/components/ui/card/CardContent.vue +14 -0
  282. package/src/components/ui/card/CardDescription.vue +14 -0
  283. package/src/components/ui/card/CardFooter.vue +14 -0
  284. package/src/components/ui/card/CardHeader.vue +17 -0
  285. package/src/components/ui/card/CardTitle.vue +14 -0
  286. package/src/components/ui/card/index.ts +6 -0
  287. package/src/components/ui/chart/Chart.vue +1042 -0
  288. package/src/components/ui/chart/index.ts +13 -0
  289. package/src/components/ui/chat/Chat.vue +1297 -0
  290. package/src/components/ui/chat/ChatAttachments.vue +278 -0
  291. package/src/components/ui/chat/ChatCodeBlock.vue +283 -0
  292. package/src/components/ui/chat/code-block.ts +30 -0
  293. package/src/components/ui/chat/index.ts +24 -0
  294. package/src/components/ui/chat/types.ts +23 -0
  295. package/src/components/ui/checkbox/Checkbox.vue +38 -0
  296. package/src/components/ui/checkbox/index.ts +1 -0
  297. package/src/components/ui/commit/Commit.vue +423 -0
  298. package/src/components/ui/commit/index.ts +9 -0
  299. package/src/components/ui/contribution-graph/ContributionGraph.vue +719 -0
  300. package/src/components/ui/contribution-graph/index.ts +9 -0
  301. package/src/components/ui/data-table/DataTable.vue +534 -0
  302. package/src/components/ui/data-table/index.ts +9 -0
  303. package/src/components/ui/date-picker/DatePicker.vue +649 -0
  304. package/src/components/ui/date-picker/index.ts +7 -0
  305. package/src/components/ui/dialog/Dialog.vue +19 -0
  306. package/src/components/ui/dialog/DialogClose.vue +17 -0
  307. package/src/components/ui/dialog/DialogContent.vue +60 -0
  308. package/src/components/ui/dialog/DialogDescription.vue +23 -0
  309. package/src/components/ui/dialog/DialogFooter.vue +17 -0
  310. package/src/components/ui/dialog/DialogHeader.vue +17 -0
  311. package/src/components/ui/dialog/DialogOverlay.vue +23 -0
  312. package/src/components/ui/dialog/DialogScrollContent.vue +69 -0
  313. package/src/components/ui/dialog/DialogTitle.vue +23 -0
  314. package/src/components/ui/dialog/DialogTrigger.vue +17 -0
  315. package/src/components/ui/dialog/index.ts +10 -0
  316. package/src/components/ui/diff/DiffTool.vue +513 -0
  317. package/src/components/ui/diff/diff-parser.ts +423 -0
  318. package/src/components/ui/diff/diff-tool.ts +39 -0
  319. package/src/components/ui/diff/index.ts +5 -0
  320. package/src/components/ui/dropdown-menu/DropdownMenu.vue +19 -0
  321. package/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +39 -0
  322. package/src/components/ui/dropdown-menu/DropdownMenuContent.vue +39 -0
  323. package/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +15 -0
  324. package/src/components/ui/dropdown-menu/DropdownMenuItem.vue +31 -0
  325. package/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +23 -0
  326. package/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +21 -0
  327. package/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +40 -0
  328. package/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +23 -0
  329. package/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +17 -0
  330. package/src/components/ui/dropdown-menu/DropdownMenuSub.vue +18 -0
  331. package/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +27 -0
  332. package/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +31 -0
  333. package/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +17 -0
  334. package/src/components/ui/dropdown-menu/index.ts +16 -0
  335. package/src/components/ui/gauge/Gauge.vue +725 -0
  336. package/src/components/ui/gauge/index.ts +9 -0
  337. package/src/components/ui/git-graph/GitGraph.vue +715 -0
  338. package/src/components/ui/git-graph/index.ts +9 -0
  339. package/src/components/ui/incident-timeline/IncidentTimeline.vue +360 -0
  340. package/src/components/ui/incident-timeline/index.ts +7 -0
  341. package/src/components/ui/input/Input.vue +159 -0
  342. package/src/components/ui/input/InputControl.vue +135 -0
  343. package/src/components/ui/input/InputFieldGroup.vue +14 -0
  344. package/src/components/ui/input/index.ts +9 -0
  345. package/src/components/ui/input/types.ts +34 -0
  346. package/src/components/ui/kpi-card/KpiCard.vue +268 -0
  347. package/src/components/ui/kpi-card/index.ts +9 -0
  348. package/src/components/ui/kpi-line-card/KpiLineCard.vue +622 -0
  349. package/src/components/ui/kpi-line-card/index.ts +11 -0
  350. package/src/components/ui/model-selector/ModelSelector.vue +328 -0
  351. package/src/components/ui/model-selector/index.ts +6 -0
  352. package/src/components/ui/model-selector/types.ts +15 -0
  353. package/src/components/ui/network-graph/NetworkGraph.vue +902 -0
  354. package/src/components/ui/network-graph/index.ts +7 -0
  355. package/src/components/ui/pagination/Pagination.vue +26 -0
  356. package/src/components/ui/pagination/PaginationContent.vue +24 -0
  357. package/src/components/ui/pagination/PaginationEllipsis.vue +27 -0
  358. package/src/components/ui/pagination/PaginationFirst.vue +33 -0
  359. package/src/components/ui/pagination/PaginationItem.vue +39 -0
  360. package/src/components/ui/pagination/PaginationLast.vue +33 -0
  361. package/src/components/ui/pagination/PaginationNext.vue +33 -0
  362. package/src/components/ui/pagination/PaginationPrevious.vue +33 -0
  363. package/src/components/ui/pagination/index.ts +8 -0
  364. package/src/components/ui/profile/Profile.vue +226 -0
  365. package/src/components/ui/profile/ProfileGroup.vue +96 -0
  366. package/src/components/ui/profile/index.ts +8 -0
  367. package/src/components/ui/progress/Progress.vue +271 -0
  368. package/src/components/ui/progress/index.ts +9 -0
  369. package/src/components/ui/prompt-input/PromptInput.vue +1094 -0
  370. package/src/components/ui/prompt-input/index.ts +14 -0
  371. package/src/components/ui/prompt-input/types.ts +78 -0
  372. package/src/components/ui/radio-group/RadioGroup.vue +36 -0
  373. package/src/components/ui/radio-group/RadioGroupItem.vue +45 -0
  374. package/src/components/ui/radio-group/RadioGroupOption.vue +80 -0
  375. package/src/components/ui/radio-group/index.ts +3 -0
  376. package/src/components/ui/reasoning/Reasoning.vue +278 -0
  377. package/src/components/ui/reasoning/index.ts +8 -0
  378. package/src/components/ui/reasoning/types.ts +29 -0
  379. package/src/components/ui/select/Select.vue +19 -0
  380. package/src/components/ui/select/SelectContent.vue +166 -0
  381. package/src/components/ui/select/SelectGroup.vue +23 -0
  382. package/src/components/ui/select/SelectItem.vue +97 -0
  383. package/src/components/ui/select/SelectItemText.vue +15 -0
  384. package/src/components/ui/select/SelectLabel.vue +17 -0
  385. package/src/components/ui/select/SelectScrollDownButton.vue +26 -0
  386. package/src/components/ui/select/SelectScrollUpButton.vue +26 -0
  387. package/src/components/ui/select/SelectSeparator.vue +19 -0
  388. package/src/components/ui/select/SelectTrigger.vue +33 -0
  389. package/src/components/ui/select/SelectValue.vue +15 -0
  390. package/src/components/ui/select/index.ts +11 -0
  391. package/src/components/ui/select/search.ts +26 -0
  392. package/src/components/ui/separator/Separator.vue +30 -0
  393. package/src/components/ui/separator/index.ts +5 -0
  394. package/src/components/ui/separator/types.ts +9 -0
  395. package/src/components/ui/shimmer/Shimmer.vue +110 -0
  396. package/src/components/ui/shimmer/index.ts +5 -0
  397. package/src/components/ui/sidebar/Sidebar.vue +142 -0
  398. package/src/components/ui/sidebar/SidebarContent.vue +18 -0
  399. package/src/components/ui/sidebar/SidebarFooter.vue +18 -0
  400. package/src/components/ui/sidebar/SidebarGroup.vue +18 -0
  401. package/src/components/ui/sidebar/SidebarGroupAction.vue +31 -0
  402. package/src/components/ui/sidebar/SidebarGroupContent.vue +18 -0
  403. package/src/components/ui/sidebar/SidebarGroupLabel.vue +30 -0
  404. package/src/components/ui/sidebar/SidebarHeader.vue +18 -0
  405. package/src/components/ui/sidebar/SidebarInput.vue +26 -0
  406. package/src/components/ui/sidebar/SidebarInset.vue +23 -0
  407. package/src/components/ui/sidebar/SidebarMenu.vue +18 -0
  408. package/src/components/ui/sidebar/SidebarMenuAction.vue +34 -0
  409. package/src/components/ui/sidebar/SidebarMenuBadge.vue +25 -0
  410. package/src/components/ui/sidebar/SidebarMenuButton.vue +37 -0
  411. package/src/components/ui/sidebar/SidebarMenuButtonChild.vue +38 -0
  412. package/src/components/ui/sidebar/SidebarMenuItem.vue +18 -0
  413. package/src/components/ui/sidebar/SidebarMenuSub.vue +18 -0
  414. package/src/components/ui/sidebar/SidebarMenuSubButton.vue +36 -0
  415. package/src/components/ui/sidebar/SidebarMenuSubItem.vue +18 -0
  416. package/src/components/ui/sidebar/SidebarProvider.vue +119 -0
  417. package/src/components/ui/sidebar/SidebarRail.vue +35 -0
  418. package/src/components/ui/sidebar/SidebarSeparator.vue +18 -0
  419. package/src/components/ui/sidebar/SidebarTrigger.vue +28 -0
  420. package/src/components/ui/sidebar/context.ts +39 -0
  421. package/src/components/ui/sidebar/index.ts +43 -0
  422. package/src/components/ui/sidebar/types.ts +13 -0
  423. package/src/components/ui/sidebar/variants.ts +25 -0
  424. package/src/components/ui/skeleton/Skeleton.vue +53 -0
  425. package/src/components/ui/skeleton/index.ts +5 -0
  426. package/src/components/ui/sonner/Sonner.vue +69 -0
  427. package/src/components/ui/sonner/index.ts +12 -0
  428. package/src/components/ui/spinner/Spinner.vue +33 -0
  429. package/src/components/ui/spinner/index.ts +1 -0
  430. package/src/components/ui/stepper/Stepper.vue +29 -0
  431. package/src/components/ui/stepper/StepperDescription.vue +30 -0
  432. package/src/components/ui/stepper/StepperIndicator.vue +50 -0
  433. package/src/components/ui/stepper/StepperItem.vue +28 -0
  434. package/src/components/ui/stepper/StepperSeparator.vue +25 -0
  435. package/src/components/ui/stepper/StepperTitle.vue +27 -0
  436. package/src/components/ui/stepper/StepperTrigger.vue +27 -0
  437. package/src/components/ui/stepper/index.ts +7 -0
  438. package/src/components/ui/switch/Switch.vue +41 -0
  439. package/src/components/ui/switch/index.ts +1 -0
  440. package/src/components/ui/table/Table.vue +23 -0
  441. package/src/components/ui/table/TableBody.vue +17 -0
  442. package/src/components/ui/table/TableCaption.vue +17 -0
  443. package/src/components/ui/table/TableCell.vue +24 -0
  444. package/src/components/ui/table/TableEmpty.vue +31 -0
  445. package/src/components/ui/table/TableFooter.vue +17 -0
  446. package/src/components/ui/table/TableHead.vue +22 -0
  447. package/src/components/ui/table/TableHeader.vue +17 -0
  448. package/src/components/ui/table/TableRow.vue +22 -0
  449. package/src/components/ui/table/index.ts +9 -0
  450. package/src/components/ui/tabs/Tabs.vue +24 -0
  451. package/src/components/ui/tabs/TabsContent.vue +22 -0
  452. package/src/components/ui/tabs/TabsList.vue +27 -0
  453. package/src/components/ui/tabs/TabsTrigger.vue +27 -0
  454. package/src/components/ui/tabs/index.ts +4 -0
  455. package/src/components/ui/tag/Tag.vue +55 -0
  456. package/src/components/ui/tag/index.ts +2 -0
  457. package/src/components/ui/tag/variants.ts +29 -0
  458. package/src/components/ui/textarea/Textarea.vue +159 -0
  459. package/src/components/ui/textarea/TextareaControl.vue +120 -0
  460. package/src/components/ui/textarea/TextareaFieldGroup.vue +14 -0
  461. package/src/components/ui/textarea/index.ts +10 -0
  462. package/src/components/ui/textarea/types.ts +35 -0
  463. package/src/components/ui/tool/Tool.vue +304 -0
  464. package/src/components/ui/tool/index.ts +7 -0
  465. package/src/components/ui/tooltip/Tooltip.vue +19 -0
  466. package/src/components/ui/tooltip/TooltipContent.vue +44 -0
  467. package/src/components/ui/tooltip/TooltipProvider.vue +14 -0
  468. package/src/components/ui/tooltip/TooltipTrigger.vue +15 -0
  469. package/src/components/ui/tooltip/index.ts +4 -0
  470. package/src/lib/code-highlight.ts +220 -0
  471. package/src/lib/utils.ts +6 -0
  472. package/src/styles.css +684 -0
@@ -0,0 +1,1094 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { computed, nextTick, onBeforeUnmount, onMounted, ref, useId, watch } from "vue"
4
+ import {
5
+ BotIcon,
6
+ BrainCircuitIcon,
7
+ FileIcon,
8
+ PaperclipIcon,
9
+ PlugIcon,
10
+ PlusIcon,
11
+ SendIcon,
12
+ SparklesIcon,
13
+ XIcon,
14
+ } from "@lucide/vue"
15
+ import { Button } from "@/components/ui/button"
16
+ import {
17
+ DropdownMenu,
18
+ DropdownMenuContent,
19
+ DropdownMenuItem,
20
+ DropdownMenuTrigger,
21
+ } from "@/components/ui/dropdown-menu"
22
+ import { ModelSelector, type ModelSelectorMode } from "@/components/ui/model-selector"
23
+ import { Tag } from "@/components/ui/tag"
24
+ import { cn } from "@/lib/utils"
25
+ import type {
26
+ PromptInputAddAction,
27
+ PromptInputAttachment,
28
+ PromptInputCommand,
29
+ PromptInputCommandData,
30
+ PromptInputCommandPayload,
31
+ PromptInputCommandRemovePayload,
32
+ PromptInputModel,
33
+ PromptInputSubmitPayload,
34
+ } from "./types"
35
+
36
+ interface PromptInputProps {
37
+ addActions?: PromptInputAddAction[]
38
+ addLabel?: string
39
+ allowEmpty?: boolean
40
+ attachmentAccept?: string
41
+ attachments?: PromptInputAttachment[]
42
+ class?: HTMLAttributes["class"]
43
+ clearAttachmentsOnSubmit?: boolean
44
+ clearCommandPayloadOnSubmit?: boolean
45
+ commandEmptyText?: string
46
+ commandLabel?: string
47
+ commandMenuClass?: HTMLAttributes["class"]
48
+ commandPayload?: PromptInputCommandData
49
+ commandTagRemoveLabel?: string
50
+ commandTrigger?: string
51
+ commands?: PromptInputCommand[]
52
+ disabled?: boolean
53
+ id?: string
54
+ maxRows?: number | string
55
+ model?: string
56
+ modelDialogClass?: HTMLAttributes["class"]
57
+ modelEmptyText?: string
58
+ modelLabel?: string
59
+ modelMenuClass?: HTMLAttributes["class"]
60
+ modelModalThreshold?: number
61
+ modelSearchPlaceholder?: string
62
+ modelSelectorMode?: ModelSelectorMode
63
+ modelValue?: string
64
+ models?: PromptInputModel[]
65
+ multipleAttachments?: boolean
66
+ placeholder?: string
67
+ removeAttachmentLabel?: string
68
+ rows?: number | string
69
+ showAdd?: boolean
70
+ showCommands?: boolean
71
+ showCommandTags?: boolean
72
+ showModel?: boolean
73
+ showSubmit?: boolean
74
+ submitLabel?: string
75
+ submitOnEnter?: boolean
76
+ textareaClass?: HTMLAttributes["class"]
77
+ textareaLabel?: string
78
+ toolbarClass?: HTMLAttributes["class"]
79
+ }
80
+
81
+ const props = withDefaults(defineProps<PromptInputProps>(), {
82
+ addActions: () => [
83
+ {
84
+ icon: PaperclipIcon,
85
+ key: "attachment",
86
+ label: "사진/파일 추가",
87
+ },
88
+ {
89
+ icon: PlugIcon,
90
+ key: "mcp",
91
+ label: "MCP",
92
+ },
93
+ ],
94
+ addLabel: "추가",
95
+ allowEmpty: false,
96
+ clearAttachmentsOnSubmit: true,
97
+ clearCommandPayloadOnSubmit: true,
98
+ commandEmptyText: "명령어가 없습니다.",
99
+ commandLabel: "명령어",
100
+ commandTagRemoveLabel: "{label} 명령어 취소",
101
+ commandTrigger: "/",
102
+ commands: () => [],
103
+ modelEmptyText: "검색 결과가 없습니다.",
104
+ modelLabel: "모델 선택",
105
+ modelModalThreshold: 8,
106
+ modelSearchPlaceholder: "모델 검색",
107
+ modelSelectorMode: "dialog",
108
+ modelValue: "",
109
+ models: () => [
110
+ {
111
+ icon: SparklesIcon,
112
+ label: "GPT-5",
113
+ value: "gpt-5",
114
+ },
115
+ {
116
+ icon: BrainCircuitIcon,
117
+ label: "GPT-5 mini",
118
+ value: "gpt-5-mini",
119
+ },
120
+ {
121
+ icon: BotIcon,
122
+ label: "Claude Sonnet",
123
+ value: "claude-sonnet",
124
+ },
125
+ {
126
+ icon: BotIcon,
127
+ label: "Claude Haiku",
128
+ value: "claude-haiku",
129
+ },
130
+ {
131
+ icon: SparklesIcon,
132
+ label: "Gemini Pro",
133
+ value: "gemini-pro",
134
+ },
135
+ {
136
+ icon: BrainCircuitIcon,
137
+ label: "Gemini Flash",
138
+ value: "gemini-flash",
139
+ },
140
+ {
141
+ icon: BotIcon,
142
+ label: "Llama 4",
143
+ value: "llama-4",
144
+ },
145
+ {
146
+ icon: SparklesIcon,
147
+ label: "Mistral Large",
148
+ value: "mistral-large",
149
+ },
150
+ {
151
+ icon: BrainCircuitIcon,
152
+ label: "DeepSeek Chat",
153
+ value: "deepseek-chat",
154
+ },
155
+ {
156
+ icon: BotIcon,
157
+ label: "Command R",
158
+ value: "command-r",
159
+ },
160
+ ],
161
+ multipleAttachments: true,
162
+ placeholder: "메시지를 입력하세요",
163
+ removeAttachmentLabel: "첨부 삭제",
164
+ maxRows: 4,
165
+ rows: 2,
166
+ showAdd: true,
167
+ showCommands: true,
168
+ showCommandTags: true,
169
+ showModel: true,
170
+ showSubmit: true,
171
+ submitLabel: "전송",
172
+ submitOnEnter: true,
173
+ textareaLabel: "프롬프트 입력",
174
+ })
175
+
176
+ const emit = defineEmits<{
177
+ "attachments-change": [attachments: PromptInputAttachment[]]
178
+ "command-payload-change": [commandPayload: PromptInputCommandData]
179
+ "remove-attachment": [attachment: PromptInputAttachment]
180
+ "update:attachments": [attachments: PromptInputAttachment[]]
181
+ "update:commandPayload": [commandPayload: PromptInputCommandData]
182
+ "update:model": [value: string]
183
+ "update:modelValue": [value: string]
184
+ add: [action: PromptInputAddAction]
185
+ "add:attachment": [action: PromptInputAddAction]
186
+ "add:mcp": [action: PromptInputAddAction]
187
+ command: [payload: PromptInputCommandPayload]
188
+ "remove-command": [payload: PromptInputCommandRemovePayload]
189
+ submit: [payload: PromptInputSubmitPayload]
190
+ upload: [attachments: PromptInputAttachment[]]
191
+ }>()
192
+
193
+ interface CommandRange {
194
+ end: number
195
+ query: string
196
+ start: number
197
+ }
198
+
199
+ interface ActiveCommandEntry {
200
+ command: PromptInputCommand
201
+ payload: PromptInputCommandData
202
+ }
203
+
204
+ const generatedId = useId()
205
+ const commandMenuElement = ref<HTMLElement | null>(null)
206
+ const commandRange = ref<CommandRange | null>(null)
207
+ const fileInputElement = ref<HTMLInputElement | null>(null)
208
+ const highlightedCommandIndex = ref(0)
209
+ const activeCommandEntries = ref<ActiveCommandEntry[]>([])
210
+ const internalAttachments = ref<PromptInputAttachment[]>([])
211
+ const internalCommandPayload = ref<PromptInputCommandData>({})
212
+ const textareaElement = ref<HTMLTextAreaElement | null>(null)
213
+ const textareaId = computed(() => props.id ?? generatedId)
214
+ const promptValue = computed(() => props.modelValue ?? "")
215
+ const resolvedAttachments = computed(() =>
216
+ props.attachments ?? internalAttachments.value,
217
+ )
218
+ const resolvedCommandPayload = computed(() =>
219
+ props.commandPayload ?? internalCommandPayload.value,
220
+ )
221
+ const selectedModelValue = computed({
222
+ get: () => props.model ?? props.models[0]?.value ?? "",
223
+ set: (value: string) => {
224
+ emit("update:model", value)
225
+ },
226
+ })
227
+ const selectedModel = computed(() =>
228
+ props.models.find((model) => model.value === selectedModelValue.value)
229
+ ?? props.models[0],
230
+ )
231
+ const filteredCommands = computed(() => {
232
+ const query = commandRange.value?.query.trim().toLocaleLowerCase() ?? ""
233
+
234
+ if (!query) return props.commands
235
+
236
+ return props.commands.filter((command) => {
237
+ const searchable = [
238
+ command.label,
239
+ command.value,
240
+ command.description,
241
+ ]
242
+ .filter(Boolean)
243
+ .join(" ")
244
+ .toLocaleLowerCase()
245
+
246
+ return searchable.includes(query)
247
+ })
248
+ })
249
+ const commandMenuVisible = computed(() =>
250
+ props.showCommands
251
+ && Boolean(commandRange.value)
252
+ && props.commands.length > 0,
253
+ )
254
+ const hasPromptMessage = computed(() => promptValue.value.trim().length > 0)
255
+ const canSubmit = computed(() =>
256
+ !props.disabled
257
+ && (props.allowEmpty || hasPromptMessage.value),
258
+ )
259
+ const submitButtonActive = computed(() =>
260
+ !props.disabled
261
+ && (props.allowEmpty || hasPromptMessage.value),
262
+ )
263
+ const minRows = computed(() => normalizeRowCount(props.rows, 2))
264
+ const maxRows = computed(() =>
265
+ Math.max(minRows.value, normalizeRowCount(props.maxRows, 4)),
266
+ )
267
+ const objectUrlSet = new Set<string>()
268
+
269
+ function normalizeRowCount(value: number | string | undefined, fallback: number) {
270
+ const parsed = Number(value)
271
+
272
+ if (!Number.isFinite(parsed) || parsed < 1) return fallback
273
+
274
+ return Math.floor(parsed)
275
+ }
276
+
277
+ function resizeTextarea() {
278
+ const textarea = textareaElement.value
279
+
280
+ if (!textarea || typeof window === "undefined") return
281
+
282
+ const style = window.getComputedStyle(textarea)
283
+ const lineHeight = Number.parseFloat(style.lineHeight) || 24
284
+ const padding =
285
+ (Number.parseFloat(style.paddingTop) || 0)
286
+ + (Number.parseFloat(style.paddingBottom) || 0)
287
+ const border =
288
+ (Number.parseFloat(style.borderTopWidth) || 0)
289
+ + (Number.parseFloat(style.borderBottomWidth) || 0)
290
+ const minHeight = (lineHeight * minRows.value) + padding + border
291
+ const maxHeight = (lineHeight * maxRows.value) + padding + border
292
+
293
+ textarea.style.height = `${minHeight}px`
294
+
295
+ const nextHeight = Math.min(
296
+ Math.max(textarea.scrollHeight, minHeight),
297
+ maxHeight,
298
+ )
299
+
300
+ textarea.style.height = `${nextHeight}px`
301
+ textarea.style.overflowY = textarea.scrollHeight > maxHeight ? "auto" : "hidden"
302
+ }
303
+
304
+ function handleInput(event: Event) {
305
+ const target = event.target as HTMLTextAreaElement
306
+
307
+ emit("update:modelValue", target.value)
308
+ updateCommandRange(target.value, target.selectionStart ?? target.value.length)
309
+ void nextTick(resizeTextarea)
310
+ }
311
+
312
+ function getCommandRange(value: string, cursor: number): CommandRange | null {
313
+ if (!props.showCommands || !props.commands.length) return null
314
+
315
+ const trigger = props.commandTrigger
316
+
317
+ if (!trigger) return null
318
+
319
+ const beforeCursor = value.slice(0, cursor)
320
+ const start = beforeCursor.lastIndexOf(trigger)
321
+
322
+ if (start === -1) return null
323
+
324
+ const previousCharacter = start > 0 ? value[start - 1] : ""
325
+
326
+ if (previousCharacter && !/\s/.test(previousCharacter)) return null
327
+
328
+ const query = value.slice(start + trigger.length, cursor)
329
+
330
+ if (/\s/.test(query)) return null
331
+
332
+ return {
333
+ end: cursor,
334
+ query,
335
+ start,
336
+ }
337
+ }
338
+
339
+ function updateCommandRange(value?: string, cursor?: number) {
340
+ const textarea = textareaElement.value
341
+ const nextValue = value ?? textarea?.value ?? promptValue.value
342
+ const nextCursor = cursor ?? textarea?.selectionStart ?? nextValue.length
343
+
344
+ commandRange.value = getCommandRange(nextValue, nextCursor)
345
+
346
+ if (!commandRange.value) {
347
+ highlightedCommandIndex.value = 0
348
+ return
349
+ }
350
+
351
+ highlightedCommandIndex.value = getFirstEnabledCommandIndex(filteredCommands.value)
352
+ }
353
+
354
+ function getFirstEnabledCommandIndex(commands = filteredCommands.value) {
355
+ const enabledIndex = commands.findIndex((command) => !command.disabled)
356
+
357
+ return enabledIndex === -1 ? 0 : enabledIndex
358
+ }
359
+
360
+ function moveHighlightedCommand(direction: 1 | -1) {
361
+ const commands = filteredCommands.value
362
+
363
+ if (!commands.length || commands.every((command) => command.disabled)) return
364
+
365
+ let nextIndex = highlightedCommandIndex.value
366
+
367
+ for (let offset = 0; offset < commands.length; offset += 1) {
368
+ nextIndex = (nextIndex + direction + commands.length) % commands.length
369
+
370
+ if (!commands[nextIndex]?.disabled) {
371
+ highlightedCommandIndex.value = nextIndex
372
+ scrollHighlightedCommandIntoView()
373
+ return
374
+ }
375
+ }
376
+ }
377
+
378
+ function scrollHighlightedCommandIntoView() {
379
+ void nextTick(() => {
380
+ commandMenuElement.value
381
+ ?.querySelector<HTMLElement>("[data-highlighted]")
382
+ ?.scrollIntoView({ block: "nearest" })
383
+ })
384
+ }
385
+
386
+ function closeCommandMenu() {
387
+ commandRange.value = null
388
+ highlightedCommandIndex.value = 0
389
+ }
390
+
391
+ function emitCommandPayload(nextCommandPayload: PromptInputCommandData) {
392
+ if (props.commandPayload === undefined) {
393
+ internalCommandPayload.value = nextCommandPayload
394
+ }
395
+
396
+ emit("update:commandPayload", nextCommandPayload)
397
+ emit("command-payload-change", nextCommandPayload)
398
+ }
399
+
400
+ function clearCommandPayload() {
401
+ activeCommandEntries.value = []
402
+ emitCommandPayload({})
403
+ }
404
+
405
+ function setActiveCommand(
406
+ command: PromptInputCommand,
407
+ commandPayloadPatch: PromptInputCommandData,
408
+ ) {
409
+ const patchKeys = new Set(Object.keys(commandPayloadPatch))
410
+ const nextEntry = {
411
+ command,
412
+ payload: { ...commandPayloadPatch },
413
+ }
414
+
415
+ activeCommandEntries.value = [
416
+ ...activeCommandEntries.value.filter((entry) => {
417
+ if (entry.command.value === command.value) return false
418
+ if (!patchKeys.size) return true
419
+
420
+ return !Object.keys(entry.payload).some((key) => patchKeys.has(key))
421
+ }),
422
+ nextEntry,
423
+ ]
424
+ }
425
+
426
+ function removeCommand(entry: ActiveCommandEntry) {
427
+ if (props.disabled) return
428
+
429
+ const commandPayload = { ...resolvedCommandPayload.value }
430
+ const nextCommandPayload = { ...commandPayload }
431
+
432
+ Object.keys(entry.payload).forEach((key) => {
433
+ delete nextCommandPayload[key]
434
+ })
435
+
436
+ activeCommandEntries.value = activeCommandEntries.value.filter(
437
+ (currentEntry) => currentEntry !== entry,
438
+ )
439
+
440
+ const payload: PromptInputCommandRemovePayload = {
441
+ command: entry.command,
442
+ commandPayload,
443
+ nextCommandPayload,
444
+ removedPayload: { ...entry.payload },
445
+ }
446
+
447
+ emitCommandPayload(nextCommandPayload)
448
+ emit("remove-command", payload)
449
+ entry.command.cancel?.(payload)
450
+ focusTextarea()
451
+ }
452
+
453
+ function resolveCommandPayloadPatch(
454
+ command: PromptInputCommand,
455
+ payload: PromptInputCommandPayload,
456
+ ) {
457
+ const commandPayloadPatch =
458
+ typeof command.payload === "function"
459
+ ? command.payload(payload)
460
+ : command.payload
461
+
462
+ return { ...(commandPayloadPatch ?? {}) }
463
+ }
464
+
465
+ function resolveCommandTagRemoveLabel(command: PromptInputCommand) {
466
+ return props.commandTagRemoveLabel.replace("{label}", command.label)
467
+ }
468
+
469
+ function selectCommand(command: PromptInputCommand) {
470
+ if (props.disabled || command.disabled || !commandRange.value) return
471
+
472
+ const textarea = textareaElement.value
473
+ const currentValue = textarea?.value ?? promptValue.value
474
+ const range = commandRange.value
475
+ const insertedValue = command.insert ?? ""
476
+ const nextValue =
477
+ currentValue.slice(0, range.start)
478
+ + insertedValue
479
+ + currentValue.slice(range.end)
480
+ const cursor = range.start + insertedValue.length
481
+ const commandPayload = { ...resolvedCommandPayload.value }
482
+ const basePayload: PromptInputCommandPayload = {
483
+ command,
484
+ commandPayload,
485
+ nextCommandPayload: commandPayload,
486
+ nextValue,
487
+ query: range.query,
488
+ trigger: props.commandTrigger,
489
+ value: currentValue,
490
+ }
491
+ const commandPayloadPatch = resolveCommandPayloadPatch(command, basePayload)
492
+ const nextCommandPayload = {
493
+ ...commandPayload,
494
+ ...commandPayloadPatch,
495
+ }
496
+ const payload: PromptInputCommandPayload = {
497
+ ...basePayload,
498
+ nextCommandPayload,
499
+ }
500
+
501
+ emit("update:modelValue", nextValue)
502
+ setActiveCommand(command, commandPayloadPatch)
503
+ emitCommandPayload(nextCommandPayload)
504
+ emit("command", payload)
505
+ command.action?.(payload)
506
+ closeCommandMenu()
507
+
508
+ void nextTick(() => {
509
+ focusTextarea()
510
+ textareaElement.value?.setSelectionRange(cursor, cursor)
511
+ resizeTextarea()
512
+ })
513
+ }
514
+
515
+ function selectHighlightedCommand() {
516
+ const command =
517
+ filteredCommands.value[highlightedCommandIndex.value]
518
+ ?? filteredCommands.value[getFirstEnabledCommandIndex()]
519
+
520
+ if (!command || command.disabled) return
521
+
522
+ selectCommand(command)
523
+ }
524
+
525
+ function emitAttachments(nextAttachments: PromptInputAttachment[]) {
526
+ if (props.attachments === undefined) {
527
+ internalAttachments.value = nextAttachments
528
+ }
529
+
530
+ emit("update:attachments", nextAttachments)
531
+ emit("attachments-change", nextAttachments)
532
+ }
533
+
534
+ function createAttachment(file: File): PromptInputAttachment {
535
+ const kind = file.type.startsWith("image/") ? "image" : "file"
536
+ const previewUrl = kind === "image" ? URL.createObjectURL(file) : undefined
537
+ const id =
538
+ globalThis.crypto?.randomUUID?.()
539
+ ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`
540
+
541
+ if (previewUrl) {
542
+ objectUrlSet.add(previewUrl)
543
+ }
544
+
545
+ return {
546
+ file,
547
+ id: `${file.name}-${file.size}-${file.lastModified}-${id}`,
548
+ kind,
549
+ name: file.name,
550
+ previewUrl,
551
+ size: file.size,
552
+ type: file.type,
553
+ }
554
+ }
555
+
556
+ function revokeAttachmentPreview(attachment: PromptInputAttachment) {
557
+ if (!attachment.previewUrl || !objectUrlSet.has(attachment.previewUrl)) return
558
+
559
+ URL.revokeObjectURL(attachment.previewUrl)
560
+ objectUrlSet.delete(attachment.previewUrl)
561
+ }
562
+
563
+ function clearAttachments() {
564
+ resolvedAttachments.value.forEach(revokeAttachmentPreview)
565
+ emitAttachments([])
566
+ }
567
+
568
+ function formatAttachmentSize(size: number) {
569
+ if (size < 1024) return `${size} B`
570
+ if (size < 1024 * 1024) return `${Math.round(size / 1024)} KB`
571
+
572
+ return `${(size / 1024 / 1024).toFixed(1)} MB`
573
+ }
574
+
575
+ function isImageAttachment(attachment: PromptInputAttachment) {
576
+ return attachment.kind === "image" && Boolean(attachment.previewUrl)
577
+ }
578
+
579
+ function handleFileInputChange(event: Event) {
580
+ if (props.disabled) return
581
+
582
+ const input = event.target as HTMLInputElement
583
+ const files = Array.from(input.files ?? [])
584
+
585
+ if (!files.length) return
586
+
587
+ const uploadedAttachments = files.map(createAttachment)
588
+
589
+ emitAttachments([
590
+ ...resolvedAttachments.value,
591
+ ...uploadedAttachments,
592
+ ])
593
+ emit("upload", uploadedAttachments)
594
+
595
+ input.value = ""
596
+ }
597
+
598
+ function removeAttachment(attachment: PromptInputAttachment) {
599
+ revokeAttachmentPreview(attachment)
600
+
601
+ emitAttachments(
602
+ resolvedAttachments.value.filter((item) => item.id !== attachment.id),
603
+ )
604
+ emit("remove-attachment", attachment)
605
+ }
606
+
607
+ function handleAdd(action: PromptInputAddAction) {
608
+ if (props.disabled) return
609
+
610
+ emit("add", action)
611
+
612
+ if (action.key === "attachment") {
613
+ emit("add:attachment", action)
614
+ fileInputElement.value?.click()
615
+ return
616
+ }
617
+
618
+ if (action.key === "mcp") {
619
+ emit("add:mcp", action)
620
+ }
621
+ }
622
+
623
+ function focusTextarea() {
624
+ if (typeof document === "undefined") return
625
+
626
+ document.getElementById(textareaId.value)?.focus()
627
+ }
628
+
629
+ function handleSurfaceClick(event: MouseEvent) {
630
+ if (props.disabled) return
631
+
632
+ event.preventDefault()
633
+ focusTextarea()
634
+ }
635
+
636
+ function handleTextareaPointer() {
637
+ void nextTick(() => updateCommandRange())
638
+ }
639
+
640
+ function handleTextareaKeyup(event: KeyboardEvent) {
641
+ if (
642
+ event.key === "ArrowDown"
643
+ || event.key === "ArrowUp"
644
+ || event.key === "Enter"
645
+ || event.key === "Tab"
646
+ || event.key === "Escape"
647
+ ) {
648
+ return
649
+ }
650
+
651
+ updateCommandRange()
652
+ }
653
+
654
+ function handleSubmit() {
655
+ if (!canSubmit.value) return
656
+
657
+ const attachments = [...resolvedAttachments.value]
658
+ const commandPayload = { ...resolvedCommandPayload.value }
659
+
660
+ emit("submit", {
661
+ attachments,
662
+ commandPayload,
663
+ model: selectedModelValue.value,
664
+ modelOption: selectedModel.value,
665
+ value: promptValue.value,
666
+ })
667
+
668
+ if (props.clearAttachmentsOnSubmit && attachments.length) {
669
+ clearAttachments()
670
+ }
671
+
672
+ if (
673
+ props.clearCommandPayloadOnSubmit
674
+ && Object.keys(commandPayload).length
675
+ ) {
676
+ clearCommandPayload()
677
+ }
678
+ }
679
+
680
+ function handleKeydown(event: KeyboardEvent) {
681
+ if (commandMenuVisible.value) {
682
+ if (event.key === "ArrowDown") {
683
+ event.preventDefault()
684
+ moveHighlightedCommand(1)
685
+ return
686
+ }
687
+
688
+ if (event.key === "ArrowUp") {
689
+ event.preventDefault()
690
+ moveHighlightedCommand(-1)
691
+ return
692
+ }
693
+
694
+ if (event.key === "Escape") {
695
+ event.preventDefault()
696
+ closeCommandMenu()
697
+ return
698
+ }
699
+
700
+ if (event.key === "Enter" || event.key === "Tab") {
701
+ event.preventDefault()
702
+ selectHighlightedCommand()
703
+ return
704
+ }
705
+ }
706
+
707
+ if (
708
+ !props.submitOnEnter
709
+ || event.isComposing
710
+ || event.key !== "Enter"
711
+ || event.shiftKey
712
+ || event.altKey
713
+ || event.ctrlKey
714
+ || event.metaKey
715
+ ) {
716
+ return
717
+ }
718
+
719
+ event.preventDefault()
720
+ handleSubmit()
721
+ }
722
+
723
+ onMounted(() => {
724
+ void nextTick(resizeTextarea)
725
+ })
726
+
727
+ onBeforeUnmount(() => {
728
+ resolvedAttachments.value.forEach(revokeAttachmentPreview)
729
+ })
730
+
731
+ watch(
732
+ [promptValue, minRows, maxRows],
733
+ () => {
734
+ void nextTick(resizeTextarea)
735
+ },
736
+ { flush: "post" },
737
+ )
738
+
739
+ watch(
740
+ filteredCommands,
741
+ (commands) => {
742
+ if (!commandMenuVisible.value) return
743
+
744
+ const currentCommand = commands[highlightedCommandIndex.value]
745
+
746
+ if (currentCommand && !currentCommand.disabled) return
747
+
748
+ highlightedCommandIndex.value = getFirstEnabledCommandIndex(commands)
749
+ },
750
+ )
751
+
752
+ watch(
753
+ () => props.attachments,
754
+ (nextAttachments = [], previousAttachments = []) => {
755
+ const nextPreviewUrls = new Set(
756
+ nextAttachments
757
+ .map((attachment) => attachment.previewUrl)
758
+ .filter(Boolean),
759
+ )
760
+
761
+ previousAttachments.forEach((attachment) => {
762
+ if (
763
+ attachment.previewUrl
764
+ && !nextPreviewUrls.has(attachment.previewUrl)
765
+ ) {
766
+ revokeAttachmentPreview(attachment)
767
+ }
768
+ })
769
+ },
770
+ )
771
+
772
+ watch(
773
+ resolvedCommandPayload,
774
+ (nextCommandPayload) => {
775
+ if (Object.keys(nextCommandPayload).length > 0) return
776
+
777
+ activeCommandEntries.value = []
778
+ },
779
+ { deep: true },
780
+ )
781
+ </script>
782
+
783
+ <template>
784
+ <form
785
+ data-slot="prompt-input"
786
+ :data-disabled="props.disabled ? '' : undefined"
787
+ :class="
788
+ cn(
789
+ 'border-input bg-background text-foreground relative flex w-full max-w-3xl flex-col overflow-visible rounded-lg border data-[disabled]:opacity-60',
790
+ props.class,
791
+ )
792
+ "
793
+ @submit.prevent="handleSubmit"
794
+ >
795
+ <input
796
+ ref="fileInputElement"
797
+ data-slot="prompt-input-file-input"
798
+ class="sr-only"
799
+ type="file"
800
+ :accept="props.attachmentAccept"
801
+ :multiple="props.multipleAttachments"
802
+ :disabled="props.disabled"
803
+ @change="handleFileInputChange"
804
+ >
805
+
806
+ <div
807
+ v-if="resolvedAttachments.length"
808
+ data-slot="prompt-input-attachments"
809
+ class="flex flex-nowrap gap-2 overflow-x-auto overflow-y-hidden px-3 pt-3 pb-1"
810
+ @click="focusTextarea"
811
+ >
812
+ <div
813
+ v-for="attachment in resolvedAttachments"
814
+ :key="attachment.id"
815
+ data-slot="prompt-input-attachment"
816
+ class="bg-muted/70 text-foreground flex w-56 max-w-[calc(100vw-3rem)] shrink-0 items-center gap-2 overflow-hidden rounded-md px-2 py-1.5 text-xs"
817
+ >
818
+ <img
819
+ v-if="isImageAttachment(attachment)"
820
+ data-slot="prompt-input-attachment-preview"
821
+ :src="attachment.previewUrl"
822
+ :alt="attachment.name"
823
+ class="size-8 shrink-0 rounded-sm object-cover"
824
+ >
825
+ <span
826
+ v-else
827
+ data-slot="prompt-input-attachment-icon"
828
+ class="bg-background text-muted-foreground flex size-8 shrink-0 items-center justify-center rounded-sm"
829
+ >
830
+ <FileIcon />
831
+ </span>
832
+ <span
833
+ data-slot="prompt-input-attachment-content"
834
+ class="grid min-w-0 flex-1"
835
+ >
836
+ <span
837
+ data-slot="prompt-input-attachment-name"
838
+ class="truncate font-medium"
839
+ :title="attachment.name"
840
+ >
841
+ {{ attachment.name }}
842
+ </span>
843
+ <span
844
+ data-slot="prompt-input-attachment-size"
845
+ class="text-muted-foreground"
846
+ >
847
+ {{ formatAttachmentSize(attachment.size) }}
848
+ </span>
849
+ </span>
850
+ <Button
851
+ type="button"
852
+ variant="ghost"
853
+ size="icon-sm"
854
+ class="-mr-1 size-7 rounded-sm"
855
+ :aria-label="props.removeAttachmentLabel"
856
+ :disabled="props.disabled"
857
+ @click.stop="removeAttachment(attachment)"
858
+ >
859
+ <XIcon />
860
+ </Button>
861
+ </div>
862
+ </div>
863
+
864
+ <textarea
865
+ ref="textareaElement"
866
+ :id="textareaId"
867
+ data-slot="prompt-input-textarea"
868
+ :class="
869
+ cn(
870
+ 'w-full resize-none border-0 bg-transparent px-4 py-3 text-sm leading-6 text-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed',
871
+ props.textareaClass,
872
+ )
873
+ "
874
+ :disabled="props.disabled"
875
+ :aria-label="props.textareaLabel"
876
+ :placeholder="props.placeholder"
877
+ :rows="minRows"
878
+ :value="promptValue"
879
+ @click="handleTextareaPointer"
880
+ @focus="handleTextareaPointer"
881
+ @input="handleInput"
882
+ @keydown="handleKeydown"
883
+ @keyup="handleTextareaKeyup"
884
+ @select="handleTextareaPointer"
885
+ />
886
+
887
+ <div
888
+ v-if="commandMenuVisible"
889
+ ref="commandMenuElement"
890
+ data-slot="prompt-input-command-menu"
891
+ role="listbox"
892
+ :aria-label="props.commandLabel"
893
+ :class="
894
+ cn(
895
+ 'absolute bottom-[calc(100%+0.5rem)] left-0 z-[999] flex max-h-56 w-full flex-col overflow-y-auto rounded-[12px] border border-border bg-popover/90 p-1 text-popover-foreground shadow-lg backdrop-blur-[15px] [-webkit-backdrop-filter:blur(15px)] [&_[data-slot=prompt-input-command-icon]]:size-3.5',
896
+ props.commandMenuClass,
897
+ )
898
+ "
899
+ @mousedown.stop
900
+ >
901
+ <button
902
+ v-for="(command, commandIndex) in filteredCommands"
903
+ :key="command.value"
904
+ type="button"
905
+ data-slot="prompt-input-command-item"
906
+ :data-highlighted="commandIndex === highlightedCommandIndex ? '' : undefined"
907
+ :disabled="command.disabled"
908
+ role="option"
909
+ :aria-selected="commandIndex === highlightedCommandIndex"
910
+ :class="
911
+ cn(
912
+ 'flex w-full min-w-0 items-center gap-1.5 rounded-[8px] px-2 py-1.5 text-left text-xs outline-none transition-[background-color,color] hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground',
913
+ )
914
+ "
915
+ @click="selectCommand(command)"
916
+ @mouseenter="highlightedCommandIndex = commandIndex"
917
+ @mousedown.prevent
918
+ >
919
+ <component
920
+ :is="command.icon"
921
+ v-if="command.icon"
922
+ data-slot="prompt-input-command-icon"
923
+ />
924
+ <span
925
+ data-slot="prompt-input-command-content"
926
+ class="grid min-w-0 flex-1 grid-flow-col grid-cols-[minmax(0,max-content)_minmax(0,1fr)] items-baseline gap-1.5"
927
+ >
928
+ <span
929
+ data-slot="prompt-input-command-label"
930
+ class="min-w-0 truncate font-medium"
931
+ >
932
+ {{ command.label }}
933
+ </span>
934
+ <span
935
+ v-if="command.description"
936
+ data-slot="prompt-input-command-description"
937
+ class="min-w-0 truncate text-[11px] leading-4 text-muted-foreground max-[520px]:hidden"
938
+ >
939
+ {{ command.description }}
940
+ </span>
941
+ </span>
942
+ <span
943
+ data-slot="prompt-input-command-value"
944
+ class="shrink-0 text-[11px] leading-4 text-muted-foreground"
945
+ >
946
+ {{ props.commandTrigger }}{{ command.value }}
947
+ </span>
948
+ </button>
949
+
950
+ <div
951
+ v-if="!filteredCommands.length"
952
+ data-slot="prompt-input-command-empty"
953
+ class="px-2 py-2.5 text-xs text-muted-foreground"
954
+ >
955
+ {{ props.commandEmptyText }}
956
+ </div>
957
+ </div>
958
+
959
+ <div
960
+ data-slot="prompt-input-toolbar"
961
+ :class="
962
+ cn(
963
+ 'relative flex min-h-12 items-center justify-between gap-3 px-2 py-2',
964
+ props.toolbarClass,
965
+ )
966
+ "
967
+ >
968
+ <label
969
+ data-slot="prompt-input-surface"
970
+ :for="textareaId"
971
+ class="absolute inset-0 z-10 cursor-text"
972
+ aria-hidden="true"
973
+ @click="handleSurfaceClick"
974
+ />
975
+
976
+ <div
977
+ data-slot="prompt-input-tools"
978
+ class="pointer-events-none relative z-20 flex min-w-0 flex-1 flex-wrap items-center gap-1 [&_*]:pointer-events-auto"
979
+ >
980
+ <DropdownMenu v-if="props.showAdd && props.addActions.length">
981
+ <DropdownMenuTrigger as-child>
982
+ <Button
983
+ type="button"
984
+ variant="ghost"
985
+ size="icon-sm"
986
+ :aria-label="props.addLabel"
987
+ :disabled="props.disabled"
988
+ >
989
+ <PlusIcon />
990
+ </Button>
991
+ </DropdownMenuTrigger>
992
+ <DropdownMenuContent align="start" class="w-40">
993
+ <DropdownMenuItem
994
+ v-for="action in props.addActions"
995
+ :key="action.key"
996
+ :disabled="action.disabled"
997
+ @select="handleAdd(action)"
998
+ >
999
+ <component
1000
+ :is="action.icon"
1001
+ v-if="action.icon"
1002
+ data-slot="prompt-input-add-action-icon"
1003
+ />
1004
+ {{ action.label }}
1005
+ </DropdownMenuItem>
1006
+ </DropdownMenuContent>
1007
+ </DropdownMenu>
1008
+
1009
+ <div
1010
+ v-if="props.showCommandTags && activeCommandEntries.length"
1011
+ data-slot="prompt-input-command-tags"
1012
+ class="flex min-w-0 flex-wrap items-center gap-1"
1013
+ >
1014
+ <Tag
1015
+ v-for="entry in activeCommandEntries"
1016
+ :key="entry.command.value"
1017
+ :icon="entry.command.icon"
1018
+ :remove-label="resolveCommandTagRemoveLabel(entry.command)"
1019
+ :title="entry.command.label"
1020
+ class="max-w-36"
1021
+ removable
1022
+ size="sm"
1023
+ variant="secondary"
1024
+ @remove="removeCommand(entry)"
1025
+ >
1026
+ {{ props.commandTrigger }}{{ entry.command.value }}
1027
+ </Tag>
1028
+ </div>
1029
+
1030
+ <ModelSelector
1031
+ v-if="props.showModel && props.models.length"
1032
+ v-model="selectedModelValue"
1033
+ :disabled="props.disabled"
1034
+ :content-class="cn('w-72', props.modelMenuClass)"
1035
+ :dialog-class="props.modelDialogClass"
1036
+ :empty-text="props.modelEmptyText"
1037
+ :label="props.modelLabel"
1038
+ :modal-threshold="props.modelModalThreshold"
1039
+ :modal-title="props.modelLabel"
1040
+ :mode="props.modelSelectorMode"
1041
+ :models="props.models"
1042
+ :placeholder="props.modelLabel"
1043
+ :search-placeholder="props.modelSearchPlaceholder"
1044
+ class="min-w-0"
1045
+ size="sm"
1046
+ trigger-class="h-8 min-w-0 max-w-52 border-transparent bg-transparent px-2 shadow-none transition-[background-color,color] hover:bg-accent hover:text-accent-foreground focus-visible:border-transparent focus-visible:bg-accent focus-visible:ring-0 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground"
1047
+ />
1048
+
1049
+ <slot
1050
+ name="tools"
1051
+ :attachments="resolvedAttachments"
1052
+ :command-payload="resolvedCommandPayload"
1053
+ :disabled="props.disabled"
1054
+ :model="selectedModelValue"
1055
+ :model-option="selectedModel"
1056
+ :value="promptValue"
1057
+ />
1058
+ </div>
1059
+
1060
+ <div
1061
+ data-slot="prompt-input-actions"
1062
+ class="pointer-events-none relative z-20 flex shrink-0 items-center gap-1 [&_*]:pointer-events-auto"
1063
+ >
1064
+ <slot
1065
+ name="actions"
1066
+ :attachments="resolvedAttachments"
1067
+ :command-payload="resolvedCommandPayload"
1068
+ :disabled="props.disabled"
1069
+ :model="selectedModelValue"
1070
+ :model-option="selectedModel"
1071
+ :submit="handleSubmit"
1072
+ :value="promptValue"
1073
+ />
1074
+
1075
+ <Button
1076
+ v-if="props.showSubmit"
1077
+ type="submit"
1078
+ :variant="submitButtonActive ? 'default' : 'secondary'"
1079
+ size="icon-sm"
1080
+ :class="
1081
+ cn(
1082
+ 'transition-[background-color,color,opacity]',
1083
+ !submitButtonActive && 'bg-muted text-muted-foreground hover:bg-muted',
1084
+ )
1085
+ "
1086
+ :aria-label="props.submitLabel"
1087
+ :disabled="!canSubmit"
1088
+ >
1089
+ <SendIcon />
1090
+ </Button>
1091
+ </div>
1092
+ </div>
1093
+ </form>
1094
+ </template>