@@ -193,9 +193,10 @@
< template v-if = "currentSubmenu === 'mannschaften'" >
< div
ref = "mannschaftenSubmenuRail"
class = "flex min-w-0 items-center gap-1 overflow-x-auto whitespace-nowrap scroll-smooth pr -7 [scrollbar-color:theme(colors.primary.700)_transparent] [scrollbar-width:thin]"
class = "flex min-w-0 items-center gap-1 overflow-x-auto whitespace-nowrap scroll-smooth px -7 [scrollbar-color:theme(colors.primary.700)_transparent] [scrollbar-width:thin]"
tabindex = "0"
aria -label = " Mannschaften -Untermenü – horizontal scrollbar "
@scroll.passive ="updateMannschaftenSubmenuControls"
>
< NuxtLink
to = "/mannschaften"
@@ -234,6 +235,17 @@
< / NuxtLink >
< / div >
< button
v-if = "showMannschaftenSubmenuLeftControl"
type = "button"
class = "absolute inset-y-0 left-0 z-10 flex w-9 items-center justify-start bg-gradient-to-r from-primary-900 via-primary-900/90 to-transparent pl-1 text-primary-300 transition-colors hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-300"
aria -label = " Vorherige Mannschaften anzeigen "
@pointerdown.stop
@click.stop.prevent ="scrollMannschaftenSubmenuLeft"
>
‹
< / button >
< button
v-if = "showMannschaftenSubmenuRightControl"
type = "button"
class = "absolute inset-y-0 right-0 z-10 flex w-9 items-center justify-end bg-gradient-to-l from-primary-900 via-primary-900/90 to-transparent pr-1 text-primary-300 transition-colors hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-300"
aria -label = " Weitere Mannschaften anzeigen "
@@ -872,7 +884,7 @@
< / template >
< script setup >
import { ref , onMounted , onUnmounted , computed } from 'vue'
import { ref , onMounted , onUnmounted , computed , nextTick , watch } from 'vue'
import { useRoute } from 'vue-router'
import { Menu , X , ChevronDown } from 'lucide-vue-next'
@@ -881,6 +893,8 @@ const isMobileMenuOpen = ref(false)
const mobileSubmenu = ref ( null )
const mannschaften = ref ( [ ] )
const mannschaftenSubmenuRail = ref ( null )
const showMannschaftenSubmenuLeftControl = ref ( false )
const showMannschaftenSubmenuRightControl = ref ( false )
const hasGalleryImages = ref ( false )
const showCmsDropdown = ref ( false )
const authStore = useAuthStore ( )
@@ -918,6 +932,28 @@ const toggleMobileSubmenu = (menu) => {
mobileSubmenu . value = mobileSubmenu . value === menu ? null : menu
}
const updateMannschaftenSubmenuControls = ( ) => {
const rail = mannschaftenSubmenuRail . value
if ( ! rail ) return
const canScroll = rail . scrollWidth > rail . clientWidth + 1
const atStart = rail . scrollLeft <= 1
const atEnd = rail . scrollLeft + rail . clientWidth >= rail . scrollWidth - 1
showMannschaftenSubmenuLeftControl . value = canScroll && ! atStart
showMannschaftenSubmenuRightControl . value = canScroll && ! atEnd
}
const scrollMannschaftenSubmenuLeft = ( ) => {
const rail = mannschaftenSubmenuRail . value
if ( ! rail ) return
rail . scrollBy ( {
left : - Math . max ( rail . clientWidth * 0.8 , 160 ) ,
behavior : 'smooth'
} )
}
const scrollMannschaftenSubmenuRight = ( ) => {
const rail = mannschaftenSubmenuRail . value
if ( ! rail ) return
@@ -1012,16 +1048,23 @@ onMounted(() => {
// Listen for global updates to mannschaften (e.g., CMS saved)
if ( typeof window !== 'undefined' ) {
window . addEventListener ( 'mannschaften:changed' , loadMannschaften )
window . addEventListener ( 'resize' , updateMannschaftenSubmenuControls )
}
nextTick ( updateMannschaftenSubmenuControls )
} )
onUnmounted ( ( ) => {
document . removeEventListener ( 'click' , handleDocumentClick )
if ( typeof window !== 'undefined' ) {
window . removeEventListener ( 'mannschaften:changed' , loadMannschaften )
window . removeEventListener ( 'resize' , updateMannschaftenSubmenuControls )
}
} )
watch ( [ currentSubmenu , mannschaften ] , ( ) => {
nextTick ( updateMannschaftenSubmenuControls )
} , { flush : 'post' } )
const toggleSubmenu = ( menu ) => {
// Wenn wir schon im richtigen Bereich sind, nichts tun (Submenu bleibt offen)
// Wenn nicht, zur Hauptseite navigieren