Select

Select is the fixed-choice dropdown in the authoring widget set.
Use it when the user must choose one option from a known list and should not type arbitrary text. The widget renders a trigger button and, when open, a flyout menu of SelectItem entries.

Example

use fission::prelude::*;

let widget: Widget = Select {
id: WidgetId::explicit("theme_select"),
selected_label: Some(view.state().theme_label.clone()),
items: vec![
    SelectItem {
        label: "System".into(),
        icon: None,
        on_select: system_theme_action,
    },
    SelectItem {
        label: "Dark".into(),
        icon: None,
        on_select: dark_theme_action,
    },
],
is_open: view.state().theme_select_open,
on_toggle: Some(toggle_theme_select_action),
placeholder: "Select theme".into(),
width: Some(240.0),
}
.into();
The Select widget only reflects state. The reducer still decides which item is selected and whether the popup is open.

Field table

Field
Type
Meaning
Notes / default behavior
id
WidgetId
Stable identity for the trigger and flyout anchor.
Required. The Default id is only suitable for demos. Use a unique id in real apps.
selected_label
Option<String>
Label currently shown in the closed trigger.
If None, the placeholder is shown.
items
Vec<SelectItem>
Options available in the menu.
Required.
is_open
bool
Whether the flyout menu is visible.
Controlled by app state.
on_toggle
Option<ActionEnvelope>
Action dispatched when the trigger is pressed.
Defaults to None. Usually toggles is_open.
placeholder
String
Text shown before the user has picked a value.
Defaults to "Select...".
width
Option<f32>
Width of the trigger and menu.
Defaults to Some(200.0) in Default.

How selection flows through the app

The trigger button only opens or closes the menu. The actual selection happens inside each SelectItem's on_select action. That is why a good item action usually does two things in the reducer: update the selected value in state and close the menu.
selected_label is only display data. In most apps you should keep the real selected value as an enum or id in state, then derive the label in component conversion or a selector.

Specific advice

Use Select for fixed choice sets. If users need search, remote results, or typeahead behavior, move to Combobox. Also be deliberate about ids: because open state is explicit and portals are anchored by id, a unique WidgetId matters in real screens.

Production checklist

For Select, review the fields that change behavior before treating the widget as finished: id, selected_label, items, is_open, on_toggle, placeholder. The goal is to make the product rule visible in state and actions, not hidden inside ad-hoc construction code.
Bind on_toggle to explicit reducer actions and test that the reducer handles unavailable, duplicate, or invalid input safely.
When child widgets are generated from data, give reordered or filtered rows an explicit WidgetId so retained local state and scroll behavior do not drift between items.
Set id only when identity must be stable across filtering, reordering, diagnostics, or tests; otherwise let Fission derive identity from structure.
Check the semantics tree for the user-facing label or role that makes this widget understandable without relying only on pixels.
Prefer parent layout and design-system sizing first; use explicit size or spacing fields when the product layout requires that constraint on this widget specifically.
Add at least one component or harness test that confirms the visible text, semantic role, action dispatch, and layout constraint that matter for this widget in context.
If a screen starts repeating the same Select setup, extract a named component around this widget. That keeps the reference API small while making product code easier to read and safer for generated code to copy.
SelectItem, Menu, MenuButton, and Combobox.
Fission
A cross-platform, GPU-accelerated user interface framework for Rust. MIT licensed.
Copyright (c) 2026 Fission
Ready to use today. Widget APIs are expected to remain stable; some runtime and shell APIs may change before 1.0.0.
Fission 0.7.0