Added mobile navigation

This commit is contained in:
lucast committed 2026-10-06 03:26:15 +02:00
1 parent 4ab58c8400
commit 4c883c60a4
1 file changed
+107 -1
+107 -1
View File
@@ -1,5 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
const router = useRouter() const router = useRouter()
const route = useRoute()
const activeTab = computed(() => {
if (route.path === "/") return "home"
if (route.path === "/search") return "search"
if (route.path.startsWith("/library/")) return "library"
return ""
})
let timeout: ReturnType<typeof setTimeout> let timeout: ReturnType<typeof setTimeout>
@@ -16,7 +24,7 @@ const { data: user } = useApiFetch<any>("/user")
</script> </script>
<template> <template>
<Sidebar> <Sidebar class="default-shell">
<template #sidebar> <template #sidebar>
<p class="title">Music</p> <p class="title">Music</p>
@@ -89,12 +97,55 @@ const { data: user } = useApiFetch<any>("/user")
<template #default> <template #default>
<slot /> <slot />
<nav class="mobile-tabs" aria-label="Primary navigation">
<NuxtLink
to="/"
class="tab"
:class="{ active: activeTab === 'home' }"
:aria-current="activeTab === 'home' ? 'page' : undefined"
>
<Icon
name="lucide:house"
class="tab-icon"
aria-hidden="true"
/>
<span>Home</span>
</NuxtLink>
<NuxtLink
to="/library/songs"
class="tab"
:class="{ active: activeTab === 'library' }"
:aria-current="activeTab === 'library' ? 'page' : undefined"
>
<Icon
name="lucide:library"
class="tab-icon"
aria-hidden="true"
/>
<span>Library</span>
</NuxtLink>
<NuxtLink
to="/search"
class="tab"
:class="{ active: activeTab === 'search' }"
:aria-current="activeTab === 'search' ? 'page' : undefined"
>
<Icon
name="lucide:search"
class="tab-icon"
aria-hidden="true"
/>
<span>Search</span>
</NuxtLink>
</nav>
</template> </template>
</Sidebar> </Sidebar>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
@use "@/styles/util" as *; @use "@/styles/util" as *;
@use "@/styles/variables" as *;
.title { .title {
@include fontSize(24px); @include fontSize(24px);
@@ -114,4 +165,59 @@ const { data: user } = useApiFetch<any>("/user")
margin-bottom: 0.1rem; margin-bottom: 0.1rem;
} }
} }
.mobile-tabs {
display: none;
}
@media (max-width: 767px) {
.default-shell {
display: block;
overflow: hidden;
:deep(> aside) {
display: none;
}
:deep(> main) {
padding: 1.25rem 1rem calc(6rem + env(safe-area-inset-bottom) + $player-height);
}
}
.mobile-tabs {
position: fixed;
z-index: 100;
inset: auto 0 0;
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
padding: 0.45rem 0.75rem calc(0.45rem + env(safe-area-inset-bottom));
border-top: 1px solid rgba(255, 255, 255, 0.12);
background: rgba(22, 22, 24, 0.96);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
}
.tab {
min-width: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 0.3rem;
border-radius: 0.65rem;
color: rgba(255, 255, 255, 0.62);
text-decoration: none;
font-size: 0.75rem;
font-weight: 600;
-webkit-tap-highlight-color: transparent;
.tab-icon {
font-size: 1.75rem;
}
&.active {
color: white;
}
}
}
</style> </style>