# 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) => ( <> Title Content )} ``` ```tsx import { Drawer, Button } from "@heroui/react"; Title Content ``` ### Placement ```tsx {(onClose) => ( <> Left Drawer Content )} ``` ```tsx Left Drawer Content ``` ### Backdrop Variant ```tsx {(onClose) => ( <> Blurred Backdrop Content )} ``` ```tsx Blurred Backdrop Content ``` ### Controlled State ```tsx import { useDisclosure } from "@heroui/react"; const { isOpen, onOpen, onOpenChange } = useDisclosure(); <> {(onClose) => ( <> Controlled Content )} ``` ```tsx import { useOverlayState } from "@heroui/react"; const state = useOverlayState(); <> Controlled Content ``` ### Non-Dismissable ```tsx {(onClose) => ( <> Confirm Action Are you sure? )} ``` ```tsx Confirm Action Are you sure? ``` ## Styling Changes ### v2: `classNames` Prop ```tsx ``` ### v3: Direct `className` Props ```tsx Title Content Actions ``` ## 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