tui_spinner/lib.rs
1//! # tui-spinner
2//!
3//! Customizable animated spinner widgets for [Ratatui](https://github.com/ratatui/ratatui) TUI applications.
4//!
5//! ## Widgets
6//!
7//! | Widget | Motion | Key options |
8//! |--------|--------|-------------|
9//! | [`LinearSpinner`] | Scrolling window or bouncing dot along a straight axis | `direction`, `flow`, `linear_style` |
10//! | [`SquareSpinner`] | Braille-dot arc rotating around a square ring | `size`, `spin`, `centre` |
11//! | [`CircleSpinner`] | Braille-dot arc rotating around a circular ring | `radius`, `spin`, `arc_len` |
12//! | [`RectSpinner`] | Braille-dot arc rotating around a configurable rectangle | `shape`, `spin`, `centre` |
13//! | [`BarSpinner`] | Solid bar with a bouncing or looping glow arc | `bar_style`, `motion`, `spin`, `track`, `fade_width` |
14//! | [`FluxSpinner`] | Single-character glyph cycling through a frame sequence | `frames`, `spin`, `phase_step` |
15//! | [`SquareSpinner`] | Legacy alias for `RectSpinner::Square` | — |
16//!
17//! ## Quick start
18//!
19//! ```no_run
20//! use ratatui::style::Color;
21//! use tui_spinner::{
22//! BarMotion, BarSpinner, BarStyle, Centre, CircleSpinner,
23//! Direction, FluxFrames, FluxSpinner, Flow, LinearSpinner,
24//! LinearStyle, RectShape, RectSpinner, Spin, SquareSpinner,
25//! };
26//!
27//! // Vertical bouncing dot
28//! let v = LinearSpinner::new(42)
29//! .direction(Direction::Vertical)
30//! .linear_style(LinearStyle::Braille)
31//! .active_color(Color::Cyan);
32//!
33//! // Square arc, clockwise, filled centre
34//! let sq = SquareSpinner::new(42)
35//! .size(3)
36//! .spin(Spin::Clockwise)
37//! .centre(Centre::Filled)
38//! .arc_color(Color::Cyan);
39//!
40//! // Circular arc, counter-clockwise
41//! let circle = CircleSpinner::new(42)
42//! .radius(5)
43//! .spin(Spin::CounterClockwise)
44//! .arc_color(Color::Magenta);
45//!
46//! // Bouncing braille bar (Bounce) — fills available width automatically
47//! let bounce = BarSpinner::new(42)
48//! .arc_color(Color::Cyan)
49//! .dim_color(Color::DarkGray);
50//!
51//! // Continuous sweep (Loop) with a Star symbol style
52//! let sweep = BarSpinner::new(42)
53//! .bar_style(BarStyle::Star)
54//! .motion(BarMotion::Loop)
55//! .spin(Spin::Clockwise)
56//! .arc_color(Color::Yellow);
57//!
58//! // Minimal 1×1 status-bar spinner
59//! let flux = FluxSpinner::new(42).color(Color::Cyan);
60//!
61//! // 8-wide travelling wave
62//! let wave = FluxSpinner::new(42)
63//! .frames(FluxFrames::ORBIT)
64//! .width(8)
65//! .phase_step(1)
66//! .color(Color::LightBlue);
67//! ```
68//!
69//! ## Integration
70//!
71//! All widgets are **stateless** — pass a monotonically-increasing `tick: u64`
72//! counter (incremented once per render frame). No mutable widget state needed.
73//!
74//! ```no_run
75//! use ratatui::Frame;
76//! use ratatui::layout::Rect;
77//! use tui_spinner::{BarSpinner, BarMotion, Spin};
78//!
79//! struct App { tick: u64 }
80//!
81//! fn draw(frame: &mut Frame, area: Rect, app: &App) {
82//! frame.render_widget(
83//! BarSpinner::new(app.tick)
84//! .motion(BarMotion::Loop)
85//! .spin(Spin::Clockwise),
86//! area,
87//! );
88//! }
89//! ```
90
91#![warn(missing_docs)]
92#![warn(clippy::pedantic)]
93#![allow(clippy::module_name_repetitions)]
94
95#[macro_use]
96mod macros;
97
98mod bar_spinner;
99mod circle_spinner;
100mod flux_spinner;
101mod linear_spinner;
102mod rect_spinner;
103mod square_spinner;
104
105pub use bar_spinner::{BarMotion, BarSpinner, BarStyle, BarTrack};
106pub use circle_spinner::CircleSpinner;
107pub use flux_spinner::{FluxFrames, FluxSpinner};
108pub use linear_spinner::{Direction, Flow, LinearSpinner, LinearStyle};
109pub use rect_spinner::{Centre, RectShape, RectSpinner, Spin};
110pub use square_spinner::SquareSpinner;
111// Note: `Centre` and `Spin` are re-exported from rect_spinner.
112// `SquareSpinner` uses the same `Centre` and `Spin` enums via re-export.