use ratatui::buffer::Buffer;
use ratatui::layout::Constraint;
use ratatui::layout::Layout;
use ratatui::layout::Rect;
use ratatui::style::Color;
use ratatui::style::Style;
use ratatui::text::Text;
use ratatui::widgets::Clear;
use ratatui::widgets::StatefulWidget;
use ratatui::widgets::Widget;
use crate::widgets::InputWidget;
use crate::widgets::ListWidget;
use super::InputSelectState;
pub struct InputSelectWidget
{
style: Style,
}
impl std::default::Default for InputSelectWidget
{
fn default() -> Self
{
Self::new()
}
}
impl InputSelectWidget
{
pub fn new() -> Self
{
Self {
style: Style::default(),
}
}
pub fn style<S: Into<Style>>(
mut self,
style: S,
) -> Self
{
self.style = style.into();
self
}
}
impl StatefulWidget for InputSelectWidget
{
type State = InputSelectState;
fn render(
self,
area: Rect,
buf: &mut Buffer,
state: &mut Self::State,
)
{
Clear.render(
area, buf,
);
let style = if state.is_valid()
{
Style::new().bg(Color::DarkGray)
}
else
{
Style::new().bg(Color::Red)
};
let label_length: u16 = state
.label
.clone()
.and_then(
|s| {
s.chars()
.count()
.try_into()
.ok()
},
)
.unwrap_or(0);
let [label_area, input_area] =
Layout::horizontal([Constraint::Length(label_length), Constraint::Fill(1)]).areas(area);
if let Some(label) = state
.label
.as_ref()
{
Text::raw(label).render(
label_area, buf,
);
}
InputWidget::new()
.style(style)
.render(
input_area,
buf,
&mut state.input,
);
let height = state
.input_options
.items()
.len()
.min(state.items_shown as usize);
let mut selection_area = input_area;
selection_area.y += 1;
selection_area.height = height as u16;
ListWidget::new(true)
.with_highlight_symbol("")
.style(
Style::new()
.bg(Color::Blue)
.fg(Color::Black),
)
.with_highlight_style(
Style::new()
.bg(Color::LightBlue)
.fg(Color::Black),
)
.render(
selection_area,
buf,
&mut state.input_options,
);
}
}