@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,177 @@
1
+ <script setup lang="ts">
2
+ import { cn } from '@/lib/utils'
3
+ import { computed, type Component } from 'vue'
4
+
5
+ interface Props {
6
+ icon?: Component | string
7
+ title: string
8
+ description?: string
9
+ selected?: boolean
10
+ disabled?: boolean
11
+ size?: 'default' | 'compact'
12
+ iconClass?: string
13
+ class?: string
14
+ }
15
+
16
+ const props = withDefaults(defineProps<Props>(), {
17
+ selected: false,
18
+ disabled: false,
19
+ size: 'default',
20
+ })
21
+
22
+ const emit = defineEmits<{
23
+ select: []
24
+ }>()
25
+
26
+ const handleClick = () => {
27
+ if (!props.disabled) {
28
+ emit('select')
29
+ }
30
+ }
31
+
32
+ const sizeClasses = {
33
+ default: {
34
+ card: 'p-6',
35
+ iconWrapper: 'w-14 h-14',
36
+ icon: 'w-6 h-6',
37
+ title: 'text-base',
38
+ description: 'text-sm',
39
+ gap: 'gap-3',
40
+ },
41
+ compact: {
42
+ card: 'p-4',
43
+ iconWrapper: 'w-10 h-10',
44
+ icon: 'w-5 h-5',
45
+ title: 'text-sm',
46
+ description: 'text-xs',
47
+ gap: 'gap-2',
48
+ },
49
+ }
50
+
51
+ const currentSize = computed(() => sizeClasses[props.size])
52
+ </script>
53
+
54
+ <template>
55
+ <div
56
+ :class="
57
+ cn(
58
+ // Base styles
59
+ 'relative flex flex-col items-center text-center rounded-2xl',
60
+ 'bg-card',
61
+ 'border border',
62
+ 'shadow-depth-1',
63
+ 'transition-all duration-200 ease-in-out',
64
+ // Size
65
+ currentSize.card,
66
+ currentSize.gap,
67
+ // Interactive states
68
+ !disabled && [
69
+ 'cursor-pointer',
70
+ 'hover:-translate-y-0.5 hover:shadow-depth-2',
71
+ 'active:translate-y-0 active:shadow-depth-1',
72
+ ],
73
+ // Selected state
74
+ selected && [
75
+ 'border-primary',
76
+ 'ring-1 ring-primary',
77
+ 'scale-[1.02]',
78
+ ],
79
+ // Disabled state
80
+ disabled && [
81
+ 'opacity-50',
82
+ 'cursor-not-allowed',
83
+ ],
84
+ props.class
85
+ )
86
+ "
87
+ role="button"
88
+ tabindex="0"
89
+ @click="handleClick"
90
+ @keydown.enter="handleClick"
91
+ @keydown.space.prevent="handleClick"
92
+ >
93
+ <!-- Selection indicator -->
94
+ <div
95
+ v-if="selected"
96
+ :class="
97
+ cn(
98
+ 'absolute -top-2 -right-2',
99
+ 'flex items-center justify-center',
100
+ 'w-6 h-6 rounded-full',
101
+ 'bg-foreground',
102
+ 'text-background',
103
+ 'shadow-md',
104
+ 'transition-transform duration-200',
105
+ 'z-10'
106
+ )
107
+ "
108
+ >
109
+ <!-- Checkmark SVG -->
110
+ <svg
111
+ xmlns="http://www.w3.org/2000/svg"
112
+ width="24"
113
+ height="24"
114
+ viewBox="0 0 24 24"
115
+ fill="none"
116
+ stroke="currentColor"
117
+ stroke-width="2.5"
118
+ stroke-linecap="round"
119
+ stroke-linejoin="round"
120
+ class="w-3.5 h-3.5"
121
+ >
122
+ <path d="M20 6 9 17l-5-5" />
123
+ </svg>
124
+ </div>
125
+
126
+ <!-- Icon area with gradient background -->
127
+ <div
128
+ :class="
129
+ cn(
130
+ 'flex items-center justify-center rounded-xl',
131
+ 'bg-primary',
132
+ currentSize.iconWrapper,
133
+ iconClass
134
+ )
135
+ "
136
+ >
137
+ <slot name="icon">
138
+ <component
139
+ v-if="icon && typeof icon !== 'string'"
140
+ :is="icon"
141
+ :class="cn('text-primary-foreground', currentSize.icon)"
142
+ />
143
+ <div
144
+ v-else-if="icon && typeof icon === 'string'"
145
+ :class="cn('text-primary-foreground font-semibold', currentSize.icon)"
146
+ >
147
+ {{ icon }}
148
+ </div>
149
+ </slot>
150
+ </div>
151
+
152
+ <!-- Content -->
153
+ <div class="flex flex-col items-center gap-1">
154
+ <h3
155
+ :class="
156
+ cn(
157
+ 'font-semibold text-card-foreground',
158
+ currentSize.title
159
+ )
160
+ "
161
+ >
162
+ {{ title }}
163
+ </h3>
164
+ <p
165
+ v-if="description"
166
+ :class="
167
+ cn(
168
+ 'text-muted-foreground leading-relaxed',
169
+ currentSize.description
170
+ )
171
+ "
172
+ >
173
+ {{ description }}
174
+ </p>
175
+ </div>
176
+ </div>
177
+ </template>
@@ -0,0 +1,139 @@
1
+ # FeatureCard Component
2
+
3
+ A selectable card component with an icon area, title, and description. Designed for feature selection interfaces.
4
+
5
+ ## Installation
6
+
7
+ ```typescript
8
+ import { FeatureCard } from '@/lib/feature-card'
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Basic Usage
14
+
15
+ ```vue
16
+ <script setup lang="ts">
17
+ import { ref } from 'vue'
18
+ import { FeatureCard } from '@/lib/feature-card'
19
+ import { Shield, Zap } from 'lucide-vue-next'
20
+
21
+ const isSafeSelected = ref(false)
22
+ const isLatestSelected = ref(true)
23
+ </script>
24
+
25
+ <template>
26
+ <div class="grid grid-cols-2 gap-4">
27
+ <FeatureCard
28
+ :icon="Shield"
29
+ title="Safe & Stable"
30
+ description="Uses well-tested dependencies"
31
+ :selected="isSafeSelected"
32
+ @select="isSafeSelected = !isSafeSelected"
33
+ />
34
+
35
+ <FeatureCard
36
+ :icon="Zap"
37
+ title="Latest"
38
+ description="Cutting-edge features and updates"
39
+ :selected="isLatestSelected"
40
+ @select="isLatestSelected = !isLatestSelected"
41
+ />
42
+ </div>
43
+ </template>
44
+ ```
45
+
46
+ ### With Custom Icon Slot
47
+
48
+ ```vue
49
+ <script setup lang="ts">
50
+ import { ref } from 'vue'
51
+ import { FeatureCard } from '@/lib/feature-card'
52
+ import { Rocket } from 'lucide-vue-next'
53
+
54
+ const isSelected = ref(false)
55
+ </script>
56
+
57
+ <template>
58
+ <FeatureCard
59
+ title="Deploy Now"
60
+ description="Push to production instantly"
61
+ :selected="isSelected"
62
+ @select="isSelected = !isSelected"
63
+ >
64
+ <template #icon>
65
+ <Rocket class="w-6 h-6 text-white" />
66
+ </template>
67
+ </FeatureCard>
68
+ </template>
69
+ ```
70
+
71
+ ### Compact Size
72
+
73
+ ```vue
74
+ <FeatureCard
75
+ :icon="Shield"
76
+ title="Basic"
77
+ description="For small teams"
78
+ size="compact"
79
+ :selected="true"
80
+ />
81
+ ```
82
+
83
+ ### Disabled State
84
+
85
+ ```vue
86
+ <FeatureCard
87
+ :icon="Shield"
88
+ title="Enterprise"
89
+ description="Contact sales"
90
+ :disabled="true"
91
+ :selected="false"
92
+ />
93
+ ```
94
+
95
+ ### Custom Styling
96
+
97
+ ```vue
98
+ <FeatureCard
99
+ :icon="Shield"
100
+ title="Custom"
101
+ description="With custom icon styling"
102
+ icon-class="from-purple-500 to-pink-500"
103
+ class="max-w-xs"
104
+ />
105
+ ```
106
+
107
+ ## Props
108
+
109
+ | Prop | Type | Default | Description |
110
+ |------|------|---------|-------------|
111
+ | `icon` | `Component \| string` | `undefined` | Icon component or string to display |
112
+ | `title` | `string` | **required** | Card title |
113
+ | `description` | `string` | `undefined` | Card description |
114
+ | `selected` | `boolean` | `false` | Whether the card is selected |
115
+ | `disabled` | `boolean` | `false` | Whether the card is disabled |
116
+ | `size` | `'default' \| 'compact'` | `'default'` | Card size variant |
117
+ | `iconClass` | `string` | `undefined` | Additional classes for the icon wrapper |
118
+ | `class` | `string` | `undefined` | Additional classes for the card |
119
+
120
+ ## Events
121
+
122
+ | Event | Description |
123
+ |-------|-------------|
124
+ | `select` | Emitted when the card is clicked (if not disabled) |
125
+
126
+ ## Slots
127
+
128
+ | Slot | Description |
129
+ |------|-------------|
130
+ | `icon` | Custom icon content (overrides the `icon` prop) |
131
+
132
+ ## Design Tokens
133
+
134
+ The component uses the following CSS variables:
135
+
136
+ - `shadow-depth-1` - Default card shadow
137
+ - `shadow-depth-2` - Hover state shadow
138
+ - Colors follow the gray scale for borders and text
139
+ - Blue gradient (`blue-500` to `blue-600`) for the icon background
@@ -0,0 +1 @@
1
+ export { default as FeatureCard } from './FeatureCard.vue'
@@ -0,0 +1,15 @@
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
+ </script>
10
+
11
+ <template>
12
+ <div :class="cn('space-y-2', props.class)">
13
+ <slot />
14
+ </div>
15
+ </template>
@@ -0,0 +1,15 @@
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
+ </script>
10
+
11
+ <template>
12
+ <p :class="cn('text-sm text-muted-foreground', props.class)">
13
+ <slot />
14
+ </p>
15
+ </template>
@@ -0,0 +1,15 @@
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
+ </script>
10
+
11
+ <template>
12
+ <p :class="cn('text-sm font-medium text-destructive', props.class)">
13
+ <slot />
14
+ </p>
15
+ </template>
@@ -0,0 +1,24 @@
1
+ <script setup lang="ts">
2
+ import { cn } from '@/lib/utils'
3
+
4
+ interface Props {
5
+ class?: string
6
+ for?: string
7
+ }
8
+
9
+ const props = defineProps<Props>()
10
+ </script>
11
+
12
+ <template>
13
+ <label
14
+ :for="props.for"
15
+ :class="
16
+ cn(
17
+ 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
18
+ props.class
19
+ )
20
+ "
21
+ >
22
+ <slot />
23
+ </label>
24
+ </template>
@@ -0,0 +1,4 @@
1
+ export { default as Field } from './Field.vue'
2
+ export { default as FieldLabel } from './FieldLabel.vue'
3
+ export { default as FieldDescription } from './FieldDescription.vue'
4
+ export { default as FieldError } from './FieldError.vue'
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+
4
+ import { HoverCardRoot } from 'radix-vue'
5
+ </script>
6
+
7
+ <template>
8
+ <HoverCardRoot v-bind="$attrs">
9
+ <slot />
10
+ </HoverCardRoot>
11
+ </template>
@@ -0,0 +1,31 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+ import {
4
+ HoverCardContent,
5
+ HoverCardPortal,
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
+ <HoverCardPortal>
14
+ <HoverCardContent
15
+ v-bind="$attrs"
16
+ :side-offset="props.sideOffset"
17
+ :class="
18
+ cn(
19
+ 'z-depth-3 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-depth-3 outline-none',
20
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out',
21
+ 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
22
+ 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
23
+ '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',
24
+ props.class
25
+ )
26
+ "
27
+ >
28
+ <slot />
29
+ </HoverCardContent>
30
+ </HoverCardPortal>
31
+ </template>
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ inheritAttrs: false })
3
+
4
+ import { HoverCardTrigger } from 'radix-vue'
5
+ </script>
6
+
7
+ <template>
8
+ <HoverCardTrigger v-bind="$attrs">
9
+ <slot />
10
+ </HoverCardTrigger>
11
+ </template>
@@ -0,0 +1,3 @@
1
+ export { default as HoverCard } from './HoverCard.vue'
2
+ export { default as HoverCardTrigger } from './HoverCardTrigger.vue'
3
+ export { default as HoverCardContent } from './HoverCardContent.vue'
@@ -0,0 +1,33 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+ import { cn } from '@/lib/utils'
4
+ import * as icons from 'lucide-vue-next'
5
+
6
+ const props = withDefaults(defineProps<{
7
+ name: string
8
+ size?: number | string
9
+ strokeWidth?: number | string
10
+ class?: string
11
+ }>(), {
12
+ size: 16,
13
+ strokeWidth: 2,
14
+ })
15
+
16
+ const iconComponent = computed(() => {
17
+ // Convert kebab-case or snake_case to PascalCase
18
+ const pascal = props.name
19
+ .replace(/[-_](.)/g, (_, c) => c.toUpperCase())
20
+ .replace(/^(.)/, (_, c) => c.toUpperCase())
21
+ return (icons as any)[pascal] || null
22
+ })
23
+ </script>
24
+
25
+ <template>
26
+ <component
27
+ v-if="iconComponent"
28
+ :is="iconComponent"
29
+ :size="size"
30
+ :stroke-width="strokeWidth"
31
+ :class="cn('shrink-0', props.class)"
32
+ />
33
+ </template>
@@ -0,0 +1,71 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import Input from './Input.vue'
4
+
5
+ describe('Input', () => {
6
+ it('renders correctly', () => {
7
+ const wrapper = mount(Input)
8
+ expect(wrapper.exists()).toBe(true)
9
+ expect(wrapper.find('input').exists()).toBe(true)
10
+ })
11
+
12
+ it('binds modelValue to input value', () => {
13
+ const wrapper = mount(Input, {
14
+ props: { modelValue: 'hello' },
15
+ })
16
+ expect(wrapper.find('input').element.value).toBe('hello')
17
+ })
18
+
19
+ it('emits update:modelValue on input', async () => {
20
+ const wrapper = mount(Input, {
21
+ props: { modelValue: '' },
22
+ })
23
+ await wrapper.find('input').setValue('new value')
24
+ expect(wrapper.emitted('update:modelValue')).toBeTruthy()
25
+ expect(wrapper.emitted('update:modelValue')![0]).toEqual(['new value'])
26
+ })
27
+
28
+ it('sets placeholder attribute', () => {
29
+ const wrapper = mount(Input, {
30
+ props: { placeholder: 'Enter text...' },
31
+ })
32
+ expect(wrapper.find('input').attributes('placeholder')).toBe('Enter text...')
33
+ })
34
+
35
+ it('is disabled when disabled prop is true', () => {
36
+ const wrapper = mount(Input, {
37
+ props: { disabled: true },
38
+ })
39
+ expect(wrapper.find('input').attributes('disabled')).toBeDefined()
40
+ })
41
+
42
+ it('applies size prop classes', () => {
43
+ const wrapper = mount(Input, {
44
+ props: { size: 'sm' },
45
+ })
46
+ const classes = wrapper.find('input').classes().join(' ')
47
+ expect(classes).toContain('h-8')
48
+ expect(classes).toContain('text-xs')
49
+ })
50
+
51
+ it('applies lg size prop classes', () => {
52
+ const wrapper = mount(Input, {
53
+ props: { size: 'lg' },
54
+ })
55
+ const classes = wrapper.find('input').classes().join(' ')
56
+ expect(classes).toContain('h-12')
57
+ expect(classes).toContain('text-base')
58
+ })
59
+
60
+ it('sets type attribute', () => {
61
+ const wrapper = mount(Input, {
62
+ props: { type: 'password' },
63
+ })
64
+ expect(wrapper.find('input').attributes('type')).toBe('password')
65
+ })
66
+
67
+ it('defaults type to text', () => {
68
+ const wrapper = mount(Input)
69
+ expect(wrapper.find('input').attributes('type')).toBe('text')
70
+ })
71
+ })
@@ -0,0 +1,85 @@
1
+ <script setup lang="ts">
2
+ import { computed, useSlots } from 'vue'
3
+ import { cn } from '@/lib/utils'
4
+
5
+ interface Props {
6
+ class?: string
7
+ type?: string
8
+ disabled?: boolean
9
+ placeholder?: string
10
+ modelValue?: string | number
11
+ size?: 'sm' | 'default' | 'lg'
12
+ }
13
+
14
+ const props = withDefaults(defineProps<Props>(), {
15
+ type: 'text',
16
+ size: 'default',
17
+ })
18
+
19
+ const sizeClasses = {
20
+ sm: 'h-8 text-xs',
21
+ default: 'h-10 text-sm',
22
+ lg: 'h-12 text-base',
23
+ }
24
+
25
+ const emit = defineEmits<{
26
+ (e: 'update:modelValue', value: string): void
27
+ }>()
28
+
29
+ const slots = useSlots()
30
+
31
+ const hasLeftIcon = computed(() => !!slots['left-icon'])
32
+ const hasRightIcon = computed(() => !!slots['right-icon'])
33
+
34
+ const handleInput = (event: Event) => {
35
+ const target = event.target as HTMLInputElement
36
+ emit('update:modelValue', target.value)
37
+ }
38
+ </script>
39
+
40
+ <template>
41
+ <div class="relative flex items-center w-full">
42
+ <!-- Left Icon -->
43
+ <div
44
+ v-if="hasLeftIcon"
45
+ class="absolute left-3 flex items-center justify-center text-muted-foreground pointer-events-none"
46
+ >
47
+ <slot name="left-icon" />
48
+ </div>
49
+
50
+ <input
51
+ :type="type"
52
+ :value="modelValue"
53
+ :placeholder="placeholder"
54
+ :class="
55
+ cn(
56
+ 'flex w-full rounded-lg border border-input',
57
+ 'bg-background',
58
+ sizeClasses[props.size],
59
+ 'ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium',
60
+ 'placeholder:text-muted-foreground',
61
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/20 focus-visible:border-primary',
62
+ 'disabled:cursor-not-allowed disabled:opacity-50',
63
+ 'shadow-depth-1 focus-visible:shadow-depth-2 transition-all duration-150 ease-out',
64
+ // Padding adjustments for icons
65
+ hasLeftIcon && 'pl-10',
66
+ hasRightIcon && 'pr-10',
67
+ !hasLeftIcon && 'px-3',
68
+ !hasRightIcon && !hasLeftIcon && 'py-2',
69
+ props.class
70
+ )
71
+ "
72
+ :disabled="disabled"
73
+ @input="handleInput"
74
+ />
75
+
76
+ <!-- Right Icon -->
77
+ <div
78
+ v-if="hasRightIcon"
79
+ class="absolute right-3 flex items-center justify-center text-muted-foreground"
80
+ :class="{ 'pointer-events-none': !$slots['right-icon-clickable'] }"
81
+ >
82
+ <slot name="right-icon" />
83
+ </div>
84
+ </div>
85
+ </template>
@@ -0,0 +1 @@
1
+ export { default as Input } from './Input.vue'
@@ -0,0 +1,24 @@
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
+ </script>
10
+
11
+ <template>
12
+ <div
13
+ :class="
14
+ cn(
15
+ 'flex h-10 w-full rounded-md border border-input bg-background text-sm',
16
+ 'ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2',
17
+ 'shadow-depth-1',
18
+ props.class
19
+ )
20
+ "
21
+ >
22
+ <slot />
23
+ </div>
24
+ </template>