typetui 0.2.1

A terminal-based typing test.
Documentation
pub mod profile;
pub mod results;
pub mod screens;
pub mod test;
pub mod theme;

use ratatui::Frame;
use ratatui::layout::Rect;
use ratatui::text::{Line, Span};
use ratatui::widgets::{Block, Borders, Clear, Paragraph};

use crate::ui::theme::Theme;

#[must_use]
pub fn centered_rect(percent_x: u16, percent_y: u16, area: Rect) -> Rect {
    let vertical_layout = ratatui::layout::Layout::default()
        .direction(ratatui::layout::Direction::Vertical)
        .constraints([
            ratatui::layout::Constraint::Percentage((100 - percent_y) / 2),
            ratatui::layout::Constraint::Percentage(percent_y),
            ratatui::layout::Constraint::Percentage((100 - percent_y) / 2),
        ])
        .split(area);

    let horizontal_layout = ratatui::layout::Layout::default()
        .direction(ratatui::layout::Direction::Horizontal)
        .constraints([
            ratatui::layout::Constraint::Percentage((100 - percent_x) / 2),
            ratatui::layout::Constraint::Percentage(percent_x),
            ratatui::layout::Constraint::Percentage((100 - percent_x) / 2),
        ])
        .split(vertical_layout[1]);

    horizontal_layout[1]
}

#[must_use]
pub fn help_text(theme: &Theme) -> Vec<Span<'static>> {
    vec![
        Span::styled("press ", theme.style_muted()),
        Span::styled("tab", theme.style_accent()),
        Span::styled(" to navigate, ", theme.style_muted()),
        Span::styled("enter", theme.style_accent()),
        Span::styled(" to select, ", theme.style_muted()),
        Span::styled("esc", theme.style_accent()),
        Span::styled(" to quit", theme.style_muted()),
    ]
}

pub fn render_help(f: &mut Frame, theme: &Theme, area: Rect) {
    let help_spans = help_text(theme);
    let help = Paragraph::new(Line::from(help_spans)).alignment(ratatui::layout::Alignment::Center);
    f.render_widget(help, area);
}

pub fn render_popup(f: &mut Frame, content: Paragraph<'_>, area: Rect) {
    let clear = Clear;
    f.render_widget(clear, area);
    f.render_widget(content, area);
}

#[must_use]
pub fn title_block<'a>(title: &'a str, theme: &'a Theme) -> Block<'a> {
    Block::default()
        .borders(Borders::ALL)
        .border_style(theme.style(theme.border))
        .title(Span::styled(title, theme.style_accent()))
        .title_alignment(ratatui::layout::Alignment::Center)
}

#[must_use]
pub fn key_hint<'a>(key: &'a str, action: &'a str, theme: &'a Theme) -> Span<'a> {
    Span::styled(format!(" {key}: {action} "), theme.style(theme.muted))
}