use ratatui::Frame;
use ratatui::layout::Rect;
use ratatui::style::{Modifier, Style};
use ratatui::text::{Line, Span};
use ratatui::widgets::{Block, BorderType, Borders, Paragraph};
use crate::ui::theme;
pub fn modal_panel(title: impl AsRef<str>) -> Block<'static> {
let t = theme::cur();
let block = Block::default()
.borders(Borders::ALL)
.border_type(BorderType::Plain)
.border_style(Style::default().fg(t.fg).bg(t.bg_dark))
.style(Style::default().fg(t.fg).bg(t.bg_dark));
let title = title.as_ref().trim();
if title.is_empty() {
block
} else {
block.title(Span::styled(
format!(" {title} "),
Style::default()
.fg(t.bg_dark)
.bg(t.cyan)
.add_modifier(Modifier::BOLD),
))
}
}
pub fn bordered_plain(title: impl AsRef<str>) -> Block<'static> {
let t = theme::cur();
let block = Block::default()
.borders(Borders::ALL)
.border_type(BorderType::Plain)
.border_style(Style::default().fg(t.bg3).bg(t.bg_dark))
.style(Style::default().fg(t.fg).bg(t.bg_dark));
let title = title.as_ref().trim();
if title.is_empty() {
block
} else {
block.title(Span::styled(
format!(" {title} "),
Style::default().fg(t.comment).bg(t.bg_dark),
))
}
}
pub fn popup_menu(title: impl AsRef<str>) -> Block<'static> {
let t = theme::cur();
let block = Block::default()
.borders(Borders::ALL)
.border_type(BorderType::Plain)
.style(Style::default().fg(t.fg).bg(t.bg2));
let title = title.as_ref().trim();
if title.is_empty() {
block
} else {
block.title(Span::styled(
format!(" {title} "),
Style::default().fg(t.comment).add_modifier(Modifier::BOLD),
))
}
}
pub fn popup_panel(title: impl AsRef<str>) -> Block<'static> {
let t = theme::cur();
let block = Block::default()
.borders(Borders::ALL)
.border_type(BorderType::Rounded)
.border_style(Style::default().fg(t.blue).bg(t.bg_darker))
.style(Style::default().fg(t.fg).bg(t.bg_darker));
let title = title.as_ref().trim();
if title.is_empty() {
block
} else {
block.title(Span::styled(
format!(" {title} "),
Style::default()
.fg(t.blue)
.bg(t.bg_darker)
.add_modifier(Modifier::BOLD),
))
}
}
pub fn hint_style() -> Style {
let t = theme::cur();
Style::default().fg(t.comment).bg(t.bg_dark)
}
pub fn row_highlight_menu() -> Style {
let t = theme::cur();
Style::default()
.fg(t.bg_dark)
.bg(t.cyan)
.add_modifier(Modifier::BOLD)
}
pub fn row_plain_menu() -> Style {
let t = theme::cur();
Style::default().fg(t.fg).bg(t.bg2)
}
pub fn paint_hint_row(frame: &mut Frame, inner: Rect, hint: &str) {
if inner.width == 0 || inner.height == 0 {
return;
}
let y = inner.y + inner.height.saturating_sub(1);
let row = Rect {
x: inner.x,
y,
width: inner.width,
height: 1,
};
let pad = inner.width.saturating_sub(hint.chars().count() as u16) / 2;
frame.render_widget(
Paragraph::new(Line::from(Span::styled(
format!("{}{hint}", " ".repeat(pad as usize)),
hint_style(),
))),
row,
);
}
pub fn chip_bar_span(glyph: impl AsRef<str>, active: bool) -> Span<'static> {
let t = theme::cur();
let fg = if active { t.cyan } else { t.comment };
Span::styled(
format!(" {} ", glyph.as_ref()),
Style::default().fg(fg).bg(t.bg_dark),
)
}