@tower_74/cms-app 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -0
- package/package.json +49 -0
- package/src/components/AppContent.vue +21 -0
- package/src/components/AppLogoIcon.vue +24 -0
- package/src/components/AppShell.vue +37 -0
- package/src/components/AppearanceTabs.vue +37 -0
- package/src/components/AuthBar.vue +58 -0
- package/src/components/BlockEditor.vue +95 -0
- package/src/components/DeleteUser.vue +87 -0
- package/src/components/FieldBuilder.vue +105 -0
- package/src/components/Heading.vue +20 -0
- package/src/components/HeadingSmall.vue +17 -0
- package/src/components/Icon.vue +30 -0
- package/src/components/InputError.vue +13 -0
- package/src/components/MenuItemsEditor.vue +59 -0
- package/src/components/NavUser.vue +30 -0
- package/src/components/Pagination.vue +28 -0
- package/src/components/PlaceholderPattern.vue +16 -0
- package/src/components/Seo.vue +28 -0
- package/src/components/TextLink.vue +24 -0
- package/src/components/UserInfo.vue +34 -0
- package/src/components/UserMenuContent.vue +37 -0
- package/src/components/commerce/OptionsEditor.vue +55 -0
- package/src/components/commerce/VariantsEditor.vue +71 -0
- package/src/components/ui/avatar/Avatar.vue +24 -0
- package/src/components/ui/avatar/AvatarFallback.vue +11 -0
- package/src/components/ui/avatar/AvatarImage.vue +9 -0
- package/src/components/ui/avatar/index.ts +24 -0
- package/src/components/ui/breadcrumb/Breadcrumb.vue +13 -0
- package/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue +18 -0
- package/src/components/ui/breadcrumb/BreadcrumbItem.vue +14 -0
- package/src/components/ui/breadcrumb/BreadcrumbLink.vue +15 -0
- package/src/components/ui/breadcrumb/BreadcrumbList.vue +14 -0
- package/src/components/ui/breadcrumb/BreadcrumbPage.vue +14 -0
- package/src/components/ui/breadcrumb/BreadcrumbSeparator.vue +17 -0
- package/src/components/ui/breadcrumb/index.ts +7 -0
- package/src/components/ui/button/Button.vue +22 -0
- package/src/components/ui/button/index.ts +31 -0
- package/src/components/ui/card/Card.vue +14 -0
- package/src/components/ui/card/CardContent.vue +14 -0
- package/src/components/ui/card/CardDescription.vue +14 -0
- package/src/components/ui/card/CardFooter.vue +14 -0
- package/src/components/ui/card/CardHeader.vue +14 -0
- package/src/components/ui/card/CardTitle.vue +14 -0
- package/src/components/ui/card/index.ts +6 -0
- package/src/components/ui/checkbox/Checkbox.vue +36 -0
- package/src/components/ui/checkbox/index.ts +1 -0
- package/src/components/ui/collapsible/Collapsible.vue +15 -0
- package/src/components/ui/collapsible/CollapsibleContent.vue +14 -0
- package/src/components/ui/collapsible/CollapsibleTrigger.vue +11 -0
- package/src/components/ui/collapsible/index.ts +3 -0
- package/src/components/ui/dialog/Dialog.vue +14 -0
- package/src/components/ui/dialog/DialogClose.vue +11 -0
- package/src/components/ui/dialog/DialogContent.vue +51 -0
- package/src/components/ui/dialog/DialogDescription.vue +21 -0
- package/src/components/ui/dialog/DialogFooter.vue +12 -0
- package/src/components/ui/dialog/DialogHeader.vue +14 -0
- package/src/components/ui/dialog/DialogScrollContent.vue +59 -0
- package/src/components/ui/dialog/DialogTitle.vue +21 -0
- package/src/components/ui/dialog/DialogTrigger.vue +11 -0
- package/src/components/ui/dialog/index.ts +9 -0
- package/src/components/ui/dropdown-menu/DropdownMenu.vue +14 -0
- package/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +42 -0
- package/src/components/ui/dropdown-menu/DropdownMenuContent.vue +40 -0
- package/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +11 -0
- package/src/components/ui/dropdown-menu/DropdownMenuItem.vue +30 -0
- package/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +21 -0
- package/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +14 -0
- package/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +43 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +21 -0
- package/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +14 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSub.vue +14 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +30 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +31 -0
- package/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +13 -0
- package/src/components/ui/dropdown-menu/index.ts +16 -0
- package/src/components/ui/input/Input.vue +32 -0
- package/src/components/ui/input/index.ts +1 -0
- package/src/components/ui/label/Label.vue +22 -0
- package/src/components/ui/label/index.ts +1 -0
- package/src/components/ui/navigation-menu/NavigationMenu.vue +25 -0
- package/src/components/ui/navigation-menu/NavigationMenuContent.vue +31 -0
- package/src/components/ui/navigation-menu/NavigationMenuIndicator.vue +29 -0
- package/src/components/ui/navigation-menu/NavigationMenuItem.vue +11 -0
- package/src/components/ui/navigation-menu/NavigationMenuLink.vue +14 -0
- package/src/components/ui/navigation-menu/NavigationMenuList.vue +21 -0
- package/src/components/ui/navigation-menu/NavigationMenuTrigger.vue +24 -0
- package/src/components/ui/navigation-menu/NavigationMenuViewport.vue +29 -0
- package/src/components/ui/navigation-menu/index.ts +14 -0
- package/src/components/ui/separator/Separator.vue +31 -0
- package/src/components/ui/separator/index.ts +1 -0
- package/src/components/ui/sheet/Sheet.vue +14 -0
- package/src/components/ui/sheet/SheetClose.vue +11 -0
- package/src/components/ui/sheet/SheetContent.vue +53 -0
- package/src/components/ui/sheet/SheetDescription.vue +19 -0
- package/src/components/ui/sheet/SheetFooter.vue +12 -0
- package/src/components/ui/sheet/SheetHeader.vue +12 -0
- package/src/components/ui/sheet/SheetTitle.vue +19 -0
- package/src/components/ui/sheet/SheetTrigger.vue +11 -0
- package/src/components/ui/sheet/index.ts +29 -0
- package/src/components/ui/sidebar/Sidebar.vue +99 -0
- package/src/components/ui/sidebar/SidebarContent.vue +17 -0
- package/src/components/ui/sidebar/SidebarFooter.vue +14 -0
- package/src/components/ui/sidebar/SidebarGroup.vue +14 -0
- package/src/components/ui/sidebar/SidebarGroupAction.vue +31 -0
- package/src/components/ui/sidebar/SidebarGroupContent.vue +14 -0
- package/src/components/ui/sidebar/SidebarGroupLabel.vue +29 -0
- package/src/components/ui/sidebar/SidebarHeader.vue +14 -0
- package/src/components/ui/sidebar/SidebarInput.vue +15 -0
- package/src/components/ui/sidebar/SidebarInset.vue +22 -0
- package/src/components/ui/sidebar/SidebarMenu.vue +14 -0
- package/src/components/ui/sidebar/SidebarMenuAction.vue +41 -0
- package/src/components/ui/sidebar/SidebarMenuBadge.vue +27 -0
- package/src/components/ui/sidebar/SidebarMenuButton.vue +52 -0
- package/src/components/ui/sidebar/SidebarMenuButtonChild.vue +33 -0
- package/src/components/ui/sidebar/SidebarMenuItem.vue +14 -0
- package/src/components/ui/sidebar/SidebarMenuSkeleton.vue +22 -0
- package/src/components/ui/sidebar/SidebarMenuSub.vue +23 -0
- package/src/components/ui/sidebar/SidebarMenuSubButton.vue +42 -0
- package/src/components/ui/sidebar/SidebarMenuSubItem.vue +7 -0
- package/src/components/ui/sidebar/SidebarProvider.vue +89 -0
- package/src/components/ui/sidebar/SidebarRail.vue +34 -0
- package/src/components/ui/sidebar/SidebarSeparator.vue +15 -0
- package/src/components/ui/sidebar/SidebarTrigger.vue +20 -0
- package/src/components/ui/sidebar/index.ts +51 -0
- package/src/components/ui/sidebar/utils.ts +19 -0
- package/src/components/ui/skeleton/Skeleton.vue +14 -0
- package/src/components/ui/skeleton/index.ts +1 -0
- package/src/components/ui/tooltip/Tooltip.vue +14 -0
- package/src/components/ui/tooltip/TooltipContent.vue +39 -0
- package/src/components/ui/tooltip/TooltipProvider.vue +11 -0
- package/src/components/ui/tooltip/TooltipTrigger.vue +11 -0
- package/src/components/ui/tooltip/index.ts +4 -0
- package/src/composables/useAppearance.ts +53 -0
- package/src/composables/useInitials.ts +14 -0
- package/src/index.ts +22 -0
- package/src/layouts/AdminLayout.vue +170 -0
- package/src/layouts/AuthLayout.vue +14 -0
- package/src/layouts/PublicLayout.vue +53 -0
- package/src/layouts/auth/AuthCardLayout.vue +36 -0
- package/src/layouts/auth/AuthSimpleLayout.vue +31 -0
- package/src/layouts/auth/AuthSplitLayout.vue +40 -0
- package/src/layouts/settings/Layout.vue +56 -0
- package/src/lib/utils.ts +6 -0
- package/src/pages/Admin/Appearance/Theme.vue +58 -0
- package/src/pages/Admin/Appearance/Widgets.vue +48 -0
- package/src/pages/Admin/Commerce/Orders/Index.vue +80 -0
- package/src/pages/Admin/Commerce/Orders/Show.vue +200 -0
- package/src/pages/Admin/Commerce/Products/Edit.vue +167 -0
- package/src/pages/Admin/Commerce/Products/Index.vue +65 -0
- package/src/pages/Admin/Content/Edit.vue +170 -0
- package/src/pages/Admin/Content/Index.vue +88 -0
- package/src/pages/Admin/Content/Preview.vue +25 -0
- package/src/pages/Admin/Dashboard.vue +26 -0
- package/src/pages/Admin/Forms/Edit.vue +98 -0
- package/src/pages/Admin/Forms/Index.vue +68 -0
- package/src/pages/Admin/Forms/Submissions/Index.vue +68 -0
- package/src/pages/Admin/Forms/Submissions/Show.vue +47 -0
- package/src/pages/Admin/Media/Index.vue +75 -0
- package/src/pages/Admin/Menus/Create.vue +37 -0
- package/src/pages/Admin/Menus/Edit.vue +54 -0
- package/src/pages/Admin/Menus/Index.vue +52 -0
- package/src/pages/Admin/Settings/Index.vue +184 -0
- package/src/pages/Admin/Taxonomy/Edit.vue +83 -0
- package/src/pages/Admin/Taxonomy/Index.vue +68 -0
- package/src/pages/Admin/Users/Edit.vue +82 -0
- package/src/pages/Admin/Users/Index.vue +74 -0
- package/src/pages/Public/Cart/Index.vue +108 -0
- package/src/pages/Public/Checkout/Confirmation.vue +110 -0
- package/src/pages/Public/Checkout/Index.vue +174 -0
- package/src/pages/Public/Index.vue +54 -0
- package/src/pages/Public/Shop/Index.vue +39 -0
- package/src/pages/Public/Shop/Show.vue +46 -0
- package/src/pages/Public/Show.vue +41 -0
- package/src/pages/Setup/Complete.vue +53 -0
- package/src/pages/Setup/Index.vue +85 -0
- package/src/pages/Welcome.vue +787 -0
- package/src/pages/auth/ConfirmPassword.vue +53 -0
- package/src/pages/auth/ForgotPassword.vue +54 -0
- package/src/pages/auth/Login.vue +91 -0
- package/src/pages/auth/Register.vue +83 -0
- package/src/pages/auth/ResetPassword.vue +81 -0
- package/src/pages/auth/VerifyEmail.vue +36 -0
- package/src/pages/settings/Appearance.vue +23 -0
- package/src/pages/settings/Password.vue +120 -0
- package/src/pages/settings/Profile.vue +105 -0
- package/src/pages.ts +9 -0
- package/src/types/index.ts +42 -0
- package/src/types/ziggy.ts +12 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
2
|
+
|
|
3
|
+
export { default as Sheet } from './Sheet.vue';
|
|
4
|
+
export { default as SheetClose } from './SheetClose.vue';
|
|
5
|
+
export { default as SheetContent } from './SheetContent.vue';
|
|
6
|
+
export { default as SheetDescription } from './SheetDescription.vue';
|
|
7
|
+
export { default as SheetFooter } from './SheetFooter.vue';
|
|
8
|
+
export { default as SheetHeader } from './SheetHeader.vue';
|
|
9
|
+
export { default as SheetTitle } from './SheetTitle.vue';
|
|
10
|
+
export { default as SheetTrigger } from './SheetTrigger.vue';
|
|
11
|
+
|
|
12
|
+
export const sheetVariants = cva(
|
|
13
|
+
'fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
|
|
14
|
+
{
|
|
15
|
+
variants: {
|
|
16
|
+
side: {
|
|
17
|
+
top: 'inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top',
|
|
18
|
+
bottom: 'inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom',
|
|
19
|
+
left: 'inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm',
|
|
20
|
+
right: 'inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
defaultVariants: {
|
|
24
|
+
side: 'right',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export type SheetVariants = VariantProps<typeof sheetVariants>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import Sheet from '@/components/ui/sheet/Sheet.vue';
|
|
3
|
+
import SheetContent from '@/components/ui/sheet/SheetContent.vue';
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
|
+
import type { HTMLAttributes } from 'vue';
|
|
6
|
+
import { SIDEBAR_WIDTH_MOBILE, useSidebar } from './utils';
|
|
7
|
+
|
|
8
|
+
defineOptions({
|
|
9
|
+
inheritAttrs: false,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const props = withDefaults(
|
|
13
|
+
defineProps<{
|
|
14
|
+
side?: 'left' | 'right';
|
|
15
|
+
variant?: 'sidebar' | 'floating' | 'inset';
|
|
16
|
+
collapsible?: 'offcanvas' | 'icon' | 'none';
|
|
17
|
+
class?: HTMLAttributes['class'];
|
|
18
|
+
}>(),
|
|
19
|
+
{
|
|
20
|
+
side: 'left',
|
|
21
|
+
variant: 'sidebar',
|
|
22
|
+
collapsible: 'offcanvas',
|
|
23
|
+
},
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<template>
|
|
30
|
+
<div
|
|
31
|
+
v-if="collapsible === 'none'"
|
|
32
|
+
:class="cn('flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground', props.class)"
|
|
33
|
+
v-bind="$attrs"
|
|
34
|
+
>
|
|
35
|
+
<slot />
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<Sheet v-else-if="isMobile" :open="openMobile" v-bind="$attrs" @update:open="setOpenMobile">
|
|
39
|
+
<SheetContent
|
|
40
|
+
data-sidebar="sidebar"
|
|
41
|
+
data-mobile="true"
|
|
42
|
+
:side="side"
|
|
43
|
+
class="w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
|
|
44
|
+
:style="{
|
|
45
|
+
'--sidebar-width': SIDEBAR_WIDTH_MOBILE,
|
|
46
|
+
}"
|
|
47
|
+
>
|
|
48
|
+
<div class="flex h-full w-full flex-col">
|
|
49
|
+
<slot />
|
|
50
|
+
</div>
|
|
51
|
+
</SheetContent>
|
|
52
|
+
</Sheet>
|
|
53
|
+
|
|
54
|
+
<div
|
|
55
|
+
v-else
|
|
56
|
+
class="group peer hidden md:block"
|
|
57
|
+
:data-state="state"
|
|
58
|
+
:data-collapsible="state === 'collapsed' ? collapsible : ''"
|
|
59
|
+
:data-variant="variant"
|
|
60
|
+
:data-side="side"
|
|
61
|
+
>
|
|
62
|
+
<!-- This is what handles the sidebar gap on desktop -->
|
|
63
|
+
<div
|
|
64
|
+
:class="
|
|
65
|
+
cn(
|
|
66
|
+
'relative h-svh w-[--sidebar-width] bg-transparent transition-[width] duration-200 ease-linear',
|
|
67
|
+
'group-data-[collapsible=offcanvas]:w-0',
|
|
68
|
+
'group-data-[side=right]:rotate-180',
|
|
69
|
+
variant === 'floating' || variant === 'inset'
|
|
70
|
+
? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]'
|
|
71
|
+
: 'group-data-[collapsible=icon]:w-[--sidebar-width-icon]',
|
|
72
|
+
)
|
|
73
|
+
"
|
|
74
|
+
/>
|
|
75
|
+
<div
|
|
76
|
+
:class="
|
|
77
|
+
cn(
|
|
78
|
+
'fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] duration-200 ease-linear md:flex',
|
|
79
|
+
side === 'left'
|
|
80
|
+
? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'
|
|
81
|
+
: 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',
|
|
82
|
+
// Adjust the padding for floating and inset variants.
|
|
83
|
+
variant === 'floating' || variant === 'inset'
|
|
84
|
+
? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]'
|
|
85
|
+
: 'group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l',
|
|
86
|
+
props.class,
|
|
87
|
+
)
|
|
88
|
+
"
|
|
89
|
+
v-bind="$attrs"
|
|
90
|
+
>
|
|
91
|
+
<div
|
|
92
|
+
data-sidebar="sidebar"
|
|
93
|
+
class="flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow"
|
|
94
|
+
>
|
|
95
|
+
<slot />
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</template>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import type { HTMLAttributes } from 'vue';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div
|
|
12
|
+
data-sidebar="content"
|
|
13
|
+
:class="cn('flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden', props.class)"
|
|
14
|
+
>
|
|
15
|
+
<slot />
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import type { HTMLAttributes } from 'vue';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div data-sidebar="footer" :class="cn('flex flex-col gap-2 p-2', props.class)">
|
|
12
|
+
<slot />
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import type { HTMLAttributes } from 'vue';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div data-sidebar="group" :class="cn('relative flex w-full min-w-0 flex-col p-2', props.class)">
|
|
12
|
+
<slot />
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import type { PrimitiveProps } from 'radix-vue';
|
|
4
|
+
import { Primitive } from 'radix-vue';
|
|
5
|
+
import type { HTMLAttributes } from 'vue';
|
|
6
|
+
|
|
7
|
+
const props = defineProps<
|
|
8
|
+
PrimitiveProps & {
|
|
9
|
+
class?: HTMLAttributes['class'];
|
|
10
|
+
}
|
|
11
|
+
>();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<Primitive
|
|
16
|
+
data-sidebar="group-action"
|
|
17
|
+
:as="as"
|
|
18
|
+
:as-child="asChild"
|
|
19
|
+
:class="
|
|
20
|
+
cn(
|
|
21
|
+
'absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
|
|
22
|
+
// Increases the hit area of the button on mobile.
|
|
23
|
+
'after:absolute after:-inset-2 after:md:hidden',
|
|
24
|
+
'group-data-[collapsible=icon]:hidden',
|
|
25
|
+
props.class,
|
|
26
|
+
)
|
|
27
|
+
"
|
|
28
|
+
>
|
|
29
|
+
<slot />
|
|
30
|
+
</Primitive>
|
|
31
|
+
</template>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import type { HTMLAttributes } from 'vue';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div data-sidebar="group-content" :class="cn('w-full text-sm', props.class)">
|
|
12
|
+
<slot />
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import type { PrimitiveProps } from 'radix-vue';
|
|
4
|
+
import { Primitive } from 'radix-vue';
|
|
5
|
+
import type { HTMLAttributes } from 'vue';
|
|
6
|
+
|
|
7
|
+
const props = defineProps<
|
|
8
|
+
PrimitiveProps & {
|
|
9
|
+
class?: HTMLAttributes['class'];
|
|
10
|
+
}
|
|
11
|
+
>();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<Primitive
|
|
16
|
+
data-sidebar="group-label"
|
|
17
|
+
:as="as"
|
|
18
|
+
:as-child="asChild"
|
|
19
|
+
:class="
|
|
20
|
+
cn(
|
|
21
|
+
'flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opa] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
|
|
22
|
+
'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',
|
|
23
|
+
props.class,
|
|
24
|
+
)
|
|
25
|
+
"
|
|
26
|
+
>
|
|
27
|
+
<slot />
|
|
28
|
+
</Primitive>
|
|
29
|
+
</template>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import type { HTMLAttributes } from 'vue';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div data-sidebar="header" :class="cn('flex flex-col gap-2 p-2', props.class)">
|
|
12
|
+
<slot />
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import Input from '@/components/ui/input/Input.vue';
|
|
3
|
+
import { cn } from '@/lib/utils';
|
|
4
|
+
import type { HTMLAttributes } from 'vue';
|
|
5
|
+
|
|
6
|
+
const props = defineProps<{
|
|
7
|
+
class?: HTMLAttributes['class'];
|
|
8
|
+
}>();
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<Input data-sidebar="input" :class="cn('h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring', props.class)">
|
|
13
|
+
<slot />
|
|
14
|
+
</Input>
|
|
15
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import type { HTMLAttributes } from 'vue';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<main
|
|
12
|
+
:class="
|
|
13
|
+
cn(
|
|
14
|
+
'relative flex min-h-svh flex-1 flex-col bg-background',
|
|
15
|
+
'peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow',
|
|
16
|
+
props.class,
|
|
17
|
+
)
|
|
18
|
+
"
|
|
19
|
+
>
|
|
20
|
+
<slot />
|
|
21
|
+
</main>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import type { HTMLAttributes } from 'vue';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<ul data-sidebar="menu" :class="cn('flex w-full min-w-0 flex-col gap-1', props.class)">
|
|
12
|
+
<slot />
|
|
13
|
+
</ul>
|
|
14
|
+
</template>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import { Primitive, type PrimitiveProps } from 'radix-vue';
|
|
4
|
+
import type { HTMLAttributes } from 'vue';
|
|
5
|
+
|
|
6
|
+
const props = withDefaults(
|
|
7
|
+
defineProps<
|
|
8
|
+
PrimitiveProps & {
|
|
9
|
+
showOnHover?: boolean;
|
|
10
|
+
class?: HTMLAttributes['class'];
|
|
11
|
+
}
|
|
12
|
+
>(),
|
|
13
|
+
{
|
|
14
|
+
as: 'button',
|
|
15
|
+
},
|
|
16
|
+
);
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<template>
|
|
20
|
+
<Primitive
|
|
21
|
+
data-sidebar="menu-action"
|
|
22
|
+
:class="
|
|
23
|
+
cn(
|
|
24
|
+
'absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0',
|
|
25
|
+
// Increases the hit area of the button on mobile.
|
|
26
|
+
'after:absolute after:-inset-2 after:md:hidden',
|
|
27
|
+
'peer-data-[size=sm]/menu-button:top-1',
|
|
28
|
+
'peer-data-[size=default]/menu-button:top-1.5',
|
|
29
|
+
'peer-data-[size=lg]/menu-button:top-2.5',
|
|
30
|
+
'group-data-[collapsible=icon]:hidden',
|
|
31
|
+
showOnHover &&
|
|
32
|
+
'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0',
|
|
33
|
+
props.class,
|
|
34
|
+
)
|
|
35
|
+
"
|
|
36
|
+
:as="as"
|
|
37
|
+
:as-child="asChild"
|
|
38
|
+
>
|
|
39
|
+
<slot />
|
|
40
|
+
</Primitive>
|
|
41
|
+
</template>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import type { HTMLAttributes } from 'vue';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div
|
|
12
|
+
data-sidebar="menu-badge"
|
|
13
|
+
:class="
|
|
14
|
+
cn(
|
|
15
|
+
'pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-sidebar-foreground',
|
|
16
|
+
'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',
|
|
17
|
+
'peer-data-[size=sm]/menu-button:top-1',
|
|
18
|
+
'peer-data-[size=default]/menu-button:top-1.5',
|
|
19
|
+
'peer-data-[size=lg]/menu-button:top-2.5',
|
|
20
|
+
'group-data-[collapsible=icon]:hidden',
|
|
21
|
+
props.class,
|
|
22
|
+
)
|
|
23
|
+
"
|
|
24
|
+
>
|
|
25
|
+
<slot />
|
|
26
|
+
</div>
|
|
27
|
+
</template>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import Tooltip from '@/components/ui/tooltip/Tooltip.vue';
|
|
3
|
+
import TooltipContent from '@/components/ui/tooltip/TooltipContent.vue';
|
|
4
|
+
import TooltipTrigger from '@/components/ui/tooltip/TooltipTrigger.vue';
|
|
5
|
+
import { computed, type Component } from 'vue';
|
|
6
|
+
import SidebarMenuButtonChild, { type SidebarMenuButtonProps } from './SidebarMenuButtonChild.vue';
|
|
7
|
+
import { useSidebar } from './utils';
|
|
8
|
+
|
|
9
|
+
defineOptions({
|
|
10
|
+
inheritAttrs: false,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const props = withDefaults(
|
|
14
|
+
defineProps<
|
|
15
|
+
SidebarMenuButtonProps & {
|
|
16
|
+
tooltip?: string | Component;
|
|
17
|
+
}
|
|
18
|
+
>(),
|
|
19
|
+
{
|
|
20
|
+
as: 'button',
|
|
21
|
+
variant: 'default',
|
|
22
|
+
size: 'default',
|
|
23
|
+
},
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
const { isMobile, state } = useSidebar();
|
|
27
|
+
|
|
28
|
+
const delegatedProps = computed(() => {
|
|
29
|
+
const { tooltip, ...delegated } = props;
|
|
30
|
+
return delegated;
|
|
31
|
+
});
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<template>
|
|
35
|
+
<SidebarMenuButtonChild v-if="!tooltip" v-bind="{ ...delegatedProps, ...$attrs }">
|
|
36
|
+
<slot />
|
|
37
|
+
</SidebarMenuButtonChild>
|
|
38
|
+
|
|
39
|
+
<Tooltip v-else>
|
|
40
|
+
<TooltipTrigger as-child>
|
|
41
|
+
<SidebarMenuButtonChild v-bind="{ ...delegatedProps, ...$attrs }">
|
|
42
|
+
<slot />
|
|
43
|
+
</SidebarMenuButtonChild>
|
|
44
|
+
</TooltipTrigger>
|
|
45
|
+
<TooltipContent side="right" align="center" :hidden="state !== 'collapsed' || isMobile">
|
|
46
|
+
<template v-if="typeof tooltip === 'string'">
|
|
47
|
+
{{ tooltip }}
|
|
48
|
+
</template>
|
|
49
|
+
<component :is="tooltip" v-else />
|
|
50
|
+
</TooltipContent>
|
|
51
|
+
</Tooltip>
|
|
52
|
+
</template>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import { Primitive, type PrimitiveProps } from 'radix-vue';
|
|
4
|
+
import type { HTMLAttributes } from 'vue';
|
|
5
|
+
import { sidebarMenuButtonVariants, type SidebarMenuButtonVariants } from '.';
|
|
6
|
+
|
|
7
|
+
export interface SidebarMenuButtonProps extends PrimitiveProps {
|
|
8
|
+
variant?: SidebarMenuButtonVariants['variant'];
|
|
9
|
+
size?: SidebarMenuButtonVariants['size'];
|
|
10
|
+
isActive?: boolean;
|
|
11
|
+
class?: HTMLAttributes['class'];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const props = withDefaults(defineProps<SidebarMenuButtonProps>(), {
|
|
15
|
+
as: 'button',
|
|
16
|
+
variant: 'default',
|
|
17
|
+
size: 'default',
|
|
18
|
+
});
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<Primitive
|
|
23
|
+
data-sidebar="menu-button"
|
|
24
|
+
:data-size="size"
|
|
25
|
+
:data-active="isActive"
|
|
26
|
+
:class="cn(sidebarMenuButtonVariants({ variant, size }), props.class)"
|
|
27
|
+
:as="as"
|
|
28
|
+
:as-child="asChild"
|
|
29
|
+
v-bind="$attrs"
|
|
30
|
+
>
|
|
31
|
+
<slot />
|
|
32
|
+
</Primitive>
|
|
33
|
+
</template>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import type { HTMLAttributes } from 'vue';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<li data-sidebar="menu-item" :class="cn('group/menu-item relative', props.class)">
|
|
12
|
+
<slot />
|
|
13
|
+
</li>
|
|
14
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import Skeleton from '@/components/ui/skeleton/Skeleton.vue';
|
|
3
|
+
import { cn } from '@/lib/utils';
|
|
4
|
+
import { computed, type HTMLAttributes } from 'vue';
|
|
5
|
+
|
|
6
|
+
const props = defineProps<{
|
|
7
|
+
showIcon?: boolean;
|
|
8
|
+
class?: HTMLAttributes['class'];
|
|
9
|
+
}>();
|
|
10
|
+
|
|
11
|
+
const width = computed(() => {
|
|
12
|
+
return `${Math.floor(Math.random() * 40) + 50}%`;
|
|
13
|
+
});
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<div data-sidebar="menu-skeleton" :class="cn('flex h-8 items-center gap-2 rounded-md px-2', props.class)">
|
|
18
|
+
<Skeleton v-if="showIcon" class="size-4 rounded-md" data-sidebar="menu-skeleton-icon" />
|
|
19
|
+
|
|
20
|
+
<Skeleton class="h-4 max-w-[--skeleton-width] flex-1" data-sidebar="menu-skeleton-text" :style="{ '--skeleton-width': width }" />
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import type { HTMLAttributes } from 'vue';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<ul
|
|
12
|
+
data-sidebar="menu-badge"
|
|
13
|
+
:class="
|
|
14
|
+
cn(
|
|
15
|
+
'mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5',
|
|
16
|
+
'group-data-[collapsible=icon]:hidden',
|
|
17
|
+
props.class,
|
|
18
|
+
)
|
|
19
|
+
"
|
|
20
|
+
>
|
|
21
|
+
<slot />
|
|
22
|
+
</ul>
|
|
23
|
+
</template>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import type { PrimitiveProps } from 'radix-vue';
|
|
4
|
+
import { Primitive } from 'radix-vue';
|
|
5
|
+
import type { HTMLAttributes } from 'vue';
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(
|
|
8
|
+
defineProps<
|
|
9
|
+
PrimitiveProps & {
|
|
10
|
+
size?: 'sm' | 'md';
|
|
11
|
+
isActive?: boolean;
|
|
12
|
+
class?: HTMLAttributes['class'];
|
|
13
|
+
}
|
|
14
|
+
>(),
|
|
15
|
+
{
|
|
16
|
+
as: 'a',
|
|
17
|
+
size: 'md',
|
|
18
|
+
},
|
|
19
|
+
);
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<Primitive
|
|
24
|
+
data-sidebar="menu-sub-button"
|
|
25
|
+
:as="as"
|
|
26
|
+
:as-child="asChild"
|
|
27
|
+
:data-size="size"
|
|
28
|
+
:data-active="isActive"
|
|
29
|
+
:class="
|
|
30
|
+
cn(
|
|
31
|
+
'flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-none ring-sidebar-ring 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 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground',
|
|
32
|
+
'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',
|
|
33
|
+
size === 'sm' && 'text-xs',
|
|
34
|
+
size === 'md' && 'text-sm',
|
|
35
|
+
'group-data-[collapsible=icon]:hidden',
|
|
36
|
+
props.class,
|
|
37
|
+
)
|
|
38
|
+
"
|
|
39
|
+
>
|
|
40
|
+
<slot />
|
|
41
|
+
</Primitive>
|
|
42
|
+
</template>
|