ProComponents, templates & AI tooling
HeroUI
27.7k

Dropdown

A dropdown displays a list of actions or options that a user can choose

Import

import { Dropdown } from '@heroui/react';

Usage

Anatomy

Import the Dropdown component and access all parts using dot notation.

import { Dropdown, Button, Label, Description, Header, Kbd, Separator } from '@heroui/react';

export default () => (
  <Dropdown>
    <Dropdown.Trigger>
      <Button />
    </Dropdown.Trigger>
    <Dropdown.Popover>
      <Dropdown.Menu>
        <Dropdown.Item>
          <Label />
          <Description />
          <Kbd slot="keyboard" />
          <Dropdown.ItemIndicator />
        </Dropdown.Item>
        <Separator />
        <Dropdown.Section>
          <Header />
          <Dropdown.Item />
        </Dropdown.Section>
        <Dropdown.SubmenuTrigger>
          <Dropdown.Item>
            <Label />
            <Dropdown.SubmenuIndicator />
          </Dropdown.Item>
          <Dropdown.Popover>
            <Dropdown.Menu>
              <Dropdown.Item />
            </Dropdown.Menu>
          </Dropdown.Popover>
        </Dropdown.SubmenuTrigger>
      </Dropdown.Menu>
    </Dropdown.Popover>
  </Dropdown>
)

With Single Selection

Single With Custom Indicator

With Multiple Selection

With Section Level Selection

With Keyboard Shortcuts

With Icons

Long Press Trigger

With Descriptions

With Sections

With Disabled Items

With Submenus

With Custom Submenu Indicator

Controlled

Controlled Open State

Custom Trigger

Styling

Passing Tailwind CSS classes

import { Dropdown, Button } from '@heroui/react';

function CustomDropdown() {
  return (
    <Dropdown>
      <Dropdown.Trigger className="rounded-lg border p-2 bg-surface">
        <Button>Actions</Button>
      </Dropdown.Trigger>
      <Dropdown.Popover className="min-w-[200px]">
        <Dropdown.Menu>
          <Dropdown.Item id="item-1" textValue="Item 1" className="hover:bg-surface-secondary">
            Item 1
          </Dropdown.Item>
        </Dropdown.Menu>
      </Dropdown.Popover>
    </Dropdown>
  );
}

Customizing the component classes

To customize the Dropdown component classes, you can use the @layer components directive.
Learn more.

@layer components {
  .dropdown {
    @apply flex flex-col gap-1;
  }

  .dropdown__trigger {
    @apply outline-none;
  }

  .dropdown__popover {
    @apply rounded-lg border border-border bg-overlay p-2;
  }

  .dropdown__menu {
    @apply flex flex-col gap-1;
  }
}

HeroUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.

CSS Classes

The Dropdown component uses these CSS classes (View source styles):

Base Classes

  • .dropdown - Base dropdown container
  • .dropdown__trigger - The button or element that triggers the dropdown
  • .dropdown__popover - The popover container
  • .dropdown__menu - The menu container inside the popover

State Classes

  • .dropdown__trigger[data-focus-visible="true"] - Focused trigger state
  • .dropdown__trigger[data-disabled="true"] - Disabled trigger state
  • .dropdown__trigger[data-pressed="true"] - Pressed trigger state
  • .dropdown__popover[data-entering] - Entering animation state
  • .dropdown__popover[data-exiting] - Exiting animation state
  • .dropdown__menu[data-selection-mode="single"] - Single selection mode
  • .dropdown__menu[data-selection-mode="multiple"] - Multiple selection mode

The Dropdown component uses Menu, MenuItem, and MenuSection as base components. These classes are also available for customization:

  • .menu - Base menu container (menu.css)
    • [data-slot="separator"] - Separator elements within the menu
  • .menu-item - Base menu item container (menu-item.css)
  • .menu-item__indicator - Selection indicator (checkmark or dot)
    • [data-slot="menu-item-indicator--checkmark"] - Checkmark indicator SVG
    • [data-slot="menu-item-indicator--dot"] - Dot indicator SVG
  • .menu-item__indicator--submenu - Submenu indicator (chevron)
  • .menu-item--default - Default variant styling
  • .menu-item--danger - Danger variant styling
  • .menu-item[data-focus-visible="true"] - Focused item state (keyboard focus)
  • .menu-item[data-focus="true"] - Focused item state
  • .menu-item[data-pressed] - Pressed item state
  • .menu-item[data-hovered] - Hovered item state
  • .menu-item[data-selected="true"] - Selected item state
  • .menu-item[data-disabled] - Disabled item state
  • .menu-item[data-has-submenu="true"] - Item with submenu
  • .menu-item[data-selection-mode="single"] - Single selection mode
  • .menu-item[data-selection-mode="multiple"] - Multiple selection mode
  • .menu-item[aria-checked="true"] - Checked item (ARIA)
  • .menu-item[aria-selected="true"] - Selected item (ARIA)

Interactive States

The component supports both CSS pseudo-classes and data attributes for flexibility:

  • Hover: :hover or [data-hovered="true"] on trigger and items
  • Focus: :focus-visible or [data-focus-visible="true"] on trigger and items
  • Disabled: :disabled or [data-disabled="true"] on trigger and items
  • Pressed: :active or [data-pressed="true"] on trigger and items
  • Selected: [data-selected="true"] or [aria-selected="true"] on items

API Reference

PropTypeDefaultDescription
isOpenboolean-Sets the open state of the menu (controlled)
defaultOpenboolean-Sets the default open state of the menu (uncontrolled)
onOpenChange(isOpen: boolean) => void-Handler called when the open state changes
trigger"press" | "longPress""press"The type of interaction that triggers the menu
classNamestring-Additional CSS classes
childrenReactNode-Dropdown content
PropTypeDefaultDescription
classNamestring-Additional CSS classes
childrenReactNode | RenderFunction-Trigger content or render function

All Button props are also supported when using a Button as the trigger.

PropTypeDefaultDescription
placement"bottom" | "bottom left" | "bottom right" | "bottom start" | "bottom end" | "top" | "top left" | "top right" | "top start" | "top end" | "left" | "left top" | "left bottom" | "start" | "start top" | "start bottom" | "right" | "right top" | "right bottom" | "end" | "end top" | "end bottom""bottom"Placement of the popover relative to the trigger
classNamestring-Additional CSS classes
childrenReactNode-Content children

All Popover props are also supported.

PropTypeDefaultDescription
selectionMode"single" | "multiple" | "none""none"Whether single or multiple selection is enabled
selectedKeysIterable<Key>-The currently selected keys (controlled)
defaultSelectedKeysIterable<Key>-The initial selected keys (uncontrolled)
onSelectionChange(keys: Selection) => void-Handler called when the selection changes
disabledKeysIterable<Key>-Keys of disabled items
onAction(key: Key) => void-Handler called when an item is activated
classNamestring-Additional CSS classes
childrenReactNode-Menu content

All Menu props are also supported.

PropTypeDefaultDescription
selectionMode"single" | "multiple"-Selection mode for items within this section
selectedKeysIterable<Key>-The currently selected keys (controlled)
defaultSelectedKeysIterable<Key>-The initial selected keys (uncontrolled)
onSelectionChange(keys: Selection) => void-Handler called when the selection changes
disabledKeysIterable<Key>-Keys of disabled items
classNamestring-Additional CSS classes
childrenReactNode-Section content

All MenuSection props are also supported.

PropTypeDefaultDescription
idKey-Unique identifier for the item
textValuestring-Text content of the item for typeahead
variant"default" | "danger""default"Visual variant of the item
classNamestring-Additional CSS classes
childrenReactNode | RenderFunction-Item content or render function

All MenuItem props are also supported.

PropTypeDefaultDescription
type"checkmark" | "dot""checkmark"Type of indicator to display
classNamestring-Additional CSS classes
childrenReactNode | RenderFunction-Custom indicator content or render function

When using a render function, these values are provided:

PropTypeDescription
isSelectedbooleanWhether the item is selected
isIndeterminatebooleanWhether the item is in an indeterminate state
PropTypeDefaultDescription
classNamestring-Additional CSS classes
childrenReactNode-Custom indicator content
PropTypeDefaultDescription
classNamestring-Additional CSS classes
childrenReactNode-Submenu trigger content

All SubmenuTrigger props are also supported.

RenderProps

When using render functions with Dropdown.Item, these values are provided:

PropTypeDescription
isSelectedbooleanWhether the item is selected
isFocusedbooleanWhether the item is focused
isDisabledbooleanWhether the item is disabled
isPressedbooleanWhether the item is being pressed

Examples

Basic Usage

import { Dropdown, Button, Label } from '@heroui/react';

<Dropdown>
  <Button aria-label="Menu" variant="secondary">
    Actions
  </Button>
  <Dropdown.Popover>
    <Dropdown.Menu onAction={(key) => alert(`Selected: ${key}`)}>
      <Dropdown.Item id="new-file" textValue="New file">
        <Label>New file</Label>
      </Dropdown.Item>
      <Dropdown.Item id="open-file" textValue="Open file">
        <Label>Open file</Label>
      </Dropdown.Item>
      <Dropdown.Item id="delete-file" textValue="Delete file" variant="danger">
        <Label>Delete file</Label>
      </Dropdown.Item>
    </Dropdown.Menu>
  </Dropdown.Popover>
</Dropdown>

With Sections

import { Dropdown, Button, Label, Header, Separator } from '@heroui/react';

<Dropdown>
  <Button aria-label="Menu" variant="secondary">
    Actions
  </Button>
  <Dropdown.Popover>
    <Dropdown.Menu onAction={(key) => alert(`Selected: ${key}`)}>
      <Dropdown.Section>
        <Header>Actions</Header>
        <Dropdown.Item id="new-file" textValue="New file">
          <Label>New file</Label>
        </Dropdown.Item>
        <Dropdown.Item id="edit-file" textValue="Edit file">
          <Label>Edit file</Label>
        </Dropdown.Item>
      </Dropdown.Section>
      <Separator />
      <Dropdown.Section>
        <Header>Danger zone</Header>
        <Dropdown.Item id="delete-file" textValue="Delete file" variant="danger">
          <Label>Delete file</Label>
        </Dropdown.Item>
      </Dropdown.Section>
    </Dropdown.Menu>
  </Dropdown.Popover>
</Dropdown>

Controlled Selection

import type { Selection } from '@heroui/react';

import { Dropdown, Button, Label } from '@heroui/react';
import { useState } from 'react';

function ControlledDropdown() {
  const [selected, setSelected] = useState<Selection>(new Set(['bold']));

  return (
    <Dropdown>
      <Button aria-label="Menu" variant="secondary">
        Actions
      </Button>
      <Dropdown.Popover>
        <Dropdown.Menu
          selectedKeys={selected}
          selectionMode="multiple"
          onSelectionChange={setSelected}
        >
          <Dropdown.Item id="bold" textValue="Bold">
            <Label>Bold</Label>
            <Dropdown.ItemIndicator />
          </Dropdown.Item>
          <Dropdown.Item id="italic" textValue="Italic">
            <Label>Italic</Label>
            <Dropdown.ItemIndicator />
          </Dropdown.Item>
        </Dropdown.Menu>
      </Dropdown.Popover>
    </Dropdown>
  );
}

With Submenus

import { Dropdown, Button, Label } from '@heroui/react';

<Dropdown>
  <Button aria-label="Menu" variant="secondary">
    Share
  </Button>
  <Dropdown.Popover>
    <Dropdown.Menu onAction={(key) => alert(`Selected: ${key}`)}>
      <Dropdown.Item id="copy-link" textValue="Copy Link">
        <Label>Copy Link</Label>
      </Dropdown.Item>
      <Dropdown.SubmenuTrigger>
        <Dropdown.Item id="share" textValue="Share">
          <Label>Other</Label>
          <Dropdown.SubmenuIndicator />
        </Dropdown.Item>
        <Dropdown.Popover>
          <Dropdown.Menu>
            <Dropdown.Item id="whatsapp" textValue="WhatsApp">
              <Label>WhatsApp</Label>
            </Dropdown.Item>
            <Dropdown.Item id="telegram" textValue="Telegram">
              <Label>Telegram</Label>
            </Dropdown.Item>
          </Dropdown.Menu>
        </Dropdown.Popover>
      </Dropdown.SubmenuTrigger>
    </Dropdown.Menu>
  </Dropdown.Popover>
</Dropdown>

Accessibility

The Dropdown component implements the ARIA menu pattern and provides:

  • Full keyboard navigation support (arrow keys, home/end, typeahead)
  • Screen reader announcements for actions and selection changes
  • Proper focus management
  • Support for disabled states
  • Long press interaction support
  • Submenu navigation

For more information, see the React Aria Menu documentation.

On this page