Skip to content

Commit 5d6a7ce

Browse files
authored
PR.19 refactor/mobile-nav-cleanup
refactor: restructure mobile nav to use Sheet subcomponents
2 parents 4d05526 + ba675c0 commit 5d6a7ce

4 files changed

Lines changed: 32 additions & 41 deletions

File tree

components/navigation/mobile-nav.tsx

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import {
1818
Sheet,
1919
SheetClose,
2020
SheetContent,
21-
SheetDescription,
21+
SheetFooter,
22+
SheetHeader,
2223
SheetTitle,
2324
SheetTrigger,
2425
} from "@/components/ui/sheet";
@@ -31,8 +32,8 @@ export function MobileNav() {
3132

3233
return (
3334
<>
34-
{/* Tap-to-dismiss overlay: modal={false} allows Clerk popups to work (they render
35-
outside Sheet), but disables SheetOverlay dismiss. See authenticated.mobile.spec.ts */}
35+
{/* modal={false} allows Clerk popups to work (they render outside Sheet), but
36+
disables SheetOverlay dismiss. See authenticated.mobile.spec.ts */}
3637
{open && (
3738
<button
3839
type="button"
@@ -61,21 +62,16 @@ export function MobileNav() {
6162
MOBILE_NAV_MAX_WIDTH,
6263
)}
6364
>
64-
{/* Visually hidden title and description for accessibility */}
65-
<SheetTitle className="sr-only">Navigation menu</SheetTitle>
66-
<SheetDescription className="sr-only">
67-
Browse site pages and manage your account
68-
</SheetDescription>
65+
<SheetHeader className="flex-row items-center p-0">
66+
<SheetTitle className="sr-only">Mobile navigation menu</SheetTitle>
67+
<SheetClose asChild>
68+
<Link href="/" className="flex items-center">
69+
<ThemeLogo />
70+
</Link>
71+
</SheetClose>
72+
</SheetHeader>
6973

70-
{/* Logo */}
71-
<SheetClose asChild>
72-
<Link href="/" className="flex items-center">
73-
<ThemeLogo />
74-
</Link>
75-
</SheetClose>
76-
77-
{/* Navigation Links */}
78-
<nav className="flex flex-col gap-3 pt-4">
74+
<nav className="flex flex-1 flex-col gap-3 pt-5">
7975
{NAV_LINKS.map((link) => (
8076
<SheetClose key={link.route} asChild>
8177
<NavLink
@@ -87,21 +83,20 @@ export function MobileNav() {
8783
))}
8884
</nav>
8985

90-
{/* Avatar - Only when signed in */}
91-
<SignedIn>
92-
<div className="mt-auto">
93-
<UserButton />
94-
</div>
95-
</SignedIn>
96-
97-
{/* Auth Buttons - Only when signed out */}
98-
<SignedOut>
99-
<div className="mt-auto flex flex-col gap-3">
86+
<SheetFooter className="gap-3 p-0 pb-4">
87+
<SignedIn>
88+
<UserButton
89+
appearance={{
90+
elements: { userButtonAvatarBox: "size-10" },
91+
}}
92+
/>
93+
</SignedIn>
94+
<SignedOut>
10095
<SignInButton>
10196
<Button
10297
variant="soft"
10398
size="lg"
104-
className="w-full"
99+
className="w-full text-base"
105100
onClick={() => setOpen(false)}
106101
>
107102
<span className="bg-(image:--gradient-primary) bg-clip-text text-transparent">
@@ -113,14 +108,14 @@ export function MobileNav() {
113108
<Button
114109
variant="muted"
115110
size="lg"
116-
className="w-full"
111+
className="w-full text-base"
117112
onClick={() => setOpen(false)}
118113
>
119114
Sign up
120115
</Button>
121116
</SignUpButton>
122-
</div>
123-
</SignedOut>
117+
</SignedOut>
118+
</SheetFooter>
124119
</SheetContent>
125120
</Sheet>
126121
</>

components/navigation/nav-link.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ type NavLinkProps = NavLinkType & {
1717
onClick?: () => void;
1818
};
1919

20-
/**
21-
* Mobile navigation link for Sheet menu.
22-
* Desktop sidebar uses SidebarMenuButton directly in AppSidebar.
23-
*/
20+
/** Navigation link for mobile Sheet menu. */
2421
export function NavLink({ imgURL, route, label, onClick }: NavLinkProps) {
2522
const pathname = usePathname();
2623
const isActive = isRouteActive(pathname, route);
@@ -30,7 +27,7 @@ export function NavLink({ imgURL, route, label, onClick }: NavLinkProps) {
3027
href={route}
3128
onClick={onClick}
3229
className={cn(
33-
"flex items-center gap-3 rounded-lg px-4 py-3",
30+
"flex items-center gap-3 rounded-lg px-3 py-3",
3431
isActive
3532
? NAV_LINK_ACTIVE_CLASSES
3633
: `${NAV_LINK_INACTIVE_CLASSES} text-sidebar-foreground hover:bg-muted`,

hooks/use-mobile.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ import * as React from "react";
33
const MOBILE_BREAKPOINT = 640; // tailwind sm breakpoint
44

55
export function useIsMobile() {
6-
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
7-
undefined,
8-
);
6+
// Start with false to match server-rendered HTML and prevent hydration mismatch
7+
const [isMobile, setIsMobile] = React.useState(false);
98

109
React.useEffect(() => {
1110
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
@@ -17,5 +16,5 @@ export function useIsMobile() {
1716
return () => mql.removeEventListener("change", onChange);
1817
}, []);
1918

20-
return !!isMobile;
19+
return isMobile;
2120
}

public/icons/star.svg

Lines changed: 1 addition & 1 deletion
Loading

0 commit comments

Comments
 (0)