From be229fc694d5c39bdec3dccd4dd5729fbd920f54 Mon Sep 17 00:00:00 2001 From: overtrue Date: Sat, 25 Oct 2025 16:04:31 +0800 Subject: [PATCH] step1: add shadcn components --- assets/css/tailwind.css | 64 + components/ui/accordion/Accordion.vue | 19 + components/ui/accordion/AccordionContent.vue | 22 + components/ui/accordion/AccordionItem.vue | 22 + components/ui/accordion/AccordionTrigger.vue | 37 + components/ui/accordion/index.ts | 4 + components/ui/alert-dialog/AlertDialog.vue | 15 + .../ui/alert-dialog/AlertDialogAction.vue | 18 + .../ui/alert-dialog/AlertDialogCancel.vue | 25 + .../ui/alert-dialog/AlertDialogContent.vue | 39 + .../alert-dialog/AlertDialogDescription.vue | 23 + .../ui/alert-dialog/AlertDialogFooter.vue | 21 + .../ui/alert-dialog/AlertDialogHeader.vue | 16 + .../ui/alert-dialog/AlertDialogTitle.vue | 20 + .../ui/alert-dialog/AlertDialogTrigger.vue | 12 + components/ui/alert-dialog/index.ts | 9 + components/ui/alert/Alert.vue | 17 + components/ui/alert/AlertDescription.vue | 14 + components/ui/alert/AlertTitle.vue | 14 + components/ui/alert/index.ts | 24 + components/ui/aspect-ratio/AspectRatio.vue | 12 + components/ui/aspect-ratio/index.ts | 1 + components/ui/auto-form/AutoForm.vue | 106 + components/ui/auto-form/AutoFormField.vue | 45 + .../ui/auto-form/AutoFormFieldArray.vue | 110 + .../ui/auto-form/AutoFormFieldBoolean.vue | 41 + components/ui/auto-form/AutoFormFieldDate.vue | 57 + components/ui/auto-form/AutoFormFieldEnum.vue | 49 + components/ui/auto-form/AutoFormFieldFile.vue | 74 + .../ui/auto-form/AutoFormFieldInput.vue | 36 + .../ui/auto-form/AutoFormFieldNumber.vue | 32 + .../ui/auto-form/AutoFormFieldObject.vue | 78 + components/ui/auto-form/AutoFormLabel.vue | 14 + components/ui/auto-form/constant.ts | 40 + components/ui/auto-form/dependencies.ts | 93 + components/ui/auto-form/index.ts | 15 + components/ui/auto-form/interface.ts | 95 + components/ui/auto-form/utils.ts | 188 + components/ui/avatar/Avatar.vue | 22 + components/ui/avatar/AvatarFallback.vue | 12 + components/ui/avatar/AvatarImage.vue | 12 + components/ui/avatar/index.ts | 25 + components/ui/badge/Badge.vue | 17 + components/ui/badge/index.ts | 26 + components/ui/breadcrumb/Breadcrumb.vue | 13 + .../ui/breadcrumb/BreadcrumbEllipsis.vue | 22 + components/ui/breadcrumb/BreadcrumbItem.vue | 16 + components/ui/breadcrumb/BreadcrumbLink.vue | 20 + components/ui/breadcrumb/BreadcrumbList.vue | 16 + components/ui/breadcrumb/BreadcrumbPage.vue | 19 + .../ui/breadcrumb/BreadcrumbSeparator.vue | 21 + components/ui/breadcrumb/index.ts | 7 + components/ui/button-group/ButtonGroup.vue | 22 + .../ui/button-group/ButtonGroupSeparator.vue | 24 + .../ui/button-group/ButtonGroupText.vue | 29 + components/ui/button-group/index.ts | 25 + components/ui/button/Button.vue | 28 + components/ui/button/index.ts | 37 + components/ui/calendar/Calendar.vue | 58 + components/ui/calendar/CalendarCell.vue | 22 + .../ui/calendar/CalendarCellTrigger.vue | 36 + components/ui/calendar/CalendarGrid.vue | 22 + components/ui/calendar/CalendarGridBody.vue | 12 + components/ui/calendar/CalendarGridHead.vue | 12 + components/ui/calendar/CalendarGridRow.vue | 19 + components/ui/calendar/CalendarHeadCell.vue | 19 + components/ui/calendar/CalendarHeader.vue | 19 + components/ui/calendar/CalendarHeading.vue | 29 + components/ui/calendar/CalendarNextButton.vue | 30 + components/ui/calendar/CalendarPrevButton.vue | 30 + components/ui/calendar/index.ts | 12 + components/ui/card/Card.vue | 21 + components/ui/card/CardContent.vue | 14 + components/ui/card/CardDescription.vue | 14 + components/ui/card/CardFooter.vue | 14 + components/ui/card/CardHeader.vue | 14 + components/ui/card/CardTitle.vue | 18 + components/ui/card/index.ts | 6 + components/ui/carousel/Carousel.vue | 52 + components/ui/carousel/CarouselContent.vue | 29 + components/ui/carousel/CarouselItem.vue | 23 + components/ui/carousel/CarouselNext.vue | 31 + components/ui/carousel/CarouselPrevious.vue | 31 + components/ui/carousel/index.ts | 10 + components/ui/carousel/interface.ts | 26 + components/ui/carousel/useCarousel.ts | 56 + components/ui/chart-area/AreaChart.vue | 141 + components/ui/chart-area/index.ts | 66 + components/ui/chart-bar/BarChart.vue | 116 + components/ui/chart-bar/index.ts | 66 + components/ui/chart-donut/DonutChart.vue | 101 + components/ui/chart-donut/index.ts | 39 + components/ui/chart-line/LineChart.vue | 107 + components/ui/chart-line/index.ts | 66 + components/ui/chart/ChartCrosshair.vue | 45 + components/ui/chart/ChartLegend.vue | 59 + components/ui/chart/ChartSingleTooltip.vue | 63 + components/ui/chart/ChartTooltip.vue | 40 + components/ui/chart/index.ts | 18 + components/ui/chart/interface.ts | 64 + components/ui/checkbox/Checkbox.vue | 30 + components/ui/checkbox/index.ts | 1 + components/ui/collapsible/Collapsible.vue | 15 + .../ui/collapsible/CollapsibleContent.vue | 12 + .../ui/collapsible/CollapsibleTrigger.vue | 12 + components/ui/collapsible/index.ts | 3 + components/ui/combobox/Combobox.vue | 15 + components/ui/combobox/ComboboxAnchor.vue | 22 + components/ui/combobox/ComboboxEmpty.vue | 17 + components/ui/combobox/ComboboxGroup.vue | 26 + components/ui/combobox/ComboboxInput.vue | 26 + components/ui/combobox/ComboboxItem.vue | 23 + components/ui/combobox/ComboboxList.vue | 31 + components/ui/combobox/ComboboxSeparator.vue | 20 + components/ui/combobox/ComboboxTrigger.vue | 23 + components/ui/combobox/index.ts | 10 + components/ui/command/Command.vue | 86 + components/ui/command/CommandDialog.vue | 21 + components/ui/command/CommandEmpty.vue | 23 + components/ui/command/CommandGroup.vue | 44 + components/ui/command/CommandInput.vue | 35 + components/ui/command/CommandItem.vue | 75 + components/ui/command/CommandList.vue | 21 + components/ui/command/CommandSeparator.vue | 20 + components/ui/command/CommandShortcut.vue | 14 + components/ui/command/index.ts | 25 + components/ui/context-menu/ContextMenu.vue | 15 + .../context-menu/ContextMenuCheckboxItem.vue | 37 + .../ui/context-menu/ContextMenuContent.vue | 33 + .../ui/context-menu/ContextMenuGroup.vue | 12 + .../ui/context-menu/ContextMenuItem.vue | 31 + .../ui/context-menu/ContextMenuLabel.vue | 23 + .../ui/context-menu/ContextMenuPortal.vue | 12 + .../ui/context-menu/ContextMenuRadioGroup.vue | 19 + .../ui/context-menu/ContextMenuRadioItem.vue | 37 + .../ui/context-menu/ContextMenuSeparator.vue | 18 + .../ui/context-menu/ContextMenuShortcut.vue | 14 + components/ui/context-menu/ContextMenuSub.vue | 19 + .../ui/context-menu/ContextMenuSubContent.vue | 32 + .../ui/context-menu/ContextMenuSubTrigger.vue | 32 + .../ui/context-menu/ContextMenuTrigger.vue | 14 + components/ui/context-menu/index.ts | 14 + components/ui/dialog/Dialog.vue | 15 + components/ui/dialog/DialogClose.vue | 12 + components/ui/dialog/DialogContent.vue | 47 + components/ui/dialog/DialogDescription.vue | 22 + components/ui/dialog/DialogFooter.vue | 19 + components/ui/dialog/DialogHeader.vue | 16 + components/ui/dialog/DialogScrollContent.vue | 56 + components/ui/dialog/DialogTitle.vue | 27 + components/ui/dialog/DialogTrigger.vue | 12 + components/ui/dialog/index.ts | 9 + components/ui/drawer/Drawer.vue | 19 + components/ui/drawer/DrawerContent.vue | 28 + components/ui/drawer/DrawerDescription.vue | 17 + components/ui/drawer/DrawerFooter.vue | 14 + components/ui/drawer/DrawerHeader.vue | 14 + components/ui/drawer/DrawerOverlay.vue | 15 + components/ui/drawer/DrawerTitle.vue | 17 + components/ui/drawer/index.ts | 8 + components/ui/dropdown-menu/DropdownMenu.vue | 15 + .../DropdownMenuCheckboxItem.vue | 37 + .../ui/dropdown-menu/DropdownMenuContent.vue | 35 + .../ui/dropdown-menu/DropdownMenuGroup.vue | 12 + .../ui/dropdown-menu/DropdownMenuItem.vue | 26 + .../ui/dropdown-menu/DropdownMenuLabel.vue | 22 + .../dropdown-menu/DropdownMenuRadioGroup.vue | 19 + .../dropdown-menu/DropdownMenuRadioItem.vue | 38 + .../dropdown-menu/DropdownMenuSeparator.vue | 20 + .../ui/dropdown-menu/DropdownMenuShortcut.vue | 14 + .../ui/dropdown-menu/DropdownMenuSub.vue | 19 + .../dropdown-menu/DropdownMenuSubContent.vue | 27 + .../dropdown-menu/DropdownMenuSubTrigger.vue | 31 + .../ui/dropdown-menu/DropdownMenuTrigger.vue | 14 + components/ui/dropdown-menu/index.ts | 16 + components/ui/empty/Empty.vue | 20 + components/ui/empty/EmptyContent.vue | 20 + components/ui/empty/EmptyDescription.vue | 20 + components/ui/empty/EmptyHeader.vue | 20 + components/ui/empty/EmptyMedia.vue | 21 + components/ui/empty/EmptyTitle.vue | 17 + components/ui/empty/index.ts | 26 + components/ui/field/Field.vue | 25 + components/ui/field/FieldContent.vue | 20 + components/ui/field/FieldDescription.vue | 22 + components/ui/field/FieldError.vue | 44 + components/ui/field/FieldGroup.vue | 20 + components/ui/field/FieldLabel.vue | 23 + components/ui/field/FieldLegend.vue | 24 + components/ui/field/FieldSeparator.vue | 29 + components/ui/field/FieldSet.vue | 21 + components/ui/field/FieldTitle.vue | 20 + components/ui/field/index.ts | 39 + components/ui/form/FormControl.vue | 16 + components/ui/form/FormDescription.vue | 20 + components/ui/form/FormItem.vue | 20 + components/ui/form/FormLabel.vue | 23 + components/ui/form/FormMessage.vue | 16 + components/ui/form/index.ts | 7 + components/ui/form/injectionKeys.ts | 4 + components/ui/form/useFormField.ts | 30 + components/ui/hover-card/HoverCard.vue | 15 + components/ui/hover-card/HoverCardContent.vue | 39 + components/ui/hover-card/HoverCardTrigger.vue | 12 + components/ui/hover-card/index.ts | 3 + components/ui/input-group/InputGroup.vue | 32 + components/ui/input-group/InputGroupAddon.vue | 36 + .../ui/input-group/InputGroupButton.vue | 21 + components/ui/input-group/InputGroupInput.vue | 19 + components/ui/input-group/InputGroupText.vue | 19 + .../ui/input-group/InputGroupTextarea.vue | 19 + components/ui/input-group/index.ts | 59 + components/ui/input/Input.vue | 24 + components/ui/input/index.ts | 1 + components/ui/item/Item.vue | 27 + components/ui/item/ItemActions.vue | 17 + components/ui/item/ItemContent.vue | 17 + components/ui/item/ItemDescription.vue | 21 + components/ui/item/ItemFooter.vue | 17 + components/ui/item/ItemGroup.vue | 18 + components/ui/item/ItemHeader.vue | 17 + components/ui/item/ItemMedia.vue | 21 + components/ui/item/ItemSeparator.vue | 18 + components/ui/item/ItemTitle.vue | 17 + components/ui/item/index.ts | 54 + components/ui/kbd/Kbd.vue | 21 + components/ui/kbd/KbdGroup.vue | 17 + components/ui/kbd/index.ts | 2 + components/ui/label/Label.vue | 25 + components/ui/label/index.ts | 1 + components/ui/menubar/Menubar.vue | 32 + components/ui/menubar/MenubarCheckboxItem.vue | 37 + components/ui/menubar/MenubarContent.vue | 41 + components/ui/menubar/MenubarGroup.vue | 12 + components/ui/menubar/MenubarItem.vue | 32 + components/ui/menubar/MenubarLabel.vue | 14 + components/ui/menubar/MenubarMenu.vue | 12 + components/ui/menubar/MenubarRadioGroup.vue | 20 + components/ui/menubar/MenubarRadioItem.vue | 37 + components/ui/menubar/MenubarSeparator.vue | 17 + components/ui/menubar/MenubarShortcut.vue | 14 + components/ui/menubar/MenubarSub.vue | 20 + components/ui/menubar/MenubarSubContent.vue | 36 + components/ui/menubar/MenubarSubTrigger.vue | 28 + components/ui/menubar/MenubarTrigger.vue | 27 + components/ui/menubar/index.ts | 15 + .../ui/navigation-menu/NavigationMenu.vue | 30 + .../navigation-menu/NavigationMenuContent.vue | 31 + .../NavigationMenuIndicator.vue | 22 + .../ui/navigation-menu/NavigationMenuItem.vue | 12 + .../ui/navigation-menu/NavigationMenuLink.vue | 19 + .../ui/navigation-menu/NavigationMenuList.vue | 27 + .../navigation-menu/NavigationMenuTrigger.vue | 32 + .../NavigationMenuViewport.vue | 31 + components/ui/navigation-menu/index.ts | 14 + components/ui/number-field/NumberField.vue | 20 + .../ui/number-field/NumberFieldContent.vue | 14 + .../ui/number-field/NumberFieldDecrement.vue | 22 + .../ui/number-field/NumberFieldIncrement.vue | 22 + .../ui/number-field/NumberFieldInput.vue | 16 + components/ui/number-field/index.ts | 5 + components/ui/pagination/Pagination.vue | 26 + .../ui/pagination/PaginationContent.vue | 22 + .../ui/pagination/PaginationEllipsis.vue | 25 + components/ui/pagination/PaginationFirst.vue | 33 + components/ui/pagination/PaginationItem.vue | 34 + components/ui/pagination/PaginationLast.vue | 33 + components/ui/pagination/PaginationNext.vue | 33 + .../ui/pagination/PaginationPrevious.vue | 33 + components/ui/pagination/index.ts | 8 + components/ui/pin-input/PinInput.vue | 22 + components/ui/pin-input/PinInputGroup.vue | 18 + components/ui/pin-input/PinInputSeparator.vue | 16 + components/ui/pin-input/PinInputSlot.vue | 17 + components/ui/pin-input/index.ts | 4 + components/ui/popover/Popover.vue | 15 + components/ui/popover/PopoverContent.vue | 45 + components/ui/popover/PopoverTrigger.vue | 12 + components/ui/popover/index.ts | 3 + components/ui/progress/Progress.vue | 37 + components/ui/progress/index.ts | 1 + components/ui/radio-group/RadioGroup.vue | 23 + components/ui/radio-group/RadioGroupItem.vue | 37 + components/ui/radio-group/index.ts | 2 + .../ui/range-calendar/RangeCalendar.vue | 58 + .../ui/range-calendar/RangeCalendarCell.vue | 22 + .../RangeCalendarCellTrigger.vue | 38 + .../ui/range-calendar/RangeCalendarGrid.vue | 22 + .../range-calendar/RangeCalendarGridBody.vue | 12 + .../range-calendar/RangeCalendarGridHead.vue | 12 + .../range-calendar/RangeCalendarGridRow.vue | 19 + .../range-calendar/RangeCalendarHeadCell.vue | 19 + .../ui/range-calendar/RangeCalendarHeader.vue | 19 + .../range-calendar/RangeCalendarHeading.vue | 29 + .../RangeCalendarNextButton.vue | 30 + .../RangeCalendarPrevButton.vue | 30 + components/ui/range-calendar/index.ts | 12 + components/ui/resizable/ResizableHandle.vue | 25 + .../ui/resizable/ResizablePanelGroup.vue | 20 + components/ui/resizable/index.ts | 3 + components/ui/scroll-area/ScrollArea.vue | 27 + components/ui/scroll-area/ScrollBar.vue | 28 + components/ui/scroll-area/index.ts | 2 + components/ui/select/Select.vue | 15 + components/ui/select/SelectContent.vue | 50 + components/ui/select/SelectGroup.vue | 17 + components/ui/select/SelectItem.vue | 42 + components/ui/select/SelectItemText.vue | 12 + components/ui/select/SelectLabel.vue | 14 + .../ui/select/SelectScrollDownButton.vue | 22 + components/ui/select/SelectScrollUpButton.vue | 22 + components/ui/select/SelectSeparator.vue | 15 + components/ui/select/SelectTrigger.vue | 29 + components/ui/select/SelectValue.vue | 12 + components/ui/select/index.ts | 11 + components/ui/separator/Separator.vue | 29 + components/ui/separator/index.ts | 1 + components/ui/sheet/Sheet.vue | 15 + components/ui/sheet/SheetClose.vue | 12 + components/ui/sheet/SheetContent.vue | 54 + components/ui/sheet/SheetDescription.vue | 20 + components/ui/sheet/SheetFooter.vue | 19 + components/ui/sheet/SheetHeader.vue | 16 + components/ui/sheet/SheetTitle.vue | 20 + components/ui/sheet/SheetTrigger.vue | 12 + components/ui/sheet/index.ts | 32 + components/ui/sidebar/Sidebar.vue | 85 + components/ui/sidebar/SidebarContent.vue | 17 + components/ui/sidebar/SidebarFooter.vue | 17 + components/ui/sidebar/SidebarGroup.vue | 17 + components/ui/sidebar/SidebarGroupAction.vue | 26 + components/ui/sidebar/SidebarGroupContent.vue | 17 + components/ui/sidebar/SidebarGroupLabel.vue | 24 + components/ui/sidebar/SidebarHeader.vue | 17 + components/ui/sidebar/SidebarInput.vue | 21 + components/ui/sidebar/SidebarInset.vue | 20 + components/ui/sidebar/SidebarMenu.vue | 17 + components/ui/sidebar/SidebarMenuAction.vue | 34 + components/ui/sidebar/SidebarMenuBadge.vue | 25 + components/ui/sidebar/SidebarMenuButton.vue | 48 + .../ui/sidebar/SidebarMenuButtonChild.vue | 35 + components/ui/sidebar/SidebarMenuItem.vue | 17 + components/ui/sidebar/SidebarMenuSkeleton.vue | 34 + components/ui/sidebar/SidebarMenuSub.vue | 21 + .../ui/sidebar/SidebarMenuSubButton.vue | 35 + components/ui/sidebar/SidebarMenuSubItem.vue | 9 + components/ui/sidebar/SidebarProvider.vue | 81 + components/ui/sidebar/SidebarRail.vue | 32 + components/ui/sidebar/SidebarSeparator.vue | 18 + components/ui/sidebar/SidebarTrigger.vue | 26 + components/ui/sidebar/index.ts | 60 + components/ui/sidebar/utils.ts | 19 + components/ui/skeleton/Skeleton.vue | 14 + components/ui/skeleton/index.ts | 1 + components/ui/slider/Slider.vue | 33 + components/ui/slider/index.ts | 1 + components/ui/sonner/Sonner.vue | 23 + components/ui/sonner/index.ts | 1 + components/ui/spinner/Spinner.vue | 17 + components/ui/spinner/index.ts | 1 + components/ui/stepper/Stepper.vue | 27 + components/ui/stepper/StepperDescription.vue | 20 + components/ui/stepper/StepperIndicator.vue | 33 + components/ui/stepper/StepperItem.vue | 23 + components/ui/stepper/StepperSeparator.vue | 28 + components/ui/stepper/StepperTitle.vue | 20 + components/ui/stepper/StepperTrigger.vue | 23 + components/ui/stepper/index.ts | 7 + components/ui/switch/Switch.vue | 36 + components/ui/switch/index.ts | 1 + components/ui/table/Table.vue | 16 + components/ui/table/TableBody.vue | 14 + components/ui/table/TableCaption.vue | 14 + components/ui/table/TableCell.vue | 21 + components/ui/table/TableEmpty.vue | 34 + components/ui/table/TableFooter.vue | 14 + components/ui/table/TableHead.vue | 14 + components/ui/table/TableHeader.vue | 14 + components/ui/table/TableRow.vue | 14 + components/ui/table/index.ts | 9 + components/ui/tabs/Tabs.vue | 15 + components/ui/tabs/TabsContent.vue | 20 + components/ui/tabs/TabsList.vue | 23 + components/ui/tabs/TabsTrigger.vue | 27 + components/ui/tabs/index.ts | 4 + components/ui/tags-input/TagsInput.vue | 20 + components/ui/tags-input/TagsInputInput.vue | 17 + components/ui/tags-input/TagsInputItem.vue | 19 + .../ui/tags-input/TagsInputItemDelete.vue | 22 + .../ui/tags-input/TagsInputItemText.vue | 17 + components/ui/tags-input/index.ts | 5 + components/ui/textarea/Textarea.vue | 24 + components/ui/textarea/index.ts | 1 + components/ui/toggle-group/ToggleGroup.vue | 34 + .../ui/toggle-group/ToggleGroupItem.vue | 36 + components/ui/toggle-group/index.ts | 2 + components/ui/toggle/Toggle.vue | 35 + components/ui/toggle/index.ts | 28 + components/ui/tooltip/Tooltip.vue | 15 + components/ui/tooltip/TooltipContent.vue | 29 + components/ui/tooltip/TooltipProvider.vue | 12 + components/ui/tooltip/TooltipTrigger.vue | 12 + components/ui/tooltip/index.ts | 4 + nuxt.config.ts | 26 +- package-lock.json | 6916 ++++++++++------- package.json | 17 +- plugins/ssr-width.ts | 5 + pnpm-lock.yaml | 1466 +++- 408 files changed, 15735 insertions(+), 2993 deletions(-) create mode 100644 components/ui/accordion/Accordion.vue create mode 100644 components/ui/accordion/AccordionContent.vue create mode 100644 components/ui/accordion/AccordionItem.vue create mode 100644 components/ui/accordion/AccordionTrigger.vue create mode 100644 components/ui/accordion/index.ts create mode 100644 components/ui/alert-dialog/AlertDialog.vue create mode 100644 components/ui/alert-dialog/AlertDialogAction.vue create mode 100644 components/ui/alert-dialog/AlertDialogCancel.vue create mode 100644 components/ui/alert-dialog/AlertDialogContent.vue create mode 100644 components/ui/alert-dialog/AlertDialogDescription.vue create mode 100644 components/ui/alert-dialog/AlertDialogFooter.vue create mode 100644 components/ui/alert-dialog/AlertDialogHeader.vue create mode 100644 components/ui/alert-dialog/AlertDialogTitle.vue create mode 100644 components/ui/alert-dialog/AlertDialogTrigger.vue create mode 100644 components/ui/alert-dialog/index.ts create mode 100644 components/ui/alert/Alert.vue create mode 100644 components/ui/alert/AlertDescription.vue create mode 100644 components/ui/alert/AlertTitle.vue create mode 100644 components/ui/alert/index.ts create mode 100644 components/ui/aspect-ratio/AspectRatio.vue create mode 100644 components/ui/aspect-ratio/index.ts create mode 100644 components/ui/auto-form/AutoForm.vue create mode 100644 components/ui/auto-form/AutoFormField.vue create mode 100644 components/ui/auto-form/AutoFormFieldArray.vue create mode 100644 components/ui/auto-form/AutoFormFieldBoolean.vue create mode 100644 components/ui/auto-form/AutoFormFieldDate.vue create mode 100644 components/ui/auto-form/AutoFormFieldEnum.vue create mode 100644 components/ui/auto-form/AutoFormFieldFile.vue create mode 100644 components/ui/auto-form/AutoFormFieldInput.vue create mode 100644 components/ui/auto-form/AutoFormFieldNumber.vue create mode 100644 components/ui/auto-form/AutoFormFieldObject.vue create mode 100644 components/ui/auto-form/AutoFormLabel.vue create mode 100644 components/ui/auto-form/constant.ts create mode 100644 components/ui/auto-form/dependencies.ts create mode 100644 components/ui/auto-form/index.ts create mode 100644 components/ui/auto-form/interface.ts create mode 100644 components/ui/auto-form/utils.ts create mode 100644 components/ui/avatar/Avatar.vue create mode 100644 components/ui/avatar/AvatarFallback.vue create mode 100644 components/ui/avatar/AvatarImage.vue create mode 100644 components/ui/avatar/index.ts create mode 100644 components/ui/badge/Badge.vue create mode 100644 components/ui/badge/index.ts create mode 100644 components/ui/breadcrumb/Breadcrumb.vue create mode 100644 components/ui/breadcrumb/BreadcrumbEllipsis.vue create mode 100644 components/ui/breadcrumb/BreadcrumbItem.vue create mode 100644 components/ui/breadcrumb/BreadcrumbLink.vue create mode 100644 components/ui/breadcrumb/BreadcrumbList.vue create mode 100644 components/ui/breadcrumb/BreadcrumbPage.vue create mode 100644 components/ui/breadcrumb/BreadcrumbSeparator.vue create mode 100644 components/ui/breadcrumb/index.ts create mode 100644 components/ui/button-group/ButtonGroup.vue create mode 100644 components/ui/button-group/ButtonGroupSeparator.vue create mode 100644 components/ui/button-group/ButtonGroupText.vue create mode 100644 components/ui/button-group/index.ts create mode 100644 components/ui/button/Button.vue create mode 100644 components/ui/button/index.ts create mode 100644 components/ui/calendar/Calendar.vue create mode 100644 components/ui/calendar/CalendarCell.vue create mode 100644 components/ui/calendar/CalendarCellTrigger.vue create mode 100644 components/ui/calendar/CalendarGrid.vue create mode 100644 components/ui/calendar/CalendarGridBody.vue create mode 100644 components/ui/calendar/CalendarGridHead.vue create mode 100644 components/ui/calendar/CalendarGridRow.vue create mode 100644 components/ui/calendar/CalendarHeadCell.vue create mode 100644 components/ui/calendar/CalendarHeader.vue create mode 100644 components/ui/calendar/CalendarHeading.vue create mode 100644 components/ui/calendar/CalendarNextButton.vue create mode 100644 components/ui/calendar/CalendarPrevButton.vue create mode 100644 components/ui/calendar/index.ts create mode 100644 components/ui/card/Card.vue create mode 100644 components/ui/card/CardContent.vue create mode 100644 components/ui/card/CardDescription.vue create mode 100644 components/ui/card/CardFooter.vue create mode 100644 components/ui/card/CardHeader.vue create mode 100644 components/ui/card/CardTitle.vue create mode 100644 components/ui/card/index.ts create mode 100644 components/ui/carousel/Carousel.vue create mode 100644 components/ui/carousel/CarouselContent.vue create mode 100644 components/ui/carousel/CarouselItem.vue create mode 100644 components/ui/carousel/CarouselNext.vue create mode 100644 components/ui/carousel/CarouselPrevious.vue create mode 100644 components/ui/carousel/index.ts create mode 100644 components/ui/carousel/interface.ts create mode 100644 components/ui/carousel/useCarousel.ts create mode 100644 components/ui/chart-area/AreaChart.vue create mode 100644 components/ui/chart-area/index.ts create mode 100644 components/ui/chart-bar/BarChart.vue create mode 100644 components/ui/chart-bar/index.ts create mode 100644 components/ui/chart-donut/DonutChart.vue create mode 100644 components/ui/chart-donut/index.ts create mode 100644 components/ui/chart-line/LineChart.vue create mode 100644 components/ui/chart-line/index.ts create mode 100644 components/ui/chart/ChartCrosshair.vue create mode 100644 components/ui/chart/ChartLegend.vue create mode 100644 components/ui/chart/ChartSingleTooltip.vue create mode 100644 components/ui/chart/ChartTooltip.vue create mode 100644 components/ui/chart/index.ts create mode 100644 components/ui/chart/interface.ts create mode 100644 components/ui/checkbox/Checkbox.vue create mode 100644 components/ui/checkbox/index.ts create mode 100644 components/ui/collapsible/Collapsible.vue create mode 100644 components/ui/collapsible/CollapsibleContent.vue create mode 100644 components/ui/collapsible/CollapsibleTrigger.vue create mode 100644 components/ui/collapsible/index.ts create mode 100644 components/ui/combobox/Combobox.vue create mode 100644 components/ui/combobox/ComboboxAnchor.vue create mode 100644 components/ui/combobox/ComboboxEmpty.vue create mode 100644 components/ui/combobox/ComboboxGroup.vue create mode 100644 components/ui/combobox/ComboboxInput.vue create mode 100644 components/ui/combobox/ComboboxItem.vue create mode 100644 components/ui/combobox/ComboboxList.vue create mode 100644 components/ui/combobox/ComboboxSeparator.vue create mode 100644 components/ui/combobox/ComboboxTrigger.vue create mode 100644 components/ui/combobox/index.ts create mode 100644 components/ui/command/Command.vue create mode 100644 components/ui/command/CommandDialog.vue create mode 100644 components/ui/command/CommandEmpty.vue create mode 100644 components/ui/command/CommandGroup.vue create mode 100644 components/ui/command/CommandInput.vue create mode 100644 components/ui/command/CommandItem.vue create mode 100644 components/ui/command/CommandList.vue create mode 100644 components/ui/command/CommandSeparator.vue create mode 100644 components/ui/command/CommandShortcut.vue create mode 100644 components/ui/command/index.ts create mode 100644 components/ui/context-menu/ContextMenu.vue create mode 100644 components/ui/context-menu/ContextMenuCheckboxItem.vue create mode 100644 components/ui/context-menu/ContextMenuContent.vue create mode 100644 components/ui/context-menu/ContextMenuGroup.vue create mode 100644 components/ui/context-menu/ContextMenuItem.vue create mode 100644 components/ui/context-menu/ContextMenuLabel.vue create mode 100644 components/ui/context-menu/ContextMenuPortal.vue create mode 100644 components/ui/context-menu/ContextMenuRadioGroup.vue create mode 100644 components/ui/context-menu/ContextMenuRadioItem.vue create mode 100644 components/ui/context-menu/ContextMenuSeparator.vue create mode 100644 components/ui/context-menu/ContextMenuShortcut.vue create mode 100644 components/ui/context-menu/ContextMenuSub.vue create mode 100644 components/ui/context-menu/ContextMenuSubContent.vue create mode 100644 components/ui/context-menu/ContextMenuSubTrigger.vue create mode 100644 components/ui/context-menu/ContextMenuTrigger.vue create mode 100644 components/ui/context-menu/index.ts create mode 100644 components/ui/dialog/Dialog.vue create mode 100644 components/ui/dialog/DialogClose.vue create mode 100644 components/ui/dialog/DialogContent.vue create mode 100644 components/ui/dialog/DialogDescription.vue create mode 100644 components/ui/dialog/DialogFooter.vue create mode 100644 components/ui/dialog/DialogHeader.vue create mode 100644 components/ui/dialog/DialogScrollContent.vue create mode 100644 components/ui/dialog/DialogTitle.vue create mode 100644 components/ui/dialog/DialogTrigger.vue create mode 100644 components/ui/dialog/index.ts create mode 100644 components/ui/drawer/Drawer.vue create mode 100644 components/ui/drawer/DrawerContent.vue create mode 100644 components/ui/drawer/DrawerDescription.vue create mode 100644 components/ui/drawer/DrawerFooter.vue create mode 100644 components/ui/drawer/DrawerHeader.vue create mode 100644 components/ui/drawer/DrawerOverlay.vue create mode 100644 components/ui/drawer/DrawerTitle.vue create mode 100644 components/ui/drawer/index.ts create mode 100644 components/ui/dropdown-menu/DropdownMenu.vue create mode 100644 components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue create mode 100644 components/ui/dropdown-menu/DropdownMenuContent.vue create mode 100644 components/ui/dropdown-menu/DropdownMenuGroup.vue create mode 100644 components/ui/dropdown-menu/DropdownMenuItem.vue create mode 100644 components/ui/dropdown-menu/DropdownMenuLabel.vue create mode 100644 components/ui/dropdown-menu/DropdownMenuRadioGroup.vue create mode 100644 components/ui/dropdown-menu/DropdownMenuRadioItem.vue create mode 100644 components/ui/dropdown-menu/DropdownMenuSeparator.vue create mode 100644 components/ui/dropdown-menu/DropdownMenuShortcut.vue create mode 100644 components/ui/dropdown-menu/DropdownMenuSub.vue create mode 100644 components/ui/dropdown-menu/DropdownMenuSubContent.vue create mode 100644 components/ui/dropdown-menu/DropdownMenuSubTrigger.vue create mode 100644 components/ui/dropdown-menu/DropdownMenuTrigger.vue create mode 100644 components/ui/dropdown-menu/index.ts create mode 100644 components/ui/empty/Empty.vue create mode 100644 components/ui/empty/EmptyContent.vue create mode 100644 components/ui/empty/EmptyDescription.vue create mode 100644 components/ui/empty/EmptyHeader.vue create mode 100644 components/ui/empty/EmptyMedia.vue create mode 100644 components/ui/empty/EmptyTitle.vue create mode 100644 components/ui/empty/index.ts create mode 100644 components/ui/field/Field.vue create mode 100644 components/ui/field/FieldContent.vue create mode 100644 components/ui/field/FieldDescription.vue create mode 100644 components/ui/field/FieldError.vue create mode 100644 components/ui/field/FieldGroup.vue create mode 100644 components/ui/field/FieldLabel.vue create mode 100644 components/ui/field/FieldLegend.vue create mode 100644 components/ui/field/FieldSeparator.vue create mode 100644 components/ui/field/FieldSet.vue create mode 100644 components/ui/field/FieldTitle.vue create mode 100644 components/ui/field/index.ts create mode 100644 components/ui/form/FormControl.vue create mode 100644 components/ui/form/FormDescription.vue create mode 100644 components/ui/form/FormItem.vue create mode 100644 components/ui/form/FormLabel.vue create mode 100644 components/ui/form/FormMessage.vue create mode 100644 components/ui/form/index.ts create mode 100644 components/ui/form/injectionKeys.ts create mode 100644 components/ui/form/useFormField.ts create mode 100644 components/ui/hover-card/HoverCard.vue create mode 100644 components/ui/hover-card/HoverCardContent.vue create mode 100644 components/ui/hover-card/HoverCardTrigger.vue create mode 100644 components/ui/hover-card/index.ts create mode 100644 components/ui/input-group/InputGroup.vue create mode 100644 components/ui/input-group/InputGroupAddon.vue create mode 100644 components/ui/input-group/InputGroupButton.vue create mode 100644 components/ui/input-group/InputGroupInput.vue create mode 100644 components/ui/input-group/InputGroupText.vue create mode 100644 components/ui/input-group/InputGroupTextarea.vue create mode 100644 components/ui/input-group/index.ts create mode 100644 components/ui/input/Input.vue create mode 100644 components/ui/input/index.ts create mode 100644 components/ui/item/Item.vue create mode 100644 components/ui/item/ItemActions.vue create mode 100644 components/ui/item/ItemContent.vue create mode 100644 components/ui/item/ItemDescription.vue create mode 100644 components/ui/item/ItemFooter.vue create mode 100644 components/ui/item/ItemGroup.vue create mode 100644 components/ui/item/ItemHeader.vue create mode 100644 components/ui/item/ItemMedia.vue create mode 100644 components/ui/item/ItemSeparator.vue create mode 100644 components/ui/item/ItemTitle.vue create mode 100644 components/ui/item/index.ts create mode 100644 components/ui/kbd/Kbd.vue create mode 100644 components/ui/kbd/KbdGroup.vue create mode 100644 components/ui/kbd/index.ts create mode 100644 components/ui/label/Label.vue create mode 100644 components/ui/label/index.ts create mode 100644 components/ui/menubar/Menubar.vue create mode 100644 components/ui/menubar/MenubarCheckboxItem.vue create mode 100644 components/ui/menubar/MenubarContent.vue create mode 100644 components/ui/menubar/MenubarGroup.vue create mode 100644 components/ui/menubar/MenubarItem.vue create mode 100644 components/ui/menubar/MenubarLabel.vue create mode 100644 components/ui/menubar/MenubarMenu.vue create mode 100644 components/ui/menubar/MenubarRadioGroup.vue create mode 100644 components/ui/menubar/MenubarRadioItem.vue create mode 100644 components/ui/menubar/MenubarSeparator.vue create mode 100644 components/ui/menubar/MenubarShortcut.vue create mode 100644 components/ui/menubar/MenubarSub.vue create mode 100644 components/ui/menubar/MenubarSubContent.vue create mode 100644 components/ui/menubar/MenubarSubTrigger.vue create mode 100644 components/ui/menubar/MenubarTrigger.vue create mode 100644 components/ui/menubar/index.ts create mode 100644 components/ui/navigation-menu/NavigationMenu.vue create mode 100644 components/ui/navigation-menu/NavigationMenuContent.vue create mode 100644 components/ui/navigation-menu/NavigationMenuIndicator.vue create mode 100644 components/ui/navigation-menu/NavigationMenuItem.vue create mode 100644 components/ui/navigation-menu/NavigationMenuLink.vue create mode 100644 components/ui/navigation-menu/NavigationMenuList.vue create mode 100644 components/ui/navigation-menu/NavigationMenuTrigger.vue create mode 100644 components/ui/navigation-menu/NavigationMenuViewport.vue create mode 100644 components/ui/navigation-menu/index.ts create mode 100644 components/ui/number-field/NumberField.vue create mode 100644 components/ui/number-field/NumberFieldContent.vue create mode 100644 components/ui/number-field/NumberFieldDecrement.vue create mode 100644 components/ui/number-field/NumberFieldIncrement.vue create mode 100644 components/ui/number-field/NumberFieldInput.vue create mode 100644 components/ui/number-field/index.ts create mode 100644 components/ui/pagination/Pagination.vue create mode 100644 components/ui/pagination/PaginationContent.vue create mode 100644 components/ui/pagination/PaginationEllipsis.vue create mode 100644 components/ui/pagination/PaginationFirst.vue create mode 100644 components/ui/pagination/PaginationItem.vue create mode 100644 components/ui/pagination/PaginationLast.vue create mode 100644 components/ui/pagination/PaginationNext.vue create mode 100644 components/ui/pagination/PaginationPrevious.vue create mode 100644 components/ui/pagination/index.ts create mode 100644 components/ui/pin-input/PinInput.vue create mode 100644 components/ui/pin-input/PinInputGroup.vue create mode 100644 components/ui/pin-input/PinInputSeparator.vue create mode 100644 components/ui/pin-input/PinInputSlot.vue create mode 100644 components/ui/pin-input/index.ts create mode 100644 components/ui/popover/Popover.vue create mode 100644 components/ui/popover/PopoverContent.vue create mode 100644 components/ui/popover/PopoverTrigger.vue create mode 100644 components/ui/popover/index.ts create mode 100644 components/ui/progress/Progress.vue create mode 100644 components/ui/progress/index.ts create mode 100644 components/ui/radio-group/RadioGroup.vue create mode 100644 components/ui/radio-group/RadioGroupItem.vue create mode 100644 components/ui/radio-group/index.ts create mode 100644 components/ui/range-calendar/RangeCalendar.vue create mode 100644 components/ui/range-calendar/RangeCalendarCell.vue create mode 100644 components/ui/range-calendar/RangeCalendarCellTrigger.vue create mode 100644 components/ui/range-calendar/RangeCalendarGrid.vue create mode 100644 components/ui/range-calendar/RangeCalendarGridBody.vue create mode 100644 components/ui/range-calendar/RangeCalendarGridHead.vue create mode 100644 components/ui/range-calendar/RangeCalendarGridRow.vue create mode 100644 components/ui/range-calendar/RangeCalendarHeadCell.vue create mode 100644 components/ui/range-calendar/RangeCalendarHeader.vue create mode 100644 components/ui/range-calendar/RangeCalendarHeading.vue create mode 100644 components/ui/range-calendar/RangeCalendarNextButton.vue create mode 100644 components/ui/range-calendar/RangeCalendarPrevButton.vue create mode 100644 components/ui/range-calendar/index.ts create mode 100644 components/ui/resizable/ResizableHandle.vue create mode 100644 components/ui/resizable/ResizablePanelGroup.vue create mode 100644 components/ui/resizable/index.ts create mode 100644 components/ui/scroll-area/ScrollArea.vue create mode 100644 components/ui/scroll-area/ScrollBar.vue create mode 100644 components/ui/scroll-area/index.ts create mode 100644 components/ui/select/Select.vue create mode 100644 components/ui/select/SelectContent.vue create mode 100644 components/ui/select/SelectGroup.vue create mode 100644 components/ui/select/SelectItem.vue create mode 100644 components/ui/select/SelectItemText.vue create mode 100644 components/ui/select/SelectLabel.vue create mode 100644 components/ui/select/SelectScrollDownButton.vue create mode 100644 components/ui/select/SelectScrollUpButton.vue create mode 100644 components/ui/select/SelectSeparator.vue create mode 100644 components/ui/select/SelectTrigger.vue create mode 100644 components/ui/select/SelectValue.vue create mode 100644 components/ui/select/index.ts create mode 100644 components/ui/separator/Separator.vue create mode 100644 components/ui/separator/index.ts create mode 100644 components/ui/sheet/Sheet.vue create mode 100644 components/ui/sheet/SheetClose.vue create mode 100644 components/ui/sheet/SheetContent.vue create mode 100644 components/ui/sheet/SheetDescription.vue create mode 100644 components/ui/sheet/SheetFooter.vue create mode 100644 components/ui/sheet/SheetHeader.vue create mode 100644 components/ui/sheet/SheetTitle.vue create mode 100644 components/ui/sheet/SheetTrigger.vue create mode 100644 components/ui/sheet/index.ts create mode 100644 components/ui/sidebar/Sidebar.vue create mode 100644 components/ui/sidebar/SidebarContent.vue create mode 100644 components/ui/sidebar/SidebarFooter.vue create mode 100644 components/ui/sidebar/SidebarGroup.vue create mode 100644 components/ui/sidebar/SidebarGroupAction.vue create mode 100644 components/ui/sidebar/SidebarGroupContent.vue create mode 100644 components/ui/sidebar/SidebarGroupLabel.vue create mode 100644 components/ui/sidebar/SidebarHeader.vue create mode 100644 components/ui/sidebar/SidebarInput.vue create mode 100644 components/ui/sidebar/SidebarInset.vue create mode 100644 components/ui/sidebar/SidebarMenu.vue create mode 100644 components/ui/sidebar/SidebarMenuAction.vue create mode 100644 components/ui/sidebar/SidebarMenuBadge.vue create mode 100644 components/ui/sidebar/SidebarMenuButton.vue create mode 100644 components/ui/sidebar/SidebarMenuButtonChild.vue create mode 100644 components/ui/sidebar/SidebarMenuItem.vue create mode 100644 components/ui/sidebar/SidebarMenuSkeleton.vue create mode 100644 components/ui/sidebar/SidebarMenuSub.vue create mode 100644 components/ui/sidebar/SidebarMenuSubButton.vue create mode 100644 components/ui/sidebar/SidebarMenuSubItem.vue create mode 100644 components/ui/sidebar/SidebarProvider.vue create mode 100644 components/ui/sidebar/SidebarRail.vue create mode 100644 components/ui/sidebar/SidebarSeparator.vue create mode 100644 components/ui/sidebar/SidebarTrigger.vue create mode 100644 components/ui/sidebar/index.ts create mode 100644 components/ui/sidebar/utils.ts create mode 100644 components/ui/skeleton/Skeleton.vue create mode 100644 components/ui/skeleton/index.ts create mode 100644 components/ui/slider/Slider.vue create mode 100644 components/ui/slider/index.ts create mode 100644 components/ui/sonner/Sonner.vue create mode 100644 components/ui/sonner/index.ts create mode 100644 components/ui/spinner/Spinner.vue create mode 100644 components/ui/spinner/index.ts create mode 100644 components/ui/stepper/Stepper.vue create mode 100644 components/ui/stepper/StepperDescription.vue create mode 100644 components/ui/stepper/StepperIndicator.vue create mode 100644 components/ui/stepper/StepperItem.vue create mode 100644 components/ui/stepper/StepperSeparator.vue create mode 100644 components/ui/stepper/StepperTitle.vue create mode 100644 components/ui/stepper/StepperTrigger.vue create mode 100644 components/ui/stepper/index.ts create mode 100644 components/ui/switch/Switch.vue create mode 100644 components/ui/switch/index.ts create mode 100644 components/ui/table/Table.vue create mode 100644 components/ui/table/TableBody.vue create mode 100644 components/ui/table/TableCaption.vue create mode 100644 components/ui/table/TableCell.vue create mode 100644 components/ui/table/TableEmpty.vue create mode 100644 components/ui/table/TableFooter.vue create mode 100644 components/ui/table/TableHead.vue create mode 100644 components/ui/table/TableHeader.vue create mode 100644 components/ui/table/TableRow.vue create mode 100644 components/ui/table/index.ts create mode 100644 components/ui/tabs/Tabs.vue create mode 100644 components/ui/tabs/TabsContent.vue create mode 100644 components/ui/tabs/TabsList.vue create mode 100644 components/ui/tabs/TabsTrigger.vue create mode 100644 components/ui/tabs/index.ts create mode 100644 components/ui/tags-input/TagsInput.vue create mode 100644 components/ui/tags-input/TagsInputInput.vue create mode 100644 components/ui/tags-input/TagsInputItem.vue create mode 100644 components/ui/tags-input/TagsInputItemDelete.vue create mode 100644 components/ui/tags-input/TagsInputItemText.vue create mode 100644 components/ui/tags-input/index.ts create mode 100644 components/ui/textarea/Textarea.vue create mode 100644 components/ui/textarea/index.ts create mode 100644 components/ui/toggle-group/ToggleGroup.vue create mode 100644 components/ui/toggle-group/ToggleGroupItem.vue create mode 100644 components/ui/toggle-group/index.ts create mode 100644 components/ui/toggle/Toggle.vue create mode 100644 components/ui/toggle/index.ts create mode 100644 components/ui/tooltip/Tooltip.vue create mode 100644 components/ui/tooltip/TooltipContent.vue create mode 100644 components/ui/tooltip/TooltipProvider.vue create mode 100644 components/ui/tooltip/TooltipTrigger.vue create mode 100644 components/ui/tooltip/index.ts create mode 100644 plugins/ssr-width.ts diff --git a/assets/css/tailwind.css b/assets/css/tailwind.css index e7fe9b0..a2be5be 100644 --- a/assets/css/tailwind.css +++ b/assets/css/tailwind.css @@ -1,5 +1,7 @@ @import 'tailwindcss'; +@custom-variant dark (&:is(.dark *)); + @layer base { :root { --background: 0 0% 100%; @@ -56,3 +58,65 @@ --chart-5: 340 75% 55%; } } + +:root { + --sidebar: hsl(0 0% 98%); + --sidebar-foreground: hsl(240 5.3% 26.1%); + --sidebar-primary: hsl(240 5.9% 10%); + --sidebar-primary-foreground: hsl(0 0% 98%); + --sidebar-accent: hsl(240 4.8% 95.9%); + --sidebar-accent-foreground: hsl(240 5.9% 10%); + --sidebar-border: hsl(220 13% 91%); + --sidebar-ring: hsl(217.2 91.2% 59.8%); +} + +.dark { + --sidebar: hsl(240 5.9% 10%); + --sidebar-foreground: hsl(240 4.8% 95.9%); + --sidebar-primary: hsl(224.3 76.3% 48%); + --sidebar-primary-foreground: hsl(0 0% 100%); + --sidebar-accent: hsl(240 3.7% 15.9%); + --sidebar-accent-foreground: hsl(240 4.8% 95.9%); + --sidebar-border: hsl(240 3.7% 15.9%); + --sidebar-ring: hsl(217.2 91.2% 59.8%); +} + +@theme inline { + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); + --animate-accordion-down: accordion-down 0.2s ease-out; + --animate-accordion-up: accordion-up 0.2s ease-out; + + @keyframes accordion-down { + from { + height: 0; + } + to { + height: var(--reka-accordion-content-height); + } + } + + @keyframes accordion-up { + from { + height: var(--reka-accordion-content-height); + } + to { + height: 0; + } + } +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/components/ui/accordion/Accordion.vue b/components/ui/accordion/Accordion.vue new file mode 100644 index 0000000..2a4a846 --- /dev/null +++ b/components/ui/accordion/Accordion.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/accordion/AccordionContent.vue b/components/ui/accordion/AccordionContent.vue new file mode 100644 index 0000000..fccb734 --- /dev/null +++ b/components/ui/accordion/AccordionContent.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/accordion/AccordionItem.vue b/components/ui/accordion/AccordionItem.vue new file mode 100644 index 0000000..0866cf1 --- /dev/null +++ b/components/ui/accordion/AccordionItem.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/accordion/AccordionTrigger.vue b/components/ui/accordion/AccordionTrigger.vue new file mode 100644 index 0000000..4575875 --- /dev/null +++ b/components/ui/accordion/AccordionTrigger.vue @@ -0,0 +1,37 @@ + + + diff --git a/components/ui/accordion/index.ts b/components/ui/accordion/index.ts new file mode 100644 index 0000000..b18018b --- /dev/null +++ b/components/ui/accordion/index.ts @@ -0,0 +1,4 @@ +export { default as Accordion } from "./Accordion.vue" +export { default as AccordionContent } from "./AccordionContent.vue" +export { default as AccordionItem } from "./AccordionItem.vue" +export { default as AccordionTrigger } from "./AccordionTrigger.vue" diff --git a/components/ui/alert-dialog/AlertDialog.vue b/components/ui/alert-dialog/AlertDialog.vue new file mode 100644 index 0000000..ff9accb --- /dev/null +++ b/components/ui/alert-dialog/AlertDialog.vue @@ -0,0 +1,15 @@ + + + diff --git a/components/ui/alert-dialog/AlertDialogAction.vue b/components/ui/alert-dialog/AlertDialogAction.vue new file mode 100644 index 0000000..09cf6fc --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogAction.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/ui/alert-dialog/AlertDialogCancel.vue b/components/ui/alert-dialog/AlertDialogCancel.vue new file mode 100644 index 0000000..e261894 --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogCancel.vue @@ -0,0 +1,25 @@ + + + diff --git a/components/ui/alert-dialog/AlertDialogContent.vue b/components/ui/alert-dialog/AlertDialogContent.vue new file mode 100644 index 0000000..73e4fcb --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogContent.vue @@ -0,0 +1,39 @@ + + + diff --git a/components/ui/alert-dialog/AlertDialogDescription.vue b/components/ui/alert-dialog/AlertDialogDescription.vue new file mode 100644 index 0000000..b6d165e --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogDescription.vue @@ -0,0 +1,23 @@ + + + diff --git a/components/ui/alert-dialog/AlertDialogFooter.vue b/components/ui/alert-dialog/AlertDialogFooter.vue new file mode 100644 index 0000000..c764e73 --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogFooter.vue @@ -0,0 +1,21 @@ + + + diff --git a/components/ui/alert-dialog/AlertDialogHeader.vue b/components/ui/alert-dialog/AlertDialogHeader.vue new file mode 100644 index 0000000..b5e5540 --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogHeader.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/alert-dialog/AlertDialogTitle.vue b/components/ui/alert-dialog/AlertDialogTitle.vue new file mode 100644 index 0000000..b829392 --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogTitle.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/alert-dialog/AlertDialogTrigger.vue b/components/ui/alert-dialog/AlertDialogTrigger.vue new file mode 100644 index 0000000..f104dcc --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogTrigger.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/ui/alert-dialog/index.ts b/components/ui/alert-dialog/index.ts new file mode 100644 index 0000000..cf1b45d --- /dev/null +++ b/components/ui/alert-dialog/index.ts @@ -0,0 +1,9 @@ +export { default as AlertDialog } from "./AlertDialog.vue" +export { default as AlertDialogAction } from "./AlertDialogAction.vue" +export { default as AlertDialogCancel } from "./AlertDialogCancel.vue" +export { default as AlertDialogContent } from "./AlertDialogContent.vue" +export { default as AlertDialogDescription } from "./AlertDialogDescription.vue" +export { default as AlertDialogFooter } from "./AlertDialogFooter.vue" +export { default as AlertDialogHeader } from "./AlertDialogHeader.vue" +export { default as AlertDialogTitle } from "./AlertDialogTitle.vue" +export { default as AlertDialogTrigger } from "./AlertDialogTrigger.vue" diff --git a/components/ui/alert/Alert.vue b/components/ui/alert/Alert.vue new file mode 100644 index 0000000..9feea31 --- /dev/null +++ b/components/ui/alert/Alert.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/alert/AlertDescription.vue b/components/ui/alert/AlertDescription.vue new file mode 100644 index 0000000..afeaa01 --- /dev/null +++ b/components/ui/alert/AlertDescription.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/alert/AlertTitle.vue b/components/ui/alert/AlertTitle.vue new file mode 100644 index 0000000..1f98d11 --- /dev/null +++ b/components/ui/alert/AlertTitle.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/alert/index.ts b/components/ui/alert/index.ts new file mode 100644 index 0000000..1106fd0 --- /dev/null +++ b/components/ui/alert/index.ts @@ -0,0 +1,24 @@ +import type { VariantProps } from "class-variance-authority" +import { cva } from "class-variance-authority" + +export { default as Alert } from "./Alert.vue" +export { default as AlertDescription } from "./AlertDescription.vue" +export { default as AlertTitle } from "./AlertTitle.vue" + +export const alertVariants = cva( + "relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground", + { + variants: { + variant: { + default: "bg-background text-foreground", + destructive: + "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +) + +export type AlertVariants = VariantProps diff --git a/components/ui/aspect-ratio/AspectRatio.vue b/components/ui/aspect-ratio/AspectRatio.vue new file mode 100644 index 0000000..e8f239a --- /dev/null +++ b/components/ui/aspect-ratio/AspectRatio.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/ui/aspect-ratio/index.ts b/components/ui/aspect-ratio/index.ts new file mode 100644 index 0000000..e658f55 --- /dev/null +++ b/components/ui/aspect-ratio/index.ts @@ -0,0 +1 @@ +export { default as AspectRatio } from "./AspectRatio.vue" diff --git a/components/ui/auto-form/AutoForm.vue b/components/ui/auto-form/AutoForm.vue new file mode 100644 index 0000000..2e88654 --- /dev/null +++ b/components/ui/auto-form/AutoForm.vue @@ -0,0 +1,106 @@ + + + diff --git a/components/ui/auto-form/AutoFormField.vue b/components/ui/auto-form/AutoFormField.vue new file mode 100644 index 0000000..0f1585c --- /dev/null +++ b/components/ui/auto-form/AutoFormField.vue @@ -0,0 +1,45 @@ + + + diff --git a/components/ui/auto-form/AutoFormFieldArray.vue b/components/ui/auto-form/AutoFormFieldArray.vue new file mode 100644 index 0000000..6d30d91 --- /dev/null +++ b/components/ui/auto-form/AutoFormFieldArray.vue @@ -0,0 +1,110 @@ + + + diff --git a/components/ui/auto-form/AutoFormFieldBoolean.vue b/components/ui/auto-form/AutoFormFieldBoolean.vue new file mode 100644 index 0000000..6770e67 --- /dev/null +++ b/components/ui/auto-form/AutoFormFieldBoolean.vue @@ -0,0 +1,41 @@ + + + diff --git a/components/ui/auto-form/AutoFormFieldDate.vue b/components/ui/auto-form/AutoFormFieldDate.vue new file mode 100644 index 0000000..2b1c694 --- /dev/null +++ b/components/ui/auto-form/AutoFormFieldDate.vue @@ -0,0 +1,57 @@ + + + diff --git a/components/ui/auto-form/AutoFormFieldEnum.vue b/components/ui/auto-form/AutoFormFieldEnum.vue new file mode 100644 index 0000000..6ec974a --- /dev/null +++ b/components/ui/auto-form/AutoFormFieldEnum.vue @@ -0,0 +1,49 @@ + + + diff --git a/components/ui/auto-form/AutoFormFieldFile.vue b/components/ui/auto-form/AutoFormFieldFile.vue new file mode 100644 index 0000000..8a80b1e --- /dev/null +++ b/components/ui/auto-form/AutoFormFieldFile.vue @@ -0,0 +1,74 @@ + + + diff --git a/components/ui/auto-form/AutoFormFieldInput.vue b/components/ui/auto-form/AutoFormFieldInput.vue new file mode 100644 index 0000000..8bfc274 --- /dev/null +++ b/components/ui/auto-form/AutoFormFieldInput.vue @@ -0,0 +1,36 @@ + + + diff --git a/components/ui/auto-form/AutoFormFieldNumber.vue b/components/ui/auto-form/AutoFormFieldNumber.vue new file mode 100644 index 0000000..4d18aa8 --- /dev/null +++ b/components/ui/auto-form/AutoFormFieldNumber.vue @@ -0,0 +1,32 @@ + + + diff --git a/components/ui/auto-form/AutoFormFieldObject.vue b/components/ui/auto-form/AutoFormFieldObject.vue new file mode 100644 index 0000000..2d54a18 --- /dev/null +++ b/components/ui/auto-form/AutoFormFieldObject.vue @@ -0,0 +1,78 @@ + + + diff --git a/components/ui/auto-form/AutoFormLabel.vue b/components/ui/auto-form/AutoFormLabel.vue new file mode 100644 index 0000000..121b5c0 --- /dev/null +++ b/components/ui/auto-form/AutoFormLabel.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/auto-form/constant.ts b/components/ui/auto-form/constant.ts new file mode 100644 index 0000000..c31b773 --- /dev/null +++ b/components/ui/auto-form/constant.ts @@ -0,0 +1,40 @@ +import type { InputComponents } from "./interface" +import AutoFormFieldArray from "./AutoFormFieldArray.vue" +import AutoFormFieldBoolean from "./AutoFormFieldBoolean.vue" +import AutoFormFieldDate from "./AutoFormFieldDate.vue" +import AutoFormFieldEnum from "./AutoFormFieldEnum.vue" +import AutoFormFieldFile from "./AutoFormFieldFile.vue" +import AutoFormFieldInput from "./AutoFormFieldInput.vue" +import AutoFormFieldNumber from "./AutoFormFieldNumber.vue" +import AutoFormFieldObject from "./AutoFormFieldObject.vue" + +export const INPUT_COMPONENTS: InputComponents = { + date: AutoFormFieldDate, + select: AutoFormFieldEnum, + radio: AutoFormFieldEnum, + checkbox: AutoFormFieldBoolean, + switch: AutoFormFieldBoolean, + textarea: AutoFormFieldInput, + number: AutoFormFieldNumber, + string: AutoFormFieldInput, + file: AutoFormFieldFile, + array: AutoFormFieldArray, + object: AutoFormFieldObject, +} + +/** + * Define handlers for specific Zod types. + * You can expand this object to support more types. + */ +export const DEFAULT_ZOD_HANDLERS: { + [key: string]: keyof typeof INPUT_COMPONENTS +} = { + ZodString: "string", + ZodBoolean: "checkbox", + ZodDate: "date", + ZodEnum: "select", + ZodNativeEnum: "select", + ZodNumber: "number", + ZodArray: "array", + ZodObject: "object", +} diff --git a/components/ui/auto-form/dependencies.ts b/components/ui/auto-form/dependencies.ts new file mode 100644 index 0000000..24a1336 --- /dev/null +++ b/components/ui/auto-form/dependencies.ts @@ -0,0 +1,93 @@ +import type { Ref } from "vue" +import type * as z from "zod" +import type { Dependency, EnumValues } from "./interface" +import { createContext } from "reka-ui" +import { useFieldValue, useFormValues } from "vee-validate" +import { computed, ref, watch } from "vue" +import { DependencyType } from "./interface" +import { getFromPath, getIndexIfArray } from "./utils" + +export const [injectDependencies, provideDependencies] = createContext>>[] | undefined>>("AutoFormDependencies") + +export default function useDependencies( + fieldName: string, +) { + const form = useFormValues() + // parsed test[0].age => test.age + const currentFieldName = fieldName.replace(/\[\d+\]/g, "") + const currentFieldValue = useFieldValue(fieldName) + + if (!form) + throw new Error("useDependencies should be used within ") + + const dependencies = injectDependencies() + const isDisabled = ref(false) + const isHidden = ref(false) + const isRequired = ref(false) + const overrideOptions = ref() + + const currentFieldDependencies = computed(() => dependencies.value?.filter( + dependency => dependency.targetField === currentFieldName, + )) + + function getSourceValue(dep: Dependency) { + const source = dep.sourceField as string + const index = getIndexIfArray(fieldName) ?? -1 + const [sourceLast, ...sourceInitial] = source.split(".").toReversed() + const [_targetLast, ...targetInitial] = (dep.targetField as string).split(".").toReversed() + + if (index >= 0 && sourceInitial.join(",") === targetInitial.join(",")) { + const [_currentLast, ...currentInitial] = fieldName.split(".").toReversed() + return getFromPath(form.value, currentInitial.join(".") + sourceLast) + } + + return getFromPath(form.value, source) + } + + const sourceFieldValues = computed(() => currentFieldDependencies.value?.map(dep => getSourceValue(dep))) + + const resetConditionState = () => { + isDisabled.value = false + isHidden.value = false + isRequired.value = false + overrideOptions.value = undefined + } + + watch([sourceFieldValues, dependencies], () => { + resetConditionState() + currentFieldDependencies.value?.forEach((dep) => { + const sourceValue = getSourceValue(dep) + const conditionMet = dep.when(sourceValue, currentFieldValue.value) + + switch (dep.type) { + case DependencyType.DISABLES: + if (conditionMet) + isDisabled.value = true + + break + case DependencyType.REQUIRES: + if (conditionMet) + isRequired.value = true + + break + case DependencyType.HIDES: + if (conditionMet) + isHidden.value = true + + break + case DependencyType.SETS_OPTIONS: + if (conditionMet) + overrideOptions.value = dep.options + + break + } + }) + }, { immediate: true, deep: true }) + + return { + isDisabled, + isHidden, + isRequired, + overrideOptions, + } +} diff --git a/components/ui/auto-form/index.ts b/components/ui/auto-form/index.ts new file mode 100644 index 0000000..79f8b98 --- /dev/null +++ b/components/ui/auto-form/index.ts @@ -0,0 +1,15 @@ +export { default as AutoForm } from "./AutoForm.vue" +export { default as AutoFormField } from "./AutoFormField.vue" + +export { default as AutoFormFieldArray } from "./AutoFormFieldArray.vue" +export { default as AutoFormFieldBoolean } from "./AutoFormFieldBoolean.vue" +export { default as AutoFormFieldDate } from "./AutoFormFieldDate.vue" + +export { default as AutoFormFieldEnum } from "./AutoFormFieldEnum.vue" +export { default as AutoFormFieldFile } from "./AutoFormFieldFile.vue" +export { default as AutoFormFieldInput } from "./AutoFormFieldInput.vue" +export { default as AutoFormFieldNumber } from "./AutoFormFieldNumber.vue" +export { default as AutoFormFieldObject } from "./AutoFormFieldObject.vue" +export { default as AutoFormLabel } from "./AutoFormLabel.vue" +export type { Config, ConfigItem, FieldProps } from "./interface" +export { getBaseSchema, getBaseType, getObjectFormSchema } from "./utils" diff --git a/components/ui/auto-form/interface.ts b/components/ui/auto-form/interface.ts new file mode 100644 index 0000000..96ddc4e --- /dev/null +++ b/components/ui/auto-form/interface.ts @@ -0,0 +1,95 @@ +import type { Component, InputHTMLAttributes } from "vue" +import type { z, ZodAny } from "zod" +import type { INPUT_COMPONENTS } from "./constant" + +export interface FieldProps { + fieldName: string + label?: string + required?: boolean + config?: ConfigItem + disabled?: boolean +} + +export interface Shape { + type: string + default?: any + required?: boolean + options?: string[] + schema?: ZodAny +} + +export interface InputComponents { + date: Component + select: Component + radio: Component + checkbox: Component + switch: Component + textarea: Component + number: Component + string: Component + file: Component + array: Component + object: Component +} + +export interface ConfigItem { + /** Value for the `FormLabel` */ + label?: string + /** Value for the `FormDescription` */ + description?: string + /** Pick which component to be rendered. */ + component?: keyof typeof INPUT_COMPONENTS | Component + /** Hide `FormLabel`. */ + hideLabel?: boolean + inputProps?: InputHTMLAttributes +} + +// Define a type to unwrap an array +type UnwrapArray = T extends (infer U)[] ? U : never + +export type Config = { + // If SchemaType.key is an object, create a nested Config, otherwise ConfigItem + [Key in keyof SchemaType]?: + SchemaType[Key] extends any[] + ? UnwrapArray> + : SchemaType[Key] extends object + ? Config + : ConfigItem; +} + +export enum DependencyType { + DISABLES, + REQUIRES, + HIDES, + SETS_OPTIONS, +} + +interface BaseDependency>> { + sourceField: keyof SchemaType + type: DependencyType + targetField: keyof SchemaType + when: (sourceFieldValue: any, targetFieldValue: any) => boolean +} + +export type ValueDependency>> + = BaseDependency & { + type: + | DependencyType.DISABLES + | DependencyType.REQUIRES + | DependencyType.HIDES + } + +export type EnumValues = readonly [string, ...string[]] + +export type OptionsDependency< + SchemaType extends z.infer>, +> = BaseDependency & { + type: DependencyType.SETS_OPTIONS + + // Partial array of values from sourceField that will trigger the dependency + options: EnumValues +} + +export type Dependency>> + = | ValueDependency + | OptionsDependency diff --git a/components/ui/auto-form/utils.ts b/components/ui/auto-form/utils.ts new file mode 100644 index 0000000..6702865 --- /dev/null +++ b/components/ui/auto-form/utils.ts @@ -0,0 +1,188 @@ +import type { z } from "zod" + +// TODO: This should support recursive ZodEffects but TypeScript doesn't allow circular type definitions. +export type ZodObjectOrWrapped + = | z.ZodObject + | z.ZodEffects> + +/** + * Beautify a camelCase string. + * e.g. "myString" -> "My String" + */ +export function beautifyObjectName(string: string) { + // Remove bracketed indices + // if numbers only return the string + let output = string.replace(/\[\d+\]/g, "").replace(/([A-Z])/g, " $1") + output = output.charAt(0).toUpperCase() + output.slice(1) + return output +} + +/** + * Parse string and extract the index + * @param string + * @returns index or undefined + */ +export function getIndexIfArray(string: string) { + const indexRegex = /\[(\d+)\]/ + // Match the index + const match = string.match(indexRegex) + // Extract the index (number) + const index = match ? Number.parseInt(match[1]) : undefined + return index +} + +/** + * Get the lowest level Zod type. + * This will unpack optionals, refinements, etc. + */ +export function getBaseSchema< + ChildType extends z.ZodAny | z.AnyZodObject = z.ZodAny, +>(schema: ChildType | z.ZodEffects): ChildType | null { + if (!schema) + return null + if ("innerType" in schema._def) + return getBaseSchema(schema._def.innerType as ChildType) + + if ("schema" in schema._def) + return getBaseSchema(schema._def.schema as ChildType) + + return schema as ChildType +} + +/** + * Get the type name of the lowest level Zod type. + * This will unpack optionals, refinements, etc. + */ +export function getBaseType(schema: z.ZodAny) { + const baseSchema = getBaseSchema(schema) + return baseSchema ? baseSchema._def.typeName : "" +} + +/** + * Search for a "ZodDefault" in the Zod stack and return its value. + */ +export function getDefaultValueInZodStack(schema: z.ZodAny): any { + const typedSchema = schema as unknown as z.ZodDefault< + z.ZodNumber | z.ZodString + > + + if (typedSchema._def.typeName === "ZodDefault") + return typedSchema._def.defaultValue() + + if ("innerType" in typedSchema._def) { + return getDefaultValueInZodStack( + typedSchema._def.innerType as unknown as z.ZodAny, + ) + } + if ("schema" in typedSchema._def) { + return getDefaultValueInZodStack( + (typedSchema._def as any).schema as z.ZodAny, + ) + } + + return undefined +} + +export function getObjectFormSchema( + schema: ZodObjectOrWrapped, +): z.ZodObject { + if (schema?._def.typeName === "ZodEffects") { + const typedSchema = schema as z.ZodEffects> + return getObjectFormSchema(typedSchema._def.schema) + } + return schema as z.ZodObject +} + +function isIndex(value: unknown): value is number { + return Number(value) >= 0 +} +/** + * Constructs a path with dot paths for arrays to use brackets to be compatible with vee-validate path syntax + */ +export function normalizeFormPath(path: string): string { + const pathArr = path.split(".") + if (!pathArr.length) + return "" + + let fullPath = String(pathArr[0]) + for (let i = 1; i < pathArr.length; i++) { + if (isIndex(pathArr[i])) { + fullPath += `[${pathArr[i]}]` + continue + } + + fullPath += `.${pathArr[i]}` + } + + return fullPath +} + +type NestedRecord = Record | { [k: string]: NestedRecord } +/** + * Checks if the path opted out of nested fields using `[fieldName]` syntax + */ +export function isNotNestedPath(path: string) { + return /^\[.+\]$/.test(path) +} +function isObject(obj: unknown): obj is Record { + return obj !== null && !!obj && typeof obj === "object" && !Array.isArray(obj) +} +function isContainerValue(value: unknown): value is Record { + return isObject(value) || Array.isArray(value) +} +function cleanupNonNestedPath(path: string) { + if (isNotNestedPath(path)) + return path.replace(/\[|\]/g, "") + + return path +} + +/** + * Gets a nested property value from an object + */ +export function getFromPath(object: NestedRecord | undefined, path: string): TValue | undefined +export function getFromPath( + object: NestedRecord | undefined, + path: string, + fallback?: TFallback, +): TValue | TFallback +export function getFromPath( + object: NestedRecord | undefined, + path: string, + fallback?: TFallback, +): TValue | TFallback | undefined { + if (!object) + return fallback + + if (isNotNestedPath(path)) + return object[cleanupNonNestedPath(path)] as TValue | undefined + + const resolvedValue = (path || "") + .split(/\.|\[(\d+)\]/) + .filter(Boolean) + .reduce((acc, propKey) => { + if (isContainerValue(acc) && propKey in acc) + return acc[propKey] + + return fallback + }, object as unknown) + + return resolvedValue as TValue | undefined +} + +type Booleanish = boolean | "true" | "false" + +export function booleanishToBoolean(value: Booleanish) { + switch (value) { + case "true": + case true: + return true + case "false": + case false: + return false + } +} + +export function maybeBooleanishToBoolean(value?: Booleanish) { + return value ? booleanishToBoolean(value) : undefined +} diff --git a/components/ui/avatar/Avatar.vue b/components/ui/avatar/Avatar.vue new file mode 100644 index 0000000..cf99fb5 --- /dev/null +++ b/components/ui/avatar/Avatar.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/avatar/AvatarFallback.vue b/components/ui/avatar/AvatarFallback.vue new file mode 100644 index 0000000..c00c6a0 --- /dev/null +++ b/components/ui/avatar/AvatarFallback.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/ui/avatar/AvatarImage.vue b/components/ui/avatar/AvatarImage.vue new file mode 100644 index 0000000..390f224 --- /dev/null +++ b/components/ui/avatar/AvatarImage.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/ui/avatar/index.ts b/components/ui/avatar/index.ts new file mode 100644 index 0000000..da44253 --- /dev/null +++ b/components/ui/avatar/index.ts @@ -0,0 +1,25 @@ +import type { VariantProps } from "class-variance-authority" +import { cva } from "class-variance-authority" + +export { default as Avatar } from "./Avatar.vue" +export { default as AvatarFallback } from "./AvatarFallback.vue" +export { default as AvatarImage } from "./AvatarImage.vue" + +export const avatarVariant = cva( + "inline-flex items-center justify-center font-normal text-foreground select-none shrink-0 bg-secondary overflow-hidden", + { + variants: { + size: { + sm: "h-10 w-10 text-xs", + base: "h-16 w-16 text-2xl", + lg: "h-32 w-32 text-5xl", + }, + shape: { + circle: "rounded-full", + square: "rounded-md", + }, + }, + }, +) + +export type AvatarVariants = VariantProps diff --git a/components/ui/badge/Badge.vue b/components/ui/badge/Badge.vue new file mode 100644 index 0000000..0374568 --- /dev/null +++ b/components/ui/badge/Badge.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/badge/index.ts b/components/ui/badge/index.ts new file mode 100644 index 0000000..98a768d --- /dev/null +++ b/components/ui/badge/index.ts @@ -0,0 +1,26 @@ +import type { VariantProps } from "class-variance-authority" +import { cva } from "class-variance-authority" + +export { default as Badge } from "./Badge.vue" + +export const badgeVariants = cva( + "inline-flex gap-1 items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + { + variants: { + variant: { + default: + "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", + secondary: + "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: + "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", + outline: "text-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +) + +export type BadgeVariants = VariantProps diff --git a/components/ui/breadcrumb/Breadcrumb.vue b/components/ui/breadcrumb/Breadcrumb.vue new file mode 100644 index 0000000..b4fc008 --- /dev/null +++ b/components/ui/breadcrumb/Breadcrumb.vue @@ -0,0 +1,13 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbEllipsis.vue b/components/ui/breadcrumb/BreadcrumbEllipsis.vue new file mode 100644 index 0000000..5bb8fa7 --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbEllipsis.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbItem.vue b/components/ui/breadcrumb/BreadcrumbItem.vue new file mode 100644 index 0000000..dcdd26e --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbItem.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbLink.vue b/components/ui/breadcrumb/BreadcrumbLink.vue new file mode 100644 index 0000000..d61232f --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbLink.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbList.vue b/components/ui/breadcrumb/BreadcrumbList.vue new file mode 100644 index 0000000..06ba68f --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbList.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbPage.vue b/components/ui/breadcrumb/BreadcrumbPage.vue new file mode 100644 index 0000000..64e61b9 --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbPage.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbSeparator.vue b/components/ui/breadcrumb/BreadcrumbSeparator.vue new file mode 100644 index 0000000..086c746 --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbSeparator.vue @@ -0,0 +1,21 @@ + + + diff --git a/components/ui/breadcrumb/index.ts b/components/ui/breadcrumb/index.ts new file mode 100644 index 0000000..f4eafdc --- /dev/null +++ b/components/ui/breadcrumb/index.ts @@ -0,0 +1,7 @@ +export { default as Breadcrumb } from "./Breadcrumb.vue" +export { default as BreadcrumbEllipsis } from "./BreadcrumbEllipsis.vue" +export { default as BreadcrumbItem } from "./BreadcrumbItem.vue" +export { default as BreadcrumbLink } from "./BreadcrumbLink.vue" +export { default as BreadcrumbList } from "./BreadcrumbList.vue" +export { default as BreadcrumbPage } from "./BreadcrumbPage.vue" +export { default as BreadcrumbSeparator } from "./BreadcrumbSeparator.vue" diff --git a/components/ui/button-group/ButtonGroup.vue b/components/ui/button-group/ButtonGroup.vue new file mode 100644 index 0000000..9dbef6a --- /dev/null +++ b/components/ui/button-group/ButtonGroup.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/button-group/ButtonGroupSeparator.vue b/components/ui/button-group/ButtonGroupSeparator.vue new file mode 100644 index 0000000..e069dd5 --- /dev/null +++ b/components/ui/button-group/ButtonGroupSeparator.vue @@ -0,0 +1,24 @@ + + + diff --git a/components/ui/button-group/ButtonGroupText.vue b/components/ui/button-group/ButtonGroupText.vue new file mode 100644 index 0000000..c436843 --- /dev/null +++ b/components/ui/button-group/ButtonGroupText.vue @@ -0,0 +1,29 @@ + + + diff --git a/components/ui/button-group/index.ts b/components/ui/button-group/index.ts new file mode 100644 index 0000000..3fd207a --- /dev/null +++ b/components/ui/button-group/index.ts @@ -0,0 +1,25 @@ +import type { VariantProps } from "class-variance-authority" +import { cva } from "class-variance-authority" + +export { default as ButtonGroup } from "./ButtonGroup.vue" +export { default as ButtonGroupSeparator } from "./ButtonGroupSeparator.vue" +export { default as ButtonGroupText } from "./ButtonGroupText.vue" + +export const buttonGroupVariants = cva( + "flex w-fit items-stretch [&>*:focus-visible]:z-10 [&>*:focus-visible]:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2", + { + variants: { + orientation: { + horizontal: + "[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none", + vertical: + "flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none", + }, + }, + defaultVariants: { + orientation: "horizontal", + }, + }, +) + +export type ButtonGroupVariants = VariantProps diff --git a/components/ui/button/Button.vue b/components/ui/button/Button.vue new file mode 100644 index 0000000..3330ec9 --- /dev/null +++ b/components/ui/button/Button.vue @@ -0,0 +1,28 @@ + + + diff --git a/components/ui/button/index.ts b/components/ui/button/index.ts new file mode 100644 index 0000000..92a950c --- /dev/null +++ b/components/ui/button/index.ts @@ -0,0 +1,37 @@ +import type { VariantProps } from "class-variance-authority" +import { cva } from "class-variance-authority" + +export { default as Button } from "./Button.vue" + +export const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: + "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + "default": "h-10 px-4 py-2", + "sm": "h-9 rounded-md px-3", + "lg": "h-11 rounded-md px-8", + "icon": "h-10 w-10", + "icon-sm": "size-9", + "icon-lg": "size-11", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + }, +) + +export type ButtonVariants = VariantProps diff --git a/components/ui/calendar/Calendar.vue b/components/ui/calendar/Calendar.vue new file mode 100644 index 0000000..d112cf3 --- /dev/null +++ b/components/ui/calendar/Calendar.vue @@ -0,0 +1,58 @@ + + + diff --git a/components/ui/calendar/CalendarCell.vue b/components/ui/calendar/CalendarCell.vue new file mode 100644 index 0000000..d11a211 --- /dev/null +++ b/components/ui/calendar/CalendarCell.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/calendar/CalendarCellTrigger.vue b/components/ui/calendar/CalendarCellTrigger.vue new file mode 100644 index 0000000..6a38084 --- /dev/null +++ b/components/ui/calendar/CalendarCellTrigger.vue @@ -0,0 +1,36 @@ + + + diff --git a/components/ui/calendar/CalendarGrid.vue b/components/ui/calendar/CalendarGrid.vue new file mode 100644 index 0000000..5f52519 --- /dev/null +++ b/components/ui/calendar/CalendarGrid.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/calendar/CalendarGridBody.vue b/components/ui/calendar/CalendarGridBody.vue new file mode 100644 index 0000000..4fe36d7 --- /dev/null +++ b/components/ui/calendar/CalendarGridBody.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/ui/calendar/CalendarGridHead.vue b/components/ui/calendar/CalendarGridHead.vue new file mode 100644 index 0000000..9f96027 --- /dev/null +++ b/components/ui/calendar/CalendarGridHead.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/ui/calendar/CalendarGridRow.vue b/components/ui/calendar/CalendarGridRow.vue new file mode 100644 index 0000000..ae99082 --- /dev/null +++ b/components/ui/calendar/CalendarGridRow.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/calendar/CalendarHeadCell.vue b/components/ui/calendar/CalendarHeadCell.vue new file mode 100644 index 0000000..3703c92 --- /dev/null +++ b/components/ui/calendar/CalendarHeadCell.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/calendar/CalendarHeader.vue b/components/ui/calendar/CalendarHeader.vue new file mode 100644 index 0000000..706f78b --- /dev/null +++ b/components/ui/calendar/CalendarHeader.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/calendar/CalendarHeading.vue b/components/ui/calendar/CalendarHeading.vue new file mode 100644 index 0000000..3b84ee8 --- /dev/null +++ b/components/ui/calendar/CalendarHeading.vue @@ -0,0 +1,29 @@ + + + diff --git a/components/ui/calendar/CalendarNextButton.vue b/components/ui/calendar/CalendarNextButton.vue new file mode 100644 index 0000000..ae8861c --- /dev/null +++ b/components/ui/calendar/CalendarNextButton.vue @@ -0,0 +1,30 @@ + + + diff --git a/components/ui/calendar/CalendarPrevButton.vue b/components/ui/calendar/CalendarPrevButton.vue new file mode 100644 index 0000000..43e32a0 --- /dev/null +++ b/components/ui/calendar/CalendarPrevButton.vue @@ -0,0 +1,30 @@ + + + diff --git a/components/ui/calendar/index.ts b/components/ui/calendar/index.ts new file mode 100644 index 0000000..f222de0 --- /dev/null +++ b/components/ui/calendar/index.ts @@ -0,0 +1,12 @@ +export { default as Calendar } from "./Calendar.vue" +export { default as CalendarCell } from "./CalendarCell.vue" +export { default as CalendarCellTrigger } from "./CalendarCellTrigger.vue" +export { default as CalendarGrid } from "./CalendarGrid.vue" +export { default as CalendarGridBody } from "./CalendarGridBody.vue" +export { default as CalendarGridHead } from "./CalendarGridHead.vue" +export { default as CalendarGridRow } from "./CalendarGridRow.vue" +export { default as CalendarHeadCell } from "./CalendarHeadCell.vue" +export { default as CalendarHeader } from "./CalendarHeader.vue" +export { default as CalendarHeading } from "./CalendarHeading.vue" +export { default as CalendarNextButton } from "./CalendarNextButton.vue" +export { default as CalendarPrevButton } from "./CalendarPrevButton.vue" diff --git a/components/ui/card/Card.vue b/components/ui/card/Card.vue new file mode 100644 index 0000000..db8c07a --- /dev/null +++ b/components/ui/card/Card.vue @@ -0,0 +1,21 @@ + + + diff --git a/components/ui/card/CardContent.vue b/components/ui/card/CardContent.vue new file mode 100644 index 0000000..4c4dfc7 --- /dev/null +++ b/components/ui/card/CardContent.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/card/CardDescription.vue b/components/ui/card/CardDescription.vue new file mode 100644 index 0000000..02bddba --- /dev/null +++ b/components/ui/card/CardDescription.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/card/CardFooter.vue b/components/ui/card/CardFooter.vue new file mode 100644 index 0000000..fad3928 --- /dev/null +++ b/components/ui/card/CardFooter.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/card/CardHeader.vue b/components/ui/card/CardHeader.vue new file mode 100644 index 0000000..119700c --- /dev/null +++ b/components/ui/card/CardHeader.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/card/CardTitle.vue b/components/ui/card/CardTitle.vue new file mode 100644 index 0000000..d0c0ea7 --- /dev/null +++ b/components/ui/card/CardTitle.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/ui/card/index.ts b/components/ui/card/index.ts new file mode 100644 index 0000000..e5c7cb2 --- /dev/null +++ b/components/ui/card/index.ts @@ -0,0 +1,6 @@ +export { default as Card } from "./Card.vue" +export { default as CardContent } from "./CardContent.vue" +export { default as CardDescription } from "./CardDescription.vue" +export { default as CardFooter } from "./CardFooter.vue" +export { default as CardHeader } from "./CardHeader.vue" +export { default as CardTitle } from "./CardTitle.vue" diff --git a/components/ui/carousel/Carousel.vue b/components/ui/carousel/Carousel.vue new file mode 100644 index 0000000..30138a9 --- /dev/null +++ b/components/ui/carousel/Carousel.vue @@ -0,0 +1,52 @@ + + + diff --git a/components/ui/carousel/CarouselContent.vue b/components/ui/carousel/CarouselContent.vue new file mode 100644 index 0000000..5f43e7e --- /dev/null +++ b/components/ui/carousel/CarouselContent.vue @@ -0,0 +1,29 @@ + + + diff --git a/components/ui/carousel/CarouselItem.vue b/components/ui/carousel/CarouselItem.vue new file mode 100644 index 0000000..71e3cf5 --- /dev/null +++ b/components/ui/carousel/CarouselItem.vue @@ -0,0 +1,23 @@ + + + diff --git a/components/ui/carousel/CarouselNext.vue b/components/ui/carousel/CarouselNext.vue new file mode 100644 index 0000000..f6e093f --- /dev/null +++ b/components/ui/carousel/CarouselNext.vue @@ -0,0 +1,31 @@ + + + diff --git a/components/ui/carousel/CarouselPrevious.vue b/components/ui/carousel/CarouselPrevious.vue new file mode 100644 index 0000000..7cecb3b --- /dev/null +++ b/components/ui/carousel/CarouselPrevious.vue @@ -0,0 +1,31 @@ + + + diff --git a/components/ui/carousel/index.ts b/components/ui/carousel/index.ts new file mode 100644 index 0000000..154bfcb --- /dev/null +++ b/components/ui/carousel/index.ts @@ -0,0 +1,10 @@ +export { default as Carousel } from "./Carousel.vue" +export { default as CarouselContent } from "./CarouselContent.vue" +export { default as CarouselItem } from "./CarouselItem.vue" +export { default as CarouselNext } from "./CarouselNext.vue" +export { default as CarouselPrevious } from "./CarouselPrevious.vue" +export type { + UnwrapRefCarouselApi as CarouselApi, +} from "./interface" + +export { useCarousel } from "./useCarousel" diff --git a/components/ui/carousel/interface.ts b/components/ui/carousel/interface.ts new file mode 100644 index 0000000..74eaf36 --- /dev/null +++ b/components/ui/carousel/interface.ts @@ -0,0 +1,26 @@ +import type useEmblaCarousel from "embla-carousel-vue" +import type { + EmblaCarouselVueType, +} from "embla-carousel-vue" +import type { HTMLAttributes, UnwrapRef } from "vue" + +type CarouselApi = EmblaCarouselVueType[1] +type UseCarouselParameters = Parameters +type CarouselOptions = UseCarouselParameters[0] +type CarouselPlugin = UseCarouselParameters[1] + +export type UnwrapRefCarouselApi = UnwrapRef + +export interface CarouselProps { + opts?: CarouselOptions + plugins?: CarouselPlugin + orientation?: "horizontal" | "vertical" +} + +export interface CarouselEmits { + (e: "init-api", payload: UnwrapRefCarouselApi): void +} + +export interface WithClassAsProps { + class?: HTMLAttributes["class"] +} diff --git a/components/ui/carousel/useCarousel.ts b/components/ui/carousel/useCarousel.ts new file mode 100644 index 0000000..32e35ca --- /dev/null +++ b/components/ui/carousel/useCarousel.ts @@ -0,0 +1,56 @@ +import type { UnwrapRefCarouselApi as CarouselApi, CarouselEmits, CarouselProps } from "./interface" +import { createInjectionState } from "@vueuse/core" +import emblaCarouselVue from "embla-carousel-vue" +import { onMounted, ref } from "vue" + +const [useProvideCarousel, useInjectCarousel] = createInjectionState( + ({ + opts, + orientation, + plugins, + }: CarouselProps, emits: CarouselEmits) => { + const [emblaNode, emblaApi] = emblaCarouselVue({ + ...opts, + axis: orientation === "horizontal" ? "x" : "y", + }, plugins) + + function scrollPrev() { + emblaApi.value?.scrollPrev() + } + function scrollNext() { + emblaApi.value?.scrollNext() + } + + const canScrollNext = ref(false) + const canScrollPrev = ref(false) + + function onSelect(api: CarouselApi) { + canScrollNext.value = api?.canScrollNext() || false + canScrollPrev.value = api?.canScrollPrev() || false + } + + onMounted(() => { + if (!emblaApi.value) + return + + emblaApi.value?.on("init", onSelect) + emblaApi.value?.on("reInit", onSelect) + emblaApi.value?.on("select", onSelect) + + emits("init-api", emblaApi.value) + }) + + return { carouselRef: emblaNode, carouselApi: emblaApi, canScrollPrev, canScrollNext, scrollPrev, scrollNext, orientation } + }, +) + +function useCarousel() { + const carouselState = useInjectCarousel() + + if (!carouselState) + throw new Error("useCarousel must be used within a ") + + return carouselState +} + +export { useCarousel, useProvideCarousel } diff --git a/components/ui/chart-area/AreaChart.vue b/components/ui/chart-area/AreaChart.vue new file mode 100644 index 0000000..361fd62 --- /dev/null +++ b/components/ui/chart-area/AreaChart.vue @@ -0,0 +1,141 @@ + + + diff --git a/components/ui/chart-area/index.ts b/components/ui/chart-area/index.ts new file mode 100644 index 0000000..a5f0336 --- /dev/null +++ b/components/ui/chart-area/index.ts @@ -0,0 +1,66 @@ +export { default as AreaChart } from "./AreaChart.vue" + +import type { Spacing } from "@unovis/ts" + +type KeyOf> = Extract + +export interface BaseChartProps> { + /** + * The source data, in which each entry is a dictionary. + */ + data: T[] + /** + * Select the categories from your data. Used to populate the legend and tooltip. + */ + categories: KeyOf[] + /** + * Sets the key to map the data to the axis. + */ + index: KeyOf + /** + * Change the default colors. + */ + colors?: string[] + /** + * Margin of each the container + */ + margin?: Spacing + /** + * Change the opacity of the non-selected field + * @default 0.2 + */ + filterOpacity?: number + /** + * Function to format X label + */ + xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string + /** + * Function to format Y label + */ + yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string + /** + * Controls the visibility of the X axis. + * @default true + */ + showXAxis?: boolean + /** + * Controls the visibility of the Y axis. + * @default true + */ + showYAxis?: boolean + /** + * Controls the visibility of tooltip. + * @default true + */ + showTooltip?: boolean + /** + * Controls the visibility of legend. + * @default true + */ + showLegend?: boolean + /** + * Controls the visibility of gridline. + * @default true + */ + showGridLine?: boolean +} diff --git a/components/ui/chart-bar/BarChart.vue b/components/ui/chart-bar/BarChart.vue new file mode 100644 index 0000000..8bb23ca --- /dev/null +++ b/components/ui/chart-bar/BarChart.vue @@ -0,0 +1,116 @@ + + + diff --git a/components/ui/chart-bar/index.ts b/components/ui/chart-bar/index.ts new file mode 100644 index 0000000..25bd137 --- /dev/null +++ b/components/ui/chart-bar/index.ts @@ -0,0 +1,66 @@ +export { default as BarChart } from "./BarChart.vue" + +import type { Spacing } from "@unovis/ts" + +type KeyOf> = Extract + +export interface BaseChartProps> { + /** + * The source data, in which each entry is a dictionary. + */ + data: T[] + /** + * Select the categories from your data. Used to populate the legend and tooltip. + */ + categories: KeyOf[] + /** + * Sets the key to map the data to the axis. + */ + index: KeyOf + /** + * Change the default colors. + */ + colors?: string[] + /** + * Margin of each the container + */ + margin?: Spacing + /** + * Change the opacity of the non-selected field + * @default 0.2 + */ + filterOpacity?: number + /** + * Function to format X label + */ + xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string + /** + * Function to format Y label + */ + yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string + /** + * Controls the visibility of the X axis. + * @default true + */ + showXAxis?: boolean + /** + * Controls the visibility of the Y axis. + * @default true + */ + showYAxis?: boolean + /** + * Controls the visibility of tooltip. + * @default true + */ + showTooltip?: boolean + /** + * Controls the visibility of legend. + * @default true + */ + showLegend?: boolean + /** + * Controls the visibility of gridline. + * @default true + */ + showGridLine?: boolean +} diff --git a/components/ui/chart-donut/DonutChart.vue b/components/ui/chart-donut/DonutChart.vue new file mode 100644 index 0000000..c439218 --- /dev/null +++ b/components/ui/chart-donut/DonutChart.vue @@ -0,0 +1,101 @@ + + + diff --git a/components/ui/chart-donut/index.ts b/components/ui/chart-donut/index.ts new file mode 100644 index 0000000..07af888 --- /dev/null +++ b/components/ui/chart-donut/index.ts @@ -0,0 +1,39 @@ +export { default as DonutChart } from "./DonutChart.vue" + +import type { Spacing } from "@unovis/ts" + +type KeyOf> = Extract + +export interface BaseChartProps> { + /** + * The source data, in which each entry is a dictionary. + */ + data: T[] + /** + * Sets the key to map the data to the axis. + */ + index: KeyOf + /** + * Change the default colors. + */ + colors?: string[] + /** + * Margin of each the container + */ + margin?: Spacing + /** + * Change the opacity of the non-selected field + * @default 0.2 + */ + filterOpacity?: number + /** + * Controls the visibility of tooltip. + * @default true + */ + showTooltip?: boolean + /** + * Controls the visibility of legend. + * @default true + */ + showLegend?: boolean +} diff --git a/components/ui/chart-line/LineChart.vue b/components/ui/chart-line/LineChart.vue new file mode 100644 index 0000000..8692f5b --- /dev/null +++ b/components/ui/chart-line/LineChart.vue @@ -0,0 +1,107 @@ + + + diff --git a/components/ui/chart-line/index.ts b/components/ui/chart-line/index.ts new file mode 100644 index 0000000..d75c079 --- /dev/null +++ b/components/ui/chart-line/index.ts @@ -0,0 +1,66 @@ +export { default as LineChart } from "./LineChart.vue" + +import type { Spacing } from "@unovis/ts" + +type KeyOf> = Extract + +export interface BaseChartProps> { + /** + * The source data, in which each entry is a dictionary. + */ + data: T[] + /** + * Select the categories from your data. Used to populate the legend and tooltip. + */ + categories: KeyOf[] + /** + * Sets the key to map the data to the axis. + */ + index: KeyOf + /** + * Change the default colors. + */ + colors?: string[] + /** + * Margin of each the container + */ + margin?: Spacing + /** + * Change the opacity of the non-selected field + * @default 0.2 + */ + filterOpacity?: number + /** + * Function to format X label + */ + xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string + /** + * Function to format Y label + */ + yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string + /** + * Controls the visibility of the X axis. + * @default true + */ + showXAxis?: boolean + /** + * Controls the visibility of the Y axis. + * @default true + */ + showYAxis?: boolean + /** + * Controls the visibility of tooltip. + * @default true + */ + showTooltip?: boolean + /** + * Controls the visibility of legend. + * @default true + */ + showLegend?: boolean + /** + * Controls the visibility of gridline. + * @default true + */ + showGridLine?: boolean +} diff --git a/components/ui/chart/ChartCrosshair.vue b/components/ui/chart/ChartCrosshair.vue new file mode 100644 index 0000000..06d327e --- /dev/null +++ b/components/ui/chart/ChartCrosshair.vue @@ -0,0 +1,45 @@ + + + diff --git a/components/ui/chart/ChartLegend.vue b/components/ui/chart/ChartLegend.vue new file mode 100644 index 0000000..672e831 --- /dev/null +++ b/components/ui/chart/ChartLegend.vue @@ -0,0 +1,59 @@ + + + diff --git a/components/ui/chart/ChartSingleTooltip.vue b/components/ui/chart/ChartSingleTooltip.vue new file mode 100644 index 0000000..55f9e36 --- /dev/null +++ b/components/ui/chart/ChartSingleTooltip.vue @@ -0,0 +1,63 @@ + + + diff --git a/components/ui/chart/ChartTooltip.vue b/components/ui/chart/ChartTooltip.vue new file mode 100644 index 0000000..a20c80c --- /dev/null +++ b/components/ui/chart/ChartTooltip.vue @@ -0,0 +1,40 @@ + + + diff --git a/components/ui/chart/index.ts b/components/ui/chart/index.ts new file mode 100644 index 0000000..a152bb8 --- /dev/null +++ b/components/ui/chart/index.ts @@ -0,0 +1,18 @@ +export { default as ChartCrosshair } from "./ChartCrosshair.vue" +export { default as ChartLegend } from "./ChartLegend.vue" +export { default as ChartSingleTooltip } from "./ChartSingleTooltip.vue" +export { default as ChartTooltip } from "./ChartTooltip.vue" + +export function defaultColors(count: number = 3) { + const quotient = Math.floor(count / 2) + const remainder = count % 2 + + const primaryCount = quotient + remainder + const secondaryCount = quotient + return [ + ...Array.from(new Array(primaryCount).keys()).map(i => `hsl(var(--vis-primary-color) / ${1 - (1 / primaryCount) * i})`), + ...Array.from(new Array(secondaryCount).keys()).map(i => `hsl(var(--vis-secondary-color) / ${1 - (1 / secondaryCount) * i})`), + ] +} + +export * from "./interface" diff --git a/components/ui/chart/interface.ts b/components/ui/chart/interface.ts new file mode 100644 index 0000000..41d9bd8 --- /dev/null +++ b/components/ui/chart/interface.ts @@ -0,0 +1,64 @@ +import type { Spacing } from "@unovis/ts" + +type KeyOf> = Extract + +export interface BaseChartProps> { + /** + * The source data, in which each entry is a dictionary. + */ + data: T[] + /** + * Select the categories from your data. Used to populate the legend and tooltip. + */ + categories: KeyOf[] + /** + * Sets the key to map the data to the axis. + */ + index: KeyOf + /** + * Change the default colors. + */ + colors?: string[] + /** + * Margin of each the container + */ + margin?: Spacing + /** + * Change the opacity of the non-selected field + * @default 0.2 + */ + filterOpacity?: number + /** + * Function to format X label + */ + xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string + /** + * Function to format Y label + */ + yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string + /** + * Controls the visibility of the X axis. + * @default true + */ + showXAxis?: boolean + /** + * Controls the visibility of the Y axis. + * @default true + */ + showYAxis?: boolean + /** + * Controls the visibility of tooltip. + * @default true + */ + showTooltip?: boolean + /** + * Controls the visibility of legend. + * @default true + */ + showLegend?: boolean + /** + * Controls the visibility of gridline. + * @default true + */ + showGridLine?: boolean +} diff --git a/components/ui/checkbox/Checkbox.vue b/components/ui/checkbox/Checkbox.vue new file mode 100644 index 0000000..f612895 --- /dev/null +++ b/components/ui/checkbox/Checkbox.vue @@ -0,0 +1,30 @@ + + + diff --git a/components/ui/checkbox/index.ts b/components/ui/checkbox/index.ts new file mode 100644 index 0000000..3391a85 --- /dev/null +++ b/components/ui/checkbox/index.ts @@ -0,0 +1 @@ +export { default as Checkbox } from "./Checkbox.vue" diff --git a/components/ui/collapsible/Collapsible.vue b/components/ui/collapsible/Collapsible.vue new file mode 100644 index 0000000..77d575e --- /dev/null +++ b/components/ui/collapsible/Collapsible.vue @@ -0,0 +1,15 @@ + + + diff --git a/components/ui/collapsible/CollapsibleContent.vue b/components/ui/collapsible/CollapsibleContent.vue new file mode 100644 index 0000000..56fab10 --- /dev/null +++ b/components/ui/collapsible/CollapsibleContent.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/ui/collapsible/CollapsibleTrigger.vue b/components/ui/collapsible/CollapsibleTrigger.vue new file mode 100644 index 0000000..05bc3f1 --- /dev/null +++ b/components/ui/collapsible/CollapsibleTrigger.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/ui/collapsible/index.ts b/components/ui/collapsible/index.ts new file mode 100644 index 0000000..86a031d --- /dev/null +++ b/components/ui/collapsible/index.ts @@ -0,0 +1,3 @@ +export { default as Collapsible } from "./Collapsible.vue" +export { default as CollapsibleContent } from "./CollapsibleContent.vue" +export { default as CollapsibleTrigger } from "./CollapsibleTrigger.vue" diff --git a/components/ui/combobox/Combobox.vue b/components/ui/combobox/Combobox.vue new file mode 100644 index 0000000..dd1891b --- /dev/null +++ b/components/ui/combobox/Combobox.vue @@ -0,0 +1,15 @@ + + + diff --git a/components/ui/combobox/ComboboxAnchor.vue b/components/ui/combobox/ComboboxAnchor.vue new file mode 100644 index 0000000..6cd6b6b --- /dev/null +++ b/components/ui/combobox/ComboboxAnchor.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/combobox/ComboboxEmpty.vue b/components/ui/combobox/ComboboxEmpty.vue new file mode 100644 index 0000000..9e261fb --- /dev/null +++ b/components/ui/combobox/ComboboxEmpty.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/combobox/ComboboxGroup.vue b/components/ui/combobox/ComboboxGroup.vue new file mode 100644 index 0000000..ed6d595 --- /dev/null +++ b/components/ui/combobox/ComboboxGroup.vue @@ -0,0 +1,26 @@ + + + diff --git a/components/ui/combobox/ComboboxInput.vue b/components/ui/combobox/ComboboxInput.vue new file mode 100644 index 0000000..f6632c2 --- /dev/null +++ b/components/ui/combobox/ComboboxInput.vue @@ -0,0 +1,26 @@ + + + diff --git a/components/ui/combobox/ComboboxItem.vue b/components/ui/combobox/ComboboxItem.vue new file mode 100644 index 0000000..59dac5b --- /dev/null +++ b/components/ui/combobox/ComboboxItem.vue @@ -0,0 +1,23 @@ + + + diff --git a/components/ui/combobox/ComboboxList.vue b/components/ui/combobox/ComboboxList.vue new file mode 100644 index 0000000..525d870 --- /dev/null +++ b/components/ui/combobox/ComboboxList.vue @@ -0,0 +1,31 @@ + + + diff --git a/components/ui/combobox/ComboboxSeparator.vue b/components/ui/combobox/ComboboxSeparator.vue new file mode 100644 index 0000000..e8c7943 --- /dev/null +++ b/components/ui/combobox/ComboboxSeparator.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/combobox/ComboboxTrigger.vue b/components/ui/combobox/ComboboxTrigger.vue new file mode 100644 index 0000000..50bb509 --- /dev/null +++ b/components/ui/combobox/ComboboxTrigger.vue @@ -0,0 +1,23 @@ + + + diff --git a/components/ui/combobox/index.ts b/components/ui/combobox/index.ts new file mode 100644 index 0000000..bc6f38e --- /dev/null +++ b/components/ui/combobox/index.ts @@ -0,0 +1,10 @@ +export { default as Combobox } from "./Combobox.vue" +export { default as ComboboxAnchor } from "./ComboboxAnchor.vue" +export { default as ComboboxEmpty } from "./ComboboxEmpty.vue" +export { default as ComboboxGroup } from "./ComboboxGroup.vue" +export { default as ComboboxInput } from "./ComboboxInput.vue" +export { default as ComboboxItem } from "./ComboboxItem.vue" +export { default as ComboboxList } from "./ComboboxList.vue" +export { default as ComboboxSeparator } from "./ComboboxSeparator.vue" + +export { ComboboxCancel, ComboboxItemIndicator, ComboboxTrigger } from "reka-ui" diff --git a/components/ui/command/Command.vue b/components/ui/command/Command.vue new file mode 100644 index 0000000..3e9a8b2 --- /dev/null +++ b/components/ui/command/Command.vue @@ -0,0 +1,86 @@ + + + diff --git a/components/ui/command/CommandDialog.vue b/components/ui/command/CommandDialog.vue new file mode 100644 index 0000000..bccd25c --- /dev/null +++ b/components/ui/command/CommandDialog.vue @@ -0,0 +1,21 @@ + + + diff --git a/components/ui/command/CommandEmpty.vue b/components/ui/command/CommandEmpty.vue new file mode 100644 index 0000000..d4d156f --- /dev/null +++ b/components/ui/command/CommandEmpty.vue @@ -0,0 +1,23 @@ + + + diff --git a/components/ui/command/CommandGroup.vue b/components/ui/command/CommandGroup.vue new file mode 100644 index 0000000..99df3a4 --- /dev/null +++ b/components/ui/command/CommandGroup.vue @@ -0,0 +1,44 @@ + + + diff --git a/components/ui/command/CommandInput.vue b/components/ui/command/CommandInput.vue new file mode 100644 index 0000000..4f7e84a --- /dev/null +++ b/components/ui/command/CommandInput.vue @@ -0,0 +1,35 @@ + + + diff --git a/components/ui/command/CommandItem.vue b/components/ui/command/CommandItem.vue new file mode 100644 index 0000000..c6088e2 --- /dev/null +++ b/components/ui/command/CommandItem.vue @@ -0,0 +1,75 @@ + + + diff --git a/components/ui/command/CommandList.vue b/components/ui/command/CommandList.vue new file mode 100644 index 0000000..d94b969 --- /dev/null +++ b/components/ui/command/CommandList.vue @@ -0,0 +1,21 @@ + + + diff --git a/components/ui/command/CommandSeparator.vue b/components/ui/command/CommandSeparator.vue new file mode 100644 index 0000000..799319b --- /dev/null +++ b/components/ui/command/CommandSeparator.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/command/CommandShortcut.vue b/components/ui/command/CommandShortcut.vue new file mode 100644 index 0000000..6d95d73 --- /dev/null +++ b/components/ui/command/CommandShortcut.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/command/index.ts b/components/ui/command/index.ts new file mode 100644 index 0000000..af18933 --- /dev/null +++ b/components/ui/command/index.ts @@ -0,0 +1,25 @@ +import type { Ref } from "vue" +import { createContext } from "reka-ui" + +export { default as Command } from "./Command.vue" +export { default as CommandDialog } from "./CommandDialog.vue" +export { default as CommandEmpty } from "./CommandEmpty.vue" +export { default as CommandGroup } from "./CommandGroup.vue" +export { default as CommandInput } from "./CommandInput.vue" +export { default as CommandItem } from "./CommandItem.vue" +export { default as CommandList } from "./CommandList.vue" +export { default as CommandSeparator } from "./CommandSeparator.vue" +export { default as CommandShortcut } from "./CommandShortcut.vue" + +export const [useCommand, provideCommandContext] = createContext<{ + allItems: Ref> + allGroups: Ref>> + filterState: { + search: string + filtered: { count: number, items: Map, groups: Set } + } +}>("Command") + +export const [useCommandGroup, provideCommandGroupContext] = createContext<{ + id?: string +}>("CommandGroup") diff --git a/components/ui/context-menu/ContextMenu.vue b/components/ui/context-menu/ContextMenu.vue new file mode 100644 index 0000000..50e8fa3 --- /dev/null +++ b/components/ui/context-menu/ContextMenu.vue @@ -0,0 +1,15 @@ + + + diff --git a/components/ui/context-menu/ContextMenuCheckboxItem.vue b/components/ui/context-menu/ContextMenuCheckboxItem.vue new file mode 100644 index 0000000..58659b0 --- /dev/null +++ b/components/ui/context-menu/ContextMenuCheckboxItem.vue @@ -0,0 +1,37 @@ + + + diff --git a/components/ui/context-menu/ContextMenuContent.vue b/components/ui/context-menu/ContextMenuContent.vue new file mode 100644 index 0000000..f8b8a5a --- /dev/null +++ b/components/ui/context-menu/ContextMenuContent.vue @@ -0,0 +1,33 @@ + + + diff --git a/components/ui/context-menu/ContextMenuGroup.vue b/components/ui/context-menu/ContextMenuGroup.vue new file mode 100644 index 0000000..5e166b5 --- /dev/null +++ b/components/ui/context-menu/ContextMenuGroup.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/ui/context-menu/ContextMenuItem.vue b/components/ui/context-menu/ContextMenuItem.vue new file mode 100644 index 0000000..3117480 --- /dev/null +++ b/components/ui/context-menu/ContextMenuItem.vue @@ -0,0 +1,31 @@ + + + diff --git a/components/ui/context-menu/ContextMenuLabel.vue b/components/ui/context-menu/ContextMenuLabel.vue new file mode 100644 index 0000000..0e413b9 --- /dev/null +++ b/components/ui/context-menu/ContextMenuLabel.vue @@ -0,0 +1,23 @@ + + + diff --git a/components/ui/context-menu/ContextMenuPortal.vue b/components/ui/context-menu/ContextMenuPortal.vue new file mode 100644 index 0000000..438e527 --- /dev/null +++ b/components/ui/context-menu/ContextMenuPortal.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/ui/context-menu/ContextMenuRadioGroup.vue b/components/ui/context-menu/ContextMenuRadioGroup.vue new file mode 100644 index 0000000..b4aca00 --- /dev/null +++ b/components/ui/context-menu/ContextMenuRadioGroup.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/context-menu/ContextMenuRadioItem.vue b/components/ui/context-menu/ContextMenuRadioItem.vue new file mode 100644 index 0000000..6f6ec28 --- /dev/null +++ b/components/ui/context-menu/ContextMenuRadioItem.vue @@ -0,0 +1,37 @@ + + + diff --git a/components/ui/context-menu/ContextMenuSeparator.vue b/components/ui/context-menu/ContextMenuSeparator.vue new file mode 100644 index 0000000..dd5f18a --- /dev/null +++ b/components/ui/context-menu/ContextMenuSeparator.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/ui/context-menu/ContextMenuShortcut.vue b/components/ui/context-menu/ContextMenuShortcut.vue new file mode 100644 index 0000000..6d95d73 --- /dev/null +++ b/components/ui/context-menu/ContextMenuShortcut.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/context-menu/ContextMenuSub.vue b/components/ui/context-menu/ContextMenuSub.vue new file mode 100644 index 0000000..0c0d0d4 --- /dev/null +++ b/components/ui/context-menu/ContextMenuSub.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/context-menu/ContextMenuSubContent.vue b/components/ui/context-menu/ContextMenuSubContent.vue new file mode 100644 index 0000000..9abfd74 --- /dev/null +++ b/components/ui/context-menu/ContextMenuSubContent.vue @@ -0,0 +1,32 @@ + + + diff --git a/components/ui/context-menu/ContextMenuSubTrigger.vue b/components/ui/context-menu/ContextMenuSubTrigger.vue new file mode 100644 index 0000000..42cdfc7 --- /dev/null +++ b/components/ui/context-menu/ContextMenuSubTrigger.vue @@ -0,0 +1,32 @@ + + + diff --git a/components/ui/context-menu/ContextMenuTrigger.vue b/components/ui/context-menu/ContextMenuTrigger.vue new file mode 100644 index 0000000..dcbd0bb --- /dev/null +++ b/components/ui/context-menu/ContextMenuTrigger.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/context-menu/index.ts b/components/ui/context-menu/index.ts new file mode 100644 index 0000000..5919fd3 --- /dev/null +++ b/components/ui/context-menu/index.ts @@ -0,0 +1,14 @@ +export { default as ContextMenu } from "./ContextMenu.vue" +export { default as ContextMenuCheckboxItem } from "./ContextMenuCheckboxItem.vue" +export { default as ContextMenuContent } from "./ContextMenuContent.vue" +export { default as ContextMenuGroup } from "./ContextMenuGroup.vue" +export { default as ContextMenuItem } from "./ContextMenuItem.vue" +export { default as ContextMenuLabel } from "./ContextMenuLabel.vue" +export { default as ContextMenuRadioGroup } from "./ContextMenuRadioGroup.vue" +export { default as ContextMenuRadioItem } from "./ContextMenuRadioItem.vue" +export { default as ContextMenuSeparator } from "./ContextMenuSeparator.vue" +export { default as ContextMenuShortcut } from "./ContextMenuShortcut.vue" +export { default as ContextMenuSub } from "./ContextMenuSub.vue" +export { default as ContextMenuSubContent } from "./ContextMenuSubContent.vue" +export { default as ContextMenuSubTrigger } from "./ContextMenuSubTrigger.vue" +export { default as ContextMenuTrigger } from "./ContextMenuTrigger.vue" diff --git a/components/ui/dialog/Dialog.vue b/components/ui/dialog/Dialog.vue new file mode 100644 index 0000000..47b0968 --- /dev/null +++ b/components/ui/dialog/Dialog.vue @@ -0,0 +1,15 @@ + + + diff --git a/components/ui/dialog/DialogClose.vue b/components/ui/dialog/DialogClose.vue new file mode 100644 index 0000000..0295976 --- /dev/null +++ b/components/ui/dialog/DialogClose.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/ui/dialog/DialogContent.vue b/components/ui/dialog/DialogContent.vue new file mode 100644 index 0000000..6f8f4ca --- /dev/null +++ b/components/ui/dialog/DialogContent.vue @@ -0,0 +1,47 @@ + + + diff --git a/components/ui/dialog/DialogDescription.vue b/components/ui/dialog/DialogDescription.vue new file mode 100644 index 0000000..062c3a5 --- /dev/null +++ b/components/ui/dialog/DialogDescription.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/dialog/DialogFooter.vue b/components/ui/dialog/DialogFooter.vue new file mode 100644 index 0000000..5f481e5 --- /dev/null +++ b/components/ui/dialog/DialogFooter.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/dialog/DialogHeader.vue b/components/ui/dialog/DialogHeader.vue new file mode 100644 index 0000000..33aa003 --- /dev/null +++ b/components/ui/dialog/DialogHeader.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/dialog/DialogScrollContent.vue b/components/ui/dialog/DialogScrollContent.vue new file mode 100644 index 0000000..e04e615 --- /dev/null +++ b/components/ui/dialog/DialogScrollContent.vue @@ -0,0 +1,56 @@ + + + diff --git a/components/ui/dialog/DialogTitle.vue b/components/ui/dialog/DialogTitle.vue new file mode 100644 index 0000000..1de56de --- /dev/null +++ b/components/ui/dialog/DialogTitle.vue @@ -0,0 +1,27 @@ + + + diff --git a/components/ui/dialog/DialogTrigger.vue b/components/ui/dialog/DialogTrigger.vue new file mode 100644 index 0000000..a4fc3ee --- /dev/null +++ b/components/ui/dialog/DialogTrigger.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/ui/dialog/index.ts b/components/ui/dialog/index.ts new file mode 100644 index 0000000..c9c577f --- /dev/null +++ b/components/ui/dialog/index.ts @@ -0,0 +1,9 @@ +export { default as Dialog } from "./Dialog.vue" +export { default as DialogClose } from "./DialogClose.vue" +export { default as DialogContent } from "./DialogContent.vue" +export { default as DialogDescription } from "./DialogDescription.vue" +export { default as DialogFooter } from "./DialogFooter.vue" +export { default as DialogHeader } from "./DialogHeader.vue" +export { default as DialogScrollContent } from "./DialogScrollContent.vue" +export { default as DialogTitle } from "./DialogTitle.vue" +export { default as DialogTrigger } from "./DialogTrigger.vue" diff --git a/components/ui/drawer/Drawer.vue b/components/ui/drawer/Drawer.vue new file mode 100644 index 0000000..6cf4a82 --- /dev/null +++ b/components/ui/drawer/Drawer.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/drawer/DrawerContent.vue b/components/ui/drawer/DrawerContent.vue new file mode 100644 index 0000000..15cd43a --- /dev/null +++ b/components/ui/drawer/DrawerContent.vue @@ -0,0 +1,28 @@ + + + diff --git a/components/ui/drawer/DrawerDescription.vue b/components/ui/drawer/DrawerDescription.vue new file mode 100644 index 0000000..d343419 --- /dev/null +++ b/components/ui/drawer/DrawerDescription.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/drawer/DrawerFooter.vue b/components/ui/drawer/DrawerFooter.vue new file mode 100644 index 0000000..9773691 --- /dev/null +++ b/components/ui/drawer/DrawerFooter.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/drawer/DrawerHeader.vue b/components/ui/drawer/DrawerHeader.vue new file mode 100644 index 0000000..48a7d4f --- /dev/null +++ b/components/ui/drawer/DrawerHeader.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/drawer/DrawerOverlay.vue b/components/ui/drawer/DrawerOverlay.vue new file mode 100644 index 0000000..6ce99dc --- /dev/null +++ b/components/ui/drawer/DrawerOverlay.vue @@ -0,0 +1,15 @@ + + + diff --git a/components/ui/drawer/DrawerTitle.vue b/components/ui/drawer/DrawerTitle.vue new file mode 100644 index 0000000..04a582c --- /dev/null +++ b/components/ui/drawer/DrawerTitle.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/drawer/index.ts b/components/ui/drawer/index.ts new file mode 100644 index 0000000..d59dff4 --- /dev/null +++ b/components/ui/drawer/index.ts @@ -0,0 +1,8 @@ +export { default as Drawer } from "./Drawer.vue" +export { default as DrawerContent } from "./DrawerContent.vue" +export { default as DrawerDescription } from "./DrawerDescription.vue" +export { default as DrawerFooter } from "./DrawerFooter.vue" +export { default as DrawerHeader } from "./DrawerHeader.vue" +export { default as DrawerOverlay } from "./DrawerOverlay.vue" +export { default as DrawerTitle } from "./DrawerTitle.vue" +export { DrawerClose, DrawerPortal, DrawerTrigger } from "vaul-vue" diff --git a/components/ui/dropdown-menu/DropdownMenu.vue b/components/ui/dropdown-menu/DropdownMenu.vue new file mode 100644 index 0000000..bf38258 --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenu.vue @@ -0,0 +1,15 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue b/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue new file mode 100644 index 0000000..1a5ced0 --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue @@ -0,0 +1,37 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuContent.vue b/components/ui/dropdown-menu/DropdownMenuContent.vue new file mode 100644 index 0000000..3c4ab26 --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuContent.vue @@ -0,0 +1,35 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuGroup.vue b/components/ui/dropdown-menu/DropdownMenuGroup.vue new file mode 100644 index 0000000..80c581a --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuGroup.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuItem.vue b/components/ui/dropdown-menu/DropdownMenuItem.vue new file mode 100644 index 0000000..98d1aa9 --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuItem.vue @@ -0,0 +1,26 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuLabel.vue b/components/ui/dropdown-menu/DropdownMenuLabel.vue new file mode 100644 index 0000000..f86fbdd --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuLabel.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue b/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue new file mode 100644 index 0000000..37a7bc9 --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuRadioItem.vue b/components/ui/dropdown-menu/DropdownMenuRadioItem.vue new file mode 100644 index 0000000..b446030 --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuRadioItem.vue @@ -0,0 +1,38 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuSeparator.vue b/components/ui/dropdown-menu/DropdownMenuSeparator.vue new file mode 100644 index 0000000..51fd557 --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuSeparator.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuShortcut.vue b/components/ui/dropdown-menu/DropdownMenuShortcut.vue new file mode 100644 index 0000000..9367641 --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuShortcut.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuSub.vue b/components/ui/dropdown-menu/DropdownMenuSub.vue new file mode 100644 index 0000000..5fc74ef --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuSub.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuSubContent.vue b/components/ui/dropdown-menu/DropdownMenuSubContent.vue new file mode 100644 index 0000000..4610dae --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuSubContent.vue @@ -0,0 +1,27 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue b/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue new file mode 100644 index 0000000..8cf712d --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue @@ -0,0 +1,31 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuTrigger.vue b/components/ui/dropdown-menu/DropdownMenuTrigger.vue new file mode 100644 index 0000000..ada9a0a --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuTrigger.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/dropdown-menu/index.ts b/components/ui/dropdown-menu/index.ts new file mode 100644 index 0000000..955fe3a --- /dev/null +++ b/components/ui/dropdown-menu/index.ts @@ -0,0 +1,16 @@ +export { default as DropdownMenu } from "./DropdownMenu.vue" + +export { default as DropdownMenuCheckboxItem } from "./DropdownMenuCheckboxItem.vue" +export { default as DropdownMenuContent } from "./DropdownMenuContent.vue" +export { default as DropdownMenuGroup } from "./DropdownMenuGroup.vue" +export { default as DropdownMenuItem } from "./DropdownMenuItem.vue" +export { default as DropdownMenuLabel } from "./DropdownMenuLabel.vue" +export { default as DropdownMenuRadioGroup } from "./DropdownMenuRadioGroup.vue" +export { default as DropdownMenuRadioItem } from "./DropdownMenuRadioItem.vue" +export { default as DropdownMenuSeparator } from "./DropdownMenuSeparator.vue" +export { default as DropdownMenuShortcut } from "./DropdownMenuShortcut.vue" +export { default as DropdownMenuSub } from "./DropdownMenuSub.vue" +export { default as DropdownMenuSubContent } from "./DropdownMenuSubContent.vue" +export { default as DropdownMenuSubTrigger } from "./DropdownMenuSubTrigger.vue" +export { default as DropdownMenuTrigger } from "./DropdownMenuTrigger.vue" +export { DropdownMenuPortal } from "reka-ui" diff --git a/components/ui/empty/Empty.vue b/components/ui/empty/Empty.vue new file mode 100644 index 0000000..2637b3c --- /dev/null +++ b/components/ui/empty/Empty.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/empty/EmptyContent.vue b/components/ui/empty/EmptyContent.vue new file mode 100644 index 0000000..d19ee00 --- /dev/null +++ b/components/ui/empty/EmptyContent.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/empty/EmptyDescription.vue b/components/ui/empty/EmptyDescription.vue new file mode 100644 index 0000000..d4d8017 --- /dev/null +++ b/components/ui/empty/EmptyDescription.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/empty/EmptyHeader.vue b/components/ui/empty/EmptyHeader.vue new file mode 100644 index 0000000..ac21d8c --- /dev/null +++ b/components/ui/empty/EmptyHeader.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/empty/EmptyMedia.vue b/components/ui/empty/EmptyMedia.vue new file mode 100644 index 0000000..c68397c --- /dev/null +++ b/components/ui/empty/EmptyMedia.vue @@ -0,0 +1,21 @@ + + + diff --git a/components/ui/empty/EmptyTitle.vue b/components/ui/empty/EmptyTitle.vue new file mode 100644 index 0000000..90c950d --- /dev/null +++ b/components/ui/empty/EmptyTitle.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/empty/index.ts b/components/ui/empty/index.ts new file mode 100644 index 0000000..ce0c489 --- /dev/null +++ b/components/ui/empty/index.ts @@ -0,0 +1,26 @@ +import type { VariantProps } from "class-variance-authority" +import { cva } from "class-variance-authority" + +export { default as Empty } from "./Empty.vue" +export { default as EmptyContent } from "./EmptyContent.vue" +export { default as EmptyDescription } from "./EmptyDescription.vue" +export { default as EmptyHeader } from "./EmptyHeader.vue" +export { default as EmptyMedia } from "./EmptyMedia.vue" +export { default as EmptyTitle } from "./EmptyTitle.vue" + +export const emptyMediaVariants = cva( + "mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0", + { + variants: { + variant: { + default: "bg-transparent", + icon: "bg-muted text-foreground flex size-10 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-6", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +) + +export type EmptyMediaVariants = VariantProps diff --git a/components/ui/field/Field.vue b/components/ui/field/Field.vue new file mode 100644 index 0000000..5519d37 --- /dev/null +++ b/components/ui/field/Field.vue @@ -0,0 +1,25 @@ + + + diff --git a/components/ui/field/FieldContent.vue b/components/ui/field/FieldContent.vue new file mode 100644 index 0000000..d9a23fd --- /dev/null +++ b/components/ui/field/FieldContent.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/field/FieldDescription.vue b/components/ui/field/FieldDescription.vue new file mode 100644 index 0000000..7240a83 --- /dev/null +++ b/components/ui/field/FieldDescription.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/field/FieldError.vue b/components/ui/field/FieldError.vue new file mode 100644 index 0000000..7ea159e --- /dev/null +++ b/components/ui/field/FieldError.vue @@ -0,0 +1,44 @@ + + + diff --git a/components/ui/field/FieldGroup.vue b/components/ui/field/FieldGroup.vue new file mode 100644 index 0000000..834d8ce --- /dev/null +++ b/components/ui/field/FieldGroup.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/field/FieldLabel.vue b/components/ui/field/FieldLabel.vue new file mode 100644 index 0000000..f84ace0 --- /dev/null +++ b/components/ui/field/FieldLabel.vue @@ -0,0 +1,23 @@ + + + diff --git a/components/ui/field/FieldLegend.vue b/components/ui/field/FieldLegend.vue new file mode 100644 index 0000000..c620fed --- /dev/null +++ b/components/ui/field/FieldLegend.vue @@ -0,0 +1,24 @@ + + + diff --git a/components/ui/field/FieldSeparator.vue b/components/ui/field/FieldSeparator.vue new file mode 100644 index 0000000..97d0efa --- /dev/null +++ b/components/ui/field/FieldSeparator.vue @@ -0,0 +1,29 @@ + + + diff --git a/components/ui/field/FieldSet.vue b/components/ui/field/FieldSet.vue new file mode 100644 index 0000000..7be4dc9 --- /dev/null +++ b/components/ui/field/FieldSet.vue @@ -0,0 +1,21 @@ + + + diff --git a/components/ui/field/FieldTitle.vue b/components/ui/field/FieldTitle.vue new file mode 100644 index 0000000..f564b8b --- /dev/null +++ b/components/ui/field/FieldTitle.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/field/index.ts b/components/ui/field/index.ts new file mode 100644 index 0000000..162ba14 --- /dev/null +++ b/components/ui/field/index.ts @@ -0,0 +1,39 @@ +import type { VariantProps } from "class-variance-authority" +import { cva } from "class-variance-authority" + +export const fieldVariants = cva( + "group/field flex w-full gap-3 data-[invalid=true]:text-destructive", + { + variants: { + orientation: { + vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"], + horizontal: [ + "flex-row items-center", + "[&>[data-slot=field-label]]:flex-auto", + "has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px", + ], + responsive: [ + "flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto", + "@md/field-group:[&>[data-slot=field-label]]:flex-auto", + "@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px", + ], + }, + }, + defaultVariants: { + orientation: "vertical", + }, + }, +) + +export type FieldVariants = VariantProps + +export { default as Field } from "./Field.vue" +export { default as FieldContent } from "./FieldContent.vue" +export { default as FieldDescription } from "./FieldDescription.vue" +export { default as FieldError } from "./FieldError.vue" +export { default as FieldGroup } from "./FieldGroup.vue" +export { default as FieldLabel } from "./FieldLabel.vue" +export { default as FieldLegend } from "./FieldLegend.vue" +export { default as FieldSeparator } from "./FieldSeparator.vue" +export { default as FieldSet } from "./FieldSet.vue" +export { default as FieldTitle } from "./FieldTitle.vue" diff --git a/components/ui/form/FormControl.vue b/components/ui/form/FormControl.vue new file mode 100644 index 0000000..0ebfad1 --- /dev/null +++ b/components/ui/form/FormControl.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/form/FormDescription.vue b/components/ui/form/FormDescription.vue new file mode 100644 index 0000000..f34123f --- /dev/null +++ b/components/ui/form/FormDescription.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/form/FormItem.vue b/components/ui/form/FormItem.vue new file mode 100644 index 0000000..efe6c37 --- /dev/null +++ b/components/ui/form/FormItem.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/form/FormLabel.vue b/components/ui/form/FormLabel.vue new file mode 100644 index 0000000..e4280a3 --- /dev/null +++ b/components/ui/form/FormLabel.vue @@ -0,0 +1,23 @@ + + + diff --git a/components/ui/form/FormMessage.vue b/components/ui/form/FormMessage.vue new file mode 100644 index 0000000..b43d01b --- /dev/null +++ b/components/ui/form/FormMessage.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/form/index.ts b/components/ui/form/index.ts new file mode 100644 index 0000000..b16bfee --- /dev/null +++ b/components/ui/form/index.ts @@ -0,0 +1,7 @@ +export { default as FormControl } from "./FormControl.vue" +export { default as FormDescription } from "./FormDescription.vue" +export { default as FormItem } from "./FormItem.vue" +export { default as FormLabel } from "./FormLabel.vue" +export { default as FormMessage } from "./FormMessage.vue" +export { FORM_ITEM_INJECTION_KEY } from "./injectionKeys" +export { Form, Field as FormField } from "vee-validate" diff --git a/components/ui/form/injectionKeys.ts b/components/ui/form/injectionKeys.ts new file mode 100644 index 0000000..42542a9 --- /dev/null +++ b/components/ui/form/injectionKeys.ts @@ -0,0 +1,4 @@ +import type { InjectionKey } from "vue" + +export const FORM_ITEM_INJECTION_KEY + = Symbol() as InjectionKey diff --git a/components/ui/form/useFormField.ts b/components/ui/form/useFormField.ts new file mode 100644 index 0000000..62d86c2 --- /dev/null +++ b/components/ui/form/useFormField.ts @@ -0,0 +1,30 @@ +import { FieldContextKey } from "vee-validate" +import { computed, inject } from "vue" +import { FORM_ITEM_INJECTION_KEY } from "./injectionKeys" + +export function useFormField() { + const fieldContext = inject(FieldContextKey) + const fieldItemContext = inject(FORM_ITEM_INJECTION_KEY) + + if (!fieldContext) + throw new Error("useFormField should be used within ") + + const { name, errorMessage: error, meta } = fieldContext + const id = fieldItemContext + + const fieldState = { + valid: computed(() => meta.valid), + isDirty: computed(() => meta.dirty), + isTouched: computed(() => meta.touched), + error, + } + + return { + id, + name, + formItemId: `${id}-form-item`, + formDescriptionId: `${id}-form-item-description`, + formMessageId: `${id}-form-item-message`, + ...fieldState, + } +} diff --git a/components/ui/hover-card/HoverCard.vue b/components/ui/hover-card/HoverCard.vue new file mode 100644 index 0000000..4dbcc70 --- /dev/null +++ b/components/ui/hover-card/HoverCard.vue @@ -0,0 +1,15 @@ + + + diff --git a/components/ui/hover-card/HoverCardContent.vue b/components/ui/hover-card/HoverCardContent.vue new file mode 100644 index 0000000..d1cc436 --- /dev/null +++ b/components/ui/hover-card/HoverCardContent.vue @@ -0,0 +1,39 @@ + + + diff --git a/components/ui/hover-card/HoverCardTrigger.vue b/components/ui/hover-card/HoverCardTrigger.vue new file mode 100644 index 0000000..11a5dca --- /dev/null +++ b/components/ui/hover-card/HoverCardTrigger.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/ui/hover-card/index.ts b/components/ui/hover-card/index.ts new file mode 100644 index 0000000..49b2930 --- /dev/null +++ b/components/ui/hover-card/index.ts @@ -0,0 +1,3 @@ +export { default as HoverCard } from "./HoverCard.vue" +export { default as HoverCardContent } from "./HoverCardContent.vue" +export { default as HoverCardTrigger } from "./HoverCardTrigger.vue" diff --git a/components/ui/input-group/InputGroup.vue b/components/ui/input-group/InputGroup.vue new file mode 100644 index 0000000..5cc1e08 --- /dev/null +++ b/components/ui/input-group/InputGroup.vue @@ -0,0 +1,32 @@ + + + diff --git a/components/ui/input-group/InputGroupAddon.vue b/components/ui/input-group/InputGroupAddon.vue new file mode 100644 index 0000000..709f482 --- /dev/null +++ b/components/ui/input-group/InputGroupAddon.vue @@ -0,0 +1,36 @@ + + + diff --git a/components/ui/input-group/InputGroupButton.vue b/components/ui/input-group/InputGroupButton.vue new file mode 100644 index 0000000..4e82e09 --- /dev/null +++ b/components/ui/input-group/InputGroupButton.vue @@ -0,0 +1,21 @@ + + + diff --git a/components/ui/input-group/InputGroupInput.vue b/components/ui/input-group/InputGroupInput.vue new file mode 100644 index 0000000..50a696e --- /dev/null +++ b/components/ui/input-group/InputGroupInput.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/input-group/InputGroupText.vue b/components/ui/input-group/InputGroupText.vue new file mode 100644 index 0000000..e317337 --- /dev/null +++ b/components/ui/input-group/InputGroupText.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/input-group/InputGroupTextarea.vue b/components/ui/input-group/InputGroupTextarea.vue new file mode 100644 index 0000000..2090be2 --- /dev/null +++ b/components/ui/input-group/InputGroupTextarea.vue @@ -0,0 +1,19 @@ + + +