‹ components

Drawer

draftv0.9.0·open in canvas

Side sheet on Radix Dialog — slides from an edge; Sheet's desktop sibling.

Installnpx shadcn add @cids/drawer
Live demo

Motion · tap to replay

honors reduced-motion

Panel slides from its edge (`slide-in-from-right/left`, 150ms enter + exit via the animate presets); overlay fades. Neutralized by `prefers-reduced-motion`.

Brand chip remounts on tap · highlighted tokens are named in this component's doc · spring is budgeted to human feedback only.

import { Drawer, Button } from "@/design-system";

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

<Drawer
  open={open}
  onOpenChange={setOpen}
  title="Order details"
  description="Filled 2m ago"
  footer={<Button variant="primary" size="sm">Done</Button>}
>
  {/* detail rows */}
</Drawer>

Tokens · live

Resolves in the active theme — flip the toggle above to verify.

States · from doc

Parsed from the doc. Interact with the live demo for hover/active.

**Closed**: nothing rendered.**Open**: overlay + panel; Escapeoverlay clickor the × closes.

Side sheet on Radix Dialog — slides from an edge; Sheet's desktop sibling.

Anatomy

      ┌─────────────────┐
▒▒▒▒▒▒│ Title        [×]│ ← header pins
▒over-│ description     │
▒lay▒▒│ children        │ ← scrolls (flex-1)
▒▒▒▒▒▒│                 │
      │        [actions]│ ← footer pins (safe-area pb)
      └─────────────────┘
       ← w-[min(88vw,340px)], inset-y-0, side border

Props

PropTypeDefaultNotes
open / onOpenChangeboolean / (open) => void—Controlled.
titlestring—Required — a drawer must name itself.
descriptionstring—Wired to aria-describedby.
side"right" "left"`"right"Edge it slides from.
childrenReactNode—Scrollable body.
footerReactNode—Pinned action row.
classNamestring—Merged onto the panel.

Motion

Panel slides from its edge (slide-in-from-right/left, 150ms enter +

exit via the animate presets); overlay fades. Neutralized by

prefers-reduced-motion.

A11y

Radix Dialog semantics: role="dialog", aria-modal, focus trap,

focus restore to the trigger on close, required accessible name from

title (+ optional description via aria-describedby, wired with

an explicit id). The close button carries aria-label="Close".

Self-contained: copy the folder into any Tailwind+React app, or use the install command above. Docs and this page render the same file on disk — they cannot drift.