@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,62 @@
1
+ import type { MaybeRefOrGetter, Ref } from 'vue'
2
+ import { onScopeDispose, ref, toValue, watch } from 'vue'
3
+
4
+ /**
5
+ * Hoãn việc BẬT một cờ, nhưng tắt ngay lập tức.
6
+ *
7
+ * Sinh ra cho chỉ báo tải: phản hồi dưới ~300ms mà vẫn nháy spinner thì **đọc
8
+ * ra hỏng hơn** là để nó im. Mắt ghi nhận cái loé đó như một glitch chứ không
9
+ * phải như phản hồi — nhất là với dữ liệu đã cache, nơi `loading` bật rồi tắt
10
+ * trong một khung hình.
11
+ *
12
+ * ```ts
13
+ * const showLoader = useDelayedFlag(() => props.loading)
14
+ * ```
15
+ *
16
+ * **Bất đối xứng là cố ý.** Bật thì hoãn, tắt thì tức thì:
17
+ *
18
+ * - Hoãn lúc tắt sẽ giữ spinner lại sau khi dữ liệu đã có — người dùng nhìn
19
+ * thấy chỉ báo tải đè lên đúng thứ vừa tải xong.
20
+ * - Không hoãn lúc bật thì mất sạch tác dụng của composable này.
21
+ *
22
+ * Không có "thời gian hiện tối thiểu": một khi đã quá 300ms thì lần chờ đó đủ
23
+ * dài để spinner kịp đọc ra là spinner, thêm ràng buộc nữa chỉ làm chậm thêm.
24
+ */
25
+ export function useDelayedFlag(
26
+ source: MaybeRefOrGetter<boolean>,
27
+ delayMs = 300,
28
+ ): Readonly<Ref<boolean>> {
29
+ const flag = ref(false)
30
+ let timer: ReturnType<typeof setTimeout> | undefined
31
+
32
+ function clear(): void {
33
+ if (timer !== undefined) {
34
+ clearTimeout(timer)
35
+ timer = undefined
36
+ }
37
+ }
38
+
39
+ watch(
40
+ () => toValue(source),
41
+ (active) => {
42
+ clear()
43
+
44
+ if (!active) {
45
+ flag.value = false
46
+ return
47
+ }
48
+
49
+ timer = setTimeout(() => {
50
+ flag.value = true
51
+ timer = undefined
52
+ }, delayMs)
53
+ },
54
+ { immediate: true },
55
+ )
56
+
57
+ // Component có thể bị gỡ giữa lúc đang chờ — hẹn giờ còn sống sẽ ghi vào một
58
+ // ref không còn ai đọc.
59
+ onScopeDispose(clear)
60
+
61
+ return flag
62
+ }
@@ -0,0 +1,107 @@
1
+ import type { ComputedRef } from 'vue'
2
+ import type { LocaleId, LocaleOption, LocaleState, MessageParams } from '../i18n'
3
+ import { computed, onMounted, shallowRef } from 'vue'
4
+ import { i18nController, locales, uiMessages } from '../i18n'
5
+
6
+ export { locales } from '../i18n'
7
+ export type { LocaleId, LocaleOption } from '../i18n'
8
+
9
+ /**
10
+ * Nối locale controller vanilla của `src/i18n` vào hệ reactivity của Vue.
11
+ *
12
+ * Toàn bộ phần code riêng của Vue cho i18n nằm ở đây — logic đọc localStorage,
13
+ * đoán ngôn ngữ trình duyệt, ghi `<html lang>` và đồng bộ giữa các tab thì ở
14
+ * package i18n, dùng chung với woodblock-react / woodblock-angular sau này. Cùng
15
+ * khuôn với `useThemeController`.
16
+ *
17
+ * Từ điển của thư viện nạp NGAY ở tầng module: mọi component cần dịch đều
18
+ * import file này, nên không có đường nào component vẽ ra trước khi chuỗi của
19
+ * nó có mặt. Nạp trong `onMounted` thì lần render đầu sẽ hiện ra khoá.
20
+ */
21
+ i18nController.addMessages('vi', uiMessages.vi)
22
+ i18nController.addMessages('en', uiMessages.en)
23
+
24
+ const state = shallowRef<LocaleState>(i18nController.getState())
25
+
26
+ // Controller gọi listener ngay khi đăng ký, nên state khớp từ dòng này trở đi.
27
+ i18nController.subscribe((next) => {
28
+ state.value = next
29
+ })
30
+
31
+ let mounted = false
32
+
33
+ /**
34
+ * Trạng thái ngôn ngữ, đã reactive.
35
+ *
36
+ * Gọi trong `setup` của component: phần khởi tạo chạy trong `onMounted` vì nó
37
+ * đụng `document`, `localStorage` và `navigator`.
38
+ */
39
+ export function useLocaleState(): ComputedRef<LocaleState> {
40
+ onMounted(() => {
41
+ if (mounted)
42
+ return
43
+ mounted = true
44
+ i18nController.init()
45
+ })
46
+
47
+ return computed(() => state.value)
48
+ }
49
+
50
+ /**
51
+ * Dịch từ NGOÀI `setup` — vẫn reactive, nhưng không tự gọi `init()`.
52
+ *
53
+ * Dành cho những chỗ không phải component mà vẫn dựng ra giao diện: hàm sinh
54
+ * column def, hàm render `h()`, factory trả về option… `useI18n()` không dùng
55
+ * được ở đó vì nó đăng ký `onMounted`.
56
+ *
57
+ * Vẫn reactive nhờ đọc `state.value`: hàm render nào gọi tới cũng đăng ký phụ
58
+ * thuộc vào locale, nên đổi ngôn ngữ là bảng vẽ lại nhãn.
59
+ *
60
+ * Không gọi `init()`, nên phải có ít nhất một component đã gọi `useI18n()` —
61
+ * trong app thì `App.vue` lo việc đó.
62
+ */
63
+ export function translate(key: string, params?: MessageParams): string {
64
+ void state.value
65
+ return i18nController.t(key, params)
66
+ }
67
+
68
+ export interface UseI18n {
69
+ /** Ngôn ngữ đang bật. Chỉ đọc — đổi bằng `setLocale`. */
70
+ locale: ComputedRef<LocaleId>
71
+ /** Thẻ BCP 47 (`vi-VN`), truyền thẳng vào `Intl` được. */
72
+ tag: ComputedRef<string>
73
+ /** Danh sách ngôn ngữ. MẢNG TĨNH, không phải ref. */
74
+ locales: readonly LocaleOption[]
75
+ setLocale: (value: LocaleId) => void
76
+ t: (key: string, params?: MessageParams) => string
77
+ }
78
+
79
+ /**
80
+ * Dịch, và đổi ngôn ngữ.
81
+ *
82
+ * `t` là hàm THƯỜNG chứ không phải computed, nhưng vẫn reactive: nó đọc
83
+ * `state.value` trước khi tra từ điển, nên effect nào gọi `t()` cũng đăng ký phụ
84
+ * thuộc vào locale và tự chạy lại khi đổi. Nhờ vậy viết `t('x')` giống nhau ở cả
85
+ * `<script setup>` lẫn template — bọc thành computed thì trong script phải viết
86
+ * `t.value('x')`, còn trong template lại là `t('x')`, hai kiểu cho một thứ.
87
+ *
88
+ * Cũng vì lý do đó mà chuỗi nạp muộn vẫn hiện ra: `addMessages` gọi `notify()`,
89
+ * `state` đổi tham chiếu, mọi chỗ gọi `t()` vẽ lại.
90
+ */
91
+ export function useI18n(): UseI18n {
92
+ const current = useLocaleState()
93
+
94
+ function t(key: string, params?: MessageParams): string {
95
+ // Đọc để tạo phụ thuộc reactive. Bỏ dòng này thì chữ đứng im khi đổi ngôn ngữ.
96
+ void current.value
97
+ return i18nController.t(key, params)
98
+ }
99
+
100
+ return {
101
+ locale: computed(() => current.value.locale),
102
+ tag: computed(() => current.value.tag),
103
+ locales,
104
+ setLocale: i18nController.setLocale,
105
+ t,
106
+ }
107
+ }
@@ -0,0 +1,34 @@
1
+ import type { Ref } from 'vue'
2
+ import { onScopeDispose, readonly, ref } from 'vue'
3
+
4
+ /** Mốc `md` của Tailwind. Sidebar đổi sang ngăn kéo ở dưới mốc này. */
5
+ const MOBILE_BREAKPOINT = 768
6
+
7
+ /**
8
+ * Bề ngang viewport có đang dưới mốc `md` hay không.
9
+ *
10
+ * Dùng `matchMedia` chứ không nghe `resize`: trình duyệt chỉ bắn khi VƯỢT mốc
11
+ * nên không phải lọc lại ở mỗi pixel kéo chuột.
12
+ *
13
+ * Giá trị đầu tiên đọc ngay lúc gọi chứ không chờ `onMounted`: sidebar quyết
14
+ * định render ngăn kéo hay cột cố định dựa vào đây, sai một nhịp là thấy rõ một
15
+ * lần nhảy. Ngoài trình duyệt (SSR) thì trả `false` — không có viewport để đo.
16
+ */
17
+ export function useIsMobile(): Readonly<Ref<boolean>> {
18
+ const isMobile = ref(false)
19
+
20
+ if (typeof window === 'undefined')
21
+ return readonly(isMobile)
22
+
23
+ const query = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
24
+ isMobile.value = query.matches
25
+
26
+ const onChange = (event: MediaQueryListEvent): void => {
27
+ isMobile.value = event.matches
28
+ }
29
+
30
+ query.addEventListener('change', onChange)
31
+ onScopeDispose(() => query.removeEventListener('change', onChange))
32
+
33
+ return readonly(isMobile)
34
+ }
@@ -0,0 +1,32 @@
1
+ import type { MenuAccentId, MenuAccentOption } from '@vestow/theme'
2
+ import type { ComputedRef } from 'vue'
3
+ import { menuAccents, themeController } from '@vestow/theme'
4
+ import { computed } from 'vue'
5
+ import { useThemeState } from './useThemeController'
6
+
7
+ export type { MenuAccentId, MenuAccentOption }
8
+ export { menuAccents }
9
+
10
+ export interface UseMenuAccentReturn {
11
+ menuAccent: ComputedRef<MenuAccentId>
12
+ menuAccents: readonly MenuAccentOption[]
13
+ setMenuAccent: (value: MenuAccentId) => void
14
+ }
15
+
16
+ /**
17
+ * Cách tô mục menu đang trỏ tới. Vỏ bọc Vue quanh `themeController`, cùng khuôn
18
+ * với `usePalette` / `useStyle` / `useBase`.
19
+ *
20
+ * Trục này chỉ đổi `--menu-accent` và `--menu-accent-foreground` — hai token mà
21
+ * `menu-styles.ts` đọc. Xem đầu `menus.css` để biết vì sao nó không đụng
22
+ * `--accent` chung.
23
+ */
24
+ export function useMenuAccent(): UseMenuAccentReturn {
25
+ const state = useThemeState()
26
+
27
+ return {
28
+ menuAccent: computed(() => state.value.menuAccent),
29
+ menuAccents,
30
+ setMenuAccent: themeController.setMenuAccent,
31
+ }
32
+ }
@@ -0,0 +1,31 @@
1
+ import type { MenuAppearanceId, MenuAppearanceOption } from '@vestow/theme'
2
+ import type { ComputedRef } from 'vue'
3
+ import { menuAppearances, themeController } from '@vestow/theme'
4
+ import { computed } from 'vue'
5
+ import { useThemeState } from './useThemeController'
6
+
7
+ export type { MenuAppearanceId, MenuAppearanceOption }
8
+ export { menuAppearances }
9
+
10
+ export interface UseMenuAppearanceReturn {
11
+ menuAppearance: ComputedRef<MenuAppearanceId>
12
+ menuAppearances: readonly MenuAppearanceOption[]
13
+ setMenuAppearance: (value: MenuAppearanceId) => void
14
+ }
15
+
16
+ /**
17
+ * Mặt menu đục hay trong. Vỏ bọc Vue quanh `themeController`.
18
+ *
19
+ * KHÔNG có tác dụng khi `surface` đang là `glass` — theme kính đã làm mọi tấm
20
+ * menu trong mờ rồi, chồng thêm là chồng kính lên kính. Khối CSS tự loại mình
21
+ * ra chứ không phải composable này; xem `menus.css`.
22
+ */
23
+ export function useMenuAppearance(): UseMenuAppearanceReturn {
24
+ const state = useThemeState()
25
+
26
+ return {
27
+ menuAppearance: computed(() => state.value.menuAppearance),
28
+ menuAppearances,
29
+ setMenuAppearance: themeController.setMenuAppearance,
30
+ }
31
+ }
@@ -0,0 +1,31 @@
1
+ import type { MenuColorId, MenuColorOption } from '@vestow/theme'
2
+ import type { ComputedRef } from 'vue'
3
+ import { menuColors, themeController } from '@vestow/theme'
4
+ import { computed } from 'vue'
5
+ import { useThemeState } from './useThemeController'
6
+
7
+ export type { MenuColorId, MenuColorOption }
8
+ export { menuColors }
9
+
10
+ export interface UseMenuColorReturn {
11
+ menuColor: ComputedRef<MenuColorId>
12
+ menuColors: readonly MenuColorOption[]
13
+ setMenuColor: (value: MenuColorId) => void
14
+ }
15
+
16
+ /**
17
+ * Mặt menu lấy màu ở đâu. Vỏ bọc Vue quanh `themeController`, cùng khuôn với
18
+ * `useMenuAccent` / `usePalette` / `useStyle`.
19
+ *
20
+ * Trục này khai lại token ngay trên phần tử `.ui-menu` chứ không trên `:root`,
21
+ * nên nó không đụng Popover và Tooltip. Xem `menus.css`.
22
+ */
23
+ export function useMenuColor(): UseMenuColorReturn {
24
+ const state = useThemeState()
25
+
26
+ return {
27
+ menuColor: computed(() => state.value.menuColor),
28
+ menuColors,
29
+ setMenuColor: themeController.setMenuColor,
30
+ }
31
+ }
@@ -0,0 +1,30 @@
1
+ import type { PaletteId, PaletteOption } from '@vestow/theme'
2
+ import type { ComputedRef } from 'vue'
3
+ import { palettes, themeController } from '@vestow/theme'
4
+ import { computed } from 'vue'
5
+ import { useThemeState } from './useThemeController'
6
+
7
+ export type { PaletteId, PaletteOption }
8
+ // Danh sách bảng màu là DỮ LIỆU, ở `@vestow/theme`. Re-export để chỗ gọi
9
+ // không phải nhớ nó nằm ở package nào.
10
+ export { palettes }
11
+
12
+ export interface UsePaletteReturn {
13
+ palette: ComputedRef<PaletteId>
14
+ palettes: readonly PaletteOption[]
15
+ setPalette: (value: PaletteId) => void
16
+ }
17
+
18
+ /**
19
+ * Bảng màu đang chọn. Vỏ bọc Vue quanh `themeController` của
20
+ * `@vestow/theme` — xem `useThemeController.ts`.
21
+ */
22
+ export function usePalette(): UsePaletteReturn {
23
+ const state = useThemeState()
24
+
25
+ return {
26
+ palette: computed(() => state.value.palette),
27
+ palettes,
28
+ setPalette: themeController.setPalette,
29
+ }
30
+ }
@@ -0,0 +1,35 @@
1
+ import type { StyleId, StyleOption } from '@vestow/theme'
2
+ import type { ComputedRef } from 'vue'
3
+ import { styleVariants, themeController } from '@vestow/theme'
4
+ import { computed } from 'vue'
5
+ import { useThemeState } from './useThemeController'
6
+
7
+ export type { StyleId, StyleOption }
8
+ // Danh sách hình khối là DỮ LIỆU, ở `@vestow/theme`. Re-export để chỗ gọi
9
+ // không phải nhớ nó nằm ở package nào.
10
+ export { styleVariants }
11
+
12
+ export interface UseStyleReturn {
13
+ style: ComputedRef<StyleId>
14
+ styleVariants: readonly StyleOption[]
15
+ setStyle: (value: StyleId) => void
16
+ }
17
+
18
+ /**
19
+ * Hình khối đang chọn — bo góc, độ đậm đường kẻ, độ thoáng của control. Vỏ bọc
20
+ * Vue quanh `themeController` của `@vestow/theme`, cùng khuôn với
21
+ * `usePalette` / `useSurface` — xem `useThemeController.ts`.
22
+ *
23
+ * Trục này ghi `data-style` lên `<html>`. Muốn đổi hình khối cho RIÊNG một vùng
24
+ * thì đừng dùng composable này: đặt thẳng `data-style` lên phần tử bao vùng đó,
25
+ * khai báo trực tiếp luôn thắng giá trị thừa kế.
26
+ */
27
+ export function useStyle(): UseStyleReturn {
28
+ const state = useThemeState()
29
+
30
+ return {
31
+ style: computed(() => state.value.style),
32
+ styleVariants,
33
+ setStyle: themeController.setStyle,
34
+ }
35
+ }
@@ -0,0 +1,30 @@
1
+ import type { SurfaceId, SurfaceOption } from '@vestow/theme'
2
+ import type { ComputedRef } from 'vue'
3
+ import { surfaces, themeController } from '@vestow/theme'
4
+ import { computed } from 'vue'
5
+ import { useThemeState } from './useThemeController'
6
+
7
+ export type { SurfaceId, SurfaceOption }
8
+ // Danh sách bề mặt là DỮ LIỆU, ở `@vestow/theme`. Re-export để chỗ gọi
9
+ // không phải nhớ nó nằm ở package nào.
10
+ export { surfaces }
11
+
12
+ export interface UseSurfaceReturn {
13
+ surface: ComputedRef<SurfaceId>
14
+ surfaces: readonly SurfaceOption[]
15
+ setSurface: (value: SurfaceId) => void
16
+ }
17
+
18
+ /**
19
+ * Bề mặt đang chọn (`solid` / `glass`) — TRỤC RIÊNG, chồng lên bảng màu.
20
+ * Vỏ bọc Vue quanh `themeController` của `@vestow/theme`.
21
+ */
22
+ export function useSurface(): UseSurfaceReturn {
23
+ const state = useThemeState()
24
+
25
+ return {
26
+ surface: computed(() => state.value.surface),
27
+ surfaces,
28
+ setSurface: themeController.setSurface,
29
+ }
30
+ }
@@ -0,0 +1,73 @@
1
+ import type { ComputedRef, Ref } from 'vue'
2
+ import type { PaginationAdapter, TableQuery } from '../components/data-table/types'
3
+ import { computed, ref } from 'vue'
4
+
5
+ export interface UseTableQueryOptions<TParams> {
6
+ adapter: PaginationAdapter<TParams>
7
+ pageSize?: number
8
+ /**
9
+ * Trạng thái khởi tạo, thường đọc từ URL để refresh và chia sẻ link đều ra
10
+ * đúng trang đang xem.
11
+ *
12
+ * Việc đọc/ghi URL cố ý KHÔNG nằm ở đây: `packages/ui` không được phụ thuộc
13
+ * `vue-router`. App tự nối — xem `useTableQueryUrl` trong `apps/admin`.
14
+ */
15
+ initialQuery?: Partial<TableQuery>
16
+ }
17
+
18
+ /**
19
+ * Giữ trạng thái truy vấn của DataTable ở phía app và dịch sang tham số API.
20
+ *
21
+ * Composable này cố tình không phụ thuộc TanStack Query: app tự ghép.
22
+ *
23
+ * const { query, params, onQueryChange } = useTableQuery({
24
+ * adapter: createPageNumberAdapter(),
25
+ * })
26
+ *
27
+ * const { data, isFetching } = useQuery({
28
+ * queryKey: ['users', params],
29
+ * queryFn: () => userApi.list(params.value),
30
+ * })
31
+ *
32
+ * <DataTable
33
+ * server-side
34
+ * :total-records="data?.totalCount ?? 0"
35
+ * @page-change="onQueryChange"
36
+ * @sort-change="onQueryChange"
37
+ * @filter-change="onQueryChange"
38
+ * />
39
+ */
40
+ export interface UseTableQueryReturn<TParams> {
41
+ query: Ref<TableQuery>
42
+ params: ComputedRef<TParams>
43
+ onQueryChange: (next: TableQuery) => void
44
+ reset: () => void
45
+ }
46
+
47
+ export function useTableQuery<TParams>(
48
+ options: UseTableQueryOptions<TParams>,
49
+ ): UseTableQueryReturn<TParams> {
50
+ function blank(): TableQuery {
51
+ return {
52
+ pageIndex: 0,
53
+ pageSize: options.pageSize ?? 20,
54
+ sorting: [],
55
+ filters: [],
56
+ }
57
+ }
58
+
59
+ const query = ref<TableQuery>({ ...blank(), ...options.initialQuery })
60
+
61
+ const params = computed<TParams>(() => options.adapter.toParams(query.value))
62
+
63
+ function onQueryChange(next: TableQuery): void {
64
+ query.value = next
65
+ }
66
+
67
+ /** Về trạng thái rỗng — KHÔNG về `initialQuery`, vì đó là "xoá bộ lọc". */
68
+ function reset(): void {
69
+ query.value = blank()
70
+ }
71
+
72
+ return { query, params, onQueryChange, reset }
73
+ }
@@ -0,0 +1,48 @@
1
+ import type { ThemeState } from '@vestow/theme'
2
+ import type { ComputedRef } from 'vue'
3
+ import { themeController } from '@vestow/theme'
4
+ import { computed, onMounted, shallowRef } from 'vue'
5
+
6
+ // Giá trị mặc định của ba trục là DỮ LIỆU ở `@vestow/theme` (controller cũng
7
+ // đọc chính nó để biết khi nào gỡ `data-palette`). Re-export để app không phải
8
+ // gõ lại `'hyperion'` / `'solid'` ở nút "khôi phục mặc định".
9
+ export { defaults as themeDefaults } from '@vestow/theme'
10
+
11
+ /**
12
+ * Nối controller vanilla của `@vestow/theme` vào hệ reactivity của Vue.
13
+ *
14
+ * Đây là TOÀN BỘ phần code riêng của Vue cho ba trục giao diện — logic đọc
15
+ * localStorage, theo dõi `prefers-color-scheme` và ghi lên `<html>` nằm ở
16
+ * package token, dùng chung với woodblock-react / woodblock-angular sau này.
17
+ *
18
+ * State ở module scope, không phải trong hàm: `<html>` chỉ có một, nên mọi
19
+ * component gọi `useColorMode()` / `usePalette()` / `useSurface()` phải đọc
20
+ * chung một giá trị. Đó cũng là lý do component library không cần Pinia (mà
21
+ * cũng không được phép phụ thuộc vào store của app).
22
+ */
23
+ const state = shallowRef<ThemeState>(themeController.getState())
24
+
25
+ // Controller gọi listener ngay khi đăng ký, nên state khớp từ dòng này trở đi.
26
+ themeController.subscribe((next) => {
27
+ state.value = next
28
+ })
29
+
30
+ let mounted = false
31
+
32
+ /**
33
+ * Trạng thái giao diện, đã reactive.
34
+ *
35
+ * Gọi trong `setup` của component: phần khởi tạo chạy trong `onMounted` vì nó
36
+ * đụng `document` và `localStorage` — gọi ngoài đó thì Vue cảnh báo và theme
37
+ * không được áp lên trang.
38
+ */
39
+ export function useThemeState(): ComputedRef<ThemeState> {
40
+ onMounted(() => {
41
+ if (mounted)
42
+ return
43
+ mounted = true
44
+ themeController.init()
45
+ })
46
+
47
+ return computed(() => state.value)
48
+ }
@@ -0,0 +1,68 @@
1
+ # `src/i18n`
2
+
3
+ Locale controller của WoodBlock cộng bộ chuỗi của chính thư viện. Không phụ thuộc
4
+ framework nào — `useI18n` mới là phần riêng của Vue, và nó nằm ở `../composables`.
5
+
6
+ Nó TỪNG là package riêng `src/i18n`. Đợt gộp đưa nó về đây vì repo chỉ còn cây
7
+ Vue, và vì 126 khoá trong `ui/` là chuỗi mà chính component phát ra — chúng không dùng
8
+ được nếu không có component.
9
+
10
+ Hai thứ nằm trong đây:
11
+
12
+ | | |
13
+ |---|---|
14
+ | **Registry** | danh sách ngôn ngữ, khoá localStorage, `lang` tag cho `Intl` |
15
+ | **Controller** | đọc lưu trữ, đoán ngôn ngữ trình duyệt, ghi `<html lang>`, đồng bộ giữa tab |
16
+
17
+ Bộ chuỗi thì chia hai: `ui/` là 126 khoá của THƯ VIỆN (nút Đóng của Dialog, `aria-label`
18
+ của Carousel, thông báo Zod), còn từ điển của app nằm ở `vue/apps/<app>/src/i18n`.
19
+
20
+ ## Dùng controller
21
+
22
+ Controller là **vanilla TypeScript**: không import framework, không chạm `document` ở tầng
23
+ module (import được trong SSR).
24
+
25
+ ```ts
26
+ import { i18nController } from '@vestow/vue/i18n'
27
+
28
+ i18nController.init() // đọc localStorage, hoặc đoán theo navigator.languages
29
+ i18nController.setLocale('en')
30
+ i18nController.subscribe(state => console.log(state.locale))
31
+ ```
32
+
33
+ Vỏ bọc cho từng framework chỉ còn việc nối `subscribe()` vào hệ reactivity của nó. Bản Vue
34
+ ở `vue/packages/ui/src/composables/useI18n.ts` (bản React ở
35
+ `react/packages/ui/src/hooks/useI18n.ts`).
36
+
37
+ ## Đoán ngôn ngữ so bằng TIỀN TỐ
38
+
39
+ Không có lựa chọn đã lưu thì controller đọc `navigator.languages` và so bằng **tiền tố**,
40
+ không so bằng nhau: `en-GB`, `vi-VN`, `en-AU` đều phải khớp. Viết `=== 'en'` thì gần như
41
+ không bao giờ trúng, vì trình duyệt hiếm khi trả về đúng hai ký tự.
42
+
43
+ ## Đồng bộ giữa tab và iframe
44
+
45
+ Controller lắng nghe sự kiện `storage`, mà sự kiện đó **chỉ phát ở document khác document
46
+ vừa ghi** — đúng quan hệ giữa trang cha và iframe. Không có vòng lặp, vì bên ghi đã tự áp
47
+ trong `setLocale`. Mở app ở hai tab cũng không lệch nhau.
48
+
49
+ ## Cố tình KHÔNG dùng `vue-i18n`
50
+
51
+ Thư viện component phải mang theo bộ chuỗi của chính nó — nút Đóng của Dialog, `aria-label`
52
+ của nút phân trang — mà `packages/ui` thì không được kéo một runtime i18n vào mọi app dùng
53
+ nó.
54
+
55
+ Cái giá: không có message compiler, không có bộ luật số nhiều đầy đủ. Chấp nhận được vì
56
+ tiếng Việt không biến đổi theo số lượng, tiếng Anh chỉ cần phân biệt 1 với phần còn lại
57
+ (tách bằng `|`), còn ngày và số thì đã đi qua `Intl`.
58
+
59
+ ## Lệnh
60
+
61
+ ```
62
+ pnpm -F @vestow/vue typecheck # không có bước build: package ship source
63
+ ```
64
+
65
+ ## Publish
66
+
67
+ `exports` trỏ vào `src/` cho tiện phát triển trong workspace; `publishConfig` đổi sang
68
+ `dist/` lúc `pnpm publish`, và `prepack` chạy `build` trước.