Skip to main content
The @zendeskgarden/react-dropdowns package provides fully accessible, WAI-ARIA compliant combobox and menu components. Use Combobox for selection-based interactions and Menu for action-triggered menus.

Installation

npm install @zendeskgarden/react-dropdowns

# Peer dependencies
npm install react react-dom styled-components @zendeskgarden/react-theming

Combobox

Combobox is the primary selection component. It supports editable input, autocomplete, single and multi-select modes, option grouping, and validation states.

Basic select

Use isEditable={false} to create a non-editable select-only combobox.
import { ThemeProvider } from '@zendeskgarden/react-theming';
import { Field, Combobox, Option } from '@zendeskgarden/react-dropdowns';

<ThemeProvider>
  <Field>
    <Field.Label>Assignee</Field.Label>
    <Combobox isEditable={false}>
      <Option value="alice" label="Alice Chen" />
      <Option value="bob" label="Bob Martinez" />
      <Option value="carol" label="Carol White" />
    </Combobox>
  </Field>
</ThemeProvider>

Autocomplete

Set isAutocomplete to show the chevron and enable filtered-list behavior. Filtering logic is left to you — update the rendered <Option> list in response to onChange.
import { ThemeProvider } from '@zendeskgarden/react-theming';
import { Field, Combobox, Option } from '@zendeskgarden/react-dropdowns';
import { useState } from 'react';

const ALL_OPTIONS = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry'];

function AutocompleteExample() {
  const [options, setOptions] = useState(ALL_OPTIONS);

  return (
    <ThemeProvider>
      <Field>
        <Field.Label>Fruit</Field.Label>
        <Combobox
          isAutocomplete
          placeholder="Type to filter..."
          onChange={({ inputValue }) => {
            if (inputValue !== undefined) {
              setOptions(
                ALL_OPTIONS.filter(o =>
                  o.toLowerCase().includes(inputValue.toLowerCase())
                )
              );
            }
          }}
        >
          {options.map(fruit => (
            <Option key={fruit} value={fruit} />
          ))}
        </Combobox>
      </Field>
    </ThemeProvider>
  );
}

Multi-select

Set isMultiselectable to allow selecting multiple options. Selected values render as removable tags inside the combobox.
import { ThemeProvider } from '@zendeskgarden/react-theming';
import { Field, Combobox, Option } from '@zendeskgarden/react-dropdowns';

<ThemeProvider>
  <Field>
    <Field.Label>Tags</Field.Label>
    <Combobox isMultiselectable isEditable={false} placeholder="Select tags...">
      <Option value="bug" label="Bug" />
      <Option value="feature" label="Feature" />
      <Option value="enhancement" label="Enhancement" />
      <Option value="documentation" label="Documentation" />
    </Combobox>
  </Field>
</ThemeProvider>

Grouped options

Use OptGroup to visually group related options with a section label.
import { ThemeProvider } from '@zendeskgarden/react-theming';
import { Field, Combobox, Option, OptGroup } from '@zendeskgarden/react-dropdowns';

<ThemeProvider>
  <Field>
    <Field.Label>Time zone</Field.Label>
    <Combobox isEditable={false}>
      <OptGroup legend="Americas">
        <Option value="America/New_York" label="Eastern Time" />
        <Option value="America/Chicago" label="Central Time" />
        <Option value="America/Denver" label="Mountain Time" />
        <Option value="America/Los_Angeles" label="Pacific Time" />
      </OptGroup>
      <OptGroup legend="Europe">
        <Option value="Europe/London" label="London" />
        <Option value="Europe/Paris" label="Paris" />
        <Option value="Europe/Berlin" label="Berlin" />
      </OptGroup>
    </Combobox>
  </Field>
</ThemeProvider>

Validation

import { ThemeProvider } from '@zendeskgarden/react-theming';
import { Field, Combobox, Option } from '@zendeskgarden/react-dropdowns';

<ThemeProvider>
  <Field>
    <Field.Label>Priority</Field.Label>
    <Field.Hint>Required for all new tickets.</Field.Hint>
    <Combobox isEditable={false} validation="error">
      <Option value="low" label="Low" />
      <Option value="normal" label="Normal" />
      <Option value="high" label="High" />
      <Option value="urgent" label="Urgent" />
    </Combobox>
    <Field.Message validation="error">Select a priority level.</Field.Message>
  </Field>
</ThemeProvider>

Combobox props

isEditable
boolean
default:"true"
Allows the user to type in the input. Set to false for a select-only combobox.
isAutocomplete
boolean
Indicates that the combobox provides autocompletion. Displays a chevron icon.
isMultiselectable
boolean
Allows selecting multiple options. Selected values render as tags.
isCompact
boolean
Applies compact sizing.
isBare
boolean
Removes borders and padding.
isDisabled
boolean
Disables all interaction.
placeholder
string
Placeholder text displayed when no value is selected.
inputValue
string
Controls the input value in a controlled combobox.
selectionValue
string | string[]
Controls the selected value(s) in a controlled combobox.
isExpanded
boolean
Controls listbox expansion in a controlled combobox.
defaultExpanded
boolean
Default expansion state in an uncontrolled combobox.
maxTags
number
default:"4"
Maximum number of tags visible when the multiselectable combobox is collapsed.
listboxMaxHeight
string
default:"400px"
Maximum height of the dropdown listbox.
listboxZIndex
number
default:"1000"
z-index of the listbox overlay.
startIcon
ReactElement
Icon displayed at the start of the input.
endIcon
ReactElement
Icon displayed at the end of the input (hidden when the chevron is shown).
focusInset
boolean
Applies inset box-shadow styling on focus.
validation
'success' | 'warning' | 'error'
Applies validation state styling.
onChange
function
Called when combobox state changes. Receives { type, isExpanded?, selectionValue?, inputValue?, activeIndex? }.
renderValue
function
Overrides the displayed value when the combobox is collapsed. Receives { selection, inputValue }.
renderExpandTags
(value: number) => string
Overrides the ”+ N more” text displayed when hidden tags exceed maxTags.
listboxAppendToNode
Element | DocumentFragment
Renders the listbox in a portal attached to the specified DOM node.
listboxAriaLabel
string
default:"Options"
Accessible label for the listbox element.

Option

Individual selectable item within a Combobox listbox.
value
string
required
The unique value returned on selection.
label
string
Display text for the option. Defaults to the value if not provided.
isDisabled
boolean
Disables interaction for this option.
isSelected
boolean
Sets the initial selection state.
isHidden
boolean
Hides the option while retaining its selection state (useful for filtered autocomplete).
icon
ReactElement
Icon displayed before the option label.
type
'add' | 'danger' | 'next' | 'previous'
Applies a semantic type style to the option.
tagProps
object
Overrides props for the tag rendered in a multiselectable combobox.

OptGroup

Groups options within a Combobox listbox with an accessible label.
legend
string
Text label for the group.
icon
ReactElement
Icon displayed before the group label.
content
ReactNode
Custom content for the group header. Overrides legend.
Menu renders a trigger button that opens a positioned action menu. Use it for context menus, action lists, and navigation dropdowns.

Basic menu

import { ThemeProvider } from '@zendeskgarden/react-theming';
import { Menu, Item } from '@zendeskgarden/react-dropdowns';

<ThemeProvider>
  <Menu
    button="Actions"
    onChange={({ selectedItems }) => {
      const [selected] = selectedItems;
      console.log('Selected:', selected?.value);
    }}
  >
    <Item value="edit" label="Edit" />
    <Item value="duplicate" label="Duplicate" />
    <Item value="archive" label="Archive" />
    <Item value="delete" label="Delete" type="danger" />
  </Menu>
</ThemeProvider>
import { ThemeProvider } from '@zendeskgarden/react-theming';
import { Menu, Item, ItemGroup, Separator } from '@zendeskgarden/react-dropdowns';

<ThemeProvider>
  <Menu button="File">
    <ItemGroup legend="Document">
      <Item value="new" label="New" />
      <Item value="open" label="Open" />
    </ItemGroup>
    <Separator />
    <Item value="save" label="Save" />
    <Item value="save-as" label="Save as..." />
    <Separator />
    <Item value="close" label="Close" type="danger" />
  </Menu>
</ThemeProvider>

Custom trigger

Pass a render function to button to use a custom trigger element instead of Garden’s default Button.
import { ThemeProvider } from '@zendeskgarden/react-theming';
import { Menu, Item } from '@zendeskgarden/react-dropdowns';
import { IconButton } from '@zendeskgarden/react-buttons';
import OverflowIcon from '@zendeskgarden/svg-icons/src/16/overflow-stroke.svg';

<ThemeProvider>
  <Menu
    button={(props, ref) => (
      <IconButton aria-label="More options" {...props} ref={ref}>
        <OverflowIcon />
      </IconButton>
    )}
  >
    <Item value="edit" label="Edit" />
    <Item value="delete" label="Delete" type="danger" />
  </Menu>
</ThemeProvider>
button
string | function
required
Text label for the default trigger Button, or a render function that receives button props and a ref to render a custom trigger.
buttonProps
IButtonProps
Additional props passed to the trigger Button when button is a string.
placement
string
default:"bottom-start"
Adjusts the position of the menu relative to its trigger. Accepts any Garden placement value.
isCompact
boolean
Applies compact styling to the menu and trigger.
maxHeight
string
default:"400px"
Maximum height of the menu before it scrolls.
hasArrow
boolean
Attaches an arrow pointing toward the trigger element.
isExpanded
boolean
Controls menu expansion in a controlled menu.
defaultExpanded
boolean
Default expansion state in an uncontrolled menu.
selectedItems
ISelectedItem[]
Controls selected items in a controlled menu.
zIndex
number
default:"1000"
z-index of the menu overlay.
onChange
function
Called on menu state changes. Receives { type, isExpanded?, selectedItems?, focusedValue? }.
restoreFocus
boolean
Returns keyboard focus to the trigger element when the menu closes.

Item

Individual item within a Menu.
value
string
required
Unique value returned on selection.
label
string
Display text for the item. Defaults to value.
icon
ReactElement
Icon displayed before the item label.
type
'add' | 'danger' | 'next' | 'previous'
Applies a semantic type style. Use 'danger' for destructive actions.
isDisabled
boolean
Disables interaction for this item.
isSelected
boolean
Sets the initial selection state.
href
string
Renders the item as an anchor element.
isExternal
boolean
Opens the href in a new tab when the item is rendered as an anchor.
name
string
Associates the item in a radio-style item group.

ItemGroup

Groups Item elements within a Menu with an optional label.
legend
string
Text label for the item group.
icon
ReactElement
Icon displayed before the group label.
type
string
Configures the selection type for items in the group (e.g., radio).
The legacy @zendeskgarden/react-dropdowns.legacy package is deprecated. Migrate to @zendeskgarden/react-dropdowns@^9.0.0 to use the Combobox and Menu components documented here.

Build docs developers (and LLMs) love