1use 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 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 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 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}