This component provides a responsive navigation bar for a web application. It includes a logo and navigation links, which adapt for desktop and mobile views. On mobile devices, a burger menu icon allows toggling the visibility of the menu.
To integrate this component into your Nuxt 3 application:
<script setup lang="ts">
const mobileMenuOpen = ref(false);
const navigationLinks = [
{ name: 'ui', label: 'UI', href: '' },
{ name: 'projects', label: 'Projects', href: '' },
{ name: 'blog', label: 'Blog', href: '' },
];
const route = useRoute();
const navigation = computed(() => {
return navigationLinks.map((link) => ({
...link,
current: (route.name as string).includes(link.name),
}));
});
const mobileMenuIcon = computed(() => {
return mobileMenuOpen.value
? 'solar:close-square-linear'
: 'solar:menu-dots-square-bold';
});
function toggleMobileMenu() {
mobileMenuOpen.value = !mobileMenuOpen.value;
}
</script>
<template>
<div
class="h-72 w-full overflow-hidden rounded-md border-4 border-black dark:border-primary"
>
<nav
class="top-0 z-20 mx-auto w-full max-w-7xl bg-black duration-700 ease-out dark:bg-primary"
>
<div
class="flex items-center justify-between px-sm py-2 md:px-lg md:py-4 lg:px-0"
>
<NuxtLink
to="/"
class="flex cursor-pointer items-center text-primary decoration-transparent dark:text-black dark:decoration-transparent"
>
<!-- Logo and brand name for all screen sizes -->
<Icon
name="mdi:skull-crossbones"
size="2rem"
/>
<span class="ml-2 text-3xl font-semibold tracking-tight"
>Cool Project</span
>
</NuxtLink>
<div class="hidden items-center space-x-4 md:flex">
<!-- Links for desktop -->
<div
v-for="link in navigation"
:key="link.name"
>
<NuxtLink
:to="link.href"
class="cursor-pointer rounded-md px-3 py-2 text-base font-normal text-primary decoration-transparent transition-colors duration-150 hover:bg-primary hover:text-black dark:text-black dark:decoration-transparent dark:hover:bg-black dark:hover:text-primary"
:class="{
' border-4 border-primary dark:border-black ': link.current,
}"
>
{{ link.label }}
</NuxtLink>
</div>
</div>
<!-- Burger icon for mobile -->
<div class="flex items-center text-primary dark:text-black md:hidden">
<button @click="toggleMobileMenu()">
<Icon
:name="mobileMenuIcon"
size="2rem"
/>
</button>
</div>
</div>
</nav>
<!-- Mobile menu -->
<div class="flex overflow-hidden">
<div
class="left-0 top-0 z-10 w-full transform bg-black text-primary transition-all duration-300 ease-in-out md:hidden"
:class="{
'-translate-y-64': !mobileMenuOpen,
'-translate-y-1': mobileMenuOpen,
}"
>
<div
v-for="link in navigation"
:key="link.name"
class="flex py-2 text-xl"
>
<NuxtLink
:to="link.href"
class="w-full rounded px-3 py-2 text-primary decoration-transparent dark:text-primary dark:decoration-transparent"
:class="{ 'border-4 border-primary': link.current }"
>
{{ link.label }}
</NuxtLink>
</div>
</div>
<div
class="inset-0 transform bg-black bg-opacity-50 transition-all duration-300 ease-in-out"
:class="{
'-translate-y-full': !mobileMenuOpen,
'translate-y': mobileMenuOpen,
}"
@click="toggleMobileMenu()"
></div>
</div>
</div>
</template>