Crate teapot

Crate teapot 

Source
Expand description

§Teapot

A Rust-native terminal UI framework following the Elm Architecture, inspired by the Charm.sh ecosystem (Bubble Tea, Bubbles, Huh).

§Architecture

This framework implements the Model-Update-View pattern:

  • Model: Your application state
  • Update: Handle messages and update state
  • View: Render state as a string

§Quick Start

use teapot::{Model, Program, Cmd, KeyCode, Event};

struct Counter {
    count: i32,
}

enum Msg {
    Increment,
    Decrement,
    Quit,
}

impl Model for Counter {
    type Message = Msg;

    fn init(&self) -> Option<Cmd<Self::Message>> {
        None
    }

    fn update(&mut self, msg: Self::Message) -> Option<Cmd<Self::Message>> {
        match msg {
            Msg::Increment => self.count += 1,
            Msg::Decrement => self.count -= 1,
            Msg::Quit => return Some(Cmd::quit()),
        }
        None
    }

    fn view(&self) -> String {
        format!("Count: {}\n\nPress +/- to change, q to quit", self.count)
    }

    fn handle_event(&self, event: Event) -> Option<Self::Message> {
        match event {
            Event::Key(key) => match key.code {
                KeyCode::Char('+') | KeyCode::Char('=') => Some(Msg::Increment),
                KeyCode::Char('-') => Some(Msg::Decrement),
                KeyCode::Char('q') | KeyCode::Esc => Some(Msg::Quit),
                _ => None,
            },
            _ => None,
        }
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let counter = Counter { count: 0 };
    Program::new(counter).run()?;
    Ok(())
}

§Components

The components module provides reusable UI widgets:

§Forms

The forms module provides declarative form building:

use teapot::forms::{Form, Group, Input, Select, Confirm};

let form = Form::new()
    .group(
        Group::new()
            .field(Input::new("name").title("Your name"))
            .field(Select::new("color").title("Favorite color")
                .options(["Red", "Green", "Blue"]))
    )
    .group(
        Group::new()
            .field(Confirm::new("agree").title("Do you agree?"))
    );

§CI/Script Compatibility

The framework automatically detects non-interactive environments and adjusts behavior accordingly (no animations, no prompts, clear errors).

§Accessible Mode

For screen reader users and other accessible environments, set the ACCESSIBLE=1 environment variable. This enables:

  • Plain text prompts without ANSI formatting
  • Numbered options for selection components
  • Line-based input instead of raw terminal mode

Forms can be run in accessible mode:

let mut form = Form::new()
    .group(Group::new()
        .field(InputField::new("name").title("Your Name").build()));

if let Some(results) = form.run_accessible()? {
    println!("Name: {}", results.get_string("name").unwrap_or(""));
}

Components implement the Accessible trait for custom accessible handling.

Re-exports§

pub use components::BadgeVariant;
pub use components::Column;
pub use components::Confirm;
pub use components::FilePicker;
pub use components::FooterHints;
pub use components::List;
pub use components::MultiProgress;
pub use components::MultiSelect;
pub use components::Progress;
pub use components::Select;
pub use components::Spinner;
pub use components::StatusBadge;
pub use components::Tab;
pub use components::TabBar;
pub use components::Table;
pub use components::TaskList;
pub use components::TaskProgressView;
pub use components::TaskStep;
pub use components::TextArea;
pub use components::TextInput;
pub use components::TitleBar;
pub use forms::Form;
pub use forms::Group;
pub use runtime::cmd;
pub use runtime::Accessible;
pub use runtime::AccessibleInput;
pub use runtime::Cmd;
pub use runtime::Model;
pub use runtime::Program;
pub use runtime::ProgramOptions;
pub use runtime::Sub;
pub use style::BOLD;
pub use style::CLEAR_LINE;
pub use style::CR;
pub use style::CURSOR_UP;
pub use style::DIM;
pub use style::HIDDEN;
pub use style::ITALIC;
pub use style::RESET;
pub use style::REVERSE;
pub use style::STRIKETHROUGH;
pub use style::UNDERLINE;
pub use style::Border;
pub use style::Color;
pub use style::Style;
pub use terminal::Event;
pub use terminal::KeyCode;
pub use terminal::KeyEvent;
pub use terminal::KeyModifiers;
pub use terminal::MouseEvent;
pub use util::ManagedWorker;
pub use util::ScrollState;
pub use util::WorkerHandle;

Modules§

components
Reusable UI components (Bubbles equivalent).
forms
Form system (Huh equivalent).
output
Simple output utilities for CLI applications.
runtime
Core runtime implementing the Elm Architecture.
style
Styling utilities for terminal output.
terminal
Terminal abstraction layer.
util
Utility functions.