@spavn/ui 0.0.1

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 (399) hide show
  1. package/cli/commands/add.d.ts +5 -0
  2. package/cli/commands/add.d.ts.map +1 -0
  3. package/cli/commands/add.js +104 -0
  4. package/cli/commands/add.js.map +1 -0
  5. package/cli/commands/init.d.ts +5 -0
  6. package/cli/commands/init.d.ts.map +1 -0
  7. package/cli/commands/init.js +129 -0
  8. package/cli/commands/init.js.map +1 -0
  9. package/cli/index.d.ts +3 -0
  10. package/cli/index.d.ts.map +1 -0
  11. package/cli/index.js +27 -0
  12. package/cli/index.js.map +1 -0
  13. package/cli/registry.d.ts +12 -0
  14. package/cli/registry.d.ts.map +1 -0
  15. package/cli/registry.js +1112 -0
  16. package/cli/registry.js.map +1 -0
  17. package/dist/index.js +7492 -0
  18. package/dist/index.umd.cjs +122 -0
  19. package/dist/style.css +1 -0
  20. package/mcp-server/index.d.ts +3 -0
  21. package/mcp-server/index.d.ts.map +1 -0
  22. package/mcp-server/index.js +1266 -0
  23. package/mcp-server/index.js.map +1 -0
  24. package/package.json +91 -0
  25. package/src/index.ts +432 -0
  26. package/src/lib/accordion/Accordion.test.ts +109 -0
  27. package/src/lib/accordion/Accordion.vue +11 -0
  28. package/src/lib/accordion/AccordionContent.vue +23 -0
  29. package/src/lib/accordion/AccordionItem.vue +16 -0
  30. package/src/lib/accordion/AccordionTrigger.vue +37 -0
  31. package/src/lib/accordion/index.ts +4 -0
  32. package/src/lib/alert/Alert.test.ts +144 -0
  33. package/src/lib/alert/Alert.vue +17 -0
  34. package/src/lib/alert/AlertDescription.vue +15 -0
  35. package/src/lib/alert/AlertTitle.vue +15 -0
  36. package/src/lib/alert/variants.test.ts +47 -0
  37. package/src/lib/alert/variants.ts +19 -0
  38. package/src/lib/alert-dialog/AlertDialog.vue +11 -0
  39. package/src/lib/alert-dialog/AlertDialogAction.vue +23 -0
  40. package/src/lib/alert-dialog/AlertDialogCancel.vue +24 -0
  41. package/src/lib/alert-dialog/AlertDialogContent.vue +33 -0
  42. package/src/lib/alert-dialog/AlertDialogDescription.vue +16 -0
  43. package/src/lib/alert-dialog/AlertDialogFooter.vue +17 -0
  44. package/src/lib/alert-dialog/AlertDialogHeader.vue +17 -0
  45. package/src/lib/alert-dialog/AlertDialogOverlay.vue +21 -0
  46. package/src/lib/alert-dialog/AlertDialogPortal.vue +11 -0
  47. package/src/lib/alert-dialog/AlertDialogTitle.vue +16 -0
  48. package/src/lib/alert-dialog/AlertDialogTrigger.vue +11 -0
  49. package/src/lib/alert-dialog/index.ts +11 -0
  50. package/src/lib/aspect-ratio/AspectRatio.vue +11 -0
  51. package/src/lib/aspect-ratio/index.ts +1 -0
  52. package/src/lib/avatar/Avatar.test.ts +58 -0
  53. package/src/lib/avatar/Avatar.vue +20 -0
  54. package/src/lib/avatar/AvatarFallback.vue +20 -0
  55. package/src/lib/avatar/AvatarImage.vue +10 -0
  56. package/src/lib/avatar/index.ts +3 -0
  57. package/src/lib/badge/Badge.test.ts +77 -0
  58. package/src/lib/badge/Badge.vue +20 -0
  59. package/src/lib/badge/index.ts +2 -0
  60. package/src/lib/badge/variants.test.ts +73 -0
  61. package/src/lib/badge/variants.ts +26 -0
  62. package/src/lib/breadcrumb/Breadcrumb.vue +13 -0
  63. package/src/lib/breadcrumb/BreadcrumbEllipsis.vue +35 -0
  64. package/src/lib/breadcrumb/BreadcrumbItem.vue +15 -0
  65. package/src/lib/breadcrumb/BreadcrumbLink.vue +21 -0
  66. package/src/lib/breadcrumb/BreadcrumbList.vue +22 -0
  67. package/src/lib/breadcrumb/BreadcrumbPage.vue +20 -0
  68. package/src/lib/breadcrumb/BreadcrumbSeparator.vue +34 -0
  69. package/src/lib/breadcrumb/index.ts +7 -0
  70. package/src/lib/button/Button.test.ts +84 -0
  71. package/src/lib/button/Button.vue +63 -0
  72. package/src/lib/button/index.ts +2 -0
  73. package/src/lib/button/variants.test.ts +128 -0
  74. package/src/lib/button/variants.ts +66 -0
  75. package/src/lib/button-group/ButtonGroup.vue +25 -0
  76. package/src/lib/button-group/index.ts +1 -0
  77. package/src/lib/calendar/Calendar.vue +58 -0
  78. package/src/lib/calendar/CalendarCell.vue +22 -0
  79. package/src/lib/calendar/CalendarCellTrigger.vue +28 -0
  80. package/src/lib/calendar/CalendarGrid.vue +16 -0
  81. package/src/lib/calendar/CalendarGridBody.vue +11 -0
  82. package/src/lib/calendar/CalendarGridHead.vue +11 -0
  83. package/src/lib/calendar/CalendarGridRow.vue +16 -0
  84. package/src/lib/calendar/CalendarHeadCell.vue +16 -0
  85. package/src/lib/calendar/CalendarHeader.vue +16 -0
  86. package/src/lib/calendar/CalendarHeading.vue +16 -0
  87. package/src/lib/calendar/CalendarNext.vue +37 -0
  88. package/src/lib/calendar/CalendarPrev.vue +37 -0
  89. package/src/lib/calendar/index.ts +12 -0
  90. package/src/lib/card/Card.test.ts +202 -0
  91. package/src/lib/card/Card.vue +36 -0
  92. package/src/lib/card/CardContent.vue +15 -0
  93. package/src/lib/card/CardDescription.vue +15 -0
  94. package/src/lib/card/CardFooter.vue +16 -0
  95. package/src/lib/card/CardHeader.vue +15 -0
  96. package/src/lib/card/CardTitle.vue +15 -0
  97. package/src/lib/card/index.ts +6 -0
  98. package/src/lib/carousel/Carousel.vue +73 -0
  99. package/src/lib/carousel/CarouselContent.vue +55 -0
  100. package/src/lib/carousel/CarouselItem.vue +25 -0
  101. package/src/lib/carousel/CarouselNext.vue +40 -0
  102. package/src/lib/carousel/CarouselPrevious.vue +40 -0
  103. package/src/lib/carousel/index.ts +6 -0
  104. package/src/lib/carousel/useCarousel.ts +24 -0
  105. package/src/lib/checkbox/Checkbox.test.ts +45 -0
  106. package/src/lib/checkbox/Checkbox.vue +39 -0
  107. package/src/lib/code-preview/CodePreview.vue +95 -0
  108. package/src/lib/collapsible/Collapsible.test.ts +95 -0
  109. package/src/lib/collapsible/Collapsible.vue +11 -0
  110. package/src/lib/collapsible/CollapsibleContent.vue +21 -0
  111. package/src/lib/collapsible/CollapsibleTrigger.vue +11 -0
  112. package/src/lib/collapsible/index.ts +3 -0
  113. package/src/lib/command/Command.vue +21 -0
  114. package/src/lib/command/CommandDialog.vue +25 -0
  115. package/src/lib/command/CommandEmpty.vue +16 -0
  116. package/src/lib/command/CommandGroup.vue +21 -0
  117. package/src/lib/command/CommandInput.vue +35 -0
  118. package/src/lib/command/CommandItem.vue +23 -0
  119. package/src/lib/command/CommandLabel.vue +16 -0
  120. package/src/lib/command/CommandList.vue +16 -0
  121. package/src/lib/command/CommandSeparator.vue +14 -0
  122. package/src/lib/command/index.ts +9 -0
  123. package/src/lib/context-menu/ContextMenu.vue +11 -0
  124. package/src/lib/context-menu/ContextMenuCheckboxItem.vue +45 -0
  125. package/src/lib/context-menu/ContextMenuContent.vue +31 -0
  126. package/src/lib/context-menu/ContextMenuGroup.vue +11 -0
  127. package/src/lib/context-menu/ContextMenuItem.vue +24 -0
  128. package/src/lib/context-menu/ContextMenuLabel.vue +16 -0
  129. package/src/lib/context-menu/ContextMenuRadioGroup.vue +11 -0
  130. package/src/lib/context-menu/ContextMenuRadioItem.vue +44 -0
  131. package/src/lib/context-menu/ContextMenuSeparator.vue +14 -0
  132. package/src/lib/context-menu/ContextMenuShortcut.vue +11 -0
  133. package/src/lib/context-menu/ContextMenuSub.vue +11 -0
  134. package/src/lib/context-menu/ContextMenuSubContent.vue +28 -0
  135. package/src/lib/context-menu/ContextMenuSubTrigger.vue +36 -0
  136. package/src/lib/context-menu/ContextMenuTrigger.vue +11 -0
  137. package/src/lib/context-menu/index.ts +14 -0
  138. package/src/lib/data-table/DataTable.vue +226 -0
  139. package/src/lib/date-range-picker/DateRangePicker.vue +201 -0
  140. package/src/lib/date-time-picker/DateTimePicker.vue +159 -0
  141. package/src/lib/dialog/Dialog.test.ts +87 -0
  142. package/src/lib/dialog/Dialog.vue +14 -0
  143. package/src/lib/dialog/DialogClose.vue +11 -0
  144. package/src/lib/dialog/DialogContent.vue +56 -0
  145. package/src/lib/dialog/DialogDescription.vue +15 -0
  146. package/src/lib/dialog/DialogFooter.vue +17 -0
  147. package/src/lib/dialog/DialogHeader.vue +17 -0
  148. package/src/lib/dialog/DialogOverlay.vue +20 -0
  149. package/src/lib/dialog/DialogPortal.vue +11 -0
  150. package/src/lib/dialog/DialogTitle.vue +15 -0
  151. package/src/lib/dialog/DialogTrigger.vue +11 -0
  152. package/src/lib/dialog/index.ts +10 -0
  153. package/src/lib/direction/Direction.vue +13 -0
  154. package/src/lib/drawer/Drawer.vue +11 -0
  155. package/src/lib/drawer/DrawerClose.vue +11 -0
  156. package/src/lib/drawer/DrawerContent.vue +31 -0
  157. package/src/lib/drawer/DrawerDescription.vue +16 -0
  158. package/src/lib/drawer/DrawerFooter.vue +15 -0
  159. package/src/lib/drawer/DrawerHeader.vue +15 -0
  160. package/src/lib/drawer/DrawerOverlay.vue +21 -0
  161. package/src/lib/drawer/DrawerTitle.vue +16 -0
  162. package/src/lib/drawer/DrawerTrigger.vue +11 -0
  163. package/src/lib/drawer/index.ts +9 -0
  164. package/src/lib/dropdown-menu/DropdownMenu.test.ts +146 -0
  165. package/src/lib/dropdown-menu/DropdownMenu.vue +11 -0
  166. package/src/lib/dropdown-menu/DropdownMenuCheckboxItem.vue +45 -0
  167. package/src/lib/dropdown-menu/DropdownMenuContent.vue +31 -0
  168. package/src/lib/dropdown-menu/DropdownMenuGroup.vue +11 -0
  169. package/src/lib/dropdown-menu/DropdownMenuItem.vue +24 -0
  170. package/src/lib/dropdown-menu/DropdownMenuLabel.vue +16 -0
  171. package/src/lib/dropdown-menu/DropdownMenuRadioGroup.vue +11 -0
  172. package/src/lib/dropdown-menu/DropdownMenuRadioItem.vue +44 -0
  173. package/src/lib/dropdown-menu/DropdownMenuSeparator.vue +14 -0
  174. package/src/lib/dropdown-menu/DropdownMenuShortcut.vue +11 -0
  175. package/src/lib/dropdown-menu/DropdownMenuSub.vue +11 -0
  176. package/src/lib/dropdown-menu/DropdownMenuSubContent.vue +27 -0
  177. package/src/lib/dropdown-menu/DropdownMenuSubTrigger.vue +36 -0
  178. package/src/lib/dropdown-menu/DropdownMenuTrigger.vue +11 -0
  179. package/src/lib/dropdown-menu/index.ts +14 -0
  180. package/src/lib/empty/Empty.vue +11 -0
  181. package/src/lib/empty/EmptyDescription.vue +11 -0
  182. package/src/lib/empty/EmptyIcon.vue +8 -0
  183. package/src/lib/empty/EmptyTitle.vue +11 -0
  184. package/src/lib/empty/index.ts +4 -0
  185. package/src/lib/feature-card/FeatureCard.vue +177 -0
  186. package/src/lib/feature-card/README.md +139 -0
  187. package/src/lib/feature-card/index.ts +1 -0
  188. package/src/lib/field/Field.vue +15 -0
  189. package/src/lib/field/FieldDescription.vue +15 -0
  190. package/src/lib/field/FieldError.vue +15 -0
  191. package/src/lib/field/FieldLabel.vue +24 -0
  192. package/src/lib/field/index.ts +4 -0
  193. package/src/lib/hover-card/HoverCard.vue +11 -0
  194. package/src/lib/hover-card/HoverCardContent.vue +31 -0
  195. package/src/lib/hover-card/HoverCardTrigger.vue +11 -0
  196. package/src/lib/hover-card/index.ts +3 -0
  197. package/src/lib/icon/Icon.vue +33 -0
  198. package/src/lib/input/Input.test.ts +71 -0
  199. package/src/lib/input/Input.vue +85 -0
  200. package/src/lib/input/index.ts +1 -0
  201. package/src/lib/input-group/InputGroup.vue +24 -0
  202. package/src/lib/input-group/InputGroupAddon.vue +25 -0
  203. package/src/lib/input-group/InputGroupInput.vue +38 -0
  204. package/src/lib/input-group/index.ts +3 -0
  205. package/src/lib/input-otp/InputOTP.vue +16 -0
  206. package/src/lib/input-otp/InputOTPGroup.vue +11 -0
  207. package/src/lib/input-otp/InputOTPSeparator.vue +8 -0
  208. package/src/lib/input-otp/InputOTPSlot.vue +20 -0
  209. package/src/lib/input-otp/index.ts +4 -0
  210. package/src/lib/kbd/Kbd.vue +11 -0
  211. package/src/lib/kbd/index.ts +1 -0
  212. package/src/lib/label/Label.test.ts +38 -0
  213. package/src/lib/label/Label.vue +20 -0
  214. package/src/lib/label/index.ts +1 -0
  215. package/src/lib/layout/AppFooter.vue +18 -0
  216. package/src/lib/layout/AppHeader.vue +22 -0
  217. package/src/lib/layout/AppLayout.vue +13 -0
  218. package/src/lib/layout/AppMain.vue +22 -0
  219. package/src/lib/layout/AppSidebar.vue +50 -0
  220. package/src/lib/menubar/Menubar.vue +21 -0
  221. package/src/lib/menubar/MenubarCheckboxItem.vue +45 -0
  222. package/src/lib/menubar/MenubarContent.vue +30 -0
  223. package/src/lib/menubar/MenubarGroup.vue +11 -0
  224. package/src/lib/menubar/MenubarItem.vue +24 -0
  225. package/src/lib/menubar/MenubarLabel.vue +16 -0
  226. package/src/lib/menubar/MenubarMenu.vue +11 -0
  227. package/src/lib/menubar/MenubarRadioGroup.vue +11 -0
  228. package/src/lib/menubar/MenubarRadioItem.vue +44 -0
  229. package/src/lib/menubar/MenubarSeparator.vue +14 -0
  230. package/src/lib/menubar/MenubarShortcut.vue +11 -0
  231. package/src/lib/menubar/MenubarSub.vue +11 -0
  232. package/src/lib/menubar/MenubarSubContent.vue +26 -0
  233. package/src/lib/menubar/MenubarSubTrigger.vue +36 -0
  234. package/src/lib/menubar/MenubarTrigger.vue +21 -0
  235. package/src/lib/menubar/index.ts +15 -0
  236. package/src/lib/modal/Modal.test.ts +81 -0
  237. package/src/lib/modal/Modal.vue +12 -0
  238. package/src/lib/modal/ModalClose.vue +9 -0
  239. package/src/lib/modal/ModalContent.vue +32 -0
  240. package/src/lib/modal/ModalTrigger.vue +11 -0
  241. package/src/lib/multi-select/MultiSelect.vue +186 -0
  242. package/src/lib/multi-select/MultiSelectItem.vue +47 -0
  243. package/src/lib/native-select/NativeSelect.vue +41 -0
  244. package/src/lib/native-select/index.ts +1 -0
  245. package/src/lib/navigation-menu/NavigationMenu.vue +23 -0
  246. package/src/lib/navigation-menu/NavigationMenuContent.vue +21 -0
  247. package/src/lib/navigation-menu/NavigationMenuIndicator.vue +21 -0
  248. package/src/lib/navigation-menu/NavigationMenuItem.vue +11 -0
  249. package/src/lib/navigation-menu/NavigationMenuLink.vue +23 -0
  250. package/src/lib/navigation-menu/NavigationMenuList.vue +21 -0
  251. package/src/lib/navigation-menu/NavigationMenuTrigger.vue +36 -0
  252. package/src/lib/navigation-menu/NavigationMenuViewport.vue +24 -0
  253. package/src/lib/navigation-menu/index.ts +8 -0
  254. package/src/lib/pagination/Pagination.vue +16 -0
  255. package/src/lib/pagination/PaginationContent.vue +16 -0
  256. package/src/lib/pagination/PaginationEllipsis.vue +27 -0
  257. package/src/lib/pagination/PaginationFirst.vue +25 -0
  258. package/src/lib/pagination/PaginationItem.vue +11 -0
  259. package/src/lib/pagination/PaginationLast.vue +25 -0
  260. package/src/lib/pagination/PaginationLink.vue +31 -0
  261. package/src/lib/pagination/PaginationNext.vue +24 -0
  262. package/src/lib/pagination/PaginationPrev.vue +24 -0
  263. package/src/lib/pagination/index.ts +9 -0
  264. package/src/lib/popover/Popover.test.ts +97 -0
  265. package/src/lib/popover/Popover.vue +11 -0
  266. package/src/lib/popover/PopoverContent.vue +31 -0
  267. package/src/lib/popover/PopoverTrigger.vue +11 -0
  268. package/src/lib/popover/index.ts +3 -0
  269. package/src/lib/progress/Progress.test.ts +59 -0
  270. package/src/lib/progress/Progress.vue +41 -0
  271. package/src/lib/progress/index.ts +1 -0
  272. package/src/lib/radio-group/RadioGroup.test.ts +45 -0
  273. package/src/lib/radio-group/RadioGroup.vue +16 -0
  274. package/src/lib/radio-group/RadioGroupItem.vue +35 -0
  275. package/src/lib/radio-group/index.ts +2 -0
  276. package/src/lib/resizable/ResizableHandle.vue +38 -0
  277. package/src/lib/resizable/ResizablePanel.vue +11 -0
  278. package/src/lib/resizable/ResizablePanelGroup.vue +16 -0
  279. package/src/lib/resizable/index.ts +3 -0
  280. package/src/lib/scroll-area/ScrollArea.vue +29 -0
  281. package/src/lib/scroll-area/ScrollBar.vue +26 -0
  282. package/src/lib/scroll-area/index.ts +2 -0
  283. package/src/lib/select/Select.vue +11 -0
  284. package/src/lib/select/SelectContent.vue +48 -0
  285. package/src/lib/select/SelectGroup.vue +11 -0
  286. package/src/lib/select/SelectItem.vue +41 -0
  287. package/src/lib/select/SelectLabel.vue +16 -0
  288. package/src/lib/select/SelectScrollDownButton.vue +29 -0
  289. package/src/lib/select/SelectScrollUpButton.vue +29 -0
  290. package/src/lib/select/SelectSeparator.vue +14 -0
  291. package/src/lib/select/SelectTrigger.vue +37 -0
  292. package/src/lib/select/SelectValue.vue +11 -0
  293. package/src/lib/select/index.ts +10 -0
  294. package/src/lib/separator/Separator.test.ts +47 -0
  295. package/src/lib/separator/Separator.vue +23 -0
  296. package/src/lib/separator/index.ts +1 -0
  297. package/src/lib/sheet/Sheet.test.ts +118 -0
  298. package/src/lib/sheet/Sheet.vue +11 -0
  299. package/src/lib/sheet/SheetClose.vue +11 -0
  300. package/src/lib/sheet/SheetContent.vue +68 -0
  301. package/src/lib/sheet/SheetDescription.vue +16 -0
  302. package/src/lib/sheet/SheetFooter.vue +15 -0
  303. package/src/lib/sheet/SheetHeader.vue +15 -0
  304. package/src/lib/sheet/SheetOverlay.vue +21 -0
  305. package/src/lib/sheet/SheetTitle.vue +16 -0
  306. package/src/lib/sheet/SheetTrigger.vue +11 -0
  307. package/src/lib/sheet/index.ts +9 -0
  308. package/src/lib/sidebar/Sidebar.vue +19 -0
  309. package/src/lib/sidebar/SidebarContent.vue +11 -0
  310. package/src/lib/sidebar/SidebarFooter.vue +11 -0
  311. package/src/lib/sidebar/SidebarGroup.vue +11 -0
  312. package/src/lib/sidebar/SidebarGroupLabel.vue +11 -0
  313. package/src/lib/sidebar/SidebarHeader.vue +11 -0
  314. package/src/lib/sidebar/SidebarInset.vue +11 -0
  315. package/src/lib/sidebar/SidebarMenu.vue +11 -0
  316. package/src/lib/sidebar/SidebarMenuButton.vue +20 -0
  317. package/src/lib/sidebar/SidebarMenuItem.vue +9 -0
  318. package/src/lib/sidebar/SidebarProvider.vue +23 -0
  319. package/src/lib/sidebar/SidebarSeparator.vue +9 -0
  320. package/src/lib/sidebar/SidebarTrigger.vue +24 -0
  321. package/src/lib/sidebar/context.ts +8 -0
  322. package/src/lib/sidebar/useSidebar.ts +10 -0
  323. package/src/lib/skeleton/Skeleton.test.ts +36 -0
  324. package/src/lib/skeleton/Skeleton.vue +9 -0
  325. package/src/lib/skeleton/index.ts +1 -0
  326. package/src/lib/slider/Slider.test.ts +63 -0
  327. package/src/lib/slider/Slider.vue +67 -0
  328. package/src/lib/slider/index.ts +1 -0
  329. package/src/lib/sonner/Toaster.vue +29 -0
  330. package/src/lib/spinner/Spinner.vue +34 -0
  331. package/src/lib/spinner/index.ts +1 -0
  332. package/src/lib/stats-card/StatsCard.vue +179 -0
  333. package/src/lib/stats-card/index.ts +2 -0
  334. package/src/lib/styles.ts +133 -0
  335. package/src/lib/switch/Switch.test.ts +52 -0
  336. package/src/lib/switch/Switch.vue +43 -0
  337. package/src/lib/table/Table.test.ts +150 -0
  338. package/src/lib/table/Table.vue +13 -0
  339. package/src/lib/table/TableBody.vue +11 -0
  340. package/src/lib/table/TableCaption.vue +11 -0
  341. package/src/lib/table/TableCell.vue +11 -0
  342. package/src/lib/table/TableFooter.vue +11 -0
  343. package/src/lib/table/TableHead.vue +11 -0
  344. package/src/lib/table/TableHeader.vue +11 -0
  345. package/src/lib/table/TableRow.vue +11 -0
  346. package/src/lib/table/index.ts +8 -0
  347. package/src/lib/tabs/Tabs.test.ts +150 -0
  348. package/src/lib/tabs/Tabs.vue +11 -0
  349. package/src/lib/tabs/TabsContent.vue +21 -0
  350. package/src/lib/tabs/TabsList.vue +21 -0
  351. package/src/lib/tabs/TabsTrigger.vue +21 -0
  352. package/src/lib/tabs/index.ts +4 -0
  353. package/src/lib/textarea/Textarea.test.ts +41 -0
  354. package/src/lib/textarea/Textarea.vue +36 -0
  355. package/src/lib/theme-selector/README.md +154 -0
  356. package/src/lib/theme-selector/ThemeSelector.vue +279 -0
  357. package/src/lib/theme-selector/index.ts +2 -0
  358. package/src/lib/time-picker/TimePicker.vue +162 -0
  359. package/src/lib/time-picker/TimePickerSegment.vue +176 -0
  360. package/src/lib/toast/Toast.test.ts +80 -0
  361. package/src/lib/toast/Toast.vue +56 -0
  362. package/src/lib/toast/ToastAction.vue +23 -0
  363. package/src/lib/toast/ToastClose.vue +38 -0
  364. package/src/lib/toast/ToastDescription.vue +12 -0
  365. package/src/lib/toast/ToastProvider.ts +65 -0
  366. package/src/lib/toast/ToastTitle.vue +12 -0
  367. package/src/lib/toast/ToastViewport.vue +18 -0
  368. package/src/lib/toast/Toaster.vue +50 -0
  369. package/src/lib/toast/index.ts +7 -0
  370. package/src/lib/toggle/Toggle.vue +21 -0
  371. package/src/lib/toggle/index.ts +2 -0
  372. package/src/lib/toggle/variants.test.ts +87 -0
  373. package/src/lib/toggle/variants.ts +21 -0
  374. package/src/lib/toggle-group/ToggleGroup.vue +24 -0
  375. package/src/lib/toggle-group/ToggleGroupItem.vue +33 -0
  376. package/src/lib/toggle-group/index.ts +2 -0
  377. package/src/lib/tooltip/Tooltip.test.ts +87 -0
  378. package/src/lib/tooltip/Tooltip.vue +11 -0
  379. package/src/lib/tooltip/TooltipContent.vue +30 -0
  380. package/src/lib/tooltip/TooltipProvider.vue +11 -0
  381. package/src/lib/tooltip/TooltipTrigger.vue +11 -0
  382. package/src/lib/tooltip/index.ts +4 -0
  383. package/src/lib/typography/TypographyBlockquote.vue +11 -0
  384. package/src/lib/typography/TypographyH1.vue +11 -0
  385. package/src/lib/typography/TypographyH2.vue +11 -0
  386. package/src/lib/typography/TypographyH3.vue +11 -0
  387. package/src/lib/typography/TypographyH4.vue +11 -0
  388. package/src/lib/typography/TypographyInlineCode.vue +11 -0
  389. package/src/lib/typography/TypographyLarge.vue +11 -0
  390. package/src/lib/typography/TypographyLead.vue +11 -0
  391. package/src/lib/typography/TypographyMuted.vue +11 -0
  392. package/src/lib/typography/TypographyP.vue +11 -0
  393. package/src/lib/typography/TypographySmall.vue +11 -0
  394. package/src/lib/typography/index.ts +11 -0
  395. package/src/lib/utils.test.ts +45 -0
  396. package/src/lib/utils.ts +14 -0
  397. package/src/lib/variants.ts +45 -0
  398. package/src/theme.css +203 -0
  399. package/src/vite-env.d.ts +6 -0
@@ -0,0 +1,36 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import { MenubarSubTrigger } from 'radix-vue'
4
+ import { cn } from '@/lib/utils'
5
+
6
+ const props = defineProps<{ class?: string; inset?: boolean }>()
7
+ </script>
8
+
9
+ <template>
10
+ <MenubarSubTrigger
11
+ v-bind="$attrs"
12
+ :class="
13
+ cn(
14
+ 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent',
15
+ inset && 'pl-8',
16
+ props.class
17
+ )
18
+ "
19
+ >
20
+ <slot />
21
+ <svg
22
+ xmlns="http://www.w3.org/2000/svg"
23
+ width="24"
24
+ height="24"
25
+ viewBox="0 0 24 24"
26
+ fill="none"
27
+ stroke="currentColor"
28
+ stroke-width="2"
29
+ stroke-linecap="round"
30
+ stroke-linejoin="round"
31
+ class="ml-auto h-4 w-4"
32
+ >
33
+ <path d="m9 18 6-6-6-6" />
34
+ </svg>
35
+ </MenubarSubTrigger>
36
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import { MenubarTrigger } from 'radix-vue'
4
+ import { cn } from '@/lib/utils'
5
+
6
+ const props = defineProps<{ class?: string }>()
7
+ </script>
8
+
9
+ <template>
10
+ <MenubarTrigger
11
+ v-bind="$attrs"
12
+ :class="
13
+ cn(
14
+ 'flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',
15
+ props.class
16
+ )
17
+ "
18
+ >
19
+ <slot />
20
+ </MenubarTrigger>
21
+ </template>
@@ -0,0 +1,15 @@
1
+ export { default as Menubar } from './Menubar.vue'
2
+ export { default as MenubarCheckboxItem } from './MenubarCheckboxItem.vue'
3
+ export { default as MenubarContent } from './MenubarContent.vue'
4
+ export { default as MenubarGroup } from './MenubarGroup.vue'
5
+ export { default as MenubarItem } from './MenubarItem.vue'
6
+ export { default as MenubarLabel } from './MenubarLabel.vue'
7
+ export { default as MenubarMenu } from './MenubarMenu.vue'
8
+ export { default as MenubarRadioGroup } from './MenubarRadioGroup.vue'
9
+ export { default as MenubarRadioItem } from './MenubarRadioItem.vue'
10
+ export { default as MenubarSeparator } from './MenubarSeparator.vue'
11
+ export { default as MenubarShortcut } from './MenubarShortcut.vue'
12
+ export { default as MenubarSub } from './MenubarSub.vue'
13
+ export { default as MenubarSubContent } from './MenubarSubContent.vue'
14
+ export { default as MenubarSubTrigger } from './MenubarSubTrigger.vue'
15
+ export { default as MenubarTrigger } from './MenubarTrigger.vue'
@@ -0,0 +1,81 @@
1
+ import { describe, it, expect, afterEach } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import { h, nextTick } from 'vue'
4
+ import Modal from './Modal.vue'
5
+ import ModalTrigger from './ModalTrigger.vue'
6
+ import ModalContent from './ModalContent.vue'
7
+
8
+ afterEach(() => {
9
+ document.body.innerHTML = ''
10
+ })
11
+
12
+ describe('Modal', () => {
13
+ it('renders without errors', () => {
14
+ const wrapper = mount(Modal, {
15
+ slots: { default: 'Modal content' },
16
+ })
17
+ expect(wrapper.exists()).toBe(true)
18
+ })
19
+
20
+ it('accepts open prop via attrs', () => {
21
+ const wrapper = mount(Modal, {
22
+ attrs: { open: true },
23
+ slots: { default: 'Modal content' },
24
+ })
25
+ expect(wrapper.exists()).toBe(true)
26
+ })
27
+ })
28
+
29
+ describe('ModalTrigger', () => {
30
+ it('renders slot content inside Modal', () => {
31
+ const wrapper = mount(Modal, {
32
+ slots: {
33
+ default: () => h(ModalTrigger, null, { default: () => 'Open Modal' }),
34
+ },
35
+ })
36
+ expect(wrapper.text()).toContain('Open Modal')
37
+ })
38
+
39
+ it('renders trigger element with as-child behavior', () => {
40
+ // ModalTrigger uses as-child on DialogTrigger, so it renders the slot
41
+ // content directly rather than wrapping in its own button element.
42
+ const wrapper = mount(Modal, {
43
+ slots: {
44
+ default: () => h(ModalTrigger, null, { default: () => h('button', null, 'Trigger') }),
45
+ },
46
+ })
47
+ expect(wrapper.find('button').exists()).toBe(true)
48
+ expect(wrapper.text()).toContain('Trigger')
49
+ })
50
+ })
51
+
52
+ describe('ModalContent', () => {
53
+ it('mounts without errors when modal is open', async () => {
54
+ // ModalContent uses DialogPortal which teleports to body.
55
+ // In jsdom, we verify the component mounts and close button text appears.
56
+ const wrapper = mount(Modal, {
57
+ attrs: { open: true },
58
+ slots: {
59
+ default: () => h(ModalContent, null, { default: () => 'Modal body' }),
60
+ },
61
+ attachTo: document.body,
62
+ })
63
+ await nextTick()
64
+ expect(document.body.textContent).toContain('Close')
65
+ wrapper.unmount()
66
+ })
67
+
68
+ it('renders close button in portaled content', async () => {
69
+ const wrapper = mount(Modal, {
70
+ attrs: { open: true },
71
+ slots: {
72
+ default: () => h(ModalContent, null, { default: () => 'Body' }),
73
+ },
74
+ attachTo: document.body,
75
+ })
76
+ await nextTick()
77
+ const srOnly = document.body.querySelector('.sr-only')
78
+ expect(srOnly?.textContent).toBe('Close')
79
+ wrapper.unmount()
80
+ })
81
+ })
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ import { DialogRoot, type DialogRootEmits, type DialogRootProps } from 'radix-vue'
3
+
4
+ const props = defineProps<DialogRootProps>()
5
+ const emit = defineEmits<DialogRootEmits>()
6
+ </script>
7
+
8
+ <template>
9
+ <DialogRoot v-bind="props" @update:open="(v) => emit('update:open', v)">
10
+ <slot />
11
+ </DialogRoot>
12
+ </template>
@@ -0,0 +1,9 @@
1
+ <script setup lang="ts">
2
+ import { DialogClose } from 'radix-vue'
3
+ </script>
4
+
5
+ <template>
6
+ <DialogClose as-child>
7
+ <slot />
8
+ </DialogClose>
9
+ </template>
@@ -0,0 +1,32 @@
1
+ <script setup lang="ts">
2
+ import { DialogContent, DialogClose, DialogPortal, DialogOverlay } from 'radix-vue'
3
+ import { cn } from '@/lib/utils'
4
+
5
+ const props = defineProps<{ class?: string }>()
6
+ </script>
7
+
8
+ <template>
9
+ <DialogPortal>
10
+ <DialogOverlay class="fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" />
11
+ <DialogContent
12
+ :class="cn(
13
+ 'fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4',
14
+ 'border bg-background p-6 shadow-depth-5 duration-200 sm:rounded-lg',
15
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out',
16
+ 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
17
+ 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
18
+ props.class,
19
+ )"
20
+ >
21
+ <slot />
22
+ <DialogClose
23
+ class="absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
24
+ >
25
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4" aria-hidden="true">
26
+ <path d="M18 6 6 18" /><path d="m6 6 12 12" />
27
+ </svg>
28
+ <span class="sr-only">Close</span>
29
+ </DialogClose>
30
+ </DialogContent>
31
+ </DialogPortal>
32
+ </template>
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ import { DialogTrigger, type DialogTriggerProps } from 'radix-vue'
3
+
4
+ const props = defineProps<DialogTriggerProps>()
5
+ </script>
6
+
7
+ <template>
8
+ <DialogTrigger v-bind="props" as-child>
9
+ <slot />
10
+ </DialogTrigger>
11
+ </template>
@@ -0,0 +1,186 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import {
4
+ ComboboxAnchor,
5
+ ComboboxContent,
6
+ ComboboxEmpty,
7
+ ComboboxInput,
8
+ ComboboxPortal,
9
+ ComboboxRoot,
10
+ ComboboxViewport,
11
+ } from 'radix-vue'
12
+ import { cn } from '@/lib/utils'
13
+ import { computed, ref } from 'vue'
14
+ import MultiSelectItem from './MultiSelectItem.vue'
15
+
16
+ export interface MultiSelectOption {
17
+ label: string
18
+ value: string
19
+ }
20
+
21
+ const props = withDefaults(
22
+ defineProps<{
23
+ modelValue?: string[]
24
+ options?: MultiSelectOption[]
25
+ placeholder?: string
26
+ searchable?: boolean
27
+ maxItems?: number
28
+ class?: string
29
+ disabled?: boolean
30
+ }>(),
31
+ {
32
+ modelValue: () => [],
33
+ options: () => [],
34
+ placeholder: 'Select items...',
35
+ searchable: true,
36
+ disabled: false,
37
+ }
38
+ )
39
+
40
+ const emit = defineEmits<{
41
+ 'update:modelValue': [value: string[]]
42
+ }>()
43
+
44
+ const open = ref(false)
45
+ const searchTerm = ref('')
46
+
47
+ const selectedValues = computed({
48
+ get: () => props.modelValue,
49
+ set: (val: string[]) => emit('update:modelValue', val),
50
+ })
51
+
52
+ const filteredOptions = computed(() => {
53
+ if (!searchTerm.value) return props.options
54
+ const term = searchTerm.value.toLowerCase()
55
+ return props.options.filter((opt) =>
56
+ opt.label.toLowerCase().includes(term)
57
+ )
58
+ })
59
+
60
+ const selectedLabels = computed(() => {
61
+ return props.modelValue
62
+ .map((val) => props.options.find((opt) => opt.value === val))
63
+ .filter(Boolean) as MultiSelectOption[]
64
+ })
65
+
66
+ const isMaxReached = computed(() => {
67
+ return props.maxItems !== undefined && props.modelValue.length >= props.maxItems
68
+ })
69
+
70
+ function removeItem(value: string) {
71
+ emit(
72
+ 'update:modelValue',
73
+ props.modelValue.filter((v) => v !== value)
74
+ )
75
+ }
76
+ </script>
77
+
78
+ <template>
79
+ <ComboboxRoot
80
+ v-model="selectedValues"
81
+ v-model:open="open"
82
+ v-model:searchTerm="searchTerm"
83
+ multiple
84
+ :disabled="disabled"
85
+ v-bind="$attrs"
86
+ :class="cn('relative', props.class)"
87
+ >
88
+ <ComboboxAnchor
89
+ :class="
90
+ cn(
91
+ 'flex min-h-10 w-full flex-wrap items-center gap-1 rounded-lg border border-input bg-background px-3 py-2 text-sm ring-offset-background shadow-depth-1',
92
+ 'focus-within:outline-none focus-within:ring-2 focus-within:ring-primary/20 focus-within:ring-offset-2',
93
+ disabled && 'cursor-not-allowed opacity-50'
94
+ )
95
+ "
96
+ >
97
+ <span
98
+ v-for="item in selectedLabels"
99
+ :key="item.value"
100
+ class="inline-flex items-center gap-1 rounded-md bg-muted px-2 py-0.5 text-xs font-medium text-foreground"
101
+ >
102
+ {{ item.label }}
103
+ <button
104
+ type="button"
105
+ class="ml-0.5 rounded-sm opacity-70 ring-offset-background hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-primary/20 focus:ring-offset-2"
106
+ :disabled="disabled"
107
+ @pointerdown.prevent.stop="removeItem(item.value)"
108
+ >
109
+ <svg
110
+ xmlns="http://www.w3.org/2000/svg"
111
+ width="24"
112
+ height="24"
113
+ viewBox="0 0 24 24"
114
+ fill="none"
115
+ stroke="currentColor"
116
+ stroke-width="2"
117
+ stroke-linecap="round"
118
+ stroke-linejoin="round"
119
+ class="h-3 w-3"
120
+ >
121
+ <path d="M18 6 6 18" />
122
+ <path d="m6 6 12 12" />
123
+ </svg>
124
+ </button>
125
+ </span>
126
+
127
+ <ComboboxInput
128
+ v-if="searchable"
129
+ :placeholder="selectedLabels.length === 0 ? placeholder : ''"
130
+ class="ml-1 flex-1 bg-transparent text-sm text-foreground placeholder:text-muted-foreground outline-none disabled:cursor-not-allowed"
131
+ :disabled="disabled"
132
+ @keydown.enter.prevent
133
+ />
134
+ <span
135
+ v-else-if="selectedLabels.length === 0"
136
+ class="text-sm text-muted-foreground"
137
+ >
138
+ {{ placeholder }}
139
+ </span>
140
+
141
+ <svg
142
+ xmlns="http://www.w3.org/2000/svg"
143
+ width="24"
144
+ height="24"
145
+ viewBox="0 0 24 24"
146
+ fill="none"
147
+ stroke="currentColor"
148
+ stroke-width="2"
149
+ stroke-linecap="round"
150
+ stroke-linejoin="round"
151
+ class="ml-auto h-4 w-4 shrink-0 opacity-50"
152
+ >
153
+ <path d="m6 9 6 6 6-6" />
154
+ </svg>
155
+ </ComboboxAnchor>
156
+
157
+ <ComboboxPortal>
158
+ <ComboboxContent
159
+ position="popper"
160
+ :class="
161
+ cn(
162
+ 'relative z-depth-3 max-h-96 min-w-[var(--radix-combobox-trigger-width)] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-depth-3',
163
+ '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',
164
+ 'data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1',
165
+ 'data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2'
166
+ )
167
+ "
168
+ >
169
+ <ComboboxViewport class="p-1">
170
+ <ComboboxEmpty class="py-6 text-center text-sm text-muted-foreground">
171
+ No results found.
172
+ </ComboboxEmpty>
173
+
174
+ <MultiSelectItem
175
+ v-for="option in filteredOptions"
176
+ :key="option.value"
177
+ :value="option.value"
178
+ :label="option.label"
179
+ :selected="modelValue.includes(option.value)"
180
+ :disabled="!modelValue.includes(option.value) && isMaxReached"
181
+ />
182
+ </ComboboxViewport>
183
+ </ComboboxContent>
184
+ </ComboboxPortal>
185
+ </ComboboxRoot>
186
+ </template>
@@ -0,0 +1,47 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import { ComboboxItem, ComboboxItemIndicator } from 'radix-vue'
4
+ import { cn } from '@/lib/utils'
5
+
6
+ const props = defineProps<{
7
+ class?: string
8
+ value: string
9
+ label: string
10
+ selected?: boolean
11
+ disabled?: boolean
12
+ }>()
13
+ </script>
14
+
15
+ <template>
16
+ <ComboboxItem
17
+ v-bind="$attrs"
18
+ :value="props.value"
19
+ :disabled="props.disabled"
20
+ :class="
21
+ cn(
22
+ 'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
23
+ props.class
24
+ )
25
+ "
26
+ >
27
+ <span class="absolute left-2 flex h-4 w-4 items-center justify-center">
28
+ <ComboboxItemIndicator>
29
+ <svg
30
+ xmlns="http://www.w3.org/2000/svg"
31
+ width="24"
32
+ height="24"
33
+ viewBox="0 0 24 24"
34
+ fill="none"
35
+ stroke="currentColor"
36
+ stroke-width="2"
37
+ stroke-linecap="round"
38
+ stroke-linejoin="round"
39
+ class="h-4 w-4"
40
+ >
41
+ <path d="M20 6 9 17l-5-5" />
42
+ </svg>
43
+ </ComboboxItemIndicator>
44
+ </span>
45
+ <span>{{ props.label }}</span>
46
+ </ComboboxItem>
47
+ </template>
@@ -0,0 +1,41 @@
1
+ <script setup lang="ts">
2
+ import { cn } from '@/lib/utils'
3
+
4
+ interface Props {
5
+ class?: string
6
+ }
7
+
8
+ const props = defineProps<Props>()
9
+
10
+ defineOptions({ inheritAttrs: false })
11
+ </script>
12
+
13
+ <template>
14
+ <div class="relative">
15
+ <select
16
+ :class="
17
+ cn(
18
+ 'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 pr-10 text-sm',
19
+ 'ring-offset-background',
20
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
21
+ 'disabled:cursor-not-allowed disabled:opacity-50',
22
+ 'shadow-depth-1',
23
+ props.class
24
+ )
25
+ "
26
+ v-bind="$attrs"
27
+ >
28
+ <slot />
29
+ </select>
30
+ <svg
31
+ class="pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 opacity-50"
32
+ xmlns="http://www.w3.org/2000/svg"
33
+ viewBox="0 0 24 24"
34
+ fill="none"
35
+ stroke="currentColor"
36
+ stroke-width="2"
37
+ >
38
+ <path d="m6 9 6 6 6-6" />
39
+ </svg>
40
+ </div>
41
+ </template>
@@ -0,0 +1 @@
1
+ export { default as NativeSelect } from './NativeSelect.vue'
@@ -0,0 +1,23 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import { NavigationMenuRoot } from 'radix-vue'
4
+ import { cn } from '@/lib/utils'
5
+ import NavigationMenuViewport from './NavigationMenuViewport.vue'
6
+
7
+ const props = defineProps<{ class?: string }>()
8
+ </script>
9
+
10
+ <template>
11
+ <NavigationMenuRoot
12
+ v-bind="$attrs"
13
+ :class="
14
+ cn(
15
+ 'relative z-10 flex max-w-max flex-1 items-center justify-center',
16
+ props.class
17
+ )
18
+ "
19
+ >
20
+ <slot />
21
+ <NavigationMenuViewport />
22
+ </NavigationMenuRoot>
23
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import { NavigationMenuContent } from 'radix-vue'
4
+ import { cn } from '@/lib/utils'
5
+
6
+ const props = defineProps<{ class?: string }>()
7
+ </script>
8
+
9
+ <template>
10
+ <NavigationMenuContent
11
+ v-bind="$attrs"
12
+ :class="
13
+ cn(
14
+ 'left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto',
15
+ props.class
16
+ )
17
+ "
18
+ >
19
+ <slot />
20
+ </NavigationMenuContent>
21
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import { NavigationMenuIndicator } from 'radix-vue'
4
+ import { cn } from '@/lib/utils'
5
+
6
+ const props = defineProps<{ class?: string }>()
7
+ </script>
8
+
9
+ <template>
10
+ <NavigationMenuIndicator
11
+ v-bind="$attrs"
12
+ :class="
13
+ cn(
14
+ 'top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in',
15
+ props.class
16
+ )
17
+ "
18
+ >
19
+ <div class="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-depth-2" />
20
+ </NavigationMenuIndicator>
21
+ </template>
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+
4
+ import { NavigationMenuItem } from 'radix-vue'
5
+ </script>
6
+
7
+ <template>
8
+ <NavigationMenuItem v-bind="$attrs">
9
+ <slot />
10
+ </NavigationMenuItem>
11
+ </template>
@@ -0,0 +1,23 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import { NavigationMenuLink } from 'radix-vue'
4
+ import { cn } from '@/lib/utils'
5
+
6
+ const props = defineProps<{ class?: string }>()
7
+ const emits = defineEmits<{ 'select': [event: Event] }>()
8
+ </script>
9
+
10
+ <template>
11
+ <NavigationMenuLink
12
+ v-bind="$attrs"
13
+ :class="
14
+ cn(
15
+ 'group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50',
16
+ props.class
17
+ )
18
+ "
19
+ @select="emits('select', $event)"
20
+ >
21
+ <slot />
22
+ </NavigationMenuLink>
23
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import { NavigationMenuList } from 'radix-vue'
4
+ import { cn } from '@/lib/utils'
5
+
6
+ const props = defineProps<{ class?: string }>()
7
+ </script>
8
+
9
+ <template>
10
+ <NavigationMenuList
11
+ v-bind="$attrs"
12
+ :class="
13
+ cn(
14
+ 'group flex flex-1 list-none items-center justify-center space-x-1',
15
+ props.class
16
+ )
17
+ "
18
+ >
19
+ <slot />
20
+ </NavigationMenuList>
21
+ </template>
@@ -0,0 +1,36 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import { NavigationMenuTrigger } from 'radix-vue'
4
+ import { cn } from '@/lib/utils'
5
+
6
+ const props = defineProps<{ class?: string }>()
7
+ </script>
8
+
9
+ <template>
10
+ <NavigationMenuTrigger
11
+ v-bind="$attrs"
12
+ :class="
13
+ cn(
14
+ 'group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50',
15
+ props.class
16
+ )
17
+ "
18
+ >
19
+ <slot />
20
+ <svg
21
+ xmlns="http://www.w3.org/2000/svg"
22
+ width="24"
23
+ height="24"
24
+ viewBox="0 0 24 24"
25
+ fill="none"
26
+ stroke="currentColor"
27
+ stroke-width="2"
28
+ stroke-linecap="round"
29
+ stroke-linejoin="round"
30
+ class="relative top-px ml-1 h-3 w-3 transition duration-200 group-data-[state=open]:rotate-180"
31
+ aria-hidden="true"
32
+ >
33
+ <path d="m6 9 6 6 6-6" />
34
+ </svg>
35
+ </NavigationMenuTrigger>
36
+ </template>