bubbletea-widgets

Crates.iobubbletea-widgets
lib.rsbubbletea-widgets
version0.1.12
created_at2025-08-08 15:32:15.221792+00
updated_at2025-11-22 13:48:31.218349+00
descriptionA collection of reusable TUI components for building terminal applications with bubbletea-rs
homepage
repositoryhttps://github.com/whit3rabbit/bubbles-rs
max_upload_size
id1786914
size1,003,480
whit3rabbit (whit3rabbit)

documentation

README

bubbletea-widgets

CI

Rust components for building TUIs with bubbletea-rs, ported from Charmbracelet's Go bubbles. This is a Rust implementation of the original Go code. All credit for the original designs and APIs goes to the Charm team and Go community.

Installation

Add bubbletea-widgets to your Cargo.toml dependencies. You will also need bubbletea-rs and lipgloss-extras for a complete TUI application.

[dependencies]
bubbletea-rs = "0.0.7"
bubbletea-widgets = "0.1.11"
lipgloss-extras = { version = "0.0.8", features = ["full"] }

Note: This repository is named bubbles-rs for historical reasons, but the package name on crates.io is bubbletea-widgets. The original bubbles-rs name was already taken by another TUI framework. Always use bubbletea-widgets when adding this crate to your dependencies.

Components

Spinner

A spinner for indicating an operation is in progress. Includes multiple presets and option-style configuration.

use bubbletea_widgets::spinner::{new, with_spinner, with_style, DOT};
use lipgloss::{Style, Color};

let sp = new(&[
    with_spinner(DOT.clone()),
    with_style(Style::new().foreground(Color::from("cyan")))
]);
let frame = sp.view();

Text Input

Single-line input akin to HTML’s <input type="text">. Supports unicode, pasting, in-place scrolling, and customizable key bindings.

use bubbletea_widgets::textinput::new;

let mut input = new();
input.set_placeholder("Your name…");
input.set_width(30);
let _ = input.focus();

Text Area

Multi-line text input akin to <textarea>. Supports unicode, soft-wrapping, vertical scrolling, and rich styling via Lip Gloss.

use bubbletea_widgets::textarea;

let mut ta = textarea::new();
ta.set_width(40);
ta.set_height(6);
ta.insert_string("Hello, world!\nThis is bubbletea-widgets.");
let view = ta.view();

Table

Scrollable, navigable tables with headers, selection, and styling.

use bubbletea_widgets::table::{Model, Column, Row};

let columns = vec![
    Column::new("Name", 20),
    Column::new("Age", 6),
];
let rows = vec![
    Row::new(vec!["Alice".into(), "30".into()]),
    Row::new(vec!["Bob".into(), "25".into()]),
];
let table = Model::new(columns).with_rows(rows);
let _out = table.view();

Progress

Simple, customizable progress meter with optional animation and gradients.

use bubbletea_widgets::progress::{new, with_width, with_solid_fill};

let mut p = new(&[with_width(30), with_solid_fill("#00ff88".into())]);
let _cmd = p.set_percent(0.4);
let out = p.view();

Paginator

Pagination logic and rendering for dot-style or numeric pagination.

use bubbletea_widgets::paginator::Model;

let mut p = Model::new();
p.set_per_page(10);
p.set_total_items(95);
let view = p.view(); // e.g., "1/10" or dots depending on type

Viewport

Vertically scrollable viewport for large content; supports key bindings and horizontal scrolling.

use bubbletea_widgets::viewport;

let mut vp = viewport::new(80, 20);
vp.set_content("line 1\nline 2\nline 3");
let visible = vp.visible_lines();

List

Customizable, batteries-included list with pagination, fuzzy filtering, spinner, status messages, and auto-generated help.

use bubbletea_widgets::list::{Model, DefaultDelegate, Item};

#[derive(Clone)]
struct ItemStr(&'static str);
impl std::fmt::Display for ItemStr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) } }
impl Item for ItemStr { fn filter_value(&self) -> String { self.0.to_string() } }

let items = vec![ItemStr("foo"), ItemStr("bar")];
let list = Model::new(items, DefaultDelegate::new(), 80, 24);
let _out = list.view();

File Picker

Navigate directories and select files with keyboard navigation and customizable styles.

use bubbletea_widgets::filepicker::Model;

let (picker, _cmd) = Model::init();
let _out = picker.view();

Timer

Countdown timer with configurable interval and start/stop/toggle commands.

use bubbletea_widgets::timer::new;
use std::time::Duration;

let timer = new(Duration::from_secs(10));
let cmd = timer.init(); // schedule ticks
let view = timer.view();

Stopwatch

Count-up timer with start/stop/toggle and reset.

use bubbletea_widgets::stopwatch::new;

let sw = new();
let start_cmd = sw.start();

Help

Horizontal mini help view that auto-generates from your key bindings; supports single and multi-line modes and truncates gracefully.

// Help is integrated into components via a KeyMap trait and `help::Model`.
// See `help.rs` and component-specific `KeyMap` implementations.

Key

Non-visual key binding management with help text generation and matching utilities.

use bubbletea_widgets::key::{new_binding, with_keys_str, with_help, matches};
use bubbletea_rs::KeyMsg;
use crossterm::event::{KeyCode, KeyModifiers};

let save = new_binding(vec![
    with_keys_str(&["ctrl+s", "f2"]),
    with_help("ctrl+s", "save"),
]);
let quit = new_binding(vec![
    with_keys_str(&["ctrl+c", "q"]),
    with_help("ctrl+c", "quit"),
]);

let msg = KeyMsg { key: KeyCode::Char('s'), modifiers: KeyModifiers::CONTROL };
let matched = matches(&msg, &[&save, &quit]);

There’s more where that came from

Community-maintained Bubbles are listed by Charm & Friends: additional bubbles.

Contributing

Issues and PRs welcome. This project aims to mirror the Go API where it makes sense in Rust, and to keep the codebase clean and idiomatic.

Attribution

This crate is a Rust implementation/port. Design, API concepts, and many behaviors are derived from the Go implementation by Charmbracelet and contributors.

Examples

Check out the interactive examples in the examples/ directory:

# Run the main list example
cargo run --example list-default --bin list-default

# Run debug versions for testing filter highlighting
cargo run --example list-default --bin debug-filter

The examples demonstrate the list component with filtering functionality and can be used to test the filter highlighting features.

License

MIT. See LICENSE.

Commit count: 0

cargo fmt