iced-cube

Overlays

Dropdown menu

A menu of actions that opens from a button, with check marks, radio choices and submenus.

use iced_cube::dropdown_menu::{
    self, Event, Output, State, checkbox_item, dropdown_menu, group_label, item,
    radio_item, separator, submenu,
};
API reference
Default: Items with icons and shortcut hints, a submenu, a disabled item and a destructive one.Default: Items with icons and shortcut hints, a submenu, a disabled item and a destructive one.
Static preview
Default. Items with icons and shortcut hints, a submenu, a disabled item and a destructive one.

Usage

The app owns a dropdown_menu::State and routes its events into it. When update returns an Output, the menu has already closed and updated its own check marks, so the app only acts on the choice. Read checkbox and radio values back with state.is_checked(id), or keep your own copy and call set_checked when it changes elsewhere.

The trigger is any element you pass in, usually a button whose message carries Event::Toggle. Escape and a click outside send Event::Close through on_event, and Escape inside a submenu closes just that submenu. The click that closes the menu goes no further, so a menu inside a dialog closes without closing the dialog too. Clicks inside the menu never reach the widgets underneath it, and a tooltip on the trigger stays hidden while the menu is open.

Moving the pointer over an item highlights it, and the keyboard moves the same highlight. The open menu handles its own keys before anything else sees them, so it needs no subscription. A closed menu claims no keys at all, so the arrow keys, Enter and Space stay free for the rest of your app. To open a menu from the keyboard, bind a chord to Action::Open and route presses from keys::subscription() through state.key_event, as the keyboard example does. The keyboard guide explains how keys reach each layer.

The menu opens on the side you ask for, or the opposite side when only that one has room for all of it. When neither does, it takes the roomier side and scrolls, so it never covers its trigger. A submenu opens beside its item, flipping to the other side near the edge of the window. On a screen too narrow for either, it drops below or above the item instead, so the item’s label stays visible.

When any item in a menu has an icon, a check mark or a radio dot, every row gets one leading slot, so all the labels start at the same place. A checked item shows its mark in that slot, and any other item shows its icon there, or leaves it empty.

Shortcut hints are only labels. Bind the keys themselves in your own keymap. The context menu uses the same entries and rows, opened with a right-click.

Examples

Checkbox items

Items that toggle a check mark, one of them disabled.

Checkbox items: Items that toggle a check mark, one of them disabled.Checkbox items: Items that toggle a check mark, one of them disabled.
Static preview

Radio items

A group of items where choosing one unchecks the others.

Radio items: A group of items where choosing one unchecks the others.Radio items: A group of items where choosing one unchecks the others.
Static preview

Submenu

A nested menu that opens beside its item, on hover or with the right arrow key.

Submenu: A nested menu that opens beside its item, on hover or with the right arrow key.Submenu: A nested menu that opens beside its item, on hover or with the right arrow key.
Static preview

Keyboard shortcuts

The open menu resolves its own keys through the keymap, with typeahead for letters. The app binds Alt+ArrowDown to open it.

Keyboard shortcuts: The open menu resolves its own keys through the keymap, with typeahead for letters. The app binds Alt+ArrowDown to open it.Keyboard shortcuts: The open menu resolves its own keys through the keymap, with typeahead for letters. The app binds Alt+ArrowDown to open it.
Static preview

In a dialog

A menu inside a dialog. A click outside or Escape closes only the menu; the next one closes the dialog.

In a dialog: A menu inside a dialog. A click outside or Escape closes only the menu; the next one closes the dialog.In a dialog: A menu inside a dialog. A click outside or Escape closes only the menu; the next one closes the dialog.
Static preview

API

ItemDescription
State::new(entries)Holds the entries, closed. Item ids must be unique, including those in submenus.
item(id, label)An action. Add .icon(glyph), .shortcut("Ctrl+S"), .disabled(true) or .destructive(true).
checkbox_item(id, label, checked)An item with a check mark that toggles when chosen.
radio_item(id, label, checked)One choice among the radio items next to it. Choosing it unchecks the rest of that run.
submenu(id, label, entries)Opens a nested menu to its right, on hover, click, Enter or the right arrow key.
group_label(text) / separator()A heading for the items below it, and a line between groups.
state.update(Event)Handles Open, Close, Toggle, Highlight, Next, Previous, First, Last, OpenSubmenu, CloseSubmenu, Activate, ActivateHighlighted and Typeahead. Returns Output::Activated, Toggled or Selected when an item is chosen, and closes the menu.
state.is_open() / state.highlighted() / state.depth()Whether the menu is open, the highlighted item's id, and how many menus are open including submenus.
state.item(id) / state.is_checked(id)An item by id, and whether a checkbox or radio item is checked.
state.set_checked(id, bool) / state.set_disabled(id, bool)Changes an item from your own state, for example when a setting changes elsewhere.
dropdown_menu(&state, trigger)Renders the trigger with the menu below it while it is open. Items render disabled until .on_event is set.
.on_event(f)Maps menu events to your message. The trigger sends Event::Toggle itself.
.side(Side) / .align(Align) / .gap(f32)Where the menu opens. Defaults to below the trigger, lined up with its left edge.
.width(f32)Width of the menu and its submenus. Defaults to 224.
.keymap(keymap)Replaces the default keymap the open menu resolves its keys with. Unbinding Escape there stops Escape closing the menu.
overlay::menu::row_style(tokens, RowStatus, destructive)The colours of a row when idle, highlighted or disabled, shared by every menu and list, for reuse in custom menus.
dropdown_menu::default_keymap()The default shortcuts as a Keymap<Action>. Bind, unbind or clear chords to change them. Open has no default chord.
state.key_event(&keymap, &key)Resolves a key press through the keymap and, while the menu is open, turns letters and digits into typeahead. Route presses from keys::subscription through it to open a closed menu with a chord bound to Action::Open.
action.event(&state)Turns a resolved Action into the Event to pass to state.update, or None when it does nothing. Only Open works while the menu is closed.

Keyboard

Default shortcuts. Every one can be changed or removed with a keymap; see Keyboard shortcuts.

KeysAction
ArrowDownNext Highlights the next enabled item, wrapping.
ArrowUpPrevious Highlights the previous enabled item, wrapping.
HomeFirst Highlights the first enabled item.
EndLast Highlights the last enabled item.
Enter or SpaceActivate Chooses the highlighted item or opens its submenu.
EscapeClose Closes the innermost submenu, or the menu.
ArrowRightOpenSubmenu Opens the highlighted submenu.
ArrowLeftCloseSubmenu Closes the innermost submenu.
Esc