2026-03-05 12:13:22 -06:00
|
|
|
import { useEffect } from 'react'
|
2026-03-05 13:17:36 -06:00
|
|
|
|
2026-03-05 12:13:22 -06:00
|
|
|
export default function Drawer({ isOpen, onClose, children }) {
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const h = (e) => { if (e.key === 'Escape') onClose() }
|
|
|
|
|
if (isOpen) document.addEventListener('keydown', h)
|
|
|
|
|
return () => document.removeEventListener('keydown', h)
|
|
|
|
|
}, [isOpen, onClose])
|
2026-03-05 13:17:36 -06:00
|
|
|
|
2026-03-05 12:13:22 -06:00
|
|
|
return (
|
|
|
|
|
<>
|
2026-03-05 13:17:36 -06:00
|
|
|
{isOpen && (
|
|
|
|
|
<div className="fixed inset-0 z-40 bg-black/50 backdrop-blur-sm" onClick={onClose} />
|
|
|
|
|
)}
|
2026-03-05 12:13:22 -06:00
|
|
|
<div
|
|
|
|
|
className={`fixed bottom-0 left-0 right-0 z-50 bg-surface-raised border-t border-surface-border rounded-t-2xl shadow-2xl transition-transform duration-300 ease-in-out ${isOpen ? 'translate-y-0' : 'translate-y-full'}`}
|
2026-03-05 13:17:36 -06:00
|
|
|
style={{ maxHeight: '72vh' }}
|
2026-03-05 12:13:22 -06:00
|
|
|
>
|
2026-03-05 13:17:36 -06:00
|
|
|
{/* Handle bar + close */}
|
|
|
|
|
<div className="relative flex items-center justify-between px-6 py-3 border-b border-surface-border flex-shrink-0">
|
2026-03-05 12:13:22 -06:00
|
|
|
<div className="absolute left-1/2 -translate-x-1/2 top-2 w-10 h-1 bg-surface-border rounded-full" />
|
|
|
|
|
<div className="flex-1" />
|
2026-03-05 13:17:36 -06:00
|
|
|
<button onClick={onClose} className="text-text-muted hover:text-gold transition-colors text-lg leading-none">✕</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Scrollable content — overflow-visible on x so badge doesn't clip */}
|
|
|
|
|
<div className="overflow-y-auto overflow-x-hidden" style={{ maxHeight: 'calc(72vh - 52px)' }}>
|
|
|
|
|
{children}
|
2026-03-05 12:13:22 -06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
)
|
|
|
|
|
}
|