Skip to main content

Drawer

Slides a panel in from a screen edge and dims the page behind it.

import { Drawer } from "@/fragments/ui";Source

Preview

<Drawer>
  <Drawer.Trigger asChild>
    <Button>Open Drawer</Button>
  </Drawer.Trigger>
  <Drawer.Content>
    <Drawer.Close />

Installation

npx @usefragments/cli add drawer

Writes src/fragments/ui/components/Drawer plus what it imports, the globals stylesheet, and .fragments/registry-lock.json, then prints the packages to add. No account, no key.

Your own registry: publish from Fragments Cloud and add --registry org/name. Connect a workspace.

Anatomy

Drawer is a compound: import the root and reach its parts through dot notation.

  • Drawer.Trigger
  • Drawer.Content
  • Drawer.Close
  • Drawer.SwipeArea
  • Drawer.Header
  • Drawer.Title
  • Drawer.Description
  • Drawer.Body
  • Drawer.Footer

Enters from the right, the default for editing and forms.

<Drawer>
  <Drawer.Trigger asChild>
    <Button>Open Drawer</Button>
  </Drawer.Trigger>
  <Drawer.Content>
    <Drawer.Close />
    <Drawer.Header>
      <Drawer.Title>Drawer Title</Drawer.Title>
      <Drawer.Description>
        A panel sliding in from the right.
      </Drawer.Description>
    </Drawer.Header>
    <Drawer.Body>
      <p>Drawer content goes here.</p>
    </Drawer.Body>
    <Drawer.Footer>
      <Drawer.Close asChild>
        <Button variant="soft">Cancel</Button>

Examples

Left Side

Enters from the left, where navigation belongs.

<Drawer>
  <Drawer.Trigger asChild>
    <Button variant="soft">Open Left</Button>
  </Drawer.Trigger>
  <Drawer.Content side="left">
    <Drawer.Close />

Bottom Sheet

Rises from the bottom for touch-reachable actions.

<Drawer>
  <Drawer.Trigger asChild>
    <Button variant="soft">Open Bottom Sheet</Button>
  </Drawer.Trigger>
  <Drawer.Content side="bottom" width="sm">
    <Drawer.Header>

With Form

Fields in the body, submit and cancel pinned to the footer.

<Drawer>
  <Drawer.Trigger asChild>
    <Button>Edit Settings</Button>
  </Drawer.Trigger>
  <Drawer.Content width="md">
    <Drawer.Close />

API

Component props
Prop
Type
Default
Description
childrenRequirednodeNot setDrawer content (use Drawer.Content, Drawer.Header, etc.)
openbooleanNot setControlled open state
defaultOpenbooleanfalseDefault open state (uncontrolled)
onOpenChangefunctionNot setCalled when open state changes
modaluniontrueWhether to render as modal (blocks interaction with rest of page)
disablePointerDismissalbooleanNot setDisable outside-click dismissal
onOpenChangeCompletefunctionNot setCalled after open/close animation completes
snapPointsarrayNot setPreset snap-point heights for bottom-sheet drawers
swipeDirectionenumupdownleftrightderived from `side` prop on ContentSwipe direction to dismiss.

Accessibility

  • Automatically traps focus within the drawer
  • Closes on Escape key press
  • Returns focus to trigger element on close
  • Uses role="dialog" with proper aria attributes

Guidance

Use when

  • Editing or creating alongside the page behind it
  • Touch-reachable action sheets
  • Navigation that slides in and back out
  • Detail views that overlay rather than replace

Avoid when

  • A centred task (use Dialog)
  • Navigation that stays on screen (use Sidebar)
  • A short list of actions (use Menu or Popover)
  • Feedback the user does not act on (use Toast)
  • DialogsiblingUse Dialog for centered modal overlays
  • SidebaralternativeUse Sidebar for permanent side navigation
  • PopoveralternativeUse Popover for small contextual content

Next steps