pub fn set_theme(theme: Theme)Expand description
Set the current theme.
Examples found in repository?
examples/14_tabs.rs (line 15)
14fn main() {
15 set_theme(Theme::dark());
16 telex::run_with_theme(App, telex::theme::Theme::nord()).unwrap();
17}
18
19struct App;
20
21impl Component for App {
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/12_text_area.rs (line 45)
21 fn render(&self, cx: Scope) -> View {
22 let show_help = state!(cx, || false);
23 let theme_idx = state!(cx, || 0usize);
24
25 // F1 toggles help
26 cx.use_command(
27 KeyBinding::key(KeyCode::F(1)),
28 with!(show_help => move || show_help.update(|v| *v = !*v)),
29 );
30
31 // F2 cycles through themes
32 cx.use_command(
33 KeyBinding::key(KeyCode::F(2)),
34 with!(theme_idx => move || {
35 let next = (theme_idx.get() + 1) % 6;
36 theme_idx.set(next);
37 let theme = match next {
38 0 => Theme::nord(),
39 1 => Theme::dark(),
40 2 => Theme::light(),
41 3 => Theme::dracula(),
42 4 => Theme::gruvbox_dark(),
43 _ => Theme::catppuccin_mocha(),
44 };
45 set_theme(theme);
46 }),
47 );
48
49 let content = state!(cx, String::new);
50 let cursor_line = state!(cx, || 0usize);
51 let cursor_col = state!(cx, || 0usize);
52
53 // Track changes and cursor position
54 let on_change = with!(content => move |text: String| {
55 content.set(text);
56 });
57
58 let on_cursor_change = with!(cursor_line, cursor_col => move |line: usize, col: usize| {
59 cursor_line.set(line);
60 cursor_col.set(col);
61 });
62
63 // Calculate stats
64 let text = content.get();
65 let line_count = if text.is_empty() {
66 0
67 } else {
68 text.lines().count()
69 };
70 let char_count = text.chars().count();
71 let word_count = text.split_whitespace().count();
72
73 let theme_name = match theme_idx.get() {
74 0 => "Nord",
75 1 => "Dark",
76 2 => "Light",
77 3 => "Dracula",
78 4 => "Gruvbox Dark",
79 _ => "Catppuccin Mocha",
80 };
81
82 View::vstack()
83 .spacing(1)
84 .child(
85 View::hstack()
86 .child(View::styled_text("Notes").color(Color::Cyan).bold().build())
87 .child(View::spacer())
88 .child(View::styled_text(format!("Theme: {}", theme_name)).dim().build())
89 .build(),
90 )
91 .child(
92 View::styled_text("A simple multi-line text editor")
93 .dim()
94 .build(),
95 )
96 .child(View::gap(1))
97 .child(
98 View::text_area()
99 .value(content.get())
100 .placeholder("Start typing your notes here...")
101 .rows(12)
102 .cursor_line(cursor_line.get())
103 .cursor_col(cursor_col.get())
104 .on_change(on_change)
105 .on_cursor_change(on_cursor_change)
106 .build(),
107 )
108 .child(View::gap(1))
109 .child(
110 View::hstack()
111 .spacing(3)
112 .child(
113 View::styled_text(format!("Lines: {}", line_count))
114 .color(Color::DarkGrey)
115 .build(),
116 )
117 .child(
118 View::styled_text(format!("Words: {}", word_count))
119 .color(Color::DarkGrey)
120 .build(),
121 )
122 .child(
123 View::styled_text(format!("Chars: {}", char_count))
124 .color(Color::DarkGrey)
125 .build(),
126 )
127 .build(),
128 )
129 .child(View::gap(1))
130 .child(View::styled_text("F1 help • F2 theme • Ctrl+Q quit").dim().build())
131 .child(
132 View::modal()
133 .visible(show_help.get())
134 .title("Example 12: TextArea")
135 .on_dismiss(with!(show_help => move || show_help.set(false)))
136 .child(
137 View::vstack()
138 .child(View::styled_text("What you're seeing").bold().build())
139 .child(View::text("• Multi-line text editing with TextArea"))
140 .child(View::text("• Real-time line/word/char counts"))
141 .child(View::text("• Cursor position tracking"))
142 .child(View::gap(1))
143 .child(View::styled_text("Key concepts").bold().build())
144 .child(View::text("• View::text_area() for multi-line input"))
145 .child(View::text("• on_change callback for text updates"))
146 .child(View::text("• on_cursor_change for cursor tracking"))
147 .child(View::text("• placeholder text when empty"))
148 .child(View::gap(1))
149 .child(View::styled_text("Try this").bold().build())
150 .child(View::text("• Type multiple lines of text"))
151 .child(View::text("• Watch the stats update in real-time"))
152 .child(View::text("• Use arrow keys to navigate"))
153 .child(View::gap(1))
154 .child(View::styled_text("Next up").bold().build())
155 .child(View::text("→ 13_split_panes: resizable panel layouts"))
156 .child(View::gap(1))
157 .child(View::styled_text("Press Escape to close").dim().build())
158 .build(),
159 )
160 .build(),
161 )
162 .build()
163 }examples/11_checkbox.rs (line 65)
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/03_theme_switcher.rs (line 66)
20 fn render(&self, cx: Scope) -> View {
21 let selected = state!(cx, || 0usize);
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 let theme_names = vec![
31 "Dark".to_string(),
32 "Light".to_string(),
33 "Nord".to_string(),
34 "Monokai".to_string(),
35 "Catppuccin Mocha".to_string(),
36 "Catppuccin Latte".to_string(),
37 "Dracula".to_string(),
38 "Gruvbox Dark".to_string(),
39 "Solarized Dark".to_string(),
40 "Rosé Pine".to_string(),
41 "Tokyo Night".to_string(),
42 "HaX0R Blue".to_string(),
43 "HaX0R Green".to_string(),
44 "HaX0R Red".to_string(),
45 ];
46
47 // Apply theme when selection changes
48 let on_select = with!(selected => move |idx: usize| {
49 selected.set(idx);
50 let theme = match idx {
51 0 => Theme::dark(),
52 1 => Theme::light(),
53 2 => Theme::nord(),
54 3 => Theme::monokai(),
55 4 => Theme::catppuccin_mocha(),
56 5 => Theme::catppuccin_latte(),
57 6 => Theme::dracula(),
58 7 => Theme::gruvbox_dark(),
59 8 => Theme::solarized_dark(),
60 9 => Theme::rose_pine(),
61 10 => Theme::tokyo_night(),
62 11 => Theme::hax0r_blue(),
63 12 => Theme::hax0r_green(),
64 _ => Theme::hax0r_red(),
65 };
66 set_theme(theme);
67 });
68
69 let theme = current_theme();
70 let true_color = supports_true_color();
71
72 let mut stack = View::vstack();
73
74 // Show warning if true color isn't supported
75 if !true_color {
76 let term = terminal_name().unwrap_or_else(|| "Unknown".to_string());
77 stack = stack
78 .child(
79 View::styled_text(format!("Warning: {} doesn't support true color", term))
80 .color(theme.warning)
81 .bold()
82 .build(),
83 )
84 .child(
85 View::styled_text("Only 'Dark' and 'Light' themes will display correctly")
86 .color(theme.muted)
87 .build(),
88 )
89 .child(View::gap(1));
90 }
91
92 stack
93 .child(
94 View::styled_text("Theme Switcher")
95 .color(theme.primary)
96 .bold()
97 .build(),
98 )
99 .child(
100 View::styled_text("Select a theme from the list")
101 .color(theme.muted)
102 .italic()
103 .build(),
104 )
105 .child(View::gap(1))
106 .child(
107 View::hstack()
108 .spacing(2)
109 .child(
110 View::boxed()
111 .border(true)
112 .min_width(25)
113 .child(
114 View::list()
115 .items(theme_names)
116 .selected(selected.get())
117 .on_select(on_select)
118 .build(),
119 )
120 .build(),
121 )
122 .child(
123 View::boxed()
124 .border(true)
125 .padding(1)
126 .child(
127 View::vstack()
128 .child(View::styled_text("Preview").bold().build())
129 .child(View::gap(1))
130 .child(
131 View::hstack()
132 .child(
133 View::styled_text("Primary")
134 .color(theme.primary)
135 .build(),
136 )
137 .child(View::text(" "))
138 .child(
139 View::styled_text("Secondary")
140 .color(theme.secondary)
141 .build(),
142 )
143 .build(),
144 )
145 .child(
146 View::hstack()
147 .child(
148 View::styled_text("Muted")
149 .color(theme.muted)
150 .build(),
151 )
152 .child(View::text(" "))
153 .child(
154 View::styled_text("Success")
155 .color(theme.success)
156 .build(),
157 )
158 .build(),
159 )
160 .child(
161 View::hstack()
162 .child(
163 View::styled_text("Warning")
164 .color(theme.warning)
165 .build(),
166 )
167 .child(View::text(" "))
168 .child(
169 View::styled_text("Error")
170 .color(theme.error)
171 .build(),
172 )
173 .build(),
174 )
175 .build(),
176 )
177 .build(),
178 )
179 .build(),
180 )
181 .child(View::gap(1))
182 .child(
183 View::styled_text("↑/↓ select • F1 help • Ctrl+Q quit")
184 .color(theme.muted)
185 .build(),
186 )
187 .child(
188 View::modal()
189 .visible(show_help.get())
190 .title("Example 03: Theme Switcher")
191 .on_dismiss(with!(show_help => move || show_help.set(false)))
192 .child(
193 View::vstack()
194 .child(View::styled_text("What you're seeing").bold().build())
195 .child(View::text("• Built-in theme system with 14 themes"))
196 .child(View::text("• View::list() for selection UI"))
197 .child(View::text("• Live preview as you navigate"))
198 .child(View::gap(1))
199 .child(View::styled_text("Key concepts").bold().build())
200 .child(View::text("• current_theme() gets active theme colors"))
201 .child(View::text("• set_theme() changes theme globally"))
202 .child(View::text(
203 "• Themes provide semantic colors (primary, error, etc.)",
204 ))
205 .child(View::gap(1))
206 .child(View::styled_text("Try this").bold().build())
207 .child(View::text(
208 "• Navigate with ↑/↓ to see themes change instantly",
209 ))
210 .child(View::text(
211 "• Notice the preview panel updates with theme colors",
212 ))
213 .child(View::gap(1))
214 .child(View::styled_text("Next up").bold().build())
215 .child(View::text("→ 04_timer: streaming data without interaction"))
216 .child(View::gap(1))
217 .child(View::styled_text("Press Escape to close").dim().build())
218 .build(),
219 )
220 .build(),
221 )
222 .build()
223 }