"use client"; import { useState, useEffect, useRef, useCallback } from "react"; export function useMobileDrawer() { const [open, setOpen] = useState(false); const drawerRef = useRef(null); const buttonRef = useRef(null); const close = useCallback(() => { setOpen(false); buttonRef.current?.focus(); }, []); const toggle = useCallback(() => setOpen((v) => !v), []); // Close on Escape useEffect(() => { if (!open) return; const handler = (e: KeyboardEvent) => { if (e.key === "Escape") close(); }; window.addEventListener("keydown", handler); return () => window.removeEventListener("keydown", handler); }, [open, close]); // Trap focus useEffect(() => { if (!open || !drawerRef.current) return; const el = drawerRef.current; const focusable = el.querySelectorAll( 'a[href], button, [tabindex]:not([tabindex="-1"])' ); if (focusable.length === 0) return; const first = focusable[0]; const last = focusable[focusable.length - 1]; const trap = (e: KeyboardEvent) => { if (e.key !== "Tab") return; if (e.shiftKey) { if (document.activeElement === first) { e.preventDefault(); last.focus(); } } else { if (document.activeElement === last) { e.preventDefault(); first.focus(); } } }; el.addEventListener("keydown", trap); return () => el.removeEventListener("keydown", trap); }, [open]); // Lock body scroll on mobile useEffect(() => { if (!open) return; const mq = window.matchMedia("(min-width: 768px)"); if (mq.matches) return; document.body.style.overflow = "hidden"; return () => { document.body.style.overflow = ""; }; }, [open]); return { open, setOpen, toggle, close, drawerRef, buttonRef }; } export function MobileDrawerOverlay({ open, onClose }: { open: boolean; onClose: () => void }) { if (!open) return null; return (