Drawer
A panel that slides in from the edge of the screen.
import { Drawer } from "@ninna-ui/overlays"pnpm add @ninna-ui/overlaysRequires @ninna-ui/core (auto-installed) + CSS setup.
Usage
Import and use the Drawer component in your application.
import { Drawer } from "@ninna-ui/overlays";import { Button , Code } from "@ninna-ui/primitives";
export default function Example() { return ( <Drawer> <Drawer.Trigger asChild> <Button>Open Drawer</Button> </Drawer.Trigger> <Drawer.Content> <Drawer.Header>Title</Drawer.Header> <Drawer.Body>Content</Drawer.Body> <Drawer.Footer> <Drawer.Close asChild> <Button variant="ghost">Cancel</Button> </Drawer.Close> <Button>Save</Button> </Drawer.Footer> </Drawer.Content> </Drawer> );}Basic
A basic right-side drawer with header, body, and footer.
Placements
Drawer can slide in from any edge: left, right, top, or bottom.
Sizes
Drawer supports xs, sm, md, lg, xl, and full sizes.
Prevent Close
Disable overlay click and Escape key to create persistent drawers.
With Form
Drawer is ideal for side forms and settings panels.
With Description
Add an accessible description to the drawer for better screen reader support.
API Reference
Complete list of props for the Drawer component and its sub-components.
Drawer (Root)
| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | - | Drawer content (Trigger, Content, etc.) |
open | boolean | - | Controlled open state |
defaultOpen | boolean | false | Default open state (uncontrolled) |
onOpenChange | (open: boolean) => void | - | Callback when open state changes |
modal | boolean | true | Whether the drawer blocks interaction with the rest of the page |
Drawer.Content
| Prop | Type | Default | Description |
|---|---|---|---|
placement | 'left' | 'right' | 'top' | 'bottom' | 'right' | Which edge the drawer slides from |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'md' | Size of the drawer panel |
description | string | - | Accessible description for the drawer. Rendered as sr-only when provided. |
closeOnOverlayClick | boolean | true | Whether clicking the overlay closes the drawer |
closeOnEscape | boolean | true | Whether pressing Escape closes the drawer |
onEscapeKeyDown | (event: KeyboardEvent) => void | - | Callback when Escape key is pressed |
onPointerDownOutside | (event: Event) => void | - | Callback when pointer clicks outside content |
className | string | - | Additional CSS classes |
Drawer.Trigger
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Render as child element instead of wrapping button |
Drawer.Close
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Render as child element instead of default close button |
Accessibility
- Uses
role="dialog"witharia-modal="true" - Focus is trapped inside the drawer when open
- Focus returns to the trigger element when the drawer is closed
- Escape key closes the drawer by default (configurable)
- Overlay click closes the drawer by default (configurable)
- Supports all four placement directions with proper slide animations