use crate::tui::theme::Theme;
use ratatui::{
style::Style,
text::{Line, Span},
};
pub fn add_section_header(lines: &mut Vec<Line<'static>>, title: &str, theme: &Theme) {
lines.push(Line::from(vec![Span::styled(
title.to_string(),
Style::default().fg(theme.muted),
)]));
}
pub fn add_label_value(
lines: &mut Vec<Line<'static>>,
label: &str,
value: String,
theme: &Theme,
width: u16,
) {
const INDENT: usize = 2;
const LABEL_WIDTH: usize = 24; const GAP: usize = 4; const VALUE_COLUMN: usize = LABEL_WIDTH + GAP;
let label_with_indent = format!("{}{}", " ".repeat(INDENT), label);
let padded_label = format!("{:width$}", label_with_indent, width = LABEL_WIDTH);
let gap = " ".repeat(GAP);
let value_width = width.saturating_sub(VALUE_COLUMN as u16) as usize;
let value_lines = wrap_text(&value, value_width);
if let Some(first_line) = value_lines.first() {
lines.push(Line::from(vec![
Span::raw(padded_label),
Span::raw(gap),
Span::styled(first_line.clone(), Style::default().fg(theme.primary)),
]));
}
let continuation_indent = " ".repeat(VALUE_COLUMN);
for continuation in value_lines.iter().skip(1) {
lines.push(Line::from(vec![
Span::raw(continuation_indent.clone()),
Span::styled(continuation.clone(), Style::default().fg(theme.primary)),
]));
}
}
fn wrap_text(text: &str, width: usize) -> Vec<String> {
if width == 0 {
return vec![text.to_string()];
}
let mut result = Vec::new();
let mut current_line = String::new();
for word in text.split_whitespace() {
let potential_len = if current_line.is_empty() {
word.len()
} else {
current_line.len() + 1 + word.len() };
if potential_len <= width {
if !current_line.is_empty() {
current_line.push(' ');
}
current_line.push_str(word);
} else {
if !current_line.is_empty() {
result.push(current_line.clone());
current_line.clear();
}
current_line.push_str(word);
}
}
if !current_line.is_empty() {
result.push(current_line);
}
if result.is_empty() {
result.push(String::new());
}
result
}
pub fn add_list_section(
lines: &mut Vec<Line<'static>>,
title: &str,
items: &[String],
max_display: usize,
theme: &Theme,
) {
if items.is_empty() {
return; }
lines.push(Line::from(vec![Span::raw(format!(
"{} ({})",
title,
items.len()
))]));
let display_count = items.len().min(max_display);
for item in &items[..display_count] {
lines.push(Line::from(vec![
Span::raw(" "),
Span::styled(item.clone(), Style::default().fg(theme.secondary())),
]));
}
if items.len() > max_display {
lines.push(Line::from(vec![
Span::raw(" "),
Span::styled(
format!("... {} more", items.len() - max_display),
Style::default().fg(theme.muted),
),
]));
}
lines.push(Line::from("")); }
pub fn add_blank_line(lines: &mut Vec<Line<'static>>) {
lines.push(Line::from(""));
}