Collections

Dropdown

Display a menu of actions anchored to a trigger.

Rust
1use herogpui::components::dropdown::{Dropdown, MenuItem};

Usage

The menu positions against the measured trigger: all eight placements flip to the side with more room when the preferred side cannot fit, keep a 12px cross-axis viewport inset, and cap the scroller to the available height with short menus keeping their natural height.

Rust
1use herogpui::prelude::{Button, Dropdown, MenuItem, Variant};
2use gpui::prelude::*;
3use gpui::px;
4
5gpui::div()
6    .flex()
7    .flex_col()
8    .items_start()
9    .gap(px(12.))
10    .children(vec![
11        Dropdown::new(
12            "dropdown-trigger-dd",
13            Button::new("dropdown-trigger")
14                .label("Actions")
15                .variant(Variant::Secondary),
16            items,
17            is_open,
18        )
19        .id("dropdown-trigger-dd")
20        .on_open_change(bool_cb(cx.listener(|this, open: &bool, _, cx| {
21            this.dropdown_open = *open;
22            cx.notify();
23        })))
24        .on_action(cx.listener(|this, key: &SharedString, _, cx| {
25            this.dropdown_selected = Some(key.clone());
26            this.dropdown_open = false;
27            cx.notify();
28        }))
29        .into_any_element(),
30        para(&format!("Last action: {selected}"), cx),
31    ])

Live HeroGPUI compiled to WebAssembly. Select any example without loading another WASM instance.

Anatomy

Rust types

DropdownMenuMenuItem

Dropdown is assembled from these builders. The API reference lists each one.

Customization

Appearance builders and theme tokens Dropdown uses.

Styling

Dropdown styling
StyleDescription
Menu built-in text styles + Kbd::new().variant(Light)Built-in labels use 14px/20px medium text; descriptions and section headers use 12px/16px. Descriptions stack without a gap, and shortcuts reuse light Kbd.
Dropdown root: flex_col + gap(px(4.))Root wrapper layout.
Dropdown::render trigger_wrap + cursor_pointerTrigger base, cursor and focus surface.
Dropdown::render trigger_wrapTrigger interaction motion.
floating + scrollable_popover + max_h_full + overlay surfacePositions against the measured trigger; all eight placements flip to the side with more room when the preferred side cannot fit, keeping a 12px cross-axis viewport inset with the scroller capped to the available height. Overlay surface.
util::overlay_radiusFloating panel radius token.
overlay_phase::Entering + placementPopover enter motion.
overlay_phase::ExitingPopover exit motion.
Menu root: flex_col + gap(px(2.)) + p(px(4.))Menu layout and inset.
Menu rootShared Menu base styles used by Dropdown.Menu.
Menu::render row .px(px(8.))Standalone Menu row metrics: 36px minimum height, 12px gap, 16px radius, 8px horizontal inset, 6px vertical inset.
Menu::render dropdown_composition .p(px(6.))Dropdown composition overrides the menu inset to 6px.
Menu::render dropdown_composition .px(px(10.))Dropdown composition overrides each row's horizontal inset to 10px.
menu item press/hover motionMenu row interaction motion.
theme hover backgroundHovered menu row surface.
press scalePressed menu row feedback.
disabled_keysDisabled row treatment.
indicator slotSelection indicator placement and size.
submenu indicatorSubmenu chevron styling.
MenuItem::dangerDanger item variant.
Curve constantsOfficial easing tokens used by trigger, popover and rows.
active theme overlay tokensOfficial floating-surface tokens.

API reference

Builders

Dropdown builders
BuilderTypeDefaultDescription
is_open(bool)boolSets the open state of the menu (controlled).
default_open(bool)boolSets the default open state of the menu (uncontrolled).
on_open_change(callback)Fn(isOpen: bool) -> ()Handler called when the open state changes.
trigger(DropdownTrigger)DropdownTriggerDropdownTrigger::PressThe type of interaction that triggers the menu.
new(id, trigger, items, is_open)id, trigger, items, is_openDropdown content.
placement(DropdownPlacement)DropdownPlacementDropdownPlacement::BottomPlacement relative to the measured trigger. All eight placements flip to the side with more room when the preferred side cannot fit, keeping a 12px cross-axis viewport inset with the scroller capped to the available height.
selection_mode(SelectionMode)SelectionModeSelectionMode::NoneWhether single or multiple selection is enabled.
selected_keys(keys)iterable of keysThe currently selected keys (controlled).
default_selected_keys(keys)iterable of keysThe initial selected keys (uncontrolled).
on_selection_change(callback)Fn(keys: Selection) -> ()Handler called when the selection changes.
disabled_keys(keys)iterable of keysKeys of disabled items.
on_action(callback)Fn(key: Key) -> ()Handler called when an item is activated.
new(id, items)id, itemsMenu content.
SectionLabel + itemsAnyElementSection content.
new(key, label)key, labelUnique identifier for the item.
danger()"default" | "danger""default"Visual variant of the item.
item_content(render)AnyElement | render closureItem content or a render function.
indicator(IndicatorKind)IndicatorKindIndicatorKind::CheckmarkType of selection indicator to display.
indicator_content(render)AnyElement | render closureCustom indicator content or render function.
item_content(state.is_selected)state.is_selectedRender-function state: whether the item is selected.
item_content(state.is_focused)state.is_focusedRender-function state: whether the item has focus.
item_content(state.is_disabled)state.is_disabledRender-function state: whether the item is disabled.
item_content(state.is_pressed)state.is_pressedRender-function state: whether the item is being pressed.
submenu(items)itemsCustom submenu indicator content.

Parts

Dropdown parts
PartDescription
DropdownMenuTrigger wrapper that owns open state and composes the trigger and popover.
DropdownButton or custom element that opens the menu.
DropdownFloating panel positioned relative to the trigger.
MenuScrollable menu container and selection owner.
MenuGrouped menu items with an optional header.
MenuItemFocusable action or selectable menu row; descriptions wrap within the popover width.
MenuCheckmark or dot selection marker.
MenuItemTrailing chevron for an item that opens a submenu.
MenuItemItem wrapper that keeps the parent open while opening a child popover.

States

Dropdown states
BuilderStateDescription
track_interaction + theme hoverHoveredPointer is over the trigger or a menu item.
FocusHandle / keyed menu focusFocusedElement owns keyboard focus.
focus_handle + status-focusedFocus visibleKeyboard focus indicator is visible.
track_interaction + scalePressedTrigger or item is being activated.
disabled_keys + disabled rowDisabledTrigger or item cannot be activated.
selected_keys + selection_modeSelectedItem is selected in single or multiple mode.
overlay_phase::EnteringEnteringPopover is playing its enter transition.
overlay_phase::ExitingExitingPopover remains mounted while its exit transition plays.