@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,100 @@
1
+ {
2
+ "$schema": "https://shadcn-vue.com/schema/registry-item.json",
3
+ "name": "select",
4
+ "title": "Select",
5
+ "description": "A select control with styled option menus, option descriptions, groups, disabled options, and optional search.",
6
+ "dependencies": [
7
+ "@lucide/vue",
8
+ "@vueuse/core",
9
+ "clsx",
10
+ "reka-ui",
11
+ "tailwind-merge"
12
+ ],
13
+ "files": [
14
+ {
15
+ "path": "src/components/ui/select/Select.vue",
16
+ "content": "<script setup lang=\"ts\">\nimport type { SelectRootEmits, SelectRootProps } from \"reka-ui\"\nimport { SelectRoot, useForwardPropsEmits } from \"reka-ui\"\n\nconst props = defineProps<SelectRootProps>()\nconst emits = defineEmits<SelectRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <SelectRoot\n v-slot=\"slotProps\"\n data-slot=\"select\"\n v-bind=\"forwarded\"\n >\n <slot v-bind=\"slotProps\" />\n </SelectRoot>\n</template>\n",
17
+ "type": "registry:ui",
18
+ "target": "components/ui/select/Select.vue"
19
+ },
20
+ {
21
+ "path": "src/components/ui/select/SelectTrigger.vue",
22
+ "content": "<script setup lang=\"ts\">\nimport type { SelectTriggerProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { ChevronDown } from \"@lucide/vue\"\nimport { reactiveOmit } from \"@vueuse/core\"\nimport { SelectIcon, SelectTrigger, useForwardProps } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = withDefaults(\n defineProps<SelectTriggerProps & { class?: HTMLAttributes[\"class\"], size?: \"sm\" | \"default\" }>(),\n { size: \"default\" },\n)\n\nconst delegatedProps = reactiveOmit(props, \"class\", \"size\")\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <SelectTrigger\n data-slot=\"select-trigger\"\n :data-size=\"size\"\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*=text-])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=size-])]:size-4',\n props.class,\n )\"\n >\n <slot />\n <SelectIcon as-child>\n <ChevronDown class=\"size-4 opacity-50\" />\n </SelectIcon>\n </SelectTrigger>\n</template>\n",
23
+ "type": "registry:ui",
24
+ "target": "components/ui/select/SelectTrigger.vue"
25
+ },
26
+ {
27
+ "path": "src/components/ui/select/SelectValue.vue",
28
+ "content": "<script setup lang=\"ts\">\nimport type { SelectValueProps } from \"reka-ui\"\nimport { SelectValue } from \"reka-ui\"\n\nconst props = defineProps<SelectValueProps>()\n</script>\n\n<template>\n <SelectValue\n data-slot=\"select-value\"\n v-bind=\"props\"\n >\n <slot />\n </SelectValue>\n</template>\n",
29
+ "type": "registry:ui",
30
+ "target": "components/ui/select/SelectValue.vue"
31
+ },
32
+ {
33
+ "path": "src/components/ui/select/SelectContent.vue",
34
+ "content": "<script setup lang=\"ts\">\nimport type { SelectContentEmits, SelectContentProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { computed, nextTick, provide, ref, shallowReactive } from \"vue\"\nimport { Search, X } from \"@lucide/vue\"\nimport { reactiveOmit } from \"@vueuse/core\"\nimport {\n SelectContent,\n SelectPortal,\n SelectViewport,\n useForwardPropsEmits,\n} from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\nimport { SelectScrollDownButton, SelectScrollUpButton } from \".\"\nimport {\n normalizeSelectSearchText,\n selectSearchContextKey,\n type SelectSearchItem,\n} from \"./search\"\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(\n defineProps<SelectContentProps & {\n class?: HTMLAttributes[\"class\"]\n emptyText?: string\n search?: boolean\n searchClearLabel?: string\n searchPlaceholder?: string\n 검색?: boolean\n }>(),\n {\n emptyText: \"No results found.\",\n position: \"popper\",\n search: false,\n searchClearLabel: \"Clear search\",\n searchPlaceholder: \"Search options\",\n 검색: false,\n },\n)\nconst emits = defineEmits<SelectContentEmits>()\n\nconst delegatedProps = reactiveOmit(\n props,\n \"class\",\n \"emptyText\",\n \"search\",\n \"searchClearLabel\",\n \"searchPlaceholder\",\n \"검색\",\n)\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\nconst searchQuery = ref(\"\")\nconst searchInputRef = ref<HTMLInputElement | null>(null)\nconst searchItems = shallowReactive(new Map<symbol, SelectSearchItem>())\nconst isSearchEnabled = computed(() => props.search || props.검색)\nconst normalizedSearchQuery = computed(() => normalizeSelectSearchText(searchQuery.value))\nconst hasSearchQuery = computed(() => normalizedSearchQuery.value.length > 0)\nconst hasVisibleItems = computed(() => {\n if (!isSearchEnabled.value || !hasSearchQuery.value) return true\n\n return Array.from(searchItems.values()).some((item) => item.matches.value)\n})\n\nfunction hasVisibleItemsInGroup(groupId: symbol) {\n if (!isSearchEnabled.value || !hasSearchQuery.value) return true\n\n return Array.from(searchItems.values()).some(\n (item) => item.groupId === groupId && item.matches.value,\n )\n}\n\nfunction handleSearchKeydown(event: KeyboardEvent) {\n if (event.key === \"Escape\" && searchQuery.value) {\n searchQuery.value = \"\"\n event.preventDefault()\n event.stopPropagation()\n return\n }\n\n if (event.key !== \"Escape\") {\n event.stopPropagation()\n }\n}\n\nfunction clearSearch() {\n searchQuery.value = \"\"\n\n void nextTick(() => searchInputRef.value?.focus())\n}\n\nprovide(selectSearchContextKey, {\n enabled: isSearchEnabled,\n hasQuery: hasSearchQuery,\n hasVisibleItems,\n query: normalizedSearchQuery,\n hasVisibleItemsInGroup,\n registerItem: (item) => searchItems.set(item.id, item),\n unregisterItem: (id) => searchItems.delete(id),\n})\n</script>\n\n<template>\n <SelectPortal>\n <SelectContent\n data-slot=\"select-content\"\n v-bind=\"{ ...$attrs, ...forwarded }\"\n :class=\"cn(\n 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--reka-select-content-available-height) min-w-[8rem] overflow-x-hidden overflow-y-auto rounded-md border shadow-md',\n position === 'popper'\n && 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',\n props.class,\n )\n \"\n >\n <SelectScrollUpButton />\n <div v-if=\"isSearchEnabled\" data-slot=\"select-search\" class=\"border-b p-1\">\n <div class=\"relative\">\n <Search\n aria-hidden=\"true\"\n class=\"pointer-events-none absolute top-1/2 left-2 size-4 -translate-y-1/2 text-muted-foreground\"\n />\n <input\n ref=\"searchInputRef\"\n v-model=\"searchQuery\"\n data-slot=\"select-search-input\"\n type=\"text\"\n role=\"searchbox\"\n autocomplete=\"off\"\n :placeholder=\"props.searchPlaceholder\"\n class=\"h-8 w-full rounded-sm bg-transparent py-1.5 pr-8 pl-8 text-sm outline-none placeholder:text-muted-foreground focus:bg-accent focus:text-accent-foreground\"\n @click.stop\n @keydown=\"handleSearchKeydown\"\n @pointerdown.stop\n />\n <button\n v-if=\"searchQuery\"\n data-slot=\"select-search-clear\"\n type=\"button\"\n :aria-label=\"props.searchClearLabel\"\n class=\"absolute top-1/2 right-1 flex size-6 -translate-y-1/2 items-center justify-center rounded-sm text-muted-foreground transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none\"\n @click.stop.prevent=\"clearSearch\"\n @keydown.stop\n @pointerdown.stop.prevent\n >\n <X aria-hidden=\"true\" class=\"size-4\" />\n </button>\n </div>\n </div>\n <SelectViewport :class=\"cn('p-1', position === 'popper' && 'h-[var(--reka-select-trigger-height)] w-full min-w-[var(--reka-select-trigger-width)] scroll-my-1')\">\n <slot />\n <div\n v-if=\"isSearchEnabled && hasSearchQuery && !hasVisibleItems\"\n data-slot=\"select-empty\"\n class=\"px-2 py-6 text-center text-sm text-muted-foreground\"\n >\n {{ props.emptyText }}\n </div>\n </SelectViewport>\n <SelectScrollDownButton />\n </SelectContent>\n </SelectPortal>\n</template>\n",
35
+ "type": "registry:ui",
36
+ "target": "components/ui/select/SelectContent.vue"
37
+ },
38
+ {
39
+ "path": "src/components/ui/select/SelectGroup.vue",
40
+ "content": "<script setup lang=\"ts\">\nimport type { SelectGroupProps } from \"reka-ui\"\nimport { computed, inject, provide } from \"vue\"\nimport { SelectGroup } from \"reka-ui\"\nimport { selectSearchContextKey, selectSearchGroupKey } from \"./search\"\n\nconst props = defineProps<SelectGroupProps>()\nconst groupId = Symbol(\"select-group\")\nconst searchContext = inject(selectSearchContextKey, null)\nconst isVisible = computed(() => searchContext?.hasVisibleItemsInGroup(groupId) ?? true)\n\nprovide(selectSearchGroupKey, groupId)\n</script>\n\n<template>\n <SelectGroup\n v-show=\"isVisible\"\n data-slot=\"select-group\"\n v-bind=\"props\"\n >\n <slot />\n </SelectGroup>\n</template>\n",
41
+ "type": "registry:ui",
42
+ "target": "components/ui/select/SelectGroup.vue"
43
+ },
44
+ {
45
+ "path": "src/components/ui/select/SelectItem.vue",
46
+ "content": "<script setup lang=\"ts\">\nimport type { SelectItemProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { computed, inject, onBeforeUnmount } from \"vue\"\nimport { Check } from \"@lucide/vue\"\nimport { reactiveOmit } from \"@vueuse/core\"\nimport {\n SelectItem,\n SelectItemIndicator,\n SelectItemText,\n useForwardProps,\n} from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\nimport {\n normalizeSelectSearchText,\n selectSearchContextKey,\n selectSearchGroupKey,\n} from \"./search\"\n\nconst props = defineProps<SelectItemProps & {\n class?: HTMLAttributes[\"class\"]\n description?: string\n descriptionClass?: HTMLAttributes[\"class\"]\n}>()\n\nconst delegatedProps = reactiveOmit(props, \"class\", \"description\", \"descriptionClass\")\n\nconst forwardedProps = useForwardProps(delegatedProps)\nconst searchContext = inject(selectSearchContextKey, null)\nconst groupId = inject(selectSearchGroupKey, undefined)\nconst itemId = Symbol(\"select-item\")\nconst itemSearchText = computed(() =>\n normalizeSelectSearchText(\n [props.textValue ?? props.value, props.description].filter(Boolean).join(\" \"),\n ),\n)\nconst matchesSearch = computed(() => {\n if (!searchContext?.enabled.value || !searchContext.hasQuery.value) return true\n\n return itemSearchText.value.includes(searchContext.query.value)\n})\nconst isVisible = computed(() => matchesSearch.value)\n\nif (searchContext) {\n searchContext.registerItem({\n groupId,\n id: itemId,\n matches: matchesSearch,\n })\n\n onBeforeUnmount(() => searchContext.unregisterItem(itemId))\n}\n</script>\n\n<template>\n <SelectItem\n v-if=\"isVisible\"\n data-slot=\"select-item\"\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'group focus:bg-accent focus:text-accent-foreground data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground [&_svg:not([class*=text-])]:text-muted-foreground relative flex w-full cursor-default items-start gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=size-])]:size-4',\n props.class,\n )\n \"\n >\n <span class=\"absolute top-1/2 right-2 flex size-3.5 -translate-y-1/2 items-center justify-center\">\n <SelectItemIndicator>\n <slot name=\"indicator-icon\">\n <Check class=\"size-4\" />\n </slot>\n </SelectItemIndicator>\n </span>\n\n <span class=\"grid min-w-0 gap-0.5\">\n <SelectItemText>\n <span data-slot=\"select-item-label\" class=\"truncate\">\n <slot />\n </span>\n </SelectItemText>\n <span\n v-if=\"props.description || $slots.description\"\n data-slot=\"select-item-description\"\n :class=\"\n cn(\n 'text-xs leading-snug text-muted-foreground group-data-[highlighted]:text-accent-foreground/80 group-focus:text-accent-foreground/80',\n props.descriptionClass,\n )\n \"\n >\n <slot name=\"description\">\n {{ props.description }}\n </slot>\n </span>\n </span>\n </SelectItem>\n</template>\n",
47
+ "type": "registry:ui",
48
+ "target": "components/ui/select/SelectItem.vue"
49
+ },
50
+ {
51
+ "path": "src/components/ui/select/SelectItemText.vue",
52
+ "content": "<script setup lang=\"ts\">\nimport type { SelectItemTextProps } from \"reka-ui\"\nimport { SelectItemText } from \"reka-ui\"\n\nconst props = defineProps<SelectItemTextProps>()\n</script>\n\n<template>\n <SelectItemText\n data-slot=\"select-item-text\"\n v-bind=\"props\"\n >\n <slot />\n </SelectItemText>\n</template>\n",
53
+ "type": "registry:ui",
54
+ "target": "components/ui/select/SelectItemText.vue"
55
+ },
56
+ {
57
+ "path": "src/components/ui/select/SelectLabel.vue",
58
+ "content": "<script setup lang=\"ts\">\nimport type { SelectLabelProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { SelectLabel } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<SelectLabelProps & { class?: HTMLAttributes[\"class\"] }>()\n</script>\n\n<template>\n <SelectLabel\n data-slot=\"select-label\"\n :class=\"cn('text-muted-foreground px-2 py-1.5 text-xs', props.class)\"\n >\n <slot />\n </SelectLabel>\n</template>\n",
59
+ "type": "registry:ui",
60
+ "target": "components/ui/select/SelectLabel.vue"
61
+ },
62
+ {
63
+ "path": "src/components/ui/select/SelectSeparator.vue",
64
+ "content": "<script setup lang=\"ts\">\nimport type { SelectSeparatorProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { reactiveOmit } from \"@vueuse/core\"\nimport { SelectSeparator } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<SelectSeparatorProps & { class?: HTMLAttributes[\"class\"] }>()\n\nconst delegatedProps = reactiveOmit(props, \"class\")\n</script>\n\n<template>\n <SelectSeparator\n data-slot=\"select-separator\"\n v-bind=\"delegatedProps\"\n :class=\"cn('bg-border pointer-events-none -mx-1 my-1 h-px', props.class)\"\n />\n</template>\n",
65
+ "type": "registry:ui",
66
+ "target": "components/ui/select/SelectSeparator.vue"
67
+ },
68
+ {
69
+ "path": "src/components/ui/select/SelectScrollUpButton.vue",
70
+ "content": "<script setup lang=\"ts\">\nimport type { SelectScrollUpButtonProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { ChevronUp } from \"@lucide/vue\"\nimport { reactiveOmit } from \"@vueuse/core\"\nimport { SelectScrollUpButton, useForwardProps } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<SelectScrollUpButtonProps & { class?: HTMLAttributes[\"class\"] }>()\n\nconst delegatedProps = reactiveOmit(props, \"class\")\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <SelectScrollUpButton\n data-slot=\"select-scroll-up-button\"\n v-bind=\"forwardedProps\"\n :class=\"cn('flex cursor-default items-center justify-center py-1', props.class)\"\n >\n <slot>\n <ChevronUp class=\"size-4\" />\n </slot>\n </SelectScrollUpButton>\n</template>\n",
71
+ "type": "registry:ui",
72
+ "target": "components/ui/select/SelectScrollUpButton.vue"
73
+ },
74
+ {
75
+ "path": "src/components/ui/select/SelectScrollDownButton.vue",
76
+ "content": "<script setup lang=\"ts\">\nimport type { SelectScrollDownButtonProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { ChevronDown } from \"@lucide/vue\"\nimport { reactiveOmit } from \"@vueuse/core\"\nimport { SelectScrollDownButton, useForwardProps } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<SelectScrollDownButtonProps & { class?: HTMLAttributes[\"class\"] }>()\n\nconst delegatedProps = reactiveOmit(props, \"class\")\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <SelectScrollDownButton\n data-slot=\"select-scroll-down-button\"\n v-bind=\"forwardedProps\"\n :class=\"cn('flex cursor-default items-center justify-center py-1', props.class)\"\n >\n <slot>\n <ChevronDown class=\"size-4\" />\n </slot>\n </SelectScrollDownButton>\n</template>\n",
77
+ "type": "registry:ui",
78
+ "target": "components/ui/select/SelectScrollDownButton.vue"
79
+ },
80
+ {
81
+ "path": "src/components/ui/select/search.ts",
82
+ "content": "import type { ComputedRef, InjectionKey } from \"vue\"\n\nexport interface SelectSearchItem {\n groupId?: symbol\n id: symbol\n matches: ComputedRef<boolean>\n}\n\nexport interface SelectSearchContext {\n enabled: ComputedRef<boolean>\n hasQuery: ComputedRef<boolean>\n hasVisibleItems: ComputedRef<boolean>\n query: ComputedRef<string>\n hasVisibleItemsInGroup: (groupId: symbol) => boolean\n registerItem: (item: SelectSearchItem) => void\n unregisterItem: (id: symbol) => void\n}\n\nexport const selectSearchContextKey: InjectionKey<SelectSearchContext> =\n Symbol(\"select-search-context\")\n\nexport const selectSearchGroupKey: InjectionKey<symbol> = Symbol(\"select-search-group\")\n\nexport function normalizeSelectSearchText(value: unknown) {\n return String(value ?? \"\").trim().toLocaleLowerCase()\n}\n",
83
+ "type": "registry:ui",
84
+ "target": "components/ui/select/search.ts"
85
+ },
86
+ {
87
+ "path": "src/components/ui/select/index.ts",
88
+ "content": "export { default as Select } from \"./Select.vue\"\nexport { default as SelectContent } from \"./SelectContent.vue\"\nexport { default as SelectGroup } from \"./SelectGroup.vue\"\nexport { default as SelectItem } from \"./SelectItem.vue\"\nexport { default as SelectItemText } from \"./SelectItemText.vue\"\nexport { default as SelectLabel } from \"./SelectLabel.vue\"\nexport { default as SelectScrollDownButton } from \"./SelectScrollDownButton.vue\"\nexport { default as SelectScrollUpButton } from \"./SelectScrollUpButton.vue\"\nexport { default as SelectSeparator } from \"./SelectSeparator.vue\"\nexport { default as SelectTrigger } from \"./SelectTrigger.vue\"\nexport { default as SelectValue } from \"./SelectValue.vue\"\n",
89
+ "type": "registry:ui",
90
+ "target": "components/ui/select/index.ts"
91
+ },
92
+ {
93
+ "path": "src/lib/utils.ts",
94
+ "content": "import { type ClassValue, clsx } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n",
95
+ "type": "registry:lib",
96
+ "target": "lib/utils.ts"
97
+ }
98
+ ],
99
+ "type": "registry:ui"
100
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "$schema": "https://shadcn-vue.com/schema/registry-item.json",
3
+ "name": "separator",
4
+ "title": "Separator",
5
+ "description": "A horizontal or vertical divider for separating related content.",
6
+ "dependencies": [
7
+ "clsx",
8
+ "tailwind-merge"
9
+ ],
10
+ "files": [
11
+ {
12
+ "path": "src/components/ui/separator/Separator.vue",
13
+ "content": "<script setup lang=\"ts\">\nimport { computed } from \"vue\"\nimport { cn } from \"@/lib/utils\"\nimport type { SeparatorProps } from \"./types\"\n\nconst props = withDefaults(defineProps<SeparatorProps>(), {\n decorative: true,\n orientation: \"horizontal\",\n})\n\nconst separatorRole = computed(() => props.decorative ? undefined : \"separator\")\nconst ariaOrientation = computed(() =>\n props.decorative ? undefined : props.orientation,\n)\n</script>\n\n<template>\n <div\n data-slot=\"separator\"\n :data-orientation=\"props.orientation\"\n :role=\"separatorRole\"\n :aria-orientation=\"ariaOrientation\"\n :class=\"\n cn(\n 'bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px',\n props.class,\n )\n \"\n />\n</template>\n",
14
+ "type": "registry:ui",
15
+ "target": "components/ui/separator/Separator.vue"
16
+ },
17
+ {
18
+ "path": "src/components/ui/separator/types.ts",
19
+ "content": "import type { HTMLAttributes } from \"vue\"\n\nexport type SeparatorOrientation = \"horizontal\" | \"vertical\"\n\nexport interface SeparatorProps {\n class?: HTMLAttributes[\"class\"]\n decorative?: boolean\n orientation?: SeparatorOrientation\n}\n",
20
+ "type": "registry:ui",
21
+ "target": "components/ui/separator/types.ts"
22
+ },
23
+ {
24
+ "path": "src/components/ui/separator/index.ts",
25
+ "content": "export { default as Separator } from \"./Separator.vue\"\nexport type {\n SeparatorOrientation,\n SeparatorProps,\n} from \"./types\"\n",
26
+ "type": "registry:ui",
27
+ "target": "components/ui/separator/index.ts"
28
+ },
29
+ {
30
+ "path": "src/lib/utils.ts",
31
+ "content": "import { type ClassValue, clsx } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n",
32
+ "type": "registry:lib",
33
+ "target": "lib/utils.ts"
34
+ }
35
+ ],
36
+ "type": "registry:ui"
37
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "$schema": "https://shadcn-vue.com/schema/registry-item.json",
3
+ "name": "shimmer",
4
+ "title": "Shimmer",
5
+ "description": "An animated text shimmer for loading states and progressive reveal effects.",
6
+ "dependencies": [
7
+ "clsx",
8
+ "tailwind-merge"
9
+ ],
10
+ "files": [
11
+ {
12
+ "path": "src/components/ui/shimmer/Shimmer.vue",
13
+ "content": "<script setup lang=\"ts\">\nimport { computed } from \"vue\"\nimport type { CSSProperties, HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\n\nexport type ShimmerTone = \"default\" | \"muted\" | \"primary\" | \"success\" | \"warning\"\n\nexport interface ShimmerProps {\n as?: string\n class?: HTMLAttributes[\"class\"]\n decorative?: boolean\n delay?: string\n disabled?: boolean\n duration?: string\n label?: string\n text?: string\n tone?: ShimmerTone\n}\n\nconst props = withDefaults(defineProps<ShimmerProps>(), {\n as: \"span\",\n decorative: false,\n delay: \"0s\",\n disabled: false,\n duration: \"3.6s\",\n tone: \"default\",\n})\n\nconst shimmerStyle = computed<CSSProperties>(() => ({\n \"--shimmer-delay\": props.delay,\n \"--shimmer-duration\": props.duration,\n} as CSSProperties))\n</script>\n\n<template>\n <component\n :is=\"props.as\"\n data-slot=\"shimmer\"\n :data-animated=\"props.disabled ? 'false' : 'true'\"\n :data-tone=\"props.tone\"\n :aria-hidden=\"props.decorative ? 'true' : undefined\"\n :aria-label=\"props.decorative ? undefined : props.label\"\n :class=\"cn('inline-block font-medium leading-none tracking-normal', props.class)\"\n :role=\"!props.decorative && props.label ? 'status' : undefined\"\n :style=\"shimmerStyle\"\n >\n <slot>{{ props.text }}</slot>\n </component>\n</template>\n\n<style scoped>\n@keyframes shimmer-text-sweep {\n 0% {\n background-position: 180% 0;\n }\n\n 100% {\n background-position: -180% 0;\n }\n}\n\n[data-slot=\"shimmer\"] {\n --shimmer-base: color-mix(in oklab, var(--foreground) 38%, transparent);\n --shimmer-highlight: var(--foreground);\n color: var(--shimmer-highlight);\n}\n\n[data-slot=\"shimmer\"][data-tone=\"muted\"] {\n --shimmer-base: color-mix(in oklab, var(--muted-foreground) 36%, transparent);\n --shimmer-highlight: var(--muted-foreground);\n}\n\n[data-slot=\"shimmer\"][data-tone=\"primary\"] {\n --shimmer-base: color-mix(in oklab, var(--primary) 38%, transparent);\n --shimmer-highlight: var(--primary);\n}\n\n[data-slot=\"shimmer\"][data-tone=\"success\"] {\n --shimmer-base: oklch(0.58 0.15 154 / 38%);\n --shimmer-highlight: oklch(0.58 0.15 154);\n}\n\n[data-slot=\"shimmer\"][data-tone=\"warning\"] {\n --shimmer-base: oklch(0.67 0.17 68 / 42%);\n --shimmer-highlight: oklch(0.58 0.15 68);\n}\n\n[data-slot=\"shimmer\"][data-animated=\"true\"] {\n animation: shimmer-text-sweep var(--shimmer-duration) ease-in-out var(--shimmer-delay) infinite;\n background-image: linear-gradient(\n 110deg,\n var(--shimmer-base) 0%,\n var(--shimmer-base) 36%,\n var(--shimmer-highlight) 50%,\n var(--shimmer-base) 64%,\n var(--shimmer-base) 100%\n );\n background-size: 260% 100%;\n -webkit-background-clip: text;\n background-clip: text;\n -webkit-text-fill-color: transparent;\n}\n\n@media (prefers-reduced-motion: reduce) {\n [data-slot=\"shimmer\"][data-animated=\"true\"] {\n animation: none;\n background-position: 50% 0;\n }\n}\n</style>\n",
14
+ "type": "registry:ui",
15
+ "target": "components/ui/shimmer/Shimmer.vue"
16
+ },
17
+ {
18
+ "path": "src/components/ui/shimmer/index.ts",
19
+ "content": "export { default as Shimmer } from \"./Shimmer.vue\"\nexport type {\n ShimmerProps,\n ShimmerTone,\n} from \"./Shimmer.vue\"\n",
20
+ "type": "registry:ui",
21
+ "target": "components/ui/shimmer/index.ts"
22
+ },
23
+ {
24
+ "path": "src/lib/utils.ts",
25
+ "content": "import { type ClassValue, clsx } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n",
26
+ "type": "registry:lib",
27
+ "target": "lib/utils.ts"
28
+ }
29
+ ],
30
+ "type": "registry:ui"
31
+ }
@@ -0,0 +1,221 @@
1
+ {
2
+ "$schema": "https://shadcn-vue.com/schema/registry-item.json",
3
+ "name": "sidebar",
4
+ "title": "Sidebar",
5
+ "description": "A composable application sidebar with provider-managed open state, menu groups, trigger controls, and collapsed icon mode.",
6
+ "dependencies": [
7
+ "@lucide/vue",
8
+ "@vueuse/core",
9
+ "class-variance-authority",
10
+ "clsx",
11
+ "reka-ui",
12
+ "tailwind-merge"
13
+ ],
14
+ "files": [
15
+ {
16
+ "path": "src/components/ui/sidebar/Sidebar.vue",
17
+ "content": "<script setup lang=\"ts\">\nimport { computed } from \"vue\"\nimport { cn } from \"@/lib/utils\"\nimport {\n SIDEBAR_WIDTH,\n SIDEBAR_WIDTH_ICON,\n SIDEBAR_WIDTH_MOBILE,\n useOptionalSidebar,\n} from \"./context\"\nimport type { SidebarProps } from \"./types\"\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<SidebarProps>(), {\n collapsible: \"offcanvas\",\n side: \"left\",\n variant: \"sidebar\",\n})\n\nconst sidebar = useOptionalSidebar()\n\nconst state = computed(() => sidebar?.state.value ?? \"expanded\")\nconst isMobile = computed(() => sidebar?.isMobile.value ?? false)\nconst isMobileOpen = computed(() => sidebar?.openMobile.value ?? false)\nconst dataCollapsible = computed(() =>\n state.value === \"collapsed\" ? props.collapsible : \"\",\n)\n\nfunction closeMobile() {\n sidebar?.setOpenMobile(false)\n}\n</script>\n\n<template>\n <aside\n v-if=\"props.collapsible === 'none'\"\n data-slot=\"sidebar\"\n data-state=\"expanded\"\n data-collapsible=\"\"\n :data-side=\"props.side\"\n :data-variant=\"props.variant\"\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH,\n '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,\n '--sidebar-width-mobile': SIDEBAR_WIDTH_MOBILE,\n }\"\n :class=\"cn('flex h-full w-(--sidebar-width) shrink-0 flex-col border-r bg-background text-foreground', props.side === 'right' && 'border-r-0 border-l', props.class)\"\n v-bind=\"$attrs\"\n >\n <slot />\n </aside>\n\n <div\n v-else-if=\"isMobile\"\n data-slot=\"sidebar-mobile\"\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH,\n '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,\n '--sidebar-width-mobile': SIDEBAR_WIDTH_MOBILE,\n }\"\n >\n <button\n v-if=\"isMobileOpen\"\n data-slot=\"sidebar-mobile-overlay\"\n type=\"button\"\n class=\"fixed inset-0 z-50 bg-[var(--overlay)] backdrop-blur-[4px] [-webkit-backdrop-filter:blur(4px)] md:hidden\"\n aria-label=\"Close sidebar\"\n @click=\"closeMobile\"\n />\n <aside\n v-if=\"isMobileOpen\"\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n :data-state=\"state\"\n :data-side=\"props.side\"\n :data-variant=\"props.variant\"\n :class=\"\n cn(\n 'fixed inset-y-0 z-50 flex w-(--sidebar-width-mobile) max-w-[calc(100vw-2rem)] flex-col bg-background text-foreground shadow-lg md:hidden',\n props.side === 'left' ? 'left-0 border-r' : 'right-0 border-l',\n props.class,\n )\n \"\n v-bind=\"$attrs\"\n >\n <slot />\n </aside>\n </div>\n\n <div\n v-else\n data-slot=\"sidebar\"\n class=\"group peer hidden text-foreground md:block\"\n :data-state=\"state\"\n :data-collapsible=\"dataCollapsible\"\n :data-side=\"props.side\"\n :data-variant=\"props.variant\"\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH,\n '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,\n '--sidebar-width-mobile': SIDEBAR_WIDTH_MOBILE,\n }\"\n >\n <div\n data-slot=\"sidebar-gap\"\n :class=\"\n cn(\n 'relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear',\n 'group-data-[collapsible=offcanvas]:w-0',\n props.variant === 'floating' || props.variant === 'inset'\n ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+1rem)]'\n : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)',\n )\n \"\n />\n <div\n data-slot=\"sidebar-container\"\n :class=\"\n cn(\n 'fixed inset-y-0 z-10 hidden h-dvh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex',\n props.side === 'left'\n ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'\n : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',\n props.variant === 'floating' || props.variant === 'inset'\n ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+1rem)]'\n : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l',\n props.class,\n )\n \"\n v-bind=\"$attrs\"\n >\n <aside\n data-sidebar=\"sidebar\"\n class=\"flex h-full w-full flex-col bg-background group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm group-data-[variant=inset]:rounded-lg group-data-[variant=inset]:border group-data-[variant=inset]:shadow-xs\"\n >\n <slot />\n </aside>\n </div>\n </div>\n</template>\n",
18
+ "type": "registry:ui",
19
+ "target": "components/ui/sidebar/Sidebar.vue"
20
+ },
21
+ {
22
+ "path": "src/components/ui/sidebar/SidebarProvider.vue",
23
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { computed, onMounted, ref, watch } from \"vue\"\nimport { useEventListener, useMediaQuery } from \"@vueuse/core\"\nimport { cn } from \"@/lib/utils\"\nimport {\n provideSidebarContext,\n SIDEBAR_KEYBOARD_SHORTCUT,\n SIDEBAR_STORAGE_KEY,\n SIDEBAR_WIDTH,\n SIDEBAR_WIDTH_ICON,\n SIDEBAR_WIDTH_MOBILE,\n} from \"./context\"\n\nexport interface SidebarProviderProps {\n class?: HTMLAttributes[\"class\"]\n defaultOpen?: boolean\n keyboardShortcut?: string\n open?: boolean\n persist?: boolean\n storageKey?: string\n}\n\nconst props = withDefaults(defineProps<SidebarProviderProps>(), {\n defaultOpen: true,\n keyboardShortcut: SIDEBAR_KEYBOARD_SHORTCUT,\n open: undefined,\n persist: false,\n storageKey: SIDEBAR_STORAGE_KEY,\n})\n\nconst emits = defineEmits<{\n \"update:open\": [open: boolean]\n}>()\n\nconst isMobile = useMediaQuery(\"(max-width: 768px)\")\nconst openMobile = ref(false)\nconst uncontrolledOpen = ref(props.defaultOpen)\nconst open = computed({\n get: () => props.open ?? uncontrolledOpen.value,\n set: (value: boolean) => {\n uncontrolledOpen.value = value\n emits(\"update:open\", value)\n },\n})\n\nconst state = computed(() => open.value ? \"expanded\" : \"collapsed\")\n\nfunction setOpen(value: boolean) {\n open.value = value\n}\n\nfunction setOpenMobile(value: boolean) {\n openMobile.value = value\n}\n\nfunction toggleSidebar() {\n if (isMobile.value) {\n setOpenMobile(!openMobile.value)\n return\n }\n\n setOpen(!open.value)\n}\n\nfunction isSidebarShortcut(event: KeyboardEvent) {\n if (!props.keyboardShortcut) return false\n\n return event.key.toLowerCase() === props.keyboardShortcut.toLowerCase()\n && (event.metaKey || event.ctrlKey)\n}\n\nonMounted(() => {\n if (!props.persist || props.open !== undefined) return\n\n const storedValue = window.localStorage.getItem(props.storageKey)\n\n if (storedValue === \"true\" || storedValue === \"false\") {\n setOpen(storedValue === \"true\")\n }\n})\n\nwatch(open, (value) => {\n if (!props.persist) return\n\n window.localStorage.setItem(props.storageKey, String(value))\n})\n\nuseEventListener(\"keydown\", (event: KeyboardEvent) => {\n if (!isSidebarShortcut(event)) return\n\n event.preventDefault()\n toggleSidebar()\n})\n\nprovideSidebarContext({\n isMobile,\n open,\n openMobile,\n setOpen,\n setOpenMobile,\n state,\n toggleSidebar,\n})\n</script>\n\n<template>\n <div\n data-slot=\"sidebar-wrapper\"\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH,\n '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,\n '--sidebar-width-mobile': SIDEBAR_WIDTH_MOBILE,\n }\"\n :class=\"cn('group/sidebar-wrapper flex min-h-svh w-full bg-background text-foreground', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
24
+ "type": "registry:ui",
25
+ "target": "components/ui/sidebar/SidebarProvider.vue"
26
+ },
27
+ {
28
+ "path": "src/components/ui/sidebar/SidebarInset.vue",
29
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<{\n class?: HTMLAttributes[\"class\"]\n}>()\n</script>\n\n<template>\n <main\n data-slot=\"sidebar-inset\"\n :class=\"\n cn(\n 'relative flex min-w-0 flex-1 flex-col bg-background',\n 'md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-lg md:peer-data-[variant=inset]:border md:peer-data-[variant=inset]:shadow-xs md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2',\n props.class,\n )\n \"\n >\n <slot />\n </main>\n</template>\n",
30
+ "type": "registry:ui",
31
+ "target": "components/ui/sidebar/SidebarInset.vue"
32
+ },
33
+ {
34
+ "path": "src/components/ui/sidebar/SidebarTrigger.vue",
35
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { PanelLeftIcon } from \"@lucide/vue\"\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"../button\"\nimport { useSidebar } from \"./context\"\n\nconst props = defineProps<{\n class?: HTMLAttributes[\"class\"]\n}>()\n\nconst { toggleSidebar } = useSidebar()\n</script>\n\n<template>\n <Button\n data-slot=\"sidebar-trigger\"\n data-sidebar=\"trigger\"\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n :class=\"cn(props.class)\"\n @click=\"toggleSidebar\"\n >\n <PanelLeftIcon aria-hidden=\"true\" />\n <span class=\"sr-only\">Toggle sidebar</span>\n </Button>\n</template>\n",
36
+ "type": "registry:ui",
37
+ "target": "components/ui/sidebar/SidebarTrigger.vue"
38
+ },
39
+ {
40
+ "path": "src/components/ui/sidebar/SidebarRail.vue",
41
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\nimport { useSidebar } from \"./context\"\n\nconst props = defineProps<{\n class?: HTMLAttributes[\"class\"]\n}>()\n\nconst { toggleSidebar } = useSidebar()\n</script>\n\n<template>\n <button\n data-slot=\"sidebar-rail\"\n data-sidebar=\"rail\"\n type=\"button\"\n aria-label=\"Toggle sidebar\"\n title=\"Toggle sidebar\"\n tabindex=\"-1\"\n :class=\"\n cn(\n 'absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-0.5 hover:after:bg-border sm:flex',\n 'group-data-[side=left]:-right-4 group-data-[side=right]:left-0',\n 'group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full',\n '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',\n 'in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize',\n props.class,\n )\n \"\n @click=\"toggleSidebar\"\n >\n <slot />\n </button>\n</template>\n",
42
+ "type": "registry:ui",
43
+ "target": "components/ui/sidebar/SidebarRail.vue"
44
+ },
45
+ {
46
+ "path": "src/components/ui/sidebar/SidebarHeader.vue",
47
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<{\n class?: HTMLAttributes[\"class\"]\n}>()\n</script>\n\n<template>\n <div\n data-slot=\"sidebar-header\"\n data-sidebar=\"header\"\n :class=\"cn('flex flex-col gap-2 p-2', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
48
+ "type": "registry:ui",
49
+ "target": "components/ui/sidebar/SidebarHeader.vue"
50
+ },
51
+ {
52
+ "path": "src/components/ui/sidebar/SidebarContent.vue",
53
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<{\n class?: HTMLAttributes[\"class\"]\n}>()\n</script>\n\n<template>\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n :class=\"cn('flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
54
+ "type": "registry:ui",
55
+ "target": "components/ui/sidebar/SidebarContent.vue"
56
+ },
57
+ {
58
+ "path": "src/components/ui/sidebar/SidebarFooter.vue",
59
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<{\n class?: HTMLAttributes[\"class\"]\n}>()\n</script>\n\n<template>\n <div\n data-slot=\"sidebar-footer\"\n data-sidebar=\"footer\"\n :class=\"cn('flex flex-col gap-2 p-2', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
60
+ "type": "registry:ui",
61
+ "target": "components/ui/sidebar/SidebarFooter.vue"
62
+ },
63
+ {
64
+ "path": "src/components/ui/sidebar/SidebarGroup.vue",
65
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<{\n class?: HTMLAttributes[\"class\"]\n}>()\n</script>\n\n<template>\n <div\n data-slot=\"sidebar-group\"\n data-sidebar=\"group\"\n :class=\"cn('relative flex w-full min-w-0 flex-col p-2', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
66
+ "type": "registry:ui",
67
+ "target": "components/ui/sidebar/SidebarGroup.vue"
68
+ },
69
+ {
70
+ "path": "src/components/ui/sidebar/SidebarGroupContent.vue",
71
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<{\n class?: HTMLAttributes[\"class\"]\n}>()\n</script>\n\n<template>\n <div\n data-slot=\"sidebar-group-content\"\n data-sidebar=\"group-content\"\n :class=\"cn('w-full text-sm', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
72
+ "type": "registry:ui",
73
+ "target": "components/ui/sidebar/SidebarGroupContent.vue"
74
+ },
75
+ {
76
+ "path": "src/components/ui/sidebar/SidebarGroupLabel.vue",
77
+ "content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { Primitive } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = withDefaults(defineProps<PrimitiveProps & {\n class?: HTMLAttributes[\"class\"]\n}>(), {\n as: \"div\",\n})\n</script>\n\n<template>\n <Primitive\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n :as=\"props.as\"\n :as-child=\"props.asChild\"\n :class=\"\n cn(\n 'flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-muted-foreground outline-none transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 focus-visible:ring-ring [&>svg]:size-4 [&>svg]:shrink-0',\n 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',\n props.class,\n )\n \"\n >\n <slot />\n </Primitive>\n</template>\n",
78
+ "type": "registry:ui",
79
+ "target": "components/ui/sidebar/SidebarGroupLabel.vue"
80
+ },
81
+ {
82
+ "path": "src/components/ui/sidebar/SidebarGroupAction.vue",
83
+ "content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { Primitive } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = withDefaults(defineProps<PrimitiveProps & {\n class?: HTMLAttributes[\"class\"]\n}>(), {\n as: \"button\",\n})\n</script>\n\n<template>\n <Primitive\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n :as=\"props.as\"\n :as-child=\"props.asChild\"\n :class=\"\n cn(\n 'absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-muted-foreground outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:ring-2 focus-visible:ring-ring [&>svg]:size-4 [&>svg]:shrink-0',\n 'after:absolute after:-inset-2 md:after:hidden',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\n \"\n >\n <slot />\n </Primitive>\n</template>\n",
84
+ "type": "registry:ui",
85
+ "target": "components/ui/sidebar/SidebarGroupAction.vue"
86
+ },
87
+ {
88
+ "path": "src/components/ui/sidebar/SidebarMenu.vue",
89
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<{\n class?: HTMLAttributes[\"class\"]\n}>()\n</script>\n\n<template>\n <ul\n data-slot=\"sidebar-menu\"\n data-sidebar=\"menu\"\n :class=\"cn('flex w-full min-w-0 flex-col gap-1', props.class)\"\n >\n <slot />\n </ul>\n</template>\n",
90
+ "type": "registry:ui",
91
+ "target": "components/ui/sidebar/SidebarMenu.vue"
92
+ },
93
+ {
94
+ "path": "src/components/ui/sidebar/SidebarMenuItem.vue",
95
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<{\n class?: HTMLAttributes[\"class\"]\n}>()\n</script>\n\n<template>\n <li\n data-slot=\"sidebar-menu-item\"\n data-sidebar=\"menu-item\"\n :class=\"cn('group/menu-item relative', props.class)\"\n >\n <slot />\n </li>\n</template>\n",
96
+ "type": "registry:ui",
97
+ "target": "components/ui/sidebar/SidebarMenuItem.vue"
98
+ },
99
+ {
100
+ "path": "src/components/ui/sidebar/SidebarMenuButton.vue",
101
+ "content": "<script setup lang=\"ts\">\nimport { computed } from \"vue\"\nimport { reactiveOmit } from \"@vueuse/core\"\nimport SidebarMenuButtonChild, {\n type SidebarMenuButtonProps,\n} from \"./SidebarMenuButtonChild.vue\"\nimport { useOptionalSidebar } from \"./context\"\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<SidebarMenuButtonProps & {\n tooltip?: string\n}>(), {\n as: \"button\",\n size: \"default\",\n variant: \"default\",\n})\n\nconst sidebar = useOptionalSidebar()\nconst delegatedProps = reactiveOmit(props, \"tooltip\")\nconst tooltipTitle = computed(() =>\n props.tooltip && sidebar?.state.value === \"collapsed\" && !sidebar?.isMobile.value\n ? props.tooltip\n : undefined,\n)\n</script>\n\n<template>\n <SidebarMenuButtonChild\n v-bind=\"{ ...delegatedProps, ...$attrs }\"\n :title=\"tooltipTitle\"\n >\n <slot />\n </SidebarMenuButtonChild>\n</template>\n",
102
+ "type": "registry:ui",
103
+ "target": "components/ui/sidebar/SidebarMenuButton.vue"
104
+ },
105
+ {
106
+ "path": "src/components/ui/sidebar/SidebarMenuButtonChild.vue",
107
+ "content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { Primitive } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\nimport {\n sidebarMenuButtonVariants,\n type SidebarMenuButtonVariants,\n} from \"./variants\"\n\nexport interface SidebarMenuButtonProps extends PrimitiveProps {\n class?: HTMLAttributes[\"class\"]\n isActive?: boolean\n size?: SidebarMenuButtonVariants[\"size\"]\n variant?: SidebarMenuButtonVariants[\"variant\"]\n}\n\nconst props = withDefaults(defineProps<SidebarMenuButtonProps>(), {\n as: \"button\",\n size: \"default\",\n variant: \"default\",\n})\n</script>\n\n<template>\n <Primitive\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n :data-active=\"props.isActive ? 'true' : undefined\"\n :data-size=\"props.size\"\n :as=\"props.as\"\n :as-child=\"props.asChild\"\n :class=\"cn(sidebarMenuButtonVariants({ size: props.size, variant: props.variant }), props.class)\"\n v-bind=\"$attrs\"\n >\n <slot />\n </Primitive>\n</template>\n",
108
+ "type": "registry:ui",
109
+ "target": "components/ui/sidebar/SidebarMenuButtonChild.vue"
110
+ },
111
+ {
112
+ "path": "src/components/ui/sidebar/SidebarMenuAction.vue",
113
+ "content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { Primitive } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = withDefaults(defineProps<PrimitiveProps & {\n class?: HTMLAttributes[\"class\"]\n showOnHover?: boolean\n}>(), {\n as: \"button\",\n})\n</script>\n\n<template>\n <Primitive\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n :as=\"props.as\"\n :as-child=\"props.asChild\"\n :class=\"\n cn(\n 'absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-muted-foreground outline-none transition-[color,opacity] hover:bg-accent hover:text-accent-foreground focus-visible:ring-2 focus-visible:ring-ring peer-hover/menu-button:text-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0',\n 'after:absolute after:-inset-2 md:after:hidden',\n 'peer-data-[size=sm]/menu-button:top-1 peer-data-[size=lg]/menu-button:top-3',\n 'group-data-[collapsible=icon]:hidden',\n props.showOnHover && 'opacity-100 md:opacity-0 group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-[active=true]/menu-button:opacity-100',\n props.class,\n )\n \"\n >\n <slot />\n </Primitive>\n</template>\n",
114
+ "type": "registry:ui",
115
+ "target": "components/ui/sidebar/SidebarMenuAction.vue"
116
+ },
117
+ {
118
+ "path": "src/components/ui/sidebar/SidebarMenuBadge.vue",
119
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<{\n class?: HTMLAttributes[\"class\"]\n}>()\n</script>\n\n<template>\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n :class=\"\n cn(\n 'pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-muted-foreground peer-hover/menu-button:text-accent-foreground peer-data-[active=true]/menu-button:text-accent-foreground',\n 'peer-data-[size=sm]/menu-button:top-1 peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-3',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\n \"\n >\n <slot />\n </div>\n</template>\n",
120
+ "type": "registry:ui",
121
+ "target": "components/ui/sidebar/SidebarMenuBadge.vue"
122
+ },
123
+ {
124
+ "path": "src/components/ui/sidebar/SidebarMenuSub.vue",
125
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<{\n class?: HTMLAttributes[\"class\"]\n}>()\n</script>\n\n<template>\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n :class=\"cn('mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5 group-data-[collapsible=icon]:hidden', props.class)\"\n >\n <slot />\n </ul>\n</template>\n",
126
+ "type": "registry:ui",
127
+ "target": "components/ui/sidebar/SidebarMenuSub.vue"
128
+ },
129
+ {
130
+ "path": "src/components/ui/sidebar/SidebarMenuSubItem.vue",
131
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<{\n class?: HTMLAttributes[\"class\"]\n}>()\n</script>\n\n<template>\n <li\n data-slot=\"sidebar-menu-sub-item\"\n data-sidebar=\"menu-sub-item\"\n :class=\"cn('group/menu-sub-item relative', props.class)\"\n >\n <slot />\n </li>\n</template>\n",
132
+ "type": "registry:ui",
133
+ "target": "components/ui/sidebar/SidebarMenuSubItem.vue"
134
+ },
135
+ {
136
+ "path": "src/components/ui/sidebar/SidebarMenuSubButton.vue",
137
+ "content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { Primitive } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = withDefaults(defineProps<PrimitiveProps & {\n class?: HTMLAttributes[\"class\"]\n isActive?: boolean\n size?: \"md\" | \"sm\"\n}>(), {\n as: \"a\",\n size: \"md\",\n})\n</script>\n\n<template>\n <Primitive\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n :as=\"props.as\"\n :as-child=\"props.asChild\"\n :data-active=\"props.isActive ? 'true' : undefined\"\n :data-size=\"props.size\"\n :class=\"\n cn(\n 'flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-muted-foreground outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:ring-2 focus-visible:ring-ring active:bg-accent active:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-accent data-[active=true]:text-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',\n props.size === 'sm' ? 'text-xs' : 'text-sm',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\n \"\n >\n <slot />\n </Primitive>\n</template>\n",
138
+ "type": "registry:ui",
139
+ "target": "components/ui/sidebar/SidebarMenuSubButton.vue"
140
+ },
141
+ {
142
+ "path": "src/components/ui/sidebar/SidebarInput.vue",
143
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = defineProps<{\n class?: HTMLAttributes[\"class\"]\n}>()\n</script>\n\n<template>\n <input\n data-slot=\"sidebar-input\"\n data-sidebar=\"input\"\n :class=\"\n cn(\n 'flex h-8 w-full min-w-0 rounded-md border border-input bg-background px-2.5 py-1 text-sm text-foreground shadow-none outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50',\n props.class,\n )\n \"\n v-bind=\"$attrs\"\n >\n</template>\n",
144
+ "type": "registry:ui",
145
+ "target": "components/ui/sidebar/SidebarInput.vue"
146
+ },
147
+ {
148
+ "path": "src/components/ui/sidebar/SidebarSeparator.vue",
149
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\nimport { Separator } from \"../separator\"\n\nconst props = defineProps<{\n class?: HTMLAttributes[\"class\"]\n}>()\n</script>\n\n<template>\n <Separator\n data-slot=\"sidebar-separator\"\n data-sidebar=\"separator\"\n decorative\n :class=\"cn('mx-2 w-auto', props.class)\"\n />\n</template>\n",
150
+ "type": "registry:ui",
151
+ "target": "components/ui/sidebar/SidebarSeparator.vue"
152
+ },
153
+ {
154
+ "path": "src/components/ui/sidebar/context.ts",
155
+ "content": "import type { ComputedRef, InjectionKey, Ref } from \"vue\"\nimport { inject, provide } from \"vue\"\nimport type { SidebarState } from \"./types\"\n\nexport const SIDEBAR_KEYBOARD_SHORTCUT = \"b\"\nexport const SIDEBAR_STORAGE_KEY = \"sidebar_state\"\nexport const SIDEBAR_WIDTH = \"16rem\"\nexport const SIDEBAR_WIDTH_ICON = \"3.25rem\"\nexport const SIDEBAR_WIDTH_MOBILE = \"18rem\"\n\nexport interface SidebarContext {\n isMobile: Ref<boolean>\n open: Ref<boolean>\n openMobile: Ref<boolean>\n setOpen: (value: boolean) => void\n setOpenMobile: (value: boolean) => void\n state: ComputedRef<SidebarState>\n toggleSidebar: () => void\n}\n\nconst sidebarContextKey: InjectionKey<SidebarContext> = Symbol(\"SidebarContext\")\n\nexport function provideSidebarContext(context: SidebarContext) {\n provide(sidebarContextKey, context)\n}\n\nexport function useOptionalSidebar() {\n return inject(sidebarContextKey, null)\n}\n\nexport function useSidebar() {\n const context = useOptionalSidebar()\n\n if (!context) {\n throw new Error(\"Sidebar components must be used within a SidebarProvider.\")\n }\n\n return context\n}\n",
156
+ "type": "registry:ui",
157
+ "target": "components/ui/sidebar/context.ts"
158
+ },
159
+ {
160
+ "path": "src/components/ui/sidebar/types.ts",
161
+ "content": "import type { HTMLAttributes } from \"vue\"\n\nexport type SidebarCollapsible = \"offcanvas\" | \"icon\" | \"none\"\nexport type SidebarSide = \"left\" | \"right\"\nexport type SidebarState = \"collapsed\" | \"expanded\"\nexport type SidebarVariant = \"floating\" | \"inset\" | \"sidebar\"\n\nexport interface SidebarProps {\n class?: HTMLAttributes[\"class\"]\n collapsible?: SidebarCollapsible\n side?: SidebarSide\n variant?: SidebarVariant\n}\n",
162
+ "type": "registry:ui",
163
+ "target": "components/ui/sidebar/types.ts"
164
+ },
165
+ {
166
+ "path": "src/components/ui/sidebar/variants.ts",
167
+ "content": "import { cva, type VariantProps } from \"class-variance-authority\"\n\nexport const sidebarMenuButtonVariants = cva(\n \"peer/menu-button flex w-full min-w-0 items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-ring transition-[background-color,color,width,height,padding] hover:bg-accent hover:text-accent-foreground focus-visible:ring-2 active:bg-accent active:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-accent data-[active=true]:font-medium data-[active=true]:text-accent-foreground group-data-[collapsible=icon]:size-9 group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:p-0 group-data-[collapsible=icon]:[&>span:last-child]:hidden [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\n {\n variants: {\n size: {\n default: \"h-8 text-sm\",\n lg: \"h-11 text-sm group-data-[collapsible=icon]:p-0\",\n sm: \"h-7 text-xs\",\n },\n variant: {\n default: \"hover:bg-accent hover:text-accent-foreground\",\n outline:\n \"bg-background shadow-[0_0_0_1px_var(--border)] hover:bg-accent hover:text-accent-foreground hover:shadow-[0_0_0_1px_var(--accent)]\",\n },\n },\n defaultVariants: {\n size: \"default\",\n variant: \"default\",\n },\n },\n)\n\nexport type SidebarMenuButtonVariants = VariantProps<typeof sidebarMenuButtonVariants>\n",
168
+ "type": "registry:ui",
169
+ "target": "components/ui/sidebar/variants.ts"
170
+ },
171
+ {
172
+ "path": "src/components/ui/sidebar/index.ts",
173
+ "content": "export { default as Sidebar } from \"./Sidebar.vue\"\nexport { default as SidebarContent } from \"./SidebarContent.vue\"\nexport { default as SidebarFooter } from \"./SidebarFooter.vue\"\nexport { default as SidebarGroup } from \"./SidebarGroup.vue\"\nexport { default as SidebarGroupAction } from \"./SidebarGroupAction.vue\"\nexport { default as SidebarGroupContent } from \"./SidebarGroupContent.vue\"\nexport { default as SidebarGroupLabel } from \"./SidebarGroupLabel.vue\"\nexport { default as SidebarHeader } from \"./SidebarHeader.vue\"\nexport { default as SidebarInput } from \"./SidebarInput.vue\"\nexport { default as SidebarInset } from \"./SidebarInset.vue\"\nexport { default as SidebarMenu } from \"./SidebarMenu.vue\"\nexport { default as SidebarMenuAction } from \"./SidebarMenuAction.vue\"\nexport { default as SidebarMenuBadge } from \"./SidebarMenuBadge.vue\"\nexport { default as SidebarMenuButton } from \"./SidebarMenuButton.vue\"\nexport { default as SidebarMenuButtonChild } from \"./SidebarMenuButtonChild.vue\"\nexport { default as SidebarMenuItem } from \"./SidebarMenuItem.vue\"\nexport { default as SidebarMenuSub } from \"./SidebarMenuSub.vue\"\nexport { default as SidebarMenuSubButton } from \"./SidebarMenuSubButton.vue\"\nexport { default as SidebarMenuSubItem } from \"./SidebarMenuSubItem.vue\"\nexport { default as SidebarProvider } from \"./SidebarProvider.vue\"\nexport { default as SidebarRail } from \"./SidebarRail.vue\"\nexport { default as SidebarSeparator } from \"./SidebarSeparator.vue\"\nexport { default as SidebarTrigger } from \"./SidebarTrigger.vue\"\nexport {\n SIDEBAR_KEYBOARD_SHORTCUT,\n SIDEBAR_STORAGE_KEY,\n SIDEBAR_WIDTH,\n SIDEBAR_WIDTH_ICON,\n SIDEBAR_WIDTH_MOBILE,\n useOptionalSidebar,\n useSidebar,\n} from \"./context\"\nexport {\n sidebarMenuButtonVariants,\n type SidebarMenuButtonVariants,\n} from \"./variants\"\nexport type {\n SidebarCollapsible,\n SidebarProps,\n SidebarSide,\n SidebarState,\n SidebarVariant,\n} from \"./types\"\n",
174
+ "type": "registry:ui",
175
+ "target": "components/ui/sidebar/index.ts"
176
+ },
177
+ {
178
+ "path": "src/components/ui/button/Button.vue",
179
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { Primitive, type PrimitiveProps } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\nimport { buttonVariants, type ButtonVariants } from \"./variants\"\n\ninterface ButtonProps extends PrimitiveProps {\n variant?: ButtonVariants[\"variant\"]\n size?: ButtonVariants[\"size\"]\n class?: HTMLAttributes[\"class\"]\n}\n\nconst props = withDefaults(defineProps<ButtonProps>(), {\n as: \"button\",\n})\n</script>\n\n<template>\n <Primitive\n data-slot=\"button\"\n :as=\"props.as\"\n :as-child=\"props.asChild\"\n :class=\"cn(buttonVariants({ variant: props.variant, size: props.size }), props.class)\"\n >\n <slot />\n </Primitive>\n</template>\n",
180
+ "type": "registry:ui",
181
+ "target": "components/ui/button/Button.vue"
182
+ },
183
+ {
184
+ "path": "src/components/ui/button/variants.ts",
185
+ "content": "import { cva, type VariantProps } from \"class-variance-authority\"\n\nexport const buttonVariants = cva(\n \"inline-flex shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium outline-none transition-[background-color,border-color,color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/30\",\n outline:\n \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n secondary: \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-6\",\n icon: \"size-9\",\n \"icon-sm\": \"size-8\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n)\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>\n",
186
+ "type": "registry:ui",
187
+ "target": "components/ui/button/variants.ts"
188
+ },
189
+ {
190
+ "path": "src/components/ui/button/index.ts",
191
+ "content": "export { default as Button } from \"./Button.vue\"\nexport { buttonVariants, type ButtonVariants } from \"./variants\"\n",
192
+ "type": "registry:ui",
193
+ "target": "components/ui/button/index.ts"
194
+ },
195
+ {
196
+ "path": "src/components/ui/separator/Separator.vue",
197
+ "content": "<script setup lang=\"ts\">\nimport { computed } from \"vue\"\nimport { cn } from \"@/lib/utils\"\nimport type { SeparatorProps } from \"./types\"\n\nconst props = withDefaults(defineProps<SeparatorProps>(), {\n decorative: true,\n orientation: \"horizontal\",\n})\n\nconst separatorRole = computed(() => props.decorative ? undefined : \"separator\")\nconst ariaOrientation = computed(() =>\n props.decorative ? undefined : props.orientation,\n)\n</script>\n\n<template>\n <div\n data-slot=\"separator\"\n :data-orientation=\"props.orientation\"\n :role=\"separatorRole\"\n :aria-orientation=\"ariaOrientation\"\n :class=\"\n cn(\n 'bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px',\n props.class,\n )\n \"\n />\n</template>\n",
198
+ "type": "registry:ui",
199
+ "target": "components/ui/separator/Separator.vue"
200
+ },
201
+ {
202
+ "path": "src/components/ui/separator/types.ts",
203
+ "content": "import type { HTMLAttributes } from \"vue\"\n\nexport type SeparatorOrientation = \"horizontal\" | \"vertical\"\n\nexport interface SeparatorProps {\n class?: HTMLAttributes[\"class\"]\n decorative?: boolean\n orientation?: SeparatorOrientation\n}\n",
204
+ "type": "registry:ui",
205
+ "target": "components/ui/separator/types.ts"
206
+ },
207
+ {
208
+ "path": "src/components/ui/separator/index.ts",
209
+ "content": "export { default as Separator } from \"./Separator.vue\"\nexport type {\n SeparatorOrientation,\n SeparatorProps,\n} from \"./types\"\n",
210
+ "type": "registry:ui",
211
+ "target": "components/ui/separator/index.ts"
212
+ },
213
+ {
214
+ "path": "src/lib/utils.ts",
215
+ "content": "import { type ClassValue, clsx } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n",
216
+ "type": "registry:lib",
217
+ "target": "lib/utils.ts"
218
+ }
219
+ ],
220
+ "type": "registry:ui"
221
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "$schema": "https://shadcn-vue.com/schema/registry-item.json",
3
+ "name": "skeleton",
4
+ "title": "Skeleton",
5
+ "description": "A placeholder block for loading surfaces with shape variants, optional animation, and accessible status labeling.",
6
+ "dependencies": [
7
+ "clsx",
8
+ "tailwind-merge"
9
+ ],
10
+ "files": [
11
+ {
12
+ "path": "src/components/ui/skeleton/Skeleton.vue",
13
+ "content": "<script setup lang=\"ts\">\nimport { computed } from \"vue\"\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\n\nexport type SkeletonVariant = \"block\" | \"text\" | \"circle\"\n\nexport interface SkeletonProps {\n animated?: boolean\n as?: string\n class?: HTMLAttributes[\"class\"]\n decorative?: boolean\n label?: string\n variant?: SkeletonVariant\n}\n\nconst props = withDefaults(defineProps<SkeletonProps>(), {\n animated: true,\n as: \"div\",\n decorative: true,\n label: \"Loading\",\n variant: \"block\",\n})\n\nconst variantClass = computed(() => {\n if (props.variant === \"circle\") return \"size-10 rounded-full\"\n if (props.variant === \"text\") return \"h-4 w-full rounded\"\n\n return \"h-24 w-full rounded-md\"\n})\n</script>\n\n<template>\n <component\n :is=\"props.as\"\n data-slot=\"skeleton\"\n :data-animated=\"props.animated ? 'true' : 'false'\"\n :data-variant=\"props.variant\"\n :aria-hidden=\"props.decorative ? 'true' : undefined\"\n :aria-label=\"props.decorative ? undefined : props.label\"\n :class=\"\n cn(\n 'block shrink-0 bg-muted',\n variantClass,\n props.animated && 'animate-pulse',\n props.class,\n )\n \"\n :role=\"props.decorative ? undefined : 'status'\"\n >\n <span v-if=\"!props.decorative\" class=\"sr-only\">{{ props.label }}</span>\n </component>\n</template>\n",
14
+ "type": "registry:ui",
15
+ "target": "components/ui/skeleton/Skeleton.vue"
16
+ },
17
+ {
18
+ "path": "src/components/ui/skeleton/index.ts",
19
+ "content": "export { default as Skeleton } from \"./Skeleton.vue\"\nexport type {\n SkeletonProps,\n SkeletonVariant,\n} from \"./Skeleton.vue\"\n",
20
+ "type": "registry:ui",
21
+ "target": "components/ui/skeleton/index.ts"
22
+ },
23
+ {
24
+ "path": "src/lib/utils.ts",
25
+ "content": "import { type ClassValue, clsx } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n",
26
+ "type": "registry:lib",
27
+ "target": "lib/utils.ts"
28
+ }
29
+ ],
30
+ "type": "registry:ui"
31
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "$schema": "https://shadcn-vue.com/schema/registry-item.json",
3
+ "name": "sonner",
4
+ "title": "Sonner",
5
+ "description": "An opinionated toast component for Vue applications.",
6
+ "dependencies": [
7
+ "@lucide/vue",
8
+ "clsx",
9
+ "tailwind-merge",
10
+ "vue-sonner"
11
+ ],
12
+ "files": [
13
+ {
14
+ "path": "src/components/ui/sonner/Sonner.vue",
15
+ "content": "<script lang=\"ts\" setup>\nimport type { ToasterProps } from \"vue-sonner\"\nimport { CircleCheckIcon, InfoIcon, Loader2Icon, OctagonXIcon, TriangleAlertIcon, XIcon } from \"@lucide/vue\"\nimport { Toaster as Sonner } from \"vue-sonner\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = withDefaults(defineProps<ToasterProps>(), {\n closeButtonPosition: \"top-right\",\n})\n</script>\n\n<template>\n <Sonner\n :class=\"cn('toaster group', props.class)\"\n :style=\"{\n '--normal-bg': 'var(--popover)',\n '--normal-text': 'var(--popover-foreground)',\n '--normal-border': 'var(--border)',\n '--border-radius': 'var(--radius)',\n }\"\n v-bind=\"props\"\n >\n <template #success-icon>\n <CircleCheckIcon class=\"size-4\" />\n </template>\n <template #info-icon>\n <InfoIcon class=\"size-4\" />\n </template>\n <template #warning-icon>\n <TriangleAlertIcon class=\"size-4\" />\n </template>\n <template #error-icon>\n <OctagonXIcon class=\"size-4\" />\n </template>\n <template #loading-icon>\n <div>\n <Loader2Icon class=\"size-4 animate-spin\" />\n </div>\n </template>\n <template #close-icon>\n <XIcon class=\"size-4\" />\n </template>\n </Sonner>\n</template>\n\n<style>\n[data-sonner-toaster] [data-close-button-position=\"top-right\"] {\n --toast-close-button-right: 0.625rem;\n --toast-close-button-top: 0.625rem;\n --toast-close-button-transform: none;\n}\n\n[data-sonner-toast][data-styled=\"true\"]:has([data-close-button]) {\n padding-right: 2.75rem;\n}\n\n[data-sonner-toast][data-styled=\"true\"] [data-close-button] {\n background: transparent;\n border-color: transparent;\n border-radius: 0;\n color: currentColor;\n}\n\n[data-sonner-toast][data-styled=\"true\"]:hover [data-close-button]:hover,\n[data-sonner-toaster][data-sonner-theme=\"dark\"] [data-sonner-toast] [data-close-button]:hover {\n background: transparent;\n border-color: transparent;\n}\n</style>\n",
16
+ "type": "registry:ui",
17
+ "target": "components/ui/sonner/Sonner.vue"
18
+ },
19
+ {
20
+ "path": "src/components/ui/sonner/index.ts",
21
+ "content": "export { default as Toaster } from \"./Sonner.vue\"\nexport {\n toast,\n useVueSonner,\n type Action,\n type ExternalToast,\n type PromiseIExtendedResult,\n type ToastClasses,\n type ToastT,\n type ToastToDismiss,\n type ToasterProps,\n} from \"vue-sonner\"\n",
22
+ "type": "registry:ui",
23
+ "target": "components/ui/sonner/index.ts"
24
+ },
25
+ {
26
+ "path": "src/lib/utils.ts",
27
+ "content": "import { type ClassValue, clsx } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n",
28
+ "type": "registry:lib",
29
+ "target": "lib/utils.ts"
30
+ }
31
+ ],
32
+ "type": "registry:ui"
33
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "$schema": "https://shadcn-vue.com/schema/registry-item.json",
3
+ "name": "spinner",
4
+ "title": "Spinner",
5
+ "description": "A compact loading indicator for buttons and status displays.",
6
+ "dependencies": [
7
+ "clsx",
8
+ "tailwind-merge"
9
+ ],
10
+ "files": [
11
+ {
12
+ "path": "src/components/ui/spinner/Spinner.vue",
13
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = withDefaults(\n defineProps<{\n class?: HTMLAttributes[\"class\"]\n label?: string\n decorative?: boolean\n }>(),\n {\n label: \"Loading\",\n decorative: false,\n },\n)\n</script>\n\n<template>\n <span\n data-slot=\"spinner\"\n :aria-hidden=\"props.decorative ? 'true' : undefined\"\n :aria-label=\"props.decorative ? undefined : props.label\"\n :class=\"\n cn(\n 'inline-block size-4 shrink-0 animate-spin rounded-full border-2 border-current border-r-transparent align-[-0.125em]',\n props.class,\n )\n \"\n :role=\"props.decorative ? undefined : 'status'\"\n >\n <span v-if=\"!props.decorative\" class=\"sr-only\">{{ props.label }}</span>\n </span>\n</template>\n",
14
+ "type": "registry:ui",
15
+ "target": "components/ui/spinner/Spinner.vue"
16
+ },
17
+ {
18
+ "path": "src/components/ui/spinner/index.ts",
19
+ "content": "export { default as Spinner } from \"./Spinner.vue\"\n",
20
+ "type": "registry:ui",
21
+ "target": "components/ui/spinner/index.ts"
22
+ },
23
+ {
24
+ "path": "src/lib/utils.ts",
25
+ "content": "import { type ClassValue, clsx } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n",
26
+ "type": "registry:lib",
27
+ "target": "lib/utils.ts"
28
+ }
29
+ ],
30
+ "type": "registry:ui"
31
+ }