@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,1042 @@
1
+ <script setup lang="ts">
2
+ import { computed } from "vue"
3
+ import type { CSSProperties, HTMLAttributes } from "vue"
4
+ import { cn } from "@/lib/utils"
5
+
6
+ export type ChartType = "bar" | "line"
7
+ export type ChartSize = "sm" | "default" | "lg"
8
+ export type ChartValue = number | string | null | undefined
9
+ export type ChartLineCurve = "linear" | "smooth"
10
+ export type ChartLegendPosition = "bottom" | "top"
11
+
12
+ export interface ChartDataPoint extends Record<string, unknown> {
13
+ id?: number | string
14
+ label?: number | string
15
+ value?: ChartValue
16
+ values?: Record<string, ChartValue>
17
+ }
18
+
19
+ export interface ChartSeries {
20
+ areaOpacity?: number
21
+ color?: string
22
+ curve?: ChartLineCurve
23
+ key: string
24
+ label?: string
25
+ showArea?: boolean
26
+ showPoints?: boolean
27
+ type?: ChartType
28
+ }
29
+
30
+ export interface ChartValueFormatterContext {
31
+ data: ChartDataPoint
32
+ index: number
33
+ key: string
34
+ label: string
35
+ series: ChartSeries
36
+ }
37
+
38
+ export type ChartValueFormatter = (
39
+ value: number,
40
+ context?: ChartValueFormatterContext,
41
+ ) => number | string
42
+
43
+ export interface ChartSelectPayload extends ChartValueFormatterContext {
44
+ value: number
45
+ }
46
+
47
+ interface ChartProps {
48
+ areaOpacity?: number
49
+ class?: HTMLAttributes["class"]
50
+ data?: ChartDataPoint[]
51
+ description?: string
52
+ emptyLabel?: string
53
+ gridLineCount?: number
54
+ height?: number
55
+ includeZero?: boolean
56
+ legendLabel?: string
57
+ legendPosition?: ChartLegendPosition
58
+ lineCurve?: ChartLineCurve
59
+ maxXLabels?: number
60
+ modelValue?: string
61
+ selectable?: boolean
62
+ series?: ChartSeries[]
63
+ showArea?: boolean
64
+ showGrid?: boolean
65
+ showLegend?: boolean
66
+ showPoints?: boolean
67
+ showXAxis?: boolean
68
+ showYAxis?: boolean
69
+ size?: ChartSize
70
+ summary?: string
71
+ title?: string
72
+ type?: ChartType
73
+ valueFormatter?: ChartValueFormatter
74
+ xKey?: string
75
+ yMax?: number
76
+ yMin?: number
77
+ }
78
+
79
+ interface NormalizedChartPoint {
80
+ data: ChartDataPoint
81
+ id: string
82
+ index: number
83
+ label: string
84
+ }
85
+
86
+ interface NormalizedChartSeries extends ChartSeries {
87
+ areaOpacity: number
88
+ color: string
89
+ curve: ChartLineCurve
90
+ label: string
91
+ showArea: boolean
92
+ showPoints: boolean
93
+ type: ChartType
94
+ }
95
+
96
+ interface ChartSeriesValue {
97
+ data: ChartDataPoint
98
+ id: string
99
+ index: number
100
+ key: string
101
+ label: string
102
+ series: NormalizedChartSeries
103
+ value: number | null
104
+ }
105
+
106
+ interface ChartNode extends ChartSelectPayload {
107
+ color: string
108
+ id: string
109
+ x: number
110
+ y: number
111
+ }
112
+
113
+ interface BarNode extends ChartNode {
114
+ height: number
115
+ width: number
116
+ }
117
+
118
+ interface LinePath {
119
+ color: string
120
+ d: string
121
+ key: string
122
+ label: string
123
+ }
124
+
125
+ interface LineAreaPath extends LinePath {
126
+ opacity: number
127
+ }
128
+
129
+ const props = withDefaults(defineProps<ChartProps>(), {
130
+ areaOpacity: 0.16,
131
+ data: () => [],
132
+ emptyLabel: "No chart data.",
133
+ gridLineCount: undefined,
134
+ includeZero: true,
135
+ legendLabel: "Chart series",
136
+ legendPosition: "bottom",
137
+ lineCurve: "linear",
138
+ maxXLabels: undefined,
139
+ selectable: true,
140
+ showArea: false,
141
+ showGrid: true,
142
+ showLegend: true,
143
+ showPoints: true,
144
+ showXAxis: true,
145
+ showYAxis: true,
146
+ size: "default",
147
+ type: "bar",
148
+ xKey: "label",
149
+ })
150
+
151
+ const emit = defineEmits<{
152
+ "select": [payload: ChartSelectPayload]
153
+ "update:modelValue": [value: string]
154
+ }>()
155
+
156
+ const chartWidth = 720
157
+ const defaultColors = [
158
+ "oklch(0.58 0.19 248)",
159
+ "oklch(0.6 0.16 153)",
160
+ "oklch(0.67 0.18 69)",
161
+ "oklch(0.59 0.21 338)",
162
+ "oklch(0.62 0.18 204)",
163
+ "oklch(0.58 0.2 27)",
164
+ ]
165
+
166
+ const numberFormatter = computed(() =>
167
+ new Intl.NumberFormat(undefined, {
168
+ maximumFractionDigits: 2,
169
+ }),
170
+ )
171
+
172
+ const sizeClasses = computed(() => {
173
+ if (props.size === "sm") {
174
+ return {
175
+ axis: "text-[10px]",
176
+ body: "p-3",
177
+ content: "text-xs",
178
+ description: "text-xs",
179
+ header: "gap-2 px-3 py-2.5",
180
+ height: 190,
181
+ legend: "gap-2 text-[11px]",
182
+ lineWidth: 2,
183
+ pointRadius: 3,
184
+ tickCount: 4,
185
+ title: "text-xs",
186
+ xLabels: 6,
187
+ }
188
+ }
189
+
190
+ if (props.size === "lg") {
191
+ return {
192
+ axis: "text-xs",
193
+ body: "p-5",
194
+ content: "text-sm",
195
+ description: "text-sm",
196
+ header: "gap-3 px-5 py-4",
197
+ height: 340,
198
+ legend: "gap-3 text-xs",
199
+ lineWidth: 3,
200
+ pointRadius: 4.5,
201
+ tickCount: 6,
202
+ title: "text-sm",
203
+ xLabels: 10,
204
+ }
205
+ }
206
+
207
+ return {
208
+ axis: "text-[11px]",
209
+ body: "p-4",
210
+ content: "text-[13px]",
211
+ description: "text-sm",
212
+ header: "gap-2.5 px-4 py-3",
213
+ height: 260,
214
+ legend: "gap-2.5 text-xs",
215
+ lineWidth: 2.5,
216
+ pointRadius: 3.75,
217
+ tickCount: 5,
218
+ title: "text-[13px]",
219
+ xLabels: 8,
220
+ }
221
+ })
222
+
223
+ const chartHeight = computed(() =>
224
+ Math.max(160, Math.trunc(props.height ?? sizeClasses.value.height)),
225
+ )
226
+
227
+ const geometry = computed(() => {
228
+ const bottom = props.showXAxis ? 40 : 16
229
+ const left = props.showYAxis ? yAxisWidth.value : 16
230
+ const right = 18
231
+ const top = 16
232
+
233
+ return {
234
+ bottom,
235
+ left,
236
+ plotHeight: Math.max(1, chartHeight.value - top - bottom),
237
+ plotWidth: Math.max(1, chartWidth - left - right),
238
+ right,
239
+ top,
240
+ }
241
+ })
242
+
243
+ const normalizedSeries = computed<NormalizedChartSeries[]>(() => {
244
+ const source = props.series?.length
245
+ ? props.series
246
+ : [{ key: "value", label: "Value" }]
247
+
248
+ return source
249
+ .filter((series) => series.key.trim().length > 0)
250
+ .map((series, index) => ({
251
+ ...series,
252
+ areaOpacity: clampOpacity(series.areaOpacity ?? props.areaOpacity),
253
+ color: series.color ?? defaultColors[index % defaultColors.length] ?? defaultColors[0],
254
+ curve: series.curve ?? props.lineCurve,
255
+ label: series.label ?? formatSeriesLabel(series.key),
256
+ showArea: series.showArea ?? props.showArea,
257
+ showPoints: series.showPoints ?? props.showPoints,
258
+ type: series.type ?? props.type,
259
+ }))
260
+ })
261
+
262
+ const normalizedData = computed<NormalizedChartPoint[]>(() =>
263
+ props.data.map((data, index) => {
264
+ const rawLabel = getDataValue(data, props.xKey)
265
+ const label = rawLabel === undefined || rawLabel === null || rawLabel === ""
266
+ ? `Item ${index + 1}`
267
+ : String(rawLabel)
268
+ const id = data.id === undefined || data.id === null
269
+ ? `${index}-${label}`
270
+ : String(data.id)
271
+
272
+ return {
273
+ data,
274
+ id,
275
+ index,
276
+ label,
277
+ }
278
+ }),
279
+ )
280
+
281
+ const seriesValues = computed(() =>
282
+ normalizedSeries.value.map((series) => ({
283
+ series,
284
+ values: normalizedData.value.map((point): ChartSeriesValue => ({
285
+ data: point.data,
286
+ id: `${point.id}:${series.key}`,
287
+ index: point.index,
288
+ key: series.key,
289
+ label: point.label,
290
+ series,
291
+ value: getSeriesValue(point.data, series.key),
292
+ })),
293
+ })),
294
+ )
295
+
296
+ const numericValues = computed(() =>
297
+ seriesValues.value.flatMap((group) =>
298
+ group.values
299
+ .map((point) => point.value)
300
+ .filter((value): value is number => value !== null),
301
+ ),
302
+ )
303
+
304
+ const rawDomain = computed(() => {
305
+ const values = numericValues.value
306
+
307
+ if (!values.length) {
308
+ return {
309
+ max: 1,
310
+ min: 0,
311
+ }
312
+ }
313
+
314
+ let min = props.yMin ?? Math.min(...values)
315
+ let max = props.yMax ?? Math.max(...values)
316
+
317
+ if (props.includeZero) {
318
+ min = Math.min(min, 0)
319
+ max = Math.max(max, 0)
320
+ }
321
+
322
+ if (min > max) {
323
+ const nextMin = max
324
+ max = min
325
+ min = nextMin
326
+ }
327
+
328
+ if (min === max) {
329
+ const delta = min === 0 ? 1 : Math.abs(min * 0.1)
330
+ min -= delta
331
+ max += delta
332
+ }
333
+
334
+ return {
335
+ max,
336
+ min,
337
+ }
338
+ })
339
+
340
+ const yTicks = computed(() =>
341
+ getNiceTicks(rawDomain.value.min, rawDomain.value.max, props.gridLineCount ?? sizeClasses.value.tickCount),
342
+ )
343
+
344
+ const yAxisWidth = computed(() => {
345
+ const longestLabel = yTicks.value.reduce((maxLength, value) =>
346
+ Math.max(maxLength, formatValue(value).length), 0)
347
+
348
+ return Math.min(132, Math.max(58, (longestLabel * 7) + 16))
349
+ })
350
+
351
+ const yDomain = computed(() => {
352
+ const ticks = yTicks.value
353
+
354
+ if (ticks.length >= 2) {
355
+ return {
356
+ max: ticks[ticks.length - 1] ?? rawDomain.value.max,
357
+ min: ticks[0] ?? rawDomain.value.min,
358
+ }
359
+ }
360
+
361
+ return rawDomain.value
362
+ })
363
+
364
+ const gridTicks = computed(() =>
365
+ yTicks.value.map((value) => ({
366
+ label: formatValue(value),
367
+ value,
368
+ y: yScale(value),
369
+ })),
370
+ )
371
+
372
+ const xLabels = computed(() => {
373
+ const points = normalizedData.value
374
+ const maxLabels = props.maxXLabels ?? sizeClasses.value.xLabels
375
+ const visibleIndexes = getVisibleLabelIndexes(points.length, maxLabels)
376
+
377
+ return points
378
+ .filter((_, index) => visibleIndexes.has(index))
379
+ .map((point) => ({
380
+ ...point,
381
+ x: categoryCenterX(point.index),
382
+ }))
383
+ })
384
+
385
+ const barSeriesGroups = computed(() =>
386
+ seriesValues.value.filter((group) => group.series.type === "bar"),
387
+ )
388
+
389
+ const lineSeriesGroups = computed(() =>
390
+ seriesValues.value.filter((group) => group.series.type === "line"),
391
+ )
392
+
393
+ const barNodes = computed<BarNode[]>(() => {
394
+ const groupCount = Math.max(1, barSeriesGroups.value.length)
395
+ const categoryStep = getCategoryStep()
396
+ const categoryPadding = Math.min(32, Math.max(10, categoryStep * 0.18))
397
+ const gap = groupCount > 1 ? Math.min(8, Math.max(3, categoryStep * 0.04)) : 0
398
+ const availableWidth = Math.max(2, categoryStep - (categoryPadding * 2) - (gap * (groupCount - 1)))
399
+ const width = Math.max(2, availableWidth / groupCount)
400
+ const baseline = yScale(0)
401
+ const nodes: BarNode[] = []
402
+
403
+ for (const [seriesIndex, group] of barSeriesGroups.value.entries()) {
404
+ for (const point of group.values) {
405
+ if (point.value === null) continue
406
+
407
+ const valueY = yScale(point.value)
408
+ const x = geometry.value.left +
409
+ (point.index * categoryStep) +
410
+ categoryPadding +
411
+ (seriesIndex * (width + gap))
412
+ const height = Math.max(1, Math.abs(baseline - valueY))
413
+ const y = point.value >= 0 ? valueY : baseline
414
+
415
+ nodes.push({
416
+ color: point.series.color,
417
+ data: point.data,
418
+ height,
419
+ id: point.id,
420
+ index: point.index,
421
+ key: point.key,
422
+ label: point.label,
423
+ series: point.series,
424
+ value: point.value,
425
+ width,
426
+ x,
427
+ y,
428
+ })
429
+ }
430
+ }
431
+
432
+ return nodes
433
+ })
434
+
435
+ const lineNodesBySeries = computed(() =>
436
+ lineSeriesGroups.value.map((group) => ({
437
+ series: group.series,
438
+ nodes: group.values
439
+ .filter((point): point is ChartSeriesValue & { value: number } => point.value !== null)
440
+ .map((point): ChartNode => ({
441
+ color: point.series.color,
442
+ data: point.data,
443
+ id: point.id,
444
+ index: point.index,
445
+ key: point.key,
446
+ label: point.label,
447
+ series: point.series,
448
+ value: point.value,
449
+ x: categoryCenterX(point.index),
450
+ y: yScale(point.value),
451
+ })),
452
+ })),
453
+ )
454
+
455
+ const linePaths = computed<LinePath[]>(() =>
456
+ lineNodesBySeries.value
457
+ .map((group) => ({
458
+ color: group.series.color,
459
+ d: buildLinePath(group.nodes, group.series.curve),
460
+ key: group.series.key,
461
+ label: group.series.label,
462
+ }))
463
+ .filter((path) => path.d.length > 0),
464
+ )
465
+
466
+ const lineAreaPaths = computed<LineAreaPath[]>(() =>
467
+ lineNodesBySeries.value
468
+ .filter((group) => group.series.showArea)
469
+ .map((group) => ({
470
+ color: group.series.color,
471
+ d: buildLineAreaPath(group.nodes, group.series.curve),
472
+ key: group.series.key,
473
+ label: group.series.label,
474
+ opacity: group.series.areaOpacity,
475
+ }))
476
+ .filter((path) => path.d.length > 0),
477
+ )
478
+
479
+ const lineNodes = computed(() =>
480
+ lineNodesBySeries.value.flatMap((group) => group.nodes),
481
+ )
482
+
483
+ const visibleLineNodes = computed(() =>
484
+ lineNodesBySeries.value.flatMap((group) =>
485
+ group.series.showPoints ? group.nodes : [],
486
+ ),
487
+ )
488
+
489
+ const lineHitNodes = computed(() =>
490
+ lineNodesBySeries.value.flatMap((group) =>
491
+ props.selectable && !group.series.showPoints ? group.nodes : [],
492
+ ),
493
+ )
494
+
495
+ const hasRenderableData = computed(() =>
496
+ barNodes.value.length > 0 || lineNodes.value.length > 0,
497
+ )
498
+
499
+ const hasHeader = computed(() =>
500
+ Boolean(props.title || props.description || props.summary),
501
+ )
502
+
503
+ const baselineY = computed(() => yScale(0))
504
+
505
+ function getDataValue(data: ChartDataPoint, key: string) {
506
+ return (data as Record<string, unknown>)[key]
507
+ }
508
+
509
+ function getSeriesValue(data: ChartDataPoint, key: string) {
510
+ const nested = data.values
511
+ const rawValue = nested && Object.prototype.hasOwnProperty.call(nested, key)
512
+ ? nested[key]
513
+ : getDataValue(data, key)
514
+
515
+ return toFiniteNumber(rawValue)
516
+ }
517
+
518
+ function toFiniteNumber(value: unknown) {
519
+ if (typeof value === "number") {
520
+ return Number.isFinite(value) ? value : null
521
+ }
522
+
523
+ if (typeof value === "string" && value.trim().length > 0) {
524
+ const parsed = Number(value)
525
+
526
+ return Number.isFinite(parsed) ? parsed : null
527
+ }
528
+
529
+ return null
530
+ }
531
+
532
+ function yScale(value: number) {
533
+ const domain = yDomain.value
534
+ const span = domain.max - domain.min || 1
535
+
536
+ return geometry.value.top + ((domain.max - value) / span) * geometry.value.plotHeight
537
+ }
538
+
539
+ function getCategoryStep() {
540
+ const count = Math.max(1, normalizedData.value.length)
541
+
542
+ return geometry.value.plotWidth / count
543
+ }
544
+
545
+ function categoryCenterX(index: number) {
546
+ return geometry.value.left + (getCategoryStep() * index) + (getCategoryStep() / 2)
547
+ }
548
+
549
+ function buildLinePath(nodes: ChartNode[], curve: ChartLineCurve) {
550
+ if (curve === "smooth") return buildSmoothLinePath(nodes)
551
+
552
+ return buildLinearLinePath(nodes)
553
+ }
554
+
555
+ function buildLineAreaPath(nodes: ChartNode[], curve: ChartLineCurve) {
556
+ if (nodes.length < 2) return ""
557
+
558
+ const linePath = buildLinePath(nodes, curve)
559
+ const first = nodes[0]
560
+ const last = nodes[nodes.length - 1]
561
+ const bottomY = geometry.value.top + geometry.value.plotHeight
562
+
563
+ if (!first || !last || !linePath) return ""
564
+
565
+ return [
566
+ linePath,
567
+ "L",
568
+ roundCoordinate(last.x),
569
+ roundCoordinate(bottomY),
570
+ "L",
571
+ roundCoordinate(first.x),
572
+ roundCoordinate(bottomY),
573
+ "Z",
574
+ ].join(" ")
575
+ }
576
+
577
+ function buildLinearLinePath(nodes: ChartNode[]) {
578
+ return nodes
579
+ .map((node, index) => `${index === 0 ? "M" : "L"} ${roundCoordinate(node.x)} ${roundCoordinate(node.y)}`)
580
+ .join(" ")
581
+ }
582
+
583
+ function buildSmoothLinePath(nodes: ChartNode[]) {
584
+ if (nodes.length < 3) return buildLinearLinePath(nodes)
585
+
586
+ const commands = [`M ${roundCoordinate(nodes[0].x)} ${roundCoordinate(nodes[0].y)}`]
587
+
588
+ for (let index = 0; index < nodes.length - 1; index += 1) {
589
+ const previous = nodes[index - 1] ?? nodes[index]
590
+ const current = nodes[index]
591
+ const next = nodes[index + 1]
592
+ const following = nodes[index + 2] ?? next
593
+
594
+ if (!previous || !current || !next || !following) continue
595
+
596
+ const controlPoint1X = current.x + ((next.x - previous.x) / 6)
597
+ const controlPoint1Y = current.y + ((next.y - previous.y) / 6)
598
+ const controlPoint2X = next.x - ((following.x - current.x) / 6)
599
+ const controlPoint2Y = next.y - ((following.y - current.y) / 6)
600
+
601
+ commands.push([
602
+ "C",
603
+ roundCoordinate(controlPoint1X),
604
+ roundCoordinate(controlPoint1Y),
605
+ roundCoordinate(controlPoint2X),
606
+ roundCoordinate(controlPoint2Y),
607
+ roundCoordinate(next.x),
608
+ roundCoordinate(next.y),
609
+ ].join(" "))
610
+ }
611
+
612
+ return commands.join(" ")
613
+ }
614
+
615
+ function getVisibleLabelIndexes(length: number, maxLabels: number) {
616
+ const count = Math.max(0, length)
617
+ const limit = Math.max(1, Math.trunc(maxLabels))
618
+ const indexes = new Set<number>()
619
+
620
+ if (count === 0) return indexes
621
+
622
+ if (count <= limit) {
623
+ for (let index = 0; index < count; index += 1) {
624
+ indexes.add(index)
625
+ }
626
+
627
+ return indexes
628
+ }
629
+
630
+ const slots = Math.max(1, limit - 1)
631
+
632
+ for (let index = 0; index < limit; index += 1) {
633
+ indexes.add(Math.round((index / slots) * (count - 1)))
634
+ }
635
+
636
+ indexes.add(count - 1)
637
+
638
+ return indexes
639
+ }
640
+
641
+ function formatSeriesLabel(key: string) {
642
+ return key
643
+ .replace(/[-_]/g, " ")
644
+ .replace(/\b\w/g, (letter) => letter.toUpperCase())
645
+ }
646
+
647
+ function formatValue(value: number, context?: ChartValueFormatterContext) {
648
+ const formatted = props.valueFormatter?.(value, context)
649
+
650
+ if (formatted !== undefined) return String(formatted)
651
+
652
+ return numberFormatter.value.format(value)
653
+ }
654
+
655
+ function formatNodeLabel(node: ChartNode) {
656
+ return `${node.label}, ${node.series.label}: ${formatValue(node.value, node)}`
657
+ }
658
+
659
+ function getNiceTicks(min: number, max: number, count: number) {
660
+ const tickCount = Math.max(2, Math.min(8, Math.trunc(count)))
661
+ const span = max - min
662
+
663
+ if (span <= 0 || !Number.isFinite(span)) return [min, max]
664
+
665
+ const step = niceNumber(span / (tickCount - 1), true)
666
+ const niceMin = Math.floor(min / step) * step
667
+ const niceMax = Math.ceil(max / step) * step
668
+ const precision = decimalPrecision(step)
669
+ const ticks: number[] = []
670
+
671
+ for (let value = niceMin; value <= niceMax + (step / 2); value += step) {
672
+ ticks.push(roundTo(value, precision))
673
+ }
674
+
675
+ return ticks
676
+ }
677
+
678
+ function niceNumber(value: number, round: boolean) {
679
+ const exponent = Math.floor(Math.log10(value))
680
+ const fraction = value / (10 ** exponent)
681
+ let niceFraction: number
682
+
683
+ if (round) {
684
+ if (fraction < 1.5) niceFraction = 1
685
+ else if (fraction < 3) niceFraction = 2
686
+ else if (fraction < 7) niceFraction = 5
687
+ else niceFraction = 10
688
+ } else if (fraction <= 1) niceFraction = 1
689
+ else if (fraction <= 2) niceFraction = 2
690
+ else if (fraction <= 5) niceFraction = 5
691
+ else niceFraction = 10
692
+
693
+ return niceFraction * (10 ** exponent)
694
+ }
695
+
696
+ function decimalPrecision(value: number) {
697
+ if (!Number.isFinite(value)) return 0
698
+
699
+ const exponent = Math.floor(Math.log10(Math.abs(value)))
700
+
701
+ return Math.max(0, -exponent + 1)
702
+ }
703
+
704
+ function roundTo(value: number, precision: number) {
705
+ const multiplier = 10 ** precision
706
+
707
+ return Math.round(value * multiplier) / multiplier
708
+ }
709
+
710
+ function roundCoordinate(value: number) {
711
+ return Math.round(value * 100) / 100
712
+ }
713
+
714
+ function clampOpacity(value: number) {
715
+ if (!Number.isFinite(value)) return 0.16
716
+
717
+ return Math.min(1, Math.max(0, value))
718
+ }
719
+
720
+ function isSelectedNode(node: ChartNode) {
721
+ return props.modelValue === node.id
722
+ }
723
+
724
+ function swatchStyle(color: string): CSSProperties {
725
+ return {
726
+ backgroundColor: color,
727
+ }
728
+ }
729
+
730
+ function isLineSeries(series: NormalizedChartSeries) {
731
+ return series.type === "line"
732
+ }
733
+
734
+ function handleSelect(node: ChartNode) {
735
+ if (!props.selectable) return
736
+
737
+ emit("update:modelValue", node.id)
738
+ emit("select", {
739
+ data: node.data,
740
+ index: node.index,
741
+ key: node.key,
742
+ label: node.label,
743
+ series: node.series,
744
+ value: node.value,
745
+ })
746
+ }
747
+
748
+ function handleNodeKeydown(event: KeyboardEvent, node: ChartNode) {
749
+ if (event.key !== "Enter" && event.key !== " ") return
750
+
751
+ event.preventDefault()
752
+ handleSelect(node)
753
+ }
754
+ </script>
755
+
756
+ <template>
757
+ <article
758
+ data-slot="chart"
759
+ :data-size="props.size"
760
+ :data-type="props.type"
761
+ :class="cn('overflow-hidden rounded-xl border bg-card text-card-foreground shadow-xs', props.class)"
762
+ >
763
+ <header
764
+ v-if="hasHeader"
765
+ data-slot="chart-header"
766
+ :class="cn('flex flex-wrap items-start justify-between border-b', sizeClasses.header)"
767
+ >
768
+ <div v-if="props.title || props.description" class="flex min-w-0 flex-col gap-1">
769
+ <h3
770
+ v-if="props.title"
771
+ data-slot="chart-title"
772
+ :class="cn('truncate font-semibold leading-tight tracking-normal', sizeClasses.title)"
773
+ >
774
+ {{ props.title }}
775
+ </h3>
776
+ <p
777
+ v-if="props.description"
778
+ data-slot="chart-description"
779
+ :class="cn('text-muted-foreground', sizeClasses.description)"
780
+ >
781
+ {{ props.description }}
782
+ </p>
783
+ </div>
784
+
785
+ <p
786
+ v-if="props.summary"
787
+ data-slot="chart-summary"
788
+ class="shrink-0 text-xs font-medium text-muted-foreground"
789
+ >
790
+ {{ props.summary }}
791
+ </p>
792
+ </header>
793
+
794
+ <div
795
+ v-if="hasRenderableData"
796
+ data-slot="chart-body"
797
+ :class="cn('flex min-w-0 flex-col gap-3', sizeClasses.body)"
798
+ >
799
+ <div
800
+ v-if="props.showLegend && normalizedSeries.length && props.legendPosition === 'top'"
801
+ data-slot="chart-legend"
802
+ data-position="top"
803
+ :class="cn('flex flex-wrap items-center justify-center text-muted-foreground', sizeClasses.legend)"
804
+ :aria-label="props.legendLabel"
805
+ >
806
+ <span
807
+ v-for="seriesItem in normalizedSeries"
808
+ :key="seriesItem.key"
809
+ data-slot="chart-legend-item"
810
+ class="inline-flex min-w-0 items-center gap-1.5"
811
+ >
812
+ <span
813
+ data-slot="chart-legend-swatch"
814
+ aria-hidden="true"
815
+ :class="cn('shrink-0', isLineSeries(seriesItem) ? 'h-0.5 w-5 rounded-full' : 'size-2.5 rounded-full')"
816
+ :style="swatchStyle(seriesItem.color)"
817
+ />
818
+ <span class="truncate">{{ seriesItem.label }}</span>
819
+ </span>
820
+ </div>
821
+
822
+ <div data-slot="chart-viewport" class="min-w-0 overflow-x-auto pb-1">
823
+ <svg
824
+ data-slot="chart-svg"
825
+ role="img"
826
+ :aria-label="props.title ?? 'Chart'"
827
+ class="block h-auto min-w-[34rem] max-w-none overflow-visible sm:min-w-0 sm:w-full"
828
+ :height="chartHeight"
829
+ :viewBox="`0 0 ${chartWidth} ${chartHeight}`"
830
+ :width="chartWidth"
831
+ >
832
+ <g
833
+ v-if="props.showGrid"
834
+ data-slot="chart-grid"
835
+ aria-hidden="true"
836
+ >
837
+ <line
838
+ v-for="tick in gridTicks"
839
+ :key="`grid-${tick.value}`"
840
+ class="text-border"
841
+ fill="none"
842
+ stroke="currentColor"
843
+ stroke-dasharray="4 6"
844
+ stroke-linecap="round"
845
+ :stroke-width="tick.value === 0 ? 1.25 : 1"
846
+ :x1="geometry.left"
847
+ :x2="geometry.left + geometry.plotWidth"
848
+ :y1="tick.y"
849
+ :y2="tick.y"
850
+ />
851
+ </g>
852
+
853
+ <line
854
+ v-if="yDomain.min < 0 && yDomain.max > 0"
855
+ data-slot="chart-zero-line"
856
+ aria-hidden="true"
857
+ class="text-foreground/60"
858
+ fill="none"
859
+ stroke="currentColor"
860
+ :stroke-width="1.25"
861
+ :x1="geometry.left"
862
+ :x2="geometry.left + geometry.plotWidth"
863
+ :y1="baselineY"
864
+ :y2="baselineY"
865
+ />
866
+
867
+ <g
868
+ v-if="props.showYAxis"
869
+ data-slot="chart-y-axis"
870
+ >
871
+ <text
872
+ v-for="tick in gridTicks"
873
+ :key="`y-${tick.value}`"
874
+ :class="cn('text-muted-foreground', sizeClasses.axis)"
875
+ dominant-baseline="middle"
876
+ fill="currentColor"
877
+ text-anchor="end"
878
+ :x="geometry.left - 12"
879
+ :y="tick.y"
880
+ >
881
+ {{ tick.label }}
882
+ </text>
883
+ </g>
884
+
885
+ <g
886
+ v-if="props.showXAxis"
887
+ data-slot="chart-x-axis"
888
+ >
889
+ <line
890
+ class="text-border"
891
+ fill="none"
892
+ stroke="currentColor"
893
+ :stroke-width="1"
894
+ :x1="geometry.left"
895
+ :x2="geometry.left + geometry.plotWidth"
896
+ :y1="geometry.top + geometry.plotHeight"
897
+ :y2="geometry.top + geometry.plotHeight"
898
+ />
899
+ <text
900
+ v-for="label in xLabels"
901
+ :key="`x-${label.id}`"
902
+ :class="cn('text-muted-foreground', sizeClasses.axis)"
903
+ dominant-baseline="hanging"
904
+ fill="currentColor"
905
+ text-anchor="middle"
906
+ :x="label.x"
907
+ :y="geometry.top + geometry.plotHeight + 12"
908
+ >
909
+ {{ label.label }}
910
+ </text>
911
+ </g>
912
+
913
+ <g data-slot="chart-bars">
914
+ <rect
915
+ v-for="node in barNodes"
916
+ :key="node.id"
917
+ data-slot="chart-bar"
918
+ :aria-label="formatNodeLabel(node)"
919
+ :aria-selected="props.selectable ? isSelectedNode(node) : undefined"
920
+ :fill="node.color"
921
+ role="button"
922
+ :rx="Math.min(4, node.width / 2)"
923
+ stroke="transparent"
924
+ :stroke-width="0"
925
+ :tabindex="props.selectable ? 0 : undefined"
926
+ :width="node.width"
927
+ :height="node.height"
928
+ :x="node.x"
929
+ :y="node.y"
930
+ class="outline-none transition-opacity hover:opacity-80 focus-visible:opacity-80"
931
+ @click="handleSelect(node)"
932
+ @keydown="handleNodeKeydown($event, node)"
933
+ >
934
+ <title>{{ formatNodeLabel(node) }}</title>
935
+ </rect>
936
+ </g>
937
+
938
+ <g data-slot="chart-lines">
939
+ <path
940
+ v-for="path in lineAreaPaths"
941
+ :key="`${path.key}:area`"
942
+ data-slot="chart-line-area"
943
+ aria-hidden="true"
944
+ :d="path.d"
945
+ :fill="path.color"
946
+ :fill-opacity="path.opacity"
947
+ stroke="none"
948
+ />
949
+
950
+ <path
951
+ v-for="path in linePaths"
952
+ :key="path.key"
953
+ data-slot="chart-line"
954
+ fill="none"
955
+ stroke-linecap="round"
956
+ stroke-linejoin="round"
957
+ :aria-label="path.label"
958
+ :d="path.d"
959
+ :stroke="path.color"
960
+ :stroke-width="sizeClasses.lineWidth"
961
+ />
962
+
963
+ <template v-if="visibleLineNodes.length">
964
+ <circle
965
+ v-for="node in visibleLineNodes"
966
+ :key="node.id"
967
+ data-slot="chart-point"
968
+ :aria-label="formatNodeLabel(node)"
969
+ :aria-selected="props.selectable ? isSelectedNode(node) : undefined"
970
+ :cx="node.x"
971
+ :cy="node.y"
972
+ :fill="node.color"
973
+ role="button"
974
+ :r="isSelectedNode(node) ? sizeClasses.pointRadius + 1 : sizeClasses.pointRadius"
975
+ stroke="var(--card)"
976
+ :stroke-width="1.5"
977
+ :tabindex="props.selectable ? 0 : undefined"
978
+ class="outline-none transition-opacity hover:opacity-80 focus-visible:opacity-80"
979
+ @click="handleSelect(node)"
980
+ @keydown="handleNodeKeydown($event, node)"
981
+ >
982
+ <title>{{ formatNodeLabel(node) }}</title>
983
+ </circle>
984
+ </template>
985
+
986
+ <circle
987
+ v-for="node in lineHitNodes"
988
+ :key="`${node.id}:hit`"
989
+ data-slot="chart-line-hit-area"
990
+ :aria-label="formatNodeLabel(node)"
991
+ :aria-selected="props.selectable ? isSelectedNode(node) : undefined"
992
+ :cx="node.x"
993
+ :cy="node.y"
994
+ fill="transparent"
995
+ role="button"
996
+ :r="Math.max(8, sizeClasses.pointRadius + 4)"
997
+ stroke="transparent"
998
+ :stroke-width="0"
999
+ :tabindex="props.selectable ? 0 : undefined"
1000
+ class="outline-none"
1001
+ @click="handleSelect(node)"
1002
+ @keydown="handleNodeKeydown($event, node)"
1003
+ >
1004
+ <title>{{ formatNodeLabel(node) }}</title>
1005
+ </circle>
1006
+ </g>
1007
+ </svg>
1008
+ </div>
1009
+
1010
+ <div
1011
+ v-if="props.showLegend && normalizedSeries.length && props.legendPosition === 'bottom'"
1012
+ data-slot="chart-legend"
1013
+ data-position="bottom"
1014
+ :class="cn('flex flex-wrap items-center justify-end text-muted-foreground', sizeClasses.legend)"
1015
+ :aria-label="props.legendLabel"
1016
+ >
1017
+ <span
1018
+ v-for="seriesItem in normalizedSeries"
1019
+ :key="seriesItem.key"
1020
+ data-slot="chart-legend-item"
1021
+ class="inline-flex min-w-0 items-center gap-1.5"
1022
+ >
1023
+ <span
1024
+ data-slot="chart-legend-swatch"
1025
+ aria-hidden="true"
1026
+ :class="cn('shrink-0', isLineSeries(seriesItem) ? 'h-0.5 w-5 rounded-full' : 'size-2.5 rounded-full')"
1027
+ :style="swatchStyle(seriesItem.color)"
1028
+ />
1029
+ <span class="truncate">{{ seriesItem.label }}</span>
1030
+ </span>
1031
+ </div>
1032
+ </div>
1033
+
1034
+ <div
1035
+ v-else
1036
+ data-slot="chart-empty"
1037
+ :class="cn('text-muted-foreground', sizeClasses.body, sizeClasses.content)"
1038
+ >
1039
+ {{ props.emptyLabel }}
1040
+ </div>
1041
+ </article>
1042
+ </template>