Expand description
§tabitha
An async, event-driven TUI framework built on ratatui and tokio.
This framework provides a clean architecture for building terminal user interfaces with minimal CPU usage. It only redraws in response to events, making it ideal for applications that need to be “quiet” and power-efficient.
§Features
- Event-driven: No polling, only responds to terminal events and task messages
- Async tasks: Background tasks communicate via typed message channels
- Builder pattern: Clean, composable application setup
- Tabs support: Built-in tab management with enable/disable support
- Minimal allocations: Designed for efficiency in hot paths
- Runtime control: Toggle mouse capture, navigate tabs, quit via contexts
§Quick Start
ⓘ
use tabitha::{AppBuilder, Component, MainUi, Event, AppContext, DrawContext, EventResult};
use ratatui::{Frame, layout::Rect, widgets::Paragraph};
struct MyApp;
impl Component for MyApp {
fn draw(&self, frame: &mut Frame, area: Rect, ctx: &DrawContext) {
frame.render_widget(Paragraph::new("Hello!"), area);
}
fn handle_event(&mut self, event: &Event, ctx: &mut AppContext) -> EventResult {
if event.is_quit() {
ctx.quit();
return EventResult::Handled;
}
EventResult::Unhandled
}
}
impl MainUi for MyApp {}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let app = AppBuilder::new()
.main_ui(MyApp)
.build()?;
app.run().await?;
Ok(())
}§Tabs
Register tabs with the application and use the context to draw and navigate them:
ⓘ
use tabitha::{Tab, AppBuilder, Component, MainUi, DrawContext, AppContext, EventResult, KeyCode};
struct HomeTab;
impl Tab for HomeTab {
fn id(&self) -> &str { "home" }
fn title(&self) -> &str { "Home" }
fn draw(&self, frame: &mut Frame, area: Rect) {
frame.render_widget(Paragraph::new("Home content"), area);
}
}
struct MyApp;
impl Component for MyApp {
fn draw(&self, frame: &mut Frame, area: Rect, ctx: &DrawContext) {
// Draw tab bar and content
ctx.tabs().draw_tabbar(frame, tab_bar_area);
ctx.tabs().draw_content(frame, content_area);
}
fn handle_event(&mut self, event: &Event, ctx: &mut AppContext) -> EventResult {
// Navigate with Tab key
if event.is_key(KeyCode::Tab) {
ctx.tabs().select_next();
return EventResult::Handled;
}
EventResult::Unhandled
}
}
let app = AppBuilder::new()
.main_ui(MyApp)
.add_tab(HomeTab)
.add_tab(SettingsTab)
.build()?;Re-exports§
pub use app::App;pub use app::AppBuilder;pub use app::AppError;pub use app::BuildError;pub use bus::MessageBus;pub use bus::SendError;pub use bus::TaskMessage;pub use bus::TaskSender;pub use bus::TrySendError;pub use component::BoxedComponent;pub use component::Component;pub use component::ComponentExt;pub use component::MainUi;pub use context::AppContext;pub use context::DrawContext;pub use context::FocusDrawContext;pub use context::FocusEventContext;pub use context::ModalEventContext;pub use context::TabEventContext;pub use context::TabsDrawContext;pub use context::TabsEventContext;pub use event::Event;pub use focus::EventResult;pub use focus::FocusManager;pub use tabs::BoxedTab;pub use tabs::Tab;pub use tabs::TabInfo;pub use tabs::TabManager;pub use task::Task;pub use task::TaskContext;pub use task::TaskHandle;pub use terminal::install_panic_hook;pub use terminal::Terminal;pub use terminal::TerminalConfig;pub use terminal::TerminalError;pub use theme::Theme;pub use widget::BoxedControl;pub use widget::Column;pub use widget::ColumnAlign;pub use widget::ColumnType;pub use widget::ColumnWidth;pub use widget::Control;pub use widget::ControlEvent;pub use widget::ControlExt;pub use widget::CursorBlinkConfig;pub use widget::DataTable;pub use widget::DataTableConfig;pub use widget::DataTableEvent;pub use widget::Modal;pub use widget::ModalButton;pub use widget::ModalConfig;pub use widget::ModalInput;pub use widget::ModalManager;pub use widget::ModalResult;pub use widget::SelectionMode;pub use widget::SimpleRow;pub use widget::SortDirection;pub use widget::SortState;pub use widget::TableRow;pub use widget::TextBox;pub use widget::TextBoxConfig;pub use widget::TextBoxEvent;
Modules§
- app
- Application builder and main event loop.
- bus
- Message bus for inter-task communication.
- component
- Component traits for the TUI framework.
- context
- Application contexts for event handlers and drawing.
- event
- Event types and handling for the TUI framework.
- focus
- Focus management for the TUI framework.
- tabs
- Tab management for the TUI framework.
- task
- Background task support for the TUI framework.
- terminal
- Terminal management for the TUI framework.
- theme
- Theme system for consistent styling across components.
- widget
- Interactive widget controls for the TUI framework.
Structs§
- Frame
- A consistent view into the terminal state for rendering a single frame.
- KeyModifiers
- Represents key modifiers (shift, control, alt, etc.).
- Rect
- A rectangular area in the terminal.
Enums§
- KeyCode
- Represents a key.
- Mouse
Button - Represents a mouse button.
- Mouse
Event Kind - A mouse event kind.