@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,179 @@
1
+ <script setup lang="ts">
2
+ import { computed, type Component } from 'vue'
3
+ import { cn } from '@/lib/utils'
4
+ import { Card, CardContent, CardHeader, CardTitle } from '@/lib/card'
5
+ import { Badge } from '@/lib/badge'
6
+
7
+ export interface StatsCardProps {
8
+ /** Card title displayed in the header */
9
+ title: string
10
+ /** Main value/metric to display */
11
+ value: string | number
12
+ /** Optional subtitle text (e.g., "remaining of $10,000") */
13
+ subtitle?: string
14
+ /** Progress value (0-100) for the progress bar */
15
+ progress?: number
16
+ /** Badge text to display in the header */
17
+ badge?: string
18
+ /** Badge variant style */
19
+ badgeVariant?: 'default' | 'secondary' | 'destructive' | 'outline'
20
+ /** Icon component to display next to the title */
21
+ icon?: Component
22
+ /** Trend indicator showing value change */
23
+ trend?: {
24
+ value: number
25
+ direction: 'up' | 'down'
26
+ }
27
+ /** Footer text displayed at the bottom */
28
+ footer?: string
29
+ /** Custom class for the card */
30
+ class?: string
31
+ /** Card elevation/shadow level */
32
+ elevation?: 0 | 1 | 2 | 3
33
+ /** Progress bar color based on thresholds */
34
+ progressColor?: 'default' | 'warning' | 'danger' | 'success' | 'auto'
35
+ }
36
+
37
+ const props = withDefaults(defineProps<StatsCardProps>(), {
38
+ badgeVariant: 'default',
39
+ elevation: 2,
40
+ progressColor: 'auto',
41
+ })
42
+
43
+ /**
44
+ * Determines the progress bar color based on the progress value
45
+ * when progressColor is set to 'auto'
46
+ * - 0-50: Success (green)
47
+ * - 51-75: Warning (yellow)
48
+ * - 76-100: Danger (red)
49
+ */
50
+ const progressBarClass = computed(() => {
51
+ const progress = props.progress ?? 0
52
+
53
+ if (props.progressColor !== 'auto') {
54
+ const colorMap: Record<string, string> = {
55
+ default: 'bg-primary',
56
+ warning: 'bg-muted',
57
+ danger: 'bg-destructive',
58
+ success: 'bg-success',
59
+ }
60
+ return colorMap[props.progressColor] || 'bg-primary'
61
+ }
62
+
63
+ // Auto color based on progress value
64
+ if (progress >= 76) return 'bg-destructive'
65
+ if (progress >= 51) return 'bg-muted'
66
+ return 'bg-success'
67
+ })
68
+
69
+ /**
70
+ * Trend indicator classes based on direction
71
+ */
72
+ const trendClasses = computed(() => {
73
+ if (!props.trend) return ''
74
+ return props.trend.direction === 'up'
75
+ ? 'text-success'
76
+ : 'text-destructive'
77
+ })
78
+ </script>
79
+
80
+ <template>
81
+ <Card
82
+ :class="cn('stats-card overflow-hidden', props.class)"
83
+ :elevation="elevation"
84
+ >
85
+ <CardHeader class="flex flex-row items-center justify-between pb-2">
86
+ <CardTitle
87
+ :class="
88
+ cn(
89
+ 'text-sm font-medium text-card-foreground flex items-center gap-2'
90
+ )
91
+ "
92
+ >
93
+ <component
94
+ :is="icon"
95
+ v-if="icon"
96
+ class="h-4 w-4 text-muted-foreground"
97
+ />
98
+ {{ title }}
99
+ </CardTitle>
100
+ <Badge v-if="badge" :variant="badgeVariant">
101
+ {{ badge }}
102
+ </Badge>
103
+ </CardHeader>
104
+
105
+ <CardContent class="space-y-3">
106
+ <!-- Progress bar -->
107
+ <div v-if="progress !== undefined" class="progress-wrapper">
108
+ <div class="relative h-1 w-full overflow-hidden rounded-full bg-muted">
109
+ <div
110
+ class="h-full w-full flex-1 transition-all duration-500 ease-out"
111
+ :class="progressBarClass"
112
+ :style="{ transform: `translateX(-${100 - progress}%)` }"
113
+ />
114
+ </div>
115
+ </div>
116
+
117
+ <!-- Value display with trend -->
118
+ <div class="flex items-baseline gap-2">
119
+ <span class="text-3xl font-bold tracking-tight text-card-foreground">
120
+ {{ value }}
121
+ </span>
122
+ <span
123
+ v-if="trend"
124
+ class="flex items-center text-sm font-medium"
125
+ :class="trendClasses"
126
+ >
127
+ <svg
128
+ v-if="trend.direction === 'up'"
129
+ class="mr-0.5 h-3 w-3"
130
+ viewBox="0 0 24 24"
131
+ fill="none"
132
+ stroke="currentColor"
133
+ stroke-width="2"
134
+ stroke-linecap="round"
135
+ stroke-linejoin="round"
136
+ >
137
+ <path d="m18 15-6-6-6 6" />
138
+ </svg>
139
+ <svg
140
+ v-else
141
+ class="mr-0.5 h-3 w-3"
142
+ viewBox="0 0 24 24"
143
+ fill="none"
144
+ stroke="currentColor"
145
+ stroke-width="2"
146
+ stroke-linecap="round"
147
+ stroke-linejoin="round"
148
+ >
149
+ <path d="m6 9 6 6 6-6" />
150
+ </svg>
151
+ {{ trend.value }}%
152
+ </span>
153
+ </div>
154
+
155
+ <!-- Subtitle -->
156
+ <p v-if="subtitle" class="text-sm text-muted-foreground">
157
+ {{ subtitle }}
158
+ </p>
159
+
160
+ <!-- Footer -->
161
+ <p
162
+ v-if="footer"
163
+ class="pt-2 text-xs text-muted-foreground border-t border-border/50"
164
+ >
165
+ {{ footer }}
166
+ </p>
167
+ </CardContent>
168
+ </Card>
169
+ </template>
170
+
171
+ <style scoped>
172
+ .stats-card {
173
+ /* Custom styles if needed */
174
+ }
175
+
176
+ .progress-wrapper {
177
+ margin-bottom: 0.75rem;
178
+ }
179
+ </style>
@@ -0,0 +1,2 @@
1
+ export { default as StatsCard } from './StatsCard.vue'
2
+ export type { StatsCardProps } from './StatsCard.vue'
@@ -0,0 +1,133 @@
1
+ /**
2
+ * CSS Variables for Depth Design System
3
+ * Include these in your :root and .dark selectors
4
+ */
5
+
6
+ export const baseStyles = `
7
+ :root {
8
+ /* Background - warm light gray */
9
+ --background: 0 0% 96%;
10
+ --foreground: 0 0% 9%;
11
+
12
+ /* Card surfaces - pure white with elevated variants */
13
+ --card: 0 0% 100%;
14
+ --card-foreground: 0 0% 9%;
15
+ --card-elevated-1: 0 0% 100%;
16
+ --card-elevated-2: 0 0% 100%;
17
+
18
+ /* Interactive surfaces */
19
+ --popover: 0 0% 100%;
20
+ --popover-foreground: 0 0% 9%;
21
+
22
+ /* Primary colors - black */
23
+ --primary: 0 0% 9%;
24
+ --primary-foreground: 0 0% 98%;
25
+
26
+ /* Secondary colors - light gray */
27
+ --secondary: 0 0% 93%;
28
+ --secondary-foreground: 0 0% 9%;
29
+
30
+ /* Muted - lighter gray */
31
+ --muted: 0 0% 93%;
32
+ --muted-foreground: 0 0% 45%;
33
+
34
+ /* Accent */
35
+ --accent: 0 0% 93%;
36
+ --accent-foreground: 0 0% 9%;
37
+
38
+ /* Destructive - red */
39
+ --destructive: 0 84% 60%;
40
+ --destructive-foreground: 0 0% 98%;
41
+
42
+ /* Success - green */
43
+ --success: 142 76% 36%;
44
+ --success-foreground: 0 0% 98%;
45
+
46
+ /* Borders & Inputs */
47
+ --border: 0 0% 90%;
48
+ --input: 0 0% 90%;
49
+ --ring: 0 0% 9%;
50
+
51
+ /* Radius - updated to match design system */
52
+ --radius: 1rem;
53
+
54
+ /* Elevation opacity overlays for depth perception - softer values */
55
+ --elevation-overlay-1: rgba(0, 0, 0, 0.02);
56
+ --elevation-overlay-2: rgba(0, 0, 0, 0.04);
57
+ --elevation-overlay-3: rgba(0, 0, 0, 0.05);
58
+ --elevation-overlay-4: rgba(0, 0, 0, 0.05);
59
+ --elevation-overlay-5: rgba(0, 0, 0, 0.1);
60
+
61
+ /* Shadow tokens */
62
+ --shadow-depth-1: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.02);
63
+ --shadow-depth-2: 0 4px 6px -1px rgba(0, 0, 0, 0.04), 0 2px 4px -2px rgba(0, 0, 0, 0.02);
64
+ --shadow-depth-3: 0 10px 15px -3px rgba(0, 0, 0, 0.05), 0 4px 6px -4px rgba(0, 0, 0, 0.02);
65
+ --shadow-depth-4: 0 20px 25px -5px rgba(0, 0, 0, 0.05), 0 8px 10px -6px rgba(0, 0, 0, 0.01);
66
+ --shadow-depth-5: 0 25px 50px -12px rgba(0, 0, 0, 0.1);
67
+ }
68
+
69
+ .dark {
70
+ /* Background - near black */
71
+ --background: 0 0% 7%;
72
+ --foreground: 0 0% 98%;
73
+
74
+ /* Card surfaces - dark gray */
75
+ --card: 0 0% 10%;
76
+ --card-foreground: 0 0% 98%;
77
+ --card-elevated-1: 0 0% 13%;
78
+ --card-elevated-2: 0 0% 16%;
79
+
80
+ /* Interactive surfaces */
81
+ --popover: 0 0% 10%;
82
+ --popover-foreground: 0 0% 98%;
83
+
84
+ /* Primary colors - white */
85
+ --primary: 0 0% 98%;
86
+ --primary-foreground: 0 0% 9%;
87
+
88
+ /* Secondary colors - dark gray */
89
+ --secondary: 0 0% 15%;
90
+ --secondary-foreground: 0 0% 98%;
91
+
92
+ /* Muted */
93
+ --muted: 0 0% 15%;
94
+ --muted-foreground: 0 0% 65%;
95
+
96
+ /* Accent */
97
+ --accent: 0 0% 15%;
98
+ --accent-foreground: 0 0% 98%;
99
+
100
+ /* Destructive */
101
+ --destructive: 0 72% 51%;
102
+ --destructive-foreground: 0 0% 98%;
103
+
104
+ /* Success */
105
+ --success: 142 71% 45%;
106
+ --success-foreground: 0 0% 7%;
107
+
108
+ /* Borders & Inputs */
109
+ --border: 0 0% 20%;
110
+ --input: 0 0% 20%;
111
+ --ring: 0 0% 80%;
112
+
113
+ /* Elevation opacity overlays for depth perception (inverted for dark mode) */
114
+ --elevation-overlay-1: rgba(255, 255, 255, 0.03);
115
+ --elevation-overlay-2: rgba(255, 255, 255, 0.06);
116
+ --elevation-overlay-3: rgba(255, 255, 255, 0.08);
117
+ --elevation-overlay-4: rgba(255, 255, 255, 0.1);
118
+ --elevation-overlay-5: rgba(255, 255, 255, 0.14);
119
+
120
+ /* Shadow tokens for dark mode */
121
+ --shadow-depth-1: 0 1px 3px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.15);
122
+ --shadow-depth-2: 0 4px 6px -1px rgba(0, 0, 0, 0.2), 0 2px 4px -2px rgba(0, 0, 0, 0.15);
123
+ --shadow-depth-3: 0 10px 15px -3px rgba(0, 0, 0, 0.25), 0 4px 6px -4px rgba(0, 0, 0, 0.15);
124
+ --shadow-depth-4: 0 20px 25px -5px rgba(0, 0, 0, 0.25), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
125
+ --shadow-depth-5: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
126
+ }
127
+ `
128
+
129
+ export const baseStylesWithCSSVariables = `
130
+ @layer base {
131
+ ${baseStyles}
132
+ }
133
+ `
@@ -0,0 +1,52 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import Switch from './Switch.vue'
4
+
5
+ describe('Switch', () => {
6
+ it('renders correctly', () => {
7
+ const wrapper = mount(Switch)
8
+ expect(wrapper.exists()).toBe(true)
9
+ })
10
+
11
+ it('renders with checked prop', () => {
12
+ const wrapper = mount(Switch, {
13
+ props: { checked: true },
14
+ })
15
+ expect(wrapper.exists()).toBe(true)
16
+ })
17
+
18
+ it('renders unchecked by default', () => {
19
+ const wrapper = mount(Switch, {
20
+ props: { checked: false },
21
+ })
22
+ expect(wrapper.exists()).toBe(true)
23
+ })
24
+
25
+ it('passes disabled attribute', () => {
26
+ const wrapper = mount(Switch, {
27
+ attrs: { disabled: true },
28
+ })
29
+ expect(wrapper.exists()).toBe(true)
30
+ })
31
+
32
+ it('has correct data-state when checked', () => {
33
+ const wrapper = mount(Switch, {
34
+ props: { checked: true },
35
+ })
36
+ expect(wrapper.html()).toContain('data-state="checked"')
37
+ })
38
+
39
+ it('has correct data-state when unchecked', () => {
40
+ const wrapper = mount(Switch, {
41
+ props: { checked: false },
42
+ })
43
+ expect(wrapper.html()).toContain('data-state="unchecked"')
44
+ })
45
+
46
+ it('applies custom class', () => {
47
+ const wrapper = mount(Switch, {
48
+ props: { class: 'custom-switch' },
49
+ })
50
+ expect(wrapper.html()).toContain('custom-switch')
51
+ })
52
+ })
@@ -0,0 +1,43 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import {
4
+ SwitchRoot,
5
+ SwitchThumb,
6
+ } from 'radix-vue'
7
+ import { cn } from '@/lib/utils'
8
+
9
+ interface Props {
10
+ class?: string
11
+ checked?: boolean
12
+ }
13
+
14
+ const props = defineProps<Props>()
15
+ </script>
16
+
17
+ <template>
18
+ <SwitchRoot
19
+ v-bind="$attrs"
20
+ :checked="checked"
21
+ :class="
22
+ cn(
23
+ 'peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-depth-1',
24
+ 'bg-muted data-[state=checked]:bg-primary',
25
+ 'ring-offset-background transition-all duration-150 ease-out',
26
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
27
+ 'disabled:cursor-not-allowed disabled:opacity-50',
28
+ 'hover:shadow-depth-2',
29
+ props.class
30
+ )
31
+ "
32
+ >
33
+ <SwitchThumb
34
+ :class="
35
+ cn(
36
+ 'pointer-events-none block h-5 w-5 rounded-full bg-background shadow-depth-2',
37
+ 'ring-0 transition-transform duration-150 ease-out',
38
+ 'data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0'
39
+ )
40
+ "
41
+ />
42
+ </SwitchRoot>
43
+ </template>
@@ -0,0 +1,150 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import Table from './Table.vue'
4
+ import TableHeader from './TableHeader.vue'
5
+ import TableBody from './TableBody.vue'
6
+ import TableRow from './TableRow.vue'
7
+ import TableHead from './TableHead.vue'
8
+ import TableCell from './TableCell.vue'
9
+
10
+ describe('Table', () => {
11
+ it('renders correctly', () => {
12
+ const wrapper = mount(Table)
13
+ expect(wrapper.exists()).toBe(true)
14
+ expect(wrapper.find('table').exists()).toBe(true)
15
+ })
16
+
17
+ it('renders slot content', () => {
18
+ const wrapper = mount(Table, {
19
+ slots: { default: '<tbody><tr><td>Cell</td></tr></tbody>' },
20
+ })
21
+ expect(wrapper.text()).toContain('Cell')
22
+ })
23
+
24
+ it('applies custom class to table element', () => {
25
+ const wrapper = mount(Table, {
26
+ props: { class: 'my-table' },
27
+ })
28
+ expect(wrapper.find('table').classes()).toContain('my-table')
29
+ })
30
+ })
31
+
32
+ describe('TableHeader', () => {
33
+ it('renders correctly', () => {
34
+ const wrapper = mount(TableHeader, {
35
+ slots: { default: '<tr><th>Header</th></tr>' },
36
+ })
37
+ expect(wrapper.element.tagName).toBe('THEAD')
38
+ expect(wrapper.text()).toContain('Header')
39
+ })
40
+
41
+ it('applies custom class', () => {
42
+ const wrapper = mount(TableHeader, {
43
+ props: { class: 'header-class' },
44
+ slots: { default: '<tr><th>H</th></tr>' },
45
+ })
46
+ expect(wrapper.classes()).toContain('header-class')
47
+ })
48
+ })
49
+
50
+ describe('TableBody', () => {
51
+ it('renders correctly', () => {
52
+ const wrapper = mount(TableBody, {
53
+ slots: { default: '<tr><td>Body</td></tr>' },
54
+ })
55
+ expect(wrapper.element.tagName).toBe('TBODY')
56
+ expect(wrapper.text()).toContain('Body')
57
+ })
58
+
59
+ it('applies custom class', () => {
60
+ const wrapper = mount(TableBody, {
61
+ props: { class: 'body-class' },
62
+ slots: { default: '<tr><td>B</td></tr>' },
63
+ })
64
+ expect(wrapper.classes()).toContain('body-class')
65
+ })
66
+ })
67
+
68
+ describe('TableRow', () => {
69
+ it('renders correctly', () => {
70
+ const wrapper = mount(TableRow, {
71
+ slots: { default: '<td>Row</td>' },
72
+ })
73
+ expect(wrapper.element.tagName).toBe('TR')
74
+ expect(wrapper.text()).toContain('Row')
75
+ })
76
+
77
+ it('applies custom class', () => {
78
+ const wrapper = mount(TableRow, {
79
+ props: { class: 'row-class' },
80
+ slots: { default: '<td>R</td>' },
81
+ })
82
+ expect(wrapper.classes()).toContain('row-class')
83
+ })
84
+ })
85
+
86
+ describe('TableHead', () => {
87
+ it('renders correctly', () => {
88
+ const wrapper = mount(TableHead, {
89
+ slots: { default: 'Column' },
90
+ })
91
+ expect(wrapper.element.tagName).toBe('TH')
92
+ expect(wrapper.text()).toContain('Column')
93
+ })
94
+
95
+ it('applies custom class', () => {
96
+ const wrapper = mount(TableHead, {
97
+ props: { class: 'head-class' },
98
+ slots: { default: 'H' },
99
+ })
100
+ expect(wrapper.classes()).toContain('head-class')
101
+ })
102
+ })
103
+
104
+ describe('TableCell', () => {
105
+ it('renders correctly', () => {
106
+ const wrapper = mount(TableCell, {
107
+ slots: { default: 'Data' },
108
+ })
109
+ expect(wrapper.element.tagName).toBe('TD')
110
+ expect(wrapper.text()).toContain('Data')
111
+ })
112
+
113
+ it('applies custom class', () => {
114
+ const wrapper = mount(TableCell, {
115
+ props: { class: 'cell-class' },
116
+ slots: { default: 'D' },
117
+ })
118
+ expect(wrapper.classes()).toContain('cell-class')
119
+ })
120
+ })
121
+
122
+ describe('Table composed', () => {
123
+ it('renders a full table with all sub-components', () => {
124
+ const wrapper = mount(Table, {
125
+ slots: {
126
+ default: {
127
+ template: `
128
+ <TableHeader>
129
+ <TableRow>
130
+ <TableHead>Name</TableHead>
131
+ <TableHead>Age</TableHead>
132
+ </TableRow>
133
+ </TableHeader>
134
+ <TableBody>
135
+ <TableRow>
136
+ <TableCell>Alice</TableCell>
137
+ <TableCell>30</TableCell>
138
+ </TableRow>
139
+ </TableBody>
140
+ `,
141
+ components: { TableHeader, TableBody, TableRow, TableHead, TableCell },
142
+ },
143
+ },
144
+ })
145
+ expect(wrapper.text()).toContain('Name')
146
+ expect(wrapper.text()).toContain('Age')
147
+ expect(wrapper.text()).toContain('Alice')
148
+ expect(wrapper.text()).toContain('30')
149
+ })
150
+ })
@@ -0,0 +1,13 @@
1
+ <script setup lang="ts">
2
+ import { cn } from '@/lib/utils'
3
+
4
+ const props = defineProps<{ class?: string }>()
5
+ </script>
6
+
7
+ <template>
8
+ <div class="relative w-full overflow-auto">
9
+ <table :class="cn('w-full caption-bottom text-sm', props.class)">
10
+ <slot />
11
+ </table>
12
+ </div>
13
+ </template>
@@ -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
+ <tbody :class="cn('[&_tr:last-child]:border-0', props.class)">
9
+ <slot />
10
+ </tbody>
11
+ </template>
@@ -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
+ <caption :class="cn('mt-4 text-sm text-muted-foreground', props.class)">
9
+ <slot />
10
+ </caption>
11
+ </template>
@@ -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
+ <td :class="cn('p-4 align-middle [&:has([role=checkbox])]:pr-0', props.class)">
9
+ <slot />
10
+ </td>
11
+ </template>
@@ -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
+ <tfoot :class="cn('border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', props.class)">
9
+ <slot />
10
+ </tfoot>
11
+ </template>
@@ -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
+ <th :class="cn('h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0', props.class)">
9
+ <slot />
10
+ </th>
11
+ </template>
@@ -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
+ <thead :class="cn('[&_tr]:border-b', props.class)">
9
+ <slot />
10
+ </thead>
11
+ </template>
@@ -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
+ <tr :class="cn('border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted', props.class)">
9
+ <slot />
10
+ </tr>
11
+ </template>
@@ -0,0 +1,8 @@
1
+ export { default as Table } from './Table.vue'
2
+ export { default as TableHeader } from './TableHeader.vue'
3
+ export { default as TableBody } from './TableBody.vue'
4
+ export { default as TableFooter } from './TableFooter.vue'
5
+ export { default as TableRow } from './TableRow.vue'
6
+ export { default as TableHead } from './TableHead.vue'
7
+ export { default as TableCell } from './TableCell.vue'
8
+ export { default as TableCaption } from './TableCaption.vue'