Sidebar is closed when links are clicked on mobile
This commit is contained in:
parent
84252b76bb
commit
3d1627a384
5 changed files with 71 additions and 14 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
|
import { useSidebar } from "~/components/ui/sidebar";
|
||||||
import { useRuntimeConfig } from "#app";
|
import { useRuntimeConfig } from "#app";
|
||||||
import { BookOpen, BookOpenText, ChevronRight, HandCoins, Settings2, SquareTerminal } from "lucide-vue-next";
|
import { BookOpen, BookOpenText, ChevronRight, HandCoins, Settings2, SquareTerminal } from "lucide-vue-next";
|
||||||
|
|
||||||
|
|
@ -99,6 +100,14 @@ const props = withDefaults(defineProps<SidebarLayoutProps>(), {
|
||||||
const navMain = computed(() => props.navItems || data.navMain);
|
const navMain = computed(() => props.navItems || data.navMain);
|
||||||
|
|
||||||
const config = useRuntimeConfig();
|
const config = useRuntimeConfig();
|
||||||
|
|
||||||
|
const { isMobile, setOpenMobile } = useSidebar();
|
||||||
|
|
||||||
|
const closeSidebarOnMobile = () => {
|
||||||
|
if (isMobile.value) {
|
||||||
|
setOpenMobile(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -107,7 +116,7 @@ const config = useRuntimeConfig();
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
<SidebarMenuItem>
|
<SidebarMenuItem>
|
||||||
<SidebarMenuButton size="lg" as-child>
|
<SidebarMenuButton size="lg" as-child>
|
||||||
<NuxtLink to="/">
|
<NuxtLink to="/" @click="closeSidebarOnMobile">
|
||||||
<div
|
<div
|
||||||
class="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground"
|
class="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground"
|
||||||
>
|
>
|
||||||
|
|
@ -147,7 +156,7 @@ const config = useRuntimeConfig();
|
||||||
<SidebarMenuSub>
|
<SidebarMenuSub>
|
||||||
<SidebarMenuSubItem v-for="subItem in item.items" :key="subItem.title">
|
<SidebarMenuSubItem v-for="subItem in item.items" :key="subItem.title">
|
||||||
<SidebarMenuSubButton as-child>
|
<SidebarMenuSubButton as-child>
|
||||||
<NuxtLink :to="subItem.url">
|
<NuxtLink :to="subItem.url" @click="closeSidebarOnMobile">
|
||||||
<span>{{ subItem.title }}</span>
|
<span>{{ subItem.title }}</span>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</SidebarMenuSubButton>
|
</SidebarMenuSubButton>
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import { BadgeCheck, Bell, ChevronsUpDown, CreditCard, LogIn, LogOut } from "luc
|
||||||
|
|
||||||
import type { User } from "better-auth";
|
import type { User } from "better-auth";
|
||||||
|
|
||||||
const { isMobile } = useSidebar();
|
const { isMobile, setOpenMobile } = useSidebar();
|
||||||
|
|
||||||
const props = defineProps<{ user?: User | null | undefined }>();
|
const props = defineProps<{ user?: User | null | undefined }>();
|
||||||
|
|
||||||
|
|
@ -28,12 +28,9 @@ const userInititials = computed(() => {
|
||||||
.join("");
|
.join("");
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleLogout = () => {
|
const handleAuthNavigation = (action: string) => {
|
||||||
navigateTo("/auth/logout");
|
setOpenMobile(false);
|
||||||
};
|
navigateTo(`/auth/${action}`);
|
||||||
|
|
||||||
const handleLogin = () => {
|
|
||||||
navigateTo("/auth/login");
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -93,7 +90,7 @@ const handleLogin = () => {
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</DropdownMenuGroup>
|
</DropdownMenuGroup>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuItem @click="handleLogout">
|
<DropdownMenuItem @click="handleAuthNavigation('logout')">
|
||||||
<LogOut />
|
<LogOut />
|
||||||
Log out
|
Log out
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
|
@ -136,7 +133,7 @@ const handleLogin = () => {
|
||||||
</div>
|
</div>
|
||||||
</DropdownMenuLabel>
|
</DropdownMenuLabel>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuItem @click="handleLogin">
|
<DropdownMenuItem @click="handleAuthNavigation('login')">
|
||||||
<LogIn />
|
<LogIn />
|
||||||
Log in
|
Log in
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
|
|
||||||
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "glowing-fiesta",
|
"name": "glowing-fiesta",
|
||||||
"version": "0.0.5",
|
"version": "0.0.6",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "glowing-fiesta",
|
"name": "glowing-fiesta",
|
||||||
"version": "0.0.5",
|
"version": "0.0.6",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pinia/nuxt": "^0.11.3",
|
"@pinia/nuxt": "^0.11.3",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "glowing-fiesta",
|
"name": "glowing-fiesta",
|
||||||
"version": "0.0.5",
|
"version": "0.0.6",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
|
|
@ -267,4 +267,55 @@ describe("SidebarLayout", () => {
|
||||||
// and renders the menu items.
|
// and renders the menu items.
|
||||||
expect(text).toContain("Playground");
|
expect(text).toContain("Playground");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("calls setOpenMobile(false) when clicking a sub-menu item on mobile", async () => {
|
||||||
|
const setOpenMobile = vi.fn();
|
||||||
|
useSidebarMock.mockReturnValue({
|
||||||
|
isMobile: ref(true),
|
||||||
|
state: ref("expanded"),
|
||||||
|
openMobile: ref(true),
|
||||||
|
setOpenMobile,
|
||||||
|
});
|
||||||
|
|
||||||
|
const wrapper = mount({
|
||||||
|
components: { SidebarLayout },
|
||||||
|
template: "<Suspense><SidebarLayout /></Suspense>",
|
||||||
|
});
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
// Find the link containing 'History' (from default data)
|
||||||
|
const link = wrapper.findAll("a").find((el) => el.text().includes("History"));
|
||||||
|
|
||||||
|
expect(link).toBeDefined();
|
||||||
|
await link.trigger("click");
|
||||||
|
|
||||||
|
expect(setOpenMobile).toHaveBeenCalledTimes(1);
|
||||||
|
expect(setOpenMobile).toHaveBeenCalledWith(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not call setOpenMobile(false) when clicking a sub-menu item on desktop", async () => {
|
||||||
|
const setOpenMobile = vi.fn();
|
||||||
|
useSidebarMock.mockReturnValue({
|
||||||
|
isMobile: ref(false),
|
||||||
|
state: ref("expanded"),
|
||||||
|
openMobile: ref(true),
|
||||||
|
setOpenMobile,
|
||||||
|
});
|
||||||
|
|
||||||
|
const wrapper = mount({
|
||||||
|
components: { SidebarLayout },
|
||||||
|
template: "<Suspense><SidebarLayout /></Suspense>",
|
||||||
|
});
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
// Find the link containing 'History' (from default data)
|
||||||
|
const link = wrapper.findAll("a").find((el) => el.text().includes("History"));
|
||||||
|
|
||||||
|
expect(link).toBeDefined();
|
||||||
|
await link.trigger("click");
|
||||||
|
|
||||||
|
expect(setOpenMobile).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue