Docs·Drawer

Drawer

An accessible, draggable side panel with focus management, configurable edges, footer layouts, and an optional grab handle.

Installation

$pnpm dlx shadcn@latest add @spiderui/drawer

Usage

API Reference

PropTypeDefault
openControls drawer visibility.
boolean—
onOpenChangeReceives visibility changes.
(open: boolean) => void—
titleRequired accessible drawer title.
ReactNode—
descriptionOptional accessible description.
ReactNode—
childrenScrollable drawer content.
ReactNode—
footerPersistent footer actions.
ReactNode—
footerAlignmentAligns footer actions.
"left" | "right" | "spread""right"
sideSets opening edge.
"left" | "right" | "top" | "bottom""right"
widthSets left and right panel width.
number | string420
heightSets top and bottom panel height.
number | string420
showHandleShows draggable dismiss handle.
booleanfalse
showCloseShows header close control.
booleantrue
closeOnEscapeAllows Escape dismissal.
booleantrue
closeOnBackdropAllows backdrop dismissal.
booleantrue
lockScrollLocks page scrolling while open.
booleantrue
dismissThresholdDrag distance ratio required to dismiss.
number0.32
inwardPullAdds restrained elastic travel toward the page.
number0.08

Click on the icon in the top right of the example preview to view the source code for specific variants.

Keep in mind

This component is inspired by various open-source projects and patterns. Please verify licenses and implementation details before using in production.

Have any questions?
Contact on@ctrlcat0x
import { Drawer } from "@/components/ui/drawer"
export function EditProfile() {
  const [open, setOpen] = useState(false)

  return (
    <>
      <Button onClick={() => setOpen(true)}>Edit profile</Button>
      <Drawer
        open={open}
        onOpenChange={setOpen}
        title="Edit profile"
        description="Visible to everyone in the workspace"
        side="right"
        width={420}
        footerAlignment="right"
        footer={
          <>
            <Button variant="outline" onClick={() => setOpen(false)}>Cancel</Button>
            <Button onClick={() => setOpen(false)}>Save changes</Button>
          </>
        }
      >
        <div>Profile fields</div>
      </Drawer>
    </>
  )
}