iconiq

Drawer

Controlled overlay drawer with side-based slide motion, staggered content reveal, and a built-in close header.

Installation

npx shadcn@latest add @iconiq/drawer

Props

Drawer

6 props

Single exported overlay drawer controlled entirely from parent state, with side-based panel motion and built-in body scroll locking.
openboolean
Required
Controls whether the drawer and overlay render at all. The component is fully controlled and does not keep its own open state.
onClose() => void
Required
Called when the overlay is clicked or when Escape is pressed while the drawer is open.
side"left" | "right" | "top" | "bottom"
Default"right"
Chooses the panel edge, slide direction, and the matching border placement from the internal panelVariants map.
titlestring
Primary heading rendered in the header row. When omitted, the heading node still renders but stays empty.
descriptionstring
Secondary helper line rendered under the title when present.
childrenReactNode
Content rendered inside the scrolling body area below the header.

Notes

This component does not forward arbitrary DOM props or refs to the overlay or panel. The public API is limited to the controlled props above.
While open, the component sets document.body.style.overflow to hidden and restores it during cleanup.
There is no focus trap, portal primitive, or aria dialog wiring here, so this version is closer to a visual application drawer than a full modal accessibility primitive.

Motion, layout, and close behavior

2 props

The drawer uses a spring-driven panel plus staggered header and body children, with a softer duration fallback when reduced motion is enabled.
overlaybuilt-in
A fixed full-screen overlay is always rendered behind the panel and closes the drawer on click.
close buttonbuilt-in
The header always includes a close button with the Lucide X icon wired to onClose.

Notes

Top and bottom drawers cap their height at 80vh, while left and right drawers cap their width at max-w-md and otherwise fill the viewport edge-to-edge.
A decorative top shimmer is always rendered inside the panel. Remove or restyle it locally if you want a flatter surface.