// composables/useCartUI.ts import { useMediaQuery } from '@vueuse/core' /** * Cart UI composable * * Manages cart sidebar/sheet UI state and responsive behavior * * Features: * - Sidebar/sheet open/close state * - Responsive detection (mobile vs desktop) * - Body scroll lock when cart is open * - Global state (shared across all components) * * Usage: * const { isOpen, isMobile, open, close, toggle } = useCartUI() */ // Global cart UI state (shared across all components) const isOpen = ref(false) export function useCartUI() { // Responsive breakpoint: mobile = width < 1024px (lg breakpoint) const isMobile = useMediaQuery('(max-width: 1023px)') /** * Open cart sidebar/sheet */ function open() { isOpen.value = true lockBodyScroll() } /** * Close cart sidebar/sheet */ function close() { isOpen.value = false unlockBodyScroll() } /** * Toggle cart sidebar/sheet */ function toggle() { if (isOpen.value) { close() } else { open() } } /** * Lock body scroll (prevent scrolling when cart is open) */ function lockBodyScroll() { if (import.meta.client) { document.body.style.overflow = 'hidden' } } /** * Unlock body scroll */ function unlockBodyScroll() { if (import.meta.client) { document.body.style.overflow = '' } } /** * Clean up: Ensure body scroll is unlocked when component unmounts */ onUnmounted(() => { unlockBodyScroll() }) /** * Watch for route changes: Close cart when navigating */ if (import.meta.client) { const route = useRoute() watch( () => route.path, () => { if (isOpen.value) { close() } } ) } return { // State isOpen: readonly(isOpen), isMobile: readonly(isMobile), // Methods open, close, toggle, } }