Sheet Drawer
A bottom sheet you can drag to dismiss, plus a side-panel mode that becomes a sheet on phones.
Overview
A drawer with real physics. Grab the handle and the sheet follows your finger 1:1 downward and resists upward. Let go past a third of its height, or flick it, and it closes. Anything less springs back. The page dims behind it, and the body scrolls independently with overscroll contained.
Side mode slides a panel in from the right on larger screens and automatically becomes a bottom sheet on phones, where a side panel would be cramped. A sticky footer holds the primary actions and respects the iOS safe area.
Use it for mobile filters, quick edits, carts and detail panels that shouldn’t take people off the page. Use a dialog for decisions that need full attention.
When to use
- A single interaction you want to feel finished, dropped into an existing screen.
When not to use
- A whole page layout: look at Sections or Templates.
Installation
pnpm dlx shadcn@latest add https://sundaeui.dev/r/sheet-drawer.jsonnpx shadcn@latest add https://sundaeui.dev/r/sheet-drawer.jsonyarn dlx shadcn@latest add https://sundaeui.dev/r/sheet-drawer.jsonbunx --bun shadcn@latest add https://sundaeui.dev/r/sheet-drawer.jsonWorks in any React project. Files are written to components/sundae/. Read the source in the stage’s Code view. Pro assets need a personal token. See authenticated installs.
- No dependencies beyond React 18 or later.
- Copy sheet-drawer.tsx into components/sundae/.
- Make sure Tailwind scans that folder (v4 detects it automatically; v3 needs it in `content`).
- Import the component and use it as shown below.
Usage
import { SheetDrawer } from '@/components/sundae/sheet-drawer'
<SheetDrawer
open={open}
onOpenChange={setOpen}
title="Filter products"
description="248 results"
footer={<button onClick={apply}>Show results</button>}
>
{filters}
</SheetDrawer>Props
| Prop | Type | Default |
|---|---|---|
open / onOpenChange*Controlled visibility. | boolean / (open) => void | — |
title*Heading (aria-labelledby). | string | — |
descriptionSecondary line (aria-describedby). | string | — |
sideRight becomes bottom below the sm breakpoint. | 'bottom' | 'right' | 'bottom' |
footerSticky action row. | ReactNode | — |
Accessibility
- A native modal <dialog>: focus is trapped and returned, and the page behind is inert.
- Escape, the close button and backdrop clicks all dismiss it. Dragging is never required.
- Reduced motion removes the slide, so it opens and closes instantly.
Customization
- Change the dismiss threshold (a third of the height) and flick velocity (0.6px/ms) in end().
- Width of side mode: sm:w-[420px].
FAQ
- Is Sheet Drawer free?
- Sheet Drawer is part of Sundae Pro. The live preview is open to everyone; the source installs with a Pro account.
- How do I install Sheet Drawer?
- Run npx shadcn@latest add https://sundaeui.dev/r/sheet-drawer.json. The files are written to components/sundae/. It has no dependencies beyond React 18 or later.
- Does Sheet Drawer support keyboard and screen readers?
- A native modal <dialog>: focus is trapped and returned, and the page behind is inert. Escape, the close button and backdrop clicks all dismiss it. Dragging is never required.
- Does Sheet Drawer respect reduced motion?
- Reduced motion removes the slide, so it opens and closes instantly.
More like this
All components →Fold Accordion
Components · UnderstatedToast Stack
Components · RefinedConfirm Dialog
Components · UnderstatedAvatar Stack
Components · Refined- Pro
Notification Center
Components · Refined Pull to Refresh
Components · Refined