Dropdown
Display a menu of actions anchored to a trigger.
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.
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
| Style | Description |
|---|---|
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_pointer | Trigger base, cursor and focus surface. |
Dropdown::render trigger_wrap | Trigger interaction motion. |
floating + scrollable_popover + max_h_full + overlay surface | Positions 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_radius | Floating panel radius token. |
overlay_phase::Entering + placement | Popover enter motion. |
overlay_phase::Exiting | Popover exit motion. |
Menu root: flex_col + gap(px(2.)) + p(px(4.)) | Menu layout and inset. |
Menu root | Shared 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 motion | Menu row interaction motion. |
theme hover background | Hovered menu row surface. |
press scale | Pressed menu row feedback. |
disabled_keys | Disabled row treatment. |
indicator slot | Selection indicator placement and size. |
submenu indicator | Submenu chevron styling. |
MenuItem::danger | Danger item variant. |
Curve constants | Official easing tokens used by trigger, popover and rows. |
active theme overlay tokens | Official floating-surface tokens. |
API reference
Builders
| Builder | Type | Default | Description |
|---|---|---|---|
is_open( | bool | — | Sets the open state of the menu (controlled). |
default_open( | bool | — | Sets the default open state of the menu (uncontrolled). |
on_open_change( | Fn( | — | Handler called when the open state changes. |
trigger( | DropdownTrigger | DropdownTrigger:: | The type of interaction that triggers the menu. |
new( | id, | — | Dropdown content. |
placement( | DropdownPlacement | DropdownPlacement:: | Placement 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 | SelectionMode:: | Whether single or multiple selection is enabled. |
selected_keys( | iterable of keys | — | The currently selected keys (controlled). |
default_selected_keys( | iterable of keys | — | The initial selected keys (uncontrolled). |
on_selection_change( | Fn( | — | Handler called when the selection changes. |
disabled_keys( | iterable of keys | — | Keys of disabled items. |
on_action( | Fn( | — | Handler called when an item is activated. |
new( | id, | — | Menu content. |
SectionLabel + items | AnyElement | — | Section content. |
new( | key, | — | Unique identifier for the item. |
danger( | "default" | | "default" | Visual variant of the item. |
item_content( | AnyElement | | — | Item content or a render function. |
indicator( | IndicatorKind | IndicatorKind:: | Type of selection indicator to display. |
indicator_content( | AnyElement | | — | Custom indicator content or render function. |
item_content( | state. | — | Render-function state: whether the item is selected. |
item_content( | state. | — | Render-function state: whether the item has focus. |
item_content( | state. | — | Render-function state: whether the item is disabled. |
item_content( | state. | — | Render-function state: whether the item is being pressed. |
submenu( | items | — | Custom submenu indicator content. |
Parts
| Part | Description |
|---|---|
Dropdown | MenuTrigger wrapper that owns open state and composes the trigger and popover. |
Dropdown | Button or custom element that opens the menu. |
Dropdown | Floating panel positioned relative to the trigger. |
Menu | Scrollable menu container and selection owner. |
Menu | Grouped menu items with an optional header. |
MenuItem | Focusable action or selectable menu row; descriptions wrap within the popover width. |
Menu | Checkmark or dot selection marker. |
MenuItem | Trailing chevron for an item that opens a submenu. |
MenuItem | Item wrapper that keeps the parent open while opening a child popover. |
States
| Builder | State | Description |
|---|---|---|
track_interaction + theme hover | Hovered | Pointer is over the trigger or a menu item. |
FocusHandle / keyed menu focus | Focused | Element owns keyboard focus. |
focus_handle + status-focused | Focus visible | Keyboard focus indicator is visible. |
track_interaction + scale | Pressed | Trigger or item is being activated. |
disabled_keys + disabled row | Disabled | Trigger or item cannot be activated. |
selected_keys + selection_mode | Selected | Item is selected in single or multiple mode. |
overlay_phase::Entering | Entering | Popover is playing its enter transition. |
overlay_phase::Exiting | Exiting | Popover remains mounted while its exit transition plays. |