Develop

Dropdown

Updated: Aug 29, 2026

Overview

Dropdowns allow users to select a single option from a list that is hidden until the user interacts with the dropdown control. The Meta VR UI Set SDK provides a labeled trigger and an icon-only trigger. Both open the same single-selection popup menu.

Common features

  • Items: items takes a PersistentList<DropdownItem>. Each item carries a title and an optional subtitle, leading icon, trailing content, and enabled flag.
  • Selection: selectedItem is matched to items on DropdownItem.key, which defaults to the title. Set key when two items share a title. The dropdown is stateless, so store the selection yourself and update it in onItemSelected.
  • Treatment: filled picks between the filled and borderless defaults. Pass colors directly for anything else.
  • Menu layout: showDividers separates items with lines instead of spacing, and menuShape and menuModifier style the popup.
  • Theming: Trigger, menu, selection, and disabled colors come from DropdownDefaults, and the geometry comes from DropdownDimensions.

Standard dropdown (Dropdown)

  • Usage: Settings and forms where the current value stays visible next to its label.
  • Content: A trigger showing the selected title, an optional leadingIcon, a placeholder for the unselected state, and an optional supportingText second line. showChevron controls the menu affordance.
import kotlinx.collections.immutable.persistentListOf
import metavrx.uiset.compose.dropdown.Dropdown
import metavrx.uiset.compose.dropdown.DropdownItem

val refreshRates = persistentListOf(
    DropdownItem(title = "72 Hz"),
    DropdownItem(title = "90 Hz", subtitle = "Recommended"),
    DropdownItem(title = "120 Hz", enabled = false),
)
var selectedRate by remember { mutableStateOf<DropdownItem?>(null) }

Dropdown(
    items = refreshRates,
    onItemSelected = { selectedRate = it },
    selectedItem = selectedRate,
    placeholder = "Select a refresh rate",
    supportingText = "Applies the next time the app starts",
)

Icon dropdown (IconDropdown)

  • Usage: Toolbars, where the icon and the surrounding context already explain the menu.
  • Content: An icon trigger with no visible label. The trigger uses the pill shape by default.
  • Accessibility: IconDropdown takes no contentDescription of its own, so name the icon you pass. That description becomes the accessible name of the trigger.
import metavrx.uiset.compose.Icon
import metavrx.uiset.compose.dropdown.IconDropdown
import metavrx.uiset.compose.theme.icons.Icons

val sortOptions = persistentListOf(
    DropdownItem(title = "Newest"),
    DropdownItem(title = "Oldest"),
    DropdownItem(title = "Name"),
)
var sortBy by remember { mutableStateOf(sortOptions.first()) }

IconDropdown(
    icon = { Icon(Icons.Regular.ListSort, contentDescription = "Sort") },
    items = sortOptions,
    onItemSelected = { sortBy = it },
    selectedItem = sortBy,
    filled = false,
)

Common parameters

  • items: PersistentList<DropdownItem>: The menu contents.
  • onItemSelected: (DropdownItem) -> Unit: Receives the chosen item.
  • selectedItem: DropdownItem? = null: Current selection, matched on key.
  • filled: Boolean = true: Selects the filled or borderless default colors.
  • enabled: Boolean = true: Controls interactivity of the trigger.
  • showDividers: Boolean = false: Separates menu items with dividers.
  • colors: DropdownColors: Trigger, menu, selection, divider, and disabled colors.
  • dimensions: DropdownDimensions: Trigger, menu, item, icon, and spacing geometry.
  • shape: Shape and menuShape: Shape: Trigger and popup shapes.
  • modifier: Modifier = Modifier: Applied to the full trigger target.
Use the labeled trigger when the reader needs to see the current value, and the icon trigger when space is tight.