Skip to main content

HStackBuilder

Struct HStackBuilder 

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

Builder for HStack views.

Implementations§

Source§

impl HStackBuilder

Source

pub fn new() -> Self

Source

pub fn child(self, view: View) -> Self

Examples found in repository?
examples/04_timer.rs (line 53)
22    fn render(&self, cx: Scope) -> View {
23        let show_help = state!(cx, || false);
24
25        // F1 toggles help
26        cx.use_command(
27            KeyBinding::key(KeyCode::F(1)),
28            with!(show_help => move || show_help.update(|v| *v = !*v)),
29        );
30
31        // Stream that yields elapsed seconds
32        let elapsed = cx.use_stream(|| {
33            (0u64..).inspect(|&s| {
34                if s > 0 {
35                    std::thread::sleep(Duration::from_secs(1));
36                }
37            })
38        });
39
40        let seconds = elapsed.get();
41        let is_running = elapsed.is_loading();
42
43        // Format as MM:SS
44        let minutes = seconds / 60;
45        let secs = seconds % 60;
46        let time_display = format!("{:02}:{:02}", minutes, secs);
47
48        View::vstack()
49            .child(View::styled_text("Timer").color(Color::Cyan).bold().build())
50            .child(View::gap(1))
51            .child(
52                View::hstack()
53                    .child(View::styled_text(&time_display).bold().build())
54                    .child(if is_running {
55                        View::styled_text(" ●").color(Color::Green).build()
56                    } else {
57                        View::styled_text(" ○").dim().build()
58                    })
59                    .build(),
60            )
61            .child(View::gap(1))
62            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
63            .child(
64                View::modal()
65                    .visible(show_help.get())
66                    .title("Example 04: Timer")
67                    .on_dismiss(with!(show_help => move || show_help.set(false)))
68                    .child(
69                        View::vstack()
70                            .child(View::styled_text("What you're seeing").bold().build())
71                            .child(View::text("• cx.use_stream() for background data"))
72                            .child(View::text("• Auto-updating UI without user input"))
73                            .child(View::text("• Green dot = stream is running"))
74                            .child(View::gap(1))
75                            .child(View::styled_text("Key concepts").bold().build())
76                            .child(View::text("• Streams run in background threads"))
77                            .child(View::text("• Each yielded value triggers a re-render"))
78                            .child(View::text("• is_loading() tells you if stream is active"))
79                            .child(View::gap(1))
80                            .child(View::styled_text("Try this").bold().build())
81                            .child(View::text("• Just watch - the timer ticks automatically"))
82                            .child(View::text("• No button presses needed for updates"))
83                            .child(View::gap(1))
84                            .child(View::styled_text("Next up").bold().build())
85                            .child(View::text("→ 05_todo_list: text input and list management"))
86                            .child(View::gap(1))
87                            .child(View::styled_text("Press Escape to close").dim().build())
88                            .build(),
89                    )
90                    .build(),
91            )
92            .build()
93    }
More examples
Hide additional examples
examples/02_counter.rs (lines 39-44)
19    fn render(&self, cx: Scope) -> View {
20        let count = state!(cx, || 0i32);
21        let show_help = state!(cx, || false);
22
23        let increment = with!(count => move || count.update(|n| *n += 1));
24        let decrement = with!(count => move || count.update(|n| *n -= 1));
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        View::vstack()
33            .child(View::styled_text("Counter").bold().build())
34            .child(View::gap(1))
35            .child(View::text(format!("Count: {}", count.get())))
36            .child(View::gap(1))
37            .child(
38                View::hstack()
39                    .child(
40                        View::button()
41                            .label("Decrement")
42                            .on_press(decrement)
43                            .build(),
44                    )
45                    .child(View::text(" "))
46                    .child(
47                        View::button()
48                            .label("Increment")
49                            .on_press(increment)
50                            .build(),
51                    )
52                    .build(),
53            )
54            .child(View::gap(1))
55            .child(
56                View::styled_text("Tab to switch • Enter to press • F1 for help • Ctrl+Q to quit")
57                    .dim()
58                    .build(),
59            )
60            .child(
61                View::modal()
62                    .visible(show_help.get())
63                    .title("Example 02: Counter")
64                    .on_dismiss(with!(show_help => move || show_help.set(false)))
65                    .child(
66                        View::vstack()
67                            .child(View::styled_text("What you're seeing").bold().build())
68                            .child(View::text("• state!() macro for reactive state"))
69                            .child(View::text("• View::button() with on_press callbacks"))
70                            .child(View::text(
71                                "• The with!() macro for capturing state in closures",
72                            ))
73                            .child(View::gap(1))
74                            .child(View::styled_text("Key concepts").bold().build())
75                            .child(View::text("• State persists across renders"))
76                            .child(View::text("• Updating state triggers a re-render"))
77                            .child(View::text("• Tab navigates between focusable elements"))
78                            .child(View::gap(1))
79                            .child(View::styled_text("Try this").bold().build())
80                            .child(View::text("• Press +/- rapidly - notice instant updates"))
81                            .child(View::text(
82                                "• The UI stays in sync with state automatically",
83                            ))
84                            .child(View::gap(1))
85                            .child(View::styled_text("Next up").bold().build())
86                            .child(View::text("→ 03_theme_switcher: styling and colors"))
87                            .child(View::gap(1))
88                            .child(View::styled_text("Press Escape to close").dim().build())
89                            .build(),
90                    )
91                    .build(),
92            )
93            .build()
94    }
examples/09_syntax_comparison.rs (line 58)
24    fn render(&self, cx: Scope) -> View {
25        let use_jsx = state!(cx, || false);
26        let show_help = state!(cx, || false);
27
28        // F1 toggles help
29        cx.use_command(
30            KeyBinding::key(KeyCode::F(1)),
31            with!(show_help => move || show_help.update(|v| *v = !*v)),
32        );
33
34        let toggle = with!(use_jsx => move || use_jsx.set(!use_jsx.get()));
35
36        // Show which syntax is currently displayed
37        let syntax_name = if use_jsx.get() {
38            "view! macro (JSX-like)"
39        } else {
40            "Builder pattern"
41        };
42
43        View::vstack()
44            .child(
45                View::styled_text("Syntax Comparison")
46                    .color(Color::Cyan)
47                    .bold()
48                    .build(),
49            )
50            .child(
51                View::styled_text("Same UI, two ways to write it")
52                    .dim()
53                    .build(),
54            )
55            .child(View::gap(1))
56            .child(
57                View::hstack()
58                    .child(View::text("Current syntax: "))
59                    .child(
60                        View::styled_text(syntax_name)
61                            .color(Color::Yellow)
62                            .bold()
63                            .build(),
64                    )
65                    .build(),
66            )
67            .child(View::gap(1))
68            .child(
69                View::boxed()
70                    .border(true)
71                    .padding(1)
72                    .child(if use_jsx.get() {
73                        counter_jsx(cx.clone())
74                    } else {
75                        counter_builder(cx.clone())
76                    })
77                    .build(),
78            )
79            .child(View::gap(1))
80            .child(
81                View::button()
82                    .label("Toggle Syntax")
83                    .on_press(toggle)
84                    .build(),
85            )
86            .child(View::gap(1))
87            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
88            .child(
89                View::modal()
90                    .visible(show_help.get())
91                    .title("Example 09: Syntax Comparison")
92                    .on_dismiss(with!(show_help => move || show_help.set(false)))
93                    .child(
94                        View::vstack()
95                            .child(View::styled_text("What you're seeing").bold().build())
96                            .child(View::text("• Two syntaxes that produce identical output"))
97                            .child(View::text("• Builder: View::vstack().child(...).build()"))
98                            .child(View::text("• Macro: view! { <VStack>...</VStack> }"))
99                            .child(View::gap(1))
100                            .child(View::styled_text("Key concepts").bold().build())
101                            .child(View::text("• Builder is Rust-native, IDE-friendly"))
102                            .child(View::text("• view! macro is JSX-like, less boilerplate"))
103                            .child(View::text("• Choose based on your preference"))
104                            .child(View::gap(1))
105                            .child(View::styled_text("Try this").bold().build())
106                            .child(View::text("• Toggle between syntaxes"))
107                            .child(View::text("• Notice the output is identical"))
108                            .child(View::text("• Check the source code to see both styles"))
109                            .child(View::gap(1))
110                            .child(View::styled_text("Next up").bold().build())
111                            .child(View::text("→ 10_state_explained: deep dive into state"))
112                            .child(View::gap(1))
113                            .child(View::styled_text("Press Escape to close").dim().build())
114                            .build(),
115                    )
116                    .build(),
117            )
118            .build()
119    }
120}
121
122// =============================================================================
123// Builder Pattern
124// =============================================================================
125// Rust-native, explicit, IDE-friendly. Each method call is clear.
126// Good for: Complex conditional logic, learning the API, debugging.
127
128fn counter_builder(cx: Scope) -> View {
129    let count = state!(cx, || 0i32);
130
131    // with! macro clones the handle for you - much cleaner!
132    let increment = with!(count => move || count.update(|n| *n += 1));
133    let decrement = with!(count => move || count.update(|n| *n -= 1));
134
135    View::vstack()
136        .child(
137            View::styled_text("// Built with builder pattern")
138                .color(Color::DarkGrey)
139                .build(),
140        )
141        .child(View::gap(1))
142        .child(
143            View::styled_text(format!("Count: {}", count.get()))
144                .bold()
145                .build(),
146        )
147        .child(View::gap(1))
148        .child(
149            View::hstack()
150                .child(View::button().label(" - ").on_press(decrement).build())
151                .child(View::text(" "))
152                .child(View::button().label(" + ").on_press(increment).build())
153                .build(),
154        )
155        .build()
156}
examples/05_todo_list.rs (line 101)
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    }
examples/10_state_explained.rs (line 86)
21    fn render(&self, cx: Scope) -> View {
22        let count = state!(cx, || 0i32);
23        let show_help = state!(cx, || false);
24
25        // F1 toggles help
26        cx.use_command(
27            KeyBinding::key(KeyCode::F(1)),
28            with!(show_help => move || show_help.update(|v| *v = !*v)),
29        );
30
31        // Clone handles for closures (this is the pattern being explained)
32        let count_for_increment = count.clone();
33        let count_for_decrement = count.clone();
34        let count_for_reset = count.clone();
35
36        let increment = move || {
37            let current = count_for_increment.get();
38            count_for_increment.set(current + 1);
39        };
40
41        let decrement = move || {
42            let current = count_for_decrement.get();
43            count_for_decrement.set(current - 1);
44        };
45
46        let reset = move || {
47            count_for_reset.set(0);
48        };
49
50        let current_value = count.get();
51
52        // Hook ordering demo
53        let _always_called_1 = state!(cx, || "hook 1");
54        let _always_called_2 = state!(cx, || "hook 2");
55
56        View::vstack()
57            .spacing(1)
58            .child(
59                View::styled_text("State Explained")
60                    .color(Color::Cyan)
61                    .bold()
62                    .build(),
63            )
64            .child(
65                View::boxed()
66                    .border(true)
67                    .padding(1)
68                    .child(
69                        View::vstack()
70                            .child(View::styled_text("The Mental Model:").bold().build())
71                            .child(View::gap(1))
72                            .child(View::text("  State<T> is a HANDLE, not data"))
73                            .child(View::text("  clone() copies the handle, not the data"))
74                            .child(View::text("  All handles point to ONE value"))
75                            .child(View::gap(1))
76                            .child(View::text("  count ──────┐"))
77                            .child(View::text("              ├──► i32: 0  (shared!)"))
78                            .child(View::text("  count2 ─────┘"))
79                            .build(),
80                    )
81                    .build(),
82            )
83            .child(
84                View::hstack()
85                    .spacing(1)
86                    .child(View::text("Current value:"))
87                    .child(
88                        View::styled_text(format!("{}", current_value))
89                            .color(Color::Yellow)
90                            .bold()
91                            .build(),
92                    )
93                    .build(),
94            )
95            .child(
96                View::hstack()
97                    .spacing(1)
98                    .child(View::button().label(" - ").on_press(decrement).build())
99                    .child(View::button().label(" + ").on_press(increment).build())
100                    .child(View::button().label("Reset").on_press(reset).build())
101                    .build(),
102            )
103            .child(
104                View::styled_text("All three buttons modify the SAME underlying i32")
105                    .dim()
106                    .build(),
107            )
108            .child(View::gap(1))
109            .child(
110                View::styled_text("Tab navigate • F1 help • Ctrl+Q quit")
111                    .dim()
112                    .build(),
113            )
114            .child(
115                View::modal()
116                    .visible(show_help.get())
117                    .title("Example 10: State Explained")
118                    .on_dismiss(with!(show_help => move || show_help.set(false)))
119                    .child(
120                        View::vstack()
121                            .child(View::styled_text("What you're seeing").bold().build())
122                            .child(View::text("• State<T> as a handle/pointer concept"))
123                            .child(View::text("• Multiple closures sharing one value"))
124                            .child(View::text("• Visual diagram of the mental model"))
125                            .child(View::gap(1))
126                            .child(View::styled_text("Key concepts").bold().build())
127                            .child(View::text("• clone() copies handle, not data"))
128                            .child(View::text("• All handles point to same underlying value"))
129                            .child(View::text(
130                                "• Hooks must be called in same order every render",
131                            ))
132                            .child(View::gap(1))
133                            .child(View::styled_text("Important rule").bold().build())
134                            .child(View::text("• NEVER put use_state inside an if block"))
135                            .child(View::text("• Use with!() macro to simplify cloning"))
136                            .child(View::gap(1))
137                            .child(View::styled_text("Next up").bold().build())
138                            .child(View::text("→ 11_checkbox: toggle controls"))
139                            .child(View::gap(1))
140                            .child(View::styled_text("Press Escape to close").dim().build())
141                            .build(),
142                    )
143                    .build(),
144            )
145            .build()
146    }
examples/32_effects.rs (lines 68-73)
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    }
Source

pub fn spacing(self, spacing: u16) -> Self

Examples found in repository?
examples/10_state_explained.rs (line 85)
21    fn render(&self, cx: Scope) -> View {
22        let count = state!(cx, || 0i32);
23        let show_help = state!(cx, || false);
24
25        // F1 toggles help
26        cx.use_command(
27            KeyBinding::key(KeyCode::F(1)),
28            with!(show_help => move || show_help.update(|v| *v = !*v)),
29        );
30
31        // Clone handles for closures (this is the pattern being explained)
32        let count_for_increment = count.clone();
33        let count_for_decrement = count.clone();
34        let count_for_reset = count.clone();
35
36        let increment = move || {
37            let current = count_for_increment.get();
38            count_for_increment.set(current + 1);
39        };
40
41        let decrement = move || {
42            let current = count_for_decrement.get();
43            count_for_decrement.set(current - 1);
44        };
45
46        let reset = move || {
47            count_for_reset.set(0);
48        };
49
50        let current_value = count.get();
51
52        // Hook ordering demo
53        let _always_called_1 = state!(cx, || "hook 1");
54        let _always_called_2 = state!(cx, || "hook 2");
55
56        View::vstack()
57            .spacing(1)
58            .child(
59                View::styled_text("State Explained")
60                    .color(Color::Cyan)
61                    .bold()
62                    .build(),
63            )
64            .child(
65                View::boxed()
66                    .border(true)
67                    .padding(1)
68                    .child(
69                        View::vstack()
70                            .child(View::styled_text("The Mental Model:").bold().build())
71                            .child(View::gap(1))
72                            .child(View::text("  State<T> is a HANDLE, not data"))
73                            .child(View::text("  clone() copies the handle, not the data"))
74                            .child(View::text("  All handles point to ONE value"))
75                            .child(View::gap(1))
76                            .child(View::text("  count ──────┐"))
77                            .child(View::text("              ├──► i32: 0  (shared!)"))
78                            .child(View::text("  count2 ─────┘"))
79                            .build(),
80                    )
81                    .build(),
82            )
83            .child(
84                View::hstack()
85                    .spacing(1)
86                    .child(View::text("Current value:"))
87                    .child(
88                        View::styled_text(format!("{}", current_value))
89                            .color(Color::Yellow)
90                            .bold()
91                            .build(),
92                    )
93                    .build(),
94            )
95            .child(
96                View::hstack()
97                    .spacing(1)
98                    .child(View::button().label(" - ").on_press(decrement).build())
99                    .child(View::button().label(" + ").on_press(increment).build())
100                    .child(View::button().label("Reset").on_press(reset).build())
101                    .build(),
102            )
103            .child(
104                View::styled_text("All three buttons modify the SAME underlying i32")
105                    .dim()
106                    .build(),
107            )
108            .child(View::gap(1))
109            .child(
110                View::styled_text("Tab navigate • F1 help • Ctrl+Q quit")
111                    .dim()
112                    .build(),
113            )
114            .child(
115                View::modal()
116                    .visible(show_help.get())
117                    .title("Example 10: State Explained")
118                    .on_dismiss(with!(show_help => move || show_help.set(false)))
119                    .child(
120                        View::vstack()
121                            .child(View::styled_text("What you're seeing").bold().build())
122                            .child(View::text("• State<T> as a handle/pointer concept"))
123                            .child(View::text("• Multiple closures sharing one value"))
124                            .child(View::text("• Visual diagram of the mental model"))
125                            .child(View::gap(1))
126                            .child(View::styled_text("Key concepts").bold().build())
127                            .child(View::text("• clone() copies handle, not data"))
128                            .child(View::text("• All handles point to same underlying value"))
129                            .child(View::text(
130                                "• Hooks must be called in same order every render",
131                            ))
132                            .child(View::gap(1))
133                            .child(View::styled_text("Important rule").bold().build())
134                            .child(View::text("• NEVER put use_state inside an if block"))
135                            .child(View::text("• Use with!() macro to simplify cloning"))
136                            .child(View::gap(1))
137                            .child(View::styled_text("Next up").bold().build())
138                            .child(View::text("→ 11_checkbox: toggle controls"))
139                            .child(View::gap(1))
140                            .child(View::styled_text("Press Escape to close").dim().build())
141                            .build(),
142                    )
143                    .build(),
144            )
145            .build()
146    }
More examples
Hide additional examples
examples/32_effects.rs (line 67)
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/12_text_area.rs (line 111)
21    fn render(&self, cx: Scope) -> View {
22        let show_help = state!(cx, || false);
23        let theme_idx = state!(cx, || 0usize);
24
25        // F1 toggles help
26        cx.use_command(
27            KeyBinding::key(KeyCode::F(1)),
28            with!(show_help => move || show_help.update(|v| *v = !*v)),
29        );
30
31        // F2 cycles through themes
32        cx.use_command(
33            KeyBinding::key(KeyCode::F(2)),
34            with!(theme_idx => move || {
35                let next = (theme_idx.get() + 1) % 6;
36                theme_idx.set(next);
37                let theme = match next {
38                    0 => Theme::nord(),
39                    1 => Theme::dark(),
40                    2 => Theme::light(),
41                    3 => Theme::dracula(),
42                    4 => Theme::gruvbox_dark(),
43                    _ => Theme::catppuccin_mocha(),
44                };
45                set_theme(theme);
46            }),
47        );
48
49        let content = state!(cx, String::new);
50        let cursor_line = state!(cx, || 0usize);
51        let cursor_col = state!(cx, || 0usize);
52
53        // Track changes and cursor position
54        let on_change = with!(content => move |text: String| {
55            content.set(text);
56        });
57
58        let on_cursor_change = with!(cursor_line, cursor_col => move |line: usize, col: usize| {
59            cursor_line.set(line);
60            cursor_col.set(col);
61        });
62
63        // Calculate stats
64        let text = content.get();
65        let line_count = if text.is_empty() {
66            0
67        } else {
68            text.lines().count()
69        };
70        let char_count = text.chars().count();
71        let word_count = text.split_whitespace().count();
72
73        let theme_name = match theme_idx.get() {
74            0 => "Nord",
75            1 => "Dark",
76            2 => "Light",
77            3 => "Dracula",
78            4 => "Gruvbox Dark",
79            _ => "Catppuccin Mocha",
80        };
81
82        View::vstack()
83            .spacing(1)
84            .child(
85                View::hstack()
86                    .child(View::styled_text("Notes").color(Color::Cyan).bold().build())
87                    .child(View::spacer())
88                    .child(View::styled_text(format!("Theme: {}", theme_name)).dim().build())
89                    .build(),
90            )
91            .child(
92                View::styled_text("A simple multi-line text editor")
93                    .dim()
94                    .build(),
95            )
96            .child(View::gap(1))
97            .child(
98                View::text_area()
99                    .value(content.get())
100                    .placeholder("Start typing your notes here...")
101                    .rows(12)
102                    .cursor_line(cursor_line.get())
103                    .cursor_col(cursor_col.get())
104                    .on_change(on_change)
105                    .on_cursor_change(on_cursor_change)
106                    .build(),
107            )
108            .child(View::gap(1))
109            .child(
110                View::hstack()
111                    .spacing(3)
112                    .child(
113                        View::styled_text(format!("Lines: {}", line_count))
114                            .color(Color::DarkGrey)
115                            .build(),
116                    )
117                    .child(
118                        View::styled_text(format!("Words: {}", word_count))
119                            .color(Color::DarkGrey)
120                            .build(),
121                    )
122                    .child(
123                        View::styled_text(format!("Chars: {}", char_count))
124                            .color(Color::DarkGrey)
125                            .build(),
126                    )
127                    .build(),
128            )
129            .child(View::gap(1))
130            .child(View::styled_text("F1 help • F2 theme • Ctrl+Q quit").dim().build())
131            .child(
132                View::modal()
133                    .visible(show_help.get())
134                    .title("Example 12: TextArea")
135                    .on_dismiss(with!(show_help => move || show_help.set(false)))
136                    .child(
137                        View::vstack()
138                            .child(View::styled_text("What you're seeing").bold().build())
139                            .child(View::text("• Multi-line text editing with TextArea"))
140                            .child(View::text("• Real-time line/word/char counts"))
141                            .child(View::text("• Cursor position tracking"))
142                            .child(View::gap(1))
143                            .child(View::styled_text("Key concepts").bold().build())
144                            .child(View::text("• View::text_area() for multi-line input"))
145                            .child(View::text("• on_change callback for text updates"))
146                            .child(View::text("• on_cursor_change for cursor tracking"))
147                            .child(View::text("• placeholder text when empty"))
148                            .child(View::gap(1))
149                            .child(View::styled_text("Try this").bold().build())
150                            .child(View::text("• Type multiple lines of text"))
151                            .child(View::text("• Watch the stats update in real-time"))
152                            .child(View::text("• Use arrow keys to navigate"))
153                            .child(View::gap(1))
154                            .child(View::styled_text("Next up").bold().build())
155                            .child(View::text("→ 13_split_panes: resizable panel layouts"))
156                            .child(View::gap(1))
157                            .child(View::styled_text("Press Escape to close").dim().build())
158                            .build(),
159                    )
160                    .build(),
161            )
162            .build()
163    }
examples/24_async_data.rs (line 97)
38    fn render(&self, cx: Scope) -> View {
39        let show_help = state!(cx, || false);
40
41        // F1 toggles help
42        cx.use_command(
43            KeyBinding::key(KeyCode::F(1)),
44            with!(show_help => move || show_help.update(|v| *v = !*v)),
45        );
46
47        // Simulate fetching user profile (slow - 2 seconds)
48        let profile = cx.use_async(|| {
49            thread::sleep(Duration::from_secs(2));
50            Ok(UserProfile {
51                name: "Alice Johnson".to_string(),
52                email: "alice@example.com".to_string(),
53                member_since: "January 2024".to_string(),
54            })
55        });
56
57        // Simulate fetching user stats (medium - 1 second)
58        let stats = cx.use_async(|| {
59            thread::sleep(Duration::from_secs(1));
60            Ok(Stats {
61                posts: 142,
62                followers: 1234,
63                following: 567,
64            })
65        });
66
67        // Simulate a failing request
68        let failing_data = cx.use_async(|| {
69            thread::sleep(Duration::from_millis(500));
70            Err::<String, _>("Network error: Connection refused".to_string())
71        });
72
73        View::vstack()
74            .spacing(1)
75            .child(
76                // Header
77                View::boxed()
78                    .border(true)
79                    .padding(1)
80                    .child(
81                        View::vstack()
82                            .child(View::styled_text("Async Data Loading Demo").bold().build())
83                            .child(
84                                View::styled_text(
85                                    "Demonstrates use_async for loading data with loading/error states",
86                                )
87                                .dim()
88                                .build(),
89                            )
90                            .build(),
91                    )
92                    .build(),
93            )
94            .child(
95                // Main content - three columns
96                View::hstack()
97                    .spacing(1)
98                    // Profile section
99                    .child(
100                        View::boxed()
101                            .flex(1)
102                            .border(true)
103                            .padding(1)
104                            .child(render_profile_section(&profile))
105                            .build(),
106                    )
107                    // Stats section
108                    .child(
109                        View::boxed()
110                            .flex(1)
111                            .border(true)
112                            .padding(1)
113                            .child(render_stats_section(&stats))
114                            .build(),
115                    )
116                    // Error section
117                    .child(
118                        View::boxed()
119                            .flex(1)
120                            .border(true)
121                            .padding(1)
122                            .child(render_error_section(&failing_data))
123                            .build(),
124                    )
125                    .build(),
126            )
127            .child(
128                // Status footer
129                View::boxed()
130                    .border(true)
131                    .padding(1)
132                    .child(
133                        View::vstack()
134                            .child(View::text(format!(
135                                "Overall status: {}",
136                                if profile.is_loading() || stats.is_loading() {
137                                    "Loading..."
138                                } else if profile.is_error() || stats.is_error() || failing_data.is_error() {
139                                    "Some requests failed"
140                                } else {
141                                    "All data loaded"
142                                }
143                            )))
144                            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
145                            .build(),
146                    )
147                    .build(),
148            )
149            .child(
150                View::modal()
151                    .visible(show_help.get())
152                    .title("Example 24: Async Data")
153                    .on_dismiss(with!(show_help => move || show_help.set(false)))
154                    .child(
155                        View::vstack()
156                            .child(View::styled_text("What you're seeing").bold().build())
157                            .child(View::text("• Three async data loads in parallel"))
158                            .child(View::text("• Loading, success, and error states"))
159                            .child(View::text("• Different load times for each"))
160                            .child(View::gap(1))
161                            .child(View::styled_text("Key concepts").bold().build())
162                            .child(View::text("• cx.use_async() runs in background"))
163                            .child(View::text("• Returns Async<T> enum"))
164                            .child(View::text("• .is_loading() / .is_error() helpers"))
165                            .child(View::text("• Pattern match for state handling"))
166                            .child(View::gap(1))
167                            .child(View::styled_text("Try this").bold().build())
168                            .child(View::text("• Watch data load progressively"))
169                            .child(View::text("• Notice the failing request"))
170                            .child(View::gap(1))
171                            .child(View::styled_text("Next up").bold().build())
172                            .child(View::text("→ 25_context: context API"))
173                            .child(View::gap(1))
174                            .child(View::styled_text("Press Escape to close").dim().build())
175                            .build()
176                    )
177                    .build()
178            )
179            .build()
180    }
examples/25_context.rs (line 143)
71    fn render(&self, cx: Scope) -> View {
72        let show_help = state!(cx, || false);
73
74        // F1 toggles help
75        cx.use_command(
76            KeyBinding::key(KeyCode::F(1)),
77            with!(show_help => move || show_help.update(|v| *v = !*v)),
78        );
79
80        // State that we'll provide via context
81        let theme = state!(cx, || ColorTheme::Default);
82        let user = state!(cx, || User {
83            name: "Guest".to_string(),
84            logged_in: false,
85        });
86
87        // Provide static config via context
88        cx.provide_context(AppConfig {
89            app_name: "Context Demo".to_string(),
90            version: "1.0.0".to_string(),
91        });
92
93        // Provide dynamic state via context (current values)
94        cx.provide_context(theme.get());
95        cx.provide_context(user.get());
96
97        // Theme switching handlers
98        let set_default = with!(theme => move || theme.set(ColorTheme::Default));
99        let set_ocean = with!(theme => move || theme.set(ColorTheme::Ocean));
100        let set_forest = with!(theme => move || theme.set(ColorTheme::Forest));
101        let set_sunset = with!(theme => move || theme.set(ColorTheme::Sunset));
102
103        // Login/logout handlers
104        let toggle_login = with!(user => move || {
105            let current = user.get();
106            if current.logged_in {
107                user.set(User {
108                    name: "Guest".to_string(),
109                    logged_in: false,
110                });
111            } else {
112                user.set(User {
113                    name: "Alice".to_string(),
114                    logged_in: true,
115                });
116            }
117        });
118
119        // Get current theme for styling
120        let current_theme = theme.get();
121
122        View::vstack()
123            .spacing(1)
124            // Header - uses context
125            .child(render_header(&cx))
126            .child(
127                // Main content
128                View::boxed()
129                    .flex(1)
130                    .border(true)
131                    .padding(1)
132                    .child(
133                        View::vstack()
134                            .spacing(1)
135                            .child(
136                                View::styled_text("Theme Selection:")
137                                    .color(current_theme.primary())
138                                    .bold()
139                                    .build(),
140                            )
141                            .child(
142                                View::hstack()
143                                    .spacing(2)
144                                    .child(
145                                        View::button()
146                                            .label("Default")
147                                            .on_press(set_default)
148                                            .build(),
149                                    )
150                                    .child(
151                                        View::button().label("Ocean").on_press(set_ocean).build(),
152                                    )
153                                    .child(
154                                        View::button().label("Forest").on_press(set_forest).build(),
155                                    )
156                                    .child(
157                                        View::button().label("Sunset").on_press(set_sunset).build(),
158                                    )
159                                    .build(),
160                            )
161                            .child(View::gap(1))
162                            .child(
163                                View::styled_text("User Actions:")
164                                    .color(current_theme.primary())
165                                    .bold()
166                                    .build(),
167                            )
168                            .child(
169                                View::button()
170                                    .label(if user.get().logged_in {
171                                        "Logout"
172                                    } else {
173                                        "Login as Alice"
174                                    })
175                                    .on_press(toggle_login)
176                                    .build(),
177                            )
178                            .child(View::spacer())
179                            // User info panel - uses context
180                            .child(render_user_panel(&cx))
181                            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
182                            .build(),
183                    )
184                    .build(),
185            )
186            // Status bar - uses context
187            .child(render_status_bar(&cx))
188            .child(
189                View::modal()
190                    .visible(show_help.get())
191                    .title("Example 25: Context")
192                    .on_dismiss(with!(show_help => move || show_help.set(false)))
193                    .child(
194                        View::vstack()
195                            .child(View::styled_text("What you're seeing").bold().build())
196                            .child(View::text("• Context API for global state"))
197                            .child(View::text("• Theme colors propagate everywhere"))
198                            .child(View::text("• User state shared across components"))
199                            .child(View::gap(1))
200                            .child(View::styled_text("Key concepts").bold().build())
201                            .child(View::text("• cx.provide_context() adds to context"))
202                            .child(View::text("• cx.use_context::<T>() reads context"))
203                            .child(View::text("• Avoids prop drilling"))
204                            .child(View::text("• Great for themes, user, config"))
205                            .child(View::gap(1))
206                            .child(View::styled_text("Try this").bold().build())
207                            .child(View::text("• Switch themes - colors update"))
208                            .child(View::text("• Login/logout - panel updates"))
209                            .child(View::text("• Header and status bar read context"))
210                            .child(View::gap(1))
211                            .child(View::styled_text("Next up").bold().build())
212                            .child(View::text("→ 26_radio_buttons: radio selections"))
213                            .child(View::gap(1))
214                            .child(View::styled_text("Press Escape to close").dim().build())
215                            .build(),
216                    )
217                    .build(),
218            )
219            .build()
220    }
examples/11_checkbox.rs (line 130)
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        // Settings state
31        let dark_mode = state!(cx, || true);
32        let notifications = state!(cx, || true);
33        let auto_save = state!(cx, || false);
34        let telemetry = state!(cx, || false);
35
36        View::vstack()
37            .spacing(1)
38            .child(
39                View::styled_text("Settings")
40                    .color(Color::Cyan)
41                    .bold()
42                    .build(),
43            )
44            .child(
45                View::styled_text("Use Tab to navigate, Enter/Space to toggle")
46                    .dim()
47                    .build(),
48            )
49            .child(View::gap(1))
50            .child(
51                View::boxed()
52                    .border(true)
53                    .padding(1)
54                    .child(
55                        View::vstack()
56                            .spacing(1)
57                            .child(View::styled_text("Appearance").bold().build())
58                            .child(
59                                View::checkbox()
60                                    .checked(dark_mode.get())
61                                    .label("Dark mode")
62                                    .on_toggle(with!(dark_mode => move |checked| {
63                                        dark_mode.set(checked);
64                                        if checked {
65                                            set_theme(Theme::dark());
66                                        } else {
67                                            set_theme(Theme::light());
68                                        }
69                                    }))
70                                    .build(),
71                            )
72                            .build(),
73                    )
74                    .build(),
75            )
76            .child(
77                View::boxed()
78                    .border(true)
79                    .padding(1)
80                    .child(
81                        View::vstack()
82                            .spacing(1)
83                            .child(View::styled_text("Behavior").bold().build())
84                            .child(
85                                View::checkbox()
86                                    .checked(notifications.get())
87                                    .label("Enable notifications")
88                                    .on_toggle(with!(notifications => move |checked| {
89                                        notifications.set(checked);
90                                    }))
91                                    .build(),
92                            )
93                            .child(
94                                View::checkbox()
95                                    .checked(auto_save.get())
96                                    .label("Auto-save documents")
97                                    .on_toggle(with!(auto_save => move |checked| {
98                                        auto_save.set(checked);
99                                    }))
100                                    .build(),
101                            )
102                            .build(),
103                    )
104                    .build(),
105            )
106            .child(
107                View::boxed()
108                    .border(true)
109                    .padding(1)
110                    .child(
111                        View::vstack()
112                            .spacing(1)
113                            .child(View::styled_text("Privacy").bold().build())
114                            .child(
115                                View::checkbox()
116                                    .checked(telemetry.get())
117                                    .label("Send anonymous usage data")
118                                    .on_toggle(with!(telemetry => move |checked| {
119                                        telemetry.set(checked);
120                                    }))
121                                    .build(),
122                            )
123                            .build(),
124                    )
125                    .build(),
126            )
127            .child(View::gap(1))
128            .child(
129                View::hstack()
130                    .spacing(2)
131                    .child(View::text("Current settings:"))
132                    .child(
133                        View::styled_text(format!(
134                            "dark={} notify={} autosave={} telemetry={}",
135                            dark_mode.get(),
136                            notifications.get(),
137                            auto_save.get(),
138                            telemetry.get()
139                        ))
140                        .color(Color::Yellow)
141                        .build(),
142                    )
143                    .build(),
144            )
145            .child(View::gap(1))
146            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
147            .child(
148                View::modal()
149                    .visible(show_help.get())
150                    .title("Example 11: Checkbox")
151                    .on_dismiss(with!(show_help => move || show_help.set(false)))
152                    .child(
153                        View::vstack()
154                            .child(View::styled_text("What you're seeing").bold().build())
155                            .child(View::text("• Checkbox widget for boolean toggles"))
156                            .child(View::text("• Grouped settings in boxed sections"))
157                            .child(View::text("• Dark mode toggle that changes theme live"))
158                            .child(View::gap(1))
159                            .child(View::styled_text("Key concepts").bold().build())
160                            .child(View::text("• View::checkbox() with checked state"))
161                            .child(View::text("• on_toggle callback receives new value"))
162                            .child(View::text("• set_theme() for live theme switching"))
163                            .child(View::gap(1))
164                            .child(View::styled_text("Try this").bold().build())
165                            .child(View::text("• Toggle Dark mode to see theme change"))
166                            .child(View::text("• Watch the status line update"))
167                            .child(View::text("• Tab between checkboxes"))
168                            .child(View::gap(1))
169                            .child(View::styled_text("Next up").bold().build())
170                            .child(View::text("→ 12_text_area: multi-line text editing"))
171                            .child(View::gap(1))
172                            .child(View::styled_text("Press Escape to close").dim().build())
173                            .build(),
174                    )
175                    .build(),
176            )
177            .build()
178    }
Source

pub fn justify(self, justify: Justify) -> Self

Set justify (main axis alignment for HStack = horizontal).

Source

pub fn align(self, align: Align) -> Self

Set align (cross axis alignment for HStack = vertical).

Source

pub fn layout_mode(self, mode: LayoutMode) -> Self

Set layout mode (algorithm for distributing space).

Source

pub fn build(self) -> View

Examples found in repository?
examples/04_timer.rs (line 59)
22    fn render(&self, cx: Scope) -> View {
23        let show_help = state!(cx, || false);
24
25        // F1 toggles help
26        cx.use_command(
27            KeyBinding::key(KeyCode::F(1)),
28            with!(show_help => move || show_help.update(|v| *v = !*v)),
29        );
30
31        // Stream that yields elapsed seconds
32        let elapsed = cx.use_stream(|| {
33            (0u64..).inspect(|&s| {
34                if s > 0 {
35                    std::thread::sleep(Duration::from_secs(1));
36                }
37            })
38        });
39
40        let seconds = elapsed.get();
41        let is_running = elapsed.is_loading();
42
43        // Format as MM:SS
44        let minutes = seconds / 60;
45        let secs = seconds % 60;
46        let time_display = format!("{:02}:{:02}", minutes, secs);
47
48        View::vstack()
49            .child(View::styled_text("Timer").color(Color::Cyan).bold().build())
50            .child(View::gap(1))
51            .child(
52                View::hstack()
53                    .child(View::styled_text(&time_display).bold().build())
54                    .child(if is_running {
55                        View::styled_text(" ●").color(Color::Green).build()
56                    } else {
57                        View::styled_text(" ○").dim().build()
58                    })
59                    .build(),
60            )
61            .child(View::gap(1))
62            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
63            .child(
64                View::modal()
65                    .visible(show_help.get())
66                    .title("Example 04: Timer")
67                    .on_dismiss(with!(show_help => move || show_help.set(false)))
68                    .child(
69                        View::vstack()
70                            .child(View::styled_text("What you're seeing").bold().build())
71                            .child(View::text("• cx.use_stream() for background data"))
72                            .child(View::text("• Auto-updating UI without user input"))
73                            .child(View::text("• Green dot = stream is running"))
74                            .child(View::gap(1))
75                            .child(View::styled_text("Key concepts").bold().build())
76                            .child(View::text("• Streams run in background threads"))
77                            .child(View::text("• Each yielded value triggers a re-render"))
78                            .child(View::text("• is_loading() tells you if stream is active"))
79                            .child(View::gap(1))
80                            .child(View::styled_text("Try this").bold().build())
81                            .child(View::text("• Just watch - the timer ticks automatically"))
82                            .child(View::text("• No button presses needed for updates"))
83                            .child(View::gap(1))
84                            .child(View::styled_text("Next up").bold().build())
85                            .child(View::text("→ 05_todo_list: text input and list management"))
86                            .child(View::gap(1))
87                            .child(View::styled_text("Press Escape to close").dim().build())
88                            .build(),
89                    )
90                    .build(),
91            )
92            .build()
93    }
More examples
Hide additional examples
examples/02_counter.rs (line 52)
19    fn render(&self, cx: Scope) -> View {
20        let count = state!(cx, || 0i32);
21        let show_help = state!(cx, || false);
22
23        let increment = with!(count => move || count.update(|n| *n += 1));
24        let decrement = with!(count => move || count.update(|n| *n -= 1));
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        View::vstack()
33            .child(View::styled_text("Counter").bold().build())
34            .child(View::gap(1))
35            .child(View::text(format!("Count: {}", count.get())))
36            .child(View::gap(1))
37            .child(
38                View::hstack()
39                    .child(
40                        View::button()
41                            .label("Decrement")
42                            .on_press(decrement)
43                            .build(),
44                    )
45                    .child(View::text(" "))
46                    .child(
47                        View::button()
48                            .label("Increment")
49                            .on_press(increment)
50                            .build(),
51                    )
52                    .build(),
53            )
54            .child(View::gap(1))
55            .child(
56                View::styled_text("Tab to switch • Enter to press • F1 for help • Ctrl+Q to quit")
57                    .dim()
58                    .build(),
59            )
60            .child(
61                View::modal()
62                    .visible(show_help.get())
63                    .title("Example 02: Counter")
64                    .on_dismiss(with!(show_help => move || show_help.set(false)))
65                    .child(
66                        View::vstack()
67                            .child(View::styled_text("What you're seeing").bold().build())
68                            .child(View::text("• state!() macro for reactive state"))
69                            .child(View::text("• View::button() with on_press callbacks"))
70                            .child(View::text(
71                                "• The with!() macro for capturing state in closures",
72                            ))
73                            .child(View::gap(1))
74                            .child(View::styled_text("Key concepts").bold().build())
75                            .child(View::text("• State persists across renders"))
76                            .child(View::text("• Updating state triggers a re-render"))
77                            .child(View::text("• Tab navigates between focusable elements"))
78                            .child(View::gap(1))
79                            .child(View::styled_text("Try this").bold().build())
80                            .child(View::text("• Press +/- rapidly - notice instant updates"))
81                            .child(View::text(
82                                "• The UI stays in sync with state automatically",
83                            ))
84                            .child(View::gap(1))
85                            .child(View::styled_text("Next up").bold().build())
86                            .child(View::text("→ 03_theme_switcher: styling and colors"))
87                            .child(View::gap(1))
88                            .child(View::styled_text("Press Escape to close").dim().build())
89                            .build(),
90                    )
91                    .build(),
92            )
93            .build()
94    }
examples/09_syntax_comparison.rs (line 65)
24    fn render(&self, cx: Scope) -> View {
25        let use_jsx = state!(cx, || false);
26        let show_help = state!(cx, || false);
27
28        // F1 toggles help
29        cx.use_command(
30            KeyBinding::key(KeyCode::F(1)),
31            with!(show_help => move || show_help.update(|v| *v = !*v)),
32        );
33
34        let toggle = with!(use_jsx => move || use_jsx.set(!use_jsx.get()));
35
36        // Show which syntax is currently displayed
37        let syntax_name = if use_jsx.get() {
38            "view! macro (JSX-like)"
39        } else {
40            "Builder pattern"
41        };
42
43        View::vstack()
44            .child(
45                View::styled_text("Syntax Comparison")
46                    .color(Color::Cyan)
47                    .bold()
48                    .build(),
49            )
50            .child(
51                View::styled_text("Same UI, two ways to write it")
52                    .dim()
53                    .build(),
54            )
55            .child(View::gap(1))
56            .child(
57                View::hstack()
58                    .child(View::text("Current syntax: "))
59                    .child(
60                        View::styled_text(syntax_name)
61                            .color(Color::Yellow)
62                            .bold()
63                            .build(),
64                    )
65                    .build(),
66            )
67            .child(View::gap(1))
68            .child(
69                View::boxed()
70                    .border(true)
71                    .padding(1)
72                    .child(if use_jsx.get() {
73                        counter_jsx(cx.clone())
74                    } else {
75                        counter_builder(cx.clone())
76                    })
77                    .build(),
78            )
79            .child(View::gap(1))
80            .child(
81                View::button()
82                    .label("Toggle Syntax")
83                    .on_press(toggle)
84                    .build(),
85            )
86            .child(View::gap(1))
87            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
88            .child(
89                View::modal()
90                    .visible(show_help.get())
91                    .title("Example 09: Syntax Comparison")
92                    .on_dismiss(with!(show_help => move || show_help.set(false)))
93                    .child(
94                        View::vstack()
95                            .child(View::styled_text("What you're seeing").bold().build())
96                            .child(View::text("• Two syntaxes that produce identical output"))
97                            .child(View::text("• Builder: View::vstack().child(...).build()"))
98                            .child(View::text("• Macro: view! { <VStack>...</VStack> }"))
99                            .child(View::gap(1))
100                            .child(View::styled_text("Key concepts").bold().build())
101                            .child(View::text("• Builder is Rust-native, IDE-friendly"))
102                            .child(View::text("• view! macro is JSX-like, less boilerplate"))
103                            .child(View::text("• Choose based on your preference"))
104                            .child(View::gap(1))
105                            .child(View::styled_text("Try this").bold().build())
106                            .child(View::text("• Toggle between syntaxes"))
107                            .child(View::text("• Notice the output is identical"))
108                            .child(View::text("• Check the source code to see both styles"))
109                            .child(View::gap(1))
110                            .child(View::styled_text("Next up").bold().build())
111                            .child(View::text("→ 10_state_explained: deep dive into state"))
112                            .child(View::gap(1))
113                            .child(View::styled_text("Press Escape to close").dim().build())
114                            .build(),
115                    )
116                    .build(),
117            )
118            .build()
119    }
120}
121
122// =============================================================================
123// Builder Pattern
124// =============================================================================
125// Rust-native, explicit, IDE-friendly. Each method call is clear.
126// Good for: Complex conditional logic, learning the API, debugging.
127
128fn counter_builder(cx: Scope) -> View {
129    let count = state!(cx, || 0i32);
130
131    // with! macro clones the handle for you - much cleaner!
132    let increment = with!(count => move || count.update(|n| *n += 1));
133    let decrement = with!(count => move || count.update(|n| *n -= 1));
134
135    View::vstack()
136        .child(
137            View::styled_text("// Built with builder pattern")
138                .color(Color::DarkGrey)
139                .build(),
140        )
141        .child(View::gap(1))
142        .child(
143            View::styled_text(format!("Count: {}", count.get()))
144                .bold()
145                .build(),
146        )
147        .child(View::gap(1))
148        .child(
149            View::hstack()
150                .child(View::button().label(" - ").on_press(decrement).build())
151                .child(View::text(" "))
152                .child(View::button().label(" + ").on_press(increment).build())
153                .build(),
154        )
155        .build()
156}
examples/05_todo_list.rs (line 102)
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    }
examples/10_state_explained.rs (line 93)
21    fn render(&self, cx: Scope) -> View {
22        let count = state!(cx, || 0i32);
23        let show_help = state!(cx, || false);
24
25        // F1 toggles help
26        cx.use_command(
27            KeyBinding::key(KeyCode::F(1)),
28            with!(show_help => move || show_help.update(|v| *v = !*v)),
29        );
30
31        // Clone handles for closures (this is the pattern being explained)
32        let count_for_increment = count.clone();
33        let count_for_decrement = count.clone();
34        let count_for_reset = count.clone();
35
36        let increment = move || {
37            let current = count_for_increment.get();
38            count_for_increment.set(current + 1);
39        };
40
41        let decrement = move || {
42            let current = count_for_decrement.get();
43            count_for_decrement.set(current - 1);
44        };
45
46        let reset = move || {
47            count_for_reset.set(0);
48        };
49
50        let current_value = count.get();
51
52        // Hook ordering demo
53        let _always_called_1 = state!(cx, || "hook 1");
54        let _always_called_2 = state!(cx, || "hook 2");
55
56        View::vstack()
57            .spacing(1)
58            .child(
59                View::styled_text("State Explained")
60                    .color(Color::Cyan)
61                    .bold()
62                    .build(),
63            )
64            .child(
65                View::boxed()
66                    .border(true)
67                    .padding(1)
68                    .child(
69                        View::vstack()
70                            .child(View::styled_text("The Mental Model:").bold().build())
71                            .child(View::gap(1))
72                            .child(View::text("  State<T> is a HANDLE, not data"))
73                            .child(View::text("  clone() copies the handle, not the data"))
74                            .child(View::text("  All handles point to ONE value"))
75                            .child(View::gap(1))
76                            .child(View::text("  count ──────┐"))
77                            .child(View::text("              ├──► i32: 0  (shared!)"))
78                            .child(View::text("  count2 ─────┘"))
79                            .build(),
80                    )
81                    .build(),
82            )
83            .child(
84                View::hstack()
85                    .spacing(1)
86                    .child(View::text("Current value:"))
87                    .child(
88                        View::styled_text(format!("{}", current_value))
89                            .color(Color::Yellow)
90                            .bold()
91                            .build(),
92                    )
93                    .build(),
94            )
95            .child(
96                View::hstack()
97                    .spacing(1)
98                    .child(View::button().label(" - ").on_press(decrement).build())
99                    .child(View::button().label(" + ").on_press(increment).build())
100                    .child(View::button().label("Reset").on_press(reset).build())
101                    .build(),
102            )
103            .child(
104                View::styled_text("All three buttons modify the SAME underlying i32")
105                    .dim()
106                    .build(),
107            )
108            .child(View::gap(1))
109            .child(
110                View::styled_text("Tab navigate • F1 help • Ctrl+Q quit")
111                    .dim()
112                    .build(),
113            )
114            .child(
115                View::modal()
116                    .visible(show_help.get())
117                    .title("Example 10: State Explained")
118                    .on_dismiss(with!(show_help => move || show_help.set(false)))
119                    .child(
120                        View::vstack()
121                            .child(View::styled_text("What you're seeing").bold().build())
122                            .child(View::text("• State<T> as a handle/pointer concept"))
123                            .child(View::text("• Multiple closures sharing one value"))
124                            .child(View::text("• Visual diagram of the mental model"))
125                            .child(View::gap(1))
126                            .child(View::styled_text("Key concepts").bold().build())
127                            .child(View::text("• clone() copies handle, not data"))
128                            .child(View::text("• All handles point to same underlying value"))
129                            .child(View::text(
130                                "• Hooks must be called in same order every render",
131                            ))
132                            .child(View::gap(1))
133                            .child(View::styled_text("Important rule").bold().build())
134                            .child(View::text("• NEVER put use_state inside an if block"))
135                            .child(View::text("• Use with!() macro to simplify cloning"))
136                            .child(View::gap(1))
137                            .child(View::styled_text("Next up").bold().build())
138                            .child(View::text("→ 11_checkbox: toggle controls"))
139                            .child(View::gap(1))
140                            .child(View::styled_text("Press Escape to close").dim().build())
141                            .build(),
142                    )
143                    .build(),
144            )
145            .build()
146    }
examples/32_effects.rs (line 80)
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    }

Trait Implementations§

Source§

impl Debug for HStackBuilder

Source§

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

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

impl Default for HStackBuilder

Source§

fn default() -> HStackBuilder

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.