Skip to main content

14_tabs/
14_tabs.rs

1//! Example 14: Tabs
2//!
3//! Demonstrates the Tabs widget for tabbed interfaces.
4//!
5//! Run with: cargo run -p telex-tui --example 14_tabs
6
7use crossterm::event::KeyCode;
8use crossterm::style::Color;
9use telex::prelude::*;
10use telex::theme::{set_theme, Theme};
11
12telex::require_api!(0, 2);
13
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    }
172}