Skip to main content

Overview

Filter results
Narrow down your search results.
Last 7 days
Last 30 days
Drawer is a mobile-first overlay panel that slides up from the bottom edge of the viewport. Use it for mobile action sheets, quick filters, and detail views.
For side-sliding panels on desktop, use Sheet instead. Drawer is optimized for bottom-sheet patterns.

Installation

npm install @araf-ds/core

Usage

import {
  Drawer,
  DrawerClose,
  DrawerContent,
  DrawerDescription,
  DrawerFooter,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
} from "@araf-ds/core"

export default function Example() {
  return (
    <Drawer>
      <DrawerTrigger asChild>
        <Button variant="outline">Open drawer</Button>
      </DrawerTrigger>
      <DrawerContent>
        <DrawerHeader>
          <DrawerTitle>Filter results</DrawerTitle>
          <DrawerDescription>Narrow down your search results.</DrawerDescription>
        </DrawerHeader>
        <div className="px-4 py-2">
          {/* filter content */}
        </div>
        <DrawerFooter>
          <Button>Apply filters</Button>
          <DrawerClose asChild>
            <Button variant="outline">Cancel</Button>
          </DrawerClose>
        </DrawerFooter>
      </DrawerContent>
    </Drawer>
  )
}

Variants

Basic Drawer

<Drawer>
  <DrawerTrigger asChild>
    <Button variant="outline">Open drawer</Button>
  </DrawerTrigger>
  <DrawerContent>
    <DrawerHeader>
      <DrawerTitle>Filter results</DrawerTitle>
      <DrawerDescription>Narrow down your search results.</DrawerDescription>
    </DrawerHeader>
    <div className="px-4 py-2">{/* filter content */}</div>
    <DrawerFooter>
      <Button>Apply filters</Button>
      <DrawerClose asChild>
        <Button variant="outline">Cancel</Button>
      </DrawerClose>
    </DrawerFooter>
  </DrawerContent>
</Drawer>

With Snap Points

<Drawer snapPoints={[0.4, 0.9]}>
  <DrawerContent>
    {/* Snaps to 40% then 90% of viewport height */}
  </DrawerContent>
</Drawer>

Controlled

const [open, setOpen] = useState(false);

<Drawer open={open} onOpenChange={setOpen}>
  <DrawerContent>
    <DrawerHeader>
      <DrawerTitle>Item details</DrawerTitle>
    </DrawerHeader>
    {/* content */}
  </DrawerContent>
</Drawer>

API Reference

Drawer (Root)

open
boolean
Controlled open state.
onOpenChange
(open: boolean) => void
Callback fired when the open state changes.
shouldScaleBackground
boolean
default:"true"
Scales the background app content when the drawer opens.
snapPoints
number[]
Snap point heights as percentages (0–1). The drawer snaps to these heights on drag.

DrawerContent

className
string
Additional Tailwind classes for custom overrides.

Accessibility

  • Drawer uses role="dialog" with aria-modal="true"
  • Focus is trapped inside the drawer while open
  • Pressing Escape closes the drawer
  • The drag handle has aria-label="Drag handle" for screen readers
  • Focus returns to the trigger when the drawer closes

Do’s & Don’ts

Do

  • Use Drawer for mobile action sheets and quick filters
  • Always include a clear close action (Cancel button or swipe down)
  • Use snapPoints for Drawers with variable content height
  • Keep drawer content focused on a single task

Don't

  • Don’t use Drawer for desktop-primary layouts — use Sheet or Modal
  • Don’t stack drawers inside other drawers
  • Don’t put complex multi-step forms in a Drawer
  • Don’t rely on the drag-to-close gesture as the only close mechanism