Drawer
Slide-in panel overlay from any viewport edge with focus trap, backdrop dismiss, and keyboard support.
01 When to use
Drawer is a <dialog> — always modal, with a backdrop and a
focus trap. Use it for a transient panel that opens on user action, pulls focus, and closes when
the action is done. The four placement values (left / right / top / bottom) cover side
sheets, top notification bars, and mobile bottom-sheets.
Pick a different overlay if you need:
02 Examples
Placements
With Footer
03 Customization
Settings Panel
Navigation Menu
04 Stacking & Nested Drawers
Multiple Drawers can be open at the same time — for example a wizard that opens a preview,
which opens a calculation trace. Drawer is rendered with a native <dialog>, so the browser handles the top-layer
stacking order automatically.
Stack order is LIFO
The most recently opened Drawer renders on top. Pressing Escape closes the topmost drawer; the underlying ones stay open. Each Drawer manages its own focus-trap, so keyboard navigation stays inside the topmost panel.
Backdrop & body-scroll
Each open Drawer adds its own backdrop. The body-scroll lock is reference-counted — scroll stays locked until every Drawer is closed. Closing the topmost panel revives keyboard interaction with the panel underneath.
Recommended depth: 2–3
Two or three layers (e.g. wizard → preview → trace) work well in practice. Beyond that, the visual stack becomes cramped, especially on mobile. Consider a master-detail pattern (list + replaceable detail panel) instead of deep nesting.
Mobile caveat
Each Drawer caps its size at 100dvw / 100dvh, so a stacked Drawer on a 320 px viewport
becomes effectively full-width. Two or three identical-size Drawers stack visually as a
single panel — open them with different sizes (e.g. md → lg) so the user can see the layering on narrow screens.
Programmatic overlayStack
Drawer, Dialog, and (mobile) Sidebar all auto-register with a shared overlayStack singleton on open. Use this for app-level
cleanup that has to span unknown overlay depth — typically logout, route changes, or auth expiry.
The stack stays untouched on Desktop sidebars (they're persistent layout, not modal overlays).
import { overlayStack } from '@urbicon-ui/blocks';
// Close every open Drawer, Dialog, and mobile Sidebar (top-down)
overlayStack.closeAll();
// Inspect the stack
overlayStack.depth; // number
overlayStack.topId; // string | null05 Accessibility
Focus Trap
When open, focus is trapped inside the drawer panel. Tab cycles through focusable elements. On close, focus returns to the element that triggered the drawer.
ARIA
Uses native <dialog> with aria-labelledby linked to the title and aria-describedby linked to the body content. The
close button has an aria-label.
Keyboard
Escape closes the drawer (configurable via closeOnEscape). Backdrop click dismiss is also
configurable.
Reduced Motion
Slide and fade transitions respect prefers-reduced-motion. The drawer appears and
disappears instantly without animation.
06 API Reference
No matching properties |