use crate::theme::Theme;
use ratatui::{
Frame,
layout::Rect,
style::{Modifier, Style},
text::{Line, Span},
widgets::{Block, Borders, Paragraph},
};
pub struct StatusInputParams<'a> {
pub label: &'a str,
pub label_color: ratatui::style::Color,
pub input: &'a str,
pub cursor_pos: usize,
pub placeholder: &'a str,
pub hint: &'a str,
}
pub fn draw_status_input(f: &mut Frame, area: Rect, params: &StatusInputParams<'_>, theme: &Theme) {
let cursor_style = Style::default().fg(theme.cursor_fg).bg(theme.cursor_bg);
let text_style = Style::default().fg(theme.text_normal);
let placeholder_style = Style::default().fg(theme.text_dim);
let hint_style = Style::default().fg(theme.text_dim);
let label_display = format!(" {} ", params.label);
let label_width = unicode_width::UnicodeWidthStr::width(label_display.as_str());
let mut spans = vec![Span::styled(
label_display,
Style::default()
.fg(params.label_color)
.add_modifier(Modifier::BOLD),
)];
if params.input.is_empty() {
spans.push(Span::styled(" ", cursor_style));
spans.push(Span::styled(
params.placeholder.to_string(),
placeholder_style,
));
} else {
let input_chars: Vec<char> = params.input.chars().collect();
for (i, ch) in input_chars.iter().enumerate() {
if i == params.cursor_pos {
spans.push(Span::styled(ch.to_string(), cursor_style));
} else {
spans.push(Span::styled(ch.to_string(), text_style));
}
}
if params.cursor_pos >= input_chars.len() {
spans.push(Span::styled(" ", cursor_style));
}
}
spans.push(Span::styled(format!(" {}", params.hint), hint_style));
let status = Paragraph::new(Line::from(spans)).block(
Block::default()
.borders(Borders::ALL)
.border_style(Style::default().fg(params.label_color)),
);
f.render_widget(status, area);
let cursor_x_offset = if params.input.is_empty() {
0
} else {
let chars_before_cursor: String = params.input.chars().take(params.cursor_pos).collect();
unicode_width::UnicodeWidthStr::width(chars_before_cursor.as_str())
};
let cursor_x = area.x + 1 + label_width as u16 + cursor_x_offset as u16;
let cursor_y = area.y + 1;
if cursor_x < area.x + area.width.saturating_sub(1) && cursor_y < area.y + area.height {
f.set_cursor_position((cursor_x, cursor_y));
}
}