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.

tsx
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.

tsx
<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 its side edge. 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.

tsx
<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:

tsx
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 DrawerDescription when the title alone isn't enough context.
  • Escape and clicks on the backdrop close the drawer; swipe-to-dismiss is enabled in the matching side direction on touch devices.

API

Drawer (Root)

PropTypeDefaultDescription
openbooleanControlled open state.
defaultOpenbooleanfalseInitial open state (uncontrolled).
onOpenChange(open: boolean) => voidCallback when the open state changes.
modalboolean | "trap-focus"trueWhether 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.
disablePointerDismissalbooleanfalsePrevents outside-click from closing.

Subcomponents

ComponentPurpose
DrawerTriggerButton that opens the drawer.
DrawerCloseButton that closes the drawer.
DrawerContentConvenience wrapper rendering Portal + Overlay + Popup.
DrawerHeaderTop section wrapper.
DrawerTitleHeading element announced by screen readers.
DrawerDescriptionOptional supporting copy below the title.
DrawerFooterBottom action row with a divider.
DrawerPortalPortals the popup to the document body.
DrawerOverlayDimmed backdrop behind the popup.
DrawerPopupPopup 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 side to the user's mental model: bottom on mobile, right for inspectors, left for 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
Made in NYC© 2026 Rogo Technologies Inc.