Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/zendeskgarden/website/llms.txt

Use this file to discover all available pages before exploring further.

Installation

npm install @zendeskgarden/react-dropdowns styled-components
import { Menu, Item, ItemGroup, Separator } from '@zendeskgarden/react-dropdowns';

When to use

Use a Menu:
  • To let users see and choose one thing from a list of items
  • To limit user selection within grouped items
Do not use a Menu:
  • To let users type or select options in a form — use Combobox instead
  • To move between views — use Tabs instead
  • To let users choose from a list of parallel actions next to a button — combine with Split button

Usage

Default

Menu renders a trigger button internally and manages its own open/close state. The button prop customises the trigger label.
import { Menu, Item } from '@zendeskgarden/react-dropdowns';

function Example() {
  return (
    <Menu
      button="Choose a flower"
      onSelect={item => console.log('Selected:', item.value)}
    >
      <Item value="sunflower">Sunflower</Item>
      <Item value="violet">Violet</Item>
      <Item value="daisy">Daisy</Item>
    </Menu>
  );
}

Custom trigger

Replace the default trigger with any interactive element by providing a button prop as a render function or using the Dropdown + Trigger pattern.
import { Button } from '@zendeskgarden/react-buttons';
import { Menu, Item } from '@zendeskgarden/react-dropdowns';

function Example() {
  return (
    <Menu button={props => <Button {...props}>Custom trigger</Button>}>
      <Item value="option-1">Option 1</Item>
      <Item value="option-2">Option 2</Item>
    </Menu>
  );
}

Danger items

Use danger styling on Item components that trigger destructive actions.
<Menu button="Actions">
  <Item value="edit">Edit</Item>
  <Item value="duplicate">Duplicate</Item>
  <Item value="delete" isDanger>Delete</Item>
</Menu>

Disabled items

Disable individual items to prevent interaction while keeping them visible.
<Menu button="Actions">
  <Item value="edit">Edit</Item>
  <Item value="archive" disabled>Archive (unavailable)</Item>
  <Item value="delete" isDanger>Delete</Item>
</Menu>

Media items

Add icons before or after item text for additional context.
import { ReactComponent as EditIcon } from '@zendeskgarden/svg-icons/src/16/pencil-stroke.svg';
import { ReactComponent as TrashIcon } from '@zendeskgarden/svg-icons/src/16/trash-stroke.svg';

<Menu button="Actions">
  <Item value="edit">
    <Item.StartIcon>
      <EditIcon />
    </Item.StartIcon>
    Edit
  </Item>
  <Item value="delete" isDanger>
    <Item.StartIcon>
      <TrashIcon />
    </Item.StartIcon>
    Delete
  </Item>
</Menu>

Meta text

Add Item.Meta inside an item to show supplementary information.
<Menu button="Environments">
  <Item value="production">
    Production
    <Item.Meta>us-east-1</Item.Meta>
  </Item>
  <Item value="staging">
    Staging
    <Item.Meta>us-west-2</Item.Meta>
  </Item>
</Menu>

Grouped items

Use ItemGroup to visually and semantically group related items. Add a legend prop to label the group.
import { Menu, Item, ItemGroup, Separator } from '@zendeskgarden/react-dropdowns';

function Example() {
  return (
    <Menu button="Choose a flower">
      <Item value="sunflower">Sunflower</Item>
      <Separator />
      <ItemGroup legend="Smaller flowers">
        <Item value="violet">Violet</Item>
        <Item value="daisy">Daisy</Item>
        <Item value="pansy">Pansy</Item>
      </ItemGroup>
    </Menu>
  );
}

Selectable groups

Set type="checkbox" or type="radio" on ItemGroup to make items selectable.
<Menu button="Sort by">
  <ItemGroup type="radio" legend="Order">
    <Item value="asc">Ascending</Item>
    <Item value="desc">Descending</Item>
  </ItemGroup>
</Menu>

Nested menus

Menus can contain nested levels for additional categorization.
<Menu button="Format">
  <Item value="bold">Bold</Item>
  <Item value="italic">Italic</Item>
  <Item value="text-size" type="next">
    Text size
    <Menu>
      <Item value="small">Small</Item>
      <Item value="medium">Medium</Item>
      <Item value="large">Large</Item>
    </Menu>
  </Item>
</Menu>

Placement

The default menu placement is bottom-start. Override it with the placement prop.
<Menu button="Open upward" placement="top-start">
  <Item value="option-1">Option 1</Item>
  <Item value="option-2">Option 2</Item>
</Menu>

Size

Menus can be default or compact. The compact size reduces vertical padding on items.
<Menu button="Compact menu" isCompact>
  <Item value="option-1">Option 1</Item>
  <Item value="option-2">Option 2</Item>
</Menu>

Iterating over items

Use Array.map to render items from data:
const ITEMS = [
  { value: 'sunflower', label: 'Sunflower' },
  { value: 'violet', label: 'Violet' },
  { value: 'daisy', label: 'Daisy' },
];

<Menu button="Choose a flower">
  {ITEMS.map(item => (
    <Item key={item.value} value={item.value}>
      {item.label}
    </Item>
  ))}
</Menu>
For groups:
const GROUPS = [
  {
    legend: 'Common',
    items: [{ value: 'sunflower', label: 'Sunflower' }],
  },
  {
    legend: 'Rare',
    items: [
      { value: 'violet', label: 'Violet' },
      { value: 'daisy', label: 'Daisy' },
    ],
  },
];

<Menu button="Choose a flower">
  {GROUPS.map(group => (
    <ItemGroup key={group.legend} legend={group.legend}>
      {group.items.map(item => (
        <Item key={item.value} value={item.value}>
          {item.label}
        </Item>
      ))}
    </ItemGroup>
  ))}
</Menu>

Keyboard navigation

KeyBehavior
Enter / SpaceOpens the menu when focus is on the trigger; selects the focused item
ArrowDownMoves focus to the next item
ArrowUpMoves focus to the previous item
ArrowRightOpens a nested menu
ArrowLeft / EscapeCloses a nested menu or the root menu
HomeMoves focus to the first item
EndMoves focus to the last item
TabCloses the menu and moves focus to the next focusable element

API

The Menu component follows this structure:
<Menu button="Trigger label">
  <Item value="..." />
  <ItemGroup legend="...">
    <Item value="..." />
  </ItemGroup>
  <Separator />
</Menu>
props.button
string | ((props: object) => ReactElement)
The trigger for the menu. Pass a string to use the default Garden button, or a render function to use a custom trigger element.
props.onSelect
(item: { value: string }) => void
Callback fired when a user selects an item. Receives the selected item object.
props.placement
string
default:"'bottom-start'"
Placement of the menu relative to the trigger. Accepts any Floating UI placement value.
props.isCompact
boolean
default:"false"
Reduces vertical padding on menu items.
props.hasArrow
boolean
default:"false"
Renders a directional arrow pointing to the trigger element.
props.fallbackPlacements
string[]
Alternative placement values for automatic repositioning when the preferred placement lacks space.

Item props

props.value
string
required
Unique value for the item. Passed to the onSelect callback.
props.isDanger
boolean
default:"false"
Applies danger styling.
props.disabled
boolean
default:"false"
Prevents interaction with the item.
props.type
'next'
Set to 'next' to indicate the item opens a nested menu.

ItemGroup props

props.legend
string
Accessible label for the group. Rendered as a visible group heading.
props.type
'checkbox' | 'radio'
Enables selection behavior within the group. 'radio' allows single selection; 'checkbox' allows multiple.

Build docs developers (and LLMs) love