pub struct CheckboxBuilder { /* private fields */ }Expand description
Builder for Checkbox views.
Implementations§
Source§impl CheckboxBuilder
impl CheckboxBuilder
pub fn new() -> Self
Sourcepub fn checked(self, checked: bool) -> Self
pub fn checked(self, checked: bool) -> Self
Examples found in repository?
examples/14_tabs.rs (line 93)
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 let active_tab = state!(cx, || 0usize);
32
33 // Settings state
34 let notifications = state!(cx, || true);
35 let dark_mode = state!(cx, || true);
36 let auto_save = state!(cx, || true);
37
38 let on_change = with!(active_tab => move |idx: usize| {
39 active_tab.set(idx);
40 });
41
42 // Checkbox handlers
43 let on_notifications = with!(notifications => move |checked: bool| {
44 notifications.set(checked);
45 });
46
47 let on_dark_mode = with!(dark_mode => move |checked: bool| {
48 dark_mode.set(checked);
49 if checked {
50 set_theme(Theme::dark());
51 } else {
52 set_theme(Theme::light());
53 }
54 });
55
56 let on_auto_save = with!(auto_save => move |checked: bool| {
57 auto_save.set(checked);
58 });
59
60 View::vstack()
61 .child(
62 View::styled_text("Tabbed Interface Demo")
63 .color(Color::Cyan)
64 .bold()
65 .build(),
66 )
67 .child(
68 View::boxed()
69 .flex(1)
70 .child(
71 View::tabs()
72 .tab(
73 "Overview",
74 View::vstack()
75 .child(View::styled_text("Welcome!").bold().build())
76 .child(View::text(
77 "\nThis is the Overview tab.\n\n\
78 Use the keyboard to switch tabs:\n\
79 - Left/Right arrows\n\
80 - [ and ] keys\n\
81 - Number keys 1-3",
82 ))
83 .build(),
84 )
85 .tab(
86 "Settings",
87 View::vstack()
88 .child(View::styled_text("Settings").bold().build())
89 .child(View::text(""))
90 .child(
91 View::checkbox()
92 .label("Enable notifications")
93 .checked(notifications.get())
94 .on_toggle(on_notifications)
95 .build(),
96 )
97 .child(
98 View::checkbox()
99 .label("Dark mode")
100 .checked(dark_mode.get())
101 .on_toggle(on_dark_mode)
102 .build(),
103 )
104 .child(
105 View::checkbox()
106 .label("Auto-save")
107 .checked(auto_save.get())
108 .on_toggle(on_auto_save)
109 .build(),
110 )
111 .build(),
112 )
113 .tab(
114 "About",
115 View::vstack()
116 .child(View::styled_text("About").bold().build())
117 .child(View::text(""))
118 .child(View::text("Telex TUI Framework"))
119 .child(View::text("Version: 0.2.1"))
120 .child(View::text(""))
121 .child(
122 View::styled_text("A React-style TUI framework for Rust")
123 .dim()
124 .build(),
125 )
126 .build(),
127 )
128 .active(active_tab.get())
129 .on_change(on_change)
130 .build(),
131 )
132 .build(),
133 )
134 .child(
135 View::styled_text("←→ or []: switch tabs | F1 help | Ctrl+Q: quit")
136 .dim()
137 .build(),
138 )
139 .child(
140 View::modal()
141 .visible(show_help.get())
142 .title("Example 14: Tabs")
143 .on_dismiss(with!(show_help => move || show_help.set(false)))
144 .child(
145 View::vstack()
146 .child(View::styled_text("What you're seeing").bold().build())
147 .child(View::text("• Tabbed interface with three tabs"))
148 .child(View::text("• Settings tab with checkboxes"))
149 .child(View::text("• Keyboard navigation between tabs"))
150 .child(View::gap(1))
151 .child(View::styled_text("Key concepts").bold().build())
152 .child(View::text("• View::tabs() creates tabbed container"))
153 .child(View::text("• .tab(\"Title\", content) adds each tab"))
154 .child(View::text("• .active() and .on_change() for state"))
155 .child(View::text("• Arrow keys, [ ], or 1-3 switch tabs"))
156 .child(View::gap(1))
157 .child(View::styled_text("Try this").bold().build())
158 .child(View::text("• Switch tabs with arrow keys"))
159 .child(View::text("• Toggle checkboxes in Settings"))
160 .child(View::text("• Try [ and ] keys for tab switching"))
161 .child(View::gap(1))
162 .child(View::styled_text("Next up").bold().build())
163 .child(View::text("→ 15_markdown: markdown rendering"))
164 .child(View::gap(1))
165 .child(View::styled_text("Press Escape to close").dim().build())
166 .build(),
167 )
168 .build(),
169 )
170 .build()
171 }More examples
examples/11_checkbox.rs (line 60)
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 }examples/27_keyed_state.rs (line 131)
42 fn render(&self, cx: Scope) -> View {
43 let show_help = state!(cx, || false);
44
45 // F1 toggles help
46 cx.use_command(
47 KeyBinding::key(KeyCode::F(1)),
48 with!(show_help => move || show_help.update(|v| *v = !*v)),
49 );
50
51 // Two independent toggles
52 let show_a = state!(cx, || true);
53 let show_b = state!(cx, || true);
54
55 // COUNTER A - state created inside conditional
56 let counter_a = if show_a.get() {
57 let count = state!(cx, || 0);
58 let inc = with!(count => move || count.update(|n| *n += 1));
59
60 View::hstack()
61 .spacing(1)
62 .child(
63 View::styled_text(format!("{}", count.get()))
64 .color(Color::Yellow)
65 .bold()
66 .build(),
67 )
68 .child(View::button().label("+").on_press(inc).build())
69 .build()
70 } else {
71 View::styled_text("--").dim().build()
72 };
73
74 // COUNTER B - state created inside a DIFFERENT conditional
75 let counter_b = if show_b.get() {
76 let count = state!(cx, || 0);
77 let inc = with!(count => move || count.update(|n| *n += 1));
78
79 View::hstack()
80 .spacing(1)
81 .child(
82 View::styled_text(format!("{}", count.get()))
83 .color(Color::Magenta)
84 .bold()
85 .build(),
86 )
87 .child(View::button().label("+").on_press(inc).build())
88 .build()
89 } else {
90 View::styled_text("--").dim().build()
91 };
92
93 let toggle_a = with!(show_a => move |_: bool| show_a.update(|b| *b = !*b));
94 let toggle_b = with!(show_b => move |_: bool| show_b.update(|b| *b = !*b));
95
96 View::vstack()
97 .spacing(1)
98 .child(
99 View::styled_text("state! Demo")
100 .color(Color::Cyan)
101 .bold()
102 .build(),
103 )
104 .child(View::gap(1))
105 .child(
106 View::hstack()
107 .spacing(2)
108 // Counter A box
109 .child(
110 View::boxed()
111 .border(true)
112 .padding(1)
113 .max_width(25)
114 .child(
115 View::vstack()
116 .child(View::styled_text("Counter A").bold().build())
117 .child(View::gap(1))
118 .child(
119 View::hstack()
120 .spacing(1)
121 .child(View::text("Value:"))
122 .child(counter_a)
123 .build(),
124 )
125 .child(
126 View::hstack()
127 .spacing(1)
128 .child(View::text("Show:"))
129 .child(
130 View::checkbox()
131 .checked(show_a.get())
132 .on_toggle(toggle_a)
133 .build(),
134 )
135 .build(),
136 )
137 .build(),
138 )
139 .build(),
140 )
141 // Counter B box
142 .child(
143 View::boxed()
144 .border(true)
145 .padding(1)
146 .max_width(25)
147 .child(
148 View::vstack()
149 .child(View::styled_text("Counter B").bold().build())
150 .child(View::gap(1))
151 .child(
152 View::hstack()
153 .spacing(1)
154 .child(View::text("Value:"))
155 .child(counter_b)
156 .build(),
157 )
158 .child(
159 View::hstack()
160 .spacing(1)
161 .child(View::text("Show:"))
162 .child(
163 View::checkbox()
164 .checked(show_b.get())
165 .on_toggle(toggle_b)
166 .build(),
167 )
168 .build(),
169 )
170 .build(),
171 )
172 .build(),
173 )
174 .build(),
175 )
176 .child(View::gap(1))
177 .child(View::styled_text("Try this:").bold().build())
178 .child(View::text(
179 " 1. Increment both counters to different values",
180 ))
181 .child(View::text(" 2. Hide counter A (uncheck its box)"))
182 .child(View::text(" 3. Counter B continues to work just fine!"))
183 .child(View::text(" 4. Show A again - it remembers its value"))
184 .child(View::gap(1))
185 .child(
186 View::styled_text("They don't interfere with each other.")
187 .color(Color::Green)
188 .build(),
189 )
190 .child(View::gap(1))
191 .child(
192 View::boxed()
193 .border(true)
194 .padding(1)
195 .child(
196 View::vstack()
197 .child(View::styled_text("The code:").bold().build())
198 .child(View::gap(1))
199 .child(
200 View::styled_text("if show_a.get() {")
201 .color(Color::DarkGrey)
202 .build(),
203 )
204 .child(
205 View::styled_text(" let count = state!(cx, || 0);")
206 .color(Color::Yellow)
207 .build(),
208 )
209 .child(View::styled_text("}").color(Color::DarkGrey).build())
210 .child(
211 View::styled_text("if show_b.get() {")
212 .color(Color::DarkGrey)
213 .build(),
214 )
215 .child(
216 View::styled_text(" let count = state!(cx, || 0);")
217 .color(Color::Magenta)
218 .build(),
219 )
220 .child(View::styled_text("}").color(Color::DarkGrey).build())
221 .child(View::gap(1))
222 .child(View::text("With use_state, hiding A would CRASH B"))
223 .child(View::text("(hook indices would shift)."))
224 .build(),
225 )
226 .build(),
227 )
228 .child(View::gap(1))
229 .child(
230 View::styled_text("Tab: navigate | F1 help | Ctrl+Q: quit")
231 .dim()
232 .build(),
233 )
234 .child(
235 View::modal()
236 .visible(show_help.get())
237 .title("Example 27: Keyed State")
238 .on_dismiss(with!(show_help => move || show_help.set(false)))
239 .child(
240 View::vstack()
241 .child(View::styled_text("What you're seeing").bold().build())
242 .child(View::text("• state! macro for order-independent hooks"))
243 .child(View::text("• Conditional state that doesn't crash"))
244 .child(View::text("• Two counters with hide/show toggles"))
245 .child(View::gap(1))
246 .child(View::styled_text("Key concepts").bold().build())
247 .child(View::text("• state!(cx, || init) creates keyed state"))
248 .child(View::text("• Each call site gets unique key"))
249 .child(View::text("• Safe to use inside if blocks"))
250 .child(View::text("• Values persist when hidden/shown"))
251 .child(View::gap(1))
252 .child(View::styled_text("Try this").bold().build())
253 .child(View::text("• Increment both counters"))
254 .child(View::text("• Hide counter A"))
255 .child(View::text("• Counter B still works!"))
256 .child(View::text("• Show A again - value preserved"))
257 .child(View::gap(1))
258 .child(View::styled_text("Next up").bold().build())
259 .child(View::text("→ 28_shared_state: shared state via keys"))
260 .child(View::gap(1))
261 .child(View::styled_text("Press Escape to close").dim().build())
262 .build(),
263 )
264 .build(),
265 )
266 .build()
267 }Sourcepub fn label(self, label: impl Into<String>) -> Self
pub fn label(self, label: impl Into<String>) -> Self
Examples found in repository?
examples/14_tabs.rs (line 92)
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 let active_tab = state!(cx, || 0usize);
32
33 // Settings state
34 let notifications = state!(cx, || true);
35 let dark_mode = state!(cx, || true);
36 let auto_save = state!(cx, || true);
37
38 let on_change = with!(active_tab => move |idx: usize| {
39 active_tab.set(idx);
40 });
41
42 // Checkbox handlers
43 let on_notifications = with!(notifications => move |checked: bool| {
44 notifications.set(checked);
45 });
46
47 let on_dark_mode = with!(dark_mode => move |checked: bool| {
48 dark_mode.set(checked);
49 if checked {
50 set_theme(Theme::dark());
51 } else {
52 set_theme(Theme::light());
53 }
54 });
55
56 let on_auto_save = with!(auto_save => move |checked: bool| {
57 auto_save.set(checked);
58 });
59
60 View::vstack()
61 .child(
62 View::styled_text("Tabbed Interface Demo")
63 .color(Color::Cyan)
64 .bold()
65 .build(),
66 )
67 .child(
68 View::boxed()
69 .flex(1)
70 .child(
71 View::tabs()
72 .tab(
73 "Overview",
74 View::vstack()
75 .child(View::styled_text("Welcome!").bold().build())
76 .child(View::text(
77 "\nThis is the Overview tab.\n\n\
78 Use the keyboard to switch tabs:\n\
79 - Left/Right arrows\n\
80 - [ and ] keys\n\
81 - Number keys 1-3",
82 ))
83 .build(),
84 )
85 .tab(
86 "Settings",
87 View::vstack()
88 .child(View::styled_text("Settings").bold().build())
89 .child(View::text(""))
90 .child(
91 View::checkbox()
92 .label("Enable notifications")
93 .checked(notifications.get())
94 .on_toggle(on_notifications)
95 .build(),
96 )
97 .child(
98 View::checkbox()
99 .label("Dark mode")
100 .checked(dark_mode.get())
101 .on_toggle(on_dark_mode)
102 .build(),
103 )
104 .child(
105 View::checkbox()
106 .label("Auto-save")
107 .checked(auto_save.get())
108 .on_toggle(on_auto_save)
109 .build(),
110 )
111 .build(),
112 )
113 .tab(
114 "About",
115 View::vstack()
116 .child(View::styled_text("About").bold().build())
117 .child(View::text(""))
118 .child(View::text("Telex TUI Framework"))
119 .child(View::text("Version: 0.2.1"))
120 .child(View::text(""))
121 .child(
122 View::styled_text("A React-style TUI framework for Rust")
123 .dim()
124 .build(),
125 )
126 .build(),
127 )
128 .active(active_tab.get())
129 .on_change(on_change)
130 .build(),
131 )
132 .build(),
133 )
134 .child(
135 View::styled_text("←→ or []: switch tabs | F1 help | Ctrl+Q: quit")
136 .dim()
137 .build(),
138 )
139 .child(
140 View::modal()
141 .visible(show_help.get())
142 .title("Example 14: Tabs")
143 .on_dismiss(with!(show_help => move || show_help.set(false)))
144 .child(
145 View::vstack()
146 .child(View::styled_text("What you're seeing").bold().build())
147 .child(View::text("• Tabbed interface with three tabs"))
148 .child(View::text("• Settings tab with checkboxes"))
149 .child(View::text("• Keyboard navigation between tabs"))
150 .child(View::gap(1))
151 .child(View::styled_text("Key concepts").bold().build())
152 .child(View::text("• View::tabs() creates tabbed container"))
153 .child(View::text("• .tab(\"Title\", content) adds each tab"))
154 .child(View::text("• .active() and .on_change() for state"))
155 .child(View::text("• Arrow keys, [ ], or 1-3 switch tabs"))
156 .child(View::gap(1))
157 .child(View::styled_text("Try this").bold().build())
158 .child(View::text("• Switch tabs with arrow keys"))
159 .child(View::text("• Toggle checkboxes in Settings"))
160 .child(View::text("• Try [ and ] keys for tab switching"))
161 .child(View::gap(1))
162 .child(View::styled_text("Next up").bold().build())
163 .child(View::text("→ 15_markdown: markdown rendering"))
164 .child(View::gap(1))
165 .child(View::styled_text("Press Escape to close").dim().build())
166 .build(),
167 )
168 .build(),
169 )
170 .build()
171 }More examples
examples/11_checkbox.rs (line 61)
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 }Sourcepub fn on_toggle(self, callback: impl Fn(bool) + 'static) -> Self
pub fn on_toggle(self, callback: impl Fn(bool) + 'static) -> Self
Examples found in repository?
examples/14_tabs.rs (line 94)
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 let active_tab = state!(cx, || 0usize);
32
33 // Settings state
34 let notifications = state!(cx, || true);
35 let dark_mode = state!(cx, || true);
36 let auto_save = state!(cx, || true);
37
38 let on_change = with!(active_tab => move |idx: usize| {
39 active_tab.set(idx);
40 });
41
42 // Checkbox handlers
43 let on_notifications = with!(notifications => move |checked: bool| {
44 notifications.set(checked);
45 });
46
47 let on_dark_mode = with!(dark_mode => move |checked: bool| {
48 dark_mode.set(checked);
49 if checked {
50 set_theme(Theme::dark());
51 } else {
52 set_theme(Theme::light());
53 }
54 });
55
56 let on_auto_save = with!(auto_save => move |checked: bool| {
57 auto_save.set(checked);
58 });
59
60 View::vstack()
61 .child(
62 View::styled_text("Tabbed Interface Demo")
63 .color(Color::Cyan)
64 .bold()
65 .build(),
66 )
67 .child(
68 View::boxed()
69 .flex(1)
70 .child(
71 View::tabs()
72 .tab(
73 "Overview",
74 View::vstack()
75 .child(View::styled_text("Welcome!").bold().build())
76 .child(View::text(
77 "\nThis is the Overview tab.\n\n\
78 Use the keyboard to switch tabs:\n\
79 - Left/Right arrows\n\
80 - [ and ] keys\n\
81 - Number keys 1-3",
82 ))
83 .build(),
84 )
85 .tab(
86 "Settings",
87 View::vstack()
88 .child(View::styled_text("Settings").bold().build())
89 .child(View::text(""))
90 .child(
91 View::checkbox()
92 .label("Enable notifications")
93 .checked(notifications.get())
94 .on_toggle(on_notifications)
95 .build(),
96 )
97 .child(
98 View::checkbox()
99 .label("Dark mode")
100 .checked(dark_mode.get())
101 .on_toggle(on_dark_mode)
102 .build(),
103 )
104 .child(
105 View::checkbox()
106 .label("Auto-save")
107 .checked(auto_save.get())
108 .on_toggle(on_auto_save)
109 .build(),
110 )
111 .build(),
112 )
113 .tab(
114 "About",
115 View::vstack()
116 .child(View::styled_text("About").bold().build())
117 .child(View::text(""))
118 .child(View::text("Telex TUI Framework"))
119 .child(View::text("Version: 0.2.1"))
120 .child(View::text(""))
121 .child(
122 View::styled_text("A React-style TUI framework for Rust")
123 .dim()
124 .build(),
125 )
126 .build(),
127 )
128 .active(active_tab.get())
129 .on_change(on_change)
130 .build(),
131 )
132 .build(),
133 )
134 .child(
135 View::styled_text("←→ or []: switch tabs | F1 help | Ctrl+Q: quit")
136 .dim()
137 .build(),
138 )
139 .child(
140 View::modal()
141 .visible(show_help.get())
142 .title("Example 14: Tabs")
143 .on_dismiss(with!(show_help => move || show_help.set(false)))
144 .child(
145 View::vstack()
146 .child(View::styled_text("What you're seeing").bold().build())
147 .child(View::text("• Tabbed interface with three tabs"))
148 .child(View::text("• Settings tab with checkboxes"))
149 .child(View::text("• Keyboard navigation between tabs"))
150 .child(View::gap(1))
151 .child(View::styled_text("Key concepts").bold().build())
152 .child(View::text("• View::tabs() creates tabbed container"))
153 .child(View::text("• .tab(\"Title\", content) adds each tab"))
154 .child(View::text("• .active() and .on_change() for state"))
155 .child(View::text("• Arrow keys, [ ], or 1-3 switch tabs"))
156 .child(View::gap(1))
157 .child(View::styled_text("Try this").bold().build())
158 .child(View::text("• Switch tabs with arrow keys"))
159 .child(View::text("• Toggle checkboxes in Settings"))
160 .child(View::text("• Try [ and ] keys for tab switching"))
161 .child(View::gap(1))
162 .child(View::styled_text("Next up").bold().build())
163 .child(View::text("→ 15_markdown: markdown rendering"))
164 .child(View::gap(1))
165 .child(View::styled_text("Press Escape to close").dim().build())
166 .build(),
167 )
168 .build(),
169 )
170 .build()
171 }More examples
examples/11_checkbox.rs (lines 62-69)
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 }examples/27_keyed_state.rs (line 132)
42 fn render(&self, cx: Scope) -> View {
43 let show_help = state!(cx, || false);
44
45 // F1 toggles help
46 cx.use_command(
47 KeyBinding::key(KeyCode::F(1)),
48 with!(show_help => move || show_help.update(|v| *v = !*v)),
49 );
50
51 // Two independent toggles
52 let show_a = state!(cx, || true);
53 let show_b = state!(cx, || true);
54
55 // COUNTER A - state created inside conditional
56 let counter_a = if show_a.get() {
57 let count = state!(cx, || 0);
58 let inc = with!(count => move || count.update(|n| *n += 1));
59
60 View::hstack()
61 .spacing(1)
62 .child(
63 View::styled_text(format!("{}", count.get()))
64 .color(Color::Yellow)
65 .bold()
66 .build(),
67 )
68 .child(View::button().label("+").on_press(inc).build())
69 .build()
70 } else {
71 View::styled_text("--").dim().build()
72 };
73
74 // COUNTER B - state created inside a DIFFERENT conditional
75 let counter_b = if show_b.get() {
76 let count = state!(cx, || 0);
77 let inc = with!(count => move || count.update(|n| *n += 1));
78
79 View::hstack()
80 .spacing(1)
81 .child(
82 View::styled_text(format!("{}", count.get()))
83 .color(Color::Magenta)
84 .bold()
85 .build(),
86 )
87 .child(View::button().label("+").on_press(inc).build())
88 .build()
89 } else {
90 View::styled_text("--").dim().build()
91 };
92
93 let toggle_a = with!(show_a => move |_: bool| show_a.update(|b| *b = !*b));
94 let toggle_b = with!(show_b => move |_: bool| show_b.update(|b| *b = !*b));
95
96 View::vstack()
97 .spacing(1)
98 .child(
99 View::styled_text("state! Demo")
100 .color(Color::Cyan)
101 .bold()
102 .build(),
103 )
104 .child(View::gap(1))
105 .child(
106 View::hstack()
107 .spacing(2)
108 // Counter A box
109 .child(
110 View::boxed()
111 .border(true)
112 .padding(1)
113 .max_width(25)
114 .child(
115 View::vstack()
116 .child(View::styled_text("Counter A").bold().build())
117 .child(View::gap(1))
118 .child(
119 View::hstack()
120 .spacing(1)
121 .child(View::text("Value:"))
122 .child(counter_a)
123 .build(),
124 )
125 .child(
126 View::hstack()
127 .spacing(1)
128 .child(View::text("Show:"))
129 .child(
130 View::checkbox()
131 .checked(show_a.get())
132 .on_toggle(toggle_a)
133 .build(),
134 )
135 .build(),
136 )
137 .build(),
138 )
139 .build(),
140 )
141 // Counter B box
142 .child(
143 View::boxed()
144 .border(true)
145 .padding(1)
146 .max_width(25)
147 .child(
148 View::vstack()
149 .child(View::styled_text("Counter B").bold().build())
150 .child(View::gap(1))
151 .child(
152 View::hstack()
153 .spacing(1)
154 .child(View::text("Value:"))
155 .child(counter_b)
156 .build(),
157 )
158 .child(
159 View::hstack()
160 .spacing(1)
161 .child(View::text("Show:"))
162 .child(
163 View::checkbox()
164 .checked(show_b.get())
165 .on_toggle(toggle_b)
166 .build(),
167 )
168 .build(),
169 )
170 .build(),
171 )
172 .build(),
173 )
174 .build(),
175 )
176 .child(View::gap(1))
177 .child(View::styled_text("Try this:").bold().build())
178 .child(View::text(
179 " 1. Increment both counters to different values",
180 ))
181 .child(View::text(" 2. Hide counter A (uncheck its box)"))
182 .child(View::text(" 3. Counter B continues to work just fine!"))
183 .child(View::text(" 4. Show A again - it remembers its value"))
184 .child(View::gap(1))
185 .child(
186 View::styled_text("They don't interfere with each other.")
187 .color(Color::Green)
188 .build(),
189 )
190 .child(View::gap(1))
191 .child(
192 View::boxed()
193 .border(true)
194 .padding(1)
195 .child(
196 View::vstack()
197 .child(View::styled_text("The code:").bold().build())
198 .child(View::gap(1))
199 .child(
200 View::styled_text("if show_a.get() {")
201 .color(Color::DarkGrey)
202 .build(),
203 )
204 .child(
205 View::styled_text(" let count = state!(cx, || 0);")
206 .color(Color::Yellow)
207 .build(),
208 )
209 .child(View::styled_text("}").color(Color::DarkGrey).build())
210 .child(
211 View::styled_text("if show_b.get() {")
212 .color(Color::DarkGrey)
213 .build(),
214 )
215 .child(
216 View::styled_text(" let count = state!(cx, || 0);")
217 .color(Color::Magenta)
218 .build(),
219 )
220 .child(View::styled_text("}").color(Color::DarkGrey).build())
221 .child(View::gap(1))
222 .child(View::text("With use_state, hiding A would CRASH B"))
223 .child(View::text("(hook indices would shift)."))
224 .build(),
225 )
226 .build(),
227 )
228 .child(View::gap(1))
229 .child(
230 View::styled_text("Tab: navigate | F1 help | Ctrl+Q: quit")
231 .dim()
232 .build(),
233 )
234 .child(
235 View::modal()
236 .visible(show_help.get())
237 .title("Example 27: Keyed State")
238 .on_dismiss(with!(show_help => move || show_help.set(false)))
239 .child(
240 View::vstack()
241 .child(View::styled_text("What you're seeing").bold().build())
242 .child(View::text("• state! macro for order-independent hooks"))
243 .child(View::text("• Conditional state that doesn't crash"))
244 .child(View::text("• Two counters with hide/show toggles"))
245 .child(View::gap(1))
246 .child(View::styled_text("Key concepts").bold().build())
247 .child(View::text("• state!(cx, || init) creates keyed state"))
248 .child(View::text("• Each call site gets unique key"))
249 .child(View::text("• Safe to use inside if blocks"))
250 .child(View::text("• Values persist when hidden/shown"))
251 .child(View::gap(1))
252 .child(View::styled_text("Try this").bold().build())
253 .child(View::text("• Increment both counters"))
254 .child(View::text("• Hide counter A"))
255 .child(View::text("• Counter B still works!"))
256 .child(View::text("• Show A again - value preserved"))
257 .child(View::gap(1))
258 .child(View::styled_text("Next up").bold().build())
259 .child(View::text("→ 28_shared_state: shared state via keys"))
260 .child(View::gap(1))
261 .child(View::styled_text("Press Escape to close").dim().build())
262 .build(),
263 )
264 .build(),
265 )
266 .build()
267 }Sourcepub fn build(self) -> View
pub fn build(self) -> View
Examples found in repository?
examples/14_tabs.rs (line 95)
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 let active_tab = state!(cx, || 0usize);
32
33 // Settings state
34 let notifications = state!(cx, || true);
35 let dark_mode = state!(cx, || true);
36 let auto_save = state!(cx, || true);
37
38 let on_change = with!(active_tab => move |idx: usize| {
39 active_tab.set(idx);
40 });
41
42 // Checkbox handlers
43 let on_notifications = with!(notifications => move |checked: bool| {
44 notifications.set(checked);
45 });
46
47 let on_dark_mode = with!(dark_mode => move |checked: bool| {
48 dark_mode.set(checked);
49 if checked {
50 set_theme(Theme::dark());
51 } else {
52 set_theme(Theme::light());
53 }
54 });
55
56 let on_auto_save = with!(auto_save => move |checked: bool| {
57 auto_save.set(checked);
58 });
59
60 View::vstack()
61 .child(
62 View::styled_text("Tabbed Interface Demo")
63 .color(Color::Cyan)
64 .bold()
65 .build(),
66 )
67 .child(
68 View::boxed()
69 .flex(1)
70 .child(
71 View::tabs()
72 .tab(
73 "Overview",
74 View::vstack()
75 .child(View::styled_text("Welcome!").bold().build())
76 .child(View::text(
77 "\nThis is the Overview tab.\n\n\
78 Use the keyboard to switch tabs:\n\
79 - Left/Right arrows\n\
80 - [ and ] keys\n\
81 - Number keys 1-3",
82 ))
83 .build(),
84 )
85 .tab(
86 "Settings",
87 View::vstack()
88 .child(View::styled_text("Settings").bold().build())
89 .child(View::text(""))
90 .child(
91 View::checkbox()
92 .label("Enable notifications")
93 .checked(notifications.get())
94 .on_toggle(on_notifications)
95 .build(),
96 )
97 .child(
98 View::checkbox()
99 .label("Dark mode")
100 .checked(dark_mode.get())
101 .on_toggle(on_dark_mode)
102 .build(),
103 )
104 .child(
105 View::checkbox()
106 .label("Auto-save")
107 .checked(auto_save.get())
108 .on_toggle(on_auto_save)
109 .build(),
110 )
111 .build(),
112 )
113 .tab(
114 "About",
115 View::vstack()
116 .child(View::styled_text("About").bold().build())
117 .child(View::text(""))
118 .child(View::text("Telex TUI Framework"))
119 .child(View::text("Version: 0.2.1"))
120 .child(View::text(""))
121 .child(
122 View::styled_text("A React-style TUI framework for Rust")
123 .dim()
124 .build(),
125 )
126 .build(),
127 )
128 .active(active_tab.get())
129 .on_change(on_change)
130 .build(),
131 )
132 .build(),
133 )
134 .child(
135 View::styled_text("←→ or []: switch tabs | F1 help | Ctrl+Q: quit")
136 .dim()
137 .build(),
138 )
139 .child(
140 View::modal()
141 .visible(show_help.get())
142 .title("Example 14: Tabs")
143 .on_dismiss(with!(show_help => move || show_help.set(false)))
144 .child(
145 View::vstack()
146 .child(View::styled_text("What you're seeing").bold().build())
147 .child(View::text("• Tabbed interface with three tabs"))
148 .child(View::text("• Settings tab with checkboxes"))
149 .child(View::text("• Keyboard navigation between tabs"))
150 .child(View::gap(1))
151 .child(View::styled_text("Key concepts").bold().build())
152 .child(View::text("• View::tabs() creates tabbed container"))
153 .child(View::text("• .tab(\"Title\", content) adds each tab"))
154 .child(View::text("• .active() and .on_change() for state"))
155 .child(View::text("• Arrow keys, [ ], or 1-3 switch tabs"))
156 .child(View::gap(1))
157 .child(View::styled_text("Try this").bold().build())
158 .child(View::text("• Switch tabs with arrow keys"))
159 .child(View::text("• Toggle checkboxes in Settings"))
160 .child(View::text("• Try [ and ] keys for tab switching"))
161 .child(View::gap(1))
162 .child(View::styled_text("Next up").bold().build())
163 .child(View::text("→ 15_markdown: markdown rendering"))
164 .child(View::gap(1))
165 .child(View::styled_text("Press Escape to close").dim().build())
166 .build(),
167 )
168 .build(),
169 )
170 .build()
171 }More examples
examples/11_checkbox.rs (line 70)
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 }examples/27_keyed_state.rs (line 133)
42 fn render(&self, cx: Scope) -> View {
43 let show_help = state!(cx, || false);
44
45 // F1 toggles help
46 cx.use_command(
47 KeyBinding::key(KeyCode::F(1)),
48 with!(show_help => move || show_help.update(|v| *v = !*v)),
49 );
50
51 // Two independent toggles
52 let show_a = state!(cx, || true);
53 let show_b = state!(cx, || true);
54
55 // COUNTER A - state created inside conditional
56 let counter_a = if show_a.get() {
57 let count = state!(cx, || 0);
58 let inc = with!(count => move || count.update(|n| *n += 1));
59
60 View::hstack()
61 .spacing(1)
62 .child(
63 View::styled_text(format!("{}", count.get()))
64 .color(Color::Yellow)
65 .bold()
66 .build(),
67 )
68 .child(View::button().label("+").on_press(inc).build())
69 .build()
70 } else {
71 View::styled_text("--").dim().build()
72 };
73
74 // COUNTER B - state created inside a DIFFERENT conditional
75 let counter_b = if show_b.get() {
76 let count = state!(cx, || 0);
77 let inc = with!(count => move || count.update(|n| *n += 1));
78
79 View::hstack()
80 .spacing(1)
81 .child(
82 View::styled_text(format!("{}", count.get()))
83 .color(Color::Magenta)
84 .bold()
85 .build(),
86 )
87 .child(View::button().label("+").on_press(inc).build())
88 .build()
89 } else {
90 View::styled_text("--").dim().build()
91 };
92
93 let toggle_a = with!(show_a => move |_: bool| show_a.update(|b| *b = !*b));
94 let toggle_b = with!(show_b => move |_: bool| show_b.update(|b| *b = !*b));
95
96 View::vstack()
97 .spacing(1)
98 .child(
99 View::styled_text("state! Demo")
100 .color(Color::Cyan)
101 .bold()
102 .build(),
103 )
104 .child(View::gap(1))
105 .child(
106 View::hstack()
107 .spacing(2)
108 // Counter A box
109 .child(
110 View::boxed()
111 .border(true)
112 .padding(1)
113 .max_width(25)
114 .child(
115 View::vstack()
116 .child(View::styled_text("Counter A").bold().build())
117 .child(View::gap(1))
118 .child(
119 View::hstack()
120 .spacing(1)
121 .child(View::text("Value:"))
122 .child(counter_a)
123 .build(),
124 )
125 .child(
126 View::hstack()
127 .spacing(1)
128 .child(View::text("Show:"))
129 .child(
130 View::checkbox()
131 .checked(show_a.get())
132 .on_toggle(toggle_a)
133 .build(),
134 )
135 .build(),
136 )
137 .build(),
138 )
139 .build(),
140 )
141 // Counter B box
142 .child(
143 View::boxed()
144 .border(true)
145 .padding(1)
146 .max_width(25)
147 .child(
148 View::vstack()
149 .child(View::styled_text("Counter B").bold().build())
150 .child(View::gap(1))
151 .child(
152 View::hstack()
153 .spacing(1)
154 .child(View::text("Value:"))
155 .child(counter_b)
156 .build(),
157 )
158 .child(
159 View::hstack()
160 .spacing(1)
161 .child(View::text("Show:"))
162 .child(
163 View::checkbox()
164 .checked(show_b.get())
165 .on_toggle(toggle_b)
166 .build(),
167 )
168 .build(),
169 )
170 .build(),
171 )
172 .build(),
173 )
174 .build(),
175 )
176 .child(View::gap(1))
177 .child(View::styled_text("Try this:").bold().build())
178 .child(View::text(
179 " 1. Increment both counters to different values",
180 ))
181 .child(View::text(" 2. Hide counter A (uncheck its box)"))
182 .child(View::text(" 3. Counter B continues to work just fine!"))
183 .child(View::text(" 4. Show A again - it remembers its value"))
184 .child(View::gap(1))
185 .child(
186 View::styled_text("They don't interfere with each other.")
187 .color(Color::Green)
188 .build(),
189 )
190 .child(View::gap(1))
191 .child(
192 View::boxed()
193 .border(true)
194 .padding(1)
195 .child(
196 View::vstack()
197 .child(View::styled_text("The code:").bold().build())
198 .child(View::gap(1))
199 .child(
200 View::styled_text("if show_a.get() {")
201 .color(Color::DarkGrey)
202 .build(),
203 )
204 .child(
205 View::styled_text(" let count = state!(cx, || 0);")
206 .color(Color::Yellow)
207 .build(),
208 )
209 .child(View::styled_text("}").color(Color::DarkGrey).build())
210 .child(
211 View::styled_text("if show_b.get() {")
212 .color(Color::DarkGrey)
213 .build(),
214 )
215 .child(
216 View::styled_text(" let count = state!(cx, || 0);")
217 .color(Color::Magenta)
218 .build(),
219 )
220 .child(View::styled_text("}").color(Color::DarkGrey).build())
221 .child(View::gap(1))
222 .child(View::text("With use_state, hiding A would CRASH B"))
223 .child(View::text("(hook indices would shift)."))
224 .build(),
225 )
226 .build(),
227 )
228 .child(View::gap(1))
229 .child(
230 View::styled_text("Tab: navigate | F1 help | Ctrl+Q: quit")
231 .dim()
232 .build(),
233 )
234 .child(
235 View::modal()
236 .visible(show_help.get())
237 .title("Example 27: Keyed State")
238 .on_dismiss(with!(show_help => move || show_help.set(false)))
239 .child(
240 View::vstack()
241 .child(View::styled_text("What you're seeing").bold().build())
242 .child(View::text("• state! macro for order-independent hooks"))
243 .child(View::text("• Conditional state that doesn't crash"))
244 .child(View::text("• Two counters with hide/show toggles"))
245 .child(View::gap(1))
246 .child(View::styled_text("Key concepts").bold().build())
247 .child(View::text("• state!(cx, || init) creates keyed state"))
248 .child(View::text("• Each call site gets unique key"))
249 .child(View::text("• Safe to use inside if blocks"))
250 .child(View::text("• Values persist when hidden/shown"))
251 .child(View::gap(1))
252 .child(View::styled_text("Try this").bold().build())
253 .child(View::text("• Increment both counters"))
254 .child(View::text("• Hide counter A"))
255 .child(View::text("• Counter B still works!"))
256 .child(View::text("• Show A again - value preserved"))
257 .child(View::gap(1))
258 .child(View::styled_text("Next up").bold().build())
259 .child(View::text("→ 28_shared_state: shared state via keys"))
260 .child(View::gap(1))
261 .child(View::styled_text("Press Escape to close").dim().build())
262 .build(),
263 )
264 .build(),
265 )
266 .build()
267 }Trait Implementations§
Source§impl Default for CheckboxBuilder
impl Default for CheckboxBuilder
Source§fn default() -> CheckboxBuilder
fn default() -> CheckboxBuilder
Returns the “default value” for a type. Read more
Auto Trait Implementations§
impl Freeze for CheckboxBuilder
impl !RefUnwindSafe for CheckboxBuilder
impl !Send for CheckboxBuilder
impl !Sync for CheckboxBuilder
impl Unpin for CheckboxBuilder
impl !UnwindSafe for CheckboxBuilder
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> 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.