# Drawer
**Category**: react
**URL**: https://www.heroui.com/docs/react/migration/drawer
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/migration/(components)/drawer.mdx
> Migration guide for Drawer from HeroUI v2 to v3
***
Refer to the [v3 Drawer documentation](/docs/react/components/drawer) for complete API reference, styling guide, and advanced examples. This guide only focuses on migrating from HeroUI v2.
## Structure Changes
In v2, `Drawer` shared the same API as `Modal`, using `DrawerContent`, `DrawerHeader`, `DrawerBody`, and `DrawerFooter` with a render callback pattern:
```tsx
import { Drawer, DrawerContent, DrawerHeader, DrawerBody, DrawerFooter, Button, useDisclosure } from "@heroui/react";
export default function App() {
const { isOpen, onOpen, onOpenChange } = useDisclosure();
return (
<>
{(onClose) => (
<>
Drawer Title
Drawer content goes here.
>
)}
>
);
}
```
In v3, Drawer uses a compound component pattern with explicit subcomponents and built-in trigger support:
```tsx
import { Drawer, Button } from "@heroui/react";
export default function App() {
return (
Drawer Title
Drawer content goes here.
);
}
```
## Key Changes
### 1. Component Structure
**v2:** `Drawer` wrapping `DrawerContent` with a render callback pattern; separate trigger via `useDisclosure`
**v3:** Compound components: `Drawer`, `Drawer.Backdrop`, `Drawer.Content`, `Drawer.Dialog`, `Drawer.Header`, `Drawer.Heading`, `Drawer.Body`, `Drawer.Footer`, `Drawer.Handle`, `Drawer.CloseTrigger`. Trigger is the first child of `Drawer`.
### 2. Trigger Pattern
**v2:** External trigger using `useDisclosure` hook with `isOpen`/`onOpenChange`
**v3:** Built-in trigger — first child of `Drawer` becomes the trigger automatically. Controlled state available via `useOverlayState` hook.
### 3. New Features in v3
- **Drag to dismiss**: Built-in pointer-based drag gestures on handle, header, and footer areas
- **Drag handle**: `Drawer.Handle` component for visual drag indicator
- **Built-in close trigger**: `Drawer.CloseTrigger` renders a close button
- **Slot-based close**: Buttons with `slot="close"` automatically close the drawer
### 4. Prop Changes
| v2 Prop | v3 Equivalent | Notes |
|---------|---------------|-------|
| `isOpen` | `Drawer.Backdrop` `isOpen` | Or use `useOverlayState` |
| `onOpenChange` | `Drawer.Backdrop` `onOpenChange` | Or use `useOverlayState` |
| `onClose` | - | Use `onOpenChange` or `slot="close"` on buttons |
| `placement` | `Drawer.Content` `placement` | `"right"` → `"right"`, `"left"` → `"left"`, `"top"` → `"top"`, `"bottom"` → `"bottom"`. Default changed from `"right"` to `"bottom"` |
| `size` | - | Removed (use Tailwind CSS on `Drawer.Dialog`) |
| `radius` | - | Removed (use Tailwind CSS) |
| `backdrop` | `Drawer.Backdrop` `variant` | Same values: `"opaque"`, `"blur"`, `"transparent"` |
| `isDismissable` | `Drawer.Backdrop` `isDismissable` | Same |
| `isKeyboardDismissDisabled` | `Drawer.Backdrop` `isKeyboardDismissDisabled` | Same |
| `shouldBlockScroll` | - | Always blocks scroll in v3 |
| `hideCloseButton` | - | Omit `Drawer.CloseTrigger` to hide |
| `closeButton` | - | Pass custom content to `Drawer.CloseTrigger` |
| `motionProps` | - | Removed (CSS-based animations in v3) |
| `disableAnimation` | - | Removed |
| `portalContainer` | - | Removed |
| `classNames` | - | Use `className` on individual compound components |
### 5. Hook Changes
**v2:** `useDisclosure` hook for open/close state
**v3:** `useOverlayState` hook (replaces `useDisclosure`)
```tsx
// v2
const { isOpen, onOpen, onOpenChange } = useDisclosure();
// v3
const state = useOverlayState();
// state.isOpen, state.open(), state.close(), state.toggle()
```
## Migration Examples
### Basic Drawer
```tsx
import { Drawer, DrawerContent, DrawerHeader, DrawerBody, DrawerFooter, Button, useDisclosure } from "@heroui/react";
const { isOpen, onOpen, onOpenChange } = useDisclosure();
<>
{(onClose) => (
<>
TitleContent
>
)}
>
```
```tsx
import { Drawer, Button } from "@heroui/react";
TitleContent
```
### Placement
```tsx
{(onClose) => (
<>
Left DrawerContent
>
)}
```
```tsx
Left DrawerContent
```
### Backdrop Variant
```tsx
{(onClose) => (
<>
Blurred BackdropContent
>
)}
```
```tsx
Blurred BackdropContent
```
### Controlled State
```tsx
import { useDisclosure } from "@heroui/react";
const { isOpen, onOpen, onOpenChange } = useDisclosure();
<>
{(onClose) => (
<>
ControlledContent
>
)}
>
```
```tsx
import { useOverlayState } from "@heroui/react";
const state = useOverlayState();
<>
ControlledContent
>
```
### Non-Dismissable
```tsx
{(onClose) => (
<>
Confirm ActionAre you sure?
>
)}
```
```tsx
Confirm ActionAre you sure?
```
## Styling Changes
### v2: `classNames` Prop
```tsx
```
### v3: Direct `className` Props
```tsx
TitleContentActions
```
## Component Anatomy
The v3 Drawer follows this structure:
```
Drawer (Root)
├── [Trigger element] (first child becomes trigger)
└── Drawer.Backdrop
└── Drawer.Content (placement)
└── Drawer.Dialog
├── Drawer.Handle (optional, drag indicator)
├── Drawer.CloseTrigger (optional, close button)
├── Drawer.Header
│ └── Drawer.Heading
├── Drawer.Body (scrollable)
└── Drawer.Footer
```
## Summary
1. **Component Structure**: Render callback pattern → compound components with explicit subcomponents
2. **Trigger Pattern**: External `useDisclosure` + `onPress` → built-in trigger (first child of `Drawer`)
3. **State Hook**: `useDisclosure` → `useOverlayState` with `open()`, `close()`, `toggle()` methods
4. **Placement**: Prop on `Drawer` → prop on `Drawer.Content`. Default changed from `"right"` to `"bottom"`
5. **Backdrop**: `backdrop` prop → `Drawer.Backdrop` `variant` prop
6. **Close Button**: `hideCloseButton`/`closeButton` props → omit or customize `Drawer.CloseTrigger`
7. **Slot-Based Close**: Buttons with `slot="close"` automatically close the drawer
8. **New Features**: Drag-to-dismiss with `Drawer.Handle`, velocity-based dismissal
9. **Animations**: `motionProps` (Framer Motion) → CSS-based animations
10. **Styling Props Removed**: `size`, `radius` → use Tailwind CSS
11. **ClassNames Removed**: Use `className` on individual compound components