Vaul Drawer Reference
Vaul provides mobile-friendly drawers and bottom sheets with drag gestures, escape/outside dismissal, focus handling, portals, and smooth open/close behavior. Use it for drawers, bottom sheets, side sheets, and gesture-driven detail panels.
Overview
Use Vaul instead of hand-rolling drawers with fixed divs. For centered modal dialogs and destructive confirmations, use Radix Dialog or AlertDialog instead.
The examples below show only the structure and layout classes needed for a working drawer. Add local Tailwind styling that matches the app's visual language.
Import
import { Drawer } from 'vaul'
Bottom sheet
Good for mobile-first create/edit forms, item details, filters, and compact task flows.
import { Drawer } from 'vaul'
function BottomSheet() {
return (
<Drawer.Root>
<Drawer.Trigger>Open sheet</Drawer.Trigger>
<Drawer.Portal>
<Drawer.Overlay className="fixed inset-0 z-40 bg-black/40" />
<Drawer.Content className="fixed inset-x-0 bottom-0 z-50 max-h-[90vh] rounded-t-3xl bg-white p-4">
<div className="mx-auto mb-4 h-1.5 w-12 rounded-full bg-gray-300" />
<Drawer.Title>Edit item</Drawer.Title>
<Drawer.Description>
Make changes, then save when you're done.
</Drawer.Description>
<div className="mt-4 overflow-y-auto">Drawer content goes here.</div>
<Drawer.Close>Close</Drawer.Close>
</Drawer.Content>
</Drawer.Portal>
</Drawer.Root>
)
}
Side drawer
Use side drawers for desktop inspector panels, detail panels, or focused editing while keeping the main app visible.
<Drawer.Root direction="right">
<Drawer.Trigger>Open details</Drawer.Trigger>
<Drawer.Portal>
<Drawer.Overlay className="fixed inset-0 z-40 bg-black/40" />
<Drawer.Content className="fixed bottom-0 right-0 top-0 z-50 flex w-full max-w-md flex-col bg-white p-4">
<Drawer.Title>Item details</Drawer.Title>
<Drawer.Description>
Review context and update this item.
</Drawer.Description>
<div className="mt-6 min-h-0 flex-1 overflow-y-auto">
Drawer content goes here.
</div>
<Drawer.Close>Close</Drawer.Close>
</Drawer.Content>
</Drawer.Portal>
</Drawer.Root>
Best practices
- Use
Drawer.Rootfor interaction state andDrawer.Portalfor overlay/content rendering. - Always include
Drawer.Title; includeDrawer.Descriptionwhen a short explanation helps. - Use
Drawer.Closefor explicit close controls. - Bottom sheets should usually use
rounded-t-*, a small drag handle, andmax-h-[85vh]tomax-h-[90vh]. - Side drawers should use
direction="left"ordirection="right"and fill the viewport height. - Keep scroll inside the drawer body only when the drawer has an explicit max height or fixed height.
- Use a full-screen drawer for immersive mobile editing flows when keeping context behind the drawer is not important.
- Do not use Vaul for basic cards, inline panels, dropdown menus, or centered confirmation dialogs.