hefesto-widgets 0.7.2

Ratatui widgets for the Hefesto TUI toolkit: popups, scrollable lists, trees, text input and spinners
Documentation
use ratatui::{
    buffer::Buffer,
    layout::Rect,
    style::Style,
    widgets::StatefulWidget,
};

use crate::spin::{Spin, SpinState};

/// Pre-built animation frame sets.
#[derive(Clone, Copy)]
pub enum SpinVariant {
    /// Braille dots spinning clockwise
    Dots,
    /// Left-right line oscillation
    Line,
    /// Braille dots in a different pattern
    Dots2,
    /// Bouncing ball
    Bounce,
    /// Expanding pulse bar
    Pulse,
    /// Rotating arrow
    Arrows,
    /// Square toggle
    Square,
    /// Clock face (requires emoji font support)
    Clock,
    /// Custom user-provided frames
    Custom(&'static [&'static str]),
}

impl SpinVariant {
    pub fn frames(&self) -> &'static [&'static str] {
        match self {
            Self::Dots => crate::DEFAULT_FRAMES,
            Self::Line => &["", ""],
            Self::Dots2 => &["", "", "", "", "", "", "", ""],
            Self::Bounce => &["", "", "", "", ""],
            Self::Pulse => &["", "", "", "", "", "", "", "", "", "", "", ""],
            Self::Arrows => &["", "", "", "", "", "", "", ""],
            Self::Square => &["", ""],
            Self::Clock => &[
                "🕐", "🕑", "🕒", "🕓", "🕔", "🕕", "🕖", "🕗", "🕘", "🕙", "🕚", "🕛",
            ],
            Self::Custom(f) => f,
        }
    }
}

impl Default for SpinVariant {
    fn default() -> Self {
        Self::Dots
    }
}

/// A widget wrapping [`Spin`](Spin) with pre-built animation variants.
///
/// Delegates rendering to [`Spin`] and shares its state ([`SpinState`](SpinState)).
#[derive(Clone)]
pub struct ThemedSpin {
    spin: Spin,
}

impl ThemedSpin {
    pub fn new() -> Self {
        Self {
            spin: Spin::new().frames(SpinVariant::Dots.frames()),
        }
    }

    pub fn variant(mut self, variant: SpinVariant) -> Self {
        self.spin = self.spin.frames(variant.frames());
        self
    }

    pub fn spinner_style(mut self, style: Style) -> Self {
        self.spin = self.spin.spinner_style(style);
        self
    }
}

impl StatefulWidget for ThemedSpin {
    type State = SpinState;

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