Skip to content

Drawer

Edge-anchored dialog with end, start, bottom, and top placement.

Primitive · overlay

Terminal window
npx shadcn@latest add https://ndigo.dev/r/drawer.json

To use the shorter @ndigo/drawer form, configure the namespace in components.json.

Source Target Type
registry/ui/drawer/nd-drawer.ts @ui/nd-drawer/nd-drawer.ts registry:ui
registry/ui/drawer/nd-drawer.css @ui/nd-drawer/nd-drawer.css registry:file

See this component rendered live on the live examples page.

Registry: Ndigo element foundation. Packages: @zag-js/dialog@~1.47.0 (installed automatically).

<nd-drawer> has the same parts and behaviour as nd-dialog — focus trap, Escape/outside dismissal, focus restore — with an edge placement instead of a centered surface.

<nd-drawer placement="end">
<button data-part="trigger">Open drawer</button>
<div data-part="content">
<h2 data-part="title">Filters</h2>
<p data-part="description">Narrow the list.</p>
<button data-part="close-trigger">Close</button>
<p>Your content goes here.</p>
</div>
</nd-drawer>

A missing trigger, backdrop, positioner, and content wrapper are created on connect, just like the dialog.

Attribute Type Description
placement string end (default), start, bottom, or top; invalid values fall back to end
open boolean Controlled open state; reflected by the element
trigger-label string Label for the generated trigger
  • nd-open-change — detail: { open: boolean }.
  • show() / hide() — open or close programmatically.

The dialog machine owns the focus trap, initial focus, focus restore, Escape, outside-click dismissal, scroll lock, and aria-modal/labelledby/describedby. Provide a title or an aria-label. The edge placement is presentational only; keyboard behaviour is identical to the dialog.

Import nd-drawer.css after the tokens. data-placement selects the flex alignment and panel sizing: side drawers fill the block size, bottom/top drawers cap at 80dvh. The backdrop uses the background token through color-mix.