modalx 0.1.1

A polished, modal-driven terminal UI framework for Rust featuring dynamic boxed frames, interactive forms, and context-aware shortcuts.
Documentation
# Getting Started

This guide walks through adding `modalx` to a Rust project, configuring terminal lifecycle handling, and running your first interactive modal dialog.

---

## Installation

Add `modalx` to your `Cargo.toml` dependencies:

```toml
[dependencies]
modalx = "0.1"
```

Or use the Cargo CLI:

```bash
cargo add modalx
```

### System Requirements
- **Rust Edition**: 2021 or later.
- **Platforms**: Linux, macOS, Windows (Windows Terminal, PowerShell, or cmd.exe with ANSI support).
- **Core Dependencies**: `crossterm` 0.29, `colored` 3.0, `thiserror` 2.0. No heavy external C libraries or windowing runtimes are required.

---

## The Prelude

For convenience, `modalx` provides a prelude module that exports all essential types, traits, and modal constructors:

```rust
use modalx::prelude::*;
```

The prelude re-exports:
- Modal structs: `SelectModal`, `FormModal`, `InputModal`, `ConfirmModal`, `InfoModal`, `TableModal`, `WaitingModal`.
- Outcome types: `SelectOutcome`, `FormResult`, `InputOutcome`, `ConfirmOutcome`, `TableOutcome`.
- Layout and styling types: `BoxFrame`, `Shortcuts`, `Shortcut`, `FieldSection`, `TitleSection`, `NavGuard`.
- Terminal guards: `TerminalGuard`, `AltScreenGuard`.
- Error types: `Result`, `TuiError`.

---

## First Modal Program

Below is a complete, standalone program demonstrating a menu modal that runs in the terminal's alternate screen buffer:

```rust
use modalx::prelude::*;

fn main() -> modalx::Result<()> {
    // Optional: Switch to alternate screen to preserve shell history
    let _alt = AltScreenGuard::enter();

    let mut selected_index = 0;

    let modal = SelectModal::new()
        .with_title("APPLICATION CONTROL PANEL", false)
        .with_raw_fields("Environment: Production | Region: us-west-2", " | ")
        .item("1", "Inspect Microservices")
        .item("2", "View Ingress Logs")
        .item("3", "Cluster Autoscaler Configuration")
        .item("4", "Restart Gateway Pods")
        .item("q", "Exit");

    match modal.run(&mut selected_index)? {
        SelectOutcome::Selected(idx) => {
            println!("User selected entry at index {}", idx);
        }
        SelectOutcome::Cancelled => {
            println!("User cancelled the prompt (pressed Esc or q).");
        }
        _ => {}
    }

    Ok(())
}
```

When run, the screen clears, switches to the alternate screen, renders a centered box frame with title and status metadata, and captures keypresses until an option is selected or dismissed. Upon exiting, the original shell contents are restored intact.

---

## Error Handling

All modal operations return `modalx::Result<T>`, where `Result<T>` is an alias for `std::result::Result<T, modalx::TuiError>`.

### Error Variants

```rust
#[derive(Debug, thiserror::Error)]
pub enum TuiError {
    #[error("Terminal I/O error: {0}")]
    Io(#[from] std::io::Error),

    #[error("Terminal window too small ({width}x{height}, required: {min_width}x{min_height})")]
    TerminalTooSmall {
        width: u16,
        height: u16,
        min_width: u16,
        min_height: u16,
    },

    #[error("Modal execution cancelled by user")]
    Cancelled,

    #[error("{0}")]
    Other(String),
}
```

### Propagating with `anyhow` or Custom Errors

Because `TuiError` implements `std::error::Error`, it integrates seamlessly with `anyhow` or `thiserror` in application code:

```rust
// In custom application error enum:
#[derive(Debug, thiserror::Error)]
pub enum AppError {
    #[error("TUI interface error: {0}")]
    Tui(#[from] modalx::TuiError),

    #[error("Network failure: {0}")]
    Network(String),
}
```