rtlibs-tui 0.1.5

rtools library: ratatui widgets
Documentation
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,
            );
        //

        // let mut filtered = state
        //     .options
        //     .clone();
        // filtered.sort();
        // let height = filtered
        //     .len()
        //     .min(state.items_shown as usize);

        // let mut selection_area = input_area;
        // selection_area.y += 1;
        // selection_area.height = height as u16;

        // Clear.render(
        //     selection_area,
        //     buf,
        // );
        // Block::new()
        //     .style(Style::new().bg(Color::DarkGray))
        //     .render(
        //         selection_area,
        //         buf,
        //     );
        // for i in 0..height
        // {
        //     let mut area = selection_area;
        //     area.y += i as u16;
        //     area.height = 1;
        //     let item = filtered
        //         .get(i)
        //         .unwrap();
        //     let selected = state
        //         .selected
        //         .map(|index| index == i)
        //         .unwrap_or(false);
        //     if selected
        //     {
        //         Text::styled(
        //             item,
        //             Style::new().bg(Color::Gray),
        //         )
        //         .render(
        //             area, buf,
        //         );
        //     }
        //     else
        //     {
        //         Text::raw(item).render(
        //             area, buf,
        //         );
        //     }
        // }
    }
}