feat: collapsible header on scroll for catalog pages
All checks were successful
Build Docker Image / build (push) Successful in 4m24s

- Add useScrollCollapse composable to track scroll and collapse state
- Update topnav.vue to show collapsed bar with chevron when scrolled
- Add collapse button (chevron up) to SubNavigation
- Make SubNavigation sticky below MainNavigation
- Update CatalogPage map/searchbar positions based on header state
This commit is contained in:
Ruslan Bakiev
2026-01-14 21:34:06 +07:00
parent 25da16f854
commit 9d0b1a6b15
4 changed files with 136 additions and 8 deletions

View File

@@ -1,7 +1,21 @@
<template>
<div class="min-h-screen flex flex-col bg-base-200">
<!-- Collapsed header bar (only on catalog pages when scrolled) -->
<div
v-if="showCollapsedBar"
class="sticky top-0 z-40 bg-base-100 border-b border-base-300 h-8 flex items-center px-4 lg:px-6"
>
<button
class="btn btn-ghost btn-xs btn-circle"
@click="expandHeader"
>
<Icon name="lucide:chevron-down" size="16" />
</button>
</div>
<!-- Main Navigation (Logo + Tabs + User) -->
<MainNavigation
v-show="!isHeaderCollapsed"
:session-checked="sessionChecked"
:logged-in="isLoggedIn"
:user-avatar-svg="userAvatarSvg"
@@ -20,7 +34,13 @@
<GlobalSearchBar v-if="showSearch" class="border-b border-base-300" />
<!-- Sub Navigation (section-specific tabs) - hidden on home page -->
<SubNavigation v-if="!isHomePage" :section="currentSection" />
<SubNavigation
v-if="!isHomePage"
v-show="!isHeaderCollapsed"
:section="currentSection"
:show-collapse-button="canCollapse"
@collapse="collapseHeader"
/>
<!-- Page content -->
<main class="flex-1 flex flex-col min-h-0 px-3 lg:px-6 py-4">
@@ -35,6 +55,9 @@ const siteUrl = runtimeConfig.public.siteUrl || 'https://optovia.ru/'
const { signIn, signOut, loggedIn, fetch: fetchSession } = useAuth()
const route = useRoute()
// Collapsible header for catalog pages
const { isCollapsed, expand, collapse } = useScrollCollapse(50)
// Theme state
const theme = useState<'default' | 'night'>('theme', () => 'default')
@@ -88,6 +111,17 @@ const isHomePage = computed(() => {
// Show search bar only on main page
const showSearch = computed(() => isHomePage.value)
// Collapsible header logic - only for catalog pages (not home page)
const canCollapse = computed(() => !isHomePage.value)
const isHeaderCollapsed = computed(() => canCollapse.value && isCollapsed.value)
const showCollapsedBar = computed(() => isHeaderCollapsed.value)
const expandHeader = () => expand()
const collapseHeader = () => collapse()
// Provide collapsed state to child components (CatalogPage needs it for map positioning)
provide('headerCollapsed', isHeaderCollapsed)
// Avatar generation
const generateUserAvatar = async (seed: string) => {
if (!seed) return