feat(nav): add full-width mobile glass dock
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { Metadata } from "next";
|
||||
import type { Metadata, Viewport } from "next";
|
||||
import localFont from "next/font/local";
|
||||
import { Suspense } from "react";
|
||||
import MobileBottomNav from "@/components/MobileBottomNav";
|
||||
@@ -18,6 +18,12 @@ const vazirmatn = localFont({
|
||||
fallback: ["Tahoma", "Arial", "sans-serif"],
|
||||
});
|
||||
|
||||
export const viewport: Viewport = {
|
||||
width: "device-width",
|
||||
initialScale: 1,
|
||||
viewportFit: "cover",
|
||||
};
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
const siteContent = await getCmsSiteContent();
|
||||
const title = siteContent.seo.title || siteContent.official_name;
|
||||
@@ -61,7 +67,7 @@ export default async function RootLayout({
|
||||
<RouteProgress />
|
||||
</Suspense>
|
||||
<Navbar siteContent={siteContent} />
|
||||
<div className="flex min-h-[calc(100svh-4.5rem)] flex-1 flex-col pb-28 md:pb-0">
|
||||
<div className="flex min-h-[calc(100svh-4.5rem)] flex-1 flex-col pb-[calc(5.5rem+env(safe-area-inset-bottom))] md:pb-0">
|
||||
<div id="main-content" tabIndex={-1} className="flex-1 outline-none">
|
||||
{children}
|
||||
</div>
|
||||
|
||||
@@ -28,7 +28,7 @@ export default function Footer({ siteContent }: { siteContent: SiteContent }) {
|
||||
].filter((contact) => contact !== null);
|
||||
|
||||
return (
|
||||
<footer className="bg-footer text-footer-foreground" dir="rtl">
|
||||
<footer className="bg-footer pb-[calc(5.5rem+env(safe-area-inset-bottom))] text-footer-foreground md:pb-0" dir="rtl">
|
||||
<div className="container mx-auto px-4 py-10 md:py-12">
|
||||
<div className="grid gap-9 sm:grid-cols-2 lg:grid-cols-[1.5fr_0.8fr_1fr]">
|
||||
<div className="space-y-4">
|
||||
|
||||
@@ -63,13 +63,10 @@ export default function MobileBottomNav({ siteContent }: { siteContent: SiteCont
|
||||
];
|
||||
|
||||
return (
|
||||
<div
|
||||
className="fixed inset-x-0 z-50 px-4 md:hidden"
|
||||
style={{ bottom: "calc(env(safe-area-inset-bottom) + 0.9rem)" }}
|
||||
>
|
||||
<div className="fixed inset-x-0 bottom-0 z-50 md:hidden">
|
||||
<nav
|
||||
aria-label="ناوبری اصلی موبایل"
|
||||
className="mx-auto flex w-full max-w-md items-center justify-between rounded-2xl border border-border bg-background/95 px-1.5 py-1.5 shadow-lg backdrop-blur-xl"
|
||||
className="mobile-bottom-nav flex w-full items-stretch justify-around px-2 pt-2 pb-[calc(env(safe-area-inset-bottom)+0.5rem)]"
|
||||
dir="rtl"
|
||||
>
|
||||
{items.map((item) => {
|
||||
@@ -81,14 +78,21 @@ export default function MobileBottomNav({ siteContent }: { siteContent: SiteCont
|
||||
key={item.key}
|
||||
to={item.href}
|
||||
className={cn(
|
||||
"flex min-h-11 min-w-0 flex-1 flex-col items-center justify-center gap-0.5 rounded-xl px-1 py-1.5 text-[10px] font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
||||
"relative flex min-h-[4.25rem] min-w-0 flex-1 flex-col items-center justify-center gap-1 rounded-xl px-1 pt-2 pb-1 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
||||
active
|
||||
? "bg-secondary text-primary"
|
||||
: "text-muted-foreground hover:bg-secondary hover:text-foreground",
|
||||
? "text-primary"
|
||||
: "text-foreground/75 hover:text-foreground",
|
||||
)}
|
||||
aria-current={active ? "page" : undefined}
|
||||
>
|
||||
<Icon aria-hidden="true" className="h-4 w-4" />
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className={cn(
|
||||
"absolute top-0.5 h-0.5 w-5 rounded-full transition-colors",
|
||||
active ? "bg-primary" : "bg-transparent",
|
||||
)}
|
||||
/>
|
||||
<Icon aria-hidden="true" className="h-6 w-6 shrink-0" />
|
||||
<span className="max-w-full truncate">{item.label}</span>
|
||||
</Link>
|
||||
);
|
||||
|
||||
@@ -120,7 +120,7 @@ export default function Navbar({ siteContent }: { siteContent: SiteContent }) {
|
||||
return (
|
||||
<nav
|
||||
aria-label="ناوبری اصلی"
|
||||
className="sticky top-0 z-40 border-b border-border bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/85"
|
||||
className="sticky top-0 z-40 border-b border-border bg-background/95 pt-[env(safe-area-inset-top)] backdrop-blur supports-[backdrop-filter]:bg-background/85 md:pt-0"
|
||||
dir="rtl"
|
||||
>
|
||||
<div className="container mx-auto px-4 py-2">
|
||||
|
||||
@@ -127,6 +127,28 @@ All colors MUST be HSL.
|
||||
@apply bg-background font-sans text-foreground;
|
||||
}
|
||||
|
||||
.mobile-bottom-nav {
|
||||
border-top: 1px solid hsl(var(--border) / 0.7);
|
||||
background-color: hsl(var(--background) / 0.82);
|
||||
box-shadow: 0 -0.75rem 2rem hsl(var(--foreground) / 0.08);
|
||||
-webkit-backdrop-filter: blur(1.25rem) saturate(1.35);
|
||||
backdrop-filter: blur(1.25rem) saturate(1.35);
|
||||
}
|
||||
|
||||
@supports not (backdrop-filter: blur(1px)) {
|
||||
.mobile-bottom-nav {
|
||||
background-color: hsl(var(--background));
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-transparency: reduce) {
|
||||
.mobile-bottom-nav {
|
||||
background-color: hsl(var(--background));
|
||||
-webkit-backdrop-filter: none;
|
||||
backdrop-filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
outline: 2px solid hsl(var(--ring));
|
||||
outline-offset: 3px;
|
||||
|
||||
Reference in New Issue
Block a user