Orhun Parmaksız ed5dd73084
docs(widgets): add example for tabs (#1559)
related #1512 

Also removes the tabs example from ratatui crate since it overlaps with
this new example in terms of functionality and it was not following the
general theme of other examples.
2024-12-09 15:22:03 -08:00

93 lines
3.2 KiB
Rust

//! # [Ratatui] `Tabs` example
//!
//! The latest version of this example is available in the [widget examples] folder in the
//! repository.
//!
//! Please note that the examples are designed to be run against the `main` branch of the Github
//! repository. This means that you may not be able to compile with the latest release version on
//! crates.io, or the one that you have installed locally.
//!
//! See the [examples readme] for more information on finding examples that match the version of the
//! library you are using.
//!
//! [Ratatui]: https://github.com/ratatui/ratatui
//! [widget examples]: https://github.com/ratatui/ratatui/blob/main/ratatui-widgets/examples
//! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md
use color_eyre::Result;
use ratatui::{
crossterm::event::{self, Event, KeyCode},
layout::{Alignment, Constraint, Layout, Offset, Rect},
style::{Color, Style, Stylize},
symbols,
text::{Line, Span},
widgets::{Block, Paragraph, Tabs},
DefaultTerminal, Frame,
};
fn main() -> Result<()> {
color_eyre::install()?;
let terminal = ratatui::init();
let result = run(terminal);
ratatui::restore();
result
}
/// Run the application.
fn run(mut terminal: DefaultTerminal) -> Result<()> {
let mut selected_tab = 0;
loop {
terminal.draw(|frame| draw(frame, selected_tab))?;
if let Event::Key(key) = event::read()? {
match key.code {
KeyCode::Char('q') => break Ok(()),
KeyCode::Right | KeyCode::Char('l') | KeyCode::Tab => {
selected_tab = (selected_tab + 1) % 3;
}
KeyCode::Left | KeyCode::Char('h') => selected_tab = (selected_tab + 2) % 3,
_ => {}
}
}
}
}
/// Draw the UI with tabs.
fn draw(frame: &mut Frame, selected_tab: usize) {
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]).spacing(1);
let [top, main] = vertical.areas(frame.area());
let title = Line::from_iter([
Span::from("Tabs Widget").bold(),
Span::from(" (Press 'q' to quit, arrow keys to navigate tabs)"),
]);
frame.render_widget(title.centered(), top);
render_content(frame, main, selected_tab);
render_tabs(frame, main.offset(Offset { x: 1, y: 0 }), selected_tab);
}
/// Render the tabs.
pub fn render_tabs(frame: &mut Frame, area: Rect, selected_tab: usize) {
let tabs = Tabs::new(vec!["Tab1", "Tab2", "Tab3"])
.style(Color::White)
.highlight_style(Style::default().magenta().on_black().bold())
.select(selected_tab)
.divider(symbols::DOT)
.padding(" ", " ");
frame.render_widget(tabs, area);
}
/// Render the tab content.
pub fn render_content(frame: &mut Frame, area: Rect, selected_tab: usize) {
let text = match selected_tab {
0 => "Great terminal interfaces start with a single widget.".into(),
1 => "In the terminal, we don't just render widgets; we create dreams.".into(),
2 => "Render boldly, style with purpose.".bold(),
_ => unreachable!(),
};
let block = Paragraph::new(text)
.alignment(Alignment::Center)
.block(Block::bordered());
frame.render_widget(block, area);
}