Drawer
A temporary side surface for focused work.
pnpm dlx shadcn@latest add @uiarc/drawer- Side panels for filters, settings, or record details that keep the page in context.
- Forms that are too long for a dialog but should not leave the current view.
- Panels from any edge, via side, with drag-to-dismiss on the header.
- Use dialog for short decisions and confirmations.
- Use bottom-sheet for mobile-first sheets with snap points.
- Use popover for small anchored content that does not need a modal overlay.
Installation
Add Drawer with the shadcn CLI, or copy the source by hand.
pnpm dlx shadcn@latest add @uiarc/drawerAdds the component and its local dependencies, and installs @radix-ui/react-dialog, motion, lucide-react. First time? Add the @uiarc registry to components.json, or use the full URL:
import { Drawer, DrawerTrigger, DrawerContent, DrawerClose } from "@/registry/components/drawer/drawer";import { Button } from "@/registry/components/button/button"; export function FiltersDrawer() { return ( <Drawer> <DrawerTrigger asChild><Button variant="secondary">Filters</Button></DrawerTrigger> <DrawerContent title="Filters" description="Narrow the list of projects."> <FilterForm /> <DrawerClose asChild><Button>Apply</Button></DrawerClose> </DrawerContent> </Drawer> );}API reference
4 parts. The first is the root.
Drawer
Root. A Radix Dialog root that keeps the panel mounted while it slides out and closes it after a drag.
openboolean–Controlled open state.defaultOpenbooleanfalseInitial state when uncontrolled.onOpenChange(open: boolean) => void–Called when the drawer opens or closes....propsComponentPropsWithoutRef<typeof DialogPrimitive.Root>–Other Radix Dialog root props, such as modal and children.DrawerTrigger
Radix Dialog.Trigger. Use asChild to wrap your own button.
...propsComponentPropsWithoutRef<typeof DialogPrimitive.Trigger>–Radix trigger props, including asChild.DrawerContent
Overlay and panel with a titled header that doubles as the drag handle, a close button, and a scrolling body.
titleRequiredstring–Rendered as the dialog title. A new title rises in while open.descriptionstring–Rendered as the dialog description under the title.side"left" | "right" | "top" | "bottom""right"Edge the panel attaches to and slides from.childrenRequiredReactNode–Body content....propsComponentPropsWithoutRef<typeof DialogPrimitive.Content>–Radix content props such as className, onInteractOutside, and onEscapeKeyDown.DrawerClose
Radix Dialog.Close for extra close buttons in the body or footer.
...propsComponentPropsWithoutRef<typeof DialogPrimitive.Close>–Radix close props, including asChild.- Escape
- Closes the drawer and returns focus to the trigger.
- TaborShift+Tab
- Cycles focus within the panel while it is open.
- Radix Dialog provides role="dialog", aria-modal, focus trapping, and focus return.
- title and description are wired to Dialog.Title and Dialog.Description, so the panel is always named.
- The header close button is labelled "Close drawer"; dragging is optional and never the only way to close.
- The panel springs in from its edge and leaves faster on a tween; a drag past a third of the panel or a quick flick closes it and keeps the release velocity.
- Dragging the header away from the edge rubber-bands; the overlay fades in and out.
- Reduced motion disables dragging and replaces the slide with a short opacity fade.
- Left and right panels are min(30rem, 100vw minus a gutter) wide; below 40rem they grow to nearly full width with tighter padding.
- Top and bottom panels span the full width and cap at min(32rem, 100dvh).
- The header is the drag handle with touch-action none, so a touch drag moves the panel while the body still scrolls normally.
- The overlay uses a 4px backdrop blur, which can cost frames on low-end devices over busy pages.
- Drag runs on motion pan handlers with no React re-render per frame; the panel stays mounted only while sliding out.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Use for side panels with forms, filters, settings, or detail views that keep the page in context. Use dialog for short decisions and bottom-sheet for mobile-first sheets.
- Always compose Drawer as the root; under a bare Radix Dialog root the panel falls back to CSS keyframes and loses drag.
- Control open when the drawer must close after an async submit.
The full library index for assistants is at /llms.txt.