pub struct State<T> { /* private fields */ }Expand description
A reactive state handle that can be copied and shared.
State
Implementations§
Source§impl<T> State<T>
impl<T> State<T>
Sourcepub fn get(&self) -> Twhere
T: Clone,
pub fn get(&self) -> Twhere
T: Clone,
Get a clone of the current value.
Examples found in repository?
examples/01_hello_world.rs (line 40)
19 fn render(&self, cx: Scope) -> View {
20 let show_help = state!(cx, || false);
21
22 // F1 toggles help
23 cx.use_command(
24 KeyBinding::key(KeyCode::F(1)),
25 with!(show_help => move || show_help.update(|v| *v = !*v)),
26 );
27
28 View::vstack()
29 .child(View::styled_text("Hello World").bold().build())
30 .child(View::gap(1))
31 .child(View::text("Welcome to Telex!"))
32 .child(View::gap(1))
33 .child(
34 View::styled_text("F1 for help • Ctrl+Q to quit")
35 .dim()
36 .build(),
37 )
38 .child(
39 View::modal()
40 .visible(show_help.get())
41 .title("Example 01: Hello World")
42 .on_dismiss(with!(show_help => move || show_help.set(false)))
43 .child(
44 View::vstack()
45 .child(View::styled_text("What you're seeing").bold().build())
46 .child(View::text(
47 "• Basic app structure with struct + Component trait",
48 ))
49 .child(View::text(
50 "• View::text() and View::styled_text() for display",
51 ))
52 .child(View::text("• View::vstack() for vertical layout"))
53 .child(View::gap(1))
54 .child(View::styled_text("Key concepts").bold().build())
55 .child(View::text("• Every Telex app implements Component"))
56 .child(View::text("• render() returns a View tree"))
57 .child(View::text("• No state yet - this is purely static"))
58 .child(View::gap(1))
59 .child(View::styled_text("Next up").bold().build())
60 .child(View::text("→ 02_counter: add state and interactivity"))
61 .child(View::gap(1))
62 .child(View::styled_text("Press Escape to close").dim().build())
63 .build(),
64 )
65 .build(),
66 )
67 .build()
68 }More examples
examples/30_image.rs (line 54)
30 fn render(&self, cx: Scope) -> View {
31 let show_help = state!(cx, || false);
32
33 // F1 toggles help
34 cx.use_command(
35 KeyBinding::key(KeyCode::F(1)),
36 with!(show_help => move || show_help.update(|v| *v = !*v)),
37 );
38 View::vstack()
39 .spacing(1)
40 .child(
41 View::styled_text("Image Widget Demo (Kitty Graphics)")
42 .bold()
43 .build(),
44 )
45 .child(View::text("Requires Kitty, Ghostty, or WezTerm terminal"))
46 .child(View::text(""))
47 // Load image from file path
48 .child(View::text("Logo (from file path):"))
49 .child(View::image().file("assets/telex-tui.png").build())
50 .child(View::text(""))
51 .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
52 .child(
53 View::modal()
54 .visible(show_help.get())
55 .title("Example 30: Image")
56 .on_dismiss(with!(show_help => move || show_help.set(false)))
57 .child(
58 View::vstack()
59 .child(View::styled_text("What you're seeing").bold().build())
60 .child(View::text("• Image display via Kitty protocol"))
61 .child(View::text("• PNG/JPEG/GIF support"))
62 .child(View::text("• Loaded from file path"))
63 .child(View::gap(1))
64 .child(View::styled_text("Key concepts").bold().build())
65 .child(View::text("• View::image() displays images"))
66 .child(View::text("• .file(\"path\") loads from disk"))
67 .child(View::text("• .bytes(data) for embedded images"))
68 .child(View::text("• Works in Kitty/Ghostty/WezTerm"))
69 .child(View::gap(1))
70 .child(View::styled_text("Try this").bold().build())
71 .child(View::text("• Run in compatible terminal"))
72 .child(View::text("• See the Telex logo rendered"))
73 .child(View::gap(1))
74 .child(View::styled_text("Next up").bold().build())
75 .child(View::text("→ 31_animated_canvas: animations"))
76 .child(View::gap(1))
77 .child(View::styled_text("Press Escape to close").dim().build())
78 .build(),
79 )
80 .build(),
81 )
82 .build()
83 }examples/04_timer.rs (line 65)
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 = stream!(cx, || {
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("• stream!() macro 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 }examples/02_counter.rs (line 35)
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/19_status_bar.rs (line 78)
24 fn render(&self, cx: Scope) -> View {
25 let show_help = state!(cx, || false);
26
27 // F1 toggles help
28 cx.use_command(
29 KeyBinding::key(KeyCode::F(1)),
30 with!(show_help => move || show_help.update(|v| *v = !*v)),
31 );
32 View::vstack()
33 .child(View::styled_text("Status Bar Examples").bold().build())
34 .child(View::text(""))
35 .child(View::text("Basic status bar (left only):"))
36 .child(View::status_bar().left("NORMAL").build())
37 .child(View::text(""))
38 .child(View::text("Left and right sections:"))
39 .child(
40 View::status_bar()
41 .left("INSERT")
42 .right("Ln 42, Col 8")
43 .build(),
44 )
45 .child(View::text(""))
46 .child(View::text("All three sections:"))
47 .child(
48 View::status_bar()
49 .left("VISUAL")
50 .center("main.rs")
51 .right("UTF-8 | LF | Rust")
52 .build(),
53 )
54 .child(View::text(""))
55 .child(View::text("Custom colors (green on dark):"))
56 .child(
57 View::status_bar()
58 .left("SUCCESS")
59 .center("All tests passed")
60 .right("100%")
61 .fg(Color::Green)
62 .bg(Color::DarkGreen)
63 .build(),
64 )
65 .child(View::text(""))
66 .child(View::text("Editor-style status bar:"))
67 .child(
68 View::status_bar()
69 .left("-- INSERT --")
70 .center("~/projects/myapp/src/main.rs [+]")
71 .right("1/100 | 50%")
72 .build(),
73 )
74 .child(View::spacer())
75 .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
76 .child(
77 View::modal()
78 .visible(show_help.get())
79 .title("Example 19: Status Bar")
80 .on_dismiss(with!(show_help => move || show_help.set(false)))
81 .child(
82 View::vstack()
83 .child(View::styled_text("What you're seeing").bold().build())
84 .child(View::text("• Status bars with left/center/right sections"))
85 .child(View::text("• Custom foreground and background colors"))
86 .child(View::text("• Editor-style status line example"))
87 .child(View::gap(1))
88 .child(View::styled_text("Key concepts").bold().build())
89 .child(View::text("• View::status_bar() creates status lines"))
90 .child(View::text("• .left(), .center(), .right() for sections"))
91 .child(View::text("• .fg() and .bg() for custom colors"))
92 .child(View::text("• Great for showing mode, file info, etc."))
93 .child(View::gap(1))
94 .child(View::styled_text("Try this").bold().build())
95 .child(View::text("• Compare different status bar styles"))
96 .child(View::text("• Notice how sections align"))
97 .child(View::gap(1))
98 .child(View::styled_text("Next up").bold().build())
99 .child(View::text("→ 20_menu_bar: dropdown menus"))
100 .child(View::gap(1))
101 .child(View::styled_text("Press Escape to close").dim().build())
102 .build(),
103 )
104 .build(),
105 )
106 .build()
107 }examples/09_syntax_comparison.rs (line 34)
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}
157
158// =============================================================================
159// view! Macro (JSX-like)
160// =============================================================================
161// Concise, familiar to React/JSX users. Less boilerplate.
162// Good for: Rapid prototyping, simple layouts, JSX fans.
163
164fn counter_jsx(cx: Scope) -> View {
165 let count = state!(cx, || 0i32);
166
167 // with! works great with view! macro too
168 view! {
169 <VStack>
170 <StyledText color={Color::DarkGrey}>"// Built with view! macro + with!"</StyledText>
171 <Spacer />
172 <StyledText bold={true}>{format!("Count: {}", count.get())}</StyledText>
173 <Spacer />
174 <HStack>
175 <Button on_press={with!(count => move || count.update(|n| *n -= 1))}>" - "</Button>
176 <Text>" "</Text>
177 <Button on_press={with!(count => move || count.update(|n| *n += 1))}>" + "</Button>
178 </HStack>
179 </VStack>
180 }
181}Additional examples can be found in:
- examples/35_slider.rs
- examples/15_markdown.rs
- examples/18_progress_bar.rs
- examples/16_tree.rs
- examples/05_todo_list.rs
- examples/37_error_boundary.rs
- examples/38_custom_widget.rs
- examples/10_state_explained.rs
- examples/32_effects.rs
- examples/13_split_panes.rs
- examples/07_file_browser.rs
- examples/12_text_area.rs
- examples/06_log_viewer.rs
- examples/24_async_data.rs
- examples/34_channels_and_intervals.rs
- examples/08_system_monitor.rs
- examples/39_port.rs
- examples/25_context.rs
- examples/14_tabs.rs
- examples/11_checkbox.rs
- examples/17_table.rs
- examples/29_canvas.rs
- examples/20_menu_bar.rs
- examples/26_radio_buttons.rs
- examples/21_toasts.rs
- examples/36_reducer.rs
- examples/03_theme_switcher.rs
- examples/28_shared_state.rs
- examples/27_keyed_state.rs
- examples/31_animated_canvas.rs
- examples/22_forms.rs
- examples/23_modal.rs
Sourcepub fn set(&self, value: T)
pub fn set(&self, value: T)
Set a new value.
Examples found in repository?
examples/01_hello_world.rs (line 42)
19 fn render(&self, cx: Scope) -> View {
20 let show_help = state!(cx, || false);
21
22 // F1 toggles help
23 cx.use_command(
24 KeyBinding::key(KeyCode::F(1)),
25 with!(show_help => move || show_help.update(|v| *v = !*v)),
26 );
27
28 View::vstack()
29 .child(View::styled_text("Hello World").bold().build())
30 .child(View::gap(1))
31 .child(View::text("Welcome to Telex!"))
32 .child(View::gap(1))
33 .child(
34 View::styled_text("F1 for help • Ctrl+Q to quit")
35 .dim()
36 .build(),
37 )
38 .child(
39 View::modal()
40 .visible(show_help.get())
41 .title("Example 01: Hello World")
42 .on_dismiss(with!(show_help => move || show_help.set(false)))
43 .child(
44 View::vstack()
45 .child(View::styled_text("What you're seeing").bold().build())
46 .child(View::text(
47 "• Basic app structure with struct + Component trait",
48 ))
49 .child(View::text(
50 "• View::text() and View::styled_text() for display",
51 ))
52 .child(View::text("• View::vstack() for vertical layout"))
53 .child(View::gap(1))
54 .child(View::styled_text("Key concepts").bold().build())
55 .child(View::text("• Every Telex app implements Component"))
56 .child(View::text("• render() returns a View tree"))
57 .child(View::text("• No state yet - this is purely static"))
58 .child(View::gap(1))
59 .child(View::styled_text("Next up").bold().build())
60 .child(View::text("→ 02_counter: add state and interactivity"))
61 .child(View::gap(1))
62 .child(View::styled_text("Press Escape to close").dim().build())
63 .build(),
64 )
65 .build(),
66 )
67 .build()
68 }More examples
examples/30_image.rs (line 56)
30 fn render(&self, cx: Scope) -> View {
31 let show_help = state!(cx, || false);
32
33 // F1 toggles help
34 cx.use_command(
35 KeyBinding::key(KeyCode::F(1)),
36 with!(show_help => move || show_help.update(|v| *v = !*v)),
37 );
38 View::vstack()
39 .spacing(1)
40 .child(
41 View::styled_text("Image Widget Demo (Kitty Graphics)")
42 .bold()
43 .build(),
44 )
45 .child(View::text("Requires Kitty, Ghostty, or WezTerm terminal"))
46 .child(View::text(""))
47 // Load image from file path
48 .child(View::text("Logo (from file path):"))
49 .child(View::image().file("assets/telex-tui.png").build())
50 .child(View::text(""))
51 .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
52 .child(
53 View::modal()
54 .visible(show_help.get())
55 .title("Example 30: Image")
56 .on_dismiss(with!(show_help => move || show_help.set(false)))
57 .child(
58 View::vstack()
59 .child(View::styled_text("What you're seeing").bold().build())
60 .child(View::text("• Image display via Kitty protocol"))
61 .child(View::text("• PNG/JPEG/GIF support"))
62 .child(View::text("• Loaded from file path"))
63 .child(View::gap(1))
64 .child(View::styled_text("Key concepts").bold().build())
65 .child(View::text("• View::image() displays images"))
66 .child(View::text("• .file(\"path\") loads from disk"))
67 .child(View::text("• .bytes(data) for embedded images"))
68 .child(View::text("• Works in Kitty/Ghostty/WezTerm"))
69 .child(View::gap(1))
70 .child(View::styled_text("Try this").bold().build())
71 .child(View::text("• Run in compatible terminal"))
72 .child(View::text("• See the Telex logo rendered"))
73 .child(View::gap(1))
74 .child(View::styled_text("Next up").bold().build())
75 .child(View::text("→ 31_animated_canvas: animations"))
76 .child(View::gap(1))
77 .child(View::styled_text("Press Escape to close").dim().build())
78 .build(),
79 )
80 .build(),
81 )
82 .build()
83 }examples/04_timer.rs (line 67)
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 = stream!(cx, || {
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("• stream!() macro 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 }examples/02_counter.rs (line 64)
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/19_status_bar.rs (line 80)
24 fn render(&self, cx: Scope) -> View {
25 let show_help = state!(cx, || false);
26
27 // F1 toggles help
28 cx.use_command(
29 KeyBinding::key(KeyCode::F(1)),
30 with!(show_help => move || show_help.update(|v| *v = !*v)),
31 );
32 View::vstack()
33 .child(View::styled_text("Status Bar Examples").bold().build())
34 .child(View::text(""))
35 .child(View::text("Basic status bar (left only):"))
36 .child(View::status_bar().left("NORMAL").build())
37 .child(View::text(""))
38 .child(View::text("Left and right sections:"))
39 .child(
40 View::status_bar()
41 .left("INSERT")
42 .right("Ln 42, Col 8")
43 .build(),
44 )
45 .child(View::text(""))
46 .child(View::text("All three sections:"))
47 .child(
48 View::status_bar()
49 .left("VISUAL")
50 .center("main.rs")
51 .right("UTF-8 | LF | Rust")
52 .build(),
53 )
54 .child(View::text(""))
55 .child(View::text("Custom colors (green on dark):"))
56 .child(
57 View::status_bar()
58 .left("SUCCESS")
59 .center("All tests passed")
60 .right("100%")
61 .fg(Color::Green)
62 .bg(Color::DarkGreen)
63 .build(),
64 )
65 .child(View::text(""))
66 .child(View::text("Editor-style status bar:"))
67 .child(
68 View::status_bar()
69 .left("-- INSERT --")
70 .center("~/projects/myapp/src/main.rs [+]")
71 .right("1/100 | 50%")
72 .build(),
73 )
74 .child(View::spacer())
75 .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
76 .child(
77 View::modal()
78 .visible(show_help.get())
79 .title("Example 19: Status Bar")
80 .on_dismiss(with!(show_help => move || show_help.set(false)))
81 .child(
82 View::vstack()
83 .child(View::styled_text("What you're seeing").bold().build())
84 .child(View::text("• Status bars with left/center/right sections"))
85 .child(View::text("• Custom foreground and background colors"))
86 .child(View::text("• Editor-style status line example"))
87 .child(View::gap(1))
88 .child(View::styled_text("Key concepts").bold().build())
89 .child(View::text("• View::status_bar() creates status lines"))
90 .child(View::text("• .left(), .center(), .right() for sections"))
91 .child(View::text("• .fg() and .bg() for custom colors"))
92 .child(View::text("• Great for showing mode, file info, etc."))
93 .child(View::gap(1))
94 .child(View::styled_text("Try this").bold().build())
95 .child(View::text("• Compare different status bar styles"))
96 .child(View::text("• Notice how sections align"))
97 .child(View::gap(1))
98 .child(View::styled_text("Next up").bold().build())
99 .child(View::text("→ 20_menu_bar: dropdown menus"))
100 .child(View::gap(1))
101 .child(View::styled_text("Press Escape to close").dim().build())
102 .build(),
103 )
104 .build(),
105 )
106 .build()
107 }examples/09_syntax_comparison.rs (line 34)
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 }Additional examples can be found in:
- examples/35_slider.rs
- examples/15_markdown.rs
- examples/18_progress_bar.rs
- examples/16_tree.rs
- examples/05_todo_list.rs
- examples/37_error_boundary.rs
- examples/38_custom_widget.rs
- examples/10_state_explained.rs
- examples/32_effects.rs
- examples/13_split_panes.rs
- examples/07_file_browser.rs
- examples/12_text_area.rs
- examples/06_log_viewer.rs
- examples/24_async_data.rs
- examples/34_channels_and_intervals.rs
- examples/08_system_monitor.rs
- examples/39_port.rs
- examples/25_context.rs
- examples/14_tabs.rs
- examples/11_checkbox.rs
- examples/17_table.rs
- examples/29_canvas.rs
- examples/20_menu_bar.rs
- examples/26_radio_buttons.rs
- examples/21_toasts.rs
- examples/36_reducer.rs
- examples/03_theme_switcher.rs
- examples/28_shared_state.rs
- examples/27_keyed_state.rs
- examples/31_animated_canvas.rs
- examples/22_forms.rs
- examples/23_modal.rs
Sourcepub fn update(&self, f: impl FnOnce(&mut T))
pub fn update(&self, f: impl FnOnce(&mut T))
Update the value using a function.
Examples found in repository?
examples/01_hello_world.rs (line 25)
19 fn render(&self, cx: Scope) -> View {
20 let show_help = state!(cx, || false);
21
22 // F1 toggles help
23 cx.use_command(
24 KeyBinding::key(KeyCode::F(1)),
25 with!(show_help => move || show_help.update(|v| *v = !*v)),
26 );
27
28 View::vstack()
29 .child(View::styled_text("Hello World").bold().build())
30 .child(View::gap(1))
31 .child(View::text("Welcome to Telex!"))
32 .child(View::gap(1))
33 .child(
34 View::styled_text("F1 for help • Ctrl+Q to quit")
35 .dim()
36 .build(),
37 )
38 .child(
39 View::modal()
40 .visible(show_help.get())
41 .title("Example 01: Hello World")
42 .on_dismiss(with!(show_help => move || show_help.set(false)))
43 .child(
44 View::vstack()
45 .child(View::styled_text("What you're seeing").bold().build())
46 .child(View::text(
47 "• Basic app structure with struct + Component trait",
48 ))
49 .child(View::text(
50 "• View::text() and View::styled_text() for display",
51 ))
52 .child(View::text("• View::vstack() for vertical layout"))
53 .child(View::gap(1))
54 .child(View::styled_text("Key concepts").bold().build())
55 .child(View::text("• Every Telex app implements Component"))
56 .child(View::text("• render() returns a View tree"))
57 .child(View::text("• No state yet - this is purely static"))
58 .child(View::gap(1))
59 .child(View::styled_text("Next up").bold().build())
60 .child(View::text("→ 02_counter: add state and interactivity"))
61 .child(View::gap(1))
62 .child(View::styled_text("Press Escape to close").dim().build())
63 .build(),
64 )
65 .build(),
66 )
67 .build()
68 }More examples
examples/30_image.rs (line 36)
30 fn render(&self, cx: Scope) -> View {
31 let show_help = state!(cx, || false);
32
33 // F1 toggles help
34 cx.use_command(
35 KeyBinding::key(KeyCode::F(1)),
36 with!(show_help => move || show_help.update(|v| *v = !*v)),
37 );
38 View::vstack()
39 .spacing(1)
40 .child(
41 View::styled_text("Image Widget Demo (Kitty Graphics)")
42 .bold()
43 .build(),
44 )
45 .child(View::text("Requires Kitty, Ghostty, or WezTerm terminal"))
46 .child(View::text(""))
47 // Load image from file path
48 .child(View::text("Logo (from file path):"))
49 .child(View::image().file("assets/telex-tui.png").build())
50 .child(View::text(""))
51 .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
52 .child(
53 View::modal()
54 .visible(show_help.get())
55 .title("Example 30: Image")
56 .on_dismiss(with!(show_help => move || show_help.set(false)))
57 .child(
58 View::vstack()
59 .child(View::styled_text("What you're seeing").bold().build())
60 .child(View::text("• Image display via Kitty protocol"))
61 .child(View::text("• PNG/JPEG/GIF support"))
62 .child(View::text("• Loaded from file path"))
63 .child(View::gap(1))
64 .child(View::styled_text("Key concepts").bold().build())
65 .child(View::text("• View::image() displays images"))
66 .child(View::text("• .file(\"path\") loads from disk"))
67 .child(View::text("• .bytes(data) for embedded images"))
68 .child(View::text("• Works in Kitty/Ghostty/WezTerm"))
69 .child(View::gap(1))
70 .child(View::styled_text("Try this").bold().build())
71 .child(View::text("• Run in compatible terminal"))
72 .child(View::text("• See the Telex logo rendered"))
73 .child(View::gap(1))
74 .child(View::styled_text("Next up").bold().build())
75 .child(View::text("→ 31_animated_canvas: animations"))
76 .child(View::gap(1))
77 .child(View::styled_text("Press Escape to close").dim().build())
78 .build(),
79 )
80 .build(),
81 )
82 .build()
83 }examples/04_timer.rs (line 28)
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 = stream!(cx, || {
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("• stream!() macro 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 }examples/02_counter.rs (line 23)
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/19_status_bar.rs (line 30)
24 fn render(&self, cx: Scope) -> View {
25 let show_help = state!(cx, || false);
26
27 // F1 toggles help
28 cx.use_command(
29 KeyBinding::key(KeyCode::F(1)),
30 with!(show_help => move || show_help.update(|v| *v = !*v)),
31 );
32 View::vstack()
33 .child(View::styled_text("Status Bar Examples").bold().build())
34 .child(View::text(""))
35 .child(View::text("Basic status bar (left only):"))
36 .child(View::status_bar().left("NORMAL").build())
37 .child(View::text(""))
38 .child(View::text("Left and right sections:"))
39 .child(
40 View::status_bar()
41 .left("INSERT")
42 .right("Ln 42, Col 8")
43 .build(),
44 )
45 .child(View::text(""))
46 .child(View::text("All three sections:"))
47 .child(
48 View::status_bar()
49 .left("VISUAL")
50 .center("main.rs")
51 .right("UTF-8 | LF | Rust")
52 .build(),
53 )
54 .child(View::text(""))
55 .child(View::text("Custom colors (green on dark):"))
56 .child(
57 View::status_bar()
58 .left("SUCCESS")
59 .center("All tests passed")
60 .right("100%")
61 .fg(Color::Green)
62 .bg(Color::DarkGreen)
63 .build(),
64 )
65 .child(View::text(""))
66 .child(View::text("Editor-style status bar:"))
67 .child(
68 View::status_bar()
69 .left("-- INSERT --")
70 .center("~/projects/myapp/src/main.rs [+]")
71 .right("1/100 | 50%")
72 .build(),
73 )
74 .child(View::spacer())
75 .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
76 .child(
77 View::modal()
78 .visible(show_help.get())
79 .title("Example 19: Status Bar")
80 .on_dismiss(with!(show_help => move || show_help.set(false)))
81 .child(
82 View::vstack()
83 .child(View::styled_text("What you're seeing").bold().build())
84 .child(View::text("• Status bars with left/center/right sections"))
85 .child(View::text("• Custom foreground and background colors"))
86 .child(View::text("• Editor-style status line example"))
87 .child(View::gap(1))
88 .child(View::styled_text("Key concepts").bold().build())
89 .child(View::text("• View::status_bar() creates status lines"))
90 .child(View::text("• .left(), .center(), .right() for sections"))
91 .child(View::text("• .fg() and .bg() for custom colors"))
92 .child(View::text("• Great for showing mode, file info, etc."))
93 .child(View::gap(1))
94 .child(View::styled_text("Try this").bold().build())
95 .child(View::text("• Compare different status bar styles"))
96 .child(View::text("• Notice how sections align"))
97 .child(View::gap(1))
98 .child(View::styled_text("Next up").bold().build())
99 .child(View::text("→ 20_menu_bar: dropdown menus"))
100 .child(View::gap(1))
101 .child(View::styled_text("Press Escape to close").dim().build())
102 .build(),
103 )
104 .build(),
105 )
106 .build()
107 }examples/09_syntax_comparison.rs (line 31)
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}
157
158// =============================================================================
159// view! Macro (JSX-like)
160// =============================================================================
161// Concise, familiar to React/JSX users. Less boilerplate.
162// Good for: Rapid prototyping, simple layouts, JSX fans.
163
164fn counter_jsx(cx: Scope) -> View {
165 let count = state!(cx, || 0i32);
166
167 // with! works great with view! macro too
168 view! {
169 <VStack>
170 <StyledText color={Color::DarkGrey}>"// Built with view! macro + with!"</StyledText>
171 <Spacer />
172 <StyledText bold={true}>{format!("Count: {}", count.get())}</StyledText>
173 <Spacer />
174 <HStack>
175 <Button on_press={with!(count => move || count.update(|n| *n -= 1))}>" - "</Button>
176 <Text>" "</Text>
177 <Button on_press={with!(count => move || count.update(|n| *n += 1))}>" + "</Button>
178 </HStack>
179 </VStack>
180 }
181}Additional examples can be found in:
- examples/35_slider.rs
- examples/15_markdown.rs
- examples/18_progress_bar.rs
- examples/16_tree.rs
- examples/05_todo_list.rs
- examples/37_error_boundary.rs
- examples/38_custom_widget.rs
- examples/10_state_explained.rs
- examples/32_effects.rs
- examples/13_split_panes.rs
- examples/07_file_browser.rs
- examples/12_text_area.rs
- examples/06_log_viewer.rs
- examples/24_async_data.rs
- examples/34_channels_and_intervals.rs
- examples/08_system_monitor.rs
- examples/39_port.rs
- examples/25_context.rs
- examples/14_tabs.rs
- examples/11_checkbox.rs
- examples/17_table.rs
- examples/29_canvas.rs
- examples/20_menu_bar.rs
- examples/26_radio_buttons.rs
- examples/21_toasts.rs
- examples/36_reducer.rs
- examples/03_theme_switcher.rs
- examples/28_shared_state.rs
- examples/27_keyed_state.rs
- examples/31_animated_canvas.rs
- examples/22_forms.rs
- examples/23_modal.rs
Sourcepub fn clear_dirty(&self)
pub fn clear_dirty(&self)
Clear the dirty flag.
Trait Implementations§
Auto Trait Implementations§
impl<T> Freeze for State<T>
impl<T> !RefUnwindSafe for State<T>
impl<T> !Send for State<T>
impl<T> !Sync for State<T>
impl<T> Unpin for State<T>
impl<T> !UnwindSafe for State<T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
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>
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)
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)
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.