# Dropdown **Category**: react **URL**: https://www.heroui.com/docs/react/migration/dropdown **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/migration/(components)/dropdown.mdx > Migration guide for Dropdown from HeroUI v2 to v3 *** Refer to the [v3 Dropdown documentation](/docs/react/components/dropdown) for complete API reference, styling guide, and advanced examples. This guide only focuses on migrating from HeroUI v2. ## Structure Changes In v2, Dropdown used separate components: `DropdownTrigger`, `DropdownMenu`, `DropdownItem`, `DropdownSection`: ```tsx import { Dropdown, DropdownTrigger, DropdownMenu, DropdownItem, Button } from "@heroui/react"; export default function App() { return ( New file Copy link ); } ``` In v3, Dropdown uses a compound component pattern with explicit subcomponents: ```tsx import { Dropdown, Button, Label } from "@heroui/react"; export default function App() { return ( ); } ``` ## Key Changes ### 1. Component Structure **v2:** Separate components: `DropdownTrigger`, `DropdownMenu`, `DropdownItem`, `DropdownSection` **v3:** Compound components: `Dropdown.Trigger`, `Dropdown.Popover`, `Dropdown.Menu`, `Dropdown.Item`, `Dropdown.Section` ### 2. Component Name Changes | v2 Component | v3 Component | Notes | |-------------|--------------|-------| | `DropdownTrigger` | `Dropdown.Trigger` | Same functionality | | `DropdownMenu` | `Dropdown.Menu` | Wrapped in `Dropdown.Popover` | | `DropdownItem` | `Dropdown.Item` | Use `id` and `textValue`; keep `key` on list items | | `DropdownSection` | `Dropdown.Section` | Same functionality | | - | `Dropdown.Popover` | New wrapper component (required) | ### 3. Item Identification **v2:** Item content passed as children; React's `key` was used for both list reconciliation and item identity (selection, focus). **v3:** Item content must use `Label` component for text. Give each item an `id` (for state/focus) and `textValue` (for accessibility when content isn't plain text). Keep React's `key` on items in lists. ### 4. Prop Changes | v2 Prop | v3 Location | Notes | |---------|-------------|-------| | `variant`, `color` (on DropdownMenu) | - | Removed (no menu variants) | | `classNames`, `itemClasses` (on DropdownMenu) | - | Use `className` on Menu and items | | `color` (on DropdownItem) | `Dropdown.Item` | Use `variant="danger"` for danger | | `title` | - | Use `Label` component as child | | `description` | - | Use `Description` component as child | | `shortcut` | - | Use `Kbd` component as child | | `startContent`, `endContent` | - | Use icon/components as children | | `selectedIcon` | - | Use `Dropdown.ItemIndicator` | | `showDivider` | - | Use `Separator` between items | | `classNames` (on DropdownItem) | - | Use `className` on item | | `isSelected` | `Dropdown.Menu` | Use `selectedKeys` on Menu | | `isDisabled` | `Dropdown.Menu` | Use `disabledKeys` on Menu | | `trigger` (on Dropdown) | `Dropdown` | Still supported: `"press"` (default) or `"longPress"` | ### 5. New Components - `Dropdown.Popover` - Required wrapper around `Dropdown.Menu` - `Dropdown.ItemIndicator` - For selection indicators (checkmark/dot) - `Dropdown.SubmenuTrigger` - For submenu functionality - `Dropdown.SubmenuIndicator` - For submenu chevron indicator ## Migration Examples ### With Action Handler ```tsx alert(key)}> New file ``` ```tsx alert(key)}> ``` ### Item Content ```tsx {/* With icon */} } > New file {/* With description */} Edit file {/* With shortcut */} Copy ``` ```tsx import { Icon } from "@iconify/react"; import { Label, Description, Kbd } from "@heroui/react"; {/* With icon */} {/* With description */} Edit the file {/* With shortcut */} C ``` ### Danger Item ```tsx Delete file ``` ```tsx ``` ### With Sections ```tsx New file Edit file Delete file ``` ```tsx import { Header, Separator } from "@heroui/react";
Actions
Danger zone
```
### Selection ```tsx import { useState } from "react"; {/* Single selection */} const [singleSelected, setSingleSelected] = useState(new Set(["text"])); Text Number {/* Multiple selection */} const [multiSelected, setMultiSelected] = useState(new Set(["bold"])); Bold Italic ``` ```tsx import { useState } from "react"; {/* Single selection */} const [singleSelected, setSingleSelected] = useState(new Set(["text"])); {/* Multiple selection */} const [multiSelected, setMultiSelected] = useState(new Set(["bold"])); ``` ### With Keyboard Shortcuts ```tsx Copy ``` ```tsx import { Label, Kbd } from "@heroui/react"; C ``` The `slot="keyboard"` prop on `Kbd` positions the shortcut at the end of the menu item, replacing the v2 `shortcut` prop. ### With Submenus ```tsx {/* v2 did not have built-in submenu support */} ``` ```tsx import { Label } from "@heroui/react"; ``` Use `Dropdown.SubmenuTrigger` to wrap an item that opens a nested menu. Place `Dropdown.SubmenuIndicator` inside the item to render a chevron icon. ### Long Press Trigger ```tsx Cut Copy ``` ```tsx ``` The `trigger` prop on `Dropdown` accepts `"press"` (default) or `"longPress"` to control how the menu is opened. ## Component Anatomy The v3 Dropdown follows this structure: ``` Dropdown (Root) — accepts trigger="press" | "longPress" ├── Dropdown.Trigger (optional, defaults to first child) ├── Dropdown.Popover (required wrapper) │ └── Dropdown.Menu │ ├── Dropdown.Item │ │ ├── Icon (optional, first child) │ │ ├── Label (required for text) │ │ ├── Description (optional) │ │ ├── Kbd slot="keyboard" (optional, for shortcuts) │ │ └── Dropdown.ItemIndicator (optional, for selection) │ ├── Separator (for dividers) │ ├── Dropdown.Section │ │ ├── Header (optional) │ │ └── Dropdown.Item │ └── Dropdown.SubmenuTrigger │ ├── Dropdown.Item │ │ ├── Label │ │ └── Dropdown.SubmenuIndicator (chevron icon) │ └── Dropdown.Popover │ └── Dropdown.Menu │ └── Dropdown.Item ``` ## Summary 1. **Component Structure**: Must use compound components (`Dropdown.Trigger`, `Dropdown.Popover`, `Dropdown.Menu`, etc.) 2. **Dropdown.Popover Required**: `Dropdown.Menu` must be wrapped in `Dropdown.Popover` 3. **Label Component**: Item text must use `Label` component 4. **Description Component**: Use `Description` component instead of `description` prop 5. **Kbd Component**: Use `Kbd` with `slot="keyboard"` instead of the `shortcut` prop — the slot positions the shortcut at the end of the menu item 6. **Icons as Children**: Icons go as first child, not `startContent` prop 7. **Separator Component**: Use `Separator` instead of `showDivider` prop 8. **ItemIndicator Component**: Use `Dropdown.ItemIndicator` for selection indicators 9. **Variant Instead of Color**: Use `variant="danger"` instead of `color="danger"` 10. **No Menu Variants**: `Dropdown.Menu` no longer supports `variant` or `color` props 11. **ClassNames Removed**: Use `className` props on individual components 12. **Submenu Support**: Use `Dropdown.SubmenuTrigger` to wrap an item that opens a nested menu, and `Dropdown.SubmenuIndicator` inside the item for a chevron icon 13. **Trigger Prop**: Use `trigger="longPress"` on `Dropdown` root to open the menu on long press instead of the default press