@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,56 @@
1
+ <script setup lang="ts">
2
+ import { ToastRoot, type ToastRootEmits, useForwardPropsEmits, type ToastRootProps } from 'radix-vue'
3
+ import { cn } from '@/lib/utils'
4
+
5
+ const props = defineProps<ToastRootProps & { class?: string }>()
6
+ const emits = defineEmits<ToastRootEmits>()
7
+
8
+ const forwarded = useForwardPropsEmits(props, emits)
9
+ </script>
10
+
11
+ <template>
12
+ <ToastRoot
13
+ v-bind="forwarded"
14
+ :class="
15
+ cn(
16
+ 'spavn-toast group pointer-events-auto relative flex w-full items-center justify-between gap-4 overflow-hidden rounded-md border p-4 pr-8 shadow-depth-4',
17
+ 'data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)]',
18
+ 'data-[swipe=cancel]:translate-x-0',
19
+ props.class
20
+ )
21
+ "
22
+ >
23
+ <slot />
24
+ </ToastRoot>
25
+ </template>
26
+
27
+ <style>
28
+ .spavn-toast[data-state="open"] {
29
+ animation: spavn-toast-in 200ms ease-out;
30
+ }
31
+ .spavn-toast[data-state="closed"] {
32
+ animation: spavn-toast-out 150ms ease-in forwards;
33
+ }
34
+
35
+ @keyframes spavn-toast-in {
36
+ from {
37
+ opacity: 0;
38
+ transform: translateY(100%);
39
+ }
40
+ to {
41
+ opacity: 1;
42
+ transform: translateY(0);
43
+ }
44
+ }
45
+
46
+ @keyframes spavn-toast-out {
47
+ from {
48
+ opacity: 1;
49
+ transform: translateX(0);
50
+ }
51
+ to {
52
+ opacity: 0;
53
+ transform: translateX(100%);
54
+ }
55
+ }
56
+ </style>
@@ -0,0 +1,23 @@
1
+ <script setup lang="ts">
2
+ import { ToastAction, type ToastActionProps } from 'radix-vue'
3
+ import { cn } from '@/lib/utils'
4
+
5
+ const props = defineProps<ToastActionProps & { class?: string }>()
6
+ </script>
7
+
8
+ <template>
9
+ <ToastAction
10
+ v-bind="props"
11
+ :class="
12
+ cn(
13
+ 'inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
14
+ 'group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30',
15
+ 'group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground',
16
+ 'group-[.destructive]:focus:ring-destructive',
17
+ props.class
18
+ )
19
+ "
20
+ >
21
+ <slot />
22
+ </ToastAction>
23
+ </template>
@@ -0,0 +1,38 @@
1
+ <script setup lang="ts">
2
+ import { ToastClose, type ToastCloseProps } from 'radix-vue'
3
+ import { cn } from '@/lib/utils'
4
+
5
+ const props = defineProps<ToastCloseProps & { class?: string }>()
6
+ </script>
7
+
8
+ <template>
9
+ <ToastClose
10
+ v-bind="props"
11
+ aria-label="Close"
12
+ :class="
13
+ cn(
14
+ 'absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100',
15
+ 'group-[.destructive]:text-destructive-foreground group-[.destructive]:hover:text-destructive-foreground',
16
+ 'group-[.destructive]:focus:ring-destructive group-[.destructive]:focus:ring-offset-destructive',
17
+ props.class
18
+ )
19
+ "
20
+ >
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="h-4 w-4"
32
+ aria-hidden="true"
33
+ >
34
+ <path d="M18 6 6 18" />
35
+ <path d="m6 6 12 12" />
36
+ </svg>
37
+ </ToastClose>
38
+ </template>
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ import { ToastDescription, type ToastDescriptionProps } from 'radix-vue'
3
+ import { cn } from '@/lib/utils'
4
+
5
+ const props = defineProps<ToastDescriptionProps & { class?: string }>()
6
+ </script>
7
+
8
+ <template>
9
+ <ToastDescription v-bind="props" :class="cn('text-sm opacity-90', props.class)">
10
+ <slot />
11
+ </ToastDescription>
12
+ </template>
@@ -0,0 +1,65 @@
1
+ import { ref, computed } from 'vue'
2
+ import type { ToastProviderProps } from 'radix-vue'
3
+
4
+ export type ToastType = 'default' | 'success' | 'error' | 'warning' | 'info'
5
+
6
+ export interface Toast {
7
+ id: string
8
+ title?: string
9
+ description?: string
10
+ type?: ToastType
11
+ duration?: number
12
+ action?: {
13
+ label: string
14
+ onClick: () => void
15
+ }
16
+ }
17
+
18
+ const toasts = ref<Toast[]>([])
19
+
20
+ let toastIdCounter = 0
21
+
22
+ function generateId(): string {
23
+ return `toast-${++toastIdCounter}-${Date.now()}`
24
+ }
25
+
26
+ function addToast(toast: Omit<Toast, 'id'>): string {
27
+ const id = generateId()
28
+ const newToast: Toast = {
29
+ id,
30
+ duration: 5000,
31
+ ...toast,
32
+ }
33
+ toasts.value = [...toasts.value, newToast]
34
+ return id
35
+ }
36
+
37
+ function dismissToast(id: string) {
38
+ toasts.value = toasts.value.filter(t => t.id !== id)
39
+ }
40
+
41
+ function dismissAll() {
42
+ toasts.value = []
43
+ }
44
+
45
+ // Export the composable
46
+ export function useToast() {
47
+ return {
48
+ toasts: computed(() => toasts.value),
49
+ toast: addToast,
50
+ success: (title: string, description?: string, duration?: number) =>
51
+ addToast({ title, description, type: 'success', duration }),
52
+ error: (title: string, description?: string, duration?: number) =>
53
+ addToast({ title, description, type: 'error', duration }),
54
+ warning: (title: string, description?: string, duration?: number) =>
55
+ addToast({ title, description, type: 'warning', duration }),
56
+ info: (title: string, description?: string, duration?: number) =>
57
+ addToast({ title, description, type: 'info', duration }),
58
+ dismiss: dismissToast,
59
+ dismissAll,
60
+ }
61
+ }
62
+
63
+ // For backward compatibility with radix-vue
64
+ export { ToastProvider } from 'radix-vue'
65
+ export type { ToastProviderProps }
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ import { ToastTitle, type ToastTitleProps } from 'radix-vue'
3
+ import { cn } from '@/lib/utils'
4
+
5
+ const props = defineProps<ToastTitleProps & { class?: string }>()
6
+ </script>
7
+
8
+ <template>
9
+ <ToastTitle v-bind="props" :class="cn('text-sm font-semibold', props.class)">
10
+ <slot />
11
+ </ToastTitle>
12
+ </template>
@@ -0,0 +1,18 @@
1
+ <script setup lang="ts">
2
+ import { ToastViewport, type ToastViewportProps } from 'radix-vue'
3
+ import { cn } from '@/lib/utils'
4
+
5
+ const props = defineProps<ToastViewportProps & { class?: string }>()
6
+ </script>
7
+
8
+ <template>
9
+ <ToastViewport
10
+ v-bind="props"
11
+ :class="
12
+ cn(
13
+ 'fixed bottom-0 right-0 z-[99999] flex max-h-screen w-full flex-col gap-2 p-4 sm:max-w-[420px]',
14
+ props.class
15
+ )
16
+ "
17
+ />
18
+ </template>
@@ -0,0 +1,50 @@
1
+ <script setup lang="ts">
2
+ import { ToastProvider } from 'radix-vue'
3
+ import Toast from './Toast.vue'
4
+ import ToastViewport from './ToastViewport.vue'
5
+ import ToastTitle from './ToastTitle.vue'
6
+ import ToastDescription from './ToastDescription.vue'
7
+ import ToastAction from './ToastAction.vue'
8
+ import ToastClose from './ToastClose.vue'
9
+ import { useToast } from './ToastProvider'
10
+ import { cn } from '@/lib/utils'
11
+
12
+ const { toasts, dismiss } = useToast()
13
+
14
+ function onOpenChange(id: string, open: boolean) {
15
+ if (!open) {
16
+ dismiss(id)
17
+ }
18
+ }
19
+ </script>
20
+
21
+ <template>
22
+ <ToastProvider>
23
+ <Toast
24
+ v-for="t in toasts"
25
+ :key="t.id"
26
+ :duration="t.duration"
27
+ :default-open="true"
28
+ @update:open="(open: boolean) => onOpenChange(t.id, open)"
29
+ :class="cn(
30
+ 'bg-card text-card-foreground border',
31
+ t.type === 'error' && 'destructive border-destructive bg-destructive text-destructive-foreground',
32
+ )"
33
+ >
34
+ <div class="grid gap-1">
35
+ <ToastTitle v-if="t.title">{{ t.title }}</ToastTitle>
36
+ <ToastDescription v-if="t.description">{{ t.description }}</ToastDescription>
37
+ </div>
38
+ <ToastAction
39
+ v-if="t.action"
40
+ :alt-text="t.action.label"
41
+ @click="t.action.onClick"
42
+ >
43
+ {{ t.action.label }}
44
+ </ToastAction>
45
+ <ToastClose />
46
+ </Toast>
47
+
48
+ <ToastViewport />
49
+ </ToastProvider>
50
+ </template>
@@ -0,0 +1,7 @@
1
+ export { default as Toast } from './Toast.vue'
2
+ export { default as ToastViewport } from './ToastViewport.vue'
3
+ export { default as ToastTitle } from './ToastTitle.vue'
4
+ export { default as ToastDescription } from './ToastDescription.vue'
5
+ export { default as ToastAction } from './ToastAction.vue'
6
+ export { default as ToastClose } from './ToastClose.vue'
7
+ export { useToast } from './ToastProvider'
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import { Toggle } from 'radix-vue'
4
+ import { cn } from '@/lib/utils'
5
+ import { toggleVariants } from './variants'
6
+
7
+ const props = defineProps<{
8
+ class?: string
9
+ variant?: 'default' | 'outline'
10
+ size?: 'default' | 'sm' | 'lg'
11
+ }>()
12
+ </script>
13
+
14
+ <template>
15
+ <Toggle
16
+ v-bind="$attrs"
17
+ :class="cn(toggleVariants({ variant: props.variant, size: props.size }), props.class)"
18
+ >
19
+ <slot />
20
+ </Toggle>
21
+ </template>
@@ -0,0 +1,2 @@
1
+ export { default as Toggle } from './Toggle.vue'
2
+ export { toggleVariants, type ToggleVariants } from './variants'
@@ -0,0 +1,87 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { toggleVariants } from './variants'
3
+
4
+ describe('toggleVariants', () => {
5
+ describe('defaults', () => {
6
+ it('returns expected classes with no arguments (default variant and size)', () => {
7
+ const result = toggleVariants()
8
+ expect(result).toContain('inline-flex')
9
+ expect(result).toContain('items-center')
10
+ expect(result).toContain('justify-center')
11
+ expect(result).toContain('rounded-md')
12
+ expect(result).toContain('bg-transparent')
13
+ expect(result).toContain('h-10')
14
+ expect(result).toContain('px-3')
15
+ })
16
+ })
17
+
18
+ describe('variant', () => {
19
+ it('default variant applies transparent background', () => {
20
+ const result = toggleVariants({ variant: 'default' })
21
+ expect(result).toContain('bg-transparent')
22
+ expect(result).not.toContain('border-input')
23
+ })
24
+
25
+ it('outline variant includes border and hover styles', () => {
26
+ const result = toggleVariants({ variant: 'outline' })
27
+ expect(result).toContain('border')
28
+ expect(result).toContain('border-input')
29
+ expect(result).toContain('bg-transparent')
30
+ expect(result).toContain('hover:bg-accent')
31
+ expect(result).toContain('hover:text-accent-foreground')
32
+ })
33
+ })
34
+
35
+ describe('size', () => {
36
+ it('default size applies h-10 and px-3', () => {
37
+ const result = toggleVariants({ size: 'default' })
38
+ expect(result).toContain('h-10')
39
+ expect(result).toContain('px-3')
40
+ })
41
+
42
+ it('sm size applies h-9 and px-2.5', () => {
43
+ const result = toggleVariants({ size: 'sm' })
44
+ expect(result).toContain('h-9')
45
+ expect(result).toContain('px-2.5')
46
+ })
47
+
48
+ it('lg size applies h-11 and px-5', () => {
49
+ const result = toggleVariants({ size: 'lg' })
50
+ expect(result).toContain('h-11')
51
+ expect(result).toContain('px-5')
52
+ })
53
+ })
54
+
55
+ describe('combining variant + size', () => {
56
+ it('outline + lg combines both variant and size classes', () => {
57
+ const result = toggleVariants({ variant: 'outline', size: 'lg' })
58
+ expect(result).toContain('border')
59
+ expect(result).toContain('border-input')
60
+ expect(result).toContain('h-11')
61
+ expect(result).toContain('px-5')
62
+ })
63
+
64
+ it('default + sm combines both variant and size classes', () => {
65
+ const result = toggleVariants({ variant: 'default', size: 'sm' })
66
+ expect(result).toContain('bg-transparent')
67
+ expect(result).toContain('h-9')
68
+ expect(result).toContain('px-2.5')
69
+ })
70
+ })
71
+
72
+ describe('base classes', () => {
73
+ it('all variants include disabled and focus-visible styles', () => {
74
+ const result = toggleVariants()
75
+ expect(result).toContain('disabled:pointer-events-none')
76
+ expect(result).toContain('disabled:opacity-50')
77
+ expect(result).toContain('focus-visible:outline-none')
78
+ expect(result).toContain('focus-visible:ring-2')
79
+ })
80
+
81
+ it('all variants include data-state=on styles', () => {
82
+ const result = toggleVariants()
83
+ expect(result).toContain('data-[state=on]:bg-accent')
84
+ expect(result).toContain('data-[state=on]:text-accent-foreground')
85
+ })
86
+ })
87
+ })
@@ -0,0 +1,21 @@
1
+ import { cva, type VariantProps } from 'class-variance-authority'
2
+
3
+ export const toggleVariants = cva(
4
+ 'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground',
5
+ {
6
+ variants: {
7
+ variant: {
8
+ default: 'bg-transparent',
9
+ outline: 'border border-input bg-transparent hover:bg-accent hover:text-accent-foreground',
10
+ },
11
+ size: {
12
+ default: 'h-10 px-3',
13
+ sm: 'h-9 px-2.5',
14
+ lg: 'h-11 px-5',
15
+ },
16
+ },
17
+ defaultVariants: { variant: 'default', size: 'default' },
18
+ }
19
+ )
20
+
21
+ export type ToggleVariants = VariantProps<typeof toggleVariants>
@@ -0,0 +1,24 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import { ToggleGroupRoot } from 'radix-vue'
4
+ import { provide } from 'vue'
5
+ import { cn } from '@/lib/utils'
6
+
7
+ const props = defineProps<{
8
+ class?: string
9
+ variant?: 'default' | 'outline'
10
+ size?: 'default' | 'sm' | 'lg'
11
+ }>()
12
+
13
+ provide('toggleGroupVariant', props.variant)
14
+ provide('toggleGroupSize', props.size)
15
+ </script>
16
+
17
+ <template>
18
+ <ToggleGroupRoot
19
+ v-bind="$attrs"
20
+ :class="cn('flex items-center justify-center gap-1', props.class)"
21
+ >
22
+ <slot />
23
+ </ToggleGroupRoot>
24
+ </template>
@@ -0,0 +1,33 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import { ToggleGroupItem } from 'radix-vue'
4
+ import { inject } from 'vue'
5
+ import { cn } from '@/lib/utils'
6
+ import { toggleVariants } from '../toggle/variants'
7
+
8
+ const props = defineProps<{
9
+ class?: string
10
+ variant?: 'default' | 'outline'
11
+ size?: 'default' | 'sm' | 'lg'
12
+ }>()
13
+
14
+ const groupVariant = inject<'default' | 'outline' | undefined>('toggleGroupVariant', undefined)
15
+ const groupSize = inject<'default' | 'sm' | 'lg' | undefined>('toggleGroupSize', undefined)
16
+ </script>
17
+
18
+ <template>
19
+ <ToggleGroupItem
20
+ v-bind="$attrs"
21
+ :class="
22
+ cn(
23
+ toggleVariants({
24
+ variant: props.variant || groupVariant,
25
+ size: props.size || groupSize,
26
+ }),
27
+ props.class
28
+ )
29
+ "
30
+ >
31
+ <slot />
32
+ </ToggleGroupItem>
33
+ </template>
@@ -0,0 +1,2 @@
1
+ export { default as ToggleGroup } from './ToggleGroup.vue'
2
+ export { default as ToggleGroupItem } from './ToggleGroupItem.vue'
@@ -0,0 +1,87 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import { h } from 'vue'
4
+ import Tooltip from './Tooltip.vue'
5
+ import TooltipProvider from './TooltipProvider.vue'
6
+ import TooltipTrigger from './TooltipTrigger.vue'
7
+ import TooltipContent from './TooltipContent.vue'
8
+
9
+ function mountWithProvider(tooltipSlots: Record<string, unknown>) {
10
+ return mount(TooltipProvider, {
11
+ slots: {
12
+ default: () => h(Tooltip, null, tooltipSlots),
13
+ },
14
+ })
15
+ }
16
+
17
+ describe('Tooltip', () => {
18
+ it('renders without errors', () => {
19
+ const wrapper = mountWithProvider({
20
+ default: () => 'Tooltip child',
21
+ })
22
+ expect(wrapper.exists()).toBe(true)
23
+ })
24
+ })
25
+
26
+ describe('TooltipProvider', () => {
27
+ it('renders without errors', () => {
28
+ const wrapper = mount(TooltipProvider, {
29
+ slots: { default: 'Provider content' },
30
+ })
31
+ expect(wrapper.exists()).toBe(true)
32
+ expect(wrapper.text()).toContain('Provider content')
33
+ })
34
+ })
35
+
36
+ describe('TooltipTrigger', () => {
37
+ it('renders slot content', () => {
38
+ const wrapper = mountWithProvider({
39
+ default: () => h(TooltipTrigger, null, { default: () => 'Hover me' }),
40
+ })
41
+ expect(wrapper.text()).toContain('Hover me')
42
+ })
43
+
44
+ it('renders as a button', () => {
45
+ const wrapper = mountWithProvider({
46
+ default: () => h(TooltipTrigger, null, { default: () => 'Trigger' }),
47
+ })
48
+ expect(wrapper.find('button').exists()).toBe(true)
49
+ })
50
+ })
51
+
52
+ describe('TooltipContent', () => {
53
+ it('mounts without errors when tooltip is rendered', () => {
54
+ // TooltipContent uses a portal, so we verify the component tree mounts
55
+ // without throwing rather than checking portal content directly
56
+ const wrapper = mountWithProvider({
57
+ default: () => [
58
+ h(TooltipTrigger, null, { default: () => 'Trigger' }),
59
+ h(TooltipContent, null, { default: () => 'Tooltip text' }),
60
+ ],
61
+ })
62
+ expect(wrapper.exists()).toBe(true)
63
+ wrapper.unmount()
64
+ })
65
+
66
+ it('accepts sideOffset prop', () => {
67
+ const wrapper = mountWithProvider({
68
+ default: () => [
69
+ h(TooltipTrigger, null, { default: () => 'Trigger' }),
70
+ h(TooltipContent, { sideOffset: 8 }, { default: () => 'Offset tooltip' }),
71
+ ],
72
+ })
73
+ expect(wrapper.exists()).toBe(true)
74
+ wrapper.unmount()
75
+ })
76
+
77
+ it('accepts custom class prop', () => {
78
+ const wrapper = mountWithProvider({
79
+ default: () => [
80
+ h(TooltipTrigger, null, { default: () => 'Trigger' }),
81
+ h(TooltipContent, { class: 'custom-tooltip' }, { default: () => 'Styled' }),
82
+ ],
83
+ })
84
+ expect(wrapper.exists()).toBe(true)
85
+ wrapper.unmount()
86
+ })
87
+ })
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+
4
+ import { TooltipRoot } from 'radix-vue'
5
+ </script>
6
+
7
+ <template>
8
+ <TooltipRoot v-bind="$attrs">
9
+ <slot />
10
+ </TooltipRoot>
11
+ </template>
@@ -0,0 +1,30 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import {
4
+ TooltipContent,
5
+ TooltipPortal,
6
+ } from 'radix-vue'
7
+ import { cn } from '@/lib/utils'
8
+
9
+ const props = withDefaults(defineProps<{ class?: string; sideOffset?: number }>(), { sideOffset: 4 })
10
+ </script>
11
+
12
+ <template>
13
+ <TooltipPortal>
14
+ <TooltipContent
15
+ v-bind="$attrs"
16
+ :side-offset="props.sideOffset"
17
+ :class="
18
+ cn(
19
+ 'z-depth-4 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-depth-2',
20
+ 'animate-in fade-in-0 zoom-in-95',
21
+ 'data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95',
22
+ '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',
23
+ props.class
24
+ )
25
+ "
26
+ >
27
+ <slot />
28
+ </TooltipContent>
29
+ </TooltipPortal>
30
+ </template>
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+
4
+ import { TooltipProvider } from 'radix-vue'
5
+ </script>
6
+
7
+ <template>
8
+ <TooltipProvider v-bind="$attrs">
9
+ <slot />
10
+ </TooltipProvider>
11
+ </template>
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+
4
+ import { TooltipTrigger } from 'radix-vue'
5
+ </script>
6
+
7
+ <template>
8
+ <TooltipTrigger v-bind="$attrs">
9
+ <slot />
10
+ </TooltipTrigger>
11
+ </template>
@@ -0,0 +1,4 @@
1
+ export { default as Tooltip } from './Tooltip.vue'
2
+ export { default as TooltipProvider } from './TooltipProvider.vue'
3
+ export { default as TooltipTrigger } from './TooltipTrigger.vue'
4
+ export { default as TooltipContent } from './TooltipContent.vue'
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ import { cn } from '@/lib/utils'
3
+
4
+ const props = defineProps<{ class?: string }>()
5
+ </script>
6
+
7
+ <template>
8
+ <blockquote :class="cn('mt-6 border-l-2 pl-6 italic', props.class)">
9
+ <slot />
10
+ </blockquote>
11
+ </template>