use ratatui::{
style::{Color, Modifier, Style},
widgets::{Block, BorderType, Borders},
};
pub const BORDER_FOCUSED: Color = Color::Cyan;
pub const BORDER_UNFOCUSED: Color = Color::Gray;
pub const BORDER_ERROR: Color = Color::Red;
pub const BORDER_WARNING: Color = Color::Yellow;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BlockVariant {
Focused,
Unfocused,
Error,
Warning,
}
pub const HIGHLIGHT_BG: Color = Color::DarkGray;
pub const HIGHLIGHT_SYMBOL: &str = "> ";
pub const NO_HIGHLIGHT_SYMBOL: &str = " ";
#[must_use]
pub fn block(title: &str, variant: BlockVariant) -> Block<'_> {
Block::default()
.title(title)
.borders(Borders::ALL)
.border_type(BorderType::Rounded)
.border_style(Style::default().fg(match variant {
BlockVariant::Focused => BORDER_FOCUSED,
BlockVariant::Unfocused => BORDER_UNFOCUSED,
BlockVariant::Error => BORDER_ERROR,
BlockVariant::Warning => BORDER_WARNING,
}))
}
#[must_use]
pub fn highlight_style(focused: bool) -> Style {
if focused {
Style::default()
.bg(HIGHLIGHT_BG)
.add_modifier(Modifier::BOLD)
} else {
Style::default()
}
}
#[must_use]
pub fn highlight_symbol(focused: bool) -> &'static str {
if focused {
HIGHLIGHT_SYMBOL
} else {
NO_HIGHLIGHT_SYMBOL
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn block_focused_has_cyan_border() {
let b = block("Test", BlockVariant::Focused);
assert_eq!(b.inner(ratatui::layout::Rect::new(0, 0, 10, 5)).width, 8);
}
#[test]
fn block_unfocused_has_gray_border() {
let b = block("Test", BlockVariant::Unfocused);
assert_eq!(b.inner(ratatui::layout::Rect::new(0, 0, 10, 5)).width, 8);
}
#[test]
fn block_error_has_red_border() {
let b = block("Error", BlockVariant::Error);
assert_eq!(b.inner(ratatui::layout::Rect::new(0, 0, 10, 5)).width, 8);
}
#[test]
fn block_warning_has_yellow_border() {
let b = block("Warning", BlockVariant::Warning);
assert_eq!(b.inner(ratatui::layout::Rect::new(0, 0, 10, 5)).width, 8);
}
#[test]
fn highlight_style_returns_bold_bg_when_focused() {
let style = highlight_style(true);
assert!(style.add_modifier.contains(Modifier::BOLD));
assert_eq!(style.bg, Some(HIGHLIGHT_BG));
}
#[test]
fn highlight_style_returns_default_when_unfocused() {
let style = highlight_style(false);
assert!(!style.add_modifier.contains(Modifier::BOLD));
assert_eq!(style.bg, None);
}
#[test]
fn highlight_symbol_returns_arrow_when_focused() {
assert_eq!(highlight_symbol(true), "> ");
}
#[test]
fn highlight_symbol_returns_spaces_when_unfocused() {
assert_eq!(highlight_symbol(false), " ");
}
}