diff --git a/app.vue b/app.vue index 2d82e7a..5f2f87d 100644 --- a/app.vue +++ b/app.vue @@ -1,6 +1,7 @@ diff --git a/bun.lock b/bun.lock index 0f3e791..8ece64c 100644 --- a/bun.lock +++ b/bun.lock @@ -10,6 +10,7 @@ "@nuxt/image": "1.10.0", "@nuxt/test-utils": "3.19.2", "@tailwindcss/vite": "^4.1.11", + "@vueuse/core": "^13.5.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "eslint": "^9.0.0", @@ -561,11 +562,11 @@ "@vue/shared": ["@vue/shared@3.5.17", "", {}, "sha512-CabR+UN630VnsJO/jHWYBC1YVXyMq94KKp6iF5MQgZJs5I8cmjw6oVMO1oDbtBkENSHSSn/UadWlW/OAgdmKrg=="], - "@vueuse/core": ["@vueuse/core@12.8.2", "", { "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "12.8.2", "@vueuse/shared": "12.8.2", "vue": "^3.5.13" } }, "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ=="], + "@vueuse/core": ["@vueuse/core@13.5.0", "", { "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "13.5.0", "@vueuse/shared": "13.5.0" }, "peerDependencies": { "vue": "^3.5.0" } }, "sha512-wV7z0eUpifKmvmN78UBZX8T7lMW53Nrk6JP5+6hbzrB9+cJ3jr//hUlhl9TZO/03bUkMK6gGkQpqOPWoabr72g=="], - "@vueuse/metadata": ["@vueuse/metadata@12.8.2", "", {}, "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A=="], + "@vueuse/metadata": ["@vueuse/metadata@13.5.0", "", {}, "sha512-euhItU3b0SqXxSy8u1XHxUCdQ8M++bsRs+TYhOLDU/OykS7KvJnyIFfep0XM5WjIFry9uAPlVSjmVHiqeshmkw=="], - "@vueuse/shared": ["@vueuse/shared@12.8.2", "", { "dependencies": { "vue": "^3.5.13" } }, "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w=="], + "@vueuse/shared": ["@vueuse/shared@13.5.0", "", { "peerDependencies": { "vue": "^3.5.0" } }, "sha512-K7GrQIxJ/ANtucxIXbQlUHdB0TPA8c+q5i+zbrjxuhJCnJ9GtBg75sBSnvmLSxHKPg2Yo8w62PWksl9kwH0Q8g=="], "@whatwg-node/disposablestack": ["@whatwg-node/disposablestack@0.0.6", "", { "dependencies": { "@whatwg-node/promise-helpers": "^1.0.0", "tslib": "^2.6.3" } }, "sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw=="], @@ -2145,6 +2146,10 @@ "regjsparser/jsesc": ["jsesc@3.0.2", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g=="], + "reka-ui/@vueuse/core": ["@vueuse/core@12.8.2", "", { "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "12.8.2", "@vueuse/shared": "12.8.2", "vue": "^3.5.13" } }, "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ=="], + + "reka-ui/@vueuse/shared": ["@vueuse/shared@12.8.2", "", { "dependencies": { "vue": "^3.5.13" } }, "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w=="], + "rollup-plugin-visualizer/open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="], "shadcn-nuxt/oxc-parser": ["oxc-parser@0.72.3", "", { "dependencies": { "@oxc-project/types": "^0.72.3" }, "optionalDependencies": { "@oxc-parser/binding-darwin-arm64": "0.72.3", "@oxc-parser/binding-darwin-x64": "0.72.3", "@oxc-parser/binding-freebsd-x64": "0.72.3", "@oxc-parser/binding-linux-arm-gnueabihf": "0.72.3", "@oxc-parser/binding-linux-arm-musleabihf": "0.72.3", "@oxc-parser/binding-linux-arm64-gnu": "0.72.3", "@oxc-parser/binding-linux-arm64-musl": "0.72.3", "@oxc-parser/binding-linux-riscv64-gnu": "0.72.3", "@oxc-parser/binding-linux-s390x-gnu": "0.72.3", "@oxc-parser/binding-linux-x64-gnu": "0.72.3", "@oxc-parser/binding-linux-x64-musl": "0.72.3", "@oxc-parser/binding-wasm32-wasi": "0.72.3", "@oxc-parser/binding-win32-arm64-msvc": "0.72.3", "@oxc-parser/binding-win32-x64-msvc": "0.72.3" } }, "sha512-JYQeJKDcUTTZ/uTdJ+fZBGFjAjkLD1h0p3Tf44ZYXRcoMk+57d81paNPFAAwzrzzqhZmkGvKKXDxwyhJXYZlpg=="], @@ -2313,6 +2318,8 @@ "readdir-glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + "reka-ui/@vueuse/core/@vueuse/metadata": ["@vueuse/metadata@12.8.2", "", {}, "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A=="], + "rollup-plugin-visualizer/open/define-lazy-prop": ["define-lazy-prop@2.0.0", "", {}, "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og=="], "rollup-plugin-visualizer/open/is-docker": ["is-docker@2.2.1", "", { "bin": { "is-docker": "cli.js" } }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="], diff --git a/components/AppSidebar.vue b/components/AppSidebar.vue new file mode 100644 index 0000000..415ab7c --- /dev/null +++ b/components/AppSidebar.vue @@ -0,0 +1,43 @@ + + + diff --git a/components/ui/breadcrumb/Breadcrumb.vue b/components/ui/breadcrumb/Breadcrumb.vue new file mode 100644 index 0000000..b99dcea --- /dev/null +++ b/components/ui/breadcrumb/Breadcrumb.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbEllipsis.vue b/components/ui/breadcrumb/BreadcrumbEllipsis.vue new file mode 100644 index 0000000..b147851 --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbEllipsis.vue @@ -0,0 +1,23 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbItem.vue b/components/ui/breadcrumb/BreadcrumbItem.vue new file mode 100644 index 0000000..f50f69d --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbItem.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbLink.vue b/components/ui/breadcrumb/BreadcrumbLink.vue new file mode 100644 index 0000000..c94995e --- /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..3a92c48 --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbList.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbPage.vue b/components/ui/breadcrumb/BreadcrumbPage.vue new file mode 100644 index 0000000..cc667bc --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbPage.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbSeparator.vue b/components/ui/breadcrumb/BreadcrumbSeparator.vue new file mode 100644 index 0000000..7ee2d01 --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbSeparator.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/breadcrumb/index.ts b/components/ui/breadcrumb/index.ts new file mode 100644 index 0000000..0590983 --- /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/Button.vue b/components/ui/button/Button.vue index d984fb4..ecf3fe3 100644 --- a/components/ui/button/Button.vue +++ b/components/ui/button/Button.vue @@ -1,27 +1,27 @@ diff --git a/components/ui/button/index.ts b/components/ui/button/index.ts index 4df6784..616d1d3 100644 --- a/components/ui/button/index.ts +++ b/components/ui/button/index.ts @@ -1,35 +1,36 @@ -import { cva, type VariantProps } from 'class-variance-authority'; +import { cva, type VariantProps } from 'class-variance-authority' -export { default as Button } from './Button.vue'; +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 transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", - { - variants: { - variant: { - default: - 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90', - destructive: - 'bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60', - outline: - 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50', - secondary: - 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80', - ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50', - link: 'text-primary underline-offset-4 hover:underline', - }, - size: { - default: 'h-9 px-4 py-2 has-[>svg]:px-3', - sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5', - lg: 'h-10 rounded-md px-6 has-[>svg]:px-4', - icon: 'size-9', - }, - }, - defaultVariants: { - variant: 'default', - size: 'default', - }, - } -); + 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*=\'size-\'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive', + { + variants: { + variant: { + default: + 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90', + destructive: + 'bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60', + outline: + 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50', + secondary: + 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80', + ghost: + 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50', + link: 'text-primary underline-offset-4 hover:underline', + }, + size: { + default: 'h-9 px-4 py-2 has-[>svg]:px-3', + sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5', + lg: 'h-10 rounded-md px-6 has-[>svg]:px-4', + icon: 'size-9', + }, + }, + defaultVariants: { + variant: 'default', + size: 'default', + }, + }, +) -export type ButtonVariants = VariantProps; +export type ButtonVariants = VariantProps diff --git a/components/ui/input/Input.vue b/components/ui/input/Input.vue new file mode 100644 index 0000000..b82c9d0 --- /dev/null +++ b/components/ui/input/Input.vue @@ -0,0 +1,33 @@ + + + diff --git a/components/ui/input/index.ts b/components/ui/input/index.ts new file mode 100644 index 0000000..a691dd6 --- /dev/null +++ b/components/ui/input/index.ts @@ -0,0 +1 @@ +export { default as Input } from './Input.vue' diff --git a/components/ui/separator/Separator.vue b/components/ui/separator/Separator.vue new file mode 100644 index 0000000..d397e08 --- /dev/null +++ b/components/ui/separator/Separator.vue @@ -0,0 +1,28 @@ + + + diff --git a/components/ui/separator/index.ts b/components/ui/separator/index.ts new file mode 100644 index 0000000..2287bcb --- /dev/null +++ b/components/ui/separator/index.ts @@ -0,0 +1 @@ +export { default as Separator } from './Separator.vue' diff --git a/components/ui/sheet/Sheet.vue b/components/ui/sheet/Sheet.vue new file mode 100644 index 0000000..e2a3374 --- /dev/null +++ b/components/ui/sheet/Sheet.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/sheet/SheetClose.vue b/components/ui/sheet/SheetClose.vue new file mode 100644 index 0000000..05077ea --- /dev/null +++ b/components/ui/sheet/SheetClose.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/sheet/SheetContent.vue b/components/ui/sheet/SheetContent.vue new file mode 100644 index 0000000..8e55613 --- /dev/null +++ b/components/ui/sheet/SheetContent.vue @@ -0,0 +1,63 @@ + + + diff --git a/components/ui/sheet/SheetDescription.vue b/components/ui/sheet/SheetDescription.vue new file mode 100644 index 0000000..e3682d3 --- /dev/null +++ b/components/ui/sheet/SheetDescription.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/sheet/SheetFooter.vue b/components/ui/sheet/SheetFooter.vue new file mode 100644 index 0000000..d2ac823 --- /dev/null +++ b/components/ui/sheet/SheetFooter.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/sheet/SheetHeader.vue b/components/ui/sheet/SheetHeader.vue new file mode 100644 index 0000000..ab20557 --- /dev/null +++ b/components/ui/sheet/SheetHeader.vue @@ -0,0 +1,15 @@ + + + diff --git a/components/ui/sheet/SheetOverlay.vue b/components/ui/sheet/SheetOverlay.vue new file mode 100644 index 0000000..3f27a86 --- /dev/null +++ b/components/ui/sheet/SheetOverlay.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/sheet/SheetTitle.vue b/components/ui/sheet/SheetTitle.vue new file mode 100644 index 0000000..262fb5b --- /dev/null +++ b/components/ui/sheet/SheetTitle.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/sheet/SheetTrigger.vue b/components/ui/sheet/SheetTrigger.vue new file mode 100644 index 0000000..5981f8e --- /dev/null +++ b/components/ui/sheet/SheetTrigger.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/sheet/index.ts b/components/ui/sheet/index.ts new file mode 100644 index 0000000..ee33431 --- /dev/null +++ b/components/ui/sheet/index.ts @@ -0,0 +1,8 @@ +export { default as Sheet } from './Sheet.vue' +export { default as SheetClose } from './SheetClose.vue' +export { default as SheetContent } from './SheetContent.vue' +export { default as SheetDescription } from './SheetDescription.vue' +export { default as SheetFooter } from './SheetFooter.vue' +export { default as SheetHeader } from './SheetHeader.vue' +export { default as SheetTitle } from './SheetTitle.vue' +export { default as SheetTrigger } from './SheetTrigger.vue' diff --git a/components/ui/sidebar/Sidebar.vue b/components/ui/sidebar/Sidebar.vue new file mode 100644 index 0000000..c75db5d --- /dev/null +++ b/components/ui/sidebar/Sidebar.vue @@ -0,0 +1,96 @@ + + + diff --git a/components/ui/sidebar/SidebarContent.vue b/components/ui/sidebar/SidebarContent.vue new file mode 100644 index 0000000..3b7536c --- /dev/null +++ b/components/ui/sidebar/SidebarContent.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/ui/sidebar/SidebarFooter.vue b/components/ui/sidebar/SidebarFooter.vue new file mode 100644 index 0000000..c324dff --- /dev/null +++ b/components/ui/sidebar/SidebarFooter.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/ui/sidebar/SidebarGroup.vue b/components/ui/sidebar/SidebarGroup.vue new file mode 100644 index 0000000..57a099f --- /dev/null +++ b/components/ui/sidebar/SidebarGroup.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/ui/sidebar/SidebarGroupAction.vue b/components/ui/sidebar/SidebarGroupAction.vue new file mode 100644 index 0000000..eb9a3ec --- /dev/null +++ b/components/ui/sidebar/SidebarGroupAction.vue @@ -0,0 +1,27 @@ + + + diff --git a/components/ui/sidebar/SidebarGroupContent.vue b/components/ui/sidebar/SidebarGroupContent.vue new file mode 100644 index 0000000..5d5e2dd --- /dev/null +++ b/components/ui/sidebar/SidebarGroupContent.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/ui/sidebar/SidebarGroupLabel.vue b/components/ui/sidebar/SidebarGroupLabel.vue new file mode 100644 index 0000000..8e1c1e3 --- /dev/null +++ b/components/ui/sidebar/SidebarGroupLabel.vue @@ -0,0 +1,25 @@ + + + diff --git a/components/ui/sidebar/SidebarHeader.vue b/components/ui/sidebar/SidebarHeader.vue new file mode 100644 index 0000000..00673f7 --- /dev/null +++ b/components/ui/sidebar/SidebarHeader.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/ui/sidebar/SidebarInput.vue b/components/ui/sidebar/SidebarInput.vue new file mode 100644 index 0000000..ecaa977 --- /dev/null +++ b/components/ui/sidebar/SidebarInput.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/sidebar/SidebarInset.vue b/components/ui/sidebar/SidebarInset.vue new file mode 100644 index 0000000..386c622 --- /dev/null +++ b/components/ui/sidebar/SidebarInset.vue @@ -0,0 +1,21 @@ + + + diff --git a/components/ui/sidebar/SidebarMenu.vue b/components/ui/sidebar/SidebarMenu.vue new file mode 100644 index 0000000..59ec071 --- /dev/null +++ b/components/ui/sidebar/SidebarMenu.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuAction.vue b/components/ui/sidebar/SidebarMenuAction.vue new file mode 100644 index 0000000..4852f28 --- /dev/null +++ b/components/ui/sidebar/SidebarMenuAction.vue @@ -0,0 +1,34 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuBadge.vue b/components/ui/sidebar/SidebarMenuBadge.vue new file mode 100644 index 0000000..3984b33 --- /dev/null +++ b/components/ui/sidebar/SidebarMenuBadge.vue @@ -0,0 +1,26 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuButton.vue b/components/ui/sidebar/SidebarMenuButton.vue new file mode 100644 index 0000000..1d934b2 --- /dev/null +++ b/components/ui/sidebar/SidebarMenuButton.vue @@ -0,0 +1,47 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuButtonChild.vue b/components/ui/sidebar/SidebarMenuButtonChild.vue new file mode 100644 index 0000000..82998df --- /dev/null +++ b/components/ui/sidebar/SidebarMenuButtonChild.vue @@ -0,0 +1,34 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuItem.vue b/components/ui/sidebar/SidebarMenuItem.vue new file mode 100644 index 0000000..b7b4d3f --- /dev/null +++ b/components/ui/sidebar/SidebarMenuItem.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuSkeleton.vue b/components/ui/sidebar/SidebarMenuSkeleton.vue new file mode 100644 index 0000000..6302c35 --- /dev/null +++ b/components/ui/sidebar/SidebarMenuSkeleton.vue @@ -0,0 +1,34 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuSub.vue b/components/ui/sidebar/SidebarMenuSub.vue new file mode 100644 index 0000000..11aec64 --- /dev/null +++ b/components/ui/sidebar/SidebarMenuSub.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuSubButton.vue b/components/ui/sidebar/SidebarMenuSubButton.vue new file mode 100644 index 0000000..f9fae8f --- /dev/null +++ b/components/ui/sidebar/SidebarMenuSubButton.vue @@ -0,0 +1,36 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuSubItem.vue b/components/ui/sidebar/SidebarMenuSubItem.vue new file mode 100644 index 0000000..f0c35bc --- /dev/null +++ b/components/ui/sidebar/SidebarMenuSubItem.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/ui/sidebar/SidebarProvider.vue b/components/ui/sidebar/SidebarProvider.vue new file mode 100644 index 0000000..2e08dec --- /dev/null +++ b/components/ui/sidebar/SidebarProvider.vue @@ -0,0 +1,81 @@ + + + diff --git a/components/ui/sidebar/SidebarRail.vue b/components/ui/sidebar/SidebarRail.vue new file mode 100644 index 0000000..07e59be --- /dev/null +++ b/components/ui/sidebar/SidebarRail.vue @@ -0,0 +1,33 @@ + + + diff --git a/components/ui/sidebar/SidebarSeparator.vue b/components/ui/sidebar/SidebarSeparator.vue new file mode 100644 index 0000000..1803bff --- /dev/null +++ b/components/ui/sidebar/SidebarSeparator.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/sidebar/SidebarTrigger.vue b/components/ui/sidebar/SidebarTrigger.vue new file mode 100644 index 0000000..59f29b9 --- /dev/null +++ b/components/ui/sidebar/SidebarTrigger.vue @@ -0,0 +1,27 @@ + + + diff --git a/components/ui/sidebar/index.ts b/components/ui/sidebar/index.ts new file mode 100644 index 0000000..48da274 --- /dev/null +++ b/components/ui/sidebar/index.ts @@ -0,0 +1,60 @@ +import type { VariantProps } from 'class-variance-authority' +import type { HTMLAttributes } from 'vue' +import { cva } from 'class-variance-authority' + +export interface SidebarProps { + side?: 'left' | 'right' + variant?: 'sidebar' | 'floating' | 'inset' + collapsible?: 'offcanvas' | 'icon' | 'none' + class?: HTMLAttributes['class'] +} + +export { default as Sidebar } from './Sidebar.vue' +export { default as SidebarContent } from './SidebarContent.vue' +export { default as SidebarFooter } from './SidebarFooter.vue' +export { default as SidebarGroup } from './SidebarGroup.vue' +export { default as SidebarGroupAction } from './SidebarGroupAction.vue' +export { default as SidebarGroupContent } from './SidebarGroupContent.vue' +export { default as SidebarGroupLabel } from './SidebarGroupLabel.vue' +export { default as SidebarHeader } from './SidebarHeader.vue' +export { default as SidebarInput } from './SidebarInput.vue' +export { default as SidebarInset } from './SidebarInset.vue' +export { default as SidebarMenu } from './SidebarMenu.vue' +export { default as SidebarMenuAction } from './SidebarMenuAction.vue' +export { default as SidebarMenuBadge } from './SidebarMenuBadge.vue' +export { default as SidebarMenuButton } from './SidebarMenuButton.vue' +export { default as SidebarMenuItem } from './SidebarMenuItem.vue' +export { default as SidebarMenuSkeleton } from './SidebarMenuSkeleton.vue' +export { default as SidebarMenuSub } from './SidebarMenuSub.vue' +export { default as SidebarMenuSubButton } from './SidebarMenuSubButton.vue' +export { default as SidebarMenuSubItem } from './SidebarMenuSubItem.vue' +export { default as SidebarProvider } from './SidebarProvider.vue' +export { default as SidebarRail } from './SidebarRail.vue' +export { default as SidebarSeparator } from './SidebarSeparator.vue' +export { default as SidebarTrigger } from './SidebarTrigger.vue' + +export { useSidebar } from './utils' + +export const sidebarMenuButtonVariants = cva( + 'peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0', + { + variants: { + variant: { + default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground', + outline: + 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]', + }, + size: { + default: 'h-8 text-sm', + sm: 'h-7 text-xs', + lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!', + }, + }, + defaultVariants: { + variant: 'default', + size: 'default', + }, + }, +) + +export type SidebarMenuButtonVariants = VariantProps diff --git a/components/ui/sidebar/utils.ts b/components/ui/sidebar/utils.ts new file mode 100644 index 0000000..6edb140 --- /dev/null +++ b/components/ui/sidebar/utils.ts @@ -0,0 +1,19 @@ +import type { ComputedRef, Ref } from 'vue' +import { createContext } from 'reka-ui' + +export const SIDEBAR_COOKIE_NAME = 'sidebar_state' +export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7 +export const SIDEBAR_WIDTH = '16rem' +export const SIDEBAR_WIDTH_MOBILE = '18rem' +export const SIDEBAR_WIDTH_ICON = '3rem' +export const SIDEBAR_KEYBOARD_SHORTCUT = 'b' + +export const [useSidebar, provideSidebarContext] = createContext<{ + state: ComputedRef<'expanded' | 'collapsed'> + open: Ref + setOpen: (value: boolean) => void + isMobile: Ref + openMobile: Ref + setOpenMobile: (value: boolean) => void + toggleSidebar: () => void +}>('Sidebar') diff --git a/components/ui/skeleton/Skeleton.vue b/components/ui/skeleton/Skeleton.vue new file mode 100644 index 0000000..153fe2c --- /dev/null +++ b/components/ui/skeleton/Skeleton.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/skeleton/index.ts b/components/ui/skeleton/index.ts new file mode 100644 index 0000000..be21fad --- /dev/null +++ b/components/ui/skeleton/index.ts @@ -0,0 +1 @@ +export { default as Skeleton } from './Skeleton.vue' diff --git a/components/ui/tooltip/Tooltip.vue b/components/ui/tooltip/Tooltip.vue new file mode 100644 index 0000000..3ebeecc --- /dev/null +++ b/components/ui/tooltip/Tooltip.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/tooltip/TooltipContent.vue b/components/ui/tooltip/TooltipContent.vue new file mode 100644 index 0000000..62712e6 --- /dev/null +++ b/components/ui/tooltip/TooltipContent.vue @@ -0,0 +1,33 @@ + + + diff --git a/components/ui/tooltip/TooltipProvider.vue b/components/ui/tooltip/TooltipProvider.vue new file mode 100644 index 0000000..4b4203e --- /dev/null +++ b/components/ui/tooltip/TooltipProvider.vue @@ -0,0 +1,13 @@ + + + diff --git a/components/ui/tooltip/TooltipTrigger.vue b/components/ui/tooltip/TooltipTrigger.vue new file mode 100644 index 0000000..36253c6 --- /dev/null +++ b/components/ui/tooltip/TooltipTrigger.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/tooltip/index.ts b/components/ui/tooltip/index.ts new file mode 100644 index 0000000..5ab9653 --- /dev/null +++ b/components/ui/tooltip/index.ts @@ -0,0 +1,4 @@ +export { default as Tooltip } from './Tooltip.vue' +export { default as TooltipContent } from './TooltipContent.vue' +export { default as TooltipProvider } from './TooltipProvider.vue' +export { default as TooltipTrigger } from './TooltipTrigger.vue' diff --git a/layouts/default.vue b/layouts/default.vue new file mode 100644 index 0000000..db04e7e --- /dev/null +++ b/layouts/default.vue @@ -0,0 +1,44 @@ + + + diff --git a/nuxt.config.ts b/nuxt.config.ts index 18b7e86..bb320e0 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -36,4 +36,19 @@ export default defineNuxtConfig({ colorMode: { classSuffix: '', }, + + icon: { + mode: 'svg', + }, + + app: { + head: { + title: 'Warren', + htmlAttrs: { + lang: 'en', + }, + }, + }, + + ssr: false, }); diff --git a/package.json b/package.json index 797b5d7..2d0c03e 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "dev": "nuxt dev", "generate": "nuxt generate", "preview": "nuxt preview", - "postinstall": "nuxt prepare" + "postinstall": "nuxt prepare", + "format": "bunx --bun prettier --write ." }, "dependencies": { "@nuxt/eslint": "1.5.2", @@ -16,6 +17,7 @@ "@nuxt/image": "1.10.0", "@nuxt/test-utils": "3.19.2", "@tailwindcss/vite": "^4.1.11", + "@vueuse/core": "^13.5.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "eslint": "^9.0.0", diff --git a/pages/about.vue b/pages/about.vue new file mode 100644 index 0000000..5b3a9b8 --- /dev/null +++ b/pages/about.vue @@ -0,0 +1,5 @@ + diff --git a/pages/index.vue b/pages/index.vue new file mode 100644 index 0000000..c627fc4 --- /dev/null +++ b/pages/index.vue @@ -0,0 +1,5 @@ +