feat(header): improve mobile menu functionality and add navigation rail

This commit is contained in:
Jewgeni Lewash 2024-09-13 07:13:18 +02:00
parent 97b75989b7
commit 6fdffbe5c6
2 changed files with 60 additions and 12 deletions

View File

@ -46,22 +46,20 @@ const setTheme = (document: Document) => {
</script> </script>
<header <header
class="z-10 block h-max w-full max-w-full rounded-none border border-white/80 bg-opacity-80 px-4 py-2 text-black shadow-md backdrop-blur-2xl backdrop-saturate-200 dark:border-black/80 dark:bg-zinc-900 sm:sticky sm:top-0 lg:px-8 lg:py-4"> class="sticky top-0 z-10 block h-16 w-full max-w-full rounded-none border border-white/80 bg-opacity-80 px-4 text-black shadow-md backdrop-blur-2xl backdrop-saturate-200 dark:border-black/80 dark:bg-zinc-900 lg:px-8">
<div class="flex items-center justify-between text-zinc-900 dark:text-zinc-100"> <div class="flex h-full items-center justify-between text-zinc-900 dark:text-zinc-100">
<button id="navToggle" class="hidden sm:block md:hidden" aria-label="Toggle navigation">
<Icon name="line-md:menu" class="h-6 w-6" />
</button>
<a <a
href="/" href="/"
class="mr-4 block cursor-pointer py-1.5 font-sans text-base font-semibold leading-relaxed text-inherit antialiased lg:ml-2"> class="mr-4 block cursor-pointer py-1.5 font-sans text-base font-semibold leading-relaxed text-inherit antialiased lg:ml-2">
<div class="flex items-center gap-2 lg:gap-4"> <div class="flex items-center gap-2 lg:gap-4">
<Image <Image src={logoImage} alt="Astro Deploy" class="size-10 lg:size-14" loading="eager" />
src={logoImage} <span class="hidden sm:inline">Astro Deploy</span>
alt="Astro Deploy"
class="-my-2 size-10 lg:-my-4 lg:size-14"
loading="eager"
/>
Astro Deploy
</div> </div>
</a> </a>
<nav class="hidden items-center space-x-4 sm:flex"> <nav class="hidden items-center space-x-4 md:flex">
{ {
navLinks.map(({ href, label }) => ( navLinks.map(({ href, label }) => (
<HeaderLink <HeaderLink
@ -78,6 +76,27 @@ const setTheme = (document: Document) => {
</div> </div>
</header> </header>
<!-- Navigation Rail -->
<nav
id="navRail"
class="fixed bottom-0 left-0 top-16 z-40 hidden w-16 flex-col items-center justify-start space-y-4 bg-white pt-4 shadow-md transition-transform duration-300 ease-in-out dark:bg-zinc-900 sm:flex md:hidden">
{
navLinks.map(({ href, label, icon }) => (
<HeaderLink
href={href}
class="group flex flex-col items-center justify-center p-2 hover:bg-gray-100 dark:hover:bg-zinc-800">
<Icon
name={icon}
class="mb-1 h-6 w-6 text-gray-500 group-hover:text-blue-600 dark:text-gray-400 dark:group-hover:text-blue-500"
/>
<span class="text-xs text-gray-500 group-hover:text-blue-600 dark:text-gray-400 dark:group-hover:text-blue-500">
{label}
</span>
</HeaderLink>
))
}
</nav>
<!-- Mobile Bottom Navigation --> <!-- Mobile Bottom Navigation -->
<nav <nav
class="fixed bottom-0 left-0 z-50 h-16 w-full border-t border-gray-200 bg-white dark:border-gray-600 dark:bg-zinc-900 sm:hidden"> class="fixed bottom-0 left-0 z-50 h-16 w-full border-t border-gray-200 bg-white dark:border-gray-600 dark:bg-zinc-900 sm:hidden">
@ -99,3 +118,32 @@ const setTheme = (document: Document) => {
} }
</div> </div>
</nav> </nav>
<script>
function setupNavigation() {
const navToggle = document.getElementById('navToggle');
const navRail = document.getElementById('navRail');
const mainContent = document.querySelector('main');
function toggleNavRail() {
navRail?.classList.toggle('-translate-x-full');
mainContent?.classList.toggle('sm:pl-16');
mainContent?.classList.toggle('sm:pl-0');
}
navToggle?.addEventListener('click', toggleNavRail);
// Check if we're on a secondary page and hide the rail if necessary
if (document.body.classList.contains('secondary-page')) {
navRail?.classList.add('-translate-x-full');
mainContent?.classList.remove('sm:pl-16');
mainContent?.classList.add('sm:pl-0');
}
}
// Run the setup on initial load
setupNavigation();
// Re-run the setup after each navigation
document.addEventListener('astro:after-swap', setupNavigation);
</script>

View File

@ -33,8 +33,8 @@ const { title, description, lang = 'en', noindex, nofollow } = Astro.props as Pr
</head> </head>
<body class="flex min-h-screen flex-col dark:bg-secondary"> <body class="flex min-h-screen flex-col dark:bg-secondary">
<Header /> <Header />
<main class="flex-grow"> <main class="flex-grow pb-20 sm:pb-0 sm:pl-16 md:pl-0">
<!-- Increased padding-bottom for mobile --> <!-- Added padding-left for sm screens -->
<slot /> <slot />
</main> </main>
<Footer /> <Footer />