@vestow/vue 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (491) hide show
  1. package/README.md +233 -0
  2. package/index.ts +8 -0
  3. package/package.json +68 -0
  4. package/src/components/accordion/Accordion.vue +45 -0
  5. package/src/components/accordion/AccordionContent.vue +31 -0
  6. package/src/components/accordion/AccordionItem.vue +26 -0
  7. package/src/components/accordion/AccordionTrigger.vue +39 -0
  8. package/src/components/accordion/index.ts +18 -0
  9. package/src/components/alert/Alert.vue +17 -0
  10. package/src/components/alert/AlertDescription.vue +12 -0
  11. package/src/components/alert/AlertTitle.vue +12 -0
  12. package/src/components/alert/index.ts +5 -0
  13. package/src/components/avatar/Avatar.vue +32 -0
  14. package/src/components/avatar/AvatarFallback.vue +23 -0
  15. package/src/components/avatar/AvatarImage.vue +18 -0
  16. package/src/components/avatar/index.ts +3 -0
  17. package/src/components/badge/Badge.vue +25 -0
  18. package/src/components/badge/index.ts +3 -0
  19. package/src/components/breadcrumb/Breadcrumb.vue +14 -0
  20. package/src/components/breadcrumb/BreadcrumbItem.vue +12 -0
  21. package/src/components/breadcrumb/BreadcrumbLink.vue +19 -0
  22. package/src/components/breadcrumb/BreadcrumbPage.vue +12 -0
  23. package/src/components/breadcrumb/BreadcrumbSeparator.vue +15 -0
  24. package/src/components/breadcrumb/index.ts +5 -0
  25. package/src/components/button/Button.vue +55 -0
  26. package/src/components/button/index.ts +3 -0
  27. package/src/components/button-group/ButtonGroup.vue +29 -0
  28. package/src/components/button-group/ButtonGroupSeparator.vue +30 -0
  29. package/src/components/button-group/ButtonGroupText.vue +29 -0
  30. package/src/components/button-group/SplitButton.vue +103 -0
  31. package/src/components/button-group/SplitButtonItems.vue +50 -0
  32. package/src/components/button-group/index.ts +34 -0
  33. package/src/components/calendar/Calendar.vue +120 -0
  34. package/src/components/calendar/RangeCalendar.vue +127 -0
  35. package/src/components/calendar/index.ts +2 -0
  36. package/src/components/card/Card.vue +12 -0
  37. package/src/components/card/CardAction.vue +12 -0
  38. package/src/components/card/CardContent.vue +12 -0
  39. package/src/components/card/CardDescription.vue +12 -0
  40. package/src/components/card/CardFooter.vue +12 -0
  41. package/src/components/card/CardHeader.vue +15 -0
  42. package/src/components/card/CardTitle.vue +12 -0
  43. package/src/components/card/index.ts +7 -0
  44. package/src/components/carousel/Carousel.vue +164 -0
  45. package/src/components/carousel/CarouselContent.vue +43 -0
  46. package/src/components/carousel/CarouselDots.vue +42 -0
  47. package/src/components/carousel/CarouselItem.vue +58 -0
  48. package/src/components/carousel/CarouselNext.vue +45 -0
  49. package/src/components/carousel/CarouselPrevious.vue +45 -0
  50. package/src/components/carousel/index.ts +44 -0
  51. package/src/components/cascade-select/CascadeSelect.vue +314 -0
  52. package/src/components/cascade-select/index.ts +11 -0
  53. package/src/components/chart/AreaChart.vue +201 -0
  54. package/src/components/chart/BarChart.vue +389 -0
  55. package/src/components/chart/ChartContainer.vue +127 -0
  56. package/src/components/chart/ChartCrosshair.vue +92 -0
  57. package/src/components/chart/ChartLegend.vue +63 -0
  58. package/src/components/chart/ChartTooltipCard.vue +49 -0
  59. package/src/components/chart/LineChart.vue +214 -0
  60. package/src/components/chart/PieChart.vue +280 -0
  61. package/src/components/chart/RadarChart.vue +291 -0
  62. package/src/components/chart/RadialChart.vue +354 -0
  63. package/src/components/chart/index.ts +30 -0
  64. package/src/components/chart/polar.ts +5 -0
  65. package/src/components/chart/tooltip.ts +5 -0
  66. package/src/components/chart/types.ts +52 -0
  67. package/src/components/chart/useChartSeries.ts +138 -0
  68. package/src/components/chart/xy-label.ts +5 -0
  69. package/src/components/checkbox/Checkbox.vue +81 -0
  70. package/src/components/checkbox/CheckboxField.vue +129 -0
  71. package/src/components/checkbox/CheckboxGroup.vue +62 -0
  72. package/src/components/checkbox/index.ts +21 -0
  73. package/src/components/chip/Chip.vue +73 -0
  74. package/src/components/chip/index.ts +3 -0
  75. package/src/components/code-block/CodeBlock.vue +100 -0
  76. package/src/components/code-block/index.ts +4 -0
  77. package/src/components/collapsible/Collapsible.vue +15 -0
  78. package/src/components/collapsible/CollapsibleContent.vue +26 -0
  79. package/src/components/collapsible/CollapsibleTrigger.vue +12 -0
  80. package/src/components/collapsible/index.ts +3 -0
  81. package/src/components/combobox/Combobox.vue +23 -0
  82. package/src/components/combobox/ComboboxAnchor.vue +20 -0
  83. package/src/components/combobox/ComboboxEmpty.vue +21 -0
  84. package/src/components/combobox/ComboboxGroup.vue +23 -0
  85. package/src/components/combobox/ComboboxInput.vue +32 -0
  86. package/src/components/combobox/ComboboxItem.vue +38 -0
  87. package/src/components/combobox/ComboboxList.vue +43 -0
  88. package/src/components/combobox/ComboboxSeparator.vue +18 -0
  89. package/src/components/combobox/ComboboxTrigger.vue +12 -0
  90. package/src/components/combobox/index.ts +9 -0
  91. package/src/components/command/Command.vue +54 -0
  92. package/src/components/command/CommandDialog.vue +41 -0
  93. package/src/components/command/CommandEmpty.vue +19 -0
  94. package/src/components/command/CommandGroup.vue +28 -0
  95. package/src/components/command/CommandInput.vue +25 -0
  96. package/src/components/command/CommandItem.vue +40 -0
  97. package/src/components/command/CommandList.vue +13 -0
  98. package/src/components/command/CommandSeparator.vue +11 -0
  99. package/src/components/command/CommandShortcut.vue +13 -0
  100. package/src/components/command/index.ts +34 -0
  101. package/src/components/command-block/CommandBlock.vue +90 -0
  102. package/src/components/command-block/index.ts +2 -0
  103. package/src/components/confirm-dialog/ConfirmDialog.vue +37 -0
  104. package/src/components/confirm-dialog/index.ts +1 -0
  105. package/src/components/confirm-popup/ConfirmPopup.vue +123 -0
  106. package/src/components/confirm-popup/index.ts +1 -0
  107. package/src/components/context-menu/ContextMenu.vue +15 -0
  108. package/src/components/context-menu/ContextMenuCheckboxItem.vue +30 -0
  109. package/src/components/context-menu/ContextMenuContent.vue +36 -0
  110. package/src/components/context-menu/ContextMenuGroup.vue +12 -0
  111. package/src/components/context-menu/ContextMenuItem.vue +32 -0
  112. package/src/components/context-menu/ContextMenuLabel.vue +21 -0
  113. package/src/components/context-menu/ContextMenuRadioGroup.vue +15 -0
  114. package/src/components/context-menu/ContextMenuRadioItem.vue +30 -0
  115. package/src/components/context-menu/ContextMenuSeparator.vue +19 -0
  116. package/src/components/context-menu/ContextMenuShortcut.vue +13 -0
  117. package/src/components/context-menu/ContextMenuSub.vue +15 -0
  118. package/src/components/context-menu/ContextMenuSubContent.vue +26 -0
  119. package/src/components/context-menu/ContextMenuSubTrigger.vue +26 -0
  120. package/src/components/context-menu/ContextMenuTrigger.vue +12 -0
  121. package/src/components/context-menu/index.ts +14 -0
  122. package/src/components/data-table/DataTable.vue +458 -0
  123. package/src/components/data-table/DataTableFacetedFilter.vue +97 -0
  124. package/src/components/data-table/DataTablePagination.vue +103 -0
  125. package/src/components/data-table/DataTableViewOptions.vue +69 -0
  126. package/src/components/data-table/features.ts +87 -0
  127. package/src/components/data-table/index.ts +27 -0
  128. package/src/components/data-table/pagination-adapter.ts +67 -0
  129. package/src/components/data-table/selection-column.ts +48 -0
  130. package/src/components/data-table/types.ts +36 -0
  131. package/src/components/data-view/DataView.vue +136 -0
  132. package/src/components/data-view/index.ts +1 -0
  133. package/src/components/date-picker/DatePicker.vue +117 -0
  134. package/src/components/date-picker/DateRangePicker.vue +122 -0
  135. package/src/components/date-picker/index.ts +2 -0
  136. package/src/components/deferred/Deferred.vue +80 -0
  137. package/src/components/deferred/index.ts +1 -0
  138. package/src/components/dialog/Dialog.vue +15 -0
  139. package/src/components/dialog/DialogClose.vue +12 -0
  140. package/src/components/dialog/DialogContent.vue +46 -0
  141. package/src/components/dialog/DialogDescription.vue +19 -0
  142. package/src/components/dialog/DialogFooter.vue +12 -0
  143. package/src/components/dialog/DialogHeader.vue +12 -0
  144. package/src/components/dialog/DialogTitle.vue +19 -0
  145. package/src/components/dialog/DialogTrigger.vue +12 -0
  146. package/src/components/dialog/index.ts +10 -0
  147. package/src/components/doc-example/DocExample.vue +41 -0
  148. package/src/components/doc-example/index.ts +1 -0
  149. package/src/components/doc-text/DocText.vue +64 -0
  150. package/src/components/doc-text/index.ts +1 -0
  151. package/src/components/dropdown-menu/DropdownMenu.vue +15 -0
  152. package/src/components/dropdown-menu/DropdownMenuCheckboxItem.vue +33 -0
  153. package/src/components/dropdown-menu/DropdownMenuContent.vue +36 -0
  154. package/src/components/dropdown-menu/DropdownMenuGroup.vue +12 -0
  155. package/src/components/dropdown-menu/DropdownMenuItem.vue +32 -0
  156. package/src/components/dropdown-menu/DropdownMenuLabel.vue +24 -0
  157. package/src/components/dropdown-menu/DropdownMenuRadioGroup.vue +15 -0
  158. package/src/components/dropdown-menu/DropdownMenuRadioItem.vue +33 -0
  159. package/src/components/dropdown-menu/DropdownMenuSeparator.vue +19 -0
  160. package/src/components/dropdown-menu/DropdownMenuShortcut.vue +13 -0
  161. package/src/components/dropdown-menu/DropdownMenuSub.vue +15 -0
  162. package/src/components/dropdown-menu/DropdownMenuSubContent.vue +29 -0
  163. package/src/components/dropdown-menu/DropdownMenuSubTrigger.vue +26 -0
  164. package/src/components/dropdown-menu/DropdownMenuTrigger.vue +12 -0
  165. package/src/components/dropdown-menu/index.ts +14 -0
  166. package/src/components/editable/Editable.vue +41 -0
  167. package/src/components/editable/EditableArea.vue +22 -0
  168. package/src/components/editable/EditableCancelTrigger.vue +40 -0
  169. package/src/components/editable/EditableEditTrigger.vue +40 -0
  170. package/src/components/editable/EditableInput.vue +28 -0
  171. package/src/components/editable/EditablePreview.vue +34 -0
  172. package/src/components/editable/EditableSubmitTrigger.vue +40 -0
  173. package/src/components/editable/index.ts +17 -0
  174. package/src/components/empty/Empty.vue +17 -0
  175. package/src/components/empty/EmptyActions.vue +14 -0
  176. package/src/components/empty/EmptyDescription.vue +12 -0
  177. package/src/components/empty/EmptyMedia.vue +16 -0
  178. package/src/components/empty/EmptyTitle.vue +17 -0
  179. package/src/components/empty/index.ts +7 -0
  180. package/src/components/field/Field.vue +22 -0
  181. package/src/components/field/FieldDescription.vue +20 -0
  182. package/src/components/field/FieldGroup.vue +22 -0
  183. package/src/components/field/FieldLabel.vue +27 -0
  184. package/src/components/field/FieldSeparator.vue +28 -0
  185. package/src/components/field/index.ts +7 -0
  186. package/src/components/fieldset/Fieldset.vue +126 -0
  187. package/src/components/fieldset/index.ts +1 -0
  188. package/src/components/file-upload/FileUpload.vue +149 -0
  189. package/src/components/file-upload/index.ts +8 -0
  190. package/src/components/float-label/FloatLabel.vue +26 -0
  191. package/src/components/float-label/index.ts +3 -0
  192. package/src/components/form/Form.vue +126 -0
  193. package/src/components/form/FormDescription.vue +12 -0
  194. package/src/components/form/FormField.vue +127 -0
  195. package/src/components/form/FormItem.vue +12 -0
  196. package/src/components/form/FormLabel.vue +14 -0
  197. package/src/components/form/FormMessage.vue +31 -0
  198. package/src/components/form/context.ts +54 -0
  199. package/src/components/form/errors.ts +6 -0
  200. package/src/components/form/index.ts +7 -0
  201. package/src/components/form/types.ts +55 -0
  202. package/src/components/hover-card/HoverCard.vue +27 -0
  203. package/src/components/hover-card/HoverCardContent.vue +36 -0
  204. package/src/components/hover-card/HoverCardTrigger.vue +12 -0
  205. package/src/components/hover-card/index.ts +3 -0
  206. package/src/components/ifta-label/IftaLabel.vue +26 -0
  207. package/src/components/ifta-label/index.ts +1 -0
  208. package/src/components/index.ts +89 -0
  209. package/src/components/input/Input.vue +87 -0
  210. package/src/components/input/index.ts +1 -0
  211. package/src/components/input-color/ColorArea.vue +36 -0
  212. package/src/components/input-color/ColorField.vue +32 -0
  213. package/src/components/input-color/ColorSlider.vue +31 -0
  214. package/src/components/input-color/InputColor.vue +65 -0
  215. package/src/components/input-color/index.ts +16 -0
  216. package/src/components/input-group/InputGroup.vue +26 -0
  217. package/src/components/input-group/InputGroupAddon.vue +32 -0
  218. package/src/components/input-group/InputGroupInput.vue +33 -0
  219. package/src/components/input-group/index.ts +17 -0
  220. package/src/components/input-number/InputNumber.vue +82 -0
  221. package/src/components/input-number/index.ts +1 -0
  222. package/src/components/input-otp/InputOtp.vue +186 -0
  223. package/src/components/input-otp/index.ts +1 -0
  224. package/src/components/input-password/InputPassword.vue +116 -0
  225. package/src/components/input-password/index.ts +5 -0
  226. package/src/components/input-tags/InputTags.vue +38 -0
  227. package/src/components/input-tags/InputTagsClear.vue +39 -0
  228. package/src/components/input-tags/InputTagsInput.vue +27 -0
  229. package/src/components/input-tags/InputTagsItem.vue +40 -0
  230. package/src/components/input-tags/InputTagsItemDelete.vue +32 -0
  231. package/src/components/input-tags/InputTagsItemText.vue +18 -0
  232. package/src/components/input-tags/index.ts +16 -0
  233. package/src/components/kbd/Kbd.vue +17 -0
  234. package/src/components/kbd/KbdGroup.vue +15 -0
  235. package/src/components/kbd/index.ts +4 -0
  236. package/src/components/label/Label.vue +23 -0
  237. package/src/components/label/index.ts +1 -0
  238. package/src/components/listbox/Listbox.vue +42 -0
  239. package/src/components/listbox/ListboxContent.vue +22 -0
  240. package/src/components/listbox/ListboxFilter.vue +34 -0
  241. package/src/components/listbox/ListboxGroup.vue +31 -0
  242. package/src/components/listbox/ListboxItem.vue +46 -0
  243. package/src/components/listbox/index.ts +19 -0
  244. package/src/components/mask/Mask.vue +205 -0
  245. package/src/components/mask/index.ts +15 -0
  246. package/src/components/menubar/Menubar.vue +26 -0
  247. package/src/components/menubar/MenubarCheckboxItem.vue +30 -0
  248. package/src/components/menubar/MenubarContent.vue +52 -0
  249. package/src/components/menubar/MenubarGroup.vue +12 -0
  250. package/src/components/menubar/MenubarItem.vue +32 -0
  251. package/src/components/menubar/MenubarLabel.vue +21 -0
  252. package/src/components/menubar/MenubarMenu.vue +12 -0
  253. package/src/components/menubar/MenubarRadioGroup.vue +15 -0
  254. package/src/components/menubar/MenubarRadioItem.vue +30 -0
  255. package/src/components/menubar/MenubarSeparator.vue +12 -0
  256. package/src/components/menubar/MenubarShortcut.vue +13 -0
  257. package/src/components/menubar/MenubarSub.vue +15 -0
  258. package/src/components/menubar/MenubarSubContent.vue +26 -0
  259. package/src/components/menubar/MenubarSubTrigger.vue +26 -0
  260. package/src/components/menubar/MenubarTrigger.vue +30 -0
  261. package/src/components/menubar/index.ts +29 -0
  262. package/src/components/navigation-menu/NavigationMenu.vue +43 -0
  263. package/src/components/navigation-menu/NavigationMenuContent.vue +63 -0
  264. package/src/components/navigation-menu/NavigationMenuIndicator.vue +31 -0
  265. package/src/components/navigation-menu/NavigationMenuItem.vue +20 -0
  266. package/src/components/navigation-menu/NavigationMenuLink.vue +34 -0
  267. package/src/components/navigation-menu/NavigationMenuList.vue +23 -0
  268. package/src/components/navigation-menu/NavigationMenuTrigger.vue +38 -0
  269. package/src/components/navigation-menu/NavigationMenuViewport.vue +34 -0
  270. package/src/components/navigation-menu/index.ts +18 -0
  271. package/src/components/order-list/OrderList.vue +168 -0
  272. package/src/components/order-list/SelectableList.vue +200 -0
  273. package/src/components/order-list/index.ts +1 -0
  274. package/src/components/pagination/Pagination.vue +133 -0
  275. package/src/components/pagination/index.ts +1 -0
  276. package/src/components/panel/Panel.vue +69 -0
  277. package/src/components/panel/index.ts +1 -0
  278. package/src/components/pick-list/PickList.vue +211 -0
  279. package/src/components/pick-list/index.ts +1 -0
  280. package/src/components/popover/Popover.vue +15 -0
  281. package/src/components/popover/PopoverAnchor.vue +12 -0
  282. package/src/components/popover/PopoverContent.vue +39 -0
  283. package/src/components/popover/PopoverTrigger.vue +12 -0
  284. package/src/components/popover/index.ts +4 -0
  285. package/src/components/progress/Progress.vue +39 -0
  286. package/src/components/progress/index.ts +1 -0
  287. package/src/components/props-table/PropsTable.vue +62 -0
  288. package/src/components/props-table/index.ts +2 -0
  289. package/src/components/radio-group/RadioGroup.vue +52 -0
  290. package/src/components/radio-group/RadioGroupItem.vue +80 -0
  291. package/src/components/radio-group/RadioGroupItemField.vue +128 -0
  292. package/src/components/radio-group/index.ts +21 -0
  293. package/src/components/rating/Rating.vue +70 -0
  294. package/src/components/rating/RatingItem.vue +26 -0
  295. package/src/components/rating/RatingItemIndicator.vue +28 -0
  296. package/src/components/rating/RatingStar.vue +16 -0
  297. package/src/components/rating/index.ts +13 -0
  298. package/src/components/scroll-area/ScrollArea.vue +52 -0
  299. package/src/components/scroll-area/index.ts +1 -0
  300. package/src/components/search-input/SearchInput.vue +46 -0
  301. package/src/components/search-input/index.ts +1 -0
  302. package/src/components/select/Select.vue +15 -0
  303. package/src/components/select/SelectContent.vue +67 -0
  304. package/src/components/select/SelectGroup.vue +20 -0
  305. package/src/components/select/SelectItem.vue +59 -0
  306. package/src/components/select/SelectLabel.vue +20 -0
  307. package/src/components/select/SelectSeparator.vue +18 -0
  308. package/src/components/select/SelectTrigger.vue +101 -0
  309. package/src/components/select/SelectValue.vue +46 -0
  310. package/src/components/select/index.ts +8 -0
  311. package/src/components/separator/Separator.vue +25 -0
  312. package/src/components/separator/index.ts +1 -0
  313. package/src/components/sheet/Sheet.vue +15 -0
  314. package/src/components/sheet/SheetClose.vue +12 -0
  315. package/src/components/sheet/SheetContent.vue +45 -0
  316. package/src/components/sheet/SheetDescription.vue +19 -0
  317. package/src/components/sheet/SheetFooter.vue +12 -0
  318. package/src/components/sheet/SheetHeader.vue +12 -0
  319. package/src/components/sheet/SheetTitle.vue +19 -0
  320. package/src/components/sheet/SheetTrigger.vue +12 -0
  321. package/src/components/sheet/index.ts +10 -0
  322. package/src/components/sidebar/Sidebar.vue +108 -0
  323. package/src/components/sidebar/SidebarContent.vue +19 -0
  324. package/src/components/sidebar/SidebarFooter.vue +19 -0
  325. package/src/components/sidebar/SidebarGroup.vue +19 -0
  326. package/src/components/sidebar/SidebarGroupAction.vue +28 -0
  327. package/src/components/sidebar/SidebarGroupContent.vue +19 -0
  328. package/src/components/sidebar/SidebarGroupLabel.vue +25 -0
  329. package/src/components/sidebar/SidebarHeader.vue +19 -0
  330. package/src/components/sidebar/SidebarInput.vue +15 -0
  331. package/src/components/sidebar/SidebarInset.vue +22 -0
  332. package/src/components/sidebar/SidebarMenu.vue +19 -0
  333. package/src/components/sidebar/SidebarMenuAction.vue +41 -0
  334. package/src/components/sidebar/SidebarMenuBadge.vue +24 -0
  335. package/src/components/sidebar/SidebarMenuButton.vue +94 -0
  336. package/src/components/sidebar/SidebarMenuItem.vue +19 -0
  337. package/src/components/sidebar/SidebarMenuSkeleton.vue +36 -0
  338. package/src/components/sidebar/SidebarMenuSub.vue +22 -0
  339. package/src/components/sidebar/SidebarMenuSubButton.vue +39 -0
  340. package/src/components/sidebar/SidebarMenuSubItem.vue +19 -0
  341. package/src/components/sidebar/SidebarProvider.vue +114 -0
  342. package/src/components/sidebar/SidebarRail.vue +37 -0
  343. package/src/components/sidebar/SidebarSeparator.vue +15 -0
  344. package/src/components/sidebar/SidebarTrigger.vue +27 -0
  345. package/src/components/sidebar/context.ts +39 -0
  346. package/src/components/sidebar/index.ts +34 -0
  347. package/src/components/skeleton/Skeleton.vue +10 -0
  348. package/src/components/skeleton/index.ts +1 -0
  349. package/src/components/skip-link/SkipLink.vue +45 -0
  350. package/src/components/skip-link/index.ts +1 -0
  351. package/src/components/slider/Slider.vue +57 -0
  352. package/src/components/slider/index.ts +3 -0
  353. package/src/components/speed-dial/SpeedDial.vue +362 -0
  354. package/src/components/speed-dial/index.ts +28 -0
  355. package/src/components/spinner/Spinner.vue +20 -0
  356. package/src/components/spinner/index.ts +1 -0
  357. package/src/components/splitter/Splitter.vue +24 -0
  358. package/src/components/splitter/SplitterHandle.vue +51 -0
  359. package/src/components/splitter/SplitterPanel.vue +30 -0
  360. package/src/components/splitter/index.ts +14 -0
  361. package/src/components/stepper/Stepper.vue +34 -0
  362. package/src/components/stepper/StepperItem.vue +113 -0
  363. package/src/components/stepper/index.ts +2 -0
  364. package/src/components/switch/Switch.vue +35 -0
  365. package/src/components/switch/index.ts +1 -0
  366. package/src/components/table/Table.vue +24 -0
  367. package/src/components/table/TableBody.vue +12 -0
  368. package/src/components/table/TableCell.vue +12 -0
  369. package/src/components/table/TableEmpty.vue +20 -0
  370. package/src/components/table/TableHead.vue +17 -0
  371. package/src/components/table/TableHeader.vue +12 -0
  372. package/src/components/table/TableRow.vue +19 -0
  373. package/src/components/table/index.ts +7 -0
  374. package/src/components/tabs/Tabs.vue +23 -0
  375. package/src/components/tabs/TabsContent.vue +23 -0
  376. package/src/components/tabs/TabsList.vue +26 -0
  377. package/src/components/tabs/TabsTrigger.vue +30 -0
  378. package/src/components/tabs/index.ts +4 -0
  379. package/src/components/textarea/Textarea.vue +25 -0
  380. package/src/components/textarea/index.ts +1 -0
  381. package/src/components/theme-controls/LocaleMenu.vue +95 -0
  382. package/src/components/theme-controls/PaletteMenu.vue +155 -0
  383. package/src/components/theme-controls/ThemeToggle.vue +21 -0
  384. package/src/components/theme-controls/index.ts +15 -0
  385. package/src/components/timeline/Timeline.vue +20 -0
  386. package/src/components/timeline/TimelineItem.vue +68 -0
  387. package/src/components/timeline/index.ts +15 -0
  388. package/src/components/toast/Toaster.vue +62 -0
  389. package/src/components/toast/index.ts +4 -0
  390. package/src/components/toast/toast.ts +57 -0
  391. package/src/components/toggle/Toggle.vue +32 -0
  392. package/src/components/toggle/ToggleGroup.vue +56 -0
  393. package/src/components/toggle/ToggleGroupItem.vue +33 -0
  394. package/src/components/toggle/index.ts +18 -0
  395. package/src/components/token-table/TokenTable.vue +67 -0
  396. package/src/components/token-table/index.ts +2 -0
  397. package/src/components/toolbar/Toolbar.vue +34 -0
  398. package/src/components/toolbar/ToolbarButton.vue +33 -0
  399. package/src/components/toolbar/ToolbarSeparator.vue +21 -0
  400. package/src/components/toolbar/index.ts +3 -0
  401. package/src/components/tooltip/Tooltip.vue +15 -0
  402. package/src/components/tooltip/TooltipContent.vue +38 -0
  403. package/src/components/tooltip/TooltipProvider.vue +16 -0
  404. package/src/components/tooltip/TooltipTrigger.vue +12 -0
  405. package/src/components/tooltip/index.ts +4 -0
  406. package/src/components/tree/Tree.vue +53 -0
  407. package/src/components/tree/TreeItem.vue +59 -0
  408. package/src/components/tree/index.ts +21 -0
  409. package/src/components/tree-select/TreeSelect.vue +141 -0
  410. package/src/components/tree-select/index.ts +1 -0
  411. package/src/components/tree-table/TreeTable.vue +302 -0
  412. package/src/components/tree-table/features.ts +49 -0
  413. package/src/components/tree-table/index.ts +3 -0
  414. package/src/components/video-player/VideoPlayer.vue +472 -0
  415. package/src/components/video-player/index.ts +20 -0
  416. package/src/composables/index.ts +15 -0
  417. package/src/composables/useBase.ts +32 -0
  418. package/src/composables/useChartPalette.ts +33 -0
  419. package/src/composables/useColorMode.ts +29 -0
  420. package/src/composables/useConfirm.ts +81 -0
  421. package/src/composables/useDelayedFlag.ts +62 -0
  422. package/src/composables/useI18n.ts +107 -0
  423. package/src/composables/useIsMobile.ts +34 -0
  424. package/src/composables/useMenuAccent.ts +32 -0
  425. package/src/composables/useMenuAppearance.ts +31 -0
  426. package/src/composables/useMenuColor.ts +31 -0
  427. package/src/composables/usePalette.ts +30 -0
  428. package/src/composables/useStyle.ts +35 -0
  429. package/src/composables/useSurface.ts +30 -0
  430. package/src/composables/useTableQuery.ts +73 -0
  431. package/src/composables/useThemeController.ts +48 -0
  432. package/src/i18n/README.md +68 -0
  433. package/src/i18n/controller.ts +233 -0
  434. package/src/i18n/dictionary.ts +43 -0
  435. package/src/i18n/index.ts +34 -0
  436. package/src/i18n/registry.ts +64 -0
  437. package/src/i18n/ui/en/ui.json +114 -0
  438. package/src/i18n/ui/en/zod.json +16 -0
  439. package/src/i18n/ui/index.ts +48 -0
  440. package/src/i18n/ui/vi/ui.json +114 -0
  441. package/src/i18n/ui/vi/zod.json +16 -0
  442. package/src/lib/date.ts +24 -0
  443. package/src/lib/focus.ts +12 -0
  444. package/src/lib/icons.ts +345 -0
  445. package/src/lib/menu-styles.ts +16 -0
  446. package/src/lib/menu.ts +20 -0
  447. package/src/lib/platform.ts +5 -0
  448. package/src/lib/types.ts +6 -0
  449. package/src/lib/utils.ts +9 -0
  450. package/src/lib/zod-messages.ts +127 -0
  451. package/src/styles/chart.css +30 -0
  452. package/src/styles/index.css +18 -0
  453. package/src/variants/README.md +55 -0
  454. package/src/variants/components/accordion.ts +71 -0
  455. package/src/variants/components/alert.ts +20 -0
  456. package/src/variants/components/badge.ts +76 -0
  457. package/src/variants/components/button-group.ts +136 -0
  458. package/src/variants/components/button.ts +160 -0
  459. package/src/variants/components/checkbox.ts +67 -0
  460. package/src/variants/components/chip.ts +51 -0
  461. package/src/variants/components/code-block.ts +22 -0
  462. package/src/variants/components/dialog.ts +28 -0
  463. package/src/variants/components/empty.ts +60 -0
  464. package/src/variants/components/field.ts +35 -0
  465. package/src/variants/components/float-label.ts +95 -0
  466. package/src/variants/components/input-group.ts +73 -0
  467. package/src/variants/components/input-password.ts +68 -0
  468. package/src/variants/components/kbd.ts +47 -0
  469. package/src/variants/components/picker-trigger.ts +30 -0
  470. package/src/variants/components/radio-group.ts +63 -0
  471. package/src/variants/components/sheet.ts +23 -0
  472. package/src/variants/components/sidebar.ts +33 -0
  473. package/src/variants/components/slider.ts +49 -0
  474. package/src/variants/components/timeline.ts +45 -0
  475. package/src/variants/components/toggle.ts +58 -0
  476. package/src/variants/index.ts +35 -0
  477. package/src/variants/lib/chart/polar.ts +139 -0
  478. package/src/variants/lib/chart/tooltip.ts +101 -0
  479. package/src/variants/lib/chart/types.ts +172 -0
  480. package/src/variants/lib/chart/xy-label.ts +42 -0
  481. package/src/variants/lib/focus.ts +66 -0
  482. package/src/variants/lib/form-errors.ts +59 -0
  483. package/src/variants/lib/highlight.ts +548 -0
  484. package/src/variants/lib/list-move.ts +63 -0
  485. package/src/variants/lib/mask.ts +106 -0
  486. package/src/variants/lib/media.ts +56 -0
  487. package/src/variants/lib/menu-styles.ts +71 -0
  488. package/src/variants/lib/platform.ts +68 -0
  489. package/src/variants/lib/tree.ts +119 -0
  490. package/src/variants/lib/upload.ts +58 -0
  491. package/src/variants/lib/utils.ts +11 -0
@@ -0,0 +1,68 @@
1
+ <script setup lang="ts">
2
+ import type { ClassProps } from '../../lib/types'
3
+ import type { TimelineMarkerVariants } from './index'
4
+ import { computed } from 'vue'
5
+ import { cn } from '../../lib/utils'
6
+ import { injectTimelineContext, timelineMarkerVariants } from './index'
7
+
8
+ const props = withDefaults(
9
+ defineProps<ClassProps & {
10
+ variant?: TimelineMarkerVariants['variant']
11
+ title?: string
12
+ /** Thời điểm, hiện mờ bên phải tiêu đề. */
13
+ time?: string
14
+ /** Mục cuối không vẽ đoạn kẻ nối xuống dưới. */
15
+ last?: boolean
16
+ }>(),
17
+ { variant: 'default', last: false },
18
+ )
19
+
20
+ const timeline = injectTimelineContext(null)
21
+ const size = computed(() => timeline?.size.value ?? 'default')
22
+
23
+ /**
24
+ * Đoạn kẻ nối vẽ bằng một div tuyệt đối, KHÔNG phải `border-l` trên cả mục.
25
+ *
26
+ * Viền trái sẽ chạy hết chiều cao mục kể cả phần trên của chấm mốc, nên nó đâm
27
+ * xuyên qua giữa chấm. Div riêng thì bắt đầu ngay dưới chấm và dừng ở đáy mục.
28
+ */
29
+ /**
30
+ * Canh tâm bằng `translate`, không phải bằng số px cứng.
31
+ *
32
+ * Chấm mốc rộng 16px (sm) hoặc 24px, nên tâm nằm ở 8px / 12px. Viết
33
+ * `left-[7px]` thì mép trái đường kẻ ở 7px và tâm nó ở 7.5px — lệch nửa pixel.
34
+ * Đã đo và thấy đúng: đường kẻ ra x=330 trong khi tâm chấm ở x=331.
35
+ * `left-2 -translate-x-1/2` đặt tâm đúng 8px bất kể đường kẻ dày bao nhiêu.
36
+ */
37
+ const lineOffset = computed(() =>
38
+ size.value === 'sm' ? 'left-2 top-5 -translate-x-1/2' : 'left-3 top-7 -translate-x-1/2',
39
+ )
40
+ const contentGap = computed(() => (size.value === 'sm' ? 'gap-2.5 pb-4' : 'gap-3 pb-6'))
41
+ </script>
42
+
43
+ <template>
44
+ <li :class="cn('relative flex', contentGap, props.last && 'pb-0', props.class)">
45
+ <div
46
+ v-if="!props.last"
47
+ :class="cn('absolute bottom-0 w-px bg-border', lineOffset)"
48
+ aria-hidden="true"
49
+ />
50
+
51
+ <span :class="timelineMarkerVariants({ variant: props.variant, size })">
52
+ <slot name="marker" />
53
+ </span>
54
+
55
+ <div class="flex min-w-0 flex-1 flex-col gap-1 pt-0.5">
56
+ <div class="flex flex-wrap items-baseline justify-between gap-x-3">
57
+ <span v-if="props.title || $slots.title" class="text-sm font-medium">
58
+ <slot name="title">{{ props.title }}</slot>
59
+ </span>
60
+ <!-- `<time>` chứ không phải span: đây là một mốc thời gian thật. -->
61
+ <time v-if="props.time" class="text-xs text-muted-foreground">{{ props.time }}</time>
62
+ </div>
63
+ <div v-if="$slots.default" class="text-sm leading-relaxed text-muted-foreground">
64
+ <slot />
65
+ </div>
66
+ </div>
67
+ </li>
68
+ </template>
@@ -0,0 +1,15 @@
1
+ import type { ComputedRef } from 'vue'
2
+ import type { TimelineVariants } from '../../variants/components/timeline'
3
+ import { createContext } from 'reka-ui'
4
+
5
+ export { timelineMarkerVariants, type TimelineMarkerVariants, timelineVariants, type TimelineVariants } from '../../variants/components/timeline'
6
+ export { default as Timeline } from './Timeline.vue'
7
+
8
+ export interface TimelineContext {
9
+ size: ComputedRef<TimelineVariants['size']>
10
+ }
11
+
12
+ export const [injectTimelineContext, provideTimelineContext]
13
+ = createContext<TimelineContext>('Timeline')
14
+
15
+ export { default as TimelineItem } from './TimelineItem.vue'
@@ -0,0 +1,62 @@
1
+ <script setup lang="ts">
2
+ import type { ToasterProps } from 'vue-sonner'
3
+ import { Toaster } from 'vue-sonner'
4
+ import { useColorMode } from '../../composables/useColorMode'
5
+ import 'vue-sonner/style.css'
6
+
7
+ // Đặt 1 lần trong AdminLayout. Toàn bộ màu lấy từ design token, không hardcode.
8
+ const props = withDefaults(defineProps<ToasterProps>(), {
9
+ // Góc dưới phải: toast không đè lên header, và không cắt ngang chỗ mắt
10
+ // đang đọc khi nội dung bắt đầu từ trên xuống.
11
+ position: 'bottom-right',
12
+ // Chỉ là mức nền cho `toast()` trần. Bốn sắc thái có thời lượng riêng, khai
13
+ // trong `toast.ts` — prop này của sonner chỉ nhận MỘT số cho mọi loại.
14
+ duration: 4000,
15
+ // Bắt buộc khi toast lỗi không tự tắt: phải luôn có đường đóng.
16
+ closeButton: true,
17
+ })
18
+
19
+ const { isDark } = useColorMode()
20
+ </script>
21
+
22
+ <template>
23
+ <!--
24
+ Mặt nền đi qua BIẾN của vue-sonner, không qua class Tailwind.
25
+
26
+ Đo được: `bg-popover`, `border-border`, `rounded-lg` và `shadow-lg` đặt qua
27
+ `classes` đều KHÔNG có tác dụng nào — stylesheet của sonner nằm ngoài mọi
28
+ `@layer` nên nó thắng utility bất kể specificity (bẫy số 8 ở đầu file này).
29
+ Toast vì vậy ra `#000` cứng thay vì `--popover`, và bo góc 8px thay vì 10px
30
+ của token; nghĩa là toast KHÔNG đi theo bảng màu, dù tài liệu vẫn nói có.
31
+
32
+ Biến thì inline style luôn thắng, nên đây là đường duy nhất đi tới nơi.
33
+ -->
34
+ <Toaster
35
+ v-bind="props"
36
+ :theme="isDark ? 'dark' : 'light'"
37
+ :style="{
38
+ '--normal-bg': 'var(--popover)',
39
+ '--normal-text': 'var(--popover-foreground)',
40
+ '--normal-border': 'var(--border)',
41
+ '--border-radius': 'var(--radius-lg)',
42
+ }"
43
+ :toast-options="{
44
+ classes: {
45
+ // Mặt nền, viền và bo góc KHÔNG ở đây — xem `style` bên trên.
46
+ // `surface` giữ lại vì nó là móc của theme kính, không phải màu.
47
+ toast: 'surface group',
48
+ title: 'text-sm font-medium',
49
+ description: 'text-sm text-muted-foreground',
50
+ actionButton: 'bg-primary text-primary-foreground rounded-md text-xs px-2 py-1',
51
+ cancelButton: 'bg-muted text-muted-foreground rounded-md text-xs px-2 py-1',
52
+ closeButton: 'bg-background border-border text-muted-foreground',
53
+ // Dùng -soft-foreground chứ không phải màu gốc: --warning sáng chỉ đạt
54
+ // 2.28:1 trên nền, kể cả cho icon (ngưỡng đồ hoạ là 3:1).
55
+ error: 'border-destructive/40 [&_[data-icon]]:text-destructive-soft-foreground',
56
+ success: 'border-success/40 [&_[data-icon]]:text-success-soft-foreground',
57
+ warning: 'border-warning/40 [&_[data-icon]]:text-warning-soft-foreground',
58
+ info: 'border-info/40 [&_[data-icon]]:text-info-soft-foreground',
59
+ },
60
+ }"
61
+ />
62
+ </template>
@@ -0,0 +1,4 @@
1
+ // Bọc `toast` để gắn thời lượng mặc định theo sắc thái — xem `toast.ts`.
2
+ export { toast } from './toast'
3
+ export { default as Toaster } from './Toaster.vue'
4
+ export type { ExternalToast, ToastT } from 'vue-sonner'
@@ -0,0 +1,57 @@
1
+ import type { ExternalToast } from 'vue-sonner'
2
+ import { toast as base } from 'vue-sonner'
3
+
4
+ /** Kiểu tham số đầu của vue-sonner (`titleT`) — thư viện không export nên suy ra. */
5
+ type Message = Parameters<typeof base.success>[0]
6
+
7
+ /** Bốn sắc thái có thời lượng mặc định riêng. */
8
+ type Severity = 'success' | 'info' | 'warning' | 'error'
9
+
10
+ /**
11
+ * Thời lượng theo **mức nghiêm trọng**, không phải một con số chung.
12
+ *
13
+ * Toast càng quan trọng càng phải ở lại lâu, và cái quan trọng nhất thì không
14
+ * được tự đi. Lỗi biến mất sau bốn giây nghĩa là người dùng vừa liếc đi chỗ
15
+ * khác là mất luôn thông tin duy nhất nói cho họ biết vừa có chuyện gì — mà
16
+ * không có cách nào lấy lại.
17
+ *
18
+ * Đây cũng là yêu cầu của WCAG 2.2.1 (Timing Adjustable): nội dung tự ẩn phải
19
+ * cho người dùng cách kéo dài, hoặc đừng tự ẩn.
20
+ */
21
+ const DURATION: Record<Severity, number> = {
22
+ success: 4000,
23
+ info: 4000,
24
+ warning: 7000,
25
+ // Number.POSITIVE_INFINITY là cách sonner hiểu "chờ người dùng tự tắt".
26
+ // Toaster đã bật `closeButton` nên luôn có đường đóng.
27
+ error: Number.POSITIVE_INFINITY,
28
+ }
29
+
30
+ /**
31
+ * `...data` đứng SAU nên bên gọi vẫn ghi đè được:
32
+ * `toast.error('…', { duration: 5000 })` chạy đúng 5 giây.
33
+ */
34
+ function withDuration(kind: Severity) {
35
+ return (message: Message, data?: ExternalToast): string | number =>
36
+ base[kind](message, { duration: DURATION[kind], ...data })
37
+ }
38
+
39
+ /**
40
+ * Bọc `toast` của vue-sonner để gắn thời lượng mặc định theo sắc thái.
41
+ *
42
+ * Phải bọc chứ không đặt được ở `<Toaster>`: prop `duration` của nó là **một**
43
+ * con số cho mọi loại, thư viện không có chỗ khai theo từng loại.
44
+ *
45
+ * Mọi thứ khác (`toast.promise`, `.loading`, `.dismiss`, gọi trực tiếp…) giữ
46
+ * nguyên bản.
47
+ */
48
+ export const toast = Object.assign(
49
+ (message: Message, data?: ExternalToast) => base(message, data),
50
+ base,
51
+ {
52
+ success: withDuration('success'),
53
+ info: withDuration('info'),
54
+ warning: withDuration('warning'),
55
+ error: withDuration('error'),
56
+ },
57
+ )
@@ -0,0 +1,32 @@
1
+ <script setup lang="ts">
2
+ import type { ToggleEmits, ToggleProps } from 'reka-ui'
3
+ import type { ClassProps } from '../../lib/types'
4
+ import type { ToggleVariants } from './index'
5
+ import { Toggle, useForwardPropsEmits } from 'reka-ui'
6
+ import { computed } from 'vue'
7
+ import { cn } from '../../lib/utils'
8
+ import { toggleVariants } from './index'
9
+
10
+ const props = defineProps<ToggleProps & ClassProps & {
11
+ variant?: ToggleVariants['variant']
12
+ size?: ToggleVariants['size']
13
+ }>()
14
+
15
+ const emits = defineEmits<ToggleEmits>()
16
+
17
+ const delegated = computed(() => {
18
+ const { class: _class, variant: _variant, size: _size, ...rest } = props
19
+ return rest
20
+ })
21
+
22
+ const forwarded = useForwardPropsEmits(delegated, emits)
23
+ </script>
24
+
25
+ <template>
26
+ <Toggle
27
+ v-bind="forwarded"
28
+ :class="cn(toggleVariants({ variant: props.variant, size: props.size }), props.class)"
29
+ >
30
+ <slot />
31
+ </Toggle>
32
+ </template>
@@ -0,0 +1,56 @@
1
+ <script setup lang="ts">
2
+ import type { ToggleGroupRootEmits, ToggleGroupRootProps } from 'reka-ui'
3
+ import type { ClassProps } from '../../lib/types'
4
+ import type { ToggleVariants } from './index'
5
+ import { ToggleGroupRoot, useForwardPropsEmits } from 'reka-ui'
6
+ import { computed } from 'vue'
7
+ import { cn } from '../../lib/utils'
8
+ import { buttonGroupVariants } from '../button-group'
9
+ import { provideToggleGroupContext } from './index'
10
+
11
+ const props = withDefaults(
12
+ defineProps<ToggleGroupRootProps & ClassProps & {
13
+ variant?: ToggleVariants['variant']
14
+ size?: ToggleVariants['size']
15
+ /**
16
+ * `true` thì các nút dính liền thành một khối; `false` thì rời nhau.
17
+ *
18
+ * Khối dính dùng lại **nguyên** `buttonGroupVariants` — một nhóm toggle dính
19
+ * liền với một ButtonGroup là cùng một thứ về mặt hình: bỏ bo góc cạnh
20
+ * trong, gộp viền chung, đẩy nút đang focus lên trên. shadcn viết lại logic
21
+ * đó lần thứ hai trong ToggleGroup; ở đây gọi lại cái đã có.
22
+ */
23
+ attached?: boolean
24
+ }>(),
25
+ { type: 'single', variant: 'ghost', size: 'default', attached: true },
26
+ )
27
+
28
+ const emits = defineEmits<ToggleGroupRootEmits>()
29
+
30
+ const delegated = computed(() => {
31
+ const { class: _class, variant: _variant, size: _size, attached: _attached, ...rest } = props
32
+ return rest
33
+ })
34
+
35
+ const forwarded = useForwardPropsEmits(delegated, emits)
36
+
37
+ provideToggleGroupContext({
38
+ variant: computed(() => props.variant),
39
+ size: computed(() => props.size),
40
+ })
41
+ </script>
42
+
43
+ <template>
44
+ <ToggleGroupRoot
45
+ v-bind="forwarded"
46
+ :class="cn(
47
+ props.attached
48
+ ? buttonGroupVariants({ orientation: props.orientation === 'vertical' ? 'vertical' : 'horizontal' })
49
+ : 'flex w-fit items-center gap-1',
50
+ !props.attached && props.orientation === 'vertical' && 'flex-col items-stretch',
51
+ props.class,
52
+ )"
53
+ >
54
+ <slot />
55
+ </ToggleGroupRoot>
56
+ </template>
@@ -0,0 +1,33 @@
1
+ <script setup lang="ts">
2
+ import type { ToggleGroupItemProps } from 'reka-ui'
3
+ import type { ClassProps } from '../../lib/types'
4
+ import type { ToggleVariants } from './index'
5
+ import { ToggleGroupItem } from 'reka-ui'
6
+ import { computed } from 'vue'
7
+ import { cn } from '../../lib/utils'
8
+ import { injectToggleGroupContext, toggleVariants } from './index'
9
+
10
+ const props = defineProps<ToggleGroupItemProps & ClassProps & {
11
+ variant?: ToggleVariants['variant']
12
+ size?: ToggleVariants['size']
13
+ }>()
14
+
15
+ const group = injectToggleGroupContext(null)
16
+
17
+ const variant = computed(() => props.variant ?? group?.variant.value)
18
+ const size = computed(() => props.size ?? group?.size.value)
19
+
20
+ const delegated = computed(() => {
21
+ const { class: _class, variant: _variant, size: _size, ...rest } = props
22
+ return rest
23
+ })
24
+ </script>
25
+
26
+ <template>
27
+ <ToggleGroupItem
28
+ v-bind="delegated"
29
+ :class="cn(toggleVariants({ variant, size }), props.class)"
30
+ >
31
+ <slot />
32
+ </ToggleGroupItem>
33
+ </template>
@@ -0,0 +1,18 @@
1
+ import type { ComputedRef } from 'vue'
2
+ import type { ToggleVariants } from '../../variants/components/toggle'
3
+ import { createContext } from 'reka-ui'
4
+
5
+ export { toggleVariants, type ToggleVariants } from '../../variants/components/toggle'
6
+ export { default as Toggle } from './Toggle.vue'
7
+ export { default as ToggleGroup } from './ToggleGroup.vue'
8
+
9
+ /** Kiểu và cỡ khai một lần ở nhóm, từng nút con đọc lại. */
10
+ export interface ToggleGroupContext {
11
+ variant: ComputedRef<ToggleVariants['variant']>
12
+ size: ComputedRef<ToggleVariants['size']>
13
+ }
14
+
15
+ export const [injectToggleGroupContext, provideToggleGroupContext]
16
+ = createContext<ToggleGroupContext>('ToggleGroup')
17
+
18
+ export { default as ToggleGroupItem } from './ToggleGroupItem.vue'
@@ -0,0 +1,67 @@
1
+ <script setup lang="ts">
2
+ import type { ClassProps } from '../../lib/types'
3
+ import { computed } from 'vue'
4
+ import { useI18n } from '../../composables/useI18n'
5
+ import { cn } from '../../lib/utils'
6
+ import { DocText } from '../doc-text'
7
+
8
+ /** Một token màu trong bảng tham chiếu. */
9
+ export interface TokenDoc {
10
+ /** Tên biến CSS, ví dụ `--primary`. */
11
+ name: string
12
+ description?: string
13
+ /** Cột phải: token này áp cho cái gì. */
14
+ meta?: string
15
+ }
16
+
17
+ const props = defineProps<ClassProps & {
18
+ rows: TokenDoc[]
19
+ heading?: string
20
+ }>()
21
+
22
+ const { t } = useI18n()
23
+
24
+ // Không đặt default trong props: chuỗi đó tính một lần lúc dựng component nên
25
+ // nó đóng băng ở ngôn ngữ lúc ấy. Rơi lui bằng computed thì đổi ngôn ngữ là đổi.
26
+ const heading = computed(() => props.heading ?? t('ui.tokenTable.heading'))
27
+
28
+ /**
29
+ * Đường dẫn chấm của một token, suy ra từ chính tên CSS — `--button-radius`
30
+ * thành `button.radius`. Đó là dạng mà `definePreset` của `@vestow/theme`
31
+ * nhận, và là cách primevue.dev bày bảng token của họ: hai cột cạnh nhau, một
32
+ * cột đường dẫn một cột biến CSS.
33
+ *
34
+ * SUY RA chứ không khai: không có dữ liệu thứ hai để mà trôi, và thêm một token
35
+ * vào CSS là dòng mới tự có cả hai dạng.
36
+ */
37
+ function tokenPath(name: string): string {
38
+ return name.replace(/^--/, '').replaceAll('-', '.')
39
+ }
40
+ </script>
41
+
42
+ <template>
43
+ <div :class="cn('overflow-hidden rounded-xl border border-border', props.class)">
44
+ <div class="border-b border-border bg-sidebar px-3.5 py-[9px] text-[10.5px] font-medium uppercase tracking-[0.05em] text-muted-foreground">
45
+ {{ heading }}
46
+ </div>
47
+
48
+ <div
49
+ v-for="row in props.rows"
50
+ :key="row.name"
51
+ class="flex min-w-0 flex-col gap-[7px] border-b border-border px-3.5 py-3 last:border-b-0"
52
+ >
53
+ <div class="flex flex-wrap items-center gap-3">
54
+ <span class="flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1">
55
+ <span class="font-mono text-[12.5px] font-semibold [overflow-wrap:anywhere]">{{ tokenPath(row.name) }}</span>
56
+ <code class="rounded-md border border-border px-1.5 py-0.5 font-mono text-[11.5px] text-muted-foreground [overflow-wrap:anywhere]">{{ row.name }}</code>
57
+ </span>
58
+ </div>
59
+
60
+ <span v-if="row.description" class="text-pretty text-[12.5px] leading-[1.55] text-muted-foreground">
61
+ <DocText :text="row.description" />
62
+ </span>
63
+
64
+ <span v-if="row.meta" class="font-mono text-[11.5px] text-muted-foreground">{{ row.meta }}</span>
65
+ </div>
66
+ </div>
67
+ </template>
@@ -0,0 +1,2 @@
1
+ export type { TokenDoc } from './TokenTable.vue'
2
+ export { default as TokenTable } from './TokenTable.vue'
@@ -0,0 +1,34 @@
1
+ <script setup lang="ts">
2
+ import type { ToolbarRootProps } from 'reka-ui'
3
+ import type { ClassProps } from '../../lib/types'
4
+ import { ToolbarRoot } from 'reka-ui'
5
+ import { computed } from 'vue'
6
+ import { cn } from '../../lib/utils'
7
+
8
+ const props = withDefaults(
9
+ defineProps<ToolbarRootProps & ClassProps & {
10
+ /** Viền và nền quanh thanh. Tắt khi nó nằm sẵn trong một Card. */
11
+ bordered?: boolean
12
+ }>(),
13
+ { orientation: 'horizontal', bordered: true, loop: true },
14
+ )
15
+
16
+ const delegated = computed(() => {
17
+ const { class: _class, bordered: _bordered, ...rest } = props
18
+ return rest
19
+ })
20
+ </script>
21
+
22
+ <template>
23
+ <ToolbarRoot
24
+ v-bind="delegated"
25
+ :class="cn(
26
+ 'flex w-full items-center gap-1',
27
+ props.orientation === 'vertical' && 'w-fit flex-col items-stretch',
28
+ props.bordered && 'rounded-lg border border-border bg-card p-1',
29
+ props.class,
30
+ )"
31
+ >
32
+ <slot />
33
+ </ToolbarRoot>
34
+ </template>
@@ -0,0 +1,33 @@
1
+ <script setup lang="ts">
2
+ import type { ToolbarButtonProps } from 'reka-ui'
3
+ import type { ClassProps } from '../../lib/types'
4
+ import type { ButtonVariants } from '../button'
5
+ import { ToolbarButton } from 'reka-ui'
6
+ import { computed } from 'vue'
7
+ import { cn } from '../../lib/utils'
8
+ import { buttonVariants } from '../button'
9
+
10
+ const props = withDefaults(
11
+ defineProps<ToolbarButtonProps & ClassProps & {
12
+ variant?: ButtonVariants['variant']
13
+ size?: ButtonVariants['size']
14
+ }>(),
15
+ { variant: 'ghost', size: 'sm' },
16
+ )
17
+
18
+ const delegated = computed(() => {
19
+ const { class: _class, variant: _variant, size: _size, ...rest } = props
20
+ return rest
21
+ })
22
+ </script>
23
+
24
+ <template>
25
+ <!-- Dùng lại `buttonVariants`: nút trong thanh công cụ và nút ngoài thanh phải
26
+ cùng chiều cao, nếu không hàng bị gợn ở chỗ giao nhau. -->
27
+ <ToolbarButton
28
+ v-bind="delegated"
29
+ :class="cn(buttonVariants({ variant: props.variant, size: props.size }), props.class)"
30
+ >
31
+ <slot />
32
+ </ToolbarButton>
33
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ import type { ToolbarSeparatorProps } from 'reka-ui'
3
+ import type { ClassProps } from '../../lib/types'
4
+ import { ToolbarSeparator } from 'reka-ui'
5
+ import { computed } from 'vue'
6
+ import { cn } from '../../lib/utils'
7
+
8
+ const props = defineProps<ToolbarSeparatorProps & ClassProps>()
9
+
10
+ const delegated = computed(() => {
11
+ const { class: _class, ...rest } = props
12
+ return rest
13
+ })
14
+ </script>
15
+
16
+ <template>
17
+ <ToolbarSeparator
18
+ v-bind="delegated"
19
+ :class="cn('mx-1 shrink-0 bg-border data-[orientation=horizontal]:h-5 data-[orientation=horizontal]:w-px data-[orientation=vertical]:my-1 data-[orientation=vertical]:mx-0 data-[orientation=vertical]:h-px data-[orientation=vertical]:w-full', props.class)"
20
+ />
21
+ </template>
@@ -0,0 +1,3 @@
1
+ export { default as Toolbar } from './Toolbar.vue'
2
+ export { default as ToolbarButton } from './ToolbarButton.vue'
3
+ export { default as ToolbarSeparator } from './ToolbarSeparator.vue'
@@ -0,0 +1,15 @@
1
+ <script setup lang="ts">
2
+ import type { TooltipRootEmits, TooltipRootProps } from 'reka-ui'
3
+ import { TooltipRoot, useForwardPropsEmits } from 'reka-ui'
4
+
5
+ const props = defineProps<TooltipRootProps>()
6
+ const emits = defineEmits<TooltipRootEmits>()
7
+
8
+ const forwarded = useForwardPropsEmits(props, emits)
9
+ </script>
10
+
11
+ <template>
12
+ <TooltipRoot v-bind="forwarded">
13
+ <slot />
14
+ </TooltipRoot>
15
+ </template>
@@ -0,0 +1,38 @@
1
+ <script setup lang="ts">
2
+ import type { TooltipContentEmits, TooltipContentProps } from 'reka-ui'
3
+ import type { ClassProps } from '../../lib/types'
4
+ import { TooltipArrow, TooltipContent, TooltipPortal, useForwardPropsEmits } from 'reka-ui'
5
+ import { computed } from 'vue'
6
+ import { cn } from '../../lib/utils'
7
+
8
+ const props = withDefaults(
9
+ defineProps<TooltipContentProps & ClassProps & { showArrow?: boolean }>(),
10
+ { sideOffset: 6, showArrow: true },
11
+ )
12
+ const emits = defineEmits<TooltipContentEmits>()
13
+
14
+ const delegated = computed(() => {
15
+ const { class: _class, showArrow: _showArrow, ...rest } = props
16
+ return rest
17
+ })
18
+
19
+ const forwarded = useForwardPropsEmits(delegated, emits)
20
+ </script>
21
+
22
+ <template>
23
+ <TooltipPortal>
24
+ <TooltipContent
25
+ v-bind="forwarded"
26
+ :class="cn(
27
+ 'z-(--z-overlay) max-w-xs rounded-md bg-foreground px-2.5 py-1.5 text-xs text-background shadow-md',
28
+ 'data-[state=delayed-open]:animate-in data-[state=instant-open]:animate-in data-[state=closed]:animate-out',
29
+ 'data-[state=closed]:fade-out-0 data-[state=delayed-open]:fade-in-0',
30
+ 'data-[state=delayed-open]:zoom-in-95 data-[state=closed]:zoom-out-95',
31
+ props.class,
32
+ )"
33
+ >
34
+ <slot />
35
+ <TooltipArrow v-if="showArrow" class="fill-foreground" :width="8" :height="4" />
36
+ </TooltipContent>
37
+ </TooltipPortal>
38
+ </template>
@@ -0,0 +1,16 @@
1
+ <script setup lang="ts">
2
+ import type { TooltipProviderProps } from 'reka-ui'
3
+ import { TooltipProvider } from 'reka-ui'
4
+
5
+ // Đặt 1 lần ở root app. Delay ngắn hợp với admin (thao tác liên tục, hover nhiều).
6
+ const props = withDefaults(defineProps<TooltipProviderProps>(), {
7
+ delayDuration: 300,
8
+ skipDelayDuration: 300,
9
+ })
10
+ </script>
11
+
12
+ <template>
13
+ <TooltipProvider v-bind="props">
14
+ <slot />
15
+ </TooltipProvider>
16
+ </template>
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ import type { TooltipTriggerProps } from 'reka-ui'
3
+ import { TooltipTrigger } from 'reka-ui'
4
+
5
+ const props = defineProps<TooltipTriggerProps>()
6
+ </script>
7
+
8
+ <template>
9
+ <TooltipTrigger v-bind="props">
10
+ <slot />
11
+ </TooltipTrigger>
12
+ </template>
@@ -0,0 +1,4 @@
1
+ export { default as Tooltip } from './Tooltip.vue'
2
+ export { default as TooltipContent } from './TooltipContent.vue'
3
+ export { default as TooltipProvider } from './TooltipProvider.vue'
4
+ export { default as TooltipTrigger } from './TooltipTrigger.vue'