From 9ff4b32db0cda253487ffc9dc70096cbe4b33528 Mon Sep 17 00:00:00 2001 From: Tonya Date: Fri, 11 Apr 2025 11:02:49 +0100 Subject: [PATCH] Switch layouts to use shadcn (#507) * feat: begin switching sonner, currently this breaks all alerts * feat: switch to using new sonner and fix class names * feat: add Shortcut component for improved keyboard shortcuts display in default layout * feat: rewrite quick menu modal in shadcn * feat: update QuickMenu modal placeholders and localize no results message in default layout * feat: begin switching modals in layout to use shadcn dialog, needs bug fixing * feat: implement DialogProvider for consistent dialog management across components * fix: types * feat: begin adding shadcn label selector (wip) * feat: shadcnify textarea * feat: begin adding location selector * feat: add hotkey support for opening create modals in dialog provider components * fix: update click event on NuxtLink and reorder sidebar menu item IDs for consistency * feat: unify shortcut text across create modals and sort issue with text centring * feat: prevent dialog from opening when a dialog alert is open * fix: prevent potential out of bounds error * feat: enhance button group UI in create modals for better layout and introduce new item photo label in the form * fix: search on label selector * chore: lint * fix: oops * feat: make selector usable * feat: add actual data to label selector * feat: label selector kinda works * fix: add legacy selector for edit page * fix: enable camera capture in image upload for CreateModal component * fix: z levels for sidebar mobile * fix: gap between inputs * feat: update radix-vue, custom search function for location selector * feat: add fuzzysort (can always remove it and go to lunr if we want to) * feat: limit label name to 50 characters in create modal and selector, helps with issues with ui not working with larger labels, as it is only enforced on the frontend could be easily bypassed but thats a them problem * feat: add colours to toast * chore: lint * feat: abstract the dialog for creation modals * feat: add drawer component and responsive dialog for create modals * feat: enhance photo preview in CreateModal * fix: remember state of sidebar * feat: add ui functionality for changing primary image * feat: use button for file upload * style: lint * fix: dont clone asset id * fix: using create and add label breaks selector * chore: oops remove logging * chore: lint * fix: cut length of label dramatically to ensure maximal compatibility, not sure if too much * fix: more limiting of label length * feat: update reka-ui (prev radix-vue) * chore: cleanup dialog provider and siebar provider a bit * fix: improve accessibility * fix: docs for shadcn error * fix: hack to prevent issues with lots of toasts in quick succession * feat: cleanup toast file and lint * feat: improvements to dialog scroll and disable the ability to set default photo for now * feat: add tooltips for photo buttons * chore: substring to length check Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/.vitepress/menus/en.mts | 1 + docs/en/contribute/shadcn.md | 4 +- frontend/app.vue | 26 +- frontend/components.json | 2 - frontend/components/App/CreateModal.vue | 43 ++++ frontend/components/App/ImportDialog.vue | 2 +- frontend/components/App/OutdatedModal.vue | 109 ++++++--- frontend/components/App/QuickMenuModal.vue | 81 +++++++ frontend/components/App/Toast.vue | 58 ----- frontend/components/Form/Multiselect.vue | 2 +- frontend/components/Form/Password.vue | 2 +- frontend/components/Form/TextArea.vue | 54 ++--- frontend/components/Form/TextField.vue | 30 ++- frontend/components/Item/CreateModal.vue | 224 +++++++++++------- frontend/components/Label/Chip.vue | 2 +- frontend/components/Label/CreateModal.vue | 74 ++---- frontend/components/Label/Selector.vue | 149 ++++++++++++ frontend/components/Location/CreateModal.vue | 66 ++---- .../components/Location/LegacySelector.vue | 63 +++++ frontend/components/Location/Selector.vue | 115 +++++---- frontend/components/Maintenance/EditModal.vue | 6 +- frontend/components/ModalConfirm.vue | 40 +++- frontend/components/global/LabelMaker.vue | 2 +- .../components/global/QuickMenu/Input.vue | 116 --------- .../components/global/QuickMenu/Modal.vue | 53 ----- .../ui/alert-dialog/AlertDialog.vue | 14 ++ .../ui/alert-dialog/AlertDialogAction.vue | 20 ++ .../ui/alert-dialog/AlertDialogCancel.vue | 27 +++ .../ui/alert-dialog/AlertDialogContent.vue | 42 ++++ .../alert-dialog/AlertDialogDescription.vue | 25 ++ .../ui/alert-dialog/AlertDialogFooter.vue | 21 ++ .../ui/alert-dialog/AlertDialogHeader.vue | 16 ++ .../ui/alert-dialog/AlertDialogTitle.vue | 22 ++ .../ui/alert-dialog/AlertDialogTrigger.vue | 11 + frontend/components/ui/alert-dialog/index.ts | 9 + frontend/components/ui/badge/Badge.vue | 16 ++ frontend/components/ui/badge/index.ts | 25 ++ frontend/components/ui/button/Button.vue | 2 +- frontend/components/ui/button/ButtonGroup.vue | 22 ++ frontend/components/ui/button/index.ts | 1 + frontend/components/ui/command/Command.vue | 30 +++ .../components/ui/command/CommandDialog.vue | 21 ++ .../components/ui/command/CommandEmpty.vue | 20 ++ .../components/ui/command/CommandGroup.vue | 29 +++ .../components/ui/command/CommandInput.vue | 33 +++ .../components/ui/command/CommandItem.vue | 26 ++ .../components/ui/command/CommandList.vue | 25 ++ .../ui/command/CommandSeparator.vue | 23 ++ .../components/ui/command/CommandShortcut.vue | 14 ++ frontend/components/ui/command/index.ts | 9 + .../ui/dialog-provider/DialogProvider.vue | 48 ++++ .../components/ui/dialog-provider/index.ts | 2 + .../components/ui/dialog-provider/utils.ts | 56 +++++ frontend/components/ui/dialog/Dialog.vue | 22 ++ frontend/components/ui/dialog/DialogClose.vue | 11 + .../components/ui/dialog/DialogContent.vue | 50 ++++ .../ui/dialog/DialogDescription.vue | 24 ++ .../components/ui/dialog/DialogFooter.vue | 19 ++ .../components/ui/dialog/DialogHeader.vue | 16 ++ .../ui/dialog/DialogScrollContent.vue | 59 +++++ frontend/components/ui/dialog/DialogTitle.vue | 29 +++ .../components/ui/dialog/DialogTrigger.vue | 11 + frontend/components/ui/dialog/index.ts | 9 + frontend/components/ui/drawer/Drawer.vue | 27 +++ .../components/ui/drawer/DrawerContent.vue | 28 +++ .../ui/drawer/DrawerDescription.vue | 20 ++ .../components/ui/drawer/DrawerFooter.vue | 14 ++ .../components/ui/drawer/DrawerHeader.vue | 14 ++ .../components/ui/drawer/DrawerOverlay.vue | 18 ++ frontend/components/ui/drawer/DrawerTitle.vue | 20 ++ frontend/components/ui/drawer/index.ts | 8 + .../ui/dropdown-menu/DropdownMenu.vue | 2 +- .../DropdownMenuCheckboxItem.vue | 2 +- .../ui/dropdown-menu/DropdownMenuContent.vue | 2 +- .../ui/dropdown-menu/DropdownMenuGroup.vue | 2 +- .../ui/dropdown-menu/DropdownMenuItem.vue | 2 +- .../ui/dropdown-menu/DropdownMenuLabel.vue | 2 +- .../dropdown-menu/DropdownMenuRadioGroup.vue | 2 +- .../dropdown-menu/DropdownMenuRadioItem.vue | 2 +- .../dropdown-menu/DropdownMenuSeparator.vue | 2 +- .../ui/dropdown-menu/DropdownMenuSub.vue | 2 +- .../dropdown-menu/DropdownMenuSubContent.vue | 2 +- .../dropdown-menu/DropdownMenuSubTrigger.vue | 2 +- .../ui/dropdown-menu/DropdownMenuTrigger.vue | 2 +- frontend/components/ui/dropdown-menu/index.ts | 2 +- frontend/components/ui/input/Input.vue | 2 +- frontend/components/ui/label/Label.vue | 27 +++ frontend/components/ui/label/index.ts | 1 + frontend/components/ui/popover/Popover.vue | 15 ++ .../components/ui/popover/PopoverContent.vue | 48 ++++ .../components/ui/popover/PopoverTrigger.vue | 11 + frontend/components/ui/popover/index.ts | 3 + .../components/ui/separator/Separator.vue | 2 +- frontend/components/ui/sheet/Sheet.vue | 2 +- frontend/components/ui/sheet/SheetClose.vue | 2 +- frontend/components/ui/sheet/SheetContent.vue | 4 +- .../components/ui/sheet/SheetDescription.vue | 2 +- frontend/components/ui/sheet/SheetTitle.vue | 2 +- frontend/components/ui/sheet/SheetTrigger.vue | 2 +- frontend/components/ui/shortcut/Shortcut.vue | 35 +++ frontend/components/ui/shortcut/index.ts | 1 + frontend/components/ui/sidebar/Sidebar.vue | 2 +- .../ui/sidebar/SidebarGroupAction.vue | 4 +- .../ui/sidebar/SidebarGroupLabel.vue | 4 +- .../ui/sidebar/SidebarMenuAction.vue | 2 +- .../ui/sidebar/SidebarMenuButtonChild.vue | 2 +- .../components/ui/sidebar/SidebarMenuLink.vue | 2 +- .../ui/sidebar/SidebarMenuSubButton.vue | 4 +- .../components/ui/sidebar/SidebarProvider.vue | 2 +- frontend/components/ui/sidebar/utils.ts | 2 +- frontend/components/ui/sonner/Sonner.vue | 25 ++ frontend/components/ui/sonner/index.ts | 2 + frontend/components/ui/sonner/toast.ts | 20 ++ .../components/ui/tags-input/TagsInput.vue | 22 ++ .../ui/tags-input/TagsInputInput.vue | 19 ++ .../ui/tags-input/TagsInputItem.vue | 22 ++ .../ui/tags-input/TagsInputItemDelete.vue | 24 ++ .../ui/tags-input/TagsInputItemText.vue | 19 ++ frontend/components/ui/tags-input/index.ts | 5 + frontend/components/ui/textarea/Textarea.vue | 30 +++ frontend/components/ui/textarea/index.ts | 1 + frontend/components/ui/tooltip/Tooltip.vue | 2 +- .../components/ui/tooltip/TooltipContent.vue | 2 +- .../components/ui/tooltip/TooltipProvider.vue | 2 +- .../components/ui/tooltip/TooltipTrigger.vue | 2 +- frontend/composables/use-ids.ts | 29 --- frontend/composables/use-notifier.ts | 55 ----- frontend/layouts/default.vue | 163 ++++--------- frontend/layouts/empty.vue | 2 +- frontend/locales/en.json | 15 +- frontend/package.json | 7 +- frontend/pages/assets/[id].vue | 3 +- frontend/pages/index.vue | 2 +- frontend/pages/item/[id]/index.vue | 2 +- frontend/pages/item/[id]/index/edit.vue | 10 +- frontend/pages/items.vue | 12 +- frontend/pages/label/[id].vue | 4 +- frontend/pages/location/[id].vue | 4 +- frontend/pages/profile.vue | 35 +-- frontend/pages/reports/label-generator.vue | 5 +- frontend/pages/testing.vue | 38 ++- frontend/pages/tools.vue | 18 +- frontend/pnpm-lock.yaml | 106 ++++++--- frontend/tailwind.config.js | 8 +- 144 files changed, 2375 insertions(+), 883 deletions(-) create mode 100644 frontend/components/App/CreateModal.vue create mode 100644 frontend/components/App/QuickMenuModal.vue delete mode 100644 frontend/components/App/Toast.vue create mode 100644 frontend/components/Label/Selector.vue create mode 100644 frontend/components/Location/LegacySelector.vue delete mode 100644 frontend/components/global/QuickMenu/Input.vue delete mode 100644 frontend/components/global/QuickMenu/Modal.vue create mode 100644 frontend/components/ui/alert-dialog/AlertDialog.vue create mode 100644 frontend/components/ui/alert-dialog/AlertDialogAction.vue create mode 100644 frontend/components/ui/alert-dialog/AlertDialogCancel.vue create mode 100644 frontend/components/ui/alert-dialog/AlertDialogContent.vue create mode 100644 frontend/components/ui/alert-dialog/AlertDialogDescription.vue create mode 100644 frontend/components/ui/alert-dialog/AlertDialogFooter.vue create mode 100644 frontend/components/ui/alert-dialog/AlertDialogHeader.vue create mode 100644 frontend/components/ui/alert-dialog/AlertDialogTitle.vue create mode 100644 frontend/components/ui/alert-dialog/AlertDialogTrigger.vue create mode 100644 frontend/components/ui/alert-dialog/index.ts create mode 100644 frontend/components/ui/badge/Badge.vue create mode 100644 frontend/components/ui/badge/index.ts create mode 100644 frontend/components/ui/button/ButtonGroup.vue create mode 100644 frontend/components/ui/command/Command.vue create mode 100644 frontend/components/ui/command/CommandDialog.vue create mode 100644 frontend/components/ui/command/CommandEmpty.vue create mode 100644 frontend/components/ui/command/CommandGroup.vue create mode 100644 frontend/components/ui/command/CommandInput.vue create mode 100644 frontend/components/ui/command/CommandItem.vue create mode 100644 frontend/components/ui/command/CommandList.vue create mode 100644 frontend/components/ui/command/CommandSeparator.vue create mode 100644 frontend/components/ui/command/CommandShortcut.vue create mode 100644 frontend/components/ui/command/index.ts create mode 100644 frontend/components/ui/dialog-provider/DialogProvider.vue create mode 100644 frontend/components/ui/dialog-provider/index.ts create mode 100644 frontend/components/ui/dialog-provider/utils.ts create mode 100644 frontend/components/ui/dialog/Dialog.vue create mode 100644 frontend/components/ui/dialog/DialogClose.vue create mode 100644 frontend/components/ui/dialog/DialogContent.vue create mode 100644 frontend/components/ui/dialog/DialogDescription.vue create mode 100644 frontend/components/ui/dialog/DialogFooter.vue create mode 100644 frontend/components/ui/dialog/DialogHeader.vue create mode 100644 frontend/components/ui/dialog/DialogScrollContent.vue create mode 100644 frontend/components/ui/dialog/DialogTitle.vue create mode 100644 frontend/components/ui/dialog/DialogTrigger.vue create mode 100644 frontend/components/ui/dialog/index.ts create mode 100644 frontend/components/ui/drawer/Drawer.vue create mode 100644 frontend/components/ui/drawer/DrawerContent.vue create mode 100644 frontend/components/ui/drawer/DrawerDescription.vue create mode 100644 frontend/components/ui/drawer/DrawerFooter.vue create mode 100644 frontend/components/ui/drawer/DrawerHeader.vue create mode 100644 frontend/components/ui/drawer/DrawerOverlay.vue create mode 100644 frontend/components/ui/drawer/DrawerTitle.vue create mode 100644 frontend/components/ui/drawer/index.ts create mode 100644 frontend/components/ui/label/Label.vue create mode 100644 frontend/components/ui/label/index.ts create mode 100644 frontend/components/ui/popover/Popover.vue create mode 100644 frontend/components/ui/popover/PopoverContent.vue create mode 100644 frontend/components/ui/popover/PopoverTrigger.vue create mode 100644 frontend/components/ui/popover/index.ts create mode 100644 frontend/components/ui/shortcut/Shortcut.vue create mode 100644 frontend/components/ui/shortcut/index.ts create mode 100644 frontend/components/ui/sonner/Sonner.vue create mode 100644 frontend/components/ui/sonner/index.ts create mode 100644 frontend/components/ui/sonner/toast.ts create mode 100644 frontend/components/ui/tags-input/TagsInput.vue create mode 100644 frontend/components/ui/tags-input/TagsInputInput.vue create mode 100644 frontend/components/ui/tags-input/TagsInputItem.vue create mode 100644 frontend/components/ui/tags-input/TagsInputItemDelete.vue create mode 100644 frontend/components/ui/tags-input/TagsInputItemText.vue create mode 100644 frontend/components/ui/tags-input/index.ts create mode 100644 frontend/components/ui/textarea/Textarea.vue create mode 100644 frontend/components/ui/textarea/index.ts delete mode 100755 frontend/composables/use-ids.ts delete mode 100644 frontend/composables/use-notifier.ts diff --git a/docs/.vitepress/menus/en.mts b/docs/.vitepress/menus/en.mts index 31b511ff..89ced4f3 100644 --- a/docs/.vitepress/menus/en.mts +++ b/docs/.vitepress/menus/en.mts @@ -26,6 +26,7 @@ export default [ text: 'Contributing', items: [ {text: 'Get Started', link: '/en/contribute/get-started'}, + {text: 'Switching to Shadcn-vue', link: '/en/contribute/shadcn'}, {text: 'Bounty Program', link: '/en/contribute/bounty'} ] }, diff --git a/docs/en/contribute/shadcn.md b/docs/en/contribute/shadcn.md index 5ffc25cd..77154d07 100644 --- a/docs/en/contribute/shadcn.md +++ b/docs/en/contribute/shadcn.md @@ -52,9 +52,9 @@ When modifying components, follow these best practices: During the migration process, you can test without DaisyUI using these commands: ```bash -DISABLE_DAISYUI=true; task ui:dev +export DISABLE_DAISYUI=true; task ui:dev ``` or ```bash -DISABLE_DAISYUI=true; task ui:fix +export DISABLE_DAISYUI=true; task ui:fix ``` diff --git a/frontend/app.vue b/frontend/app.vue index f6b0ade6..ba159df7 100644 --- a/frontend/app.vue +++ b/frontend/app.vue @@ -1,17 +1,25 @@ diff --git a/frontend/components/App/ImportDialog.vue b/frontend/components/App/ImportDialog.vue index 48276f28..e553f77d 100644 --- a/frontend/components/App/ImportDialog.vue +++ b/frontend/components/App/ImportDialog.vue @@ -46,6 +46,7 @@ diff --git a/frontend/components/App/QuickMenuModal.vue b/frontend/components/App/QuickMenuModal.vue new file mode 100644 index 00000000..8ecddfa3 --- /dev/null +++ b/frontend/components/App/QuickMenuModal.vue @@ -0,0 +1,81 @@ + + + diff --git a/frontend/components/App/Toast.vue b/frontend/components/App/Toast.vue deleted file mode 100644 index 014488db..00000000 --- a/frontend/components/App/Toast.vue +++ /dev/null @@ -1,58 +0,0 @@ - - - - - diff --git a/frontend/components/Form/Multiselect.vue b/frontend/components/Form/Multiselect.vue index c0ed6083..a822b43a 100644 --- a/frontend/components/Form/Multiselect.vue +++ b/frontend/components/Form/Multiselect.vue @@ -47,6 +47,7 @@ diff --git a/frontend/components/Form/TextField.vue b/frontend/components/Form/TextField.vue index 7e63a215..fe003195 100644 --- a/frontend/components/Form/TextField.vue +++ b/frontend/components/Form/TextField.vue @@ -1,7 +1,8 @@ diff --git a/frontend/components/Location/CreateModal.vue b/frontend/components/Location/CreateModal.vue index 3363c50f..0d075907 100644 --- a/frontend/components/Location/CreateModal.vue +++ b/frontend/components/Location/CreateModal.vue @@ -1,7 +1,6 @@ diff --git a/frontend/components/Location/Selector.vue b/frontend/components/Location/Selector.vue index bbb4997d..bd22ebf4 100644 --- a/frontend/components/Location/Selector.vue +++ b/frontend/components/Location/Selector.vue @@ -1,62 +1,95 @@ - diff --git a/frontend/components/global/LabelMaker.vue b/frontend/components/global/LabelMaker.vue index 8e29b6dc..bc40c3dd 100644 --- a/frontend/components/global/LabelMaker.vue +++ b/frontend/components/global/LabelMaker.vue @@ -1,5 +1,6 @@ diff --git a/frontend/components/global/QuickMenu/Modal.vue b/frontend/components/global/QuickMenu/Modal.vue deleted file mode 100644 index 84eb8838..00000000 --- a/frontend/components/global/QuickMenu/Modal.vue +++ /dev/null @@ -1,53 +0,0 @@ - - - diff --git a/frontend/components/ui/alert-dialog/AlertDialog.vue b/frontend/components/ui/alert-dialog/AlertDialog.vue new file mode 100644 index 00000000..035b4881 --- /dev/null +++ b/frontend/components/ui/alert-dialog/AlertDialog.vue @@ -0,0 +1,14 @@ + + + diff --git a/frontend/components/ui/alert-dialog/AlertDialogAction.vue b/frontend/components/ui/alert-dialog/AlertDialogAction.vue new file mode 100644 index 00000000..722c4fcf --- /dev/null +++ b/frontend/components/ui/alert-dialog/AlertDialogAction.vue @@ -0,0 +1,20 @@ + + + diff --git a/frontend/components/ui/alert-dialog/AlertDialogCancel.vue b/frontend/components/ui/alert-dialog/AlertDialogCancel.vue new file mode 100644 index 00000000..7ec5b6b2 --- /dev/null +++ b/frontend/components/ui/alert-dialog/AlertDialogCancel.vue @@ -0,0 +1,27 @@ + + + diff --git a/frontend/components/ui/alert-dialog/AlertDialogContent.vue b/frontend/components/ui/alert-dialog/AlertDialogContent.vue new file mode 100644 index 00000000..30ff8f45 --- /dev/null +++ b/frontend/components/ui/alert-dialog/AlertDialogContent.vue @@ -0,0 +1,42 @@ + + + diff --git a/frontend/components/ui/alert-dialog/AlertDialogDescription.vue b/frontend/components/ui/alert-dialog/AlertDialogDescription.vue new file mode 100644 index 00000000..4577a4d0 --- /dev/null +++ b/frontend/components/ui/alert-dialog/AlertDialogDescription.vue @@ -0,0 +1,25 @@ + + + diff --git a/frontend/components/ui/alert-dialog/AlertDialogFooter.vue b/frontend/components/ui/alert-dialog/AlertDialogFooter.vue new file mode 100644 index 00000000..55d0a0eb --- /dev/null +++ b/frontend/components/ui/alert-dialog/AlertDialogFooter.vue @@ -0,0 +1,21 @@ + + + diff --git a/frontend/components/ui/alert-dialog/AlertDialogHeader.vue b/frontend/components/ui/alert-dialog/AlertDialogHeader.vue new file mode 100644 index 00000000..c61c4495 --- /dev/null +++ b/frontend/components/ui/alert-dialog/AlertDialogHeader.vue @@ -0,0 +1,16 @@ + + + diff --git a/frontend/components/ui/alert-dialog/AlertDialogTitle.vue b/frontend/components/ui/alert-dialog/AlertDialogTitle.vue new file mode 100644 index 00000000..fd17cd52 --- /dev/null +++ b/frontend/components/ui/alert-dialog/AlertDialogTitle.vue @@ -0,0 +1,22 @@ + + + diff --git a/frontend/components/ui/alert-dialog/AlertDialogTrigger.vue b/frontend/components/ui/alert-dialog/AlertDialogTrigger.vue new file mode 100644 index 00000000..aabd777e --- /dev/null +++ b/frontend/components/ui/alert-dialog/AlertDialogTrigger.vue @@ -0,0 +1,11 @@ + + + diff --git a/frontend/components/ui/alert-dialog/index.ts b/frontend/components/ui/alert-dialog/index.ts new file mode 100644 index 00000000..448d5198 --- /dev/null +++ b/frontend/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/frontend/components/ui/badge/Badge.vue b/frontend/components/ui/badge/Badge.vue new file mode 100644 index 00000000..9ed80393 --- /dev/null +++ b/frontend/components/ui/badge/Badge.vue @@ -0,0 +1,16 @@ + + + diff --git a/frontend/components/ui/badge/index.ts b/frontend/components/ui/badge/index.ts new file mode 100644 index 00000000..35e7a1a0 --- /dev/null +++ b/frontend/components/ui/badge/index.ts @@ -0,0 +1,25 @@ +import { cva, type VariantProps } from 'class-variance-authority' + +export { default as Badge } from './Badge.vue' + +export const badgeVariants = cva( + 'inline-flex 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/frontend/components/ui/button/Button.vue b/frontend/components/ui/button/Button.vue index 19c44c15..b330368b 100644 --- a/frontend/components/ui/button/Button.vue +++ b/frontend/components/ui/button/Button.vue @@ -1,6 +1,6 @@ + + diff --git a/frontend/components/ui/button/index.ts b/frontend/components/ui/button/index.ts index 417aeb03..14ee433e 100644 --- a/frontend/components/ui/button/index.ts +++ b/frontend/components/ui/button/index.ts @@ -1,6 +1,7 @@ import { cva, type VariantProps } from "class-variance-authority"; export { default as Button } from "./Button.vue"; +export { default as ButtonGroup } from "./ButtonGroup.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", diff --git a/frontend/components/ui/command/Command.vue b/frontend/components/ui/command/Command.vue new file mode 100644 index 00000000..467ae019 --- /dev/null +++ b/frontend/components/ui/command/Command.vue @@ -0,0 +1,30 @@ + + + diff --git a/frontend/components/ui/command/CommandDialog.vue b/frontend/components/ui/command/CommandDialog.vue new file mode 100644 index 00000000..825774ec --- /dev/null +++ b/frontend/components/ui/command/CommandDialog.vue @@ -0,0 +1,21 @@ + + + diff --git a/frontend/components/ui/command/CommandEmpty.vue b/frontend/components/ui/command/CommandEmpty.vue new file mode 100644 index 00000000..1908f93c --- /dev/null +++ b/frontend/components/ui/command/CommandEmpty.vue @@ -0,0 +1,20 @@ + + + diff --git a/frontend/components/ui/command/CommandGroup.vue b/frontend/components/ui/command/CommandGroup.vue new file mode 100644 index 00000000..683bf592 --- /dev/null +++ b/frontend/components/ui/command/CommandGroup.vue @@ -0,0 +1,29 @@ + + + diff --git a/frontend/components/ui/command/CommandInput.vue b/frontend/components/ui/command/CommandInput.vue new file mode 100644 index 00000000..2713203f --- /dev/null +++ b/frontend/components/ui/command/CommandInput.vue @@ -0,0 +1,33 @@ + + + diff --git a/frontend/components/ui/command/CommandItem.vue b/frontend/components/ui/command/CommandItem.vue new file mode 100644 index 00000000..dd5a872d --- /dev/null +++ b/frontend/components/ui/command/CommandItem.vue @@ -0,0 +1,26 @@ + + + diff --git a/frontend/components/ui/command/CommandList.vue b/frontend/components/ui/command/CommandList.vue new file mode 100644 index 00000000..9106b444 --- /dev/null +++ b/frontend/components/ui/command/CommandList.vue @@ -0,0 +1,25 @@ + + + diff --git a/frontend/components/ui/command/CommandSeparator.vue b/frontend/components/ui/command/CommandSeparator.vue new file mode 100644 index 00000000..cc5f0550 --- /dev/null +++ b/frontend/components/ui/command/CommandSeparator.vue @@ -0,0 +1,23 @@ + + + diff --git a/frontend/components/ui/command/CommandShortcut.vue b/frontend/components/ui/command/CommandShortcut.vue new file mode 100644 index 00000000..0d4da921 --- /dev/null +++ b/frontend/components/ui/command/CommandShortcut.vue @@ -0,0 +1,14 @@ + + + diff --git a/frontend/components/ui/command/index.ts b/frontend/components/ui/command/index.ts new file mode 100644 index 00000000..0e35f4b9 --- /dev/null +++ b/frontend/components/ui/command/index.ts @@ -0,0 +1,9 @@ +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' diff --git a/frontend/components/ui/dialog-provider/DialogProvider.vue b/frontend/components/ui/dialog-provider/DialogProvider.vue new file mode 100644 index 00000000..c7513012 --- /dev/null +++ b/frontend/components/ui/dialog-provider/DialogProvider.vue @@ -0,0 +1,48 @@ + + + + diff --git a/frontend/components/ui/dialog-provider/index.ts b/frontend/components/ui/dialog-provider/index.ts new file mode 100644 index 00000000..cc9f4adb --- /dev/null +++ b/frontend/components/ui/dialog-provider/index.ts @@ -0,0 +1,2 @@ +export { useDialog, useDialogHotkey } from "./utils"; +export { default as DialogProvider } from "./DialogProvider.vue"; diff --git a/frontend/components/ui/dialog-provider/utils.ts b/frontend/components/ui/dialog-provider/utils.ts new file mode 100644 index 00000000..3309ddb2 --- /dev/null +++ b/frontend/components/ui/dialog-provider/utils.ts @@ -0,0 +1,56 @@ +import type { ComputedRef } from "vue"; +import { createContext } from "reka-ui"; +import { useMagicKeys, useActiveElement } from "@vueuse/core"; + +export const [useDialog, provideDialogContext] = createContext<{ + activeDialog: ComputedRef; + activeAlerts: ComputedRef; + openDialog: (dialogId: string) => void; + closeDialog: (dialogId?: string) => void; + addAlert: (alertId: string) => void; + removeAlert: (alertId: string) => void; +}>("DialogProvider"); + +export const useDialogHotkey = ( + dialogId: string, + key: { + shift?: boolean; + ctrl?: boolean; + code: string; + } +) => { + const { openDialog } = useDialog(); + + const activeElement = useActiveElement(); + + const notUsingInput = computed( + () => activeElement.value?.tagName !== "INPUT" && activeElement.value?.tagName !== "TEXTAREA" + ); + + useMagicKeys({ + passive: false, + onEventFired: event => { + // console.log({ + // event, + // notUsingInput: notUsingInput.value, + // eventType: event.type, + // keyCode: event.code, + // matchingKeyCode: key.code === event.code, + // shift: event.shiftKey, + // matchingShift: key.shift === undefined || event.shiftKey === key.shift, + // ctrl: event.ctrlKey, + // matchingCtrl: key.ctrl === undefined || event.ctrlKey === key.ctrl, + // }); + if ( + notUsingInput.value && + event.type === "keydown" && + event.code === key.code && + (key.shift === undefined || event.shiftKey === key.shift) && + (key.ctrl === undefined || event.ctrlKey === key.ctrl) + ) { + openDialog(dialogId); + event.preventDefault(); + } + }, + }); +}; diff --git a/frontend/components/ui/dialog/Dialog.vue b/frontend/components/ui/dialog/Dialog.vue new file mode 100644 index 00000000..a174bd05 --- /dev/null +++ b/frontend/components/ui/dialog/Dialog.vue @@ -0,0 +1,22 @@ + + + diff --git a/frontend/components/ui/dialog/DialogClose.vue b/frontend/components/ui/dialog/DialogClose.vue new file mode 100644 index 00000000..ba036b51 --- /dev/null +++ b/frontend/components/ui/dialog/DialogClose.vue @@ -0,0 +1,11 @@ + + + diff --git a/frontend/components/ui/dialog/DialogContent.vue b/frontend/components/ui/dialog/DialogContent.vue new file mode 100644 index 00000000..be00c5e6 --- /dev/null +++ b/frontend/components/ui/dialog/DialogContent.vue @@ -0,0 +1,50 @@ + + + diff --git a/frontend/components/ui/dialog/DialogDescription.vue b/frontend/components/ui/dialog/DialogDescription.vue new file mode 100644 index 00000000..5afbab04 --- /dev/null +++ b/frontend/components/ui/dialog/DialogDescription.vue @@ -0,0 +1,24 @@ + + + diff --git a/frontend/components/ui/dialog/DialogFooter.vue b/frontend/components/ui/dialog/DialogFooter.vue new file mode 100644 index 00000000..ac2d0c18 --- /dev/null +++ b/frontend/components/ui/dialog/DialogFooter.vue @@ -0,0 +1,19 @@ + + + diff --git a/frontend/components/ui/dialog/DialogHeader.vue b/frontend/components/ui/dialog/DialogHeader.vue new file mode 100644 index 00000000..b2c9085d --- /dev/null +++ b/frontend/components/ui/dialog/DialogHeader.vue @@ -0,0 +1,16 @@ + + + diff --git a/frontend/components/ui/dialog/DialogScrollContent.vue b/frontend/components/ui/dialog/DialogScrollContent.vue new file mode 100644 index 00000000..c1caf2be --- /dev/null +++ b/frontend/components/ui/dialog/DialogScrollContent.vue @@ -0,0 +1,59 @@ + + + diff --git a/frontend/components/ui/dialog/DialogTitle.vue b/frontend/components/ui/dialog/DialogTitle.vue new file mode 100644 index 00000000..30cbb368 --- /dev/null +++ b/frontend/components/ui/dialog/DialogTitle.vue @@ -0,0 +1,29 @@ + + + diff --git a/frontend/components/ui/dialog/DialogTrigger.vue b/frontend/components/ui/dialog/DialogTrigger.vue new file mode 100644 index 00000000..2984f371 --- /dev/null +++ b/frontend/components/ui/dialog/DialogTrigger.vue @@ -0,0 +1,11 @@ + + + diff --git a/frontend/components/ui/dialog/index.ts b/frontend/components/ui/dialog/index.ts new file mode 100644 index 00000000..ca8cfeae --- /dev/null +++ b/frontend/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/frontend/components/ui/drawer/Drawer.vue b/frontend/components/ui/drawer/Drawer.vue new file mode 100644 index 00000000..a30a01e6 --- /dev/null +++ b/frontend/components/ui/drawer/Drawer.vue @@ -0,0 +1,27 @@ + + + diff --git a/frontend/components/ui/drawer/DrawerContent.vue b/frontend/components/ui/drawer/DrawerContent.vue new file mode 100644 index 00000000..618df111 --- /dev/null +++ b/frontend/components/ui/drawer/DrawerContent.vue @@ -0,0 +1,28 @@ + + + diff --git a/frontend/components/ui/drawer/DrawerDescription.vue b/frontend/components/ui/drawer/DrawerDescription.vue new file mode 100644 index 00000000..092dc503 --- /dev/null +++ b/frontend/components/ui/drawer/DrawerDescription.vue @@ -0,0 +1,20 @@ + + + diff --git a/frontend/components/ui/drawer/DrawerFooter.vue b/frontend/components/ui/drawer/DrawerFooter.vue new file mode 100644 index 00000000..1eb35278 --- /dev/null +++ b/frontend/components/ui/drawer/DrawerFooter.vue @@ -0,0 +1,14 @@ + + + diff --git a/frontend/components/ui/drawer/DrawerHeader.vue b/frontend/components/ui/drawer/DrawerHeader.vue new file mode 100644 index 00000000..ecef7a67 --- /dev/null +++ b/frontend/components/ui/drawer/DrawerHeader.vue @@ -0,0 +1,14 @@ + + + diff --git a/frontend/components/ui/drawer/DrawerOverlay.vue b/frontend/components/ui/drawer/DrawerOverlay.vue new file mode 100644 index 00000000..f9307b71 --- /dev/null +++ b/frontend/components/ui/drawer/DrawerOverlay.vue @@ -0,0 +1,18 @@ + + + diff --git a/frontend/components/ui/drawer/DrawerTitle.vue b/frontend/components/ui/drawer/DrawerTitle.vue new file mode 100644 index 00000000..475c3ab4 --- /dev/null +++ b/frontend/components/ui/drawer/DrawerTitle.vue @@ -0,0 +1,20 @@ + + + diff --git a/frontend/components/ui/drawer/index.ts b/frontend/components/ui/drawer/index.ts new file mode 100644 index 00000000..d41b7928 --- /dev/null +++ b/frontend/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/frontend/components/ui/dropdown-menu/DropdownMenu.vue b/frontend/components/ui/dropdown-menu/DropdownMenu.vue index 3e142aaf..f9adc74b 100644 --- a/frontend/components/ui/dropdown-menu/DropdownMenu.vue +++ b/frontend/components/ui/dropdown-menu/DropdownMenu.vue @@ -4,7 +4,7 @@ type DropdownMenuRootEmits, type DropdownMenuRootProps, useForwardPropsEmits, - } from "radix-vue"; + } from "reka-ui"; const props = defineProps(); const emits = defineEmits(); diff --git a/frontend/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue b/frontend/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue index d992ec1f..dad68f98 100644 --- a/frontend/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +++ b/frontend/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue @@ -6,7 +6,7 @@ type DropdownMenuCheckboxItemProps, DropdownMenuItemIndicator, useForwardPropsEmits, - } from "radix-vue"; + } from "reka-ui"; import { computed, type HTMLAttributes } from "vue"; import { cn } from "@/lib/utils"; diff --git a/frontend/components/ui/dropdown-menu/DropdownMenuContent.vue b/frontend/components/ui/dropdown-menu/DropdownMenuContent.vue index d7006d0e..c99785c9 100644 --- a/frontend/components/ui/dropdown-menu/DropdownMenuContent.vue +++ b/frontend/components/ui/dropdown-menu/DropdownMenuContent.vue @@ -5,7 +5,7 @@ type DropdownMenuContentProps, DropdownMenuPortal, useForwardPropsEmits, - } from "radix-vue"; + } from "reka-ui"; import { computed, type HTMLAttributes } from "vue"; import { cn } from "@/lib/utils"; diff --git a/frontend/components/ui/dropdown-menu/DropdownMenuGroup.vue b/frontend/components/ui/dropdown-menu/DropdownMenuGroup.vue index 84f14944..7c1f0df3 100644 --- a/frontend/components/ui/dropdown-menu/DropdownMenuGroup.vue +++ b/frontend/components/ui/dropdown-menu/DropdownMenuGroup.vue @@ -1,5 +1,5 @@ diff --git a/frontend/components/ui/dropdown-menu/DropdownMenuItem.vue b/frontend/components/ui/dropdown-menu/DropdownMenuItem.vue index 20d29de9..28c60bc4 100644 --- a/frontend/components/ui/dropdown-menu/DropdownMenuItem.vue +++ b/frontend/components/ui/dropdown-menu/DropdownMenuItem.vue @@ -1,5 +1,5 @@ + + diff --git a/frontend/components/ui/label/index.ts b/frontend/components/ui/label/index.ts new file mode 100644 index 00000000..572c2f01 --- /dev/null +++ b/frontend/components/ui/label/index.ts @@ -0,0 +1 @@ +export { default as Label } from './Label.vue' diff --git a/frontend/components/ui/popover/Popover.vue b/frontend/components/ui/popover/Popover.vue new file mode 100644 index 00000000..72e0b5fa --- /dev/null +++ b/frontend/components/ui/popover/Popover.vue @@ -0,0 +1,15 @@ + + + diff --git a/frontend/components/ui/popover/PopoverContent.vue b/frontend/components/ui/popover/PopoverContent.vue new file mode 100644 index 00000000..9e6c2882 --- /dev/null +++ b/frontend/components/ui/popover/PopoverContent.vue @@ -0,0 +1,48 @@ + + + diff --git a/frontend/components/ui/popover/PopoverTrigger.vue b/frontend/components/ui/popover/PopoverTrigger.vue new file mode 100644 index 00000000..ac265950 --- /dev/null +++ b/frontend/components/ui/popover/PopoverTrigger.vue @@ -0,0 +1,11 @@ + + + diff --git a/frontend/components/ui/popover/index.ts b/frontend/components/ui/popover/index.ts new file mode 100644 index 00000000..c621f9b1 --- /dev/null +++ b/frontend/components/ui/popover/index.ts @@ -0,0 +1,3 @@ +export { default as Popover } from './Popover.vue' +export { default as PopoverContent } from './PopoverContent.vue' +export { default as PopoverTrigger } from './PopoverTrigger.vue' diff --git a/frontend/components/ui/separator/Separator.vue b/frontend/components/ui/separator/Separator.vue index 62fd094e..0fc01413 100644 --- a/frontend/components/ui/separator/Separator.vue +++ b/frontend/components/ui/separator/Separator.vue @@ -1,5 +1,5 @@ diff --git a/frontend/components/ui/sheet/SheetContent.vue b/frontend/components/ui/sheet/SheetContent.vue index 74314684..5ee4992b 100644 --- a/frontend/components/ui/sheet/SheetContent.vue +++ b/frontend/components/ui/sheet/SheetContent.vue @@ -8,7 +8,7 @@ DialogOverlay, DialogPortal, useForwardPropsEmits, - } from "radix-vue"; + } from "reka-ui"; import { computed, type HTMLAttributes } from "vue"; import { type SheetVariants, sheetVariants } from "."; import { cn } from "@/lib/utils"; @@ -38,7 +38,7 @@