Files
Cagire/crates/ratatui/src/text_input.rs

84 lines
2.3 KiB
Rust

use crate::theme::{input, ui};
use ratatui::layout::{Constraint, Layout, Rect};
use ratatui::style::{Color, Style};
use ratatui::text::{Line, Span};
use ratatui::widgets::Paragraph;
use ratatui::Frame;
use super::ModalFrame;
pub struct TextInputModal<'a> {
title: &'a str,
input: &'a str,
hint: Option<&'a str>,
border_color: Color,
width: u16,
}
impl<'a> TextInputModal<'a> {
pub fn new(title: &'a str, input: &'a str) -> Self {
Self {
title,
input,
hint: None,
border_color: ui::TEXT_PRIMARY,
width: 50,
}
}
pub fn hint(mut self, h: &'a str) -> Self {
self.hint = Some(h);
self
}
pub fn border_color(mut self, c: Color) -> Self {
self.border_color = c;
self
}
pub fn width(mut self, w: u16) -> Self {
self.width = w;
self
}
pub fn render_centered(self, frame: &mut Frame, term: Rect) {
let height = if self.hint.is_some() { 6 } else { 5 };
let inner = ModalFrame::new(self.title)
.width(self.width)
.height(height)
.border_color(self.border_color)
.render_centered(frame, term);
if self.hint.is_some() {
let rows =
Layout::vertical([Constraint::Length(1), Constraint::Length(1)]).split(inner);
frame.render_widget(
Paragraph::new(Line::from(vec![
Span::raw("> "),
Span::styled(self.input, Style::new().fg(input::TEXT)),
Span::styled("", Style::new().fg(input::CURSOR)),
])),
rows[0],
);
if let Some(hint) = self.hint {
frame.render_widget(
Paragraph::new(Span::styled(hint, Style::new().fg(input::HINT))),
rows[1],
);
}
} else {
frame.render_widget(
Paragraph::new(Line::from(vec![
Span::raw("> "),
Span::styled(self.input, Style::new().fg(input::TEXT)),
Span::styled("", Style::new().fg(input::CURSOR)),
])),
inner,
);
}
}
}