aether-tui 0.1.7

A lightweight terminal UI rendering library for building rich CLI applications
Documentation
The core abstraction for all interactive widgets. Every built-in widget implements this trait, and parent components compose children through it.

The trait follows an event-message design: [`on_event`](Component::on_event) receives input and optionally produces typed messages that bubble up to the parent. [`render`](Component::render) produces a [`Frame`] from the current state.

# Event handling contract

[`on_event`](Component::on_event) returns one of three outcomes:

- **`None`** — the event was not recognized. The parent should propagate it elsewhere.
- **`Some(vec![])`** — the event was consumed but produced no messages (e.g. internal cursor movement).
- **`Some(vec![msg, ...])`** — the event was consumed and produced one or more messages for the parent to handle.

Use [`merge`](crate::merge) to combine outcomes from multiple children.

# Rendering

[`render`](Component::render) receives a [`ViewContext`](crate::ViewContext) — the **allocated render region** plus theme — and returns a [`Frame`](crate::Frame), a vector of [`Line`](crate::Line)s plus an optional [`Cursor`](crate::Cursor) position.

Parents are responsible for narrowing the context to the child's slot before calling `render` (using [`with_width`](crate::ViewContext::with_width), [`with_size`](crate::ViewContext::with_size), or [`inset`](crate::ViewContext::inset)). Children should treat `ctx.size` as authoritative — only the root component should assume the full terminal width. Composition between siblings happens on `Frame` itself via [`fit`](crate::Frame::fit), [`indent`](crate::Frame::indent), [`vstack`](crate::Frame::vstack), and [`hstack`](crate::Frame::hstack), not by reaching back into the parent's context.

# Usage

```rust,no_run
use tui::{Component, Event, Frame, KeyCode, Line, ViewContext};

struct Counter { count: i32 }

impl Component for Counter {
    type Message = ();
    async fn on_event(&mut self, event: &Event) -> Option<Vec<()>> {
        if let Event::Key(key) = event {
            match key.code {
                KeyCode::Up => self.count += 1,
                KeyCode::Down => self.count -= 1,
                _ => return None,
            }
            return Some(vec![]);
        }
        None
    }
    fn render(&mut self, _ctx: &ViewContext) -> Frame {
        Frame::new(vec![Line::new(format!("Count: {}", self.count))])
    }
}
```

# See also

- [`Event`] — the input events passed to `on_event`.
- [`Frame`] — the output of `render`.
- [`ViewContext`] — the environment passed to `render`.
- [`merge`](crate::merge) — combine event outcomes from multiple children.