ratatui-toolkit 0.2.6

DEPRECATED: this crate was renamed to `ratkit`. Please migrate to `ratkit`.
Documentation
use ratatui::layout::{Constraint, Direction, Layout, Rect};
use ratatui::text::Line;
use ratatui::widgets::{Block, Borders, Paragraph, Widget};
use ratatui::Frame;

use crate::primitives::pane::Pane;

impl<'a> Pane<'a> {
    pub fn render<W>(&self, frame: &mut Frame, area: Rect, content: W)
    where
        W: Widget,
    {
        let padded_area = self.get_padded_area(area);
        let block = self.build_block();
        let inner = block.inner(padded_area);

        frame.render_widget(block, padded_area);
        frame.render_widget(content, inner);
    }

    pub fn render_with_footer<C, F>(&self, frame: &mut Frame, area: Rect, content: C, footer: F)
    where
        C: Widget,
        F: Widget,
    {
        let padded_area = self.get_padded_area(area);
        let block = self.build_block();
        let inner = block.inner(padded_area);

        frame.render_widget(block, padded_area);

        if self.footer_height == 0 {
            frame.render_widget(content, inner);
            return;
        }

        let chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([Constraint::Min(0), Constraint::Length(self.footer_height)])
            .split(inner);

        frame.render_widget(content, chunks[0]);
        frame.render_widget(footer, chunks[1]);
    }

    pub fn render_paragraph(&self, frame: &mut Frame, area: Rect, content: Vec<Line<'a>>) {
        let paragraph = Paragraph::new(content);
        self.render(frame, area, paragraph);
    }

    pub fn render_paragraph_with_footer<F>(
        &self,
        frame: &mut Frame,
        area: Rect,
        content: Vec<Line<'a>>,
        footer: F,
    ) where
        F: Widget,
    {
        let paragraph = Paragraph::new(content);
        self.render_with_footer(frame, area, paragraph, footer);
    }

    pub fn render_block(&self, frame: &mut Frame, area: Rect) -> (Rect, Option<Rect>) {
        let padded_area = self.get_padded_area(area);
        let block = self.build_block();
        let inner = block.inner(padded_area);

        frame.render_widget(block, padded_area);

        if self.footer_height == 0 {
            return (inner, None);
        }

        let chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([Constraint::Min(0), Constraint::Length(self.footer_height)])
            .split(inner);

        (chunks[0], Some(chunks[1]))
    }

    fn get_padded_area(&self, area: Rect) -> Rect {
        Rect {
            x: area.x + self.padding.3,
            y: area.y + self.padding.0,
            width: area.width.saturating_sub(self.padding.1 + self.padding.3),
            height: area.height.saturating_sub(self.padding.0 + self.padding.2),
        }
    }

    fn build_title_line(&self) -> Line<'a> {
        use ratatui::text::Span;

        let mut spans = vec![Span::raw(" ")];

        if let Some(ref icon) = self.icon {
            spans.push(Span::styled(icon.clone(), self.title_style));
            spans.push(Span::raw(" "));
        }

        spans.push(Span::styled(self.title.clone(), self.title_style));
        spans.push(Span::raw(" "));

        Line::from(spans)
    }

    fn build_block(&self) -> Block<'a> {
        let mut block = Block::default()
            .borders(Borders::ALL)
            .border_type(self.border_type)
            .border_style(self.border_style)
            .title(self.build_title_line());

        if let Some(ref footer) = self.text_footer {
            block = block.title_bottom(footer.clone().style(self.footer_style));
        }

        block
    }
}