@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.
- package/README.md +233 -0
- package/index.ts +8 -0
- package/package.json +68 -0
- package/src/components/accordion/Accordion.vue +45 -0
- package/src/components/accordion/AccordionContent.vue +31 -0
- package/src/components/accordion/AccordionItem.vue +26 -0
- package/src/components/accordion/AccordionTrigger.vue +39 -0
- package/src/components/accordion/index.ts +18 -0
- package/src/components/alert/Alert.vue +17 -0
- package/src/components/alert/AlertDescription.vue +12 -0
- package/src/components/alert/AlertTitle.vue +12 -0
- package/src/components/alert/index.ts +5 -0
- package/src/components/avatar/Avatar.vue +32 -0
- package/src/components/avatar/AvatarFallback.vue +23 -0
- package/src/components/avatar/AvatarImage.vue +18 -0
- package/src/components/avatar/index.ts +3 -0
- package/src/components/badge/Badge.vue +25 -0
- package/src/components/badge/index.ts +3 -0
- package/src/components/breadcrumb/Breadcrumb.vue +14 -0
- package/src/components/breadcrumb/BreadcrumbItem.vue +12 -0
- package/src/components/breadcrumb/BreadcrumbLink.vue +19 -0
- package/src/components/breadcrumb/BreadcrumbPage.vue +12 -0
- package/src/components/breadcrumb/BreadcrumbSeparator.vue +15 -0
- package/src/components/breadcrumb/index.ts +5 -0
- package/src/components/button/Button.vue +55 -0
- package/src/components/button/index.ts +3 -0
- package/src/components/button-group/ButtonGroup.vue +29 -0
- package/src/components/button-group/ButtonGroupSeparator.vue +30 -0
- package/src/components/button-group/ButtonGroupText.vue +29 -0
- package/src/components/button-group/SplitButton.vue +103 -0
- package/src/components/button-group/SplitButtonItems.vue +50 -0
- package/src/components/button-group/index.ts +34 -0
- package/src/components/calendar/Calendar.vue +120 -0
- package/src/components/calendar/RangeCalendar.vue +127 -0
- package/src/components/calendar/index.ts +2 -0
- package/src/components/card/Card.vue +12 -0
- package/src/components/card/CardAction.vue +12 -0
- package/src/components/card/CardContent.vue +12 -0
- package/src/components/card/CardDescription.vue +12 -0
- package/src/components/card/CardFooter.vue +12 -0
- package/src/components/card/CardHeader.vue +15 -0
- package/src/components/card/CardTitle.vue +12 -0
- package/src/components/card/index.ts +7 -0
- package/src/components/carousel/Carousel.vue +164 -0
- package/src/components/carousel/CarouselContent.vue +43 -0
- package/src/components/carousel/CarouselDots.vue +42 -0
- package/src/components/carousel/CarouselItem.vue +58 -0
- package/src/components/carousel/CarouselNext.vue +45 -0
- package/src/components/carousel/CarouselPrevious.vue +45 -0
- package/src/components/carousel/index.ts +44 -0
- package/src/components/cascade-select/CascadeSelect.vue +314 -0
- package/src/components/cascade-select/index.ts +11 -0
- package/src/components/chart/AreaChart.vue +201 -0
- package/src/components/chart/BarChart.vue +389 -0
- package/src/components/chart/ChartContainer.vue +127 -0
- package/src/components/chart/ChartCrosshair.vue +92 -0
- package/src/components/chart/ChartLegend.vue +63 -0
- package/src/components/chart/ChartTooltipCard.vue +49 -0
- package/src/components/chart/LineChart.vue +214 -0
- package/src/components/chart/PieChart.vue +280 -0
- package/src/components/chart/RadarChart.vue +291 -0
- package/src/components/chart/RadialChart.vue +354 -0
- package/src/components/chart/index.ts +30 -0
- package/src/components/chart/polar.ts +5 -0
- package/src/components/chart/tooltip.ts +5 -0
- package/src/components/chart/types.ts +52 -0
- package/src/components/chart/useChartSeries.ts +138 -0
- package/src/components/chart/xy-label.ts +5 -0
- package/src/components/checkbox/Checkbox.vue +81 -0
- package/src/components/checkbox/CheckboxField.vue +129 -0
- package/src/components/checkbox/CheckboxGroup.vue +62 -0
- package/src/components/checkbox/index.ts +21 -0
- package/src/components/chip/Chip.vue +73 -0
- package/src/components/chip/index.ts +3 -0
- package/src/components/code-block/CodeBlock.vue +100 -0
- package/src/components/code-block/index.ts +4 -0
- package/src/components/collapsible/Collapsible.vue +15 -0
- package/src/components/collapsible/CollapsibleContent.vue +26 -0
- package/src/components/collapsible/CollapsibleTrigger.vue +12 -0
- package/src/components/collapsible/index.ts +3 -0
- package/src/components/combobox/Combobox.vue +23 -0
- package/src/components/combobox/ComboboxAnchor.vue +20 -0
- package/src/components/combobox/ComboboxEmpty.vue +21 -0
- package/src/components/combobox/ComboboxGroup.vue +23 -0
- package/src/components/combobox/ComboboxInput.vue +32 -0
- package/src/components/combobox/ComboboxItem.vue +38 -0
- package/src/components/combobox/ComboboxList.vue +43 -0
- package/src/components/combobox/ComboboxSeparator.vue +18 -0
- package/src/components/combobox/ComboboxTrigger.vue +12 -0
- package/src/components/combobox/index.ts +9 -0
- package/src/components/command/Command.vue +54 -0
- package/src/components/command/CommandDialog.vue +41 -0
- package/src/components/command/CommandEmpty.vue +19 -0
- package/src/components/command/CommandGroup.vue +28 -0
- package/src/components/command/CommandInput.vue +25 -0
- package/src/components/command/CommandItem.vue +40 -0
- package/src/components/command/CommandList.vue +13 -0
- package/src/components/command/CommandSeparator.vue +11 -0
- package/src/components/command/CommandShortcut.vue +13 -0
- package/src/components/command/index.ts +34 -0
- package/src/components/command-block/CommandBlock.vue +90 -0
- package/src/components/command-block/index.ts +2 -0
- package/src/components/confirm-dialog/ConfirmDialog.vue +37 -0
- package/src/components/confirm-dialog/index.ts +1 -0
- package/src/components/confirm-popup/ConfirmPopup.vue +123 -0
- package/src/components/confirm-popup/index.ts +1 -0
- package/src/components/context-menu/ContextMenu.vue +15 -0
- package/src/components/context-menu/ContextMenuCheckboxItem.vue +30 -0
- package/src/components/context-menu/ContextMenuContent.vue +36 -0
- package/src/components/context-menu/ContextMenuGroup.vue +12 -0
- package/src/components/context-menu/ContextMenuItem.vue +32 -0
- package/src/components/context-menu/ContextMenuLabel.vue +21 -0
- package/src/components/context-menu/ContextMenuRadioGroup.vue +15 -0
- package/src/components/context-menu/ContextMenuRadioItem.vue +30 -0
- package/src/components/context-menu/ContextMenuSeparator.vue +19 -0
- package/src/components/context-menu/ContextMenuShortcut.vue +13 -0
- package/src/components/context-menu/ContextMenuSub.vue +15 -0
- package/src/components/context-menu/ContextMenuSubContent.vue +26 -0
- package/src/components/context-menu/ContextMenuSubTrigger.vue +26 -0
- package/src/components/context-menu/ContextMenuTrigger.vue +12 -0
- package/src/components/context-menu/index.ts +14 -0
- package/src/components/data-table/DataTable.vue +458 -0
- package/src/components/data-table/DataTableFacetedFilter.vue +97 -0
- package/src/components/data-table/DataTablePagination.vue +103 -0
- package/src/components/data-table/DataTableViewOptions.vue +69 -0
- package/src/components/data-table/features.ts +87 -0
- package/src/components/data-table/index.ts +27 -0
- package/src/components/data-table/pagination-adapter.ts +67 -0
- package/src/components/data-table/selection-column.ts +48 -0
- package/src/components/data-table/types.ts +36 -0
- package/src/components/data-view/DataView.vue +136 -0
- package/src/components/data-view/index.ts +1 -0
- package/src/components/date-picker/DatePicker.vue +117 -0
- package/src/components/date-picker/DateRangePicker.vue +122 -0
- package/src/components/date-picker/index.ts +2 -0
- package/src/components/deferred/Deferred.vue +80 -0
- package/src/components/deferred/index.ts +1 -0
- package/src/components/dialog/Dialog.vue +15 -0
- package/src/components/dialog/DialogClose.vue +12 -0
- package/src/components/dialog/DialogContent.vue +46 -0
- package/src/components/dialog/DialogDescription.vue +19 -0
- package/src/components/dialog/DialogFooter.vue +12 -0
- package/src/components/dialog/DialogHeader.vue +12 -0
- package/src/components/dialog/DialogTitle.vue +19 -0
- package/src/components/dialog/DialogTrigger.vue +12 -0
- package/src/components/dialog/index.ts +10 -0
- package/src/components/doc-example/DocExample.vue +41 -0
- package/src/components/doc-example/index.ts +1 -0
- package/src/components/doc-text/DocText.vue +64 -0
- package/src/components/doc-text/index.ts +1 -0
- package/src/components/dropdown-menu/DropdownMenu.vue +15 -0
- package/src/components/dropdown-menu/DropdownMenuCheckboxItem.vue +33 -0
- package/src/components/dropdown-menu/DropdownMenuContent.vue +36 -0
- package/src/components/dropdown-menu/DropdownMenuGroup.vue +12 -0
- package/src/components/dropdown-menu/DropdownMenuItem.vue +32 -0
- package/src/components/dropdown-menu/DropdownMenuLabel.vue +24 -0
- package/src/components/dropdown-menu/DropdownMenuRadioGroup.vue +15 -0
- package/src/components/dropdown-menu/DropdownMenuRadioItem.vue +33 -0
- package/src/components/dropdown-menu/DropdownMenuSeparator.vue +19 -0
- package/src/components/dropdown-menu/DropdownMenuShortcut.vue +13 -0
- package/src/components/dropdown-menu/DropdownMenuSub.vue +15 -0
- package/src/components/dropdown-menu/DropdownMenuSubContent.vue +29 -0
- package/src/components/dropdown-menu/DropdownMenuSubTrigger.vue +26 -0
- package/src/components/dropdown-menu/DropdownMenuTrigger.vue +12 -0
- package/src/components/dropdown-menu/index.ts +14 -0
- package/src/components/editable/Editable.vue +41 -0
- package/src/components/editable/EditableArea.vue +22 -0
- package/src/components/editable/EditableCancelTrigger.vue +40 -0
- package/src/components/editable/EditableEditTrigger.vue +40 -0
- package/src/components/editable/EditableInput.vue +28 -0
- package/src/components/editable/EditablePreview.vue +34 -0
- package/src/components/editable/EditableSubmitTrigger.vue +40 -0
- package/src/components/editable/index.ts +17 -0
- package/src/components/empty/Empty.vue +17 -0
- package/src/components/empty/EmptyActions.vue +14 -0
- package/src/components/empty/EmptyDescription.vue +12 -0
- package/src/components/empty/EmptyMedia.vue +16 -0
- package/src/components/empty/EmptyTitle.vue +17 -0
- package/src/components/empty/index.ts +7 -0
- package/src/components/field/Field.vue +22 -0
- package/src/components/field/FieldDescription.vue +20 -0
- package/src/components/field/FieldGroup.vue +22 -0
- package/src/components/field/FieldLabel.vue +27 -0
- package/src/components/field/FieldSeparator.vue +28 -0
- package/src/components/field/index.ts +7 -0
- package/src/components/fieldset/Fieldset.vue +126 -0
- package/src/components/fieldset/index.ts +1 -0
- package/src/components/file-upload/FileUpload.vue +149 -0
- package/src/components/file-upload/index.ts +8 -0
- package/src/components/float-label/FloatLabel.vue +26 -0
- package/src/components/float-label/index.ts +3 -0
- package/src/components/form/Form.vue +126 -0
- package/src/components/form/FormDescription.vue +12 -0
- package/src/components/form/FormField.vue +127 -0
- package/src/components/form/FormItem.vue +12 -0
- package/src/components/form/FormLabel.vue +14 -0
- package/src/components/form/FormMessage.vue +31 -0
- package/src/components/form/context.ts +54 -0
- package/src/components/form/errors.ts +6 -0
- package/src/components/form/index.ts +7 -0
- package/src/components/form/types.ts +55 -0
- package/src/components/hover-card/HoverCard.vue +27 -0
- package/src/components/hover-card/HoverCardContent.vue +36 -0
- package/src/components/hover-card/HoverCardTrigger.vue +12 -0
- package/src/components/hover-card/index.ts +3 -0
- package/src/components/ifta-label/IftaLabel.vue +26 -0
- package/src/components/ifta-label/index.ts +1 -0
- package/src/components/index.ts +89 -0
- package/src/components/input/Input.vue +87 -0
- package/src/components/input/index.ts +1 -0
- package/src/components/input-color/ColorArea.vue +36 -0
- package/src/components/input-color/ColorField.vue +32 -0
- package/src/components/input-color/ColorSlider.vue +31 -0
- package/src/components/input-color/InputColor.vue +65 -0
- package/src/components/input-color/index.ts +16 -0
- package/src/components/input-group/InputGroup.vue +26 -0
- package/src/components/input-group/InputGroupAddon.vue +32 -0
- package/src/components/input-group/InputGroupInput.vue +33 -0
- package/src/components/input-group/index.ts +17 -0
- package/src/components/input-number/InputNumber.vue +82 -0
- package/src/components/input-number/index.ts +1 -0
- package/src/components/input-otp/InputOtp.vue +186 -0
- package/src/components/input-otp/index.ts +1 -0
- package/src/components/input-password/InputPassword.vue +116 -0
- package/src/components/input-password/index.ts +5 -0
- package/src/components/input-tags/InputTags.vue +38 -0
- package/src/components/input-tags/InputTagsClear.vue +39 -0
- package/src/components/input-tags/InputTagsInput.vue +27 -0
- package/src/components/input-tags/InputTagsItem.vue +40 -0
- package/src/components/input-tags/InputTagsItemDelete.vue +32 -0
- package/src/components/input-tags/InputTagsItemText.vue +18 -0
- package/src/components/input-tags/index.ts +16 -0
- package/src/components/kbd/Kbd.vue +17 -0
- package/src/components/kbd/KbdGroup.vue +15 -0
- package/src/components/kbd/index.ts +4 -0
- package/src/components/label/Label.vue +23 -0
- package/src/components/label/index.ts +1 -0
- package/src/components/listbox/Listbox.vue +42 -0
- package/src/components/listbox/ListboxContent.vue +22 -0
- package/src/components/listbox/ListboxFilter.vue +34 -0
- package/src/components/listbox/ListboxGroup.vue +31 -0
- package/src/components/listbox/ListboxItem.vue +46 -0
- package/src/components/listbox/index.ts +19 -0
- package/src/components/mask/Mask.vue +205 -0
- package/src/components/mask/index.ts +15 -0
- package/src/components/menubar/Menubar.vue +26 -0
- package/src/components/menubar/MenubarCheckboxItem.vue +30 -0
- package/src/components/menubar/MenubarContent.vue +52 -0
- package/src/components/menubar/MenubarGroup.vue +12 -0
- package/src/components/menubar/MenubarItem.vue +32 -0
- package/src/components/menubar/MenubarLabel.vue +21 -0
- package/src/components/menubar/MenubarMenu.vue +12 -0
- package/src/components/menubar/MenubarRadioGroup.vue +15 -0
- package/src/components/menubar/MenubarRadioItem.vue +30 -0
- package/src/components/menubar/MenubarSeparator.vue +12 -0
- package/src/components/menubar/MenubarShortcut.vue +13 -0
- package/src/components/menubar/MenubarSub.vue +15 -0
- package/src/components/menubar/MenubarSubContent.vue +26 -0
- package/src/components/menubar/MenubarSubTrigger.vue +26 -0
- package/src/components/menubar/MenubarTrigger.vue +30 -0
- package/src/components/menubar/index.ts +29 -0
- package/src/components/navigation-menu/NavigationMenu.vue +43 -0
- package/src/components/navigation-menu/NavigationMenuContent.vue +63 -0
- package/src/components/navigation-menu/NavigationMenuIndicator.vue +31 -0
- package/src/components/navigation-menu/NavigationMenuItem.vue +20 -0
- package/src/components/navigation-menu/NavigationMenuLink.vue +34 -0
- package/src/components/navigation-menu/NavigationMenuList.vue +23 -0
- package/src/components/navigation-menu/NavigationMenuTrigger.vue +38 -0
- package/src/components/navigation-menu/NavigationMenuViewport.vue +34 -0
- package/src/components/navigation-menu/index.ts +18 -0
- package/src/components/order-list/OrderList.vue +168 -0
- package/src/components/order-list/SelectableList.vue +200 -0
- package/src/components/order-list/index.ts +1 -0
- package/src/components/pagination/Pagination.vue +133 -0
- package/src/components/pagination/index.ts +1 -0
- package/src/components/panel/Panel.vue +69 -0
- package/src/components/panel/index.ts +1 -0
- package/src/components/pick-list/PickList.vue +211 -0
- package/src/components/pick-list/index.ts +1 -0
- package/src/components/popover/Popover.vue +15 -0
- package/src/components/popover/PopoverAnchor.vue +12 -0
- package/src/components/popover/PopoverContent.vue +39 -0
- package/src/components/popover/PopoverTrigger.vue +12 -0
- package/src/components/popover/index.ts +4 -0
- package/src/components/progress/Progress.vue +39 -0
- package/src/components/progress/index.ts +1 -0
- package/src/components/props-table/PropsTable.vue +62 -0
- package/src/components/props-table/index.ts +2 -0
- package/src/components/radio-group/RadioGroup.vue +52 -0
- package/src/components/radio-group/RadioGroupItem.vue +80 -0
- package/src/components/radio-group/RadioGroupItemField.vue +128 -0
- package/src/components/radio-group/index.ts +21 -0
- package/src/components/rating/Rating.vue +70 -0
- package/src/components/rating/RatingItem.vue +26 -0
- package/src/components/rating/RatingItemIndicator.vue +28 -0
- package/src/components/rating/RatingStar.vue +16 -0
- package/src/components/rating/index.ts +13 -0
- package/src/components/scroll-area/ScrollArea.vue +52 -0
- package/src/components/scroll-area/index.ts +1 -0
- package/src/components/search-input/SearchInput.vue +46 -0
- package/src/components/search-input/index.ts +1 -0
- package/src/components/select/Select.vue +15 -0
- package/src/components/select/SelectContent.vue +67 -0
- package/src/components/select/SelectGroup.vue +20 -0
- package/src/components/select/SelectItem.vue +59 -0
- package/src/components/select/SelectLabel.vue +20 -0
- package/src/components/select/SelectSeparator.vue +18 -0
- package/src/components/select/SelectTrigger.vue +101 -0
- package/src/components/select/SelectValue.vue +46 -0
- package/src/components/select/index.ts +8 -0
- package/src/components/separator/Separator.vue +25 -0
- package/src/components/separator/index.ts +1 -0
- package/src/components/sheet/Sheet.vue +15 -0
- package/src/components/sheet/SheetClose.vue +12 -0
- package/src/components/sheet/SheetContent.vue +45 -0
- package/src/components/sheet/SheetDescription.vue +19 -0
- package/src/components/sheet/SheetFooter.vue +12 -0
- package/src/components/sheet/SheetHeader.vue +12 -0
- package/src/components/sheet/SheetTitle.vue +19 -0
- package/src/components/sheet/SheetTrigger.vue +12 -0
- package/src/components/sheet/index.ts +10 -0
- package/src/components/sidebar/Sidebar.vue +108 -0
- package/src/components/sidebar/SidebarContent.vue +19 -0
- package/src/components/sidebar/SidebarFooter.vue +19 -0
- package/src/components/sidebar/SidebarGroup.vue +19 -0
- package/src/components/sidebar/SidebarGroupAction.vue +28 -0
- package/src/components/sidebar/SidebarGroupContent.vue +19 -0
- package/src/components/sidebar/SidebarGroupLabel.vue +25 -0
- package/src/components/sidebar/SidebarHeader.vue +19 -0
- package/src/components/sidebar/SidebarInput.vue +15 -0
- package/src/components/sidebar/SidebarInset.vue +22 -0
- package/src/components/sidebar/SidebarMenu.vue +19 -0
- package/src/components/sidebar/SidebarMenuAction.vue +41 -0
- package/src/components/sidebar/SidebarMenuBadge.vue +24 -0
- package/src/components/sidebar/SidebarMenuButton.vue +94 -0
- package/src/components/sidebar/SidebarMenuItem.vue +19 -0
- package/src/components/sidebar/SidebarMenuSkeleton.vue +36 -0
- package/src/components/sidebar/SidebarMenuSub.vue +22 -0
- package/src/components/sidebar/SidebarMenuSubButton.vue +39 -0
- package/src/components/sidebar/SidebarMenuSubItem.vue +19 -0
- package/src/components/sidebar/SidebarProvider.vue +114 -0
- package/src/components/sidebar/SidebarRail.vue +37 -0
- package/src/components/sidebar/SidebarSeparator.vue +15 -0
- package/src/components/sidebar/SidebarTrigger.vue +27 -0
- package/src/components/sidebar/context.ts +39 -0
- package/src/components/sidebar/index.ts +34 -0
- package/src/components/skeleton/Skeleton.vue +10 -0
- package/src/components/skeleton/index.ts +1 -0
- package/src/components/skip-link/SkipLink.vue +45 -0
- package/src/components/skip-link/index.ts +1 -0
- package/src/components/slider/Slider.vue +57 -0
- package/src/components/slider/index.ts +3 -0
- package/src/components/speed-dial/SpeedDial.vue +362 -0
- package/src/components/speed-dial/index.ts +28 -0
- package/src/components/spinner/Spinner.vue +20 -0
- package/src/components/spinner/index.ts +1 -0
- package/src/components/splitter/Splitter.vue +24 -0
- package/src/components/splitter/SplitterHandle.vue +51 -0
- package/src/components/splitter/SplitterPanel.vue +30 -0
- package/src/components/splitter/index.ts +14 -0
- package/src/components/stepper/Stepper.vue +34 -0
- package/src/components/stepper/StepperItem.vue +113 -0
- package/src/components/stepper/index.ts +2 -0
- package/src/components/switch/Switch.vue +35 -0
- package/src/components/switch/index.ts +1 -0
- package/src/components/table/Table.vue +24 -0
- package/src/components/table/TableBody.vue +12 -0
- package/src/components/table/TableCell.vue +12 -0
- package/src/components/table/TableEmpty.vue +20 -0
- package/src/components/table/TableHead.vue +17 -0
- package/src/components/table/TableHeader.vue +12 -0
- package/src/components/table/TableRow.vue +19 -0
- package/src/components/table/index.ts +7 -0
- package/src/components/tabs/Tabs.vue +23 -0
- package/src/components/tabs/TabsContent.vue +23 -0
- package/src/components/tabs/TabsList.vue +26 -0
- package/src/components/tabs/TabsTrigger.vue +30 -0
- package/src/components/tabs/index.ts +4 -0
- package/src/components/textarea/Textarea.vue +25 -0
- package/src/components/textarea/index.ts +1 -0
- package/src/components/theme-controls/LocaleMenu.vue +95 -0
- package/src/components/theme-controls/PaletteMenu.vue +155 -0
- package/src/components/theme-controls/ThemeToggle.vue +21 -0
- package/src/components/theme-controls/index.ts +15 -0
- package/src/components/timeline/Timeline.vue +20 -0
- package/src/components/timeline/TimelineItem.vue +68 -0
- package/src/components/timeline/index.ts +15 -0
- package/src/components/toast/Toaster.vue +62 -0
- package/src/components/toast/index.ts +4 -0
- package/src/components/toast/toast.ts +57 -0
- package/src/components/toggle/Toggle.vue +32 -0
- package/src/components/toggle/ToggleGroup.vue +56 -0
- package/src/components/toggle/ToggleGroupItem.vue +33 -0
- package/src/components/toggle/index.ts +18 -0
- package/src/components/token-table/TokenTable.vue +67 -0
- package/src/components/token-table/index.ts +2 -0
- package/src/components/toolbar/Toolbar.vue +34 -0
- package/src/components/toolbar/ToolbarButton.vue +33 -0
- package/src/components/toolbar/ToolbarSeparator.vue +21 -0
- package/src/components/toolbar/index.ts +3 -0
- package/src/components/tooltip/Tooltip.vue +15 -0
- package/src/components/tooltip/TooltipContent.vue +38 -0
- package/src/components/tooltip/TooltipProvider.vue +16 -0
- package/src/components/tooltip/TooltipTrigger.vue +12 -0
- package/src/components/tooltip/index.ts +4 -0
- package/src/components/tree/Tree.vue +53 -0
- package/src/components/tree/TreeItem.vue +59 -0
- package/src/components/tree/index.ts +21 -0
- package/src/components/tree-select/TreeSelect.vue +141 -0
- package/src/components/tree-select/index.ts +1 -0
- package/src/components/tree-table/TreeTable.vue +302 -0
- package/src/components/tree-table/features.ts +49 -0
- package/src/components/tree-table/index.ts +3 -0
- package/src/components/video-player/VideoPlayer.vue +472 -0
- package/src/components/video-player/index.ts +20 -0
- package/src/composables/index.ts +15 -0
- package/src/composables/useBase.ts +32 -0
- package/src/composables/useChartPalette.ts +33 -0
- package/src/composables/useColorMode.ts +29 -0
- package/src/composables/useConfirm.ts +81 -0
- package/src/composables/useDelayedFlag.ts +62 -0
- package/src/composables/useI18n.ts +107 -0
- package/src/composables/useIsMobile.ts +34 -0
- package/src/composables/useMenuAccent.ts +32 -0
- package/src/composables/useMenuAppearance.ts +31 -0
- package/src/composables/useMenuColor.ts +31 -0
- package/src/composables/usePalette.ts +30 -0
- package/src/composables/useStyle.ts +35 -0
- package/src/composables/useSurface.ts +30 -0
- package/src/composables/useTableQuery.ts +73 -0
- package/src/composables/useThemeController.ts +48 -0
- package/src/i18n/README.md +68 -0
- package/src/i18n/controller.ts +233 -0
- package/src/i18n/dictionary.ts +43 -0
- package/src/i18n/index.ts +34 -0
- package/src/i18n/registry.ts +64 -0
- package/src/i18n/ui/en/ui.json +114 -0
- package/src/i18n/ui/en/zod.json +16 -0
- package/src/i18n/ui/index.ts +48 -0
- package/src/i18n/ui/vi/ui.json +114 -0
- package/src/i18n/ui/vi/zod.json +16 -0
- package/src/lib/date.ts +24 -0
- package/src/lib/focus.ts +12 -0
- package/src/lib/icons.ts +345 -0
- package/src/lib/menu-styles.ts +16 -0
- package/src/lib/menu.ts +20 -0
- package/src/lib/platform.ts +5 -0
- package/src/lib/types.ts +6 -0
- package/src/lib/utils.ts +9 -0
- package/src/lib/zod-messages.ts +127 -0
- package/src/styles/chart.css +30 -0
- package/src/styles/index.css +18 -0
- package/src/variants/README.md +55 -0
- package/src/variants/components/accordion.ts +71 -0
- package/src/variants/components/alert.ts +20 -0
- package/src/variants/components/badge.ts +76 -0
- package/src/variants/components/button-group.ts +136 -0
- package/src/variants/components/button.ts +160 -0
- package/src/variants/components/checkbox.ts +67 -0
- package/src/variants/components/chip.ts +51 -0
- package/src/variants/components/code-block.ts +22 -0
- package/src/variants/components/dialog.ts +28 -0
- package/src/variants/components/empty.ts +60 -0
- package/src/variants/components/field.ts +35 -0
- package/src/variants/components/float-label.ts +95 -0
- package/src/variants/components/input-group.ts +73 -0
- package/src/variants/components/input-password.ts +68 -0
- package/src/variants/components/kbd.ts +47 -0
- package/src/variants/components/picker-trigger.ts +30 -0
- package/src/variants/components/radio-group.ts +63 -0
- package/src/variants/components/sheet.ts +23 -0
- package/src/variants/components/sidebar.ts +33 -0
- package/src/variants/components/slider.ts +49 -0
- package/src/variants/components/timeline.ts +45 -0
- package/src/variants/components/toggle.ts +58 -0
- package/src/variants/index.ts +35 -0
- package/src/variants/lib/chart/polar.ts +139 -0
- package/src/variants/lib/chart/tooltip.ts +101 -0
- package/src/variants/lib/chart/types.ts +172 -0
- package/src/variants/lib/chart/xy-label.ts +42 -0
- package/src/variants/lib/focus.ts +66 -0
- package/src/variants/lib/form-errors.ts +59 -0
- package/src/variants/lib/highlight.ts +548 -0
- package/src/variants/lib/list-move.ts +63 -0
- package/src/variants/lib/mask.ts +106 -0
- package/src/variants/lib/media.ts +56 -0
- package/src/variants/lib/menu-styles.ts +71 -0
- package/src/variants/lib/platform.ts +68 -0
- package/src/variants/lib/tree.ts +119 -0
- package/src/variants/lib/upload.ts +58 -0
- package/src/variants/lib/utils.ts +11 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { SwitchRootEmits, SwitchRootProps } from 'reka-ui'
|
|
3
|
+
import type { ClassProps } from '../../lib/types'
|
|
4
|
+
import { SwitchRoot, SwitchThumb, useForwardPropsEmits } from 'reka-ui'
|
|
5
|
+
import { computed } from 'vue'
|
|
6
|
+
import { focusRing } from '../../lib/focus'
|
|
7
|
+
import { cn } from '../../lib/utils'
|
|
8
|
+
|
|
9
|
+
const props = defineProps<SwitchRootProps & ClassProps>()
|
|
10
|
+
const emits = defineEmits<SwitchRootEmits>()
|
|
11
|
+
|
|
12
|
+
const delegated = computed(() => {
|
|
13
|
+
const { class: _class, ...rest } = props
|
|
14
|
+
return rest
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const forwarded = useForwardPropsEmits(delegated, emits)
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<SwitchRoot
|
|
22
|
+
v-bind="forwarded"
|
|
23
|
+
:class="cn(
|
|
24
|
+
'peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors',
|
|
25
|
+
focusRing,
|
|
26
|
+
'disabled:cursor-not-allowed disabled:opacity-50',
|
|
27
|
+
'data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',
|
|
28
|
+
props.class,
|
|
29
|
+
)"
|
|
30
|
+
>
|
|
31
|
+
<SwitchThumb
|
|
32
|
+
class="pointer-events-none block size-4 rounded-full bg-background shadow-sm ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
|
|
33
|
+
/>
|
|
34
|
+
</SwitchRoot>
|
|
35
|
+
</template>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Switch } from './Switch.vue'
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ClassProps } from '../../lib/types'
|
|
3
|
+
import { cn } from '../../lib/utils'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Thuộc tính rơi tự do đi xuống `<table>`, KHÔNG xuống cái div bọc.
|
|
7
|
+
*
|
|
8
|
+
* Cái div chỉ là vùng cuộn — nó đã có `containerClass` của riêng nó. Đặt
|
|
9
|
+
* `role="treegrid"` lên `<Table>` mà nó dính vào div thì bảng vẫn là `table`,
|
|
10
|
+
* còn cái div thành một treegrid rỗng: hai lời khai sai cùng lúc, không có gì báo.
|
|
11
|
+
*/
|
|
12
|
+
defineOptions({ inheritAttrs: false })
|
|
13
|
+
|
|
14
|
+
const props = defineProps<ClassProps & { containerClass?: string }>()
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<template>
|
|
18
|
+
<!-- Bảng luôn cuộn trong container riêng -> body trang không bao giờ cuộn ngang -->
|
|
19
|
+
<div :class="cn('relative w-full overflow-auto', props.containerClass)">
|
|
20
|
+
<table v-bind="$attrs" :class="cn('w-full caption-bottom border-separate border-spacing-0 text-sm', props.class)">
|
|
21
|
+
<slot />
|
|
22
|
+
</table>
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ClassProps } from '../../lib/types'
|
|
3
|
+
import { cn } from '../../lib/utils'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<ClassProps>()
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<tbody :class="cn('[&_tr:last-child_td]:border-b-0', props.class)">
|
|
10
|
+
<slot />
|
|
11
|
+
</tbody>
|
|
12
|
+
</template>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ClassProps } from '../../lib/types'
|
|
3
|
+
import { cn } from '../../lib/utils'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<ClassProps>()
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<td :class="cn('border-b border-border px-3 py-2 align-middle', props.class)">
|
|
10
|
+
<slot />
|
|
11
|
+
</td>
|
|
12
|
+
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ClassProps } from '../../lib/types'
|
|
3
|
+
import { useI18n } from '../../composables/useI18n'
|
|
4
|
+
import { Inbox } from '../../lib/icons'
|
|
5
|
+
import { cn } from '../../lib/utils'
|
|
6
|
+
|
|
7
|
+
const props = defineProps<ClassProps & { colspan: number, message?: string }>()
|
|
8
|
+
const { t } = useI18n()
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<tr>
|
|
13
|
+
<td :colspan="props.colspan" :class="cn('h-40 text-center', props.class)">
|
|
14
|
+
<div class="flex flex-col items-center justify-center gap-2 text-muted-foreground">
|
|
15
|
+
<Inbox class="size-6" />
|
|
16
|
+
<span class="text-sm">{{ props.message ?? t('ui.table.empty') }}</span>
|
|
17
|
+
</div>
|
|
18
|
+
</td>
|
|
19
|
+
</tr>
|
|
20
|
+
</template>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ClassProps } from '../../lib/types'
|
|
3
|
+
import { cn } from '../../lib/utils'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<ClassProps>()
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<th
|
|
10
|
+
:class="cn(
|
|
11
|
+
'h-10 whitespace-nowrap border-b border-border bg-muted/60 px-3 text-left align-middle text-xs font-medium text-muted-foreground backdrop-blur',
|
|
12
|
+
props.class,
|
|
13
|
+
)"
|
|
14
|
+
>
|
|
15
|
+
<slot />
|
|
16
|
+
</th>
|
|
17
|
+
</template>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ClassProps } from '../../lib/types'
|
|
3
|
+
import { cn } from '../../lib/utils'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<ClassProps & { sticky?: boolean }>()
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<thead :class="cn(props.sticky && '[&_th]:sticky [&_th]:top-0 [&_th]:z-(--z-raised)', props.class)">
|
|
10
|
+
<slot />
|
|
11
|
+
</thead>
|
|
12
|
+
</template>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ClassProps } from '../../lib/types'
|
|
3
|
+
import { cn } from '../../lib/utils'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<ClassProps & { selected?: boolean, clickable?: boolean }>()
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<tr
|
|
10
|
+
:data-state="props.selected ? 'selected' : undefined"
|
|
11
|
+
:class="cn(
|
|
12
|
+
'transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',
|
|
13
|
+
props.clickable && 'cursor-pointer',
|
|
14
|
+
props.class,
|
|
15
|
+
)"
|
|
16
|
+
>
|
|
17
|
+
<slot />
|
|
18
|
+
</tr>
|
|
19
|
+
</template>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { default as Table } from './Table.vue'
|
|
2
|
+
export { default as TableBody } from './TableBody.vue'
|
|
3
|
+
export { default as TableCell } from './TableCell.vue'
|
|
4
|
+
export { default as TableEmpty } from './TableEmpty.vue'
|
|
5
|
+
export { default as TableHead } from './TableHead.vue'
|
|
6
|
+
export { default as TableHeader } from './TableHeader.vue'
|
|
7
|
+
export { default as TableRow } from './TableRow.vue'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { TabsRootEmits, TabsRootProps } from 'reka-ui'
|
|
3
|
+
import type { ClassProps } from '../../lib/types'
|
|
4
|
+
import { TabsRoot, useForwardPropsEmits } from 'reka-ui'
|
|
5
|
+
import { computed } from 'vue'
|
|
6
|
+
import { cn } from '../../lib/utils'
|
|
7
|
+
|
|
8
|
+
const props = defineProps<TabsRootProps & ClassProps>()
|
|
9
|
+
const emits = defineEmits<TabsRootEmits>()
|
|
10
|
+
|
|
11
|
+
const delegated = computed(() => {
|
|
12
|
+
const { class: _class, ...rest } = props
|
|
13
|
+
return rest
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const forwarded = useForwardPropsEmits(delegated, emits)
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<template>
|
|
20
|
+
<TabsRoot v-bind="forwarded" :class="cn('flex flex-col gap-4', props.class)">
|
|
21
|
+
<slot />
|
|
22
|
+
</TabsRoot>
|
|
23
|
+
</template>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { TabsContentProps } from 'reka-ui'
|
|
3
|
+
import type { ClassProps } from '../../lib/types'
|
|
4
|
+
import { TabsContent } from 'reka-ui'
|
|
5
|
+
import { computed } from 'vue'
|
|
6
|
+
import { cn } from '../../lib/utils'
|
|
7
|
+
|
|
8
|
+
const props = defineProps<TabsContentProps & ClassProps>()
|
|
9
|
+
|
|
10
|
+
const delegated = computed(() => {
|
|
11
|
+
const { class: _class, ...rest } = props
|
|
12
|
+
return rest
|
|
13
|
+
})
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<TabsContent
|
|
18
|
+
v-bind="delegated"
|
|
19
|
+
:class="cn('outline-none focus-visible:ring-2 focus-visible:ring-ring', props.class)"
|
|
20
|
+
>
|
|
21
|
+
<slot />
|
|
22
|
+
</TabsContent>
|
|
23
|
+
</template>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { TabsListProps } from 'reka-ui'
|
|
3
|
+
import type { ClassProps } from '../../lib/types'
|
|
4
|
+
import { TabsList } from 'reka-ui'
|
|
5
|
+
import { computed } from 'vue'
|
|
6
|
+
import { cn } from '../../lib/utils'
|
|
7
|
+
|
|
8
|
+
const props = defineProps<TabsListProps & ClassProps>()
|
|
9
|
+
|
|
10
|
+
const delegated = computed(() => {
|
|
11
|
+
const { class: _class, ...rest } = props
|
|
12
|
+
return rest
|
|
13
|
+
})
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<TabsList
|
|
18
|
+
v-bind="delegated"
|
|
19
|
+
:class="cn(
|
|
20
|
+
'inline-flex h-9 w-fit items-center justify-center gap-1 rounded-lg bg-muted p-1 text-muted-foreground',
|
|
21
|
+
props.class,
|
|
22
|
+
)"
|
|
23
|
+
>
|
|
24
|
+
<slot />
|
|
25
|
+
</TabsList>
|
|
26
|
+
</template>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { TabsTriggerProps } from 'reka-ui'
|
|
3
|
+
import type { ClassProps } from '../../lib/types'
|
|
4
|
+
import { TabsTrigger } from 'reka-ui'
|
|
5
|
+
import { computed } from 'vue'
|
|
6
|
+
import { cn } from '../../lib/utils'
|
|
7
|
+
|
|
8
|
+
const props = defineProps<TabsTriggerProps & ClassProps>()
|
|
9
|
+
|
|
10
|
+
const delegated = computed(() => {
|
|
11
|
+
const { class: _class, ...rest } = props
|
|
12
|
+
return rest
|
|
13
|
+
})
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<TabsTrigger
|
|
18
|
+
v-bind="delegated"
|
|
19
|
+
:class="cn(
|
|
20
|
+
'inline-flex items-center justify-center gap-1.5 whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium transition-all',
|
|
21
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
|
22
|
+
'disabled:pointer-events-none disabled:opacity-50',
|
|
23
|
+
'data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm',
|
|
24
|
+
'[&_svg]:size-4 [&_svg]:shrink-0',
|
|
25
|
+
props.class,
|
|
26
|
+
)"
|
|
27
|
+
>
|
|
28
|
+
<slot />
|
|
29
|
+
</TabsTrigger>
|
|
30
|
+
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ClassProps } from '../../lib/types'
|
|
3
|
+
import { focusRing, invalidRing } from '../../lib/focus'
|
|
4
|
+
import { cn } from '../../lib/utils'
|
|
5
|
+
|
|
6
|
+
defineProps<ClassProps & { invalid?: boolean }>()
|
|
7
|
+
|
|
8
|
+
const model = defineModel<string | null>()
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<textarea
|
|
13
|
+
v-model="model"
|
|
14
|
+
:aria-invalid="invalid || undefined"
|
|
15
|
+
:data-invalid="invalid || undefined"
|
|
16
|
+
:class="cn(
|
|
17
|
+
'flex min-h-20 w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-colors',
|
|
18
|
+
'placeholder:text-muted-foreground',
|
|
19
|
+
focusRing,
|
|
20
|
+
'disabled:cursor-not-allowed disabled:opacity-50',
|
|
21
|
+
invalidRing,
|
|
22
|
+
$props.class,
|
|
23
|
+
)"
|
|
24
|
+
/>
|
|
25
|
+
</template>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Textarea } from './Textarea.vue'
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useI18n } from '../../composables/useI18n'
|
|
3
|
+
import { Check, Languages } from '../../lib/icons'
|
|
4
|
+
import { Button } from '../button'
|
|
5
|
+
import {
|
|
6
|
+
DropdownMenu,
|
|
7
|
+
DropdownMenuContent,
|
|
8
|
+
DropdownMenuItem,
|
|
9
|
+
DropdownMenuLabel,
|
|
10
|
+
DropdownMenuTrigger,
|
|
11
|
+
} from '../dropdown-menu'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Nút đổi ngôn ngữ. Dùng ở CẢ HAI header — `KitHeader` của trang giới thiệu và
|
|
15
|
+
* `AdminLayout` của màn quản trị.
|
|
16
|
+
*
|
|
17
|
+
* Trước đó danh sách ngôn ngữ nằm trong `PaletteMenu`, mà `PaletteMenu` chỉ có ở
|
|
18
|
+
* `KitHeader` — nghĩa là vào `/admin` rồi thì không còn đường đổi ngôn ngữ. Tách
|
|
19
|
+
* ra thành control riêng vì ngôn ngữ không phải một trục *giao diện*: nó không
|
|
20
|
+
* đi cùng nhóm với bảng màu, chế độ sáng tối và bề mặt.
|
|
21
|
+
*
|
|
22
|
+
* Nút là ICON, không phải mã ngôn ngữ.
|
|
23
|
+
*
|
|
24
|
+
* Bản trước hiện "EN" / "VI" với lý do: người đang lạc sang thứ tiếng không đọc
|
|
25
|
+
* được vẫn nhận ra mã, còn icon thì chỉ nói đây là chỗ đổi ngôn ngữ chứ không
|
|
26
|
+
* nói đang ở ngôn ngữ nào. Đánh đổi đó vẫn có thật — nhưng thông tin ấy không
|
|
27
|
+
* mất, nó lùi vào trong menu: mục đang bật có dấu tick, và tên mỗi ngôn ngữ
|
|
28
|
+
* viết bằng CHÍNH ngôn ngữ đó nên vẫn nhận ra được mà không cần đọc hiểu.
|
|
29
|
+
*
|
|
30
|
+
* `Languages` chứ không phải `Globe`: quả địa cầu trong lucide đọc ra là vùng /
|
|
31
|
+
* trang web, còn cái này là dịch thuật.
|
|
32
|
+
*
|
|
33
|
+
* **Nét 2,2 chứ không phải 2 mặc định của Lucide** — chỉnh cho THUẬN MẮT, và là
|
|
34
|
+
* chỗ duy nhất trong repo đi chệch nét chuẩn.
|
|
35
|
+
*
|
|
36
|
+
* `languages` là một glyph THƯA: hai cụm nhỏ nằm chéo nhau, nét ngắn, ở giữa
|
|
37
|
+
* gần như trống. Đo độ phủ mực trên 24 icon Lucide đang dùng thì nó được 0,219
|
|
38
|
+
* — thấp hơn trung vị 0,265 khoảng 17%, và thấp nhất trong ba icon của cụm bên
|
|
39
|
+
* phải `KitHeader`. Cùng khung 16px mà nhìn ra nhạt hơn hẳn.
|
|
40
|
+
*
|
|
41
|
+
* Không chữa bằng cách phóng to: thiếu MỰC chứ không thiếu BỀ NGANG — nét chéo
|
|
42
|
+
* đã trải kín khung, nên 17–18px làm nó to hơn hai icon kia thấy rõ (đã dựng
|
|
43
|
+
* thử ở mức phóng 4×). Chữa bằng nét thì mực dày lên mà hình không đổi cỡ.
|
|
44
|
+
*
|
|
45
|
+
* 2,4 bù đủ mực theo số đo nhưng nhìn ra ĐẬM hơn hai icon kia — dấu hiệu cho
|
|
46
|
+
* thấy khớp riêng độ phủ là sai, vì phép đo đó phạt oan glyph thưa mà rộng.
|
|
47
|
+
* 2,2 là chỗ mắt thấy cả ba cùng sức nặng.
|
|
48
|
+
*/
|
|
49
|
+
const props = defineProps<{
|
|
50
|
+
/** Class cho nút bấm. Hai header có kích thước nút khác nhau. */
|
|
51
|
+
class?: string
|
|
52
|
+
}>()
|
|
53
|
+
|
|
54
|
+
const { locale, locales, setLocale, t } = useI18n()
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<template>
|
|
58
|
+
<DropdownMenu>
|
|
59
|
+
<DropdownMenuTrigger as-child>
|
|
60
|
+
<Button
|
|
61
|
+
variant="ghost"
|
|
62
|
+
:class="props.class"
|
|
63
|
+
:aria-label="t('ui.locale.language')"
|
|
64
|
+
>
|
|
65
|
+
<!-- Nét 2,2, không phải 2 — lý do ở JSDoc đầu file. -->
|
|
66
|
+
<Languages :stroke-width="2.2" />
|
|
67
|
+
</Button>
|
|
68
|
+
</DropdownMenuTrigger>
|
|
69
|
+
|
|
70
|
+
<DropdownMenuContent align="end" class="w-[212px]">
|
|
71
|
+
<DropdownMenuLabel>{{ t('ui.locale.language') }}</DropdownMenuLabel>
|
|
72
|
+
|
|
73
|
+
<DropdownMenuItem
|
|
74
|
+
v-for="item in locales"
|
|
75
|
+
:key="item.id"
|
|
76
|
+
class="gap-2.5"
|
|
77
|
+
@select="setLocale(item.id)"
|
|
78
|
+
>
|
|
79
|
+
<span class="grid size-[26px] flex-none place-items-center rounded-lg border border-border bg-secondary text-[10px] font-semibold uppercase">
|
|
80
|
+
{{ item.id }}
|
|
81
|
+
</span>
|
|
82
|
+
|
|
83
|
+
<span class="flex min-w-0 flex-1 flex-col">
|
|
84
|
+
<!-- Tên viết bằng CHÍNH ngôn ngữ đó, không dịch — xem `locales` trong
|
|
85
|
+
`src/i18n`. Dịch nó ra thì người đang lạc ngôn ngữ không tìm
|
|
86
|
+
được đường về. -->
|
|
87
|
+
<span class="text-[12.5px] font-medium">{{ item.name }}</span>
|
|
88
|
+
<span class="truncate text-[11px] text-muted-foreground">{{ item.tag }}</span>
|
|
89
|
+
</span>
|
|
90
|
+
|
|
91
|
+
<Check v-if="item.id === locale" class="flex-none text-primary" />
|
|
92
|
+
</DropdownMenuItem>
|
|
93
|
+
</DropdownMenuContent>
|
|
94
|
+
</DropdownMenu>
|
|
95
|
+
</template>
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { Component } from 'vue'
|
|
3
|
+
import type { ColorMode } from '../../composables/useColorMode'
|
|
4
|
+
import { computed } from 'vue'
|
|
5
|
+
import { useColorMode } from '../../composables/useColorMode'
|
|
6
|
+
import { useI18n } from '../../composables/useI18n'
|
|
7
|
+
import { usePalette } from '../../composables/usePalette'
|
|
8
|
+
import { Check, Monitor, Moon, Palette, Sun } from '../../lib/icons'
|
|
9
|
+
import { cn } from '../../lib/utils'
|
|
10
|
+
import { Button } from '../button'
|
|
11
|
+
import {
|
|
12
|
+
DropdownMenu,
|
|
13
|
+
DropdownMenuContent,
|
|
14
|
+
DropdownMenuItem,
|
|
15
|
+
DropdownMenuLabel,
|
|
16
|
+
DropdownMenuSeparator,
|
|
17
|
+
DropdownMenuTrigger,
|
|
18
|
+
} from '../dropdown-menu'
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
* Ngôn ngữ KHÔNG nằm ở đây — nó có `LocaleMenu` riêng. Ba trục trong menu này
|
|
22
|
+
* đều là diện mạo và đều ghi lên `<html>` qua `themeController`; ngôn ngữ thì
|
|
23
|
+
* không cùng nhóm, và menu này lại chỉ có ở `KitHeader`, nên để chung là màn
|
|
24
|
+
* quản trị không có đường đổi ngôn ngữ.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Đọc thẳng ba composable, KHÔNG qua pinia store của app.
|
|
29
|
+
*
|
|
30
|
+
* Trước đây control này nằm ở `apps/admin` và đi qua `useThemeStore`. Cái store
|
|
31
|
+
* đó không giữ state — nó chỉ chuyền tiếp đúng ba composable dưới đây — nên bỏ
|
|
32
|
+
* nó đi không tạo ra nguồn sự thật thứ hai, mà lại gỡ được ràng buộc cuối cùng
|
|
33
|
+
* giữ control này ngoài `packages/ui`: không router, không store.
|
|
34
|
+
*
|
|
35
|
+
* Nhờ vậy cả ba app (kit, blocks, admin) dùng chung một bản.
|
|
36
|
+
*/
|
|
37
|
+
const props = defineProps<{
|
|
38
|
+
/**
|
|
39
|
+
* Class cho nút bấm. Cùng khuôn với `LocaleMenu` — hai control này luôn đứng
|
|
40
|
+
* cạnh nhau nên chúng phải nhận sắc thái từ cùng một chỗ.
|
|
41
|
+
*/
|
|
42
|
+
class?: string
|
|
43
|
+
}>()
|
|
44
|
+
|
|
45
|
+
const { t } = useI18n()
|
|
46
|
+
const { mode, setMode } = useColorMode()
|
|
47
|
+
const { palette, palettes, setPalette } = usePalette()
|
|
48
|
+
|
|
49
|
+
const activePalette = computed(() => palettes.find(item => item.id === palette.value) ?? palettes[0])
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Khai ngay tại đây chứ không đưa vào `useColorMode`: composable nằm trong
|
|
53
|
+
* `packages/ui`, mà chuỗi người dùng nhìn thấy thì thuộc về app.
|
|
54
|
+
*
|
|
55
|
+
* Phải là `computed`, không phải hằng ở tầng module: hằng tính đúng một lần lúc
|
|
56
|
+
* import nên nó đóng băng ở ngôn ngữ lúc ấy — cùng cái bẫy của `withDefaults`.
|
|
57
|
+
*/
|
|
58
|
+
const colorModes = computed<{ id: ColorMode, name: string, description: string, icon: Component }[]>(() => [
|
|
59
|
+
{ id: 'light', name: t('ui.theme.modeLight'), description: t('ui.theme.modeLightHint'), icon: Sun },
|
|
60
|
+
{ id: 'dark', name: t('ui.theme.modeDark'), description: t('ui.theme.modeDarkHint'), icon: Moon },
|
|
61
|
+
{ id: 'system', name: t('ui.theme.modeSystem'), description: t('ui.theme.modeSystemHint'), icon: Monitor },
|
|
62
|
+
])
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Mô tả của bảng màu PHỦ lên registry, không sửa registry.
|
|
66
|
+
*
|
|
67
|
+
* `@vestow/theme` là dữ liệu thuần dùng chung cho mọi framework — nhét một
|
|
68
|
+
* danh sách ngôn ngữ vào đó là bắt nó biết tới i18n. Chuỗi tiếng Anh ở registry
|
|
69
|
+
* vì vậy vẫn còn nguyên và làm bản mặc định cho bên dùng không có i18n; app thì
|
|
70
|
+
* phủ lên theo `id`.
|
|
71
|
+
*
|
|
72
|
+
* Tên bảng màu là danh từ riêng nên giữ nguyên — chỉ mô tả mới dịch.
|
|
73
|
+
*/
|
|
74
|
+
const paletteOptions = computed(() =>
|
|
75
|
+
palettes.map(item => ({ ...item, description: t(`ui.theme.paletteHint.${item.id}`) })),
|
|
76
|
+
)
|
|
77
|
+
</script>
|
|
78
|
+
|
|
79
|
+
<template>
|
|
80
|
+
<DropdownMenu>
|
|
81
|
+
<DropdownMenuTrigger as-child>
|
|
82
|
+
<!--
|
|
83
|
+
Icon, không phải ô màu của bảng đang chọn.
|
|
84
|
+
|
|
85
|
+
Bản trước vẽ một chấm tròn mang đúng màu primary đang bật — nó nói được
|
|
86
|
+
"đang ở bảng nào" ngay ở trạng thái nghỉ. Đổi sang icon thì mất vế đó,
|
|
87
|
+
nhưng thông tin lùi vào menu chứ không mất hẳn: mục đang bật có dấu tick,
|
|
88
|
+
và mỗi bảng màu vẫn hiện dải ô màu của nó.
|
|
89
|
+
|
|
90
|
+
Đổi lại, ba nút trong cụm bên phải header giờ cùng một ngôn ngữ hình ảnh
|
|
91
|
+
(icon đơn sắc) thay vì một chấm màu đứng giữa hai icon.
|
|
92
|
+
|
|
93
|
+
Nhãn nói CHUNG về giao diện, không riêng bảng màu: menu này gom cả ba
|
|
94
|
+
trục — bảng màu, sáng/tối, bề mặt.
|
|
95
|
+
-->
|
|
96
|
+
<Button variant="ghost" size="icon" :class="cn('size-[30px] rounded-full', props.class)" :aria-label="t('ui.theme.appearanceSettings')">
|
|
97
|
+
<Palette />
|
|
98
|
+
</Button>
|
|
99
|
+
</DropdownMenuTrigger>
|
|
100
|
+
|
|
101
|
+
<DropdownMenuContent align="end" class="w-[262px]">
|
|
102
|
+
<DropdownMenuLabel>{{ t('ui.theme.palette') }}</DropdownMenuLabel>
|
|
103
|
+
|
|
104
|
+
<DropdownMenuItem
|
|
105
|
+
v-for="item in paletteOptions"
|
|
106
|
+
:key="item.id"
|
|
107
|
+
class="gap-2.5"
|
|
108
|
+
@select="setPalette(item.id)"
|
|
109
|
+
>
|
|
110
|
+
<span class="flex flex-none gap-[3px]">
|
|
111
|
+
<span
|
|
112
|
+
v-for="(swatch, index) in item.swatches"
|
|
113
|
+
:key="index"
|
|
114
|
+
class="size-3.5 rounded-md border border-border"
|
|
115
|
+
:style="{ background: swatch }"
|
|
116
|
+
/>
|
|
117
|
+
</span>
|
|
118
|
+
|
|
119
|
+
<span class="flex min-w-0 flex-1 flex-col">
|
|
120
|
+
<span class="text-[12.5px] font-medium">{{ item.name }}</span>
|
|
121
|
+
<span class="truncate text-[11px] text-muted-foreground">{{ item.description }}</span>
|
|
122
|
+
</span>
|
|
123
|
+
|
|
124
|
+
<Check v-if="item.id === palette" class="flex-none text-primary" />
|
|
125
|
+
</DropdownMenuItem>
|
|
126
|
+
|
|
127
|
+
<DropdownMenuSeparator />
|
|
128
|
+
|
|
129
|
+
<DropdownMenuLabel>{{ t('ui.theme.appearance') }}</DropdownMenuLabel>
|
|
130
|
+
|
|
131
|
+
<DropdownMenuItem
|
|
132
|
+
v-for="item in colorModes"
|
|
133
|
+
:key="item.id"
|
|
134
|
+
class="gap-2.5"
|
|
135
|
+
@select="setMode(item.id)"
|
|
136
|
+
>
|
|
137
|
+
<span class="grid size-[26px] flex-none place-items-center rounded-lg border border-border bg-secondary">
|
|
138
|
+
<component :is="item.icon" />
|
|
139
|
+
</span>
|
|
140
|
+
|
|
141
|
+
<span class="flex min-w-0 flex-1 flex-col">
|
|
142
|
+
<span class="text-[12.5px] font-medium">{{ item.name }}</span>
|
|
143
|
+
<span class="truncate text-[11px] text-muted-foreground">{{ item.description }}</span>
|
|
144
|
+
</span>
|
|
145
|
+
|
|
146
|
+
<Check v-if="item.id === mode" class="flex-none text-primary" />
|
|
147
|
+
</DropdownMenuItem>
|
|
148
|
+
|
|
149
|
+
<div class="flex items-center justify-between gap-2 px-2 pb-1 pt-0.5 font-mono text-[11px] text-muted-foreground">
|
|
150
|
+
<span>--primary</span>
|
|
151
|
+
<span class="text-foreground">{{ activePalette.swatches[0] }}</span>
|
|
152
|
+
</div>
|
|
153
|
+
</DropdownMenuContent>
|
|
154
|
+
</DropdownMenu>
|
|
155
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useColorMode } from '../../composables/useColorMode'
|
|
3
|
+
import { useI18n } from '../../composables/useI18n'
|
|
4
|
+
import { Moon, Sun } from '../../lib/icons'
|
|
5
|
+
import { Button } from '../button'
|
|
6
|
+
|
|
7
|
+
const { t } = useI18n()
|
|
8
|
+
const { isDark, toggle } = useColorMode()
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<Button
|
|
13
|
+
variant="ghost"
|
|
14
|
+
size="icon"
|
|
15
|
+
:aria-label="isDark ? t('ui.theme.toLight') : t('ui.theme.toDark')"
|
|
16
|
+
@click="toggle()"
|
|
17
|
+
>
|
|
18
|
+
<Moon v-if="isDark" />
|
|
19
|
+
<Sun v-else />
|
|
20
|
+
</Button>
|
|
21
|
+
</template>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ba control cho ba trục giao diện, cộng nút đổi ngôn ngữ.
|
|
3
|
+
*
|
|
4
|
+
* Nằm ở `packages/ui` chứ không ở app vì chúng **không đọc router và không đọc
|
|
5
|
+
* store** — chỉ đi qua `useColorMode` / `usePalette` / `useSurface` / `useI18n`,
|
|
6
|
+
* mà cả bốn đều ở ngay trong package này. Nhờ vậy kit, blocks và admin dùng
|
|
7
|
+
* chung đúng một bản thay vì mỗi app một bản trôi dần khỏi nhau.
|
|
8
|
+
*
|
|
9
|
+
* Trước đây chúng ở `apps/admin` với lý do "phải đọc pinia store". Lý do đó
|
|
10
|
+
* không đứng vững: cái store ấy không giữ state, nó chỉ chuyền tiếp đúng ba
|
|
11
|
+
* composable trên.
|
|
12
|
+
*/
|
|
13
|
+
export { default as LocaleMenu } from './LocaleMenu.vue'
|
|
14
|
+
export { default as PaletteMenu } from './PaletteMenu.vue'
|
|
15
|
+
export { default as ThemeToggle } from './ThemeToggle.vue'
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ClassProps } from '../../lib/types'
|
|
3
|
+
import type { TimelineVariants } from './index'
|
|
4
|
+
import { computed } from 'vue'
|
|
5
|
+
import { cn } from '../../lib/utils'
|
|
6
|
+
import { provideTimelineContext, timelineVariants } from './index'
|
|
7
|
+
|
|
8
|
+
const props = withDefaults(
|
|
9
|
+
defineProps<ClassProps & { size?: TimelineVariants['size'] }>(),
|
|
10
|
+
{ size: 'default' },
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
provideTimelineContext({ size: computed(() => props.size) })
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<ol :class="cn(timelineVariants({ size: props.size }), props.class)">
|
|
18
|
+
<slot />
|
|
19
|
+
</ol>
|
|
20
|
+
</template>
|