# ratatui-interact
[](https://crates.io/crates/ratatui-interact)
[](https://docs.rs/ratatui-interact)
[](https://opensource.org/licenses/MIT)
Interactive TUI components for [ratatui](https://github.com/ratatui/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
- **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`:
```toml
[dependencies]
ratatui-interact = "0.4"
```
Or from git:
```toml
[dependencies]
ratatui-interact = { git = "https://github.com/Brainwires/ratatui-interact.git" }
```
## Quick Start
```rust
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
| **CheckBox** | Toggleable checkbox with multiple symbol styles (ASCII, Unicode, checkmark) |
| **Input** | Text input with cursor, insertion, deletion, and navigation |
| **TextArea** | Multi-line text input with cursor, line numbers, scrolling, and word wrap |
| **Button** | Multiple variants: SingleLine, Block, Toggle, Icon+Text |
| **Select** | Dropdown select box with popup options, keyboard/mouse navigation |
| **ContextMenu** | Right-click popup menu with actions, separators, shortcuts, and submenus |
| **MenuBar** | Traditional File/Edit/View/Help style menu bar with dropdowns, submenus, and shortcuts |
| **PopupDialog** | Container for modal dialogs with focus management |
| **HotkeyDialog** | Hotkey configuration dialog with search, categories, and trait-based customization |
### Display Components
| **AnimatedText** | Animated text with color effects (pulse, wave, rainbow, gradient, sparkle) |
| **ParagraphExt** | Extended paragraph with word-wrapping and scrolling |
| **Toast** | Transient notification popup with auto-expiration and style variants |
| **Progress** | Progress bar with label, percentage, and step counter |
| **MarqueeText** | Scrolling text for long content in limited space (continuous, bounce, static modes) |
| **Spinner** | Animated loading indicator with 12 frame styles (dots, braille, line, etc.) |
| **MousePointer** | Visual indicator at mouse cursor position with customizable styles |
### Navigation Components
| **ListPicker** | Scrollable list with selection cursor for picking items |
| **TreeView** | Collapsible tree view with selection and customizable rendering |
| **FileExplorer** | File browser with multi-select, search, and hidden file toggle |
| **Accordion** | Collapsible sections with single or multiple expansion modes |
| **Breadcrumb** | Hierarchical navigation path with ellipsis collapsing and keyboard/mouse support |
### Layout Components
| **TabView** | Tab bar with content switching, supports top/bottom/left/right positions |
| **SplitPane** | Resizable split pane with drag-to-resize divider, horizontal/vertical orientations |
### Viewer Components
| **ScrollableContent** | Scrollable text pane with focus support, keyboard/mouse navigation, and View/Copy mode for native terminal text selection |
| **LogViewer** | Scrollable log viewer with line numbers, search, and log-level coloring |
| **DiffViewer** | Diff viewer with unified and side-by-side modes, hunk navigation, search, and syntax highlighting |
| **StepDisplay** | Multi-step progress display with sub-steps and output areas |
## Utilities
### ANSI Parser
Parse ANSI escape codes to ratatui styles:
```rust
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
```rust
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
```rust
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](examples/README.md) for detailed code examples of each component.
Run the examples:
```bash
# 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 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
| Focus management | ✅ Generic `FocusManager<T>` | ✅ `FocusFlag` based | ❌ |
| Mouse click regions | ✅ `ClickRegion` with hit-testing | ✅ Area-based | ❌ |
| Ready-to-use widgets | ✅ Many (see above) | ❌ | ✅ Input only |
| Composition traits | ✅ Focusable, Clickable, Container | ❌ | ❌ |
## License
MIT