@una-ui/nuxt 0.40.0-beta.1 → 0.41.0-beta.1
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/dist/module.json +1 -1
- package/dist/module.mjs +10 -4
- package/dist/runtime/components/data/table/Table.vue +1 -0
- package/dist/runtime/components/elements/Button.vue +1 -0
- package/dist/runtime/components/elements/Link.vue +53 -18
- package/dist/runtime/components/elements/Link.vue.d.ts +1 -0
- package/dist/runtime/components/forms/select/SelectTrigger.vue +2 -1
- package/dist/runtime/components/misc/ThemeSwitcher.vue +5 -3
- package/dist/runtime/components/navigation/breadcrumb/BreadcrumbPage.vue +19 -0
- package/dist/runtime/components/overlays/toast/Toast.vue +3 -3
- package/dist/runtime/components/overlays/toast/ToastClose.vue +1 -1
- package/dist/runtime/components/overlays/toast/ToastDescription.vue +1 -1
- package/dist/runtime/components/overlays/toast/ToastInfo.vue +1 -1
- package/dist/runtime/components/overlays/toast/ToastTitle.vue +1 -1
- package/dist/runtime/components/overlays/toast/ToastViewport.vue +1 -1
- package/dist/runtime/components/sheet/Sheet.vue +64 -62
- package/dist/runtime/components/sidebar/Sidebar.vue +115 -0
- package/dist/runtime/components/sidebar/SidebarContent.vue +22 -0
- package/dist/runtime/components/sidebar/SidebarFooter.vue +19 -0
- package/dist/runtime/components/sidebar/SidebarGroup.vue +28 -0
- package/dist/runtime/components/sidebar/SidebarGroupAction.vue +25 -0
- package/dist/runtime/components/sidebar/SidebarGroupContent.vue +19 -0
- package/dist/runtime/components/sidebar/SidebarGroupLabel.vue +25 -0
- package/dist/runtime/components/sidebar/SidebarHeader.vue +19 -0
- package/dist/runtime/components/sidebar/SidebarInput.vue +20 -0
- package/dist/runtime/components/sidebar/SidebarInset.vue +18 -0
- package/dist/runtime/components/sidebar/SidebarMenu.vue +30 -0
- package/dist/runtime/components/sidebar/SidebarMenuAction.vue +25 -0
- package/dist/runtime/components/sidebar/SidebarMenuBadge.vue +19 -0
- package/dist/runtime/components/sidebar/SidebarMenuButton.vue +59 -0
- package/dist/runtime/components/sidebar/SidebarMenuButtonChild.vue +64 -0
- package/dist/runtime/components/sidebar/SidebarMenuItem.vue +19 -0
- package/dist/runtime/components/sidebar/SidebarMenuSkeleton.vue +37 -0
- package/dist/runtime/components/sidebar/SidebarMenuSub.vue +19 -0
- package/dist/runtime/components/sidebar/SidebarMenuSubButton.vue +31 -0
- package/dist/runtime/components/sidebar/SidebarMenuSubItem.vue +18 -0
- package/dist/runtime/components/sidebar/SidebarProvider.vue +82 -0
- package/dist/runtime/components/sidebar/SidebarRail.vue +26 -0
- package/dist/runtime/components/sidebar/SidebarSeparator.vue +20 -0
- package/dist/runtime/components/sidebar/SidebarTrigger.vue +28 -0
- package/dist/runtime/composables/useSidebar.d.ts +56 -0
- package/dist/runtime/composables/useSidebar.js +8 -0
- package/dist/runtime/types/index.d.ts +1 -0
- package/dist/runtime/types/index.js +1 -0
- package/dist/runtime/types/link.d.ts +1 -1
- package/dist/runtime/types/sheet.d.ts +53 -0
- package/dist/runtime/types/sidebar.d.ts +545 -0
- package/dist/runtime/types/sidebar.js +0 -0
- package/dist/una.config.d.mts +5 -2
- package/dist/una.config.d.ts +5 -2
- package/dist/una.config.mjs +44 -31
- package/package.json +13 -12
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { defineNuxtModule, createResolver, addComponentsDir, addPlugin, addImportsDir, installModule } from '@nuxt/kit';
|
|
2
2
|
import extendUnocssOptions from './una.config.mjs';
|
|
3
|
+
import '@iconify/utils/lib/loader/external-pkg';
|
|
3
4
|
import '@una-ui/extractor-vue-script';
|
|
4
5
|
import '@una-ui/preset';
|
|
5
6
|
import '@una-ui/preset/prefixes';
|
|
@@ -7,7 +8,7 @@ import 'unocss';
|
|
|
7
8
|
import 'unocss-preset-animations';
|
|
8
9
|
|
|
9
10
|
const name = "@una-ui/nuxt";
|
|
10
|
-
const version = "0.
|
|
11
|
+
const version = "0.41.0-beta.1";
|
|
11
12
|
|
|
12
13
|
const module = defineNuxtModule({
|
|
13
14
|
meta: {
|
|
@@ -169,6 +170,13 @@ const module = defineNuxtModule({
|
|
|
169
170
|
watch: nuxt.options.dev,
|
|
170
171
|
priority: 10
|
|
171
172
|
});
|
|
173
|
+
addComponentsDir({
|
|
174
|
+
path: resolve(runtimeDir, "components", "sidebar"),
|
|
175
|
+
prefix: options.prefix,
|
|
176
|
+
global: options.global,
|
|
177
|
+
watch: nuxt.options.dev,
|
|
178
|
+
priority: 10
|
|
179
|
+
});
|
|
172
180
|
addComponentsDir({
|
|
173
181
|
path: resolve(runtimeDir, "components", "scroll-area"),
|
|
174
182
|
prefix: options.prefix,
|
|
@@ -180,10 +188,8 @@ const module = defineNuxtModule({
|
|
|
180
188
|
addPlugin(resolve(runtimeDir, "plugins", "theme.client"));
|
|
181
189
|
addPlugin(resolve(runtimeDir, "plugins", "theme.server"));
|
|
182
190
|
}
|
|
183
|
-
if (!options.dev)
|
|
184
|
-
nuxt.options.unocss = extendUnocssOptions(nuxt.options.unocss);
|
|
185
191
|
addImportsDir(resolve(runtimeDir, "utils", "cn"));
|
|
186
|
-
await installModule("@unocss/nuxt");
|
|
192
|
+
await installModule("@unocss/nuxt", extendUnocssOptions(nuxt.options.unocss));
|
|
187
193
|
await installModule("@nuxtjs/color-mode", {
|
|
188
194
|
classSuffix: ""
|
|
189
195
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { NuxtLink } from "#components";
|
|
3
|
-
import {
|
|
3
|
+
import { useRoute } from "#imports";
|
|
4
|
+
import { diff, isEqual } from "ohash/utils";
|
|
4
5
|
import { defineComponent } from "vue";
|
|
5
6
|
export default defineComponent({
|
|
6
7
|
inheritAttrs: false,
|
|
@@ -24,7 +25,7 @@ export default defineComponent({
|
|
|
24
25
|
type: String,
|
|
25
26
|
default: void 0
|
|
26
27
|
},
|
|
27
|
-
// preset
|
|
28
|
+
// TODO: convert to sidebar preset
|
|
28
29
|
navLinkActive: {
|
|
29
30
|
type: String,
|
|
30
31
|
default: void 0
|
|
@@ -35,10 +36,11 @@ export default defineComponent({
|
|
|
35
36
|
}
|
|
36
37
|
},
|
|
37
38
|
setup(props) {
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
const route = useRoute();
|
|
40
|
+
function resolveLinkClass(route2, $route, { isActive, isExactActive }) {
|
|
41
|
+
if (props.exactQuery && !isEqual(route2.query, $route.query))
|
|
40
42
|
return props.inactiveClass;
|
|
41
|
-
if (props.exactHash && !isEqual(
|
|
43
|
+
if (props.exactHash && !isEqual(route2.hash, $route.hash))
|
|
42
44
|
return props.inactiveClass;
|
|
43
45
|
if (props.exact && isExactActive)
|
|
44
46
|
return props.exactActiveClass;
|
|
@@ -46,10 +48,10 @@ export default defineComponent({
|
|
|
46
48
|
return props.activeClass;
|
|
47
49
|
return props.inactiveClass;
|
|
48
50
|
}
|
|
49
|
-
function resolveNavLinkActive(
|
|
50
|
-
if (props.exactQuery && !isEqual(
|
|
51
|
+
function resolveNavLinkActive(route2, $route, { isActive, isExactActive }) {
|
|
52
|
+
if (props.exactQuery && !isEqual(route2.query, $route.query))
|
|
51
53
|
return null;
|
|
52
|
-
if (props.exactHash && !isEqual(
|
|
54
|
+
if (props.exactHash && !isEqual(route2.hash, $route.hash))
|
|
53
55
|
return null;
|
|
54
56
|
if (props.exact && isExactActive)
|
|
55
57
|
return props.navLinkActive;
|
|
@@ -57,42 +59,75 @@ export default defineComponent({
|
|
|
57
59
|
return props.navLinkActive;
|
|
58
60
|
return null;
|
|
59
61
|
}
|
|
60
|
-
function resolveNavLinkInactive(
|
|
61
|
-
if (props.exactQuery && !isEqual(
|
|
62
|
+
function resolveNavLinkInactive(route2, $route, { isActive, isExactActive }) {
|
|
63
|
+
if (props.exactQuery && !isEqual(route2.query, $route.query))
|
|
62
64
|
return props.navLinkInactive;
|
|
63
|
-
if (props.exactHash && !isEqual(
|
|
65
|
+
if (props.exactHash && !isEqual(route2.hash, $route.hash))
|
|
64
66
|
return props.navLinkInactive;
|
|
65
67
|
if (!props.exact && isActive || props.exact && isExactActive)
|
|
66
68
|
return null;
|
|
67
69
|
return props.navLinkInactive;
|
|
68
70
|
}
|
|
71
|
+
function isPartiallyEqual(item1, item2) {
|
|
72
|
+
const diffedKeys = diff(item1, item2).reduce((filtered, q) => {
|
|
73
|
+
if (q.type === "added") {
|
|
74
|
+
filtered.add(q.key);
|
|
75
|
+
}
|
|
76
|
+
return filtered;
|
|
77
|
+
}, /* @__PURE__ */ new Set());
|
|
78
|
+
const item1Filtered = Object.fromEntries(Object.entries(item1).filter(([key]) => !diffedKeys.has(key)));
|
|
79
|
+
const item2Filtered = Object.fromEntries(Object.entries(item2).filter(([key]) => !diffedKeys.has(key)));
|
|
80
|
+
return isEqual(item1Filtered, item2Filtered);
|
|
81
|
+
}
|
|
82
|
+
function isLinkActive({ route: linkRoute, isActive, isExactActive }) {
|
|
83
|
+
if (props.active !== void 0) {
|
|
84
|
+
return props.active;
|
|
85
|
+
}
|
|
86
|
+
if (props.exactQuery === "partial") {
|
|
87
|
+
if (!isPartiallyEqual(linkRoute.query, route.query))
|
|
88
|
+
return false;
|
|
89
|
+
} else if (props.exactQuery === true) {
|
|
90
|
+
if (!isEqual(linkRoute.query, route.query))
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
if (props.exactHash && linkRoute.hash !== route.hash) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
if (props.exact && isExactActive) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
if (!props.exact && isActive) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
69
104
|
return {
|
|
70
105
|
resolveLinkClass,
|
|
71
106
|
resolveNavLinkActive,
|
|
72
|
-
resolveNavLinkInactive
|
|
107
|
+
resolveNavLinkInactive,
|
|
108
|
+
isLinkActive
|
|
73
109
|
};
|
|
74
110
|
}
|
|
75
111
|
});
|
|
76
112
|
</script>
|
|
77
113
|
|
|
78
114
|
<template>
|
|
79
|
-
<!-- eslint-disable vue/no-template-shadow -->
|
|
80
115
|
<NuxtLink
|
|
81
|
-
v-slot="{ route, href, target, rel, navigate, isActive, isExactActive, isExternal
|
|
116
|
+
v-slot="{ route, href, target, rel, navigate, isActive, isExactActive, isExternal }"
|
|
82
117
|
v-bind="$props"
|
|
83
118
|
custom
|
|
84
119
|
>
|
|
85
120
|
<a
|
|
86
121
|
v-bind="$attrs"
|
|
87
|
-
:href
|
|
88
|
-
:rel="rel"
|
|
89
|
-
:target="target"
|
|
122
|
+
:href
|
|
123
|
+
:rel="rel ?? undefined"
|
|
124
|
+
:target="target ?? undefined"
|
|
90
125
|
:class="resolveLinkClass(route, $route, { isActive, isExactActive })"
|
|
91
126
|
:nav-link-active="resolveNavLinkActive(route, $route, { isActive, isExactActive })"
|
|
92
127
|
:nav-link-inactive="resolveNavLinkInactive(route, $route, { isActive, isExactActive })"
|
|
93
128
|
@click="(e) => !isExternal && navigate(e)"
|
|
94
129
|
>
|
|
95
|
-
<slot
|
|
130
|
+
<slot :active="isLinkActive({ route, isActive, isExactActive })" />
|
|
96
131
|
</a>
|
|
97
132
|
</NuxtLink>
|
|
98
133
|
</template>
|
|
@@ -11,6 +11,7 @@ declare const _default: import("vue").DefineComponent<{}, {
|
|
|
11
11
|
isActive: boolean;
|
|
12
12
|
isExactActive: boolean;
|
|
13
13
|
}) => string | null;
|
|
14
|
+
isLinkActive: ({ route: linkRoute, isActive, isExactActive }: any) => any;
|
|
14
15
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {} | {
|
|
15
16
|
[x: string]: any;
|
|
16
17
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -25,7 +25,7 @@ const statusClassVariants = computed(() => {
|
|
|
25
25
|
success: props.una?.selectTriggerSuccessIcon ?? 'select-trigger-success-icon',
|
|
26
26
|
warning: props.una?.selectTriggerWarningIcon ?? 'select-trigger-warning-icon',
|
|
27
27
|
error: props.una?.selectTriggerErrorIcon ?? 'select-trigger-error-icon',
|
|
28
|
-
default: props.una?.selectTriggerTrailingIcon ?? 'select-trigger-trailing-icon',
|
|
28
|
+
default: props?.trailing ?? props.una?.selectTriggerTrailingIcon ?? 'select-trigger-trailing-icon',
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
return {
|
|
@@ -35,6 +35,7 @@ const statusClassVariants = computed(() => {
|
|
|
35
35
|
})
|
|
36
36
|
|
|
37
37
|
const id = computed(() => props.id ?? randomId('select-trigger'))
|
|
38
|
+
const status = computed(() => props.status ?? 'default')
|
|
38
39
|
</script>
|
|
39
40
|
|
|
40
41
|
<template>
|
|
@@ -48,9 +48,11 @@ function shuffleTheme(): void {
|
|
|
48
48
|
</script>
|
|
49
49
|
|
|
50
50
|
<template>
|
|
51
|
-
<Popover
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
<Popover
|
|
52
|
+
:_popover-content="{ align: 'end', class: 'w-73 bg-muted' }"
|
|
53
|
+
>
|
|
54
|
+
<template #trigger="{ open }">
|
|
55
|
+
<slot name="trigger" :open="open">
|
|
54
56
|
<Button
|
|
55
57
|
btn="soft"
|
|
56
58
|
square
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
import { cn } from '../../../utils'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class']
|
|
7
|
+
}>()
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<span
|
|
12
|
+
role="link"
|
|
13
|
+
aria-disabled="true"
|
|
14
|
+
aria-current="page"
|
|
15
|
+
:class="cn('font-normal text-base', props.class)"
|
|
16
|
+
>
|
|
17
|
+
<slot />
|
|
18
|
+
</span>
|
|
19
|
+
</template>
|
|
@@ -23,7 +23,7 @@ const props = withDefaults(defineProps<NToastProps>(), {
|
|
|
23
23
|
})
|
|
24
24
|
|
|
25
25
|
const emits = defineEmits<ToastRootEmits>()
|
|
26
|
-
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'defaultOpen', 'open', 'duration', 'type'), emits)
|
|
26
|
+
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'asChild', 'defaultOpen', 'open', 'duration', 'type', 'forceMount'), emits)
|
|
27
27
|
</script>
|
|
28
28
|
|
|
29
29
|
<template>
|
|
@@ -31,10 +31,10 @@ const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'defaultOpen',
|
|
|
31
31
|
v-slot="{ remaining, duration }"
|
|
32
32
|
:class="cn(
|
|
33
33
|
'group toast data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--reka-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--reka-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full',
|
|
34
|
-
props.class,
|
|
35
34
|
props.una?.toast,
|
|
35
|
+
props.class,
|
|
36
36
|
)"
|
|
37
|
-
v-bind="rootProps"
|
|
37
|
+
v-bind="{ ...rootProps, ...$attrs }"
|
|
38
38
|
:toast
|
|
39
39
|
@update:open="onOpenChange"
|
|
40
40
|
>
|
|
@@ -30,73 +30,75 @@ const forwarded = useForwardPropsEmits(rootProps, emits)
|
|
|
30
30
|
|
|
31
31
|
<template>
|
|
32
32
|
<DialogRoot v-slot="{ open }" v-bind="forwarded">
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
<slot name="root">
|
|
34
|
+
<SheetTrigger
|
|
35
|
+
v-if="$slots.trigger"
|
|
36
|
+
v-bind="_sheetTrigger"
|
|
37
|
+
>
|
|
38
|
+
<slot name="trigger" :open />
|
|
39
|
+
</SheetTrigger>
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
41
|
+
<SheetContent
|
|
42
|
+
:_sheet-close
|
|
43
|
+
:_sheet-overlay
|
|
44
|
+
:_sheet-portal
|
|
45
|
+
:sheet
|
|
46
|
+
:prevent-close
|
|
47
|
+
:show-close
|
|
48
|
+
:overlay
|
|
49
|
+
v-bind="_sheetContent"
|
|
50
|
+
:una
|
|
51
|
+
>
|
|
52
|
+
<VisuallyHidden v-if="(title === DEFAULT_TITLE || !!$slots.title) || (description === DEFAULT_DESCRIPTION || !!$slots.description)">
|
|
53
|
+
<SheetTitle v-if="title === DEFAULT_TITLE || !!$slots.title">
|
|
54
|
+
{{ title }}
|
|
55
|
+
</SheetTitle>
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
<SheetDescription v-if="description === DEFAULT_DESCRIPTION || !!$slots.description">
|
|
58
|
+
{{ description }}
|
|
59
|
+
</SheetDescription>
|
|
60
|
+
</VisuallyHidden>
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
62
|
+
<slot name="content">
|
|
63
|
+
<SheetHeader
|
|
64
|
+
v-if="!!$slots.header || (title !== DEFAULT_TITLE || !!$slots.title) || (description !== DEFAULT_DESCRIPTION || !!$slots.description)"
|
|
65
|
+
v-bind="_sheetHeader"
|
|
66
|
+
:una
|
|
67
|
+
>
|
|
68
|
+
<slot name="header">
|
|
69
|
+
<SheetTitle
|
|
70
|
+
v-if="$slots.title || title !== DEFAULT_TITLE"
|
|
71
|
+
v-bind="_sheetTitle"
|
|
72
|
+
:una
|
|
73
|
+
>
|
|
74
|
+
<slot name="title">
|
|
75
|
+
{{ title }}
|
|
76
|
+
</slot>
|
|
77
|
+
</SheetTitle>
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
79
|
+
<SheetDescription
|
|
80
|
+
v-if="$slots.description || description !== DEFAULT_DESCRIPTION"
|
|
81
|
+
v-bind="_sheetDescription"
|
|
82
|
+
:una
|
|
83
|
+
>
|
|
84
|
+
<slot name="description">
|
|
85
|
+
{{ description }}
|
|
86
|
+
</slot>
|
|
87
|
+
</SheetDescription>
|
|
88
|
+
</slot>
|
|
89
|
+
</SheetHeader>
|
|
89
90
|
|
|
90
|
-
|
|
91
|
+
<slot />
|
|
91
92
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
93
|
+
<SheetFooter
|
|
94
|
+
v-if="$slots.footer"
|
|
95
|
+
v-bind="_sheetFooter"
|
|
96
|
+
:una
|
|
97
|
+
>
|
|
98
|
+
<slot name="footer" />
|
|
99
|
+
</SheetFooter>
|
|
100
|
+
</slot>
|
|
101
|
+
</SheetContent>
|
|
102
|
+
</slot>
|
|
101
103
|
</DialogRoot>
|
|
102
104
|
</template>
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { NSidebarProps } from '../../types'
|
|
3
|
+
import { createReusableTemplate } from '@vueuse/core'
|
|
4
|
+
import { SIDEBAR_WIDTH_MOBILE, useSidebar } from '../../composables/useSidebar'
|
|
5
|
+
import { cn } from '../../utils'
|
|
6
|
+
import Sheet from '../sheet/Sheet.vue'
|
|
7
|
+
import SidebarContent from './SidebarContent.vue'
|
|
8
|
+
import SidebarFooter from './SidebarFooter.vue'
|
|
9
|
+
import SidebarHeader from './SidebarHeader.vue'
|
|
10
|
+
|
|
11
|
+
defineOptions({
|
|
12
|
+
inheritAttrs: false,
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const props = withDefaults(defineProps<NSidebarProps>(), {
|
|
16
|
+
sheet: 'left',
|
|
17
|
+
sidebar: 'sidebar',
|
|
18
|
+
collapsible: 'offcanvas',
|
|
19
|
+
rail: true,
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
|
|
23
|
+
|
|
24
|
+
const [DefineSlot, ReuseSlot] = createReusableTemplate()
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<template>
|
|
28
|
+
<DefineSlot>
|
|
29
|
+
<slot>
|
|
30
|
+
<SidebarHeader v-bind="props._sidebarHeader">
|
|
31
|
+
<slot name="header" />
|
|
32
|
+
</SidebarHeader>
|
|
33
|
+
<SidebarContent v-bind="props._sidebarContent">
|
|
34
|
+
<slot name="content" />
|
|
35
|
+
</SidebarContent>
|
|
36
|
+
<SidebarFooter v-bind="props._sidebarFooter">
|
|
37
|
+
<slot name="footer" />
|
|
38
|
+
</SidebarFooter>
|
|
39
|
+
<NSidebarRail v-if="rail" v-bind="props._sidebarRail" />
|
|
40
|
+
</slot>
|
|
41
|
+
</DefineSlot>
|
|
42
|
+
|
|
43
|
+
<div
|
|
44
|
+
v-if="collapsible === 'none'"
|
|
45
|
+
:class="cn(
|
|
46
|
+
'sidebar-collapsible-none',
|
|
47
|
+
props.una?.sidebar,
|
|
48
|
+
props.class,
|
|
49
|
+
)"
|
|
50
|
+
v-bind="$attrs"
|
|
51
|
+
>
|
|
52
|
+
<ReuseSlot />
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<Sheet
|
|
56
|
+
v-else-if="isMobile"
|
|
57
|
+
:open="openMobile"
|
|
58
|
+
v-bind="$attrs"
|
|
59
|
+
:_sheet-content="{
|
|
60
|
+
dataSidebar: 'sidebar',
|
|
61
|
+
dataMobile: true,
|
|
62
|
+
sheet,
|
|
63
|
+
class: 'sidebar-mobile',
|
|
64
|
+
style: {
|
|
65
|
+
'--sidebar-width': SIDEBAR_WIDTH_MOBILE,
|
|
66
|
+
},
|
|
67
|
+
...props._sheetContent,
|
|
68
|
+
}"
|
|
69
|
+
@update:open="setOpenMobile"
|
|
70
|
+
>
|
|
71
|
+
<div class="sidebar-mobile-inner">
|
|
72
|
+
<ReuseSlot />
|
|
73
|
+
</div>
|
|
74
|
+
</Sheet>
|
|
75
|
+
|
|
76
|
+
<div
|
|
77
|
+
v-else :class="cn('group peer sidebar-desktop')"
|
|
78
|
+
:data-state="state"
|
|
79
|
+
:data-collapsible="state === 'collapsed' ? collapsible : ''"
|
|
80
|
+
:data-variant="sidebar"
|
|
81
|
+
:data-side="sheet"
|
|
82
|
+
>
|
|
83
|
+
<!-- This is what handles the sidebar gap on desktop -->
|
|
84
|
+
<div
|
|
85
|
+
:class="cn(
|
|
86
|
+
'sidebar-desktop-gap',
|
|
87
|
+
sidebar === 'floating' || sidebar === 'inset'
|
|
88
|
+
? 'sidebar-desktop-gap-floating'
|
|
89
|
+
: 'sidebar-desktop-gap-default',
|
|
90
|
+
)"
|
|
91
|
+
/>
|
|
92
|
+
<div
|
|
93
|
+
:class="cn(
|
|
94
|
+
'sidebar-desktop-position',
|
|
95
|
+
sheet === 'left'
|
|
96
|
+
? 'sidebar-desktop-position-left'
|
|
97
|
+
: 'sidebar-desktop-position-right',
|
|
98
|
+
// Adjust the padding for floating and inset variants.
|
|
99
|
+
sidebar === 'floating' || sidebar === 'inset'
|
|
100
|
+
? 'sidebar-desktop-padding-floating'
|
|
101
|
+
: 'sidebar-desktop-padding-default',
|
|
102
|
+
props.una?.sidebar,
|
|
103
|
+
props.class,
|
|
104
|
+
)"
|
|
105
|
+
v-bind="$attrs"
|
|
106
|
+
>
|
|
107
|
+
<div
|
|
108
|
+
data-sidebar="sidebar"
|
|
109
|
+
class="sidebar-desktop-inner"
|
|
110
|
+
>
|
|
111
|
+
<ReuseSlot />
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { NSidebarContentProps } from '../../types'
|
|
3
|
+
import { cn } from '../../utils'
|
|
4
|
+
import ScrollArea from '../scroll-area/ScrollArea.vue'
|
|
5
|
+
|
|
6
|
+
const props = defineProps<NSidebarContentProps>()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<div
|
|
11
|
+
data-sidebar="content"
|
|
12
|
+
:class="cn(
|
|
13
|
+
'sidebar-content',
|
|
14
|
+
props.una?.sidebarContent,
|
|
15
|
+
props.class,
|
|
16
|
+
)"
|
|
17
|
+
>
|
|
18
|
+
<ScrollArea>
|
|
19
|
+
<slot />
|
|
20
|
+
</ScrollArea>
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { NSidebarFooterProps } from '../../types'
|
|
3
|
+
import { cn } from '../../utils'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<NSidebarFooterProps>()
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<div
|
|
10
|
+
data-sidebar="footer"
|
|
11
|
+
:class="cn(
|
|
12
|
+
'sidebar-footer',
|
|
13
|
+
props.una?.sidebarFooter,
|
|
14
|
+
props.class,
|
|
15
|
+
)"
|
|
16
|
+
>
|
|
17
|
+
<slot />
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { NSidebarGroupProps } from '../../types'
|
|
3
|
+
import { cn } from '../../utils'
|
|
4
|
+
import SidebarGroupLabel from './SidebarGroupLabel.vue'
|
|
5
|
+
|
|
6
|
+
const props = defineProps<NSidebarGroupProps>()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<div
|
|
11
|
+
data-sidebar="group"
|
|
12
|
+
:class="cn(
|
|
13
|
+
'sidebar-group',
|
|
14
|
+
props.una?.sidebarGroup,
|
|
15
|
+
props.class,
|
|
16
|
+
)"
|
|
17
|
+
>
|
|
18
|
+
<slot name="root">
|
|
19
|
+
<SidebarGroupLabel v-if="props.label">
|
|
20
|
+
<slot name="label">
|
|
21
|
+
{{ props.label }}
|
|
22
|
+
</slot>
|
|
23
|
+
</SidebarGroupLabel>
|
|
24
|
+
|
|
25
|
+
<slot />
|
|
26
|
+
</slot>
|
|
27
|
+
</div>
|
|
28
|
+
</template>
|