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::InputNumberWidget;

use super::InputDateState;

pub struct InputDateWidget
{
    style: Style,
}

impl std::default::Default for InputDateWidget
{
    fn default() -> Self
    {
        Self::new()
    }
}

impl InputDateWidget
{
    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 InputDateWidget
{
    type State = InputDateState;

    fn render(
        self,
        area: Rect,
        buf: &mut Buffer,
        state: &mut Self::State,
    )
    {
        Clear.render(
            area, buf,
        );

        let style = if state
            .input()
            .is_some()
        {
            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, day_area, sep1_area, month_area, sep2_area, year_area, _] =
            Layout::horizontal([
                Constraint::Length(label_length),
                Constraint::Length(2),
                Constraint::Length(1),
                Constraint::Length(2),
                Constraint::Length(1),
                Constraint::Length(4),
                Constraint::Fill(1),
            ])
            .areas(area);

        if let Some(label) = state
            .label
            .as_ref()
        {
            Text::raw(label).render(
                label_area, buf,
            );
        }

        Text::raw("/").render(
            sep1_area, buf,
        );
        Text::raw("/").render(
            sep2_area, buf,
        );

        InputNumberWidget::new()
            .style(style)
            .render(
                day_area,
                buf,
                &mut state.input_day,
            );
        InputNumberWidget::new()
            .style(style)
            .render(
                month_area,
                buf,
                &mut state.input_month,
            );
        InputNumberWidget::new()
            .style(style)
            .render(
                year_area,
                buf,
                &mut state.input_year,
            );
    }
}