Drawer

A swipeable Base UI drawer that can enter from any edge while preserving the active theme frame.

Preview#

drawer

import {
  Drawer,
  DrawerActions,
  DrawerBody,
  DrawerClose,
  DrawerContent,
  DrawerDescription,
  DrawerFooter,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
} from "raft-ui";

<Drawer>
  <DrawerTrigger />
  <DrawerContent>
    <DrawerHeader>
      <DrawerTitle />
    </DrawerHeader>
    <DrawerBody>
      <DrawerDescription />
    </DrawerBody>
    <DrawerFooter>
      <DrawerActions>
        <DrawerClose />
      </DrawerActions>
    </DrawerFooter>
  </DrawerContent>
</Drawer>

Snap points#

Snap points apply to vertical drawers. Compare separate bottom and top notifications; each expands from an 8rem summary to a 24rem detail view.

Nested close callbacks#

Each nested drawer owns its close callback; removing a member closes the confirmation and details layers together.

Full-width side drawer#

Override DrawerContent on small screens to span the floating inset.

Responsive placement#

Switch swipeDirection at md: bottom on mobile, right on desktop.

API#WIP

PropTypeDefaultDescription
openbooleanControlled open state. Pair with onOpenChange.
defaultOpenbooleanfalseInitial open state for uncontrolled usage.
onOpenChange(open: boolean, eventDetails) => voidFires on trigger, close, Escape, outside press, or swipe dismissal.
onOpenChangeComplete(open: boolean) => voidFires after the opening or closing transition completes. Attach it to a nested Drawer and check for open === false to observe that layer closing.
modalboolean | "trap-focus"trueControls outside interaction. Use "trap-focus" to contain focus without making the rest of the page inert.
swipeDirection"down" | "up" | "left" | "right""down"Direction the drawer follows and can be swiped to dismiss.
snapPointsArray<number | string>Preset heights for vertical drawers. Fractions use viewport height, values greater than 1 use pixels, and strings support px or rem.
defaultSnapPointnumber | string | nullInitial snap point for an uncontrolled drawer.
snapPointnumber | string | nullThe currently active snap point. Use with onSnapPointChange to control it.
onSnapPointChange(snapPoint: number | string | null, eventDetails) => voidCalled when the active snap point changes.
PropTypeDefaultDescription
...propsBase UI Drawer.Trigger.PropsOpens the drawer. Compose Button through render for visible triggers.
PropTypeDefaultDescription
containerHTMLElement | RefObject | nullCustom portal container for framed previews or contained overlays.
...propsBase UI Drawer.Portal.PropsPortals the drawer to the body or a custom container.
PropTypeDefaultDescription
...propsBase UI Drawer.Backdrop.PropsBackdrop behind the drawer while it is open.
PropTypeDefaultDescription
portalPropsDrawerPortalPropsPass the Base UI portal container, keepMounted state, or portal element props.
...propsBase UI Drawer.Popup.PropsPortal-backed surface that composes the backdrop, viewport, popup, and selectable content region.
PropTypeDefaultDescription
...propsuseRender.ComponentProps<"div">Top region for the drawer title and close action.
PropTypeDefaultDescription
...propsBase UI Drawer.Title.PropsAccessible drawer heading.
PropTypeDefaultDescription
...propsBase UI Drawer.Description.PropsAccessible supporting copy for the drawer.
PropTypeDefaultDescription
...propsComponentPropsWithRef<"div">Main content area between header and footer.
PropTypeDefaultDescription
...propsComponentPropsWithRef<"div">Width-aware action cluster for one or more actions.
PropTypeDefaultDescription
variantButton variantButton styling for the default close control.
sizeButton sizeButton size for the default close control.
...propsBase UI Drawer.Close.PropsCloses the drawer. Compose your own visual affordance with render/className.