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
278            .date_picker
279            .update_and_scroll_to_displayed_year(action),
280        Message::DateRangePickerChanged(action) => state
281            .date_range_picker
282            .update_and_scroll_to_displayed_year(action),
283        Message::TimePickerChanged(action) => {
284            state.time_picker.update(action);
285            Task::none()
286        }
287        Message::SliderChanged(progress) => {
288            state.progress = progress;
289            Task::none()
290        }
291        Message::EnabledChanged(enabled) => {
292            state.enabled = enabled;
293            Task::none()
294        }
295        Message::ChoiceSelected(choice) => {
296            state.radio_choice = Some(choice);
297            Task::none()
298        }
299        Message::SegmentSelected(choice) => {
300            state.segment_choice = choice;
301            state.segment_state.select(choice.index(), Instant::now());
302            Task::none()
303        }
304        Message::PrimaryTabSelected(choice) => {
305            state.primary_tab = choice;
306            state.primary_tab_state.select(
307                choice.index(),
308                Instant::now(),
309                material::widget::tabs::Variant::Primary,
310            );
311            Task::none()
312        }
313        Message::SecondaryTabSelected(choice) => {
314            state.secondary_tab = choice;
315            state.secondary_tab_state.select(
316                choice.index(),
317                Instant::now(),
318                material::widget::tabs::Variant::Secondary,
319            );
320            Task::none()
321        }
322        Message::MenuPressed => {
323            state.navigation.toggle_menu_now();
324            Task::none()
325        }
326        Message::DialogOpened => {
327            state.alert_dialog.show(Instant::now());
328            Task::none()
329        }
330        Message::DialogDismissed => {
331            state.alert_dialog.dismiss(Instant::now());
332            Task::none()
333        }
334        Message::DialogConfirmed => {
335            state.alert_dialog.dismiss(Instant::now());
336            state.count += 1;
337            Task::none()
338        }
339        Message::ShowSnackbar => {
340            state.snackbar.show(Instant::now());
341            Task::none()
342        }
343        Message::SnackbarUndo => {
344            state.count -= 1;
345            state.snackbar.dismiss(Instant::now());
346            Task::none()
347        }
348        Message::WindowResized(size) => {
349            state.window_size = size;
350            Task::none()
351        }
352        Message::ThemeChanged(action) => {
353            state.theme_controller.update(
354                action,
355                state.window_size,
356                theme_picker::bottom_margin_for_navigation_layout(
357                    state.adaptive_navigation_layout(),
358                ),
359                Instant::now(),
360            );
361            Task::none()
362        }
363        Message::Frame(now) => {
364            let _ = state.theme_controller.advance(now);
365            let _ = state.navigation.advance(now);
366            let _ = state.segment_state.advance(now);
367            let _ = state.primary_tab_state.advance(now);
368            let _ = state.secondary_tab_state.advance(now);
369            state.progress_animation.advance(now);
370            let _ = state.alert_dialog.advance(now);
371            let _ = state.snackbar.advance(now);
372            let _ = state.date_picker.advance(now);
373            let _ = state.date_range_picker.advance(now);
374            let _ = state.time_picker.advance(now);
375            Task::none()
376        }
377    }
378}
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
278            .date_picker
279            .update_and_scroll_to_displayed_year(action),
280        Message::DateRangePickerChanged(action) => state
281            .date_range_picker
282            .update_and_scroll_to_displayed_year(action),
283        Message::TimePickerChanged(action) => {
284            state.time_picker.update(action);
285            Task::none()
286        }
287        Message::SliderChanged(progress) => {
288            state.progress = progress;
289            Task::none()
290        }
291        Message::EnabledChanged(enabled) => {
292            state.enabled = enabled;
293            Task::none()
294        }
295        Message::ChoiceSelected(choice) => {
296            state.radio_choice = Some(choice);
297            Task::none()
298        }
299        Message::SegmentSelected(choice) => {
300            state.segment_choice = choice;
301            state.segment_state.select(choice.index(), Instant::now());
302            Task::none()
303        }
304        Message::PrimaryTabSelected(choice) => {
305            state.primary_tab = choice;
306            state.primary_tab_state.select(
307                choice.index(),
308                Instant::now(),
309                material::widget::tabs::Variant::Primary,
310            );
311            Task::none()
312        }
313        Message::SecondaryTabSelected(choice) => {
314            state.secondary_tab = choice;
315            state.secondary_tab_state.select(
316                choice.index(),
317                Instant::now(),
318                material::widget::tabs::Variant::Secondary,
319            );
320            Task::none()
321        }
322        Message::MenuPressed => {
323            state.navigation.toggle_menu_now();
324            Task::none()
325        }
326        Message::DialogOpened => {
327            state.alert_dialog.show(Instant::now());
328            Task::none()
329        }
330        Message::DialogDismissed => {
331            state.alert_dialog.dismiss(Instant::now());
332            Task::none()
333        }
334        Message::DialogConfirmed => {
335            state.alert_dialog.dismiss(Instant::now());
336            state.count += 1;
337            Task::none()
338        }
339        Message::ShowSnackbar => {
340            state.snackbar.show(Instant::now());
341            Task::none()
342        }
343        Message::SnackbarUndo => {
344            state.count -= 1;
345            state.snackbar.dismiss(Instant::now());
346            Task::none()
347        }
348        Message::WindowResized(size) => {
349            state.window_size = size;
350            Task::none()
351        }
352        Message::ThemeChanged(action) => {
353            state.theme_controller.update(
354                action,
355                state.window_size,
356                theme_picker::bottom_margin_for_navigation_layout(
357                    state.adaptive_navigation_layout(),
358                ),
359                Instant::now(),
360            );
361            Task::none()
362        }
363        Message::Frame(now) => {
364            let _ = state.theme_controller.advance(now);
365            let _ = state.navigation.advance(now);
366            let _ = state.segment_state.advance(now);
367            let _ = state.primary_tab_state.advance(now);
368            let _ = state.secondary_tab_state.advance(now);
369            state.progress_animation.advance(now);
370            let _ = state.alert_dialog.advance(now);
371            let _ = state.snackbar.advance(now);
372            let _ = state.date_picker.advance(now);
373            let _ = state.date_range_picker.advance(now);
374            let _ = state.time_picker.advance(now);
375            Task::none()
376        }
377    }
378}

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