import * as React from 'react'; import { cn } from '@/lib/utils'; import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from '@/components/ui/sheet'; /** * Panel widths. * * Each entry states its `max-w` as well as its `w`. The underlying Sheet caps a * side panel at `sm:max-w-sm` (24rem), so a width alone was silently ignored on * desktop and every "large" drawer in the app was drawn at phone width — the * reason detail panels wrapped and scrolled far more than their content needed. */ const WIDTHS = { sm: 'w-full sm:w-80 sm:max-w-[20rem]', default: 'w-full sm:w-[28rem] sm:max-w-[28rem]', lg: 'w-full sm:w-[36rem] sm:max-w-[36rem]', /* A record with a two-column body: 704px on desktop, 768px from `2xl` (1536px and up), and never the whole screen — the page behind it stays visible, which is what keeps the drawer a drawer. */ xl: 'w-full sm:w-[44rem] sm:max-w-[44rem] 2xl:w-[48rem] 2xl:max-w-[48rem]', }; /** * Drawer — an edge-anchored panel for detail views, filters and mobile nav. * * Same header/body/footer contract as Modal, so the two are interchangeable: * a detail view can be a Drawer on desktop and a bottom sheet on mobile without * its contents changing. */ export function Drawer({ open, onOpenChange, title, description, icon: Icon, side = 'right', size = 'default', footer, children, className, /** Hides the header for a fully custom panel (the mobile nav does this). */ bare = false, }) { const isVertical = side === 'top' || side === 'bottom'; return ( {!bare && (
{Icon && ( )}
{title} {description && ( {description} )}
)}
{children}
{footer && (
{footer}
)}
); }