Skip to main content

State

Struct State 

Source
pub struct State<T> { /* private fields */ }
Expand description

Searchable select state.

The inner state keeps the current search query and filtered Material menu options. The public state also stores the original options so selected values and typed input can be mirrored by the demo/application state without replacing user-entered text on blur.

Implementations§

Source§

impl<T> State<T>
where T: Display + Clone,

Source

pub fn new(options: Vec<T>) -> Self

Creates a new State for a combobox with the given list of options.

Source

pub fn with_selection(options: Vec<T>, selection: Option<&T>) -> Self

Creates a new State for a combobox with the given list of options and selected value.

Examples found in repository?
examples/showcase/app.rs (lines 183-186)
173    fn default() -> Self {
174        Self {
175            navigation: navigation::NavigationState::new(ShowcasePage::Inputs),
176            window_size: Size::new(1080.0, 980.0),
177            count: 0,
178            note: String::new(),
179            editor_content: material::widget::text_editor::Content::with_text(
180                "Material 3 multi-line text editor",
181            ),
182            select_choice: Some("Assist"),
183            combobox_options: material::widget::combobox::State::with_selection(
184                vec!["Assist", "Suggestion", "Filter"],
185                Some(&"Suggestion"),
186            ),
187            combobox_choice: Some("Suggestion"),
188            combobox_input: String::new(),
189            search_query: String::new(),
190            date_picker: material::widget::picker::DatePickerState::new(
191                material::widget::picker::Date::new(2026, 7, 4),
192            ),
193            date_range_picker: material::widget::picker::DateRangePickerState::new(
194                material::widget::picker::Date::new(2026, 7, 4),
195                material::widget::picker::Date::new(2026, 7, 10),
196            ),
197            time_picker: material::widget::picker::TimePickerState::new(14, 30, false),
198            progress: 42.0,
199            enabled: true,
200            radio_choice: Some(RadioChoice::Standard),
201            segment_choice: SegmentChoice::List,
202            segment_state: material::widget::segmented_button::State::new(
203                SegmentChoice::List.index(),
204            ),
205            primary_tab: TabChoice::Inputs,
206            primary_tab_state: material::widget::tabs::State::new(TabChoice::Inputs.index()),
207            secondary_tab: TabChoice::Controls,
208            secondary_tab_state: material::widget::tabs::State::new(TabChoice::Controls.index()),
209            progress_animation: material::widget::progress_bar::IndeterminateState::new(
210                Instant::now(),
211            ),
212            alert_dialog: material::widget::dialog::Transition::default(),
213            snackbar: material::widget::snackbar::Transition::default(),
214            theme_controller: theme_picker::ThemeController::default(),
215        }
216    }
Source

pub fn options(&self) -> &[T]

Returns the original options.

Source

pub fn push(&mut self, new_option: T)

Pushes a new option.

Source

pub fn into_options(self) -> Vec<T>

Returns ownership of the original options.

Source

pub fn set_input(&mut self, input: impl Into<String>)

Synchronizes the internal query with the latest user input.

Examples found in repository?
examples/showcase/app.rs (line 268)
233fn update(state: &mut Showcase, message: Message) -> Task<Message> {
234    match message {
235        Message::Navigate(page) => {
236            state
237                .navigation
238                .select(page, Instant::now(), state.adaptive_navigation_layout());
239            Task::none()
240        }
241        Message::Increment => {
242            state.count += 1;
243            Task::none()
244        }
245        Message::Decrement => {
246            state.count -= 1;
247            Task::none()
248        }
249        Message::TextChanged(note) => {
250            state.note = note;
251            Task::none()
252        }
253        Message::EditorAction(action) => {
254            state.editor_content.perform(action);
255            Task::none()
256        }
257        Message::SelectChanged(choice) => {
258            state.select_choice = Some(choice);
259            Task::none()
260        }
261        Message::ComboboxSelected(choice) => {
262            state.combobox_choice = Some(choice);
263            state.combobox_input.clear();
264            state.combobox_options.set_selection(Some(&choice));
265            Task::none()
266        }
267        Message::ComboboxInputChanged(input) => {
268            state.combobox_options.set_input(input.clone());
269            state.combobox_input = input;
270            state.combobox_choice = None;
271            Task::none()
272        }
273        Message::SearchChanged(query) => {
274            state.search_query = query;
275            Task::none()
276        }
277        Message::DatePickerChanged(action) => state.date_picker.update_and_scroll(action),
278        Message::DateRangePickerChanged(action) => {
279            state.date_range_picker.update_and_scroll(action)
280        }
281        Message::TimePickerChanged(action) => {
282            state.time_picker.update(action);
283            Task::none()
284        }
285        Message::SliderChanged(progress) => {
286            state.progress = progress;
287            Task::none()
288        }
289        Message::EnabledChanged(enabled) => {
290            state.enabled = enabled;
291            Task::none()
292        }
293        Message::ChoiceSelected(choice) => {
294            state.radio_choice = Some(choice);
295            Task::none()
296        }
297        Message::SegmentSelected(choice) => {
298            state.segment_choice = choice;
299            state.segment_state.select(choice.index(), Instant::now());
300            Task::none()
301        }
302        Message::PrimaryTabSelected(choice) => {
303            state.primary_tab = choice;
304            state.primary_tab_state.select(
305                choice.index(),
306                Instant::now(),
307                material::widget::tabs::Variant::Primary,
308            );
309            Task::none()
310        }
311        Message::SecondaryTabSelected(choice) => {
312            state.secondary_tab = choice;
313            state.secondary_tab_state.select(
314                choice.index(),
315                Instant::now(),
316                material::widget::tabs::Variant::Secondary,
317            );
318            Task::none()
319        }
320        Message::MenuPressed => {
321            state.navigation.toggle_menu_now();
322            Task::none()
323        }
324        Message::DialogOpened => {
325            state.alert_dialog.show(Instant::now());
326            Task::none()
327        }
328        Message::DialogDismissed => {
329            state.alert_dialog.dismiss(Instant::now());
330            Task::none()
331        }
332        Message::DialogConfirmed => {
333            state.alert_dialog.dismiss(Instant::now());
334            state.count += 1;
335            Task::none()
336        }
337        Message::ShowSnackbar => {
338            state.snackbar.show(Instant::now());
339            Task::none()
340        }
341        Message::SnackbarUndo => {
342            state.count -= 1;
343            state.snackbar.dismiss(Instant::now());
344            Task::none()
345        }
346        Message::WindowResized(size) => {
347            state.window_size = size;
348            Task::none()
349        }
350        Message::ThemeChanged(action) => {
351            state.theme_controller.update(
352                action,
353                state.window_size,
354                theme_picker::bottom_margin(state.adaptive_navigation_layout()),
355                Instant::now(),
356            );
357            Task::none()
358        }
359        Message::Frame(now) => {
360            let _ = state.theme_controller.advance(now);
361            let _ = state.navigation.advance(now);
362            let _ = state.segment_state.advance(now);
363            let _ = state.primary_tab_state.advance(now);
364            let _ = state.secondary_tab_state.advance(now);
365            state.progress_animation.advance(now);
366            let _ = state.alert_dialog.advance(now);
367            let _ = state.snackbar.advance(now);
368            let _ = state.date_picker.advance(now);
369            let _ = state.date_range_picker.advance(now);
370            let _ = state.time_picker.advance(now);
371            Task::none()
372        }
373    }
374}
Source

pub fn set_selection(&mut self, selection: Option<&T>)

Synchronizes the internal query with the selected option.

Examples found in repository?
examples/showcase/app.rs (line 264)
233fn update(state: &mut Showcase, message: Message) -> Task<Message> {
234    match message {
235        Message::Navigate(page) => {
236            state
237                .navigation
238                .select(page, Instant::now(), state.adaptive_navigation_layout());
239            Task::none()
240        }
241        Message::Increment => {
242            state.count += 1;
243            Task::none()
244        }
245        Message::Decrement => {
246            state.count -= 1;
247            Task::none()
248        }
249        Message::TextChanged(note) => {
250            state.note = note;
251            Task::none()
252        }
253        Message::EditorAction(action) => {
254            state.editor_content.perform(action);
255            Task::none()
256        }
257        Message::SelectChanged(choice) => {
258            state.select_choice = Some(choice);
259            Task::none()
260        }
261        Message::ComboboxSelected(choice) => {
262            state.combobox_choice = Some(choice);
263            state.combobox_input.clear();
264            state.combobox_options.set_selection(Some(&choice));
265            Task::none()
266        }
267        Message::ComboboxInputChanged(input) => {
268            state.combobox_options.set_input(input.clone());
269            state.combobox_input = input;
270            state.combobox_choice = None;
271            Task::none()
272        }
273        Message::SearchChanged(query) => {
274            state.search_query = query;
275            Task::none()
276        }
277        Message::DatePickerChanged(action) => state.date_picker.update_and_scroll(action),
278        Message::DateRangePickerChanged(action) => {
279            state.date_range_picker.update_and_scroll(action)
280        }
281        Message::TimePickerChanged(action) => {
282            state.time_picker.update(action);
283            Task::none()
284        }
285        Message::SliderChanged(progress) => {
286            state.progress = progress;
287            Task::none()
288        }
289        Message::EnabledChanged(enabled) => {
290            state.enabled = enabled;
291            Task::none()
292        }
293        Message::ChoiceSelected(choice) => {
294            state.radio_choice = Some(choice);
295            Task::none()
296        }
297        Message::SegmentSelected(choice) => {
298            state.segment_choice = choice;
299            state.segment_state.select(choice.index(), Instant::now());
300            Task::none()
301        }
302        Message::PrimaryTabSelected(choice) => {
303            state.primary_tab = choice;
304            state.primary_tab_state.select(
305                choice.index(),
306                Instant::now(),
307                material::widget::tabs::Variant::Primary,
308            );
309            Task::none()
310        }
311        Message::SecondaryTabSelected(choice) => {
312            state.secondary_tab = choice;
313            state.secondary_tab_state.select(
314                choice.index(),
315                Instant::now(),
316                material::widget::tabs::Variant::Secondary,
317            );
318            Task::none()
319        }
320        Message::MenuPressed => {
321            state.navigation.toggle_menu_now();
322            Task::none()
323        }
324        Message::DialogOpened => {
325            state.alert_dialog.show(Instant::now());
326            Task::none()
327        }
328        Message::DialogDismissed => {
329            state.alert_dialog.dismiss(Instant::now());
330            Task::none()
331        }
332        Message::DialogConfirmed => {
333            state.alert_dialog.dismiss(Instant::now());
334            state.count += 1;
335            Task::none()
336        }
337        Message::ShowSnackbar => {
338            state.snackbar.show(Instant::now());
339            Task::none()
340        }
341        Message::SnackbarUndo => {
342            state.count -= 1;
343            state.snackbar.dismiss(Instant::now());
344            Task::none()
345        }
346        Message::WindowResized(size) => {
347            state.window_size = size;
348            Task::none()
349        }
350        Message::ThemeChanged(action) => {
351            state.theme_controller.update(
352                action,
353                state.window_size,
354                theme_picker::bottom_margin(state.adaptive_navigation_layout()),
355                Instant::now(),
356            );
357            Task::none()
358        }
359        Message::Frame(now) => {
360            let _ = state.theme_controller.advance(now);
361            let _ = state.navigation.advance(now);
362            let _ = state.segment_state.advance(now);
363            let _ = state.primary_tab_state.advance(now);
364            let _ = state.secondary_tab_state.advance(now);
365            state.progress_animation.advance(now);
366            let _ = state.alert_dialog.advance(now);
367            let _ = state.snackbar.advance(now);
368            let _ = state.date_picker.advance(now);
369            let _ = state.date_range_picker.advance(now);
370            let _ = state.time_picker.advance(now);
371            Task::none()
372        }
373    }
374}

Trait Implementations§

Source§

impl<T> Debug for State<T>
where T: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Default for State<T>
where T: Display + Clone,

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<T> !Freeze for State<T>

§

impl<T> !RefUnwindSafe for State<T>

§

impl<T> !Sync for State<T>

§

impl<T> Send for State<T>
where T: Send,

§

impl<T> Unpin for State<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for State<T>

§

impl<T> UnwindSafe for State<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<State, Message> IntoBoot<State, Message> for State

Source§

fn into_boot(self) -> (State, Task<Message>)

Turns some type into the initial state of some Application.
Source§

impl<T> MaybeClone for T

Source§

impl<T> MaybeDebug for T

Source§

impl<T> MaybeSend for T
where T: Send,

Source§

impl<T> NoneValue for T
where T: Default,

Source§

type NoneType = T

Source§

fn null_value() -> T

The none-equivalent value.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more