ratatui-interact

March 30, 2026 · View on GitHub

Crates.io Documentation License: MIT

Interactive TUI components for ratatui with focus management and mouse support.

Ratatui doesn't include built-in focus navigation or mouse click handling. This library fills that gap with ready-to-use interactive widgets and a flexible composition system.

Features

  • Focus Management - Tab/Shift+Tab navigation with FocusManager<T>
  • Mouse Click Support - Click regions with hit-testing via ClickRegion and ClickRegionRegistry
  • Interactive Widgets - CheckBox, Input, Button, Select, ContextMenu, MenuBar, PopupDialog
  • Display Widgets - ParagraphExt, Toast, Progress, MarqueeText, Spinner, MousePointer
  • Navigation Widgets - ListPicker, TreeView, FileExplorer, Accordion
  • Layout Widgets - TabView, SplitPane
  • Viewer Widgets - ScrollableContent, LogViewer, DiffViewer, StepDisplay
  • Color Theming - Centralized Theme / ColorPalette with dark/light presets; derive any component style with theme.style::<T>()
  • Utilities - ANSI parsing, display helpers, View/Copy mode, exit strategies
  • Composition Traits - Focusable, Clickable, Container for building custom components

Installation

Add to your Cargo.toml:

[dependencies]
ratatui-interact = "0.5"

Or from git:

[dependencies]
ratatui-interact = { git = "https://github.com/Brainwires/ratatui-interact.git" }

Quick Start

use ratatui_interact::prelude::*;

// Define focusable elements
#[derive(Clone, Eq, PartialEq, Hash)]
enum Element {
    NameInput,
    EnableCheckbox,
    SubmitButton,
}

// Set up focus manager
let mut focus = FocusManager::new();
focus.register(Element::NameInput);
focus.register(Element::EnableCheckbox);
focus.register(Element::SubmitButton);

// Create component states
let mut input_state = InputState::new("Hello");
let mut checkbox_state = CheckBoxState::new(false);
let button_state = ButtonState::enabled();

// Handle keyboard events
match event {
    Event::Key(key) if is_tab(key) => focus.next(),
    Event::Key(key) if is_shift_tab(key) => focus.prev(),
    _ => {}
}

// Render with focus awareness
let input = Input::new(&input_state)
    .label("Name")
    .focused(focus.is_focused(&Element::NameInput));
let click_region = input.render_stateful(frame, area);

// Handle mouse clicks
if let Some(element) = click_region.contains(mouse_x, mouse_y) {
    focus.focus(&element);
}

Components

Interactive Components

ComponentDescription
CheckBoxToggleable checkbox with multiple symbol styles (ASCII, Unicode, checkmark)
InputText input with cursor, insertion, deletion, and navigation
TextAreaMulti-line text input with cursor, line numbers, scrolling, and word wrap
ButtonMultiple variants: SingleLine, Block, Toggle, Icon+Text
SelectDropdown select box with popup options, keyboard/mouse navigation
ContextMenuRight-click popup menu with actions, separators, shortcuts, and submenus
MenuBarTraditional File/Edit/View/Help style menu bar with dropdowns, submenus, and shortcuts
PopupDialogContainer for modal dialogs with focus management
HotkeyDialogHotkey configuration dialog with search, categories, and trait-based customization

Display Components

ComponentDescription
AnimatedTextAnimated text with color effects (pulse, wave, rainbow, gradient, sparkle)
ParagraphExtExtended paragraph with word-wrapping and scrolling
ToastTransient notification popup with auto-expiration and style variants
ProgressProgress bar with label, percentage, and step counter
MarqueeTextScrolling text for long content in limited space (continuous, bounce, static modes)
SpinnerAnimated loading indicator with 12 frame styles (dots, braille, line, etc.)
ToastStackQueue of simultaneous overlay toasts with configurable placement, ordering, and per-toast dismiss policies
MousePointerVisual indicator at mouse cursor position with customizable styles
ComponentDescription
ListPickerScrollable list with selection cursor for picking items
TreeViewCollapsible tree view with selection and customizable rendering
FileExplorerFile browser with multi-select, search, and hidden file toggle
AccordionCollapsible sections with single or multiple expansion modes
BreadcrumbHierarchical navigation path with ellipsis collapsing and keyboard/mouse support

Layout Components

ComponentDescription
TabViewTab bar with content switching, supports top/bottom/left/right positions
SplitPaneResizable split pane with drag-to-resize divider, horizontal/vertical orientations

Viewer Components

ComponentDescription
ScrollableContentScrollable text pane with focus support, keyboard/mouse navigation, and View/Copy mode for native terminal text selection
LogViewerScrollable log viewer with line numbers, search, and log-level coloring
DiffViewerDiff viewer with unified and side-by-side modes, hunk navigation, search, and syntax highlighting
StepDisplayMulti-step progress display with sub-steps and output areas

Utilities

ANSI Parser

Parse ANSI escape codes to ratatui styles:

use ratatui_interact::utils::ansi::parse_ansi_to_spans;

let text = "\x1b[31mRed\x1b[0m Normal";
let spans = parse_ansi_to_spans(text);

Supports: SGR codes (bold, italic, colors), 256-color mode, RGB mode.

Display Utilities

use ratatui_interact::utils::display::{
    truncate_to_width, pad_to_width, clean_for_display, format_size
};

let truncated = truncate_to_width("Hello World", 8); // "Hello..."
let padded = pad_to_width("Hi", 10); // "Hi        "
let clean = clean_for_display("\x1b[31mText\x1b[0m");
let size = format_size(1536); // "1.5 KB"

View/Copy Mode & Exit Strategies

use ratatui_interact::utils::{ViewCopyMode, ViewCopyConfig, ExitStrategy};

// Enter view/copy mode for native terminal text selection
let mode = ViewCopyMode::enter(&mut stdout)?;
mode.print_lines(&content)?;
// ... wait for user input ...
mode.exit(&mut terminal)?;

// Choose exit strategy
let strategy = ExitStrategy::PrintContent(content); // or ExitStrategy::RestoreConsole
strategy.execute()?;

Examples

See examples/README.md for detailed code examples of each component.

Run the examples:

# Interactive Components
cargo run --example checkbox_demo       # Checkbox with multiple styles
cargo run --example input_demo          # Text input with cursor
cargo run --example textarea_demo       # Multi-line text input
cargo run --example button_demo         # Button variants and styles
cargo run --example select_demo         # Dropdown select boxes
cargo run --example context_menu_demo   # Right-click context menus
cargo run --example menu_bar_demo       # File/Edit/View/Help style menu bar
cargo run --example dialog_demo         # Modal dialogs
cargo run --example hotkey_dialog_demo  # Hotkey configuration dialog

# Display & Viewer Components
cargo run --example animated_text_demo  # Animated text with color effects
cargo run --example theme_demo          # Theme system with dark/light switching
cargo run --example toast_stack_demo    # Multiple simultaneous toasts with dismiss policies
cargo run --example marquee_demo        # Scrolling text animation
cargo run --example mouse_pointer_demo  # Mouse cursor indicator
cargo run --example spinner_demo        # Animated loading indicators
cargo run --example display_demo        # Progress, StepDisplay, ParagraphExt
cargo run --example diff_viewer_demo    # Diff viewer with unified/side-by-side modes
cargo run --example copyable_pane_demo  # ScrollableContent with View/Copy mode

# Navigation & Layout Components
cargo run --example accordion_demo      # Collapsible sections
cargo run --example tab_view_demo       # Tab bar with positions
cargo run --example split_pane_demo     # Resizable split panes
cargo run --example breadcrumb_demo     # Hierarchical path navigation
cargo run --example navigation_demo     # ListPicker and TreeView

# Combined Demo (requires filesystem feature)
cargo run --example explorer_log_demo --features filesystem

Comparison with Alternatives

Featureratatui-interactrat-focustui-input
Focus management✅ Generic FocusManager<T>FocusFlag based
Mouse click regionsClickRegion with hit-testing✅ Area-based
Ready-to-use widgets✅ Many (see above)✅ Input only
Composition traits✅ Focusable, Clickable, Container

License

MIT