create-nala 3.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 (316) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +58 -0
  3. package/dist/index.js +227 -0
  4. package/package.json +48 -0
  5. package/template/.env.example +45 -0
  6. package/template/_gitignore +33 -0
  7. package/template/components.json +24 -0
  8. package/template/index.html +30 -0
  9. package/template/package.json +51 -0
  10. package/template/public/favicon.svg +15 -0
  11. package/template/public/icons.svg +24 -0
  12. package/template/public/img/avatar.webp +0 -0
  13. package/template/public/screenshot.png +0 -0
  14. package/template/src/App.vue +15 -0
  15. package/template/src/auto-imports.d.ts +691 -0
  16. package/template/src/components/AppLogo.vue +159 -0
  17. package/template/src/components/EmptyState.vue +60 -0
  18. package/template/src/components/PageHeader.vue +60 -0
  19. package/template/src/components/layout/AppNavbar.vue +159 -0
  20. package/template/src/components/layout/AppSidebar.vue +74 -0
  21. package/template/src/components/layout/CommandSearchDialog.vue +120 -0
  22. package/template/src/components/ui/accordion/Accordion.vue +15 -0
  23. package/template/src/components/ui/accordion/AccordionContent.vue +20 -0
  24. package/template/src/components/ui/accordion/AccordionItem.vue +20 -0
  25. package/template/src/components/ui/accordion/AccordionTrigger.vue +34 -0
  26. package/template/src/components/ui/accordion/index.ts +4 -0
  27. package/template/src/components/ui/alert/Alert.vue +21 -0
  28. package/template/src/components/ui/alert/AlertDescription.vue +17 -0
  29. package/template/src/components/ui/alert/AlertTitle.vue +17 -0
  30. package/template/src/components/ui/alert/index.ts +30 -0
  31. package/template/src/components/ui/alert-dialog/AlertDialog.vue +15 -0
  32. package/template/src/components/ui/alert-dialog/AlertDialogAction.vue +18 -0
  33. package/template/src/components/ui/alert-dialog/AlertDialogCancel.vue +25 -0
  34. package/template/src/components/ui/alert-dialog/AlertDialogContent.vue +44 -0
  35. package/template/src/components/ui/alert-dialog/AlertDialogDescription.vue +23 -0
  36. package/template/src/components/ui/alert-dialog/AlertDialogFooter.vue +22 -0
  37. package/template/src/components/ui/alert-dialog/AlertDialogHeader.vue +17 -0
  38. package/template/src/components/ui/alert-dialog/AlertDialogTitle.vue +21 -0
  39. package/template/src/components/ui/alert-dialog/AlertDialogTrigger.vue +12 -0
  40. package/template/src/components/ui/alert-dialog/index.ts +9 -0
  41. package/template/src/components/ui/avatar/Avatar.vue +50 -0
  42. package/template/src/components/ui/avatar/AvatarFallback.vue +21 -0
  43. package/template/src/components/ui/avatar/AvatarGroup.vue +69 -0
  44. package/template/src/components/ui/avatar/AvatarImage.vue +16 -0
  45. package/template/src/components/ui/avatar/index.ts +4 -0
  46. package/template/src/components/ui/badge/Badge.vue +40 -0
  47. package/template/src/components/ui/badge/index.ts +45 -0
  48. package/template/src/components/ui/breadcrumb/Breadcrumb.vue +17 -0
  49. package/template/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue +23 -0
  50. package/template/src/components/ui/breadcrumb/BreadcrumbItem.vue +17 -0
  51. package/template/src/components/ui/breadcrumb/BreadcrumbLink.vue +21 -0
  52. package/template/src/components/ui/breadcrumb/BreadcrumbList.vue +17 -0
  53. package/template/src/components/ui/breadcrumb/BreadcrumbPage.vue +20 -0
  54. package/template/src/components/ui/breadcrumb/BreadcrumbSeparator.vue +22 -0
  55. package/template/src/components/ui/breadcrumb/index.ts +7 -0
  56. package/template/src/components/ui/button/Button.spec.ts +46 -0
  57. package/template/src/components/ui/button/Button.vue +31 -0
  58. package/template/src/components/ui/button/index.ts +41 -0
  59. package/template/src/components/ui/calendar/Calendar.vue +106 -0
  60. package/template/src/components/ui/calendar/index.ts +1 -0
  61. package/template/src/components/ui/card/Card.vue +29 -0
  62. package/template/src/components/ui/card/CardAction.vue +17 -0
  63. package/template/src/components/ui/card/CardContent.vue +17 -0
  64. package/template/src/components/ui/card/CardDescription.vue +17 -0
  65. package/template/src/components/ui/card/CardFooter.vue +17 -0
  66. package/template/src/components/ui/card/CardHeader.vue +29 -0
  67. package/template/src/components/ui/card/CardTitle.vue +17 -0
  68. package/template/src/components/ui/card/index.ts +7 -0
  69. package/template/src/components/ui/chart/AreaChart.vue +143 -0
  70. package/template/src/components/ui/chart/BarChart.vue +142 -0
  71. package/template/src/components/ui/chart/DonutChart.vue +75 -0
  72. package/template/src/components/ui/chart/LineChart.vue +132 -0
  73. package/template/src/components/ui/chart/index.ts +4 -0
  74. package/template/src/components/ui/checkbox/Checkbox.vue +57 -0
  75. package/template/src/components/ui/checkbox/index.ts +1 -0
  76. package/template/src/components/ui/collapsible/Collapsible.vue +15 -0
  77. package/template/src/components/ui/collapsible/CollapsibleContent.vue +18 -0
  78. package/template/src/components/ui/collapsible/CollapsibleTrigger.vue +12 -0
  79. package/template/src/components/ui/collapsible/index.ts +3 -0
  80. package/template/src/components/ui/command/Command.vue +88 -0
  81. package/template/src/components/ui/command/CommandDialog.vue +31 -0
  82. package/template/src/components/ui/command/CommandEmpty.vue +27 -0
  83. package/template/src/components/ui/command/CommandGroup.vue +45 -0
  84. package/template/src/components/ui/command/CommandInput.vue +39 -0
  85. package/template/src/components/ui/command/CommandItem.vue +76 -0
  86. package/template/src/components/ui/command/CommandList.vue +25 -0
  87. package/template/src/components/ui/command/CommandSeparator.vue +21 -0
  88. package/template/src/components/ui/command/CommandShortcut.vue +17 -0
  89. package/template/src/components/ui/command/index.ts +25 -0
  90. package/template/src/components/ui/context-menu/ContextMenu.vue +15 -0
  91. package/template/src/components/ui/context-menu/ContextMenuCheckboxItem.vue +36 -0
  92. package/template/src/components/ui/context-menu/ContextMenuContent.vue +33 -0
  93. package/template/src/components/ui/context-menu/ContextMenuGroup.vue +12 -0
  94. package/template/src/components/ui/context-menu/ContextMenuItem.vue +36 -0
  95. package/template/src/components/ui/context-menu/ContextMenuLabel.vue +25 -0
  96. package/template/src/components/ui/context-menu/ContextMenuRadioGroup.vue +18 -0
  97. package/template/src/components/ui/context-menu/ContextMenuRadioItem.vue +36 -0
  98. package/template/src/components/ui/context-menu/ContextMenuSeparator.vue +18 -0
  99. package/template/src/components/ui/context-menu/ContextMenuShortcut.vue +17 -0
  100. package/template/src/components/ui/context-menu/ContextMenuSub.vue +15 -0
  101. package/template/src/components/ui/context-menu/ContextMenuSubContent.vue +36 -0
  102. package/template/src/components/ui/context-menu/ContextMenuSubTrigger.vue +32 -0
  103. package/template/src/components/ui/context-menu/ContextMenuTrigger.vue +13 -0
  104. package/template/src/components/ui/context-menu/index.ts +14 -0
  105. package/template/src/components/ui/date-picker/DatePicker.vue +233 -0
  106. package/template/src/components/ui/date-picker/index.ts +1 -0
  107. package/template/src/components/ui/dialog/Dialog.vue +19 -0
  108. package/template/src/components/ui/dialog/DialogClose.vue +15 -0
  109. package/template/src/components/ui/dialog/DialogContent.vue +53 -0
  110. package/template/src/components/ui/dialog/DialogDescription.vue +23 -0
  111. package/template/src/components/ui/dialog/DialogFooter.vue +27 -0
  112. package/template/src/components/ui/dialog/DialogHeader.vue +17 -0
  113. package/template/src/components/ui/dialog/DialogOverlay.vue +21 -0
  114. package/template/src/components/ui/dialog/DialogScrollContent.vue +59 -0
  115. package/template/src/components/ui/dialog/DialogTitle.vue +23 -0
  116. package/template/src/components/ui/dialog/DialogTrigger.vue +15 -0
  117. package/template/src/components/ui/dialog/index.ts +10 -0
  118. package/template/src/components/ui/dropdown-menu/DropdownMenu.vue +19 -0
  119. package/template/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +39 -0
  120. package/template/src/components/ui/dropdown-menu/DropdownMenuContent.vue +41 -0
  121. package/template/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +15 -0
  122. package/template/src/components/ui/dropdown-menu/DropdownMenuItem.vue +31 -0
  123. package/template/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +23 -0
  124. package/template/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +21 -0
  125. package/template/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +40 -0
  126. package/template/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +23 -0
  127. package/template/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +17 -0
  128. package/template/src/components/ui/dropdown-menu/DropdownMenuSub.vue +18 -0
  129. package/template/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +27 -0
  130. package/template/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +31 -0
  131. package/template/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +17 -0
  132. package/template/src/components/ui/dropdown-menu/index.ts +16 -0
  133. package/template/src/components/ui/form/FormControl.vue +17 -0
  134. package/template/src/components/ui/form/FormDescription.vue +21 -0
  135. package/template/src/components/ui/form/FormItem.vue +23 -0
  136. package/template/src/components/ui/form/FormLabel.vue +25 -0
  137. package/template/src/components/ui/form/FormMessage.vue +23 -0
  138. package/template/src/components/ui/form/index.ts +7 -0
  139. package/template/src/components/ui/form/injectionKeys.ts +4 -0
  140. package/template/src/components/ui/form/useFormField.ts +30 -0
  141. package/template/src/components/ui/hover-card/HoverCard.vue +19 -0
  142. package/template/src/components/ui/hover-card/HoverCardContent.vue +43 -0
  143. package/template/src/components/ui/hover-card/HoverCardTrigger.vue +15 -0
  144. package/template/src/components/ui/hover-card/index.ts +3 -0
  145. package/template/src/components/ui/index.ts +47 -0
  146. package/template/src/components/ui/input/Input.vue +33 -0
  147. package/template/src/components/ui/input/InputAddon.vue +29 -0
  148. package/template/src/components/ui/input/InputGroup.vue +17 -0
  149. package/template/src/components/ui/input/InputIcon.vue +29 -0
  150. package/template/src/components/ui/input/index.ts +4 -0
  151. package/template/src/components/ui/kbd/Kbd.vue +30 -0
  152. package/template/src/components/ui/kbd/index.ts +1 -0
  153. package/template/src/components/ui/label/Label.vue +26 -0
  154. package/template/src/components/ui/label/index.ts +1 -0
  155. package/template/src/components/ui/loading-bar/LoadingBar.vue +41 -0
  156. package/template/src/components/ui/loading-bar/index.ts +2 -0
  157. package/template/src/components/ui/pagination/Pagination.vue +26 -0
  158. package/template/src/components/ui/pagination/PaginationContent.vue +22 -0
  159. package/template/src/components/ui/pagination/PaginationEllipsis.vue +25 -0
  160. package/template/src/components/ui/pagination/PaginationFirst.vue +33 -0
  161. package/template/src/components/ui/pagination/PaginationItem.vue +34 -0
  162. package/template/src/components/ui/pagination/PaginationLast.vue +33 -0
  163. package/template/src/components/ui/pagination/PaginationNext.vue +33 -0
  164. package/template/src/components/ui/pagination/PaginationPrevious.vue +33 -0
  165. package/template/src/components/ui/pagination/index.ts +8 -0
  166. package/template/src/components/ui/pin-input/PinInput.vue +28 -0
  167. package/template/src/components/ui/pin-input/PinInputGroup.vue +18 -0
  168. package/template/src/components/ui/pin-input/PinInputInput.vue +24 -0
  169. package/template/src/components/ui/pin-input/PinInputSeparator.vue +21 -0
  170. package/template/src/components/ui/pin-input/index.ts +4 -0
  171. package/template/src/components/ui/popover/Popover.vue +19 -0
  172. package/template/src/components/ui/popover/PopoverAnchor.vue +15 -0
  173. package/template/src/components/ui/popover/PopoverContent.vue +45 -0
  174. package/template/src/components/ui/popover/PopoverTrigger.vue +15 -0
  175. package/template/src/components/ui/popover/index.ts +4 -0
  176. package/template/src/components/ui/progress/Progress.vue +35 -0
  177. package/template/src/components/ui/progress/index.ts +1 -0
  178. package/template/src/components/ui/radio-group/RadioGroup.vue +23 -0
  179. package/template/src/components/ui/radio-group/RadioGroupItem.vue +30 -0
  180. package/template/src/components/ui/radio-group/index.ts +2 -0
  181. package/template/src/components/ui/scroll-area/ScrollArea.vue +40 -0
  182. package/template/src/components/ui/scroll-area/ScrollBar.vue +44 -0
  183. package/template/src/components/ui/scroll-area/index.ts +2 -0
  184. package/template/src/components/ui/select/Select.vue +19 -0
  185. package/template/src/components/ui/select/SelectContent.vue +51 -0
  186. package/template/src/components/ui/select/SelectGroup.vue +15 -0
  187. package/template/src/components/ui/select/SelectItem.vue +44 -0
  188. package/template/src/components/ui/select/SelectItemText.vue +15 -0
  189. package/template/src/components/ui/select/SelectLabel.vue +17 -0
  190. package/template/src/components/ui/select/SelectScrollDownButton.vue +26 -0
  191. package/template/src/components/ui/select/SelectScrollUpButton.vue +26 -0
  192. package/template/src/components/ui/select/SelectSeparator.vue +19 -0
  193. package/template/src/components/ui/select/SelectTrigger.vue +33 -0
  194. package/template/src/components/ui/select/SelectValue.vue +15 -0
  195. package/template/src/components/ui/select/index.ts +11 -0
  196. package/template/src/components/ui/separator/Separator.vue +29 -0
  197. package/template/src/components/ui/separator/index.ts +1 -0
  198. package/template/src/components/ui/sheet/Sheet.vue +19 -0
  199. package/template/src/components/ui/sheet/SheetClose.vue +15 -0
  200. package/template/src/components/ui/sheet/SheetContent.vue +62 -0
  201. package/template/src/components/ui/sheet/SheetDescription.vue +21 -0
  202. package/template/src/components/ui/sheet/SheetFooter.vue +16 -0
  203. package/template/src/components/ui/sheet/SheetHeader.vue +15 -0
  204. package/template/src/components/ui/sheet/SheetOverlay.vue +21 -0
  205. package/template/src/components/ui/sheet/SheetTitle.vue +21 -0
  206. package/template/src/components/ui/sheet/SheetTrigger.vue +15 -0
  207. package/template/src/components/ui/sheet/index.ts +8 -0
  208. package/template/src/components/ui/sidebar/Sidebar.vue +113 -0
  209. package/template/src/components/ui/sidebar/SidebarContent.vue +18 -0
  210. package/template/src/components/ui/sidebar/SidebarControl.vue +53 -0
  211. package/template/src/components/ui/sidebar/SidebarFooter.vue +18 -0
  212. package/template/src/components/ui/sidebar/SidebarGroup.vue +18 -0
  213. package/template/src/components/ui/sidebar/SidebarGroupAction.vue +27 -0
  214. package/template/src/components/ui/sidebar/SidebarGroupContent.vue +18 -0
  215. package/template/src/components/ui/sidebar/SidebarGroupLabel.vue +25 -0
  216. package/template/src/components/ui/sidebar/SidebarHeader.vue +18 -0
  217. package/template/src/components/ui/sidebar/SidebarInput.vue +22 -0
  218. package/template/src/components/ui/sidebar/SidebarInset.vue +21 -0
  219. package/template/src/components/ui/sidebar/SidebarMenu.vue +18 -0
  220. package/template/src/components/ui/sidebar/SidebarMenuAction.vue +35 -0
  221. package/template/src/components/ui/sidebar/SidebarMenuBadge.vue +26 -0
  222. package/template/src/components/ui/sidebar/SidebarMenuButton.vue +48 -0
  223. package/template/src/components/ui/sidebar/SidebarMenuButtonChild.vue +36 -0
  224. package/template/src/components/ui/sidebar/SidebarMenuItem.vue +18 -0
  225. package/template/src/components/ui/sidebar/SidebarMenuSkeleton.vue +35 -0
  226. package/template/src/components/ui/sidebar/SidebarMenuSub.vue +22 -0
  227. package/template/src/components/ui/sidebar/SidebarMenuSubButton.vue +36 -0
  228. package/template/src/components/ui/sidebar/SidebarMenuSubItem.vue +18 -0
  229. package/template/src/components/ui/sidebar/SidebarProvider.vue +136 -0
  230. package/template/src/components/ui/sidebar/SidebarRail.vue +33 -0
  231. package/template/src/components/ui/sidebar/SidebarSeparator.vue +19 -0
  232. package/template/src/components/ui/sidebar/SidebarTrigger.vue +27 -0
  233. package/template/src/components/ui/sidebar/index.ts +61 -0
  234. package/template/src/components/ui/sidebar/utils.ts +27 -0
  235. package/template/src/components/ui/skeleton/Skeleton.vue +17 -0
  236. package/template/src/components/ui/skeleton/index.ts +1 -0
  237. package/template/src/components/ui/slider/Slider.vue +42 -0
  238. package/template/src/components/ui/slider/index.ts +1 -0
  239. package/template/src/components/ui/sonner/Sonner.vue +42 -0
  240. package/template/src/components/ui/sonner/index.ts +2 -0
  241. package/template/src/components/ui/stepper/Stepper.vue +102 -0
  242. package/template/src/components/ui/stepper/index.ts +1 -0
  243. package/template/src/components/ui/switch/Switch.vue +38 -0
  244. package/template/src/components/ui/switch/index.ts +1 -0
  245. package/template/src/components/ui/table/Table.vue +16 -0
  246. package/template/src/components/ui/table/TableBody.vue +17 -0
  247. package/template/src/components/ui/table/TableCaption.vue +17 -0
  248. package/template/src/components/ui/table/TableCell.vue +22 -0
  249. package/template/src/components/ui/table/TableEmpty.vue +34 -0
  250. package/template/src/components/ui/table/TableFooter.vue +17 -0
  251. package/template/src/components/ui/table/TableHead.vue +17 -0
  252. package/template/src/components/ui/table/TableHeader.vue +17 -0
  253. package/template/src/components/ui/table/TableRow.vue +17 -0
  254. package/template/src/components/ui/table/index.ts +9 -0
  255. package/template/src/components/ui/table/utils.ts +10 -0
  256. package/template/src/components/ui/tabs/Tabs.vue +24 -0
  257. package/template/src/components/ui/tabs/TabsContent.vue +21 -0
  258. package/template/src/components/ui/tabs/TabsList.vue +24 -0
  259. package/template/src/components/ui/tabs/TabsTrigger.vue +26 -0
  260. package/template/src/components/ui/tabs/index.ts +4 -0
  261. package/template/src/components/ui/textarea/Textarea.vue +28 -0
  262. package/template/src/components/ui/textarea/index.ts +1 -0
  263. package/template/src/components/ui/timeline/Timeline.vue +73 -0
  264. package/template/src/components/ui/timeline/index.ts +1 -0
  265. package/template/src/components/ui/toggle/Toggle.vue +35 -0
  266. package/template/src/components/ui/toggle/index.ts +28 -0
  267. package/template/src/components/ui/toggle-group/ToggleGroup.vue +41 -0
  268. package/template/src/components/ui/toggle-group/ToggleGroupItem.vue +43 -0
  269. package/template/src/components/ui/toggle-group/index.ts +12 -0
  270. package/template/src/components/ui/tooltip/Tooltip.vue +19 -0
  271. package/template/src/components/ui/tooltip/TooltipContent.vue +34 -0
  272. package/template/src/components/ui/tooltip/TooltipProvider.vue +14 -0
  273. package/template/src/components/ui/tooltip/TooltipTrigger.vue +15 -0
  274. package/template/src/components/ui/tooltip/index.ts +4 -0
  275. package/template/src/components.d.ts +228 -0
  276. package/template/src/composables/useFormatter.ts +105 -0
  277. package/template/src/composables/useThemeConfig.ts +252 -0
  278. package/template/src/layouts/AdminLayout.vue +55 -0
  279. package/template/src/layouts/AuthLayout.vue +42 -0
  280. package/template/src/lib/axios.spec.ts +46 -0
  281. package/template/src/lib/axios.ts +243 -0
  282. package/template/src/lib/formatters.spec.ts +137 -0
  283. package/template/src/lib/formatters.ts +332 -0
  284. package/template/src/lib/loading-bar.ts +103 -0
  285. package/template/src/lib/utils.spec.ts +26 -0
  286. package/template/src/lib/utils.ts +7 -0
  287. package/template/src/lib/validation.spec.ts +78 -0
  288. package/template/src/main.ts +13 -0
  289. package/template/src/router/index.ts +147 -0
  290. package/template/src/services/auth.service.spec.ts +93 -0
  291. package/template/src/services/auth.service.ts +243 -0
  292. package/template/src/services/index.ts +3 -0
  293. package/template/src/services/types.ts +28 -0
  294. package/template/src/services/user.service.spec.ts +91 -0
  295. package/template/src/services/user.service.ts +283 -0
  296. package/template/src/stores/auth.spec.ts +52 -0
  297. package/template/src/stores/auth.ts +130 -0
  298. package/template/src/style.css +587 -0
  299. package/template/src/views/_starter/BlankView.vue +47 -0
  300. package/template/src/views/auth/ConfirmEmailView.vue +209 -0
  301. package/template/src/views/auth/ForgotPasswordView.vue +151 -0
  302. package/template/src/views/auth/LockScreenView.vue +175 -0
  303. package/template/src/views/auth/LoginView.vue +54 -0
  304. package/template/src/views/auth/RegisterView.vue +265 -0
  305. package/template/src/views/auth/ResetPasswordView.vue +260 -0
  306. package/template/src/views/auth/VerifyOtpView.vue +261 -0
  307. package/template/src/views/dashboard/IndexView.vue +159 -0
  308. package/template/src/views/errors/ComingSoonView.vue +241 -0
  309. package/template/src/views/errors/MaintenanceView.vue +252 -0
  310. package/template/src/views/errors/NotFoundView.vue +81 -0
  311. package/template/src/views/errors/ServerErrorView.vue +101 -0
  312. package/template/src/views/errors/UnauthorizedView.vue +64 -0
  313. package/template/tsconfig.app.json +27 -0
  314. package/template/tsconfig.json +19 -0
  315. package/template/tsconfig.node.json +23 -0
  316. package/template/vite.config.ts +46 -0
@@ -0,0 +1,23 @@
1
+ <script lang="ts" setup>
2
+ import type { HTMLAttributes } from "vue"
3
+ import { MoreHorizontal } from "@lucide/vue"
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const props = defineProps<{
7
+ class?: HTMLAttributes["class"]
8
+ }>()
9
+ </script>
10
+
11
+ <template>
12
+ <span
13
+ data-slot="breadcrumb-ellipsis"
14
+ role="presentation"
15
+ aria-hidden="true"
16
+ :class="cn('flex size-9 items-center justify-center', props.class)"
17
+ >
18
+ <slot>
19
+ <MoreHorizontal class="size-4" />
20
+ </slot>
21
+ <span class="sr-only">More</span>
22
+ </span>
23
+ </template>
@@ -0,0 +1,17 @@
1
+ <script lang="ts" setup>
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const props = defineProps<{
6
+ class?: HTMLAttributes["class"]
7
+ }>()
8
+ </script>
9
+
10
+ <template>
11
+ <li
12
+ data-slot="breadcrumb-item"
13
+ :class="cn('inline-flex items-center gap-1.5', props.class)"
14
+ >
15
+ <slot />
16
+ </li>
17
+ </template>
@@ -0,0 +1,21 @@
1
+ <script lang="ts" setup>
2
+ import type { PrimitiveProps } from "reka-ui"
3
+ import type { HTMLAttributes } from "vue"
4
+ import { Primitive } from "reka-ui"
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const props = withDefaults(defineProps<PrimitiveProps & { class?: HTMLAttributes["class"] }>(), {
8
+ as: "a",
9
+ })
10
+ </script>
11
+
12
+ <template>
13
+ <Primitive
14
+ data-slot="breadcrumb-link"
15
+ :as="as"
16
+ :as-child="asChild"
17
+ :class="cn('hover:text-foreground transition-colors', props.class)"
18
+ >
19
+ <slot />
20
+ </Primitive>
21
+ </template>
@@ -0,0 +1,17 @@
1
+ <script lang="ts" setup>
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const props = defineProps<{
6
+ class?: HTMLAttributes["class"]
7
+ }>()
8
+ </script>
9
+
10
+ <template>
11
+ <ol
12
+ data-slot="breadcrumb-list"
13
+ :class="cn('text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5', props.class)"
14
+ >
15
+ <slot />
16
+ </ol>
17
+ </template>
@@ -0,0 +1,20 @@
1
+ <script lang="ts" setup>
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const props = defineProps<{
6
+ class?: HTMLAttributes["class"]
7
+ }>()
8
+ </script>
9
+
10
+ <template>
11
+ <span
12
+ data-slot="breadcrumb-page"
13
+ role="link"
14
+ aria-disabled="true"
15
+ aria-current="page"
16
+ :class="cn('text-foreground font-normal', props.class)"
17
+ >
18
+ <slot />
19
+ </span>
20
+ </template>
@@ -0,0 +1,22 @@
1
+ <script lang="ts" setup>
2
+ import type { HTMLAttributes } from "vue"
3
+ import { ChevronRight } from "@lucide/vue"
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const props = defineProps<{
7
+ class?: HTMLAttributes["class"]
8
+ }>()
9
+ </script>
10
+
11
+ <template>
12
+ <li
13
+ data-slot="breadcrumb-separator"
14
+ role="presentation"
15
+ aria-hidden="true"
16
+ :class="cn('[&>svg]:size-3.5', props.class)"
17
+ >
18
+ <slot>
19
+ <ChevronRight />
20
+ </slot>
21
+ </li>
22
+ </template>
@@ -0,0 +1,7 @@
1
+ export { default as Breadcrumb } from "./Breadcrumb.vue"
2
+ export { default as BreadcrumbEllipsis } from "./BreadcrumbEllipsis.vue"
3
+ export { default as BreadcrumbItem } from "./BreadcrumbItem.vue"
4
+ export { default as BreadcrumbLink } from "./BreadcrumbLink.vue"
5
+ export { default as BreadcrumbList } from "./BreadcrumbList.vue"
6
+ export { default as BreadcrumbPage } from "./BreadcrumbPage.vue"
7
+ export { default as BreadcrumbSeparator } from "./BreadcrumbSeparator.vue"
@@ -0,0 +1,46 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import Button from './Button.vue'
4
+
5
+ describe('Button component', () => {
6
+ it('renders default slot content correctly', () => {
7
+ const wrapper = mount(Button, {
8
+ slots: {
9
+ default: 'Click Me',
10
+ },
11
+ })
12
+ expect(wrapper.text()).toBe('Click Me')
13
+ expect(wrapper.element.tagName).toBe('BUTTON')
14
+ })
15
+
16
+ it('applies default variant and size attributes', () => {
17
+ const wrapper = mount(Button)
18
+ expect(wrapper.attributes('data-slot')).toBe('button')
19
+ })
20
+
21
+ it('applies custom variant classes properly', () => {
22
+ const wrapper = mount(Button, {
23
+ props: {
24
+ variant: 'destructive',
25
+ },
26
+ })
27
+ expect(wrapper.attributes('data-variant')).toBe('destructive')
28
+ expect(wrapper.classes()).toContain('bg-destructive')
29
+ })
30
+
31
+ it('applies custom classes passed via props', () => {
32
+ const wrapper = mount(Button, {
33
+ props: {
34
+ class: 'custom-test-class',
35
+ },
36
+ })
37
+ expect(wrapper.classes()).toContain('custom-test-class')
38
+ })
39
+
40
+ it('triggers click event when clicked', async () => {
41
+ const wrapper = mount(Button)
42
+ await wrapper.trigger('click')
43
+ expect(wrapper.emitted()).toHaveProperty('click')
44
+ expect(wrapper.emitted('click')).toHaveLength(1)
45
+ })
46
+ })
@@ -0,0 +1,31 @@
1
+ <script setup lang="ts">
2
+ import type { PrimitiveProps } from "reka-ui"
3
+ import type { HTMLAttributes } from "vue"
4
+ import type { ButtonVariants } from "."
5
+ import { Primitive } from "reka-ui"
6
+ import { cn } from "@/lib/utils"
7
+ import { buttonVariants } from "."
8
+
9
+ interface Props extends PrimitiveProps {
10
+ variant?: ButtonVariants["variant"]
11
+ size?: ButtonVariants["size"]
12
+ class?: HTMLAttributes["class"]
13
+ }
14
+
15
+ const props = withDefaults(defineProps<Props>(), {
16
+ as: "button",
17
+ })
18
+ </script>
19
+
20
+ <template>
21
+ <Primitive
22
+ data-slot="button"
23
+ :data-variant="variant"
24
+ :data-size="size"
25
+ :as="as"
26
+ :as-child="asChild"
27
+ :class="cn(buttonVariants({ variant, size }), props.class)"
28
+ >
29
+ <slot />
30
+ </Primitive>
31
+ </template>
@@ -0,0 +1,41 @@
1
+ import type { VariantProps } from "class-variance-authority"
2
+ import { cva } from "class-variance-authority"
3
+
4
+ export { default as Button } from "./Button.vue"
5
+
6
+ export const buttonVariants = cva(
7
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive cursor-pointer",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default:
12
+ "bg-primary text-primary-foreground font-medium border border-emerald-600/30 dark:border-emerald-500/40 shadow-xs hover:bg-primary/90 active:bg-primary/95 transition-colors",
13
+ destructive:
14
+ "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
15
+ outline:
16
+ "border border-border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/20 dark:border-input/40 dark:hover:bg-input/40",
17
+ secondary:
18
+ "bg-secondary text-secondary-foreground border border-border/50 hover:bg-secondary/80 hover:text-foreground shadow-xs",
19
+ ghost:
20
+ "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
21
+ link: "text-brand-500 hover:text-brand-600 dark:text-brand-400 dark:hover:text-brand-300 underline-offset-4 hover:underline",
22
+ },
23
+ size: {
24
+ "default": "h-9 px-4 py-2 has-[>svg]:px-3",
25
+ "xs": "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
26
+ "sm": "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
27
+ "lg": "h-10 rounded-md px-6 has-[>svg]:px-4",
28
+ "icon": "size-9",
29
+ "icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
30
+ "icon-sm": "size-8",
31
+ "icon-lg": "size-10",
32
+ },
33
+ },
34
+ defaultVariants: {
35
+ variant: "default",
36
+ size: "default",
37
+ },
38
+ },
39
+ )
40
+
41
+ export type ButtonVariants = VariantProps<typeof buttonVariants>
@@ -0,0 +1,106 @@
1
+ <script setup lang="ts">
2
+ import type { CalendarRootEmits, CalendarRootProps } from "reka-ui"
3
+ import type { HTMLAttributes } from "vue"
4
+ import { cn } from "@/lib/utils"
5
+ import {
6
+ CalendarCell,
7
+ CalendarCellTrigger,
8
+ CalendarGrid,
9
+ CalendarGridBody,
10
+ CalendarGridHead,
11
+ CalendarGridRow,
12
+ CalendarHeadCell,
13
+ CalendarHeader,
14
+ CalendarHeading,
15
+ CalendarNext,
16
+ CalendarPrev,
17
+ CalendarRoot,
18
+ useForwardPropsEmits,
19
+ } from "reka-ui"
20
+ import { ChevronLeft, ChevronRight } from "@lucide/vue"
21
+
22
+ const props = withDefaults(
23
+ defineProps<CalendarRootProps & { class?: HTMLAttributes["class"] }>(),
24
+ {
25
+ modelValue: undefined,
26
+ placeholder: undefined,
27
+ }
28
+ )
29
+
30
+ const emits = defineEmits<CalendarRootEmits>()
31
+ const forwarded = useForwardPropsEmits(props, emits)
32
+ </script>
33
+
34
+ <template>
35
+ <CalendarRoot
36
+ v-slot="{ grid, weekDays }"
37
+ v-bind="forwarded"
38
+ data-slot="calendar"
39
+ :class="cn('p-3 rounded-xl border bg-card text-card-foreground shadow-xs select-none w-fit', props.class)"
40
+ >
41
+ <!-- Calendar Navigation Header -->
42
+ <CalendarHeader class="flex items-center justify-between pt-1 pb-3 px-1">
43
+ <CalendarPrev
44
+ class="inline-flex items-center justify-center h-7 w-7 rounded-lg border border-border bg-background text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors cursor-pointer"
45
+ >
46
+ <slot name="prev-icon">
47
+ <ChevronLeft class="h-4 w-4" />
48
+ </slot>
49
+ </CalendarPrev>
50
+
51
+ <CalendarHeading class="text-xs font-bold text-foreground capitalize tracking-tight" />
52
+
53
+ <CalendarNext
54
+ class="inline-flex items-center justify-center h-7 w-7 rounded-lg border border-border bg-background text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors cursor-pointer"
55
+ >
56
+ <slot name="next-icon">
57
+ <ChevronRight class="h-4 w-4" />
58
+ </slot>
59
+ </CalendarNext>
60
+ </CalendarHeader>
61
+
62
+ <!-- Month Day Grid -->
63
+ <div class="flex flex-col gap-y-4">
64
+ <CalendarGrid
65
+ v-for="month in grid"
66
+ :key="month.value.toString()"
67
+ class="w-full border-collapse space-y-1"
68
+ >
69
+ <!-- Weekday Head -->
70
+ <CalendarGridHead>
71
+ <CalendarGridRow class="flex">
72
+ <CalendarHeadCell
73
+ v-for="day in weekDays"
74
+ :key="day"
75
+ class="w-8 rounded-md text-[11px] font-medium text-muted-foreground text-center"
76
+ >
77
+ {{ day }}
78
+ </CalendarHeadCell>
79
+ </CalendarGridRow>
80
+ </CalendarGridHead>
81
+
82
+ <!-- Days Body -->
83
+ <CalendarGridBody class="grid">
84
+ <CalendarGridRow
85
+ v-for="(weekDates, index) in month.rows"
86
+ :key="`weekDate-${index}`"
87
+ class="flex w-full mt-1"
88
+ >
89
+ <CalendarCell
90
+ v-for="weekDate in weekDates"
91
+ :key="weekDate.toString()"
92
+ :date="weekDate"
93
+ class="relative p-0 text-center text-xs focus-within:relative focus-within:z-20 has-data-selected:bg-primary/10 first:has-data-selected:rounded-l-md last:has-data-selected:rounded-r-md"
94
+ >
95
+ <CalendarCellTrigger
96
+ :day="weekDate"
97
+ :month="month.value"
98
+ class="inline-flex items-center justify-center h-8 w-8 rounded-lg text-xs font-medium text-foreground transition-all cursor-pointer hover:bg-muted/80 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring data-selected:bg-primary data-selected:text-primary-foreground data-selected:font-bold data-today:border data-today:border-primary/50 data-today:font-semibold data-outside-view:text-muted-foreground/40 data-disabled:text-muted-foreground/30 data-disabled:cursor-not-allowed"
99
+ />
100
+ </CalendarCell>
101
+ </CalendarGridRow>
102
+ </CalendarGridBody>
103
+ </CalendarGrid>
104
+ </div>
105
+ </CalendarRoot>
106
+ </template>
@@ -0,0 +1 @@
1
+ export { default as Calendar } from "./Calendar.vue"
@@ -0,0 +1,29 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const props = withDefaults(
6
+ defineProps<{
7
+ class?: HTMLAttributes["class"]
8
+ flush?: boolean
9
+ }>(),
10
+ {
11
+ flush: false,
12
+ },
13
+ )
14
+ </script>
15
+
16
+ <template>
17
+ <div
18
+ data-slot="card"
19
+ :class="
20
+ cn(
21
+ 'bg-card text-card-foreground flex flex-col rounded-lg border shadow-xs',
22
+ props.flush ? 'overflow-hidden py-0 gap-0' : 'py-6 gap-6',
23
+ props.class,
24
+ )
25
+ "
26
+ >
27
+ <slot />
28
+ </div>
29
+ </template>
@@ -0,0 +1,17 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const props = defineProps<{
6
+ class?: HTMLAttributes["class"]
7
+ }>()
8
+ </script>
9
+
10
+ <template>
11
+ <div
12
+ data-slot="card-action"
13
+ :class="cn('col-start-2 row-span-2 row-start-1 self-start justify-self-end', props.class)"
14
+ >
15
+ <slot />
16
+ </div>
17
+ </template>
@@ -0,0 +1,17 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const props = defineProps<{
6
+ class?: HTMLAttributes["class"]
7
+ }>()
8
+ </script>
9
+
10
+ <template>
11
+ <div
12
+ data-slot="card-content"
13
+ :class="cn('px-6', props.class)"
14
+ >
15
+ <slot />
16
+ </div>
17
+ </template>
@@ -0,0 +1,17 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const props = defineProps<{
6
+ class?: HTMLAttributes["class"]
7
+ }>()
8
+ </script>
9
+
10
+ <template>
11
+ <p
12
+ data-slot="card-description"
13
+ :class="cn('text-muted-foreground text-sm', props.class)"
14
+ >
15
+ <slot />
16
+ </p>
17
+ </template>
@@ -0,0 +1,17 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const props = defineProps<{
6
+ class?: HTMLAttributes["class"]
7
+ }>()
8
+ </script>
9
+
10
+ <template>
11
+ <div
12
+ data-slot="card-footer"
13
+ :class="cn('flex items-center px-6 [.border-t]:pt-6', props.class)"
14
+ >
15
+ <slot />
16
+ </div>
17
+ </template>
@@ -0,0 +1,29 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const props = withDefaults(
6
+ defineProps<{
7
+ class?: HTMLAttributes["class"]
8
+ section?: boolean
9
+ }>(),
10
+ {
11
+ section: false,
12
+ },
13
+ )
14
+ </script>
15
+
16
+ <template>
17
+ <div
18
+ data-slot="card-header"
19
+ :class="
20
+ cn(
21
+ '@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6',
22
+ props.section && 'p-6 border-b border-border bg-muted/10',
23
+ props.class,
24
+ )
25
+ "
26
+ >
27
+ <slot />
28
+ </div>
29
+ </template>
@@ -0,0 +1,17 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const props = defineProps<{
6
+ class?: HTMLAttributes["class"]
7
+ }>()
8
+ </script>
9
+
10
+ <template>
11
+ <h3
12
+ data-slot="card-title"
13
+ :class="cn('leading-none font-semibold', props.class)"
14
+ >
15
+ <slot />
16
+ </h3>
17
+ </template>
@@ -0,0 +1,7 @@
1
+ export { default as Card } from "./Card.vue"
2
+ export { default as CardAction } from "./CardAction.vue"
3
+ export { default as CardContent } from "./CardContent.vue"
4
+ export { default as CardDescription } from "./CardDescription.vue"
5
+ export { default as CardFooter } from "./CardFooter.vue"
6
+ export { default as CardHeader } from "./CardHeader.vue"
7
+ export { default as CardTitle } from "./CardTitle.vue"
@@ -0,0 +1,143 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+ import { VisXYContainer, VisArea, VisLine, VisAxis, VisTooltip, VisCrosshair } from '@unovis/vue'
4
+ import { CurveType } from '@unovis/ts'
5
+
6
+ interface Props {
7
+ data: Record<string, any>[]
8
+ index: string
9
+ categories: string[]
10
+ colors?: string[]
11
+ curveType?: CurveType
12
+ showGridLine?: boolean
13
+ showXAxis?: boolean
14
+ showYAxis?: boolean
15
+ showTooltip?: boolean
16
+ showLegend?: boolean
17
+ yFormatter?: (tick: number) => string
18
+ xFormatter?: (tick: number, i?: number) => string
19
+ opacity?: number
20
+ }
21
+
22
+ const props = withDefaults(defineProps<Props>(), {
23
+ colors: () => ['var(--primary)', '#3b82f6', '#10b981', '#f59e0b', '#8b5cf6'],
24
+ curveType: CurveType.MonotoneX,
25
+ showGridLine: false,
26
+ showXAxis: true,
27
+ showYAxis: true,
28
+ showTooltip: true,
29
+ showLegend: false,
30
+ opacity: 0.15,
31
+ })
32
+
33
+ const x = (_: any, i: number) => i
34
+
35
+ function getColor(i: number): string {
36
+ return props.colors[i % props.colors.length]
37
+ }
38
+
39
+ const defaultYFormatter = (tick: number) => {
40
+ if (tick >= 1_000_000) return `${(tick / 1_000_000).toFixed(1)}M`
41
+ if (tick >= 1_000) return `${(tick / 1_000).toFixed(0)}k`
42
+ return `${tick}`
43
+ }
44
+
45
+ const defaultXFormatter = (i: number) => {
46
+ const d = props.data[i]
47
+ return d ? String(d[props.index]) : ''
48
+ }
49
+
50
+ const tooltipTemplate = computed(() => {
51
+ return (d: Record<string, any>) => {
52
+ if (!d) return ''
53
+ const title = d[props.index] ?? ''
54
+ const rows = props.categories
55
+ .map((cat, idx) => {
56
+ const val = d[cat]
57
+ const color = getColor(idx)
58
+ const formattedVal = typeof val === 'number' ? val.toLocaleString() : val
59
+ return `
60
+ <div class="flex items-center justify-between gap-4 text-xs py-0.5">
61
+ <span class="flex items-center gap-1.5 text-muted-foreground capitalize">
62
+ <span class="h-2 w-2 rounded-full shrink-0" style="background-color: ${color}"></span>
63
+ ${cat}
64
+ </span>
65
+ <span class="font-mono font-bold text-foreground">${formattedVal}</span>
66
+ </div>
67
+ `
68
+ })
69
+ .join('')
70
+
71
+ return `
72
+ <div class="rounded-lg border border-border bg-popover/95 backdrop-blur-md px-3 py-2 text-xs shadow-md min-w-36">
73
+ <div class="font-bold text-foreground mb-1.5 pb-1 border-b border-border/40">${title}</div>
74
+ <div class="space-y-0.5">${rows}</div>
75
+ </div>
76
+ `
77
+ }
78
+ })
79
+ </script>
80
+
81
+ <template>
82
+ <div class="w-full h-full flex flex-col">
83
+ <!-- Optional Legend -->
84
+ <div v-if="showLegend" class="flex flex-wrap items-center gap-4 mb-3 text-xs">
85
+ <div
86
+ v-for="(cat, idx) in categories"
87
+ :key="cat"
88
+ class="flex items-center gap-1.5 text-muted-foreground font-medium capitalize"
89
+ >
90
+ <span class="h-2.5 w-2.5 rounded-full" :style="{ backgroundColor: getColor(idx) }" />
91
+ <span>{{ cat }}</span>
92
+ </div>
93
+ </div>
94
+
95
+ <!-- Chart Container -->
96
+ <div class="flex-1 w-full min-h-45 relative">
97
+ <VisXYContainer :data="data" class="w-full h-full">
98
+ <!-- Area & Line series -->
99
+ <template v-for="(category, idx) in categories" :key="category">
100
+ <VisArea
101
+ :x="x"
102
+ :y="(d: any) => d[category]"
103
+ :color="getColor(idx)"
104
+ :opacity="opacity"
105
+ :curveType="curveType"
106
+ />
107
+ <VisLine
108
+ :x="x"
109
+ :y="(d: any) => d[category]"
110
+ :color="getColor(idx)"
111
+ :lineWidth="2"
112
+ :curveType="curveType"
113
+ />
114
+ </template>
115
+
116
+ <!-- X & Y Axes -->
117
+ <VisAxis
118
+ v-if="showXAxis"
119
+ type="x"
120
+ :tickFormat="xFormatter || defaultXFormatter"
121
+ :numTicks="data.length"
122
+ :gridLine="false"
123
+ :domainLine="false"
124
+ :tickLine="false"
125
+ tickTextColor="var(--muted-foreground)"
126
+ />
127
+ <VisAxis
128
+ v-if="showYAxis"
129
+ type="y"
130
+ :tickFormat="yFormatter || defaultYFormatter"
131
+ :numTicks="4"
132
+ :gridLine="showGridLine"
133
+ :domainLine="false"
134
+ :tickLine="false"
135
+ tickTextColor="var(--muted-foreground)"
136
+ />
137
+
138
+ <VisTooltip v-if="showTooltip" :attributes="{ 'data-unovis-tooltip': '' }" />
139
+ <VisCrosshair v-if="showTooltip" :template="tooltipTemplate" />
140
+ </VisXYContainer>
141
+ </div>
142
+ </div>
143
+ </template>