Drawer
A panel that slides in from an edge of the viewport for focused tasks that don't deserve a full dialog. Use it for mobile sheets, side panels, citation previews, and similar lateral views. For a centered modal, prefer Dialog.
Examples
Basic (bottom, sticky)
Sticky on every side
Floating on every side
Sticky vs floating (same side)
Overview
Built on Base UI Drawer. The wrapper threads the side prop through to the underlying swipeDirection so swipe-to-dismiss matches the entry direction, and applies UI package tokens (bg-surface, border-primary-solid) for surface and border.
import {
Drawer,
DrawerTrigger,
DrawerContent,
DrawerHeader,
DrawerTitle,
DrawerDescription,
DrawerFooter,
DrawerClose,
} from "@rogo-technologies/ui/drawer";
<Drawer>
<DrawerTrigger>Open</DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Title</DrawerTitle>
<DrawerDescription>Optional supporting copy.</DrawerDescription>
</DrawerHeader>
<DrawerFooter>
<DrawerClose>Close</DrawerClose>
</DrawerFooter>
</DrawerContent>
</Drawer>;Usage
Side
Pass side on the root to control which edge the drawer slides in from. Available values: bottom (default), top, left, right. The swipe-to-dismiss direction is matched automatically.
<Drawer side="right">…</Drawer>Variant
Pass variant on the root to control how the drawer relates to the viewport edges:
sticky(default) — the drawer anchors flush to itssideedge. The corners on the edge it attaches to stay square; on the opposite, exposed edge they round. Use this for full-bleed sheets, mobile drawers, and traditional side panels.floating— the drawer sits as a panel with a 4px gap on every free edge, all corners rounded, and a soft elevation shadow. Use this when the surrounding page should remain partially visible — for inspectors that float over the canvas, citation previews, or any drawer that should feel like a card rather than an extension of the chrome.
Both variants work on every side.
<Drawer side="right" variant="floating">
…
</Drawer>Composition
For more control — for example to nest a custom backdrop or skip the viewport — compose the low-level parts directly:
import {
Drawer,
DrawerTrigger,
DrawerPortal,
DrawerOverlay,
DrawerPopup,
} from "@rogo-technologies/ui/drawer";
<Drawer>
<DrawerTrigger>Open</DrawerTrigger>
<DrawerPortal>
<DrawerOverlay />
<DrawerPopup>…</DrawerPopup>
</DrawerPortal>
</Drawer>;Accessibility
- Always render a
DrawerTitle; screen readers announce it as the dialog name. - Add a
DrawerDescriptionwhen the title alone isn't enough context. Escapeand clicks on the backdrop close the drawer; swipe-to-dismiss is enabled in the matchingsidedirection on touch devices.
API
Drawer (Root)
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controlled open state. |
defaultOpen | boolean | false | Initial open state (uncontrolled). |
onOpenChange | (open: boolean) => void | — | Callback when the open state changes. |
modal | boolean | "trap-focus" | true | Whether the drawer is modal. |
side | "bottom" | "top" | "left" | "right" | "bottom" | Edge the drawer slides in from. |
variant | "sticky" | "floating" | "sticky" | Edge-anchored vs floating panel. |
disablePointerDismissal | boolean | false | Prevents outside-click from closing. |
Subcomponents
| Component | Purpose |
|---|---|
DrawerTrigger | Button that opens the drawer. |
DrawerClose | Button that closes the drawer. |
DrawerContent | Convenience wrapper rendering Portal + Overlay + Popup. |
DrawerHeader | Top section wrapper. |
DrawerTitle | Heading element announced by screen readers. |
DrawerDescription | Optional supporting copy below the title. |
DrawerFooter | Bottom action row with a divider. |
DrawerPortal | Portals the popup to the document body. |
DrawerOverlay | Dimmed backdrop behind the popup. |
DrawerPopup | Popup container (low-level alternative to DrawerContent). |
DrawerPopup also accepts the side and variant props directly if you need to override the root's setting.
Guidelines
Do
- Use a Drawer when the task feels lateral to the page — a sheet of options, a citation, a detail panel
- Match
sideto the user's mental model:bottomon mobile,rightfor inspectors,leftfor navigation - Provide a clear close affordance in the footer for keyboard and mouse users — swipe alone isn't enough
Don't
- Don't use a Drawer for destructive confirmations — use
AlertDialog - Don't stack Drawers on top of each other; collapse the flow or switch to a route
- Don't omit
DrawerTitle— it's required for screen readers even when the title looks redundant