/** * Composable for collapsing header on scroll * Returns isCollapsed state that becomes true when scroll > threshold * User can manually override the collapsed state */ export const useScrollCollapse = (threshold = 50) => { const isCollapsed = ref(false) const scrollY = ref(0) const manualOverride = ref(false) const onScroll = () => { if (import.meta.server) return scrollY.value = window.scrollY // Only auto-collapse if user hasn't manually expanded if (!manualOverride.value) { isCollapsed.value = scrollY.value > threshold } // Reset manual override when scrolling back to top if (scrollY.value <= threshold) { manualOverride.value = false isCollapsed.value = false } } // Manual expand (user clicked chevron down) const expand = () => { isCollapsed.value = false manualOverride.value = true } // Manual collapse (user clicked chevron up) const collapse = () => { isCollapsed.value = true manualOverride.value = false } onMounted(() => { window.addEventListener('scroll', onScroll, { passive: true }) // Initial check onScroll() }) onUnmounted(() => { window.removeEventListener('scroll', onScroll) }) return { isCollapsed: readonly(isCollapsed), scrollY: readonly(scrollY), expand, collapse } }