Skip to main content
ninna-ui

Drawer

A panel that slides in from the edge of the screen.

import { Drawer } from "@ninna-ui/overlays"
pnpm add @ninna-ui/overlays

Requires @ninna-ui/core (auto-installed) + CSS setup.

View source

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)

PropTypeDefaultDescription
children*ReactNode-Drawer content (Trigger, Content, etc.)
openboolean-Controlled open state
defaultOpenbooleanfalseDefault open state (uncontrolled)
onOpenChange(open: boolean) => void-Callback when open state changes
modalbooleantrueWhether the drawer blocks interaction with the rest of the page

Drawer.Content

PropTypeDefaultDescription
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
descriptionstring-Accessible description for the drawer. Rendered as sr-only when provided.
closeOnOverlayClickbooleantrueWhether clicking the overlay closes the drawer
closeOnEscapebooleantrueWhether 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
classNamestring-Additional CSS classes

Drawer.Trigger

PropTypeDefaultDescription
asChildbooleanfalseRender as child element instead of wrapping button

Drawer.Close

PropTypeDefaultDescription
asChildbooleanfalseRender as child element instead of default close button

Accessibility

  • Uses role="dialog" with aria-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