Skip to main content

TextInputBuilder

Struct TextInputBuilder 

Source
pub struct TextInputBuilder { /* private fields */ }
Expand description

Builder for TextInput views.

Implementations§

Source§

impl TextInputBuilder

Source

pub fn new() -> Self

Source

pub fn value(self, value: impl Into<String>) -> Self

Examples found in repository?
examples/05_todo_list.rs (line 82)
20    fn render(&self, cx: Scope) -> View {
21        let items = state!(cx, || {
22            vec![
23                "Learn Telex".to_string(),
24                "Build something cool".to_string(),
25            ]
26        });
27        let input_value = state!(cx, String::new);
28        let selected = state!(cx, || 0usize);
29        let show_help = state!(cx, || false);
30
31        // F1 toggles help
32        cx.use_command(
33            KeyBinding::key(KeyCode::F(1)),
34            with!(show_help => move || show_help.update(|v| *v = !*v)),
35        );
36
37        // Add new item on submit
38        let on_submit = with!(items, input_value => move || {
39            let text = input_value.get();
40            if !text.is_empty() {
41                items.update(|v| v.push(text));
42                input_value.set(String::new());
43            }
44        });
45
46        // Handle input changes
47        let on_change = with!(input_value => move |text: String| {
48            input_value.set(text);
49        });
50
51        // Delete selected item
52        let on_delete = with!(items, selected => move || {
53            let idx = selected.get();
54            items.update(|v| {
55                if idx < v.len() {
56                    v.remove(idx);
57                    // Adjust selection if needed
58                    if idx > 0 && idx >= v.len() {
59                        selected.set(idx - 1);
60                    }
61                }
62            });
63        });
64
65        // Track selection
66        let on_select = with!(selected => move |idx: usize| {
67            selected.set(idx);
68        });
69
70        let item_count = items.get().len();
71
72        View::vstack()
73            .child(
74                View::styled_text("Todo List")
75                    .color(Color::Cyan)
76                    .bold()
77                    .build(),
78            )
79            .child(View::gap(1))
80            .child(
81                View::text_input()
82                    .value(input_value.get())
83                    .placeholder("Type something to add...")
84                    .on_change(on_change)
85                    .on_submit(on_submit)
86                    .build(),
87            )
88            .child(View::gap(1))
89            .child(if item_count > 0 {
90                View::list()
91                    .items(items.get())
92                    .selected(selected.get())
93                    .on_select(on_select)
94                    .build()
95            } else {
96                View::styled_text("No items yet").dim().build()
97            })
98            .child(View::gap(1))
99            .child(
100                View::hstack()
101                    .child(View::button().label("Delete").on_press(on_delete).build())
102                    .build(),
103            )
104            .child(View::gap(1))
105            .child(
106                View::styled_text("Tab navigate • Enter add/select • F1 help • Ctrl+Q quit")
107                    .dim()
108                    .build(),
109            )
110            .child(
111                View::modal()
112                    .visible(show_help.get())
113                    .title("Example 05: Todo List")
114                    .on_dismiss(with!(show_help => move || show_help.set(false)))
115                    .child(
116                        View::vstack()
117                            .child(View::styled_text("What you're seeing").bold().build())
118                            .child(View::text("• View::text_input() for text entry"))
119                            .child(View::text("• View::list() for displaying items"))
120                            .child(View::text("• on_submit callback for Enter key"))
121                            .child(View::gap(1))
122                            .child(View::styled_text("Key concepts").bold().build())
123                            .child(View::text("• Controlled input: value + on_change"))
124                            .child(View::text("• Vec<String> state for list items"))
125                            .child(View::text("• Conditional rendering (empty state)"))
126                            .child(View::gap(1))
127                            .child(View::styled_text("Try this").bold().build())
128                            .child(View::text("• Type something and press Enter to add"))
129                            .child(View::text("• Use ↑/↓ to select, then Delete button"))
130                            .child(View::text("• Delete all items to see empty state"))
131                            .child(View::gap(1))
132                            .child(View::styled_text("Next up").bold().build())
133                            .child(View::text("→ 06_log_viewer: streaming text content"))
134                            .child(View::gap(1))
135                            .child(View::styled_text("Press Escape to close").dim().build())
136                            .build(),
137                    )
138                    .build(),
139            )
140            .build()
141    }
More examples
Hide additional examples
examples/32_effects.rs (line 92)
23    fn render(&self, cx: Scope) -> View {
24        let show_help = state!(cx, || false);
25
26        // F1 toggles help
27        cx.use_command(
28            KeyBinding::key(KeyCode::F(1)),
29            with!(show_help => move || show_help.update(|v| *v = !*v)),
30        );
31
32        let count = state!(cx, || 0);
33        let name = state!(cx, String::new);
34        let last_effect = state!(cx, || String::from("(none yet)"));
35        let init_done = state!(cx, || false);
36
37        // Effect that runs only once - initialization
38        // Using effect_once! macro (order-independent)
39        effect_once!(cx, with!(init_done, last_effect => move || {
40            init_done.set(true);
41            last_effect.set("effect_once!: initialized!".to_string());
42            || {}
43        }));
44
45        // Effect that runs when count changes
46        // Using effect! macro (order-independent)
47        effect!(cx, count.get(), with!(last_effect => move |&val| {
48            last_effect.set(format!("effect!: count → {}", val));
49            || {}
50        }));
51
52        // Effect that runs when name changes
53        effect!(cx, name.get(), with!(last_effect => move |n: &String| {
54            if !n.is_empty() {
55                last_effect.set(format!("effect!: name → \"{}\"", n));
56            }
57            || {}
58        }));
59
60        View::vstack()
61            .spacing(1)
62            .child(View::styled_text("effect! Demo").bold().build())
63            .child(View::text(""))
64            .child(View::text(format!("Counter: {}", count.get())))
65            .child(
66                View::hstack()
67                    .spacing(1)
68                    .child(
69                        View::button()
70                            .label("[ - ]")
71                            .on_press(with!(count => move || count.update(|n| *n -= 1)))
72                            .build(),
73                    )
74                    .child(
75                        View::button()
76                            .label("[ + ]")
77                            .on_press(with!(count => move || count.update(|n| *n += 1)))
78                            .build(),
79                    )
80                    .build(),
81            )
82            .child(View::text(""))
83            .child({
84                let n = name.get();
85                View::text(format!(
86                    "Name: {}",
87                    if n.is_empty() { "(empty)" } else { &n }
88                ))
89            })
90            .child(
91                View::text_input()
92                    .value(name.get())
93                    .placeholder("Type your name...")
94                    .on_change(with!(name => move |s| name.set(s)))
95                    .build(),
96            )
97            .child(View::text(""))
98            .child(View::styled_text("─── Effect Status ───").dim().build())
99            .child(View::text(""))
100            .child(View::text(format!(
101                "Initialized: {}",
102                if init_done.get() { "✓ yes" } else { "no" }
103            )))
104            .child(View::text(format!("Last effect: {}", last_effect.get())))
105            .child(View::text(""))
106            .child(View::styled_text("─── How it works ───").dim().build())
107            .child(View::text(""))
108            .child(View::text("effect_once!  → Ran once at startup"))
109            .child(View::text("effect!       → Runs when deps change"))
110            .child(View::text(""))
111            .child(
112                View::styled_text("Press +/- or type to see effects trigger")
113                    .dim()
114                    .build(),
115            )
116            .child(View::text(""))
117            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
118            .child(
119                View::modal()
120                    .visible(show_help.get())
121                    .title("Example 32: Effects")
122                    .on_dismiss(with!(show_help => move || show_help.set(false)))
123                    .child(
124                        View::vstack()
125                            .child(View::styled_text("What you're seeing").bold().build())
126                            .child(View::text("• effect_once! runs at startup"))
127                            .child(View::text("• effect! runs when deps change"))
128                            .child(View::text("• Last effect shows what triggered"))
129                            .child(View::gap(1))
130                            .child(View::styled_text("Key concepts").bold().build())
131                            .child(View::text("• effect_once!(cx, || { cleanup })"))
132                            .child(View::text("• effect!(cx, deps, |&d| { cleanup })"))
133                            .child(View::text("• Return || {} for cleanup"))
134                            .child(View::text("• Effects run AFTER render"))
135                            .child(View::text("• Safe in conditionals!"))
136                            .child(View::gap(1))
137                            .child(View::styled_text("Try this").bold().build())
138                            .child(View::text("• Click +/- to change counter"))
139                            .child(View::text("• Type in the name field"))
140                            .child(View::text("• Watch 'Last effect' update"))
141                            .child(View::gap(1))
142                            .child(View::styled_text("Press Escape to close").dim().build())
143                            .build(),
144                    )
145                    .build(),
146            )
147            .build()
148    }
examples/36_reducer.rs (line 105)
38    fn render(&self, cx: Scope) -> View {
39        let show_help = state!(cx, || false);
40
41        cx.use_command(
42            KeyBinding::key(KeyCode::F(1)),
43            with!(show_help => move || show_help.update(|v| *v = !*v)),
44        );
45
46        let (wizard, dispatch) = reducer!(cx, WizardState::Welcome, |state: WizardState, action: WizardAction| {
47            match (state, action) {
48                (_, WizardAction::Reset) => WizardState::Welcome,
49                (WizardState::Welcome, WizardAction::Next) => WizardState::Name(String::new()),
50                (WizardState::Name(_), WizardAction::SetName(n)) => WizardState::Name(n),
51                (WizardState::Name(name), WizardAction::Next) => {
52                    let name = if name.is_empty() { "Anonymous".to_string() } else { name };
53                    WizardState::Color(name, String::new())
54                }
55                (WizardState::Name(_), WizardAction::Back) => WizardState::Welcome,
56                (WizardState::Color(name, _), WizardAction::SetColor(c)) => WizardState::Color(name, c),
57                (WizardState::Color(name, color), WizardAction::Next) => {
58                    let color = if color.is_empty() { "Blue".to_string() } else { color };
59                    WizardState::Done(name, color)
60                }
61                (WizardState::Color(_, _), WizardAction::Back) => WizardState::Name(String::new()),
62                (WizardState::Done(_, _), WizardAction::Back) => WizardState::Welcome,
63                (s, _) => s,
64            }
65        });
66
67        let step = match &wizard.get() {
68            WizardState::Welcome => 1,
69            WizardState::Name(_) => 2,
70            WizardState::Color(_, _) => 3,
71            WizardState::Done(_, _) => 4,
72        };
73
74        let progress = format!("Step {} of 4", step);
75        let dots: String = (1..=4)
76            .map(|i| if i <= step { "●" } else { "○" })
77            .collect::<Vec<_>>()
78            .join(" ");
79
80        let content = match &wizard.get() {
81            WizardState::Welcome => {
82                let d = dispatch.clone();
83                View::vstack()
84                    .spacing(1)
85                    .child(View::styled_text("Welcome to the Wizard!").color(Color::Cyan).bold().build())
86                    .child(View::text("This example shows centralized state"))
87                    .child(View::text("management with reducer!"))
88                    .child(
89                        View::button()
90                            .label("[ Start -> ]")
91                            .on_press(move || d(WizardAction::Next))
92                            .build(),
93                    )
94                    .build()
95            }
96            WizardState::Name(name) => {
97                let d1 = dispatch.clone();
98                let d2 = dispatch.clone();
99                let d3 = dispatch.clone();
100                View::vstack()
101                    .spacing(1)
102                    .child(View::styled_text("What's your name?").color(Color::Cyan).bold().build())
103                    .child(
104                        View::text_input()
105                            .value(name.clone())
106                            .placeholder("Enter your name...")
107                            .on_change(move |s: String| d1(WizardAction::SetName(s)))
108                            .build(),
109                    )
110                    .child(
111                        View::hstack()
112                            .spacing(1)
113                            .child(
114                                View::button()
115                                    .label("[ <- Back ]")
116                                    .on_press(move || d2(WizardAction::Back))
117                                    .build(),
118                            )
119                            .child(
120                                View::button()
121                                    .label("[ Next -> ]")
122                                    .on_press(move || d3(WizardAction::Next))
123                                    .build(),
124                            )
125                            .build(),
126                    )
127                    .build()
128            }
129            WizardState::Color(name, color) => {
130                let d1 = dispatch.clone();
131                let d2 = dispatch.clone();
132                let d3 = dispatch.clone();
133                View::vstack()
134                    .spacing(1)
135                    .child(View::styled_text(format!("Hi, {}! Pick a color:", name)).color(Color::Cyan).bold().build())
136                    .child(
137                        View::text_input()
138                            .value(color.clone())
139                            .placeholder("Enter a color (e.g. Blue)...")
140                            .on_change(move |s: String| d1(WizardAction::SetColor(s)))
141                            .build(),
142                    )
143                    .child(
144                        View::hstack()
145                            .spacing(1)
146                            .child(
147                                View::button()
148                                    .label("[ <- Back ]")
149                                    .on_press(move || d2(WizardAction::Back))
150                                    .build(),
151                            )
152                            .child(
153                                View::button()
154                                    .label("[ Finish -> ]")
155                                    .on_press(move || d3(WizardAction::Next))
156                                    .build(),
157                            )
158                            .build(),
159                    )
160                    .build()
161            }
162            WizardState::Done(name, color) => {
163                let d = dispatch.clone();
164                View::vstack()
165                    .spacing(1)
166                    .child(View::styled_text("All done!").color(Color::Green).bold().build())
167                    .child(View::text(format!("Name:  {}", name)))
168                    .child(View::text(format!("Color: {}", color)))
169                    .child(
170                        View::button()
171                            .label("[ Start Over ]")
172                            .on_press(move || d(WizardAction::Reset))
173                            .build(),
174                    )
175                    .build()
176            }
177        };
178
179        View::vstack()
180            .spacing(1)
181            .child(View::styled_text("Reducer Wizard").bold().build())
182            .child(
183                View::hstack()
184                    .spacing(1)
185                    .child(View::styled_text(&progress).dim().build())
186                    .child(View::styled_text(&dots).color(Color::Cyan).build())
187                    .build(),
188            )
189            .child(View::styled_text("────────────────────────").dim().build())
190            .child(content)
191            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
192            .child(
193                View::modal()
194                    .visible(show_help.get())
195                    .title("Example 36: Reducer")
196                    .on_dismiss(with!(show_help => move || show_help.set(false)))
197                    .child(
198                        View::vstack()
199                            .child(View::styled_text("What you're seeing").bold().build())
200                            .child(View::text("• Multi-step wizard state machine"))
201                            .child(View::text("• All transitions in one reducer fn"))
202                            .child(View::text("• No scattered booleans"))
203                            .child(View::gap(1))
204                            .child(View::styled_text("Key concepts").bold().build())
205                            .child(View::text("• reducer!(cx, init, |state, action| ...)"))
206                            .child(View::text("• Returns (State<S>, Rc<dyn Fn(A)>)"))
207                            .child(View::text("• dispatch(action) to transition"))
208                            .child(View::text("• Pattern match (state, action) pairs"))
209                            .child(View::gap(1))
210                            .child(View::styled_text("Try this").bold().build())
211                            .child(View::text("• Walk through all 4 steps"))
212                            .child(View::text("• Go back and change answers"))
213                            .child(View::text("• Watch the progress dots"))
214                            .child(View::gap(1))
215                            .child(View::styled_text("Next up").bold().build())
216                            .child(View::text("-> 37_error_boundary: crash protection"))
217                            .child(View::gap(1))
218                            .child(View::styled_text("Press Escape to close").dim().build())
219                            .build(),
220                    )
221                    .build(),
222            )
223            .build()
224    }
examples/23_modal.rs (line 262)
21    fn render(&self, cx: Scope) -> View {
22        let show_help = state!(cx, || false);
23
24        // F1 toggles help
25        cx.use_command(
26            KeyBinding::key(KeyCode::F(1)),
27            with!(show_help => move || show_help.update(|v| *v = !*v)),
28        );
29
30        // Modal visibility states
31        let show_confirm = state!(cx, || false);
32        let show_alert = state!(cx, || false);
33        let show_custom = state!(cx, || false);
34
35        // App state that modals can modify
36        let deleted_count = state!(cx, || 0);
37        let custom_input = state!(cx, String::new);
38        let last_action = state!(cx, || "No action yet".to_string());
39
40        // Handlers
41        let open_confirm = with!(show_confirm => move || {
42            show_confirm.set(true);
43        });
44
45        let open_alert = with!(show_alert => move || {
46            show_alert.set(true);
47        });
48
49        let open_custom = with!(show_custom => move || {
50            show_custom.set(true);
51        });
52
53        let on_confirm_yes = with!(show_confirm, deleted_count, last_action => move || {
54            deleted_count.set(deleted_count.get() + 1);
55            last_action.set(format!("Deleted item #{}", deleted_count.get()));
56            show_confirm.set(false);
57        });
58
59        let on_confirm_no = with!(show_confirm, last_action => move || {
60            last_action.set("Cancelled delete".to_string());
61            show_confirm.set(false);
62        });
63
64        let on_alert_dismiss = with!(show_alert, last_action => move || {
65            last_action.set("Dismissed alert".to_string());
66            show_alert.set(false);
67        });
68
69        let on_custom_save = with!(show_custom, custom_input, last_action => move || {
70            let value = custom_input.get();
71            if !value.is_empty() {
72                last_action.set(format!("Saved: {}", value));
73                custom_input.set(String::new());
74            }
75            show_custom.set(false);
76        });
77
78        let on_custom_dismiss = with!(show_custom => move || {
79            show_custom.set(false);
80        });
81
82        View::vstack()
83            .spacing(1)
84            .child(
85                // Header
86                View::boxed()
87                    .border(true)
88                    .padding(1)
89                    .child(
90                        View::vstack()
91                            .child(View::styled_text("Modal Dialogs Demo").bold().build())
92                            .child(
93                                View::styled_text("Click buttons to open different modal types")
94                                    .dim()
95                                    .build(),
96                            )
97                            .build(),
98                    )
99                    .build(),
100            )
101            .child(
102                // Main content
103                View::boxed()
104                    .flex(1)
105                    .border(true)
106                    .padding(1)
107                    .child(
108                        View::vstack()
109                            .spacing(1)
110                            .child(View::text("Modal Types:"))
111                            .child(
112                                View::hstack()
113                                    .spacing(2)
114                                    .child(
115                                        View::button()
116                                            .label("Confirm Dialog")
117                                            .on_press(open_confirm)
118                                            .build(),
119                                    )
120                                    .child(
121                                        View::button()
122                                            .label("Alert Dialog")
123                                            .on_press(open_alert)
124                                            .build(),
125                                    )
126                                    .child(
127                                        View::button()
128                                            .label("Custom Modal")
129                                            .on_press(open_custom)
130                                            .build(),
131                                    )
132                                    .build(),
133                            )
134                            .child(View::spacer())
135                            .child(
136                                View::styled_text(format!(
137                                    "Deleted items: {}",
138                                    deleted_count.get()
139                                ))
140                                .color(Color::Yellow)
141                                .build(),
142                            )
143                            .child(
144                                View::styled_text(format!("Last action: {}", last_action.get()))
145                                    .dim()
146                                    .build(),
147                            )
148                            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
149                            .build(),
150                    )
151                    .build(),
152            )
153            // Help modal
154            .child(
155                View::modal()
156                    .visible(show_help.get())
157                    .title("Example 23: Modal")
158                    .on_dismiss(with!(show_help => move || show_help.set(false)))
159                    .child(
160                        View::vstack()
161                            .child(View::styled_text("What you're seeing").bold().build())
162                            .child(View::text("• Confirm, alert, and custom modals"))
163                            .child(View::text("• Modal focus containment"))
164                            .child(View::text("• Escape to dismiss"))
165                            .child(View::gap(1))
166                            .child(View::styled_text("Key concepts").bold().build())
167                            .child(View::text("• View::modal() creates overlay"))
168                            .child(View::text("• .visible() controls show/hide"))
169                            .child(View::text("• .on_dismiss() handles Escape"))
170                            .child(View::text("• Focus trapped in open modal"))
171                            .child(View::gap(1))
172                            .child(View::styled_text("Try this").bold().build())
173                            .child(View::text("• Open confirm, click Yes/No"))
174                            .child(View::text("• Custom modal has text input"))
175                            .child(View::text("• Press Escape to close modals"))
176                            .child(View::gap(1))
177                            .child(View::styled_text("Next up").bold().build())
178                            .child(View::text("→ 24_async_data: async loading"))
179                            .child(View::gap(1))
180                            .child(View::styled_text("Press Escape to close").dim().build())
181                            .build(),
182                    )
183                    .build(),
184            )
185            // Confirm dialog modal
186            .child(
187                View::modal()
188                    .visible(show_confirm.get())
189                    .title("Confirm Delete")
190                    .on_dismiss(on_confirm_no.clone())
191                    .width(40)
192                    .height(30)
193                    .child(
194                        View::vstack()
195                            .spacing(1)
196                            .child(View::text("Are you sure you want to delete this item?"))
197                            .child(View::text("This action cannot be undone."))
198                            .child(View::spacer())
199                            .child(
200                                View::hstack()
201                                    .spacing(2)
202                                    .child(
203                                        View::button()
204                                            .label("Yes, Delete")
205                                            .on_press(on_confirm_yes)
206                                            .build(),
207                                    )
208                                    .child(
209                                        View::button()
210                                            .label("Cancel")
211                                            .on_press(on_confirm_no)
212                                            .build(),
213                                    )
214                                    .build(),
215                            )
216                            .build(),
217                    )
218                    .build(),
219            )
220            // Alert dialog modal
221            .child(
222                View::modal()
223                    .visible(show_alert.get())
224                    .title("Alert")
225                    .on_dismiss(on_alert_dismiss.clone())
226                    .width(50)
227                    .height(25)
228                    .child(
229                        View::vstack()
230                            .spacing(1)
231                            .child(
232                                View::styled_text("Operation completed successfully!")
233                                    .color(Color::Green)
234                                    .build(),
235                            )
236                            .child(View::text("Your changes have been saved."))
237                            .child(View::spacer())
238                            .child(
239                                View::button()
240                                    .label("OK")
241                                    .on_press(on_alert_dismiss)
242                                    .build(),
243                            )
244                            .build(),
245                    )
246                    .build(),
247            )
248            // Custom modal with input
249            .child(
250                View::modal()
251                    .visible(show_custom.get())
252                    .title("Enter Details")
253                    .on_dismiss(on_custom_dismiss.clone())
254                    .width(50)
255                    .height(40)
256                    .child(
257                        View::vstack()
258                            .spacing(1)
259                            .child(View::text("Enter a value:"))
260                            .child(
261                                View::text_input()
262                                    .value(custom_input.get())
263                                    .placeholder("Type something...")
264                                    .on_change(with!(custom_input => move |v: String| {
265                                        custom_input.set(v);
266                                    }))
267                                    .build(),
268                            )
269                            .child(View::spacer())
270                            .child(
271                                View::hstack()
272                                    .spacing(2)
273                                    .child(
274                                        View::button()
275                                            .label("Save")
276                                            .on_press(on_custom_save)
277                                            .build(),
278                                    )
279                                    .child(
280                                        View::button()
281                                            .label("Cancel")
282                                            .on_press(on_custom_dismiss)
283                                            .build(),
284                                    )
285                                    .build(),
286                            )
287                            .build(),
288                    )
289                    .build(),
290            )
291            .build()
292    }
Source

pub fn placeholder(self, placeholder: impl Into<String>) -> Self

Examples found in repository?
examples/05_todo_list.rs (line 83)
20    fn render(&self, cx: Scope) -> View {
21        let items = state!(cx, || {
22            vec![
23                "Learn Telex".to_string(),
24                "Build something cool".to_string(),
25            ]
26        });
27        let input_value = state!(cx, String::new);
28        let selected = state!(cx, || 0usize);
29        let show_help = state!(cx, || false);
30
31        // F1 toggles help
32        cx.use_command(
33            KeyBinding::key(KeyCode::F(1)),
34            with!(show_help => move || show_help.update(|v| *v = !*v)),
35        );
36
37        // Add new item on submit
38        let on_submit = with!(items, input_value => move || {
39            let text = input_value.get();
40            if !text.is_empty() {
41                items.update(|v| v.push(text));
42                input_value.set(String::new());
43            }
44        });
45
46        // Handle input changes
47        let on_change = with!(input_value => move |text: String| {
48            input_value.set(text);
49        });
50
51        // Delete selected item
52        let on_delete = with!(items, selected => move || {
53            let idx = selected.get();
54            items.update(|v| {
55                if idx < v.len() {
56                    v.remove(idx);
57                    // Adjust selection if needed
58                    if idx > 0 && idx >= v.len() {
59                        selected.set(idx - 1);
60                    }
61                }
62            });
63        });
64
65        // Track selection
66        let on_select = with!(selected => move |idx: usize| {
67            selected.set(idx);
68        });
69
70        let item_count = items.get().len();
71
72        View::vstack()
73            .child(
74                View::styled_text("Todo List")
75                    .color(Color::Cyan)
76                    .bold()
77                    .build(),
78            )
79            .child(View::gap(1))
80            .child(
81                View::text_input()
82                    .value(input_value.get())
83                    .placeholder("Type something to add...")
84                    .on_change(on_change)
85                    .on_submit(on_submit)
86                    .build(),
87            )
88            .child(View::gap(1))
89            .child(if item_count > 0 {
90                View::list()
91                    .items(items.get())
92                    .selected(selected.get())
93                    .on_select(on_select)
94                    .build()
95            } else {
96                View::styled_text("No items yet").dim().build()
97            })
98            .child(View::gap(1))
99            .child(
100                View::hstack()
101                    .child(View::button().label("Delete").on_press(on_delete).build())
102                    .build(),
103            )
104            .child(View::gap(1))
105            .child(
106                View::styled_text("Tab navigate • Enter add/select • F1 help • Ctrl+Q quit")
107                    .dim()
108                    .build(),
109            )
110            .child(
111                View::modal()
112                    .visible(show_help.get())
113                    .title("Example 05: Todo List")
114                    .on_dismiss(with!(show_help => move || show_help.set(false)))
115                    .child(
116                        View::vstack()
117                            .child(View::styled_text("What you're seeing").bold().build())
118                            .child(View::text("• View::text_input() for text entry"))
119                            .child(View::text("• View::list() for displaying items"))
120                            .child(View::text("• on_submit callback for Enter key"))
121                            .child(View::gap(1))
122                            .child(View::styled_text("Key concepts").bold().build())
123                            .child(View::text("• Controlled input: value + on_change"))
124                            .child(View::text("• Vec<String> state for list items"))
125                            .child(View::text("• Conditional rendering (empty state)"))
126                            .child(View::gap(1))
127                            .child(View::styled_text("Try this").bold().build())
128                            .child(View::text("• Type something and press Enter to add"))
129                            .child(View::text("• Use ↑/↓ to select, then Delete button"))
130                            .child(View::text("• Delete all items to see empty state"))
131                            .child(View::gap(1))
132                            .child(View::styled_text("Next up").bold().build())
133                            .child(View::text("→ 06_log_viewer: streaming text content"))
134                            .child(View::gap(1))
135                            .child(View::styled_text("Press Escape to close").dim().build())
136                            .build(),
137                    )
138                    .build(),
139            )
140            .build()
141    }
More examples
Hide additional examples
examples/32_effects.rs (line 93)
23    fn render(&self, cx: Scope) -> View {
24        let show_help = state!(cx, || false);
25
26        // F1 toggles help
27        cx.use_command(
28            KeyBinding::key(KeyCode::F(1)),
29            with!(show_help => move || show_help.update(|v| *v = !*v)),
30        );
31
32        let count = state!(cx, || 0);
33        let name = state!(cx, String::new);
34        let last_effect = state!(cx, || String::from("(none yet)"));
35        let init_done = state!(cx, || false);
36
37        // Effect that runs only once - initialization
38        // Using effect_once! macro (order-independent)
39        effect_once!(cx, with!(init_done, last_effect => move || {
40            init_done.set(true);
41            last_effect.set("effect_once!: initialized!".to_string());
42            || {}
43        }));
44
45        // Effect that runs when count changes
46        // Using effect! macro (order-independent)
47        effect!(cx, count.get(), with!(last_effect => move |&val| {
48            last_effect.set(format!("effect!: count → {}", val));
49            || {}
50        }));
51
52        // Effect that runs when name changes
53        effect!(cx, name.get(), with!(last_effect => move |n: &String| {
54            if !n.is_empty() {
55                last_effect.set(format!("effect!: name → \"{}\"", n));
56            }
57            || {}
58        }));
59
60        View::vstack()
61            .spacing(1)
62            .child(View::styled_text("effect! Demo").bold().build())
63            .child(View::text(""))
64            .child(View::text(format!("Counter: {}", count.get())))
65            .child(
66                View::hstack()
67                    .spacing(1)
68                    .child(
69                        View::button()
70                            .label("[ - ]")
71                            .on_press(with!(count => move || count.update(|n| *n -= 1)))
72                            .build(),
73                    )
74                    .child(
75                        View::button()
76                            .label("[ + ]")
77                            .on_press(with!(count => move || count.update(|n| *n += 1)))
78                            .build(),
79                    )
80                    .build(),
81            )
82            .child(View::text(""))
83            .child({
84                let n = name.get();
85                View::text(format!(
86                    "Name: {}",
87                    if n.is_empty() { "(empty)" } else { &n }
88                ))
89            })
90            .child(
91                View::text_input()
92                    .value(name.get())
93                    .placeholder("Type your name...")
94                    .on_change(with!(name => move |s| name.set(s)))
95                    .build(),
96            )
97            .child(View::text(""))
98            .child(View::styled_text("─── Effect Status ───").dim().build())
99            .child(View::text(""))
100            .child(View::text(format!(
101                "Initialized: {}",
102                if init_done.get() { "✓ yes" } else { "no" }
103            )))
104            .child(View::text(format!("Last effect: {}", last_effect.get())))
105            .child(View::text(""))
106            .child(View::styled_text("─── How it works ───").dim().build())
107            .child(View::text(""))
108            .child(View::text("effect_once!  → Ran once at startup"))
109            .child(View::text("effect!       → Runs when deps change"))
110            .child(View::text(""))
111            .child(
112                View::styled_text("Press +/- or type to see effects trigger")
113                    .dim()
114                    .build(),
115            )
116            .child(View::text(""))
117            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
118            .child(
119                View::modal()
120                    .visible(show_help.get())
121                    .title("Example 32: Effects")
122                    .on_dismiss(with!(show_help => move || show_help.set(false)))
123                    .child(
124                        View::vstack()
125                            .child(View::styled_text("What you're seeing").bold().build())
126                            .child(View::text("• effect_once! runs at startup"))
127                            .child(View::text("• effect! runs when deps change"))
128                            .child(View::text("• Last effect shows what triggered"))
129                            .child(View::gap(1))
130                            .child(View::styled_text("Key concepts").bold().build())
131                            .child(View::text("• effect_once!(cx, || { cleanup })"))
132                            .child(View::text("• effect!(cx, deps, |&d| { cleanup })"))
133                            .child(View::text("• Return || {} for cleanup"))
134                            .child(View::text("• Effects run AFTER render"))
135                            .child(View::text("• Safe in conditionals!"))
136                            .child(View::gap(1))
137                            .child(View::styled_text("Try this").bold().build())
138                            .child(View::text("• Click +/- to change counter"))
139                            .child(View::text("• Type in the name field"))
140                            .child(View::text("• Watch 'Last effect' update"))
141                            .child(View::gap(1))
142                            .child(View::styled_text("Press Escape to close").dim().build())
143                            .build(),
144                    )
145                    .build(),
146            )
147            .build()
148    }
examples/36_reducer.rs (line 106)
38    fn render(&self, cx: Scope) -> View {
39        let show_help = state!(cx, || false);
40
41        cx.use_command(
42            KeyBinding::key(KeyCode::F(1)),
43            with!(show_help => move || show_help.update(|v| *v = !*v)),
44        );
45
46        let (wizard, dispatch) = reducer!(cx, WizardState::Welcome, |state: WizardState, action: WizardAction| {
47            match (state, action) {
48                (_, WizardAction::Reset) => WizardState::Welcome,
49                (WizardState::Welcome, WizardAction::Next) => WizardState::Name(String::new()),
50                (WizardState::Name(_), WizardAction::SetName(n)) => WizardState::Name(n),
51                (WizardState::Name(name), WizardAction::Next) => {
52                    let name = if name.is_empty() { "Anonymous".to_string() } else { name };
53                    WizardState::Color(name, String::new())
54                }
55                (WizardState::Name(_), WizardAction::Back) => WizardState::Welcome,
56                (WizardState::Color(name, _), WizardAction::SetColor(c)) => WizardState::Color(name, c),
57                (WizardState::Color(name, color), WizardAction::Next) => {
58                    let color = if color.is_empty() { "Blue".to_string() } else { color };
59                    WizardState::Done(name, color)
60                }
61                (WizardState::Color(_, _), WizardAction::Back) => WizardState::Name(String::new()),
62                (WizardState::Done(_, _), WizardAction::Back) => WizardState::Welcome,
63                (s, _) => s,
64            }
65        });
66
67        let step = match &wizard.get() {
68            WizardState::Welcome => 1,
69            WizardState::Name(_) => 2,
70            WizardState::Color(_, _) => 3,
71            WizardState::Done(_, _) => 4,
72        };
73
74        let progress = format!("Step {} of 4", step);
75        let dots: String = (1..=4)
76            .map(|i| if i <= step { "●" } else { "○" })
77            .collect::<Vec<_>>()
78            .join(" ");
79
80        let content = match &wizard.get() {
81            WizardState::Welcome => {
82                let d = dispatch.clone();
83                View::vstack()
84                    .spacing(1)
85                    .child(View::styled_text("Welcome to the Wizard!").color(Color::Cyan).bold().build())
86                    .child(View::text("This example shows centralized state"))
87                    .child(View::text("management with reducer!"))
88                    .child(
89                        View::button()
90                            .label("[ Start -> ]")
91                            .on_press(move || d(WizardAction::Next))
92                            .build(),
93                    )
94                    .build()
95            }
96            WizardState::Name(name) => {
97                let d1 = dispatch.clone();
98                let d2 = dispatch.clone();
99                let d3 = dispatch.clone();
100                View::vstack()
101                    .spacing(1)
102                    .child(View::styled_text("What's your name?").color(Color::Cyan).bold().build())
103                    .child(
104                        View::text_input()
105                            .value(name.clone())
106                            .placeholder("Enter your name...")
107                            .on_change(move |s: String| d1(WizardAction::SetName(s)))
108                            .build(),
109                    )
110                    .child(
111                        View::hstack()
112                            .spacing(1)
113                            .child(
114                                View::button()
115                                    .label("[ <- Back ]")
116                                    .on_press(move || d2(WizardAction::Back))
117                                    .build(),
118                            )
119                            .child(
120                                View::button()
121                                    .label("[ Next -> ]")
122                                    .on_press(move || d3(WizardAction::Next))
123                                    .build(),
124                            )
125                            .build(),
126                    )
127                    .build()
128            }
129            WizardState::Color(name, color) => {
130                let d1 = dispatch.clone();
131                let d2 = dispatch.clone();
132                let d3 = dispatch.clone();
133                View::vstack()
134                    .spacing(1)
135                    .child(View::styled_text(format!("Hi, {}! Pick a color:", name)).color(Color::Cyan).bold().build())
136                    .child(
137                        View::text_input()
138                            .value(color.clone())
139                            .placeholder("Enter a color (e.g. Blue)...")
140                            .on_change(move |s: String| d1(WizardAction::SetColor(s)))
141                            .build(),
142                    )
143                    .child(
144                        View::hstack()
145                            .spacing(1)
146                            .child(
147                                View::button()
148                                    .label("[ <- Back ]")
149                                    .on_press(move || d2(WizardAction::Back))
150                                    .build(),
151                            )
152                            .child(
153                                View::button()
154                                    .label("[ Finish -> ]")
155                                    .on_press(move || d3(WizardAction::Next))
156                                    .build(),
157                            )
158                            .build(),
159                    )
160                    .build()
161            }
162            WizardState::Done(name, color) => {
163                let d = dispatch.clone();
164                View::vstack()
165                    .spacing(1)
166                    .child(View::styled_text("All done!").color(Color::Green).bold().build())
167                    .child(View::text(format!("Name:  {}", name)))
168                    .child(View::text(format!("Color: {}", color)))
169                    .child(
170                        View::button()
171                            .label("[ Start Over ]")
172                            .on_press(move || d(WizardAction::Reset))
173                            .build(),
174                    )
175                    .build()
176            }
177        };
178
179        View::vstack()
180            .spacing(1)
181            .child(View::styled_text("Reducer Wizard").bold().build())
182            .child(
183                View::hstack()
184                    .spacing(1)
185                    .child(View::styled_text(&progress).dim().build())
186                    .child(View::styled_text(&dots).color(Color::Cyan).build())
187                    .build(),
188            )
189            .child(View::styled_text("────────────────────────").dim().build())
190            .child(content)
191            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
192            .child(
193                View::modal()
194                    .visible(show_help.get())
195                    .title("Example 36: Reducer")
196                    .on_dismiss(with!(show_help => move || show_help.set(false)))
197                    .child(
198                        View::vstack()
199                            .child(View::styled_text("What you're seeing").bold().build())
200                            .child(View::text("• Multi-step wizard state machine"))
201                            .child(View::text("• All transitions in one reducer fn"))
202                            .child(View::text("• No scattered booleans"))
203                            .child(View::gap(1))
204                            .child(View::styled_text("Key concepts").bold().build())
205                            .child(View::text("• reducer!(cx, init, |state, action| ...)"))
206                            .child(View::text("• Returns (State<S>, Rc<dyn Fn(A)>)"))
207                            .child(View::text("• dispatch(action) to transition"))
208                            .child(View::text("• Pattern match (state, action) pairs"))
209                            .child(View::gap(1))
210                            .child(View::styled_text("Try this").bold().build())
211                            .child(View::text("• Walk through all 4 steps"))
212                            .child(View::text("• Go back and change answers"))
213                            .child(View::text("• Watch the progress dots"))
214                            .child(View::gap(1))
215                            .child(View::styled_text("Next up").bold().build())
216                            .child(View::text("-> 37_error_boundary: crash protection"))
217                            .child(View::gap(1))
218                            .child(View::styled_text("Press Escape to close").dim().build())
219                            .build(),
220                    )
221                    .build(),
222            )
223            .build()
224    }
examples/23_modal.rs (line 263)
21    fn render(&self, cx: Scope) -> View {
22        let show_help = state!(cx, || false);
23
24        // F1 toggles help
25        cx.use_command(
26            KeyBinding::key(KeyCode::F(1)),
27            with!(show_help => move || show_help.update(|v| *v = !*v)),
28        );
29
30        // Modal visibility states
31        let show_confirm = state!(cx, || false);
32        let show_alert = state!(cx, || false);
33        let show_custom = state!(cx, || false);
34
35        // App state that modals can modify
36        let deleted_count = state!(cx, || 0);
37        let custom_input = state!(cx, String::new);
38        let last_action = state!(cx, || "No action yet".to_string());
39
40        // Handlers
41        let open_confirm = with!(show_confirm => move || {
42            show_confirm.set(true);
43        });
44
45        let open_alert = with!(show_alert => move || {
46            show_alert.set(true);
47        });
48
49        let open_custom = with!(show_custom => move || {
50            show_custom.set(true);
51        });
52
53        let on_confirm_yes = with!(show_confirm, deleted_count, last_action => move || {
54            deleted_count.set(deleted_count.get() + 1);
55            last_action.set(format!("Deleted item #{}", deleted_count.get()));
56            show_confirm.set(false);
57        });
58
59        let on_confirm_no = with!(show_confirm, last_action => move || {
60            last_action.set("Cancelled delete".to_string());
61            show_confirm.set(false);
62        });
63
64        let on_alert_dismiss = with!(show_alert, last_action => move || {
65            last_action.set("Dismissed alert".to_string());
66            show_alert.set(false);
67        });
68
69        let on_custom_save = with!(show_custom, custom_input, last_action => move || {
70            let value = custom_input.get();
71            if !value.is_empty() {
72                last_action.set(format!("Saved: {}", value));
73                custom_input.set(String::new());
74            }
75            show_custom.set(false);
76        });
77
78        let on_custom_dismiss = with!(show_custom => move || {
79            show_custom.set(false);
80        });
81
82        View::vstack()
83            .spacing(1)
84            .child(
85                // Header
86                View::boxed()
87                    .border(true)
88                    .padding(1)
89                    .child(
90                        View::vstack()
91                            .child(View::styled_text("Modal Dialogs Demo").bold().build())
92                            .child(
93                                View::styled_text("Click buttons to open different modal types")
94                                    .dim()
95                                    .build(),
96                            )
97                            .build(),
98                    )
99                    .build(),
100            )
101            .child(
102                // Main content
103                View::boxed()
104                    .flex(1)
105                    .border(true)
106                    .padding(1)
107                    .child(
108                        View::vstack()
109                            .spacing(1)
110                            .child(View::text("Modal Types:"))
111                            .child(
112                                View::hstack()
113                                    .spacing(2)
114                                    .child(
115                                        View::button()
116                                            .label("Confirm Dialog")
117                                            .on_press(open_confirm)
118                                            .build(),
119                                    )
120                                    .child(
121                                        View::button()
122                                            .label("Alert Dialog")
123                                            .on_press(open_alert)
124                                            .build(),
125                                    )
126                                    .child(
127                                        View::button()
128                                            .label("Custom Modal")
129                                            .on_press(open_custom)
130                                            .build(),
131                                    )
132                                    .build(),
133                            )
134                            .child(View::spacer())
135                            .child(
136                                View::styled_text(format!(
137                                    "Deleted items: {}",
138                                    deleted_count.get()
139                                ))
140                                .color(Color::Yellow)
141                                .build(),
142                            )
143                            .child(
144                                View::styled_text(format!("Last action: {}", last_action.get()))
145                                    .dim()
146                                    .build(),
147                            )
148                            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
149                            .build(),
150                    )
151                    .build(),
152            )
153            // Help modal
154            .child(
155                View::modal()
156                    .visible(show_help.get())
157                    .title("Example 23: Modal")
158                    .on_dismiss(with!(show_help => move || show_help.set(false)))
159                    .child(
160                        View::vstack()
161                            .child(View::styled_text("What you're seeing").bold().build())
162                            .child(View::text("• Confirm, alert, and custom modals"))
163                            .child(View::text("• Modal focus containment"))
164                            .child(View::text("• Escape to dismiss"))
165                            .child(View::gap(1))
166                            .child(View::styled_text("Key concepts").bold().build())
167                            .child(View::text("• View::modal() creates overlay"))
168                            .child(View::text("• .visible() controls show/hide"))
169                            .child(View::text("• .on_dismiss() handles Escape"))
170                            .child(View::text("• Focus trapped in open modal"))
171                            .child(View::gap(1))
172                            .child(View::styled_text("Try this").bold().build())
173                            .child(View::text("• Open confirm, click Yes/No"))
174                            .child(View::text("• Custom modal has text input"))
175                            .child(View::text("• Press Escape to close modals"))
176                            .child(View::gap(1))
177                            .child(View::styled_text("Next up").bold().build())
178                            .child(View::text("→ 24_async_data: async loading"))
179                            .child(View::gap(1))
180                            .child(View::styled_text("Press Escape to close").dim().build())
181                            .build(),
182                    )
183                    .build(),
184            )
185            // Confirm dialog modal
186            .child(
187                View::modal()
188                    .visible(show_confirm.get())
189                    .title("Confirm Delete")
190                    .on_dismiss(on_confirm_no.clone())
191                    .width(40)
192                    .height(30)
193                    .child(
194                        View::vstack()
195                            .spacing(1)
196                            .child(View::text("Are you sure you want to delete this item?"))
197                            .child(View::text("This action cannot be undone."))
198                            .child(View::spacer())
199                            .child(
200                                View::hstack()
201                                    .spacing(2)
202                                    .child(
203                                        View::button()
204                                            .label("Yes, Delete")
205                                            .on_press(on_confirm_yes)
206                                            .build(),
207                                    )
208                                    .child(
209                                        View::button()
210                                            .label("Cancel")
211                                            .on_press(on_confirm_no)
212                                            .build(),
213                                    )
214                                    .build(),
215                            )
216                            .build(),
217                    )
218                    .build(),
219            )
220            // Alert dialog modal
221            .child(
222                View::modal()
223                    .visible(show_alert.get())
224                    .title("Alert")
225                    .on_dismiss(on_alert_dismiss.clone())
226                    .width(50)
227                    .height(25)
228                    .child(
229                        View::vstack()
230                            .spacing(1)
231                            .child(
232                                View::styled_text("Operation completed successfully!")
233                                    .color(Color::Green)
234                                    .build(),
235                            )
236                            .child(View::text("Your changes have been saved."))
237                            .child(View::spacer())
238                            .child(
239                                View::button()
240                                    .label("OK")
241                                    .on_press(on_alert_dismiss)
242                                    .build(),
243                            )
244                            .build(),
245                    )
246                    .build(),
247            )
248            // Custom modal with input
249            .child(
250                View::modal()
251                    .visible(show_custom.get())
252                    .title("Enter Details")
253                    .on_dismiss(on_custom_dismiss.clone())
254                    .width(50)
255                    .height(40)
256                    .child(
257                        View::vstack()
258                            .spacing(1)
259                            .child(View::text("Enter a value:"))
260                            .child(
261                                View::text_input()
262                                    .value(custom_input.get())
263                                    .placeholder("Type something...")
264                                    .on_change(with!(custom_input => move |v: String| {
265                                        custom_input.set(v);
266                                    }))
267                                    .build(),
268                            )
269                            .child(View::spacer())
270                            .child(
271                                View::hstack()
272                                    .spacing(2)
273                                    .child(
274                                        View::button()
275                                            .label("Save")
276                                            .on_press(on_custom_save)
277                                            .build(),
278                                    )
279                                    .child(
280                                        View::button()
281                                            .label("Cancel")
282                                            .on_press(on_custom_dismiss)
283                                            .build(),
284                                    )
285                                    .build(),
286                            )
287                            .build(),
288                    )
289                    .build(),
290            )
291            .build()
292    }
Source

pub fn on_change(self, callback: impl Fn(String) + 'static) -> Self

Examples found in repository?
examples/05_todo_list.rs (line 84)
20    fn render(&self, cx: Scope) -> View {
21        let items = state!(cx, || {
22            vec![
23                "Learn Telex".to_string(),
24                "Build something cool".to_string(),
25            ]
26        });
27        let input_value = state!(cx, String::new);
28        let selected = state!(cx, || 0usize);
29        let show_help = state!(cx, || false);
30
31        // F1 toggles help
32        cx.use_command(
33            KeyBinding::key(KeyCode::F(1)),
34            with!(show_help => move || show_help.update(|v| *v = !*v)),
35        );
36
37        // Add new item on submit
38        let on_submit = with!(items, input_value => move || {
39            let text = input_value.get();
40            if !text.is_empty() {
41                items.update(|v| v.push(text));
42                input_value.set(String::new());
43            }
44        });
45
46        // Handle input changes
47        let on_change = with!(input_value => move |text: String| {
48            input_value.set(text);
49        });
50
51        // Delete selected item
52        let on_delete = with!(items, selected => move || {
53            let idx = selected.get();
54            items.update(|v| {
55                if idx < v.len() {
56                    v.remove(idx);
57                    // Adjust selection if needed
58                    if idx > 0 && idx >= v.len() {
59                        selected.set(idx - 1);
60                    }
61                }
62            });
63        });
64
65        // Track selection
66        let on_select = with!(selected => move |idx: usize| {
67            selected.set(idx);
68        });
69
70        let item_count = items.get().len();
71
72        View::vstack()
73            .child(
74                View::styled_text("Todo List")
75                    .color(Color::Cyan)
76                    .bold()
77                    .build(),
78            )
79            .child(View::gap(1))
80            .child(
81                View::text_input()
82                    .value(input_value.get())
83                    .placeholder("Type something to add...")
84                    .on_change(on_change)
85                    .on_submit(on_submit)
86                    .build(),
87            )
88            .child(View::gap(1))
89            .child(if item_count > 0 {
90                View::list()
91                    .items(items.get())
92                    .selected(selected.get())
93                    .on_select(on_select)
94                    .build()
95            } else {
96                View::styled_text("No items yet").dim().build()
97            })
98            .child(View::gap(1))
99            .child(
100                View::hstack()
101                    .child(View::button().label("Delete").on_press(on_delete).build())
102                    .build(),
103            )
104            .child(View::gap(1))
105            .child(
106                View::styled_text("Tab navigate • Enter add/select • F1 help • Ctrl+Q quit")
107                    .dim()
108                    .build(),
109            )
110            .child(
111                View::modal()
112                    .visible(show_help.get())
113                    .title("Example 05: Todo List")
114                    .on_dismiss(with!(show_help => move || show_help.set(false)))
115                    .child(
116                        View::vstack()
117                            .child(View::styled_text("What you're seeing").bold().build())
118                            .child(View::text("• View::text_input() for text entry"))
119                            .child(View::text("• View::list() for displaying items"))
120                            .child(View::text("• on_submit callback for Enter key"))
121                            .child(View::gap(1))
122                            .child(View::styled_text("Key concepts").bold().build())
123                            .child(View::text("• Controlled input: value + on_change"))
124                            .child(View::text("• Vec<String> state for list items"))
125                            .child(View::text("• Conditional rendering (empty state)"))
126                            .child(View::gap(1))
127                            .child(View::styled_text("Try this").bold().build())
128                            .child(View::text("• Type something and press Enter to add"))
129                            .child(View::text("• Use ↑/↓ to select, then Delete button"))
130                            .child(View::text("• Delete all items to see empty state"))
131                            .child(View::gap(1))
132                            .child(View::styled_text("Next up").bold().build())
133                            .child(View::text("→ 06_log_viewer: streaming text content"))
134                            .child(View::gap(1))
135                            .child(View::styled_text("Press Escape to close").dim().build())
136                            .build(),
137                    )
138                    .build(),
139            )
140            .build()
141    }
More examples
Hide additional examples
examples/32_effects.rs (line 94)
23    fn render(&self, cx: Scope) -> View {
24        let show_help = state!(cx, || false);
25
26        // F1 toggles help
27        cx.use_command(
28            KeyBinding::key(KeyCode::F(1)),
29            with!(show_help => move || show_help.update(|v| *v = !*v)),
30        );
31
32        let count = state!(cx, || 0);
33        let name = state!(cx, String::new);
34        let last_effect = state!(cx, || String::from("(none yet)"));
35        let init_done = state!(cx, || false);
36
37        // Effect that runs only once - initialization
38        // Using effect_once! macro (order-independent)
39        effect_once!(cx, with!(init_done, last_effect => move || {
40            init_done.set(true);
41            last_effect.set("effect_once!: initialized!".to_string());
42            || {}
43        }));
44
45        // Effect that runs when count changes
46        // Using effect! macro (order-independent)
47        effect!(cx, count.get(), with!(last_effect => move |&val| {
48            last_effect.set(format!("effect!: count → {}", val));
49            || {}
50        }));
51
52        // Effect that runs when name changes
53        effect!(cx, name.get(), with!(last_effect => move |n: &String| {
54            if !n.is_empty() {
55                last_effect.set(format!("effect!: name → \"{}\"", n));
56            }
57            || {}
58        }));
59
60        View::vstack()
61            .spacing(1)
62            .child(View::styled_text("effect! Demo").bold().build())
63            .child(View::text(""))
64            .child(View::text(format!("Counter: {}", count.get())))
65            .child(
66                View::hstack()
67                    .spacing(1)
68                    .child(
69                        View::button()
70                            .label("[ - ]")
71                            .on_press(with!(count => move || count.update(|n| *n -= 1)))
72                            .build(),
73                    )
74                    .child(
75                        View::button()
76                            .label("[ + ]")
77                            .on_press(with!(count => move || count.update(|n| *n += 1)))
78                            .build(),
79                    )
80                    .build(),
81            )
82            .child(View::text(""))
83            .child({
84                let n = name.get();
85                View::text(format!(
86                    "Name: {}",
87                    if n.is_empty() { "(empty)" } else { &n }
88                ))
89            })
90            .child(
91                View::text_input()
92                    .value(name.get())
93                    .placeholder("Type your name...")
94                    .on_change(with!(name => move |s| name.set(s)))
95                    .build(),
96            )
97            .child(View::text(""))
98            .child(View::styled_text("─── Effect Status ───").dim().build())
99            .child(View::text(""))
100            .child(View::text(format!(
101                "Initialized: {}",
102                if init_done.get() { "✓ yes" } else { "no" }
103            )))
104            .child(View::text(format!("Last effect: {}", last_effect.get())))
105            .child(View::text(""))
106            .child(View::styled_text("─── How it works ───").dim().build())
107            .child(View::text(""))
108            .child(View::text("effect_once!  → Ran once at startup"))
109            .child(View::text("effect!       → Runs when deps change"))
110            .child(View::text(""))
111            .child(
112                View::styled_text("Press +/- or type to see effects trigger")
113                    .dim()
114                    .build(),
115            )
116            .child(View::text(""))
117            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
118            .child(
119                View::modal()
120                    .visible(show_help.get())
121                    .title("Example 32: Effects")
122                    .on_dismiss(with!(show_help => move || show_help.set(false)))
123                    .child(
124                        View::vstack()
125                            .child(View::styled_text("What you're seeing").bold().build())
126                            .child(View::text("• effect_once! runs at startup"))
127                            .child(View::text("• effect! runs when deps change"))
128                            .child(View::text("• Last effect shows what triggered"))
129                            .child(View::gap(1))
130                            .child(View::styled_text("Key concepts").bold().build())
131                            .child(View::text("• effect_once!(cx, || { cleanup })"))
132                            .child(View::text("• effect!(cx, deps, |&d| { cleanup })"))
133                            .child(View::text("• Return || {} for cleanup"))
134                            .child(View::text("• Effects run AFTER render"))
135                            .child(View::text("• Safe in conditionals!"))
136                            .child(View::gap(1))
137                            .child(View::styled_text("Try this").bold().build())
138                            .child(View::text("• Click +/- to change counter"))
139                            .child(View::text("• Type in the name field"))
140                            .child(View::text("• Watch 'Last effect' update"))
141                            .child(View::gap(1))
142                            .child(View::styled_text("Press Escape to close").dim().build())
143                            .build(),
144                    )
145                    .build(),
146            )
147            .build()
148    }
examples/36_reducer.rs (line 107)
38    fn render(&self, cx: Scope) -> View {
39        let show_help = state!(cx, || false);
40
41        cx.use_command(
42            KeyBinding::key(KeyCode::F(1)),
43            with!(show_help => move || show_help.update(|v| *v = !*v)),
44        );
45
46        let (wizard, dispatch) = reducer!(cx, WizardState::Welcome, |state: WizardState, action: WizardAction| {
47            match (state, action) {
48                (_, WizardAction::Reset) => WizardState::Welcome,
49                (WizardState::Welcome, WizardAction::Next) => WizardState::Name(String::new()),
50                (WizardState::Name(_), WizardAction::SetName(n)) => WizardState::Name(n),
51                (WizardState::Name(name), WizardAction::Next) => {
52                    let name = if name.is_empty() { "Anonymous".to_string() } else { name };
53                    WizardState::Color(name, String::new())
54                }
55                (WizardState::Name(_), WizardAction::Back) => WizardState::Welcome,
56                (WizardState::Color(name, _), WizardAction::SetColor(c)) => WizardState::Color(name, c),
57                (WizardState::Color(name, color), WizardAction::Next) => {
58                    let color = if color.is_empty() { "Blue".to_string() } else { color };
59                    WizardState::Done(name, color)
60                }
61                (WizardState::Color(_, _), WizardAction::Back) => WizardState::Name(String::new()),
62                (WizardState::Done(_, _), WizardAction::Back) => WizardState::Welcome,
63                (s, _) => s,
64            }
65        });
66
67        let step = match &wizard.get() {
68            WizardState::Welcome => 1,
69            WizardState::Name(_) => 2,
70            WizardState::Color(_, _) => 3,
71            WizardState::Done(_, _) => 4,
72        };
73
74        let progress = format!("Step {} of 4", step);
75        let dots: String = (1..=4)
76            .map(|i| if i <= step { "●" } else { "○" })
77            .collect::<Vec<_>>()
78            .join(" ");
79
80        let content = match &wizard.get() {
81            WizardState::Welcome => {
82                let d = dispatch.clone();
83                View::vstack()
84                    .spacing(1)
85                    .child(View::styled_text("Welcome to the Wizard!").color(Color::Cyan).bold().build())
86                    .child(View::text("This example shows centralized state"))
87                    .child(View::text("management with reducer!"))
88                    .child(
89                        View::button()
90                            .label("[ Start -> ]")
91                            .on_press(move || d(WizardAction::Next))
92                            .build(),
93                    )
94                    .build()
95            }
96            WizardState::Name(name) => {
97                let d1 = dispatch.clone();
98                let d2 = dispatch.clone();
99                let d3 = dispatch.clone();
100                View::vstack()
101                    .spacing(1)
102                    .child(View::styled_text("What's your name?").color(Color::Cyan).bold().build())
103                    .child(
104                        View::text_input()
105                            .value(name.clone())
106                            .placeholder("Enter your name...")
107                            .on_change(move |s: String| d1(WizardAction::SetName(s)))
108                            .build(),
109                    )
110                    .child(
111                        View::hstack()
112                            .spacing(1)
113                            .child(
114                                View::button()
115                                    .label("[ <- Back ]")
116                                    .on_press(move || d2(WizardAction::Back))
117                                    .build(),
118                            )
119                            .child(
120                                View::button()
121                                    .label("[ Next -> ]")
122                                    .on_press(move || d3(WizardAction::Next))
123                                    .build(),
124                            )
125                            .build(),
126                    )
127                    .build()
128            }
129            WizardState::Color(name, color) => {
130                let d1 = dispatch.clone();
131                let d2 = dispatch.clone();
132                let d3 = dispatch.clone();
133                View::vstack()
134                    .spacing(1)
135                    .child(View::styled_text(format!("Hi, {}! Pick a color:", name)).color(Color::Cyan).bold().build())
136                    .child(
137                        View::text_input()
138                            .value(color.clone())
139                            .placeholder("Enter a color (e.g. Blue)...")
140                            .on_change(move |s: String| d1(WizardAction::SetColor(s)))
141                            .build(),
142                    )
143                    .child(
144                        View::hstack()
145                            .spacing(1)
146                            .child(
147                                View::button()
148                                    .label("[ <- Back ]")
149                                    .on_press(move || d2(WizardAction::Back))
150                                    .build(),
151                            )
152                            .child(
153                                View::button()
154                                    .label("[ Finish -> ]")
155                                    .on_press(move || d3(WizardAction::Next))
156                                    .build(),
157                            )
158                            .build(),
159                    )
160                    .build()
161            }
162            WizardState::Done(name, color) => {
163                let d = dispatch.clone();
164                View::vstack()
165                    .spacing(1)
166                    .child(View::styled_text("All done!").color(Color::Green).bold().build())
167                    .child(View::text(format!("Name:  {}", name)))
168                    .child(View::text(format!("Color: {}", color)))
169                    .child(
170                        View::button()
171                            .label("[ Start Over ]")
172                            .on_press(move || d(WizardAction::Reset))
173                            .build(),
174                    )
175                    .build()
176            }
177        };
178
179        View::vstack()
180            .spacing(1)
181            .child(View::styled_text("Reducer Wizard").bold().build())
182            .child(
183                View::hstack()
184                    .spacing(1)
185                    .child(View::styled_text(&progress).dim().build())
186                    .child(View::styled_text(&dots).color(Color::Cyan).build())
187                    .build(),
188            )
189            .child(View::styled_text("────────────────────────").dim().build())
190            .child(content)
191            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
192            .child(
193                View::modal()
194                    .visible(show_help.get())
195                    .title("Example 36: Reducer")
196                    .on_dismiss(with!(show_help => move || show_help.set(false)))
197                    .child(
198                        View::vstack()
199                            .child(View::styled_text("What you're seeing").bold().build())
200                            .child(View::text("• Multi-step wizard state machine"))
201                            .child(View::text("• All transitions in one reducer fn"))
202                            .child(View::text("• No scattered booleans"))
203                            .child(View::gap(1))
204                            .child(View::styled_text("Key concepts").bold().build())
205                            .child(View::text("• reducer!(cx, init, |state, action| ...)"))
206                            .child(View::text("• Returns (State<S>, Rc<dyn Fn(A)>)"))
207                            .child(View::text("• dispatch(action) to transition"))
208                            .child(View::text("• Pattern match (state, action) pairs"))
209                            .child(View::gap(1))
210                            .child(View::styled_text("Try this").bold().build())
211                            .child(View::text("• Walk through all 4 steps"))
212                            .child(View::text("• Go back and change answers"))
213                            .child(View::text("• Watch the progress dots"))
214                            .child(View::gap(1))
215                            .child(View::styled_text("Next up").bold().build())
216                            .child(View::text("-> 37_error_boundary: crash protection"))
217                            .child(View::gap(1))
218                            .child(View::styled_text("Press Escape to close").dim().build())
219                            .build(),
220                    )
221                    .build(),
222            )
223            .build()
224    }
examples/23_modal.rs (lines 264-266)
21    fn render(&self, cx: Scope) -> View {
22        let show_help = state!(cx, || false);
23
24        // F1 toggles help
25        cx.use_command(
26            KeyBinding::key(KeyCode::F(1)),
27            with!(show_help => move || show_help.update(|v| *v = !*v)),
28        );
29
30        // Modal visibility states
31        let show_confirm = state!(cx, || false);
32        let show_alert = state!(cx, || false);
33        let show_custom = state!(cx, || false);
34
35        // App state that modals can modify
36        let deleted_count = state!(cx, || 0);
37        let custom_input = state!(cx, String::new);
38        let last_action = state!(cx, || "No action yet".to_string());
39
40        // Handlers
41        let open_confirm = with!(show_confirm => move || {
42            show_confirm.set(true);
43        });
44
45        let open_alert = with!(show_alert => move || {
46            show_alert.set(true);
47        });
48
49        let open_custom = with!(show_custom => move || {
50            show_custom.set(true);
51        });
52
53        let on_confirm_yes = with!(show_confirm, deleted_count, last_action => move || {
54            deleted_count.set(deleted_count.get() + 1);
55            last_action.set(format!("Deleted item #{}", deleted_count.get()));
56            show_confirm.set(false);
57        });
58
59        let on_confirm_no = with!(show_confirm, last_action => move || {
60            last_action.set("Cancelled delete".to_string());
61            show_confirm.set(false);
62        });
63
64        let on_alert_dismiss = with!(show_alert, last_action => move || {
65            last_action.set("Dismissed alert".to_string());
66            show_alert.set(false);
67        });
68
69        let on_custom_save = with!(show_custom, custom_input, last_action => move || {
70            let value = custom_input.get();
71            if !value.is_empty() {
72                last_action.set(format!("Saved: {}", value));
73                custom_input.set(String::new());
74            }
75            show_custom.set(false);
76        });
77
78        let on_custom_dismiss = with!(show_custom => move || {
79            show_custom.set(false);
80        });
81
82        View::vstack()
83            .spacing(1)
84            .child(
85                // Header
86                View::boxed()
87                    .border(true)
88                    .padding(1)
89                    .child(
90                        View::vstack()
91                            .child(View::styled_text("Modal Dialogs Demo").bold().build())
92                            .child(
93                                View::styled_text("Click buttons to open different modal types")
94                                    .dim()
95                                    .build(),
96                            )
97                            .build(),
98                    )
99                    .build(),
100            )
101            .child(
102                // Main content
103                View::boxed()
104                    .flex(1)
105                    .border(true)
106                    .padding(1)
107                    .child(
108                        View::vstack()
109                            .spacing(1)
110                            .child(View::text("Modal Types:"))
111                            .child(
112                                View::hstack()
113                                    .spacing(2)
114                                    .child(
115                                        View::button()
116                                            .label("Confirm Dialog")
117                                            .on_press(open_confirm)
118                                            .build(),
119                                    )
120                                    .child(
121                                        View::button()
122                                            .label("Alert Dialog")
123                                            .on_press(open_alert)
124                                            .build(),
125                                    )
126                                    .child(
127                                        View::button()
128                                            .label("Custom Modal")
129                                            .on_press(open_custom)
130                                            .build(),
131                                    )
132                                    .build(),
133                            )
134                            .child(View::spacer())
135                            .child(
136                                View::styled_text(format!(
137                                    "Deleted items: {}",
138                                    deleted_count.get()
139                                ))
140                                .color(Color::Yellow)
141                                .build(),
142                            )
143                            .child(
144                                View::styled_text(format!("Last action: {}", last_action.get()))
145                                    .dim()
146                                    .build(),
147                            )
148                            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
149                            .build(),
150                    )
151                    .build(),
152            )
153            // Help modal
154            .child(
155                View::modal()
156                    .visible(show_help.get())
157                    .title("Example 23: Modal")
158                    .on_dismiss(with!(show_help => move || show_help.set(false)))
159                    .child(
160                        View::vstack()
161                            .child(View::styled_text("What you're seeing").bold().build())
162                            .child(View::text("• Confirm, alert, and custom modals"))
163                            .child(View::text("• Modal focus containment"))
164                            .child(View::text("• Escape to dismiss"))
165                            .child(View::gap(1))
166                            .child(View::styled_text("Key concepts").bold().build())
167                            .child(View::text("• View::modal() creates overlay"))
168                            .child(View::text("• .visible() controls show/hide"))
169                            .child(View::text("• .on_dismiss() handles Escape"))
170                            .child(View::text("• Focus trapped in open modal"))
171                            .child(View::gap(1))
172                            .child(View::styled_text("Try this").bold().build())
173                            .child(View::text("• Open confirm, click Yes/No"))
174                            .child(View::text("• Custom modal has text input"))
175                            .child(View::text("• Press Escape to close modals"))
176                            .child(View::gap(1))
177                            .child(View::styled_text("Next up").bold().build())
178                            .child(View::text("→ 24_async_data: async loading"))
179                            .child(View::gap(1))
180                            .child(View::styled_text("Press Escape to close").dim().build())
181                            .build(),
182                    )
183                    .build(),
184            )
185            // Confirm dialog modal
186            .child(
187                View::modal()
188                    .visible(show_confirm.get())
189                    .title("Confirm Delete")
190                    .on_dismiss(on_confirm_no.clone())
191                    .width(40)
192                    .height(30)
193                    .child(
194                        View::vstack()
195                            .spacing(1)
196                            .child(View::text("Are you sure you want to delete this item?"))
197                            .child(View::text("This action cannot be undone."))
198                            .child(View::spacer())
199                            .child(
200                                View::hstack()
201                                    .spacing(2)
202                                    .child(
203                                        View::button()
204                                            .label("Yes, Delete")
205                                            .on_press(on_confirm_yes)
206                                            .build(),
207                                    )
208                                    .child(
209                                        View::button()
210                                            .label("Cancel")
211                                            .on_press(on_confirm_no)
212                                            .build(),
213                                    )
214                                    .build(),
215                            )
216                            .build(),
217                    )
218                    .build(),
219            )
220            // Alert dialog modal
221            .child(
222                View::modal()
223                    .visible(show_alert.get())
224                    .title("Alert")
225                    .on_dismiss(on_alert_dismiss.clone())
226                    .width(50)
227                    .height(25)
228                    .child(
229                        View::vstack()
230                            .spacing(1)
231                            .child(
232                                View::styled_text("Operation completed successfully!")
233                                    .color(Color::Green)
234                                    .build(),
235                            )
236                            .child(View::text("Your changes have been saved."))
237                            .child(View::spacer())
238                            .child(
239                                View::button()
240                                    .label("OK")
241                                    .on_press(on_alert_dismiss)
242                                    .build(),
243                            )
244                            .build(),
245                    )
246                    .build(),
247            )
248            // Custom modal with input
249            .child(
250                View::modal()
251                    .visible(show_custom.get())
252                    .title("Enter Details")
253                    .on_dismiss(on_custom_dismiss.clone())
254                    .width(50)
255                    .height(40)
256                    .child(
257                        View::vstack()
258                            .spacing(1)
259                            .child(View::text("Enter a value:"))
260                            .child(
261                                View::text_input()
262                                    .value(custom_input.get())
263                                    .placeholder("Type something...")
264                                    .on_change(with!(custom_input => move |v: String| {
265                                        custom_input.set(v);
266                                    }))
267                                    .build(),
268                            )
269                            .child(View::spacer())
270                            .child(
271                                View::hstack()
272                                    .spacing(2)
273                                    .child(
274                                        View::button()
275                                            .label("Save")
276                                            .on_press(on_custom_save)
277                                            .build(),
278                                    )
279                                    .child(
280                                        View::button()
281                                            .label("Cancel")
282                                            .on_press(on_custom_dismiss)
283                                            .build(),
284                                    )
285                                    .build(),
286                            )
287                            .build(),
288                    )
289                    .build(),
290            )
291            .build()
292    }
Source

pub fn on_cursor_change(self, callback: impl Fn(usize) + 'static) -> Self

Source

pub fn on_submit(self, callback: impl Fn() + 'static) -> Self

Examples found in repository?
examples/05_todo_list.rs (line 85)
20    fn render(&self, cx: Scope) -> View {
21        let items = state!(cx, || {
22            vec![
23                "Learn Telex".to_string(),
24                "Build something cool".to_string(),
25            ]
26        });
27        let input_value = state!(cx, String::new);
28        let selected = state!(cx, || 0usize);
29        let show_help = state!(cx, || false);
30
31        // F1 toggles help
32        cx.use_command(
33            KeyBinding::key(KeyCode::F(1)),
34            with!(show_help => move || show_help.update(|v| *v = !*v)),
35        );
36
37        // Add new item on submit
38        let on_submit = with!(items, input_value => move || {
39            let text = input_value.get();
40            if !text.is_empty() {
41                items.update(|v| v.push(text));
42                input_value.set(String::new());
43            }
44        });
45
46        // Handle input changes
47        let on_change = with!(input_value => move |text: String| {
48            input_value.set(text);
49        });
50
51        // Delete selected item
52        let on_delete = with!(items, selected => move || {
53            let idx = selected.get();
54            items.update(|v| {
55                if idx < v.len() {
56                    v.remove(idx);
57                    // Adjust selection if needed
58                    if idx > 0 && idx >= v.len() {
59                        selected.set(idx - 1);
60                    }
61                }
62            });
63        });
64
65        // Track selection
66        let on_select = with!(selected => move |idx: usize| {
67            selected.set(idx);
68        });
69
70        let item_count = items.get().len();
71
72        View::vstack()
73            .child(
74                View::styled_text("Todo List")
75                    .color(Color::Cyan)
76                    .bold()
77                    .build(),
78            )
79            .child(View::gap(1))
80            .child(
81                View::text_input()
82                    .value(input_value.get())
83                    .placeholder("Type something to add...")
84                    .on_change(on_change)
85                    .on_submit(on_submit)
86                    .build(),
87            )
88            .child(View::gap(1))
89            .child(if item_count > 0 {
90                View::list()
91                    .items(items.get())
92                    .selected(selected.get())
93                    .on_select(on_select)
94                    .build()
95            } else {
96                View::styled_text("No items yet").dim().build()
97            })
98            .child(View::gap(1))
99            .child(
100                View::hstack()
101                    .child(View::button().label("Delete").on_press(on_delete).build())
102                    .build(),
103            )
104            .child(View::gap(1))
105            .child(
106                View::styled_text("Tab navigate • Enter add/select • F1 help • Ctrl+Q quit")
107                    .dim()
108                    .build(),
109            )
110            .child(
111                View::modal()
112                    .visible(show_help.get())
113                    .title("Example 05: Todo List")
114                    .on_dismiss(with!(show_help => move || show_help.set(false)))
115                    .child(
116                        View::vstack()
117                            .child(View::styled_text("What you're seeing").bold().build())
118                            .child(View::text("• View::text_input() for text entry"))
119                            .child(View::text("• View::list() for displaying items"))
120                            .child(View::text("• on_submit callback for Enter key"))
121                            .child(View::gap(1))
122                            .child(View::styled_text("Key concepts").bold().build())
123                            .child(View::text("• Controlled input: value + on_change"))
124                            .child(View::text("• Vec<String> state for list items"))
125                            .child(View::text("• Conditional rendering (empty state)"))
126                            .child(View::gap(1))
127                            .child(View::styled_text("Try this").bold().build())
128                            .child(View::text("• Type something and press Enter to add"))
129                            .child(View::text("• Use ↑/↓ to select, then Delete button"))
130                            .child(View::text("• Delete all items to see empty state"))
131                            .child(View::gap(1))
132                            .child(View::styled_text("Next up").bold().build())
133                            .child(View::text("→ 06_log_viewer: streaming text content"))
134                            .child(View::gap(1))
135                            .child(View::styled_text("Press Escape to close").dim().build())
136                            .build(),
137                    )
138                    .build(),
139            )
140            .build()
141    }
Source

pub fn on_key_up(self, callback: impl Fn() + 'static) -> Self

Set callback for when Up arrow is pressed (e.g., for command history).

Source

pub fn on_key_down(self, callback: impl Fn() + 'static) -> Self

Set callback for when Down arrow is pressed (e.g., for command history).

Source

pub fn cursor(self, pos: usize) -> Self

Source

pub fn focused(self, focused: bool) -> Self

Set this input to have initial focus when the app starts.

Source

pub fn build(self) -> View

Examples found in repository?
examples/05_todo_list.rs (line 86)
20    fn render(&self, cx: Scope) -> View {
21        let items = state!(cx, || {
22            vec![
23                "Learn Telex".to_string(),
24                "Build something cool".to_string(),
25            ]
26        });
27        let input_value = state!(cx, String::new);
28        let selected = state!(cx, || 0usize);
29        let show_help = state!(cx, || false);
30
31        // F1 toggles help
32        cx.use_command(
33            KeyBinding::key(KeyCode::F(1)),
34            with!(show_help => move || show_help.update(|v| *v = !*v)),
35        );
36
37        // Add new item on submit
38        let on_submit = with!(items, input_value => move || {
39            let text = input_value.get();
40            if !text.is_empty() {
41                items.update(|v| v.push(text));
42                input_value.set(String::new());
43            }
44        });
45
46        // Handle input changes
47        let on_change = with!(input_value => move |text: String| {
48            input_value.set(text);
49        });
50
51        // Delete selected item
52        let on_delete = with!(items, selected => move || {
53            let idx = selected.get();
54            items.update(|v| {
55                if idx < v.len() {
56                    v.remove(idx);
57                    // Adjust selection if needed
58                    if idx > 0 && idx >= v.len() {
59                        selected.set(idx - 1);
60                    }
61                }
62            });
63        });
64
65        // Track selection
66        let on_select = with!(selected => move |idx: usize| {
67            selected.set(idx);
68        });
69
70        let item_count = items.get().len();
71
72        View::vstack()
73            .child(
74                View::styled_text("Todo List")
75                    .color(Color::Cyan)
76                    .bold()
77                    .build(),
78            )
79            .child(View::gap(1))
80            .child(
81                View::text_input()
82                    .value(input_value.get())
83                    .placeholder("Type something to add...")
84                    .on_change(on_change)
85                    .on_submit(on_submit)
86                    .build(),
87            )
88            .child(View::gap(1))
89            .child(if item_count > 0 {
90                View::list()
91                    .items(items.get())
92                    .selected(selected.get())
93                    .on_select(on_select)
94                    .build()
95            } else {
96                View::styled_text("No items yet").dim().build()
97            })
98            .child(View::gap(1))
99            .child(
100                View::hstack()
101                    .child(View::button().label("Delete").on_press(on_delete).build())
102                    .build(),
103            )
104            .child(View::gap(1))
105            .child(
106                View::styled_text("Tab navigate • Enter add/select • F1 help • Ctrl+Q quit")
107                    .dim()
108                    .build(),
109            )
110            .child(
111                View::modal()
112                    .visible(show_help.get())
113                    .title("Example 05: Todo List")
114                    .on_dismiss(with!(show_help => move || show_help.set(false)))
115                    .child(
116                        View::vstack()
117                            .child(View::styled_text("What you're seeing").bold().build())
118                            .child(View::text("• View::text_input() for text entry"))
119                            .child(View::text("• View::list() for displaying items"))
120                            .child(View::text("• on_submit callback for Enter key"))
121                            .child(View::gap(1))
122                            .child(View::styled_text("Key concepts").bold().build())
123                            .child(View::text("• Controlled input: value + on_change"))
124                            .child(View::text("• Vec<String> state for list items"))
125                            .child(View::text("• Conditional rendering (empty state)"))
126                            .child(View::gap(1))
127                            .child(View::styled_text("Try this").bold().build())
128                            .child(View::text("• Type something and press Enter to add"))
129                            .child(View::text("• Use ↑/↓ to select, then Delete button"))
130                            .child(View::text("• Delete all items to see empty state"))
131                            .child(View::gap(1))
132                            .child(View::styled_text("Next up").bold().build())
133                            .child(View::text("→ 06_log_viewer: streaming text content"))
134                            .child(View::gap(1))
135                            .child(View::styled_text("Press Escape to close").dim().build())
136                            .build(),
137                    )
138                    .build(),
139            )
140            .build()
141    }
More examples
Hide additional examples
examples/32_effects.rs (line 95)
23    fn render(&self, cx: Scope) -> View {
24        let show_help = state!(cx, || false);
25
26        // F1 toggles help
27        cx.use_command(
28            KeyBinding::key(KeyCode::F(1)),
29            with!(show_help => move || show_help.update(|v| *v = !*v)),
30        );
31
32        let count = state!(cx, || 0);
33        let name = state!(cx, String::new);
34        let last_effect = state!(cx, || String::from("(none yet)"));
35        let init_done = state!(cx, || false);
36
37        // Effect that runs only once - initialization
38        // Using effect_once! macro (order-independent)
39        effect_once!(cx, with!(init_done, last_effect => move || {
40            init_done.set(true);
41            last_effect.set("effect_once!: initialized!".to_string());
42            || {}
43        }));
44
45        // Effect that runs when count changes
46        // Using effect! macro (order-independent)
47        effect!(cx, count.get(), with!(last_effect => move |&val| {
48            last_effect.set(format!("effect!: count → {}", val));
49            || {}
50        }));
51
52        // Effect that runs when name changes
53        effect!(cx, name.get(), with!(last_effect => move |n: &String| {
54            if !n.is_empty() {
55                last_effect.set(format!("effect!: name → \"{}\"", n));
56            }
57            || {}
58        }));
59
60        View::vstack()
61            .spacing(1)
62            .child(View::styled_text("effect! Demo").bold().build())
63            .child(View::text(""))
64            .child(View::text(format!("Counter: {}", count.get())))
65            .child(
66                View::hstack()
67                    .spacing(1)
68                    .child(
69                        View::button()
70                            .label("[ - ]")
71                            .on_press(with!(count => move || count.update(|n| *n -= 1)))
72                            .build(),
73                    )
74                    .child(
75                        View::button()
76                            .label("[ + ]")
77                            .on_press(with!(count => move || count.update(|n| *n += 1)))
78                            .build(),
79                    )
80                    .build(),
81            )
82            .child(View::text(""))
83            .child({
84                let n = name.get();
85                View::text(format!(
86                    "Name: {}",
87                    if n.is_empty() { "(empty)" } else { &n }
88                ))
89            })
90            .child(
91                View::text_input()
92                    .value(name.get())
93                    .placeholder("Type your name...")
94                    .on_change(with!(name => move |s| name.set(s)))
95                    .build(),
96            )
97            .child(View::text(""))
98            .child(View::styled_text("─── Effect Status ───").dim().build())
99            .child(View::text(""))
100            .child(View::text(format!(
101                "Initialized: {}",
102                if init_done.get() { "✓ yes" } else { "no" }
103            )))
104            .child(View::text(format!("Last effect: {}", last_effect.get())))
105            .child(View::text(""))
106            .child(View::styled_text("─── How it works ───").dim().build())
107            .child(View::text(""))
108            .child(View::text("effect_once!  → Ran once at startup"))
109            .child(View::text("effect!       → Runs when deps change"))
110            .child(View::text(""))
111            .child(
112                View::styled_text("Press +/- or type to see effects trigger")
113                    .dim()
114                    .build(),
115            )
116            .child(View::text(""))
117            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
118            .child(
119                View::modal()
120                    .visible(show_help.get())
121                    .title("Example 32: Effects")
122                    .on_dismiss(with!(show_help => move || show_help.set(false)))
123                    .child(
124                        View::vstack()
125                            .child(View::styled_text("What you're seeing").bold().build())
126                            .child(View::text("• effect_once! runs at startup"))
127                            .child(View::text("• effect! runs when deps change"))
128                            .child(View::text("• Last effect shows what triggered"))
129                            .child(View::gap(1))
130                            .child(View::styled_text("Key concepts").bold().build())
131                            .child(View::text("• effect_once!(cx, || { cleanup })"))
132                            .child(View::text("• effect!(cx, deps, |&d| { cleanup })"))
133                            .child(View::text("• Return || {} for cleanup"))
134                            .child(View::text("• Effects run AFTER render"))
135                            .child(View::text("• Safe in conditionals!"))
136                            .child(View::gap(1))
137                            .child(View::styled_text("Try this").bold().build())
138                            .child(View::text("• Click +/- to change counter"))
139                            .child(View::text("• Type in the name field"))
140                            .child(View::text("• Watch 'Last effect' update"))
141                            .child(View::gap(1))
142                            .child(View::styled_text("Press Escape to close").dim().build())
143                            .build(),
144                    )
145                    .build(),
146            )
147            .build()
148    }
examples/36_reducer.rs (line 108)
38    fn render(&self, cx: Scope) -> View {
39        let show_help = state!(cx, || false);
40
41        cx.use_command(
42            KeyBinding::key(KeyCode::F(1)),
43            with!(show_help => move || show_help.update(|v| *v = !*v)),
44        );
45
46        let (wizard, dispatch) = reducer!(cx, WizardState::Welcome, |state: WizardState, action: WizardAction| {
47            match (state, action) {
48                (_, WizardAction::Reset) => WizardState::Welcome,
49                (WizardState::Welcome, WizardAction::Next) => WizardState::Name(String::new()),
50                (WizardState::Name(_), WizardAction::SetName(n)) => WizardState::Name(n),
51                (WizardState::Name(name), WizardAction::Next) => {
52                    let name = if name.is_empty() { "Anonymous".to_string() } else { name };
53                    WizardState::Color(name, String::new())
54                }
55                (WizardState::Name(_), WizardAction::Back) => WizardState::Welcome,
56                (WizardState::Color(name, _), WizardAction::SetColor(c)) => WizardState::Color(name, c),
57                (WizardState::Color(name, color), WizardAction::Next) => {
58                    let color = if color.is_empty() { "Blue".to_string() } else { color };
59                    WizardState::Done(name, color)
60                }
61                (WizardState::Color(_, _), WizardAction::Back) => WizardState::Name(String::new()),
62                (WizardState::Done(_, _), WizardAction::Back) => WizardState::Welcome,
63                (s, _) => s,
64            }
65        });
66
67        let step = match &wizard.get() {
68            WizardState::Welcome => 1,
69            WizardState::Name(_) => 2,
70            WizardState::Color(_, _) => 3,
71            WizardState::Done(_, _) => 4,
72        };
73
74        let progress = format!("Step {} of 4", step);
75        let dots: String = (1..=4)
76            .map(|i| if i <= step { "●" } else { "○" })
77            .collect::<Vec<_>>()
78            .join(" ");
79
80        let content = match &wizard.get() {
81            WizardState::Welcome => {
82                let d = dispatch.clone();
83                View::vstack()
84                    .spacing(1)
85                    .child(View::styled_text("Welcome to the Wizard!").color(Color::Cyan).bold().build())
86                    .child(View::text("This example shows centralized state"))
87                    .child(View::text("management with reducer!"))
88                    .child(
89                        View::button()
90                            .label("[ Start -> ]")
91                            .on_press(move || d(WizardAction::Next))
92                            .build(),
93                    )
94                    .build()
95            }
96            WizardState::Name(name) => {
97                let d1 = dispatch.clone();
98                let d2 = dispatch.clone();
99                let d3 = dispatch.clone();
100                View::vstack()
101                    .spacing(1)
102                    .child(View::styled_text("What's your name?").color(Color::Cyan).bold().build())
103                    .child(
104                        View::text_input()
105                            .value(name.clone())
106                            .placeholder("Enter your name...")
107                            .on_change(move |s: String| d1(WizardAction::SetName(s)))
108                            .build(),
109                    )
110                    .child(
111                        View::hstack()
112                            .spacing(1)
113                            .child(
114                                View::button()
115                                    .label("[ <- Back ]")
116                                    .on_press(move || d2(WizardAction::Back))
117                                    .build(),
118                            )
119                            .child(
120                                View::button()
121                                    .label("[ Next -> ]")
122                                    .on_press(move || d3(WizardAction::Next))
123                                    .build(),
124                            )
125                            .build(),
126                    )
127                    .build()
128            }
129            WizardState::Color(name, color) => {
130                let d1 = dispatch.clone();
131                let d2 = dispatch.clone();
132                let d3 = dispatch.clone();
133                View::vstack()
134                    .spacing(1)
135                    .child(View::styled_text(format!("Hi, {}! Pick a color:", name)).color(Color::Cyan).bold().build())
136                    .child(
137                        View::text_input()
138                            .value(color.clone())
139                            .placeholder("Enter a color (e.g. Blue)...")
140                            .on_change(move |s: String| d1(WizardAction::SetColor(s)))
141                            .build(),
142                    )
143                    .child(
144                        View::hstack()
145                            .spacing(1)
146                            .child(
147                                View::button()
148                                    .label("[ <- Back ]")
149                                    .on_press(move || d2(WizardAction::Back))
150                                    .build(),
151                            )
152                            .child(
153                                View::button()
154                                    .label("[ Finish -> ]")
155                                    .on_press(move || d3(WizardAction::Next))
156                                    .build(),
157                            )
158                            .build(),
159                    )
160                    .build()
161            }
162            WizardState::Done(name, color) => {
163                let d = dispatch.clone();
164                View::vstack()
165                    .spacing(1)
166                    .child(View::styled_text("All done!").color(Color::Green).bold().build())
167                    .child(View::text(format!("Name:  {}", name)))
168                    .child(View::text(format!("Color: {}", color)))
169                    .child(
170                        View::button()
171                            .label("[ Start Over ]")
172                            .on_press(move || d(WizardAction::Reset))
173                            .build(),
174                    )
175                    .build()
176            }
177        };
178
179        View::vstack()
180            .spacing(1)
181            .child(View::styled_text("Reducer Wizard").bold().build())
182            .child(
183                View::hstack()
184                    .spacing(1)
185                    .child(View::styled_text(&progress).dim().build())
186                    .child(View::styled_text(&dots).color(Color::Cyan).build())
187                    .build(),
188            )
189            .child(View::styled_text("────────────────────────").dim().build())
190            .child(content)
191            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
192            .child(
193                View::modal()
194                    .visible(show_help.get())
195                    .title("Example 36: Reducer")
196                    .on_dismiss(with!(show_help => move || show_help.set(false)))
197                    .child(
198                        View::vstack()
199                            .child(View::styled_text("What you're seeing").bold().build())
200                            .child(View::text("• Multi-step wizard state machine"))
201                            .child(View::text("• All transitions in one reducer fn"))
202                            .child(View::text("• No scattered booleans"))
203                            .child(View::gap(1))
204                            .child(View::styled_text("Key concepts").bold().build())
205                            .child(View::text("• reducer!(cx, init, |state, action| ...)"))
206                            .child(View::text("• Returns (State<S>, Rc<dyn Fn(A)>)"))
207                            .child(View::text("• dispatch(action) to transition"))
208                            .child(View::text("• Pattern match (state, action) pairs"))
209                            .child(View::gap(1))
210                            .child(View::styled_text("Try this").bold().build())
211                            .child(View::text("• Walk through all 4 steps"))
212                            .child(View::text("• Go back and change answers"))
213                            .child(View::text("• Watch the progress dots"))
214                            .child(View::gap(1))
215                            .child(View::styled_text("Next up").bold().build())
216                            .child(View::text("-> 37_error_boundary: crash protection"))
217                            .child(View::gap(1))
218                            .child(View::styled_text("Press Escape to close").dim().build())
219                            .build(),
220                    )
221                    .build(),
222            )
223            .build()
224    }
examples/23_modal.rs (line 267)
21    fn render(&self, cx: Scope) -> View {
22        let show_help = state!(cx, || false);
23
24        // F1 toggles help
25        cx.use_command(
26            KeyBinding::key(KeyCode::F(1)),
27            with!(show_help => move || show_help.update(|v| *v = !*v)),
28        );
29
30        // Modal visibility states
31        let show_confirm = state!(cx, || false);
32        let show_alert = state!(cx, || false);
33        let show_custom = state!(cx, || false);
34
35        // App state that modals can modify
36        let deleted_count = state!(cx, || 0);
37        let custom_input = state!(cx, String::new);
38        let last_action = state!(cx, || "No action yet".to_string());
39
40        // Handlers
41        let open_confirm = with!(show_confirm => move || {
42            show_confirm.set(true);
43        });
44
45        let open_alert = with!(show_alert => move || {
46            show_alert.set(true);
47        });
48
49        let open_custom = with!(show_custom => move || {
50            show_custom.set(true);
51        });
52
53        let on_confirm_yes = with!(show_confirm, deleted_count, last_action => move || {
54            deleted_count.set(deleted_count.get() + 1);
55            last_action.set(format!("Deleted item #{}", deleted_count.get()));
56            show_confirm.set(false);
57        });
58
59        let on_confirm_no = with!(show_confirm, last_action => move || {
60            last_action.set("Cancelled delete".to_string());
61            show_confirm.set(false);
62        });
63
64        let on_alert_dismiss = with!(show_alert, last_action => move || {
65            last_action.set("Dismissed alert".to_string());
66            show_alert.set(false);
67        });
68
69        let on_custom_save = with!(show_custom, custom_input, last_action => move || {
70            let value = custom_input.get();
71            if !value.is_empty() {
72                last_action.set(format!("Saved: {}", value));
73                custom_input.set(String::new());
74            }
75            show_custom.set(false);
76        });
77
78        let on_custom_dismiss = with!(show_custom => move || {
79            show_custom.set(false);
80        });
81
82        View::vstack()
83            .spacing(1)
84            .child(
85                // Header
86                View::boxed()
87                    .border(true)
88                    .padding(1)
89                    .child(
90                        View::vstack()
91                            .child(View::styled_text("Modal Dialogs Demo").bold().build())
92                            .child(
93                                View::styled_text("Click buttons to open different modal types")
94                                    .dim()
95                                    .build(),
96                            )
97                            .build(),
98                    )
99                    .build(),
100            )
101            .child(
102                // Main content
103                View::boxed()
104                    .flex(1)
105                    .border(true)
106                    .padding(1)
107                    .child(
108                        View::vstack()
109                            .spacing(1)
110                            .child(View::text("Modal Types:"))
111                            .child(
112                                View::hstack()
113                                    .spacing(2)
114                                    .child(
115                                        View::button()
116                                            .label("Confirm Dialog")
117                                            .on_press(open_confirm)
118                                            .build(),
119                                    )
120                                    .child(
121                                        View::button()
122                                            .label("Alert Dialog")
123                                            .on_press(open_alert)
124                                            .build(),
125                                    )
126                                    .child(
127                                        View::button()
128                                            .label("Custom Modal")
129                                            .on_press(open_custom)
130                                            .build(),
131                                    )
132                                    .build(),
133                            )
134                            .child(View::spacer())
135                            .child(
136                                View::styled_text(format!(
137                                    "Deleted items: {}",
138                                    deleted_count.get()
139                                ))
140                                .color(Color::Yellow)
141                                .build(),
142                            )
143                            .child(
144                                View::styled_text(format!("Last action: {}", last_action.get()))
145                                    .dim()
146                                    .build(),
147                            )
148                            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
149                            .build(),
150                    )
151                    .build(),
152            )
153            // Help modal
154            .child(
155                View::modal()
156                    .visible(show_help.get())
157                    .title("Example 23: Modal")
158                    .on_dismiss(with!(show_help => move || show_help.set(false)))
159                    .child(
160                        View::vstack()
161                            .child(View::styled_text("What you're seeing").bold().build())
162                            .child(View::text("• Confirm, alert, and custom modals"))
163                            .child(View::text("• Modal focus containment"))
164                            .child(View::text("• Escape to dismiss"))
165                            .child(View::gap(1))
166                            .child(View::styled_text("Key concepts").bold().build())
167                            .child(View::text("• View::modal() creates overlay"))
168                            .child(View::text("• .visible() controls show/hide"))
169                            .child(View::text("• .on_dismiss() handles Escape"))
170                            .child(View::text("• Focus trapped in open modal"))
171                            .child(View::gap(1))
172                            .child(View::styled_text("Try this").bold().build())
173                            .child(View::text("• Open confirm, click Yes/No"))
174                            .child(View::text("• Custom modal has text input"))
175                            .child(View::text("• Press Escape to close modals"))
176                            .child(View::gap(1))
177                            .child(View::styled_text("Next up").bold().build())
178                            .child(View::text("→ 24_async_data: async loading"))
179                            .child(View::gap(1))
180                            .child(View::styled_text("Press Escape to close").dim().build())
181                            .build(),
182                    )
183                    .build(),
184            )
185            // Confirm dialog modal
186            .child(
187                View::modal()
188                    .visible(show_confirm.get())
189                    .title("Confirm Delete")
190                    .on_dismiss(on_confirm_no.clone())
191                    .width(40)
192                    .height(30)
193                    .child(
194                        View::vstack()
195                            .spacing(1)
196                            .child(View::text("Are you sure you want to delete this item?"))
197                            .child(View::text("This action cannot be undone."))
198                            .child(View::spacer())
199                            .child(
200                                View::hstack()
201                                    .spacing(2)
202                                    .child(
203                                        View::button()
204                                            .label("Yes, Delete")
205                                            .on_press(on_confirm_yes)
206                                            .build(),
207                                    )
208                                    .child(
209                                        View::button()
210                                            .label("Cancel")
211                                            .on_press(on_confirm_no)
212                                            .build(),
213                                    )
214                                    .build(),
215                            )
216                            .build(),
217                    )
218                    .build(),
219            )
220            // Alert dialog modal
221            .child(
222                View::modal()
223                    .visible(show_alert.get())
224                    .title("Alert")
225                    .on_dismiss(on_alert_dismiss.clone())
226                    .width(50)
227                    .height(25)
228                    .child(
229                        View::vstack()
230                            .spacing(1)
231                            .child(
232                                View::styled_text("Operation completed successfully!")
233                                    .color(Color::Green)
234                                    .build(),
235                            )
236                            .child(View::text("Your changes have been saved."))
237                            .child(View::spacer())
238                            .child(
239                                View::button()
240                                    .label("OK")
241                                    .on_press(on_alert_dismiss)
242                                    .build(),
243                            )
244                            .build(),
245                    )
246                    .build(),
247            )
248            // Custom modal with input
249            .child(
250                View::modal()
251                    .visible(show_custom.get())
252                    .title("Enter Details")
253                    .on_dismiss(on_custom_dismiss.clone())
254                    .width(50)
255                    .height(40)
256                    .child(
257                        View::vstack()
258                            .spacing(1)
259                            .child(View::text("Enter a value:"))
260                            .child(
261                                View::text_input()
262                                    .value(custom_input.get())
263                                    .placeholder("Type something...")
264                                    .on_change(with!(custom_input => move |v: String| {
265                                        custom_input.set(v);
266                                    }))
267                                    .build(),
268                            )
269                            .child(View::spacer())
270                            .child(
271                                View::hstack()
272                                    .spacing(2)
273                                    .child(
274                                        View::button()
275                                            .label("Save")
276                                            .on_press(on_custom_save)
277                                            .build(),
278                                    )
279                                    .child(
280                                        View::button()
281                                            .label("Cancel")
282                                            .on_press(on_custom_dismiss)
283                                            .build(),
284                                    )
285                                    .build(),
286                            )
287                            .build(),
288                    )
289                    .build(),
290            )
291            .build()
292    }

Trait Implementations§

Source§

impl Default for TextInputBuilder

Source§

fn default() -> TextInputBuilder

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

Auto Trait Implementations§

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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<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.