SelectItem
SelectItem is the option record used by Select.
It is not a widget on its own. Instead, it carries the label, optional icon, and already-prepared action for one row in the opened select menu.
Example
use fission::prelude::*;
let items = vec![
SelectItem {
label: "Compact".into(),
icon: None,
on_select: ActionEnvelope {
id: set_density_id,
payload: serde_json::to_vec(&SetDensity(Density::Compact)).unwrap(),
},
},
SelectItem {
label: "Comfortable".into(),
icon: None,
on_select: ActionEnvelope {
id: set_density_id,
payload: serde_json::to_vec(&SetDensity(Density::Comfortable)).unwrap(),
},
},
];
Each item contains the final action for that option, so Select does not have to guess how your state model works.
Field table
| Field | Type | Meaning | Notes / default behavior |
|---|---|---|---|
label | String | Visible text for the option row. | Required. |
icon | Option<String> | Optional icon source shown before the label. | Defaults to None. |
on_select | ActionEnvelope | Action dispatched when this option is chosen. | Required. Usually updates the selected value and closes the menu. |
How to think about it
Because SelectItem stores a ready-made ActionEnvelope, it works best when every item can prepare its own payload during build. That is exactly what you want for enums, ids, and other small typed choices.
A good reducer usually stores the real selected value in state and derives selected_label separately. Do not let the label string become your only source of truth unless the label is the product value.
Specific advice
Make the on_select action do both pieces of work the user expects: set the new value and close the select by updating is_open in state. The widget itself will not close unless your state says so.