Full Code of microsandbox/rxtui for AI

main ddd15bea46e4 cached
99 files
1.1 MB
265.0k tokens
1097 symbols
1 requests
Download .txt
Showing preview only (1,232K chars total). Download the full file or copy to clipboard to get everything.
Repository: microsandbox/rxtui
Branch: main
Commit: ddd15bea46e4
Files: 99
Total size: 1.1 MB

Directory structure:
gitextract_sx7sm9zf/

├── .gitignore
├── .pre-commit-config.yaml
├── API_REFERENCE.md
├── CONTRIBUTING.md
├── Cargo.toml
├── DEVELOPMENT.md
├── DOCS.md
├── IMPLEMENTATION.md
├── LICENSE
├── QUICK_REFERENCE.md
├── README.md
├── TUTORIAL.md
├── examples/
│   ├── README.md
│   ├── align.rs
│   ├── components.rs
│   ├── counter.rs
│   ├── demo.rs
│   ├── demo_pages/
│   │   ├── mod.rs
│   │   ├── page10_unicode.rs
│   │   ├── page11_content_sizing.rs
│   │   ├── page12_focus.rs
│   │   ├── page13_rich_text.rs
│   │   ├── page14_text_input.rs
│   │   ├── page15_scrollable.rs
│   │   ├── page16_text_alignment.rs
│   │   ├── page1_overflow.rs
│   │   ├── page2_direction.rs
│   │   ├── page3_percentages.rs
│   │   ├── page4_borders.rs
│   │   ├── page5_absolute.rs
│   │   ├── page6_text_styles.rs
│   │   ├── page7_auto_sizing.rs
│   │   ├── page8_text_wrap.rs
│   │   └── page9_element_wrap.rs
│   ├── form.rs
│   ├── gap.rs
│   ├── hover.rs
│   ├── inline.rs
│   ├── progressbar.rs
│   ├── rxtui.rs
│   ├── scroll.rs
│   ├── scroll_nested.rs
│   ├── shimmer_text.rs
│   ├── spinner.rs
│   ├── spinner_custom.rs
│   ├── stopwatch.rs
│   └── textinput.rs
├── plan.md
├── rxtui/
│   ├── Cargo.toml
│   ├── LICENSE
│   ├── README.md
│   ├── lib/
│   │   ├── app/
│   │   │   ├── config.rs
│   │   │   ├── context.rs
│   │   │   ├── core.rs
│   │   │   ├── events.rs
│   │   │   ├── inline.rs
│   │   │   ├── mod.rs
│   │   │   └── renderer.rs
│   │   ├── bounds.rs
│   │   ├── buffer.rs
│   │   ├── component.rs
│   │   ├── components/
│   │   │   ├── mod.rs
│   │   │   ├── shimmer_text.rs
│   │   │   ├── spinner.rs
│   │   │   └── text_input.rs
│   │   ├── diff.rs
│   │   ├── effect/
│   │   │   ├── mod.rs
│   │   │   ├── runtime.rs
│   │   │   └── types.rs
│   │   ├── key.rs
│   │   ├── lib.rs
│   │   ├── macros/
│   │   │   ├── internal.rs
│   │   │   ├── mod.rs
│   │   │   └── node.rs
│   │   ├── node/
│   │   │   ├── div.rs
│   │   │   ├── mod.rs
│   │   │   ├── rich_text.rs
│   │   │   └── text.rs
│   │   ├── prelude.rs
│   │   ├── providers.rs
│   │   ├── render_tree/
│   │   │   ├── mod.rs
│   │   │   ├── node.rs
│   │   │   ├── tests/
│   │   │   │   ├── layout_tests.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── rich_text_tests.rs
│   │   │   │   ├── sizing_tests.rs
│   │   │   │   └── wrapping_tests.rs
│   │   │   └── tree.rs
│   │   ├── style.rs
│   │   ├── terminal.rs
│   │   ├── tests/
│   │   │   └── rich_text_tests.rs
│   │   ├── utils.rs
│   │   ├── vdom.rs
│   │   └── vnode.rs
│   └── tests/
│       └── macro_tests.rs
└── rxtui-macros/
    ├── Cargo.toml
    ├── LICENSE
    ├── README.md
    └── src/
        └── lib.rs

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Rust
target/**
**/*.rs.bk
Cargo.lock

# IDE
.idea/
.vscode/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Environment
.env
.env.local
.env.test

# Build artifacts
dist/
build/

# Logs
*.log

# Testing
coverage/
*.lcov

# Temporary files
tmp/
temp/

ignore/


================================================
FILE: .pre-commit-config.yaml
================================================
repos:
  # Standard pre-commit hooks
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-added-large-files
      - id: check-merge-conflict
      - id: mixed-line-ending
        args: [--fix=lf]
      - id: no-commit-to-branch
        args: [--branch, main, --branch, master]

  # Rust-specific hooks
  - repo: local
    hooks:
      - id: cargo-fmt
        name: cargo fmt
        entry: cargo fmt --all --
        language: system
        types: [rust]
        pass_filenames: false
      - id: cargo-clippy
        name: cargo clippy
        entry: cargo clippy --all-targets --all-features -- -D warnings
        language: system
        types: [rust]
        pass_filenames: false


================================================
FILE: API_REFERENCE.md
================================================
# RxTUI API Reference

Complete API documentation for the RxTUI framework.

## Module Structure

```
rxtui
├── prelude          // Common imports
├── component        // Component trait and types
├── node             // UI node types
├── style            // Styling types
├── app              // Application core
├── components       // Built-in components
├── macros           // Macro exports
└── effect           // Async effects (feature-gated)
```

## Prelude

```rust
use rxtui::prelude::*;
```

Imports all commonly used types:
- Core: `App`, `Context`, `Component`, `Node`, `Action`
- State: `State`, `StateExt`, `Message`, `MessageExt`
- Style: `Color`, `Style`, `Direction`, `Spacing`, `Border`, `BorderStyle`, `BorderEdges`
- Key: `Key`, `KeyWithModifiers`
- Macros: `node!`, `#[component]`, `#[update]`, `#[view]`, `#[effect]`

## Core Types

### Component

```rust
pub trait Component: 'static {
    fn update(&self, ctx: &Context, msg: Box<dyn Message>, topic: Option<&str>) -> Action;
    fn view(&self, ctx: &Context) -> Node;
    fn effects(&self, ctx: &Context) -> Vec<Effect>;
    fn as_any(&self) -> &dyn Any;
    fn as_any_mut(&mut self) -> &mut dyn Any;
}
```

Derive with:
```rust
#[derive(Component)]
struct MyComponent;
```

### Action

```rust
pub enum Action {
    Update(Box<dyn State>),              // Update component state
    UpdateTopic(String, Box<dyn State>), // Update topic state
    None,                                // No action
    Exit,                                // Exit application
}
```

Helper methods:
```rust
Action::update(state)        // Shorthand for Update
Action::update_topic(topic, state)  // Shorthand for UpdateTopic
Action::none()               // Shorthand for None
Action::exit()               // Shorthand for Exit
```

### Context

```rust
impl Context {
    // Message handling
    pub fn handler<M: Message>(&self, msg: M) -> Box<dyn Fn()>;
    pub fn handler_with_value<F, M>(&self, f: F) -> Box<dyn Fn(T)>
        where F: Fn(T) -> M, M: Message;

    // State management
    pub fn get_state<S: State>(&self) -> S;
    pub fn get_state_or<S: State>(&self, default: S) -> S;

    // Topic messaging
    pub fn send_to_topic<M: Message>(&self, topic: &str, msg: M);
    pub fn read_topic<S: State>(&self, topic: &str) -> Option<S>;

    // Direct messaging
    pub fn send<M: Message>(&self, msg: M);
}
```

### Message

```rust
pub trait Message: Any + Send + Sync + 'static {
    fn as_any(&self) -> &dyn Any;
    fn clone_box(&self) -> Box<dyn Message>;
}
```

Auto-implemented for types that are `Clone + Send + Sync + 'static`.

### State

```rust
pub trait State: Any + Send + Sync + 'static {
    fn as_any(&self) -> &dyn Any;
    fn as_any_mut(&mut self) -> &mut dyn Any;
    fn clone_box(&self) -> Box<dyn State>;
}
```

Auto-implemented for types that are `Clone + Send + Sync + 'static`.

## Node Types

### Node

```rust
pub enum Node {
    Component(Arc<dyn Component>),
    Div(Div),
    Text(Text),
    RichText(RichText),
}
```

### Div

```rust
impl Div {
    pub fn new() -> Self;

    // Layout
    pub fn direction(self, dir: Direction) -> Self;
    pub fn gap(self, gap: u16) -> Self;
    pub fn wrap(self, mode: WrapMode) -> Self;

    // Alignment
    pub fn justify_content(self, justify: JustifyContent) -> Self;
    pub fn align_items(self, align: AlignItems) -> Self;
    pub fn align_self(self, align: AlignSelf) -> Self;

    // Sizing
    pub fn width(self, w: u16) -> Self;
    pub fn width_fraction(self, frac: f32) -> Self;
    pub fn width_auto(self) -> Self;
    pub fn width_content(self) -> Self;
    pub fn height(self, h: u16) -> Self;
    pub fn height_fraction(self, frac: f32) -> Self;
    pub fn height_auto(self) -> Self;
    pub fn height_content(self) -> Self;

    // Styling
    pub fn background(self, color: Color) -> Self;
    pub fn padding(self, spacing: Spacing) -> Self;
    pub fn style(self, style: Style) -> Self;

    // Borders
    pub fn border_color(self, color: Color) -> Self;
    pub fn border_style_with_color(self, style: BorderStyle, color: Color) -> Self;
    pub fn border_edges(self, edges: BorderEdges) -> Self;
    pub fn border_full(self, style: BorderStyle, color: Color, edges: BorderEdges) -> Self;

    // Positioning
    pub fn position(self, pos: Position) -> Self;
    pub fn top(self, offset: i16) -> Self;
    pub fn right(self, offset: i16) -> Self;
    pub fn bottom(self, offset: i16) -> Self;
    pub fn left(self, offset: i16) -> Self;
    pub fn z_index(self, z: i32) -> Self;

    // Scrolling
    pub fn overflow(self, overflow: Overflow) -> Self;
    pub fn show_scrollbar(self, show: bool) -> Self;

    // Focus
    pub fn focusable(self, focusable: bool) -> Self;
    pub fn focus_style(self, style: Style) -> Self;

    // Events
    pub fn on_click(self, handler: impl Fn()) -> Self;
    pub fn on_key(self, key: Key, handler: impl Fn()) -> Self;
    pub fn on_key_global(self, key: Key, handler: impl Fn()) -> Self;
    pub fn on_char(self, ch: char, handler: impl Fn()) -> Self;
    pub fn on_char_global(self, ch: char, handler: impl Fn()) -> Self;
    pub fn on_any_char(self, handler: impl Fn(char)) -> Self;
    pub fn on_focus(self, handler: impl Fn()) -> Self;
    pub fn on_blur(self, handler: impl Fn()) -> Self;

    // Children
    pub fn children(self, children: Vec<Node>) -> Self;
    pub fn child(self, child: Node) -> Self;
}
```

### Text

```rust
impl Text {
    pub fn new(content: impl Into<String>) -> Self;

    // Styling
    pub fn color(self, color: Color) -> Self;
    pub fn background(self, color: Color) -> Self;
    pub fn bold(self) -> Self;
    pub fn italic(self) -> Self;
    pub fn underline(self) -> Self;
    pub fn strikethrough(self) -> Self;
    pub fn style(self, style: TextStyle) -> Self;

    // Wrapping
    pub fn wrap(self, mode: TextWrap) -> Self;

    // Alignment
    pub fn align(self, align: TextAlign) -> Self;
}
```

### RichText

```rust
impl RichText {
    pub fn new() -> Self;

    // Add spans
    pub fn text(self, content: impl Into<String>) -> Self;
    pub fn styled(self, content: impl Into<String>, style: TextStyle) -> Self;
    pub fn colored(self, content: impl Into<String>, color: Color) -> Self;
    pub fn bold(self, content: impl Into<String>) -> Self;
    pub fn italic(self, content: impl Into<String>) -> Self;

    // Apply to all spans
    pub fn color(self, color: Color) -> Self;
    pub fn background(self, color: Color) -> Self;
    pub fn bold_all(self) -> Self;
    pub fn italic_all(self) -> Self;

    // Wrapping
    pub fn wrap(self, mode: TextWrap) -> Self;

    // Alignment
    pub fn align(self, align: TextAlign) -> Self;

    // Cursor support
    pub fn with_cursor(content: &str, position: usize, style: TextStyle) -> Self;
}
```

## Style Types

### Color

```rust
pub enum Color {
    // Basic colors
    Black, Red, Green, Yellow, Blue, Magenta, Cyan, White,

    // Bright colors
    BrightBlack, BrightRed, BrightGreen, BrightYellow,
    BrightBlue, BrightMagenta, BrightCyan, BrightWhite,

    // RGB
    Rgb(u8, u8, u8),
}

impl Color {
    pub fn from_hex(hex: &str) -> Result<Self, ParseError>;
}
```

### Style

```rust
pub struct Style {
    pub background: Option<Color>,
    pub direction: Option<Direction>,
    pub padding: Option<Spacing>,
    pub width: Option<Dimension>,
    pub height: Option<Dimension>,
    pub gap: Option<u16>,
    pub wrap: Option<WrapMode>,
    pub overflow: Option<Overflow>,
    pub border: Option<Border>,
    pub position: Option<Position>,
    pub top: Option<i16>,
    pub right: Option<i16>,
    pub bottom: Option<i16>,
    pub left: Option<i16>,
    pub z_index: Option<i32>,
    pub justify_content: Option<JustifyContent>,
    pub align_items: Option<AlignItems>,
    pub align_self: Option<AlignSelf>,
}

impl Style {
    pub fn new() -> Self;
    pub fn background(self, color: Color) -> Self;
    pub fn padding(self, spacing: Spacing) -> Self;
    pub fn border(self, color: Color) -> Self;
    // ... builder methods for all fields
}
```

### Key

```rust
pub enum Key {
    // Regular character
    Char(char),

    // Special keys
    Esc, Enter, Tab, BackTab, Backspace, Delete,

    // Arrow keys
    Up, Down, Left, Right,

    // Navigation
    PageUp, PageDown, Home, End,

    // Function keys
    F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
}

pub struct KeyWithModifiers {
    pub key: Key,
    pub ctrl: bool,
    pub alt: bool,
    pub shift: bool,
    pub meta: bool,  // Cmd on macOS, Win on Windows
}

impl KeyWithModifiers {
    pub fn new(key: Key) -> Self;
    pub fn with_ctrl(key: Key) -> Self;
    pub fn with_alt(key: Key) -> Self;
    pub fn with_shift(key: Key) -> Self;
    pub fn is_primary_modifier(&self) -> bool;  // Platform-aware (Cmd on macOS, Ctrl elsewhere)
}
```

### TextAlign

```rust
pub enum TextAlign {
    Left,    // Align text to the left edge (default)
    Center,  // Center text horizontally
    Right,   // Align text to the right edge
}
```

### JustifyContent

```rust
pub enum JustifyContent {
    Start,         // Pack items at the start of the main axis (default)
    Center,        // Center items along the main axis
    End,           // Pack items at the end of the main axis
    SpaceBetween,  // Distribute items evenly, first at start, last at end
    SpaceAround,   // Distribute items evenly with equal space around each item
    SpaceEvenly,   // Distribute items evenly with equal space between and around items
}
```

### AlignItems

```rust
pub enum AlignItems {
    Start,   // Align items at the start of the cross axis (default)
    Center,  // Center items along the cross axis
    End,     // Align items at the end of the cross axis
}
```

### AlignSelf

```rust
pub enum AlignSelf {
    Auto,    // Use the parent's AlignItems value (default)
    Start,   // Align at the start of the cross axis
    Center,  // Center along the cross axis
    End,     // Align at the end of the cross axis
}
```

### TextStyle

```rust
pub struct TextStyle {
    pub color: Option<Color>,
    pub background: Option<Color>,
    pub bold: Option<bool>,
    pub italic: Option<bool>,
    pub underline: Option<bool>,
    pub strikethrough: Option<bool>,
    pub wrap: Option<TextWrap>,
    pub align: Option<TextAlign>,
}

impl TextStyle {
    pub fn new() -> Self;
    pub fn color(self, color: Color) -> Self;
    pub fn background(self, color: Color) -> Self;
    pub fn bold(self) -> Self;
    pub fn italic(self) -> Self;
    pub fn underline(self) -> Self;
    pub fn strikethrough(self) -> Self;
    pub fn merge(base: Option<Self>, overlay: Option<Self>) -> Option<Self>;
}
```

### Dimension

```rust
pub enum Dimension {
    Fixed(u16),       // Exact size
    Percentage(f32),  // Normalized (0.0 to 1.0)
    Auto,             // Share remaining
    Content,          // Fit content
}
```

### Direction

```rust
pub enum Direction {
    Horizontal,
    Vertical,
}
```

### Spacing

```rust
pub struct Spacing {
    pub top: u16,
    pub right: u16,
    pub bottom: u16,
    pub left: u16,
}

impl Spacing {
    pub fn all(value: u16) -> Self;
    pub fn horizontal(value: u16) -> Self;
    pub fn vertical(value: u16) -> Self;
    pub fn new(top: u16, right: u16, bottom: u16, left: u16) -> Self;
}
```

### BorderStyle

```rust
pub enum BorderStyle {
    Single,
    Double,
    Rounded,
    Thick,
}
```

### BorderEdges

```rust
bitflags! {
    pub struct BorderEdges: u8 {
        const TOP = 0b0001;
        const RIGHT = 0b0010;
        const BOTTOM = 0b0100;
        const LEFT = 0b1000;
        const ALL = 0b1111;
    }
}
```

### Border

```rust
pub struct Border {
    pub enabled: bool,
    pub style: BorderStyle,
    pub color: Color,
    pub edges: BorderEdges,
}

impl Border {
    pub fn new(color: Color) -> Self;
    pub fn style(self, style: BorderStyle) -> Self;
    pub fn edges(self, edges: BorderEdges) -> Self;
}
```

### Position

```rust
pub enum Position {
    Relative,
    Absolute,
}
```

### Overflow

```rust
pub enum Overflow {
    None,    // No clipping
    Hidden,  // Clip content
    Scroll,  // Scrollable
    Auto,    // Auto scrollbars
}
```

### WrapMode

```rust
pub enum WrapMode {
    NoWrap,
    Wrap,
}
```

### TextWrap

```rust
pub enum TextWrap {
    None,
    Character,
    Word,
    WordBreak,
}
```

## App

```rust
pub struct App {
    // Private fields
}

impl App {
    /// Creates app with alternate screen mode (default).
    pub fn new() -> Result<Self>;

    /// Creates app with inline rendering mode.
    /// Content renders directly in terminal and persists after exit.
    pub fn inline() -> Result<Self>;

    /// Creates app with custom inline configuration.
    pub fn inline_with_config(config: InlineConfig) -> Result<Self>;

    /// Creates app with specified terminal mode.
    pub fn with_mode(mode: TerminalMode) -> Result<Self>;

    /// Runs the application with the given root component.
    pub fn run<C: Component>(&mut self, root: C) -> Result<()>;
}
```

### TerminalMode

```rust
/// Terminal rendering mode.
pub enum TerminalMode {
    /// Full-screen alternate buffer (default behavior).
    /// Content disappears when app exits.
    AlternateScreen,

    /// Inline rendering in main terminal buffer.
    /// Content persists in terminal history after app exits.
    Inline(InlineConfig),
}
```

### InlineConfig

```rust
/// Configuration for inline rendering mode.
pub struct InlineConfig {
    /// How to determine rendering height.
    pub height: InlineHeight,

    /// Whether to show cursor during rendering.
    pub cursor_visible: bool,

    /// Whether to preserve output after app exits.
    pub preserve_on_exit: bool,

    /// Whether to capture mouse events.
    /// Default is false to allow natural terminal scrolling.
    pub mouse_capture: bool,
}

impl Default for InlineConfig {
    fn default() -> Self {
        Self {
            height: InlineHeight::Content { max: None },
            cursor_visible: false,
            preserve_on_exit: true,
            mouse_capture: false,
        }
    }
}
```

### InlineHeight

```rust
/// Height determination strategy for inline mode.
pub enum InlineHeight {
    /// Fixed number of lines.
    Fixed(u16),

    /// Grow to fit content, with optional maximum.
    Content { max: Option<u16> },

    /// Fill remaining terminal space below cursor.
    Fill { min: u16 },
}
```

### RenderConfig

```rust
pub struct RenderConfig {
    pub poll_duration_ms: u64,  // Event poll timeout (default: 16)
    pub use_double_buffer: bool, // Enable double buffering (default: true)
    pub use_diffing: bool,       // Enable cell diffing (default: true)
    pub use_alternate_screen: bool, // Use alternate screen (default: true)
}
```

## Key

```rust
pub enum Key {
    // Special keys
    Backspace, Enter, Left, Right, Up, Down,
    Home, End, PageUp, PageDown,
    Tab, Delete, Insert, Esc,

    // Function keys
    F(u8),  // F1-F12

    // Character
    Char(char),

    // Null
    Null,
}
```

### KeyWithModifiers

```rust
pub struct KeyWithModifiers {
    pub key: Key,
    pub ctrl: bool,
    pub alt: bool,
    pub shift: bool,
    pub meta: bool,
}

impl KeyWithModifiers {
    pub fn with_ctrl(key: Key) -> Self;
    pub fn with_alt(key: Key) -> Self;
    pub fn with_shift(key: Key) -> Self;
    pub fn with_meta(key: Key) -> Self;
}
```

## Built-in Components

### TextInput

```rust
use rxtui::components::TextInput;

impl TextInput {
    pub fn new() -> Self;

    // Content
    pub fn placeholder(self, text: impl Into<String>) -> Self;
    pub fn password(self, enabled: bool) -> Self;

    // Container styling
    pub fn background(self, color: Color) -> Self;
    pub fn border(self, color: Color) -> Self;
    pub fn border_style(self, style: BorderStyle, color: Color) -> Self;
    pub fn border_edges(self, edges: BorderEdges) -> Self;
    pub fn border_full(self, style: BorderStyle, color: Color, edges: BorderEdges) -> Self;
    pub fn padding(self, spacing: Spacing) -> Self;
    pub fn z_index(self, z: i32) -> Self;
    pub fn position(self, pos: Position) -> Self;
    pub fn absolute(self) -> Self;
    pub fn top(self, offset: i16) -> Self;
    pub fn right(self, offset: i16) -> Self;
    pub fn bottom(self, offset: i16) -> Self;
    pub fn left(self, offset: i16) -> Self;

    // Sizing
    pub fn width(self, w: u16) -> Self;
    pub fn width_fraction(self, frac: f32) -> Self;
    pub fn width_auto(self) -> Self;
    pub fn width_content(self) -> Self;
    pub fn height(self, h: u16) -> Self;
    pub fn height_fraction(self, frac: f32) -> Self;
    pub fn height_auto(self) -> Self;
    pub fn height_content(self) -> Self;

    // Text styling
    pub fn content_color(self, color: Color) -> Self;
    pub fn content_bold(self, bold: bool) -> Self;
    pub fn content_background(self, color: Color) -> Self;
    pub fn placeholder_color(self, color: Color) -> Self;
    pub fn placeholder_background(self, color: Color) -> Self;
    pub fn placeholder_bold(self, bold: bool) -> Self;
    pub fn placeholder_italic(self, italic: bool) -> Self;
    pub fn placeholder_underline(self, underline: bool) -> Self;
    pub fn placeholder_style(self, style: TextStyle) -> Self;
    pub fn content_style(self, style: TextStyle) -> Self;
    pub fn cursor_color(self, color: Color) -> Self;

    // Focus
    pub fn focusable(self, enabled: bool) -> Self;
    pub fn focus_border(self, color: Color) -> Self;
    pub fn focus_border_style(self, style: BorderStyle, color: Color) -> Self;
    pub fn focus_background(self, color: Color) -> Self;
    pub fn focus_style(self, style: Style) -> Self;
    pub fn focus_padding(self, spacing: Spacing) -> Self;

    // Wrapping
    pub fn wrap(self, mode: TextWrap) -> Self;

    // Events
    pub fn on_change(self, callback: impl Fn(String) + 'static) -> Self;
    pub fn on_submit(self, callback: impl Fn() + 'static) -> Self;
    pub fn on_blur(self, callback: impl Fn() + 'static) -> Self;
    pub fn on_key(self, key: Key, handler: impl Fn() + 'static) -> Self;
    pub fn on_key_global(self, key: Key, handler: impl Fn() + 'static) -> Self;
    pub fn on_key_with_modifiers(self, key: KeyWithModifiers, handler: impl Fn() + 'static) -> Self;
    pub fn on_key_with_modifiers_global(
        self,
        key: KeyWithModifiers,
        handler: impl Fn() + 'static,
    ) -> Self;
}
```

Messages:
```rust
pub enum TextInputMsg {
    Focused,
    Blurred,
    CharInput(char),
    Backspace,
    Delete,
    CursorLeft,
    CursorRight,
    CursorHome,
    CursorEnd,
    // ... more
}
```

## Attribute Macros

### #[derive(Component)]

Automatically implements the Component trait:

```rust
#[derive(Component)]
struct MyComponent {
    // Fields
}
```

### #[component]

Enables collection of `#[effect]` methods:

```rust
#[derive(Component)]
struct Timer;

#[component]  // Required for #[effect]
impl Timer {
    // Methods
}
```

### #[update]

Simplifies update method with automatic state handling:

```rust
// Basic
#[update]
fn update(&self, ctx: &Context, msg: MyMsg) -> Action {
    // No state parameter = stateless
}

// With state
#[update]
fn update(&self, ctx: &Context, msg: MyMsg, mut state: MyState) -> Action {
    // State automatically fetched and passed
}

// With topics
#[update(msg = MyMsg, topics = ["topic" => TopicMsg])]
fn update(&self, ctx: &Context, messages: Messages, mut state: MyState) -> Action {
    match messages {
        Messages::MyMsg(msg) => { /* ... */ }
        Messages::TopicMsg(msg) => { /* ... */ }
    }
}

// Dynamic topics
#[update(msg = MyMsg, topics = [self.topic_field => TopicMsg])]
fn update(&self, ctx: &Context, messages: Messages, state: MyState) -> Action {
    // Topic name from component field
}
```

### #[view]

Simplifies view method with automatic state handling:

```rust
// Without state
#[view]
fn view(&self, ctx: &Context) -> Node {
    // No state needed
}

// With state
#[view]
fn view(&self, ctx: &Context, state: MyState) -> Node {
    // State automatically fetched and passed
}
```

### #[effect]

Marks async methods as effects (requires `effects` feature):

```rust
#[component]
impl MyComponent {
    #[effect]
    async fn background_task(&self, ctx: &Context) {
        // Async code
    }

    #[effect]
    async fn with_state(&self, ctx: &Context, state: MyState) {
        // Can access state
    }
}
```

## Effects (Feature-gated)

Enable with:
```toml
rxtui = { path = "rxtui", features = ["effects"] }
```

### Effect Type

```rust
pub type Effect = Pin<Box<dyn Future<Output = ()> + Send>>;
```

### Manual Implementation

```rust
impl Component for MyComponent {
    fn effects(&self, ctx: &Context) -> Vec<Effect> {
        vec![
            Box::pin(async move {
                // Async task
            })
        ]
    }
}
```

## node! Macro

### Syntax Reference

```rust
node! {
    // Element types
    div(...) [...],
    text(...),
    richtext(...) [...],
    vstack(...) [...],
    hstack(...) [...],
    input(...),
    spacer(n),
    node(component),

    // Properties (in parentheses)
    prop: value,
    flag,  // Boolean flags

    // Children (in brackets)
    [
        child1,
        child2,
    ],

    // Event handlers (start with @)
    @event: handler,
}
```

### Property Shortcuts

| Short | Full | Type |
|-------|------|------|
| `bg` | `background` | Color |
| `dir` | `direction` | Direction |
| `pad` | `padding` | u16 (all sides) |
| `pad_h` | - | u16 (horizontal) |
| `pad_v` | - | u16 (vertical) |
| `w` | `width` | u16 |
| `h` | `height` | u16 |
| `w_frac` | - | f32 (0.0-1.0) |
| `h_frac` | - | f32 (0.0-1.0) |
| `w_auto` | - | flag |
| `h_auto` | - | flag |
| `w_content` | - | flag |
| `h_content` | - | flag |
| `justify` | `justify_content` | JustifyContent |
| `align` | `align_items` | AlignItems |
| `align_self` | - | AlignSelf |

### Color Values

```rust
// Named colors (no prefix needed)
color: red
color: bright_blue

// Hex strings
color: "#FF5733"
color: "#F50"

// Expressions (need parentheses)
color: (Color::Rgb(255, 0, 0))
color: (my_color_variable)

// Conditional
color: (if condition { red } else { blue })

// Optional (with ! suffix)
color: (optional_color)!
```

### Event Handlers

| Syntax | Description |
|--------|-------------|
| `@click: handler` | Mouse click |
| `@char('x'): handler` | Character key |
| `@key(enter): handler` | Special key |
| `@key(Char('-')): handler` | Character via Key enum |
| `@key(ctrl + 'c'): handler` | Key with modifiers |
| `@char_global('q'): handler` | Global character |
| `@key_global(esc): handler` | Global special key |
| `@key_global(ctrl + enter): handler` | Global key with modifiers |
| `@focus: handler` | Gained focus |
| `@blur: handler` | Lost focus |
| `@any_char: \|ch\| handler` | Any character |

## Helper Macros

### color_value!

Internal macro for parsing color values in node!:

```rust
color_value!(red)           // Named color
color_value!("#FF0000")     // Hex color
color_value!((expr))        // Expression
```

### direction_value!

Internal macro for parsing directions:

```rust
direction_value!(horizontal)
direction_value!(vertical)
direction_value!(h)  // Short for horizontal
direction_value!(v)  // Short for vertical
```

### justify_value!

Internal macro for parsing justify content values:

```rust
justify_value!(start)
justify_value!(center)
justify_value!(end)
justify_value!(space_between)
justify_value!(space_around)
justify_value!(space_evenly)
```

### align_items_value!

Internal macro for parsing align items values:

```rust
align_items_value!(start)
align_items_value!(center)
align_items_value!(end)
```

### align_self_value!

Internal macro for parsing align self values:

```rust
align_self_value!(auto)
align_self_value!(start)
align_self_value!(center)
align_self_value!(end)
```

## Type Aliases

```rust
pub type ComponentId = String;
pub type TopicName = String;
```

## Traits

### MessageExt

Extension trait for message downcasting:

```rust
pub trait MessageExt {
    fn downcast<T: Any>(&self) -> Option<&T>;
}
```

### StateExt

Extension trait for state downcasting:

```rust
pub trait StateExt {
    fn downcast<T: Any>(&self) -> Option<&T>;
}
```

## Error Types

RxTUI uses `std::io::Result` for most operations that can fail (terminal I/O).

## Platform Support

- **Unix/Linux**: Full support
- **macOS**: Full support
- **Windows**: Supported via crossterm backend

## Feature Flags

| Flag | Description |
|------|-------------|
| `effects` | Enable async effects system (requires tokio) |

## Thread Safety

- Components must be `Send + Sync + 'static`
- State and Messages must be `Send + Sync + 'static`
- Effects run on a separate Tokio runtime

## Performance Considerations

- Virtual DOM diffing minimizes updates
- Double buffering eliminates flicker
- Cell-level diffing reduces terminal I/O
- Lazy state cloning only when modified
- Topic messages use zero-copy routing when possible


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to RxTUI

Thank you for your interest in contributing to RxTUI! We welcome contributions from everyone.

## How to Contribute

### Reporting Issues

If you find a bug or have a feature request, please open an issue on our [GitHub repository](https://github.com/yourusername/rxtui/issues). When reporting issues, please include:

- A clear description of the problem
- Steps to reproduce the issue
- Expected behavior vs actual behavior
- Your environment (OS, Rust version, etc.)
- Any relevant code snippets or error messages

### Submitting Pull Requests

1. **Fork the repository** and create your branch from `main`
2. **Make your changes** following our code style guidelines
3. **Add tests** for any new functionality
4. **Update documentation** if you've changed APIs
5. **Ensure all tests pass** with `cargo test`
6. **Run formatting** with `cargo fmt`
7. **Check linting** with `cargo clippy`
8. **Submit a pull request** with a clear description of your changes

### Code Style

- Follow Rust's standard naming conventions
- Use `rustfmt` for code formatting
- Keep functions focused and small
- Add comments for complex logic
- Write clear commit messages

### Testing

- Write unit tests for new functionality
- Ensure all existing tests pass
- Add integration tests for new features
- Test on multiple platforms if possible

### Documentation

- Update relevant documentation for API changes
- Add examples for new features
- Keep code comments up to date
- Update the CHANGELOG for notable changes

## Development Setup

See [DEVELOPMENT.md](DEVELOPMENT.md) for detailed setup instructions.

## Code of Conduct

Please be respectful and inclusive in all interactions. We aim to create a welcoming environment for all contributors.

## Questions?

Feel free to open an issue for any questions about contributing!

## License

By contributing to RxTUI, you agree that your contributions will be licensed under the Apache License 2.0.


================================================
FILE: Cargo.toml
================================================
[package]
name = "rxtui-workspace"
version = "0.1.8"
edition = "2021"
publish = false

[features]
default = ["effects", "components"]
effects = ["rxtui/effects"]
components = ["rxtui/components"]

[workspace]
resolver = "2"
members = [
    "rxtui",
    "rxtui-macros",
]

[workspace.package]
version = "0.1.8"
edition = "2024"
authors = ["Microsandbox Team"]
license = "Apache-2.0"
repository = "https://github.com/microsandbox/rxtui"
homepage = "https://github.com/microsandbox/rxtui"
documentation = "https://docs.rs/rxtui"

[workspace.dependencies]
serde = { version = "1.0", features = ["derive"] }
thiserror = "2.0"

[dependencies]
rxtui = { path = "rxtui", features = ["effects", "components"] }
tokio = { version = "1", features = ["rt", "rt-multi-thread", "time", "sync", "macros"] }

# Profile configurations
[profile.release]
opt-level = 3
lto = true
codegen-units = 1


================================================
FILE: DEVELOPMENT.md
================================================
# Development Guide

This guide will help you set up your development environment for working on RxTUI.

## Prerequisites

- Rust 1.70+ (install via [rustup](https://rustup.rs/))
- Git
- A terminal emulator with Unicode support

## Setting Up Your Development Environment

### 1. Clone the Repository

```bash
git clone https://github.com/yourusername/rxtui.git
cd rxtui
```

### 2. Install Dependencies

```bash
cargo build
```

This will download and compile all dependencies.

### 3. Run Tests

```bash
# Run all tests
cargo test

# Run tests with output
cargo test -- --nocapture

# Run specific test
cargo test test_name
```

### 4. Build Examples

```bash
# Build all examples
cargo build --examples

# Run specific example
cargo run --example demo
```

## Project Structure

```
rxtui/
├── rxtui/               # Main library crate
│   ├── lib/            # Library source code
│   │   ├── app/        # Application core
│   │   ├── components/ # Built-in components
│   │   ├── macros/     # Macro implementations
│   │   └── ...
│   ├── examples/       # Example applications
│   └── tests/          # Integration tests
├── rxtui-macros/       # Proc macro crate
├── docs/               # Documentation
└── examples/           # Standalone examples
```

## Development Workflow

### Running in Development Mode

For faster iteration during development:

```bash
# Watch for changes and rebuild
cargo watch -x build

# Run tests on file change
cargo watch -x test

# Run specific example on change
cargo watch -x "run --example demo"
```

### Debugging

Enable debug output:

```rust
// In your app configuration
let app = App::new()?
    .render_config(RenderConfig {
        use_double_buffer: false,  // Disable for debugging
        use_diffing: false,        // See all renders
        poll_duration_ms: 100,     // Slower polling
    });
```

### Performance Profiling

```bash
# Build with release optimizations but keep debug symbols
cargo build --release --features debug

# Profile with your favorite tool
# Example with perf on Linux:
perf record --call-graph=dwarf cargo run --release --example demo
perf report
```

## Common Development Tasks

### Adding a New Component

1. Create component file in `rxtui/lib/components/`
2. Implement the Component trait
3. Add to `mod.rs` exports
4. Write tests in component file
5. Add example usage

### Modifying the node! Macro

1. Edit `rxtui/lib/macros/node.rs`
2. Test with `cargo test macro_tests`
3. Update documentation if syntax changes
4. Add examples of new syntax

### Adding Event Handlers

1. Define event in `rxtui/lib/app/events.rs`
2. Add handler parsing in macro
3. Implement event dispatch
4. Write tests for new events

## Testing Guidelines

### Unit Tests

Place unit tests in the same file as the code:

```rust
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_feature() {
        // Test implementation
    }
}
```

### Integration Tests

Place in `rxtui/tests/` directory:

```rust
use rxtui::prelude::*;

#[test]
fn test_complete_flow() {
    // Test complete user flow
}
```

### Visual Tests

For testing rendered output:

```rust
#[test]
fn test_rendering() {
    let buffer = TestBuffer::new(80, 24);
    // Render and assert buffer contents
}
```

## Code Quality

### Before Committing

Run these checks:

```bash
# Format code
cargo fmt

# Run clippy
cargo clippy -- -D warnings

# Run tests
cargo test

# Check documentation
cargo doc --no-deps --open
```

### Continuous Integration

Our CI runs:
- `cargo fmt -- --check`
- `cargo clippy -- -D warnings`
- `cargo test`
- `cargo doc`

## Troubleshooting

### Common Issues

**Terminal doesn't display correctly**
- Ensure your terminal supports Unicode
- Check TERM environment variable
- Try different terminal emulator

**Tests fail with display issues**
- Tests should use headless mode
- Mock terminal for testing

**Performance issues**
- Enable optimizations: `cargo build --release`
- Profile to find bottlenecks
- Check render configuration

## Getting Help

- Open an issue on GitHub
- Join our community discussions
- Check existing issues for solutions

## Release Process

1. Update version in `Cargo.toml`
2. Update CHANGELOG.md
3. Run full test suite
4. Create git tag
5. Push to trigger CI release

## Resources

- [Rust Book](https://doc.rust-lang.org/book/)
- [Cargo Documentation](https://doc.rust-lang.org/cargo/)
- [Terminal Escape Sequences](https://en.wikipedia.org/wiki/ANSI_escape_code)
- [crossterm Documentation](https://docs.rs/crossterm/)


================================================
FILE: DOCS.md
================================================
# RxTUI Documentation

RxTUI is a reactive terminal user interface framework for Rust that brings modern component-based architecture to the terminal. It combines React-like patterns with efficient terminal rendering through virtual DOM diffing.

## Table of Contents

- [Getting Started](#getting-started)
- [Terminal Modes](#terminal-modes)
- [Components](#components)
- [The node! Macro](#the-node-macro)
- [State Management](#state-management)
- [Message Handling](#message-handling)
- [Topic-Based Communication](#topic-based-communication)
- [Layout System](#layout-system)
- [Styling](#styling)
- [Event Handling](#event-handling)
- [Built-in Components](#built-in-components)
- [Effects (Async)](#effects-async)
- [Examples](#examples)

## Getting Started

Add RxTUI to your `Cargo.toml`:

```toml
[dependencies]
rxtui = "0.1"
tokio = { version = "1.0", features = ["full"] }  # Required for async effects
```

Note: The `effects` feature is enabled by default. To disable it:

```toml
[dependencies]
rxtui = { version = "0.1", default-features = false }
```

Create your first app:

```rust
use rxtui::prelude::*;

#[derive(Component)]
struct HelloWorld;

impl HelloWorld {
    #[view]
    fn view(&self, ctx: &Context) -> Node {
        node! {
            div(bg: blue, pad: 2, @key_global(esc): ctx.handler(())) [
                text("Hello, Terminal!", color: white, bold),
                text("Press Esc to exit", color: white)
            ]
        }
    }
}

fn main() -> std::io::Result<()> {
    App::new()?.run(HelloWorld)
}
```

<div align='center'>• • •</div>

## Terminal Modes

RxTUI supports two terminal rendering modes: **Alternate Screen** (default) and **Inline**.

#### Alternate Screen Mode (Default)

The default mode uses the terminal's alternate screen buffer. This is ideal for full-screen applications:

```rust
fn main() -> std::io::Result<()> {
    App::new()?.run(MyComponent)  // Uses alternate screen
}
```

Characteristics:
- Takes over the full terminal screen
- Content disappears when the app exits
- Best for interactive applications, editors, dashboards

#### Inline Mode

Inline mode renders directly in the terminal buffer without switching screens. Content persists after the app exits, making it ideal for CLI tools:

```rust
fn main() -> std::io::Result<()> {
    // Simple inline mode with defaults
    App::inline()?.run(MyComponent)?;

    // This prints after the UI since content is preserved
    println!("Done! The UI above is preserved.");
    Ok(())
}
```

Characteristics:
- Renders in the main terminal buffer
- Content persists in terminal history after exit
- Height is content-based by default (grows to fit)
- Mouse capture disabled by default (allows terminal scrolling)

#### Custom Inline Configuration

For fine-grained control over inline rendering:

```rust
use rxtui::{App, InlineConfig, InlineHeight};

fn main() -> std::io::Result<()> {
    let config = InlineConfig {
        // Fixed height of 10 lines
        height: InlineHeight::Fixed(10),
        // Show cursor during rendering
        cursor_visible: true,
        // Preserve output after exit
        preserve_on_exit: true,
        // Don't capture mouse (allow terminal scrolling)
        mouse_capture: false,
    };

    App::inline_with_config(config)?.run(MyComponent)
}
```

#### Height Modes

Control how inline mode determines rendering height:

```rust
// Fixed number of lines
InlineHeight::Fixed(10)

// Grow to fit content, with optional maximum
InlineHeight::Content { max: Some(24) }  // Max 24 lines
InlineHeight::Content { max: None }       // No limit (default)

// Fill remaining terminal space below cursor
InlineHeight::Fill { min: 5 }  // At least 5 lines
```

<div align='center'>• • •</div>

## Components

Everything in RxTUI is a component. Think of them as self-contained UI pieces that know how to manage their own state and behavior. Components have three main capabilities: handling events (through `update`), rendering UI (through `view`), and running async operations (through `effect`):

#### Basic Component

```rust
#[derive(Component)]
struct TodoList;

impl TodoList {
    #[update]
    fn update(&self, ctx: &Context, msg: TodoMsg, mut state: TodoState) -> Action {
        // Messages come here from events in your view
        // You update state, then return Action::update(state) to re-render
    }

    #[view]
    fn view(&self, ctx: &Context, state: TodoState) -> Node {
        // This renders your UI using the current state
        // Uses the node! macro to build the UI tree
    }

    #[effect]
    async fn fetch_todos(&self, ctx: &Context, state: TodoState) {
        // Async effects for background tasks
        // Useful for timers, API calls, or any async operation
    }
}
```

#### Component Trait

The `#[derive(Component)]` macro automatically implements the Component trait. You can also implement it manually:

```rust
impl Component for MyComponent {
    fn update(&self, ctx: &Context, msg: Box<dyn Message>, topic: Option<&str>) -> Action {
        // Handle messages
    }

    fn view(&self, ctx: &Context) -> Node {
        // Return UI tree
    }

    fn effects(&self, ctx: &Context) -> Vec<Effect> {
        // Return async effects
    }
}
```

#### Complete Working Example

Here's a complete working example of a stopwatch component with async effects:

```rust
use rxtui::prelude::*;

#[derive(Component)]
struct Stopwatch;

impl Stopwatch {
    #[update]
    fn update(&self, _ctx: &Context, tick: bool, state: u64) -> Action {
        if !tick {
            return Action::exit();
        }
        Action::update(state + 10)
    }

    #[view]
    fn view(&self, ctx: &Context, state: u64) -> Node {
        let seconds = state / 1000;
        let centiseconds = (state % 1000) / 10;

        node! {
            div(
                pad: 2,
                align: center,
                w_frac: 1.0,
                gap: 1,
                @key(esc): ctx.handler(false),
                @char_global('q'): ctx.handler(false)
            ) [
                richtext[
                    text("Elapsed: ", color: white),
                    text(
                        format!(" {}.{:02}s ", seconds, centiseconds),
                        color: "#ffffff",
                        bg: "#9d29c3",
                        bold
                    ),
                ],
                text("press esc or q to exit", color: bright_black)
            ]
        }
    }

    #[effect]
    async fn tick(&self, ctx: &Context) {
        loop {
            tokio::time::sleep(std::time::Duration::from_millis(10)).await;
            ctx.send(true);
        }
    }
}

fn main() -> std::io::Result<()> {
    App::new()?.fast_polling().run(Stopwatch)
}
```

This example demonstrates:
- State management with the `#[update]` method handling timer ticks
- Async effects with the `#[effect]` method for continuous updates
- Rich text formatting with inline styles and hex colors
- Global keyboard event handling with `@key` and `@char_global`
- Layout control with centering and responsive width (`w_frac: 1.0`)

<div align='center'>• • •</div>

## The node! Macro

The `node!` macro is how you actually build your UI. It gives you a clean, declarative syntax that lives inside your component's `view` method. Instead of imperatively creating and configuring widgets, you describe what the UI should look like:

#### Basic Syntax

```rust
node! {
    // Root node
    div(...<properties>, ...<handlers>) [

        // Children nodes here
        text("content", ...<properties>),
        div(...) [

            // Nested nodes
            ...<children>
        ]
    ]
}
```

Example:
```rust
node! {
    div(
        bg: blue,
        pad: 2,
        border: white,
        @key(enter): ctx.handler("submit"),
        @click: ctx.handler("clicked")
    ) [
        richtext(align: center, wrap: word) [
            text("Welcome to ", color: bright_white),
            text("RxTUI", color: yellow, bold),
            text("!", color: bright_white)
        ],
        div [
            text("Nested content")
        ]
    ]
}
```

#### Elements

##### Expressions

You can use any Rust expression that returns a `Node` by wrapping it in parentheses:

```rust
node! {
    div [
        // Variable
        (my_node_variable),

        // Match expression
        (match state.status {
            Loading => node! { text("Loading...") },
            Ready => node! { text("Ready!") },
        }),

        // If expression
        (if condition {
            node! { text("True branch") }
        } else {
            node! { text("False branch") }
        }),

        // Method call
        (self.create_node()),
    ]
}
```

##### Spread Operator

Use the `...` spread operator to expand a `Vec<Node>` as children:

```rust
node! {
    div [
        // Spread a vector of nodes
        ...(vec![
            node! { text("Item 1") },
            node! { text("Item 2") },
            node! { text("Item 3") },
        ]),

        // Spread from iterator
        ...(state.items.iter().map(|item| {
            node! {
                div(pad: 1) [
                    text(&item.name)
                ]
            }
        }).collect::<Vec<Node>>()),

        // Combine with regular children
        text("Header", bold),
        ...(item_nodes),
        text("Footer"),
    ]
}
```

This is particularly useful for rendering lists or collections dynamically.

##### Div Container

```rust
node! {
    div(
        // Layout
        dir: vertical,      // or horizontal, v, h
        gap: 2,            // space between children
        wrap: wrap,        // wrap mode

        // Sizing
        w: 50,             // fixed width
        h: 20,             // fixed height
        w_frac: 0.5,        // 50% of parent width
        h_frac: 0.8,        // 80% of parent height
        w_auto,            // automatic width
        h_content,         // size to content

        // Styling
        bg: blue,          // background color
        pad: 2,            // padding all sides
        pad_h: 1,          // horizontal padding
        pad_v: 1,          // vertical padding

        // Borders
        border: white,     // border color
        border_style: rounded,
        border_color: yellow,
        border_edges: BorderEdges::TOP | BorderEdges::BOTTOM,

        // Interaction
        focusable,         // can receive focus
        overflow: scroll,  // scroll, hidden, auto
        show_scrollbar: true,

        // Positioning
        absolute,          // absolute positioning
        top: 5,
        left: 10,
        z: 100            // z-index
    ) [
        // Children here
    ]
}
```

##### Text

```rust
node! {
    div [
        // Simple text
        text("Hello"),

        // Styled text
        text("Styled", color: red, bold, italic, underline),

        // Dynamic text
        text(format!("Count: {}", count)),

        // Text with wrapping
        text("Long text...", wrap: word),

        // Text with alignment
        text("Centered", align: center),
        text("Right aligned", align: right)
    ]
}
```

##### Rich Text

```rust
node! {
    div [
        richtext [
            text("Normal "),
            text("Bold", bold),
            text(" and "),
            text("Colored", color: red)
        ],

        // With top-level styling
        richtext(wrap: word) [
            text("Line 1 "),
            text("Important", color: yellow, bold),
            text(" continues...")
        ],

        // With alignment
        richtext(align: center) [
            text("Centered "),
            text("rich text", bold)
        ]
    ]
}
```

##### Stacks

```rust
node! {
    div [
        // Vertical stack (default)
        vstack [
            text("Top"),
            text("Bottom")
        ],

        // Horizontal stack
        hstack(gap: 2) [
            text("Left"),
            text("Right")
        ]
    ]
}
```

##### Components

```rust
node! {
    div [
        // Embed other components
        node(MyComponent::new("config")),
        node(Counter)
    ]
}
```

##### Spacers

```rust
node! {
    div [
        text("Top"),
        spacer(2),  // 2 lines of space
        text("Bottom")
    ]
}
```

#### Event Handlers

```rust
node! {
    div(
        focusable,
        // Mouse events
        @click: ctx.handler(Msg::Clicked),
        // Keyboard events (requires focus)
        @char('a'): ctx.handler(Msg::KeyA),
        @key(enter): ctx.handler(Msg::Enter),
        @key(Char('-')): ctx.handler(Msg::Minus),
        // Focus events
        @focus: ctx.handler(Msg::Focused),
        @blur: ctx.handler(Msg::Blurred),
        // Global events (work without focus)
        @char_global('q'): ctx.handler(Msg::Quit),
        @key_global(esc): ctx.handler(Msg::Exit),
        // Any character handler
        @any_char: |ch| ctx.handler(Msg::Typed(ch))
    ) [
        text("Interactive")
    ]
}
```

#### Optional Properties

Use `!` suffix for optional properties:

```rust
node! {
    div(
        // Only applied if Some
        bg: (optional_color)!,
        w: (optional_width)!,
        border: (if selected { Some(Color::Yellow) } else { None })!
    ) [
        text("Conditional styling")
    ]
}
```

<div align='center'>• • •</div>

## State Management

These are the heart of your component's logic. State is just your data - what your component needs to remember.

#### Component State

```rust
#[derive(Debug, Clone, Default)]
struct MyState {
    counter: i32,
    text: String,
}

impl MyComponent {
    #[update]
    fn update(&self, ctx: &Context, msg: MyMsg, mut state: MyState) -> Action {
        // The #[update] macro automatically fetches state
        // and passes it as the last parameter

        state.counter += 1;
        Action::update(state)  // Save the new state
    }

    #[view]
    fn view(&self, ctx: &Context, state: MyState) -> Node {
        // The #[view] macro automatically fetches state
        node! {
            div [
                text(format!("Counter: {}", state.counter))
            ]
        }
    }
}
```

#### Manual State Access

```rust
fn update(&self, ctx: &Context, msg: Box<dyn Message>, _topic: Option<&str>) -> Action {
    // Manually get state (or initialize with Default)
    let mut state = ctx.get_state::<MyState>();

    // Modify state
    state.counter += 1;

    // Return updated state
    Action::update(state)
}
```

<div align='center'>• • •</div>

## Message Handling

Messages are how components respond to events - user clicks, key presses, timers firing. When a message arrives, you update your state, and the UI automatically re-renders.

#### Basic Messages

```rust
#[derive(Debug, Clone)]
enum MyMsg {
    Click,
    KeyPress(char),
    Update(String),
}

impl MyComponent {
    #[update]
    fn update(&self, ctx: &Context, msg: MyMsg, mut state: MyState) -> Action {
        match msg {
            MyMsg::Click => {
                state.clicked = true;
                Action::update(state)
            }
            MyMsg::KeyPress(ch) => {
                state.text.push(ch);
                Action::update(state)
            }
            MyMsg::Update(text) => {
                state.text = text;
                Action::update(state)
            }
        }
    }
}
```

#### Actions

Update methods return an Action:

```rust
pub enum Action {
    Update(Box<dyn State>),              // Update component state
    UpdateTopic(String, Box<dyn State>), // Update topic state
    None,                                // No action
    Exit,                                // Exit application
}
```

#### Message with Value

```rust
// In view
node! {
    div [
        @any_char: ctx.handler_with_value(|ch| Box::new(MyMsg::Typed(ch)))
    ]
}
```

<div align='center'>• • •</div>

## Topic-Based Communication

Topics enable cross-component communication without direct references.

#### Sending to Topics

```rust
impl Dashboard {
    #[update]
    fn update(&self, ctx: &Context, msg: DashboardMsg, state: DashboardState) -> Action {
        match msg {
            DashboardMsg::NotifyAll => {
                // Send message to topic
                ctx.send_to_topic("notifications", NotificationMsg::Alert);
                Action::none()
            }
        }
    }
}
```

#### Receiving Topic Messages

```rust
impl NotificationBar {
    // Static topic
    #[update(msg = LocalMsg, topics = ["notifications" => NotificationMsg])]
    fn update(&self, ctx: &Context, messages: Messages, mut state: State) -> Action {
        match messages {
            Messages::LocalMsg(msg) => {
                // Handle local messages
            }
            Messages::NotificationMsg(msg) => {
                // Handle topic messages
                // Returning Action::update claims topic ownership
                state.notifications.push(msg);
                Action::update(state)
            }
        }
    }
}
```

#### Dynamic Topics

```rust
struct Counter {
    topic_name: String,  // Topic determined at runtime
}

impl Counter {
    // Dynamic topic from field
    #[update(msg = CounterMsg, topics = [self.topic_name => ResetSignal])]
    fn update(&self, ctx: &Context, messages: Messages, mut state: CounterState) -> Action {
        match messages {
            Messages::CounterMsg(msg) => { /* ... */ }
            Messages::ResetSignal(_) => {
                // Reset when signal received
                Action::update(CounterState::default())
            }
        }
    }
}
```

#### Topic State

```rust
// Write topic state (first writer becomes owner)
Action::UpdateTopic("app.settings".to_string(), Box::new(settings))

// Read topic state from any component
let settings: Option<Settings> = ctx.read_topic("app.settings");
```

<div align='center'>• • •</div>

## Layout System

RxTUI provides a flexible layout system with multiple sizing modes.

#### Dimension Types

```rust
pub enum Dimension {
    Fixed(u16),       // Exact size in cells
    Percentage(f32),  // Percentage of parent (stored 0.0 to 1.0)
    Auto,            // Share remaining space equally
    Content,         // Size based on children
}
```

#### Layout Examples

```rust
node! {
    // Fixed layout
    div(w: 80, h: 24) [
        text("Fixed size")
    ],

    // Percentage-based
    div(w_frac: 0.5, h_frac: 0.8) [
        text("50% width, 80% height")
    ],

    // Auto sizing - share remaining space
    hstack [
        div(w: 20) [ text("Fixed") ],
        div(w_auto) [ text("Auto 1") ],  // Gets 50% of remaining
        div(w_auto) [ text("Auto 2") ]   // Gets 50% of remaining
    ],

    // Content-based sizing
    div(w_content, h_content) [
        text("Size fits content")
    ]
}
```

#### Direction and Wrapping

```rust
node! {
    // Vertical layout (default)
    div(dir: vertical, gap: 2) [
        text("Line 1"),
        text("Line 2")
    ],

    // Horizontal layout
    div(dir: horizontal, gap: 1) [
        text("Col 1"),
        text("Col 2")
    ],

    // With wrapping
    div(dir: horizontal, wrap: wrap, w: 40) [
        // Children wrap to next line when width exceeded
        div(w: 15) [ text("Item 1") ],
        div(w: 15) [ text("Item 2") ],
        div(w: 15) [ text("Item 3") ]  // Wraps to next line
    ]
}
```

#### Scrolling

```rust
node! {
    div(
        h: 10,              // Fixed container height
        overflow: scroll,   // Enable scrolling
        show_scrollbar: true,
        focusable          // Must be focusable for keyboard scrolling
    ) [
        // Content taller than container
        text("Line 1"),
        text("Line 2"),
        // ... many more lines
        text("Line 50")
    ]
}
```

Scrolling controls:

- **Arrow keys**: Scroll up/down by 1 line
- **Page Up/Down**: Scroll by container height
- **Home/End**: Jump to top/bottom
- **Mouse wheel**: Scroll up/down

Note: Only vertical scrolling is currently implemented.

<div align='center'>• • •</div>

## Styling

#### Colors

RxTUI supports multiple color formats:

```rust
node! {
    div [
        // Named colors
        text("Red", color: red),
        text("Bright Blue", color: bright_blue),

        // Hex colors
        text("Hex", color: "#FF5733"),

        // RGB
        text("RGB", color: (Color::Rgb(255, 128, 0))),

        // Conditional
        text("Status", color: (if ok { Color::Green } else { Color::Red }))
    ]
}
```

Available named colors:

- Basic: `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`
- Bright: `bright_black`, `bright_red`, `bright_green`, `bright_yellow`, `bright_blue`, `bright_magenta`, `bright_cyan`, `bright_white`

#### Text Alignment

Text and RichText nodes support horizontal alignment within their containers:

```rust
node! {
    div(w: 50) [
        // Basic text alignment
        text("Left aligned", align: left),
        text("Centered text", align: center),
        text("Right aligned", align: right),

        // RichText alignment
        richtext(align: center) [
            text("This "),
            text("rich text", bold),
            text(" is centered")
        ],

        // Alignment with wrapping
        text(
            "Long text that wraps to multiple lines. Each line will be aligned.",
            wrap: word,
            align: right
        )
    ]
}
```

Note: Text nodes with alignment automatically expand to fill their parent's width to enable proper alignment calculation.

#### Div Alignment (Flexbox-style)

Divs support CSS Flexbox-style alignment for their children along both the main and cross axes:

```rust
node! {
    // Justify content (main axis)
    div(dir: h, justify: center, w: 50) [
        div(w: 10, h: 3, bg: red) [],
        div(w: 10, h: 3, bg: green) [],
        div(w: 10, h: 3, bg: blue) []
    ],

    // Align items (cross axis)
    div(dir: h, align: end, w: 50, h: 10) [
        div(w: 10, h: 3, bg: red) [],
        div(w: 10, h: 5, bg: green) [],
        div(w: 10, h: 7, bg: blue) []
    ],

    // Combined justify and align
    div(dir: v, justify: space_between, align: center, w: 40, h: 20) [
        text("Item 1"),
        text("Item 2"),
        text("Item 3")
    ],

    // With align_self override
    div(dir: h, align: start, w: 50, h: 10) [
        div(w: 10, h: 3, bg: red) [],
        div(w: 10, h: 3, bg: green, align_self: center) [],
        div(w: 10, h: 3, bg: blue, align_self: end) []
    ]
}
```

**JustifyContent** (distributes items along main axis):
- `start` - Pack items at the start (default)
- `center` - Center items
- `end` - Pack items at the end
- `space_between` - Distribute evenly, first at start, last at end
- `space_around` - Equal space around each item
- `space_evenly` - Equal space between and around items

**AlignItems** (aligns items on cross axis):
- `start` - Align at the start (default)
- `center` - Center items
- `end` - Align at the end

**AlignSelf** (per-child cross axis override):
- `auto` - Use parent's align_items (default)
- `start` - Align at the start
- `center` - Center
- `end` - Align at the end

The main axis is determined by the direction:
- `dir: h` (horizontal) - main axis is horizontal, cross axis is vertical
- `dir: v` (vertical) - main axis is vertical, cross axis is horizontal

#### Borders

```rust
node! {
    div [
        // Simple border
        div(border: white) [ text("Single border") ],

        // Border styles
        div(
            border_style: rounded,
            border_color: cyan
        ) [
            text("Rounded border")
        ],

        // Partial borders
        div(
            border: white,
            border_edges: top | bottom
        ) [
            text("Top and bottom only")
        ]
    ]
}
```

Border styles:

- `Single` - Normal lines
- `Double` - Double lines
- `Rounded` - Rounded corners
- `Thick` - Thick lines

#### Spacing

```rust
node! {
    div [
        // Padding
        div(pad: 2) [ text("All sides") ],
        div(pad_h: 2) [ text("Horizontal") ],
        div(pad_v: 1) [ text("Vertical") ],
        div(padding: (Spacing::new(1, 2, 3, 4))) [ text("Custom") ],

        // Gap between children
        div(gap: 2) [
            text("Item 1"),
            text("Item 2")  // 2 cells gap
        ]
    ]
}
```

#### Focus Styles

```rust
node! {
    div(
        focusable,
        border: white,
        focus_style: ({
            Style::default()
                .background(Color::Blue)
                .border(Color::Yellow)
        })
    ) [
        text("Changes style when focused")
    ]
}
```

<div align='center'>• • •</div>

## Event Handling

#### Focus-Based Events

Most events require the element to be focused:

```rust
node! {
    div(
        focusable,

        // Mouse
        @click: ctx.handler(Msg::Clicked),

        // Keyboard
        @char('a'): ctx.handler(Msg::PressedA),
        @key(enter): ctx.handler(Msg::Confirmed),
        @key(backspace): ctx.handler(Msg::Delete),

        // Focus
        @focus: ctx.handler(Msg::GainedFocus),
        @blur: ctx.handler(Msg::LostFocus)
    ) [
        text("Click or press keys")
    ]
}
```

#### Global Events

Global events work regardless of focus:

```rust
node! {
    div(
        // Application-wide shortcuts
        @char_global('q'): ctx.handler(Msg::Quit),
        @key_global(esc): ctx.handler(Msg::Cancel),
        @char_global('/'): ctx.handler(Msg::Search)
    ) [
        // Children here
    ]
}
```

#### Focus Navigation

- **Tab**: Move to next focusable element
- **Shift+Tab**: Move to previous focusable element

#### Programmatic Focus

Use the `Context` focus helpers to move focus immediately after a render:

```rust
#[view]
fn view(&self, ctx: &Context, state: MyState) -> Node {
    if ctx.is_first_render() {
        ctx.focus_self(); // focus the first focusable node in this component
    }

    node! {
        div [
            input(focusable),
            button(focusable)
        ]
    }
}
```

- `ctx.focus_self()` focuses the first focusable element inside the component's subtree.
- `ctx.focus_first()` focuses the first focusable element in the entire app.
- `ctx.is_first_render()` is handy for gating autofocus so you do not wrestle with user-driven focus changes later.

<div align='center'>• • •</div>

## Built-in Components

#### TextInput

A full-featured text input component:

```rust
use rxtui::components::TextInput;

node! {
    div [
        // Basic input
        input(placeholder: "Enter name...", focusable),

        // Custom styling
        input(
            placeholder: "Password...",
            password,              // Mask input
            border: yellow,
            w: 40,
            content_color: green,
            cursor_color: white
        ),

        // Or use the builder API
        node(
            TextInput::new()
                .placeholder("Email...")
                .width(50)
                .border(Color::Cyan)
                .focus_border(Color::Yellow)
        )
    ]
}
```

TextInput features:

- Full text editing (insert, delete, backspace)
- Cursor movement (arrows, Home/End)
- Word navigation (Alt+B/F or Ctrl+arrows)
- Word deletion (Ctrl+W, Alt+D)
- Line deletion (Ctrl+U/K)
- Password mode
- Placeholder text
- Customizable styling

<div align='center'>• • •</div>

## Effects (Async)

Effects enable async operations like timers, network requests, and file monitoring.

#### Basic Effect

```rust
use rxtui::prelude::*;
use std::time::Duration;

#[derive(Component)]
struct Timer;

#[component]  // Required to collect #[effect] methods
impl Timer {
    #[update]
    fn update(&self, ctx: &Context, msg: TimerMsg, mut state: TimerState) -> Action {
        match msg {
            TimerMsg::Tick => {
                state.seconds += 1;
                Action::update(state)
            }
        }
    }

    #[view]
    fn view(&self, ctx: &Context, state: TimerState) -> Node {
        node! {
            div [
                text(format!("Time: {}s", state.seconds))
            ]
        }
    }

    #[effect]
    async fn tick(&self, ctx: &Context) {
        loop {
            tokio::time::sleep(Duration::from_secs(1)).await;
            ctx.send(TimerMsg::Tick);
        }
    }
}
```

#### Multiple Effects

```rust
#[component]
impl MyComponent {
    #[effect]
    async fn monitor_file(&self, ctx: &Context) {
        // Watch for file changes
    }

    #[effect]
    async fn fetch_data(&self, ctx: &Context, state: MyState) {
        // Effects can access state
        if state.should_fetch {
            // Fetch from API
        }
    }
}
```

#### Manual Effects

```rust
impl Component for MyComponent {
    fn effects(&self, ctx: &Context) -> Vec<Effect> {
        vec![
            Box::pin(async move {
                // Async code
            })
        ]
    }
}
```

<div align='center'>• • •</div>

## Advanced Topics

#### Performance Tips

1. **Use keys for lists**: Helps with efficient diffing (not yet implemented)
2. **Minimize state updates**: Only update when necessary
3. **Use topics wisely**: Don't overuse for simple parent-child communication
4. **Profile rendering**: Use `RenderConfig` for debugging

#### Debugging

```rust
let mut app = App::new()?
    .render_config(RenderConfig {
        use_double_buffer: false,  // Disable for debugging
        use_diffing: false,        // Show all updates
        poll_duration_ms: 100,     // Slow down for observation
    });
app.run(MyComponent)?;
```


================================================
FILE: IMPLEMENTATION.md
================================================
# RxTUI - Implementation Details

## Overview

RxTUI is a reactive terminal user interface framework inspired by Elm's message-passing architecture and React's component model. It provides a declarative, component-based API for building interactive terminal applications with efficient rendering through virtual DOM diffing and advanced cross-component communication via topic-based messaging.

## Architecture

```text
┌─────────────────────────────────────────────────────────┐
│                     Component System                    │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐   │
│  │  Components  │  │   Messages   │  │    Topics    │   │
│  │  - update()  │  │  - Direct    │  │  - Ownership │   │
│  │  - view()    │  │  - Topic     │  │  - Broadcast │   │
│  │  - effects() │  │  - Async     │  │  - State     │   │
│  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘   │
│         │                 │                 │           │
│  ┌──────▼─────────────────▼─────────────────▼────────┐  │
│  │                     Context                       │  │
│  │  - StateMap: Component state storage              │  │
│  │  - Dispatcher: Message routing                    │  │
│  │  - TopicStore: Topic ownership & state            │  │
│  └──────────────────────┬────────────────────────────┘  │
└─────────────────────────┼───────────────────────────────┘
                          │
┌─────────────────────────▼──────────────────────────────┐
│                    Rendering Pipeline                  │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │
│  │     Node     │──│     VNode    │──│  RenderNode  │  │
│  │  (Component) │  │  (Virtual)   │  │ (Positioned) │  │
│  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘  │
│         │                 │                 │          │
│  ┌──────▼─────────────────▼─────────────────▼───────┐  │
│  │                   Virtual DOM (VDom)             │  │
│  │  - Diff: Compare old and new trees               │  │
│  │  - Patch: Generate minimal updates               │  │
│  │  - Layout: Calculate positions and sizes         │  │
│  └──────────────────────┬───────────────────────────┘  │
└─────────────────────────┼──────────────────────────────┘
                          │
┌─────────────────────────▼──────────────────────────────┐
│                     Terminal Output                    │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │
│  │Double Buffer │  │Cell Diffing  │  │  Optimized   │  │
│  │  Front/Back  │  │   Updates    │  │   Renderer   │  │
│  └──────────────┘  └──────────────┘  └──────────────┘  │
└────────────────────────────────────────────────────────┘
```

## Core Components

### 1. Component System (`lib/component.rs`)

The component system is the heart of the framework, providing a React-like component model with state management and message passing.

#### Component Trait

```rust
pub trait Component: 'static {
    fn update(&self, ctx: &Context, msg: Box<dyn Message>, topic: Option<&str>) -> Action {
        Action::default()
    }

    fn view(&self, ctx: &Context) -> Node;

    #[cfg(feature = "effects")]
    fn effects(&self, ctx: &Context) -> Vec<Effect> {
        vec![]
    }

    fn as_any(&self) -> &dyn Any;
    fn as_any_mut(&mut self) -> &mut dyn Any;
}
```

**Key Design Decisions:**
- Components are stateless - all state is managed by Context
- Update method receives optional topic for cross-component messaging
- Components can be derived using `#[derive(Component)]` macro
- Effects support async background tasks (with feature flag)
- Default implementations provided for update and effects

#### Message and State Traits

Both Message and State traits are auto-implemented for any type that is `Clone + Send + Sync + 'static`:

```rust
pub trait Message: Any + Send + Sync + 'static {
    fn as_any(&self) -> &dyn Any;
    fn clone_box(&self) -> Box<dyn Message>;
}

pub trait State: Any + Send + Sync + 'static {
    fn as_any(&self) -> &dyn Any;
    fn as_any_mut(&mut self) -> &mut dyn Any;
    fn clone_box(&self) -> Box<dyn State>;
}
```

**Extension Traits for Downcasting:**
- `MessageExt` provides `downcast<T>()` for message type checking
- `StateExt` provides `downcast<T>()` for state type checking

#### Actions

Components return actions from their update method:

```rust
#[derive(Default)]
pub enum Action {
    Update(Box<dyn State>),              // Update component's local state
    UpdateTopic(String, Box<dyn State>), // Update topic state (first writer owns)
    None,                                // No action needed
    #[default]
    Exit,                                // Exit the application
}
```

Helper methods for ergonomic construction:
```rust
Action::update(state)        // Create Update action
Action::update_topic(topic, state)  // Create UpdateTopic action
Action::none()              // Create None action
Action::exit()              // Create Exit action
```

### 2. Context System (`lib/app/context.rs`)

The Context provides components with everything they need to function:

#### Core Components

**Context Structure:**
- `current_component_id`: Component being processed
- `dispatch`: Message dispatcher
- `states`: Component state storage (StateMap)
- `topics`: Topic-based messaging (Arc<TopicStore>)
- `message_queues`: Regular message queues (Arc<RwLock<HashMap>>)
- `topic_message_queues`: Topic message queues (Arc<RwLock<HashMap>>)

**StateMap:**
- Stores component states with interior mutability using `Arc<RwLock<HashMap>>`
- `get_or_init<T>()`: Get state or initialize with Default, handles type mismatches
- Type-safe state retrieval with automatic downcasting
- Thread-safe with RwLock protection

**Dispatcher:**
- Routes messages to components or topics
- `send_to_id(component_id, message)`: Direct component messaging
- `send_to_topic(topic, message)`: Topic-based messaging
- Shared message queue storage with Context

**TopicStore:**
- Manages topic ownership (first writer becomes owner)
- Stores topic states separately from component states
- Tracks which component owns which topic via `owners: RwLock<HashMap<String, ComponentId>>`
- Thread-safe with RwLock protection
- `update_topic()`: Returns bool indicating if update was successful

#### Context Public API

```rust
impl Context {
    // Message handling
    pub fn handler<M: Message>(&self, msg: M) -> Box<dyn Fn() + 'static>;
    pub fn handler_with_value<F, M, T>(&self, f: F) -> Box<dyn Fn(T) + 'static>;

    // State management
    pub fn get_state<S: State + Default + Clone>(&self) -> S;
    pub fn get_state_or<S: State + Clone>(&self, default: S) -> S;

    // Direct messaging
    pub fn send<M: Message>(&self, msg: M);

    // Topic messaging
    pub fn send_to_topic<M: Message>(&self, topic: &str, msg: M);
    pub fn read_topic<S: State + Clone>(&self, topic: &str) -> Option<S>;
}
```

#### Message Flow

1. **Direct Messages**: Sent to specific component via `ctx.handler(msg)` which creates closures
2. **Topic Messages**: Sent via `ctx.send_to_topic(topic, msg)`
   - If topic has owner → delivered only to owner
   - If no owner → broadcast to all components until one claims it

### 3. Topic-Based Messaging System

A unique feature for cross-component communication without direct references:

#### Concepts

- **Topics**: Named channels for messages (e.g., "counter_a", "global_state")
- **Ownership**: First component to write to a topic becomes its owner
- **Unassigned Messages**: Messages to unclaimed topics are broadcast to all components

#### How It Works

1. **Sending Messages:**
   ```rust
   ctx.send_to_topic("my-topic", MyMessage);
   ```

2. **Claiming Ownership:**
   ```rust
   // First component to return this action owns the topic
   Action::UpdateTopic("my-topic".to_string(), Box::new(MyState))
   ```

3. **Handling Topic Messages (Using Macros):**
   ```rust
   // With the #[update] macro:
   #[update(msg = MyMsg, topics = ["my-topic" => TopicMsg])]
   fn update(&self, ctx: &Context, messages: Messages, mut state: MyState) -> Action {
       match messages {
           Messages::MyMsg(msg) => { /* handle regular message */ }
           Messages::TopicMsg(msg) => { /* handle topic message */ }
       }
   }

   // Dynamic topics from component fields:
   #[update(msg = MyMsg, topics = [self.topic_name => TopicMsg])]
   fn update(&self, ctx: &Context, messages: Messages, state: MyState) -> Action {
       // Topic name from self.topic_name field
   }
   ```

4. **Reading Topic State:**
   ```rust
   let state: Option<MyState> = ctx.read_topic("my-topic");
   ```

**Design Rationale:**
- Enables decoupled component communication
- Supports both single-writer/multiple-reader and broadcast patterns
- Automatic ownership management prevents conflicts
- Idempotent updates - multiple attempts to claim ownership are safe

### 4. Application Core (`lib/app/core.rs`)

The App struct manages the entire application lifecycle:

#### Initialization
```rust
App::new()  // Standard initialization
App::with_config(RenderConfig { ... })  // With custom config
```
- Enables terminal raw mode and alternate screen
- Hides cursor and enables mouse capture
- Initializes double buffer for flicker-free rendering
- Sets up event handling with crossterm
- Creates effect runtime (if feature enabled) using Tokio

#### Event Loop

The main loop (`run_loop`) follows this sequence:

1. **Component Tree Expansion**:
   - Start with root component
   - Recursively expand components to VNodes
   - Assign component IDs based on tree position using `ComponentId::child(index)` method (e.g., "0", "0.0", "0.1")

2. **Message Processing**:
   - Components drain all pending messages (regular + topic)
   - Messages trigger state updates via component's `update` method
   - Handle actions (Update, UpdateTopic, Exit, None)

3. **Virtual DOM Update**:
   - VDom diffs new tree against current
   - Generates patches for changes
   - Updates render tree

4. **Layout & Rendering**:
   - Calculate positions and sizes based on Dimension types
   - Render to back buffer
   - Diff buffers and apply changes to terminal

5. **Event Handling**:
   - Process keyboard/mouse events (poll with 16ms timeout by default)
   - Events trigger new messages via event handlers
   - Handle terminal resize events

6. **Effect Management** (if feature enabled):
   - Spawn effects for newly mounted components
   - Cleanup effects for unmounted components
   - Effects run in Tokio runtime with JoinHandle tracking

#### Component Tree Expansion

The `expand_component_tree` method is crucial:

1. Drains all messages for the component (both regular and topic messages)
2. Processes each message:
   - Regular messages → component's update
   - Topic messages → check if component handles topic
3. Handles actions:
   - `Update` → update component state via StateMap
   - `UpdateTopic` → update topic state, claim ownership if first
   - `Exit` → propagate exit signal
   - `None` → no operation
4. Calls component's `view` to get UI tree
5. Recursively expands child components

### 5. Node Types

Three levels of node representation:

#### Node (`lib/node/mod.rs`)
High-level component tree:
```rust
pub enum Node {
    Component(Arc<dyn Component>),  // Component instance (Arc for sharing)
    Div(Div<Node>),                 // Container with children
    Text(Text),                     // Text content
    RichText(RichText),            // Styled text with multiple spans
}
```

#### VNode (`lib/vnode.rs`)
Virtual DOM nodes after component expansion:
```rust
pub enum VNode {
    Div(Div<VNode>),        // Expanded div (generic over child type)
    Text(Text),             // Text node
    RichText(RichText),     // Rich text node
}
```

#### RenderNode (`lib/render_tree/node.rs`)
Positioned nodes ready for drawing:
```rust
pub struct RenderNode {
    pub node_type: RenderNodeType,
    pub x: u16, pub y: u16,           // Position
    pub width: u16, pub height: u16,   // Size
    pub content_width: u16,            // Actual content size
    pub content_height: u16,
    pub scroll_y: u16,                 // Vertical scroll offset
    pub scrollable: bool,              // Has overflow:scroll/auto
    pub style: Option<Style>,          // Visual style
    pub children: Vec<Rc<RefCell<RenderNode>>>,
    pub parent: Option<Weak<RefCell<RenderNode>>>,
    pub focusable: bool,
    pub focused: bool,
    pub dirty: bool,
    pub z_index: i32,
    // Event handlers stored as Rc<dyn Fn()>
}
```

### 6. Div System (`lib/node/div.rs`)

Divs are generic containers that can hold different child types:

```rust
pub struct Div<T> {
    pub children: Vec<T>,
    pub styles: DivStyles,           // Base, focus, hover styles
    pub gap: Option<u16>,
    pub wrap: Option<WrapMode>,
    pub focusable: bool,
    pub overflow: Option<Overflow>,
    pub show_scrollbar: Option<bool>,
    pub callbacks: EventCallbacks,   // Click, focus, blur handlers
    pub key_handlers: Vec<KeyHandler>,
    pub global_key_handlers: Vec<KeyHandler>,
    pub key_with_modifiers_handlers: Vec<KeyWithModifiersHandler>,
    pub any_char_handler: Option<Rc<dyn Fn(char) -> Box<dyn Message>>>,
}
```

#### DivStyles
```rust
pub struct DivStyles {
    pub base: Option<Style>,    // Normal style
    pub focus: Option<Style>,   // When focused
    pub hover: Option<Style>,   // When hovered (future)
}
```

#### Builder Pattern

Both the builder pattern and the `node!` macro are fully supported ways to create UIs. Choose based on your preference and use case.

```rust
// Using the builder pattern
Div::new()
    .background(Color::Blue)
    .padding(Spacing::all(2))
    .direction(Direction::Horizontal)
    .width(20)
    .height_fraction(0.5)
    .focusable(true)
    .overflow(Overflow::Scroll)
    .show_scrollbar(true)
    .on_click(handler)
    .on_key(Key::Enter, handler)
    .on_key_with_modifiers(KeyWithModifiers::with_ctrl(Key::Char('a')), handler)
    .children(vec![...])

// Using the node! macro
node! {
    div(
        bg: blue,
        pad: 2,
        dir: horizontal,
        w: 20,
        h_frac: 0.5,
        focusable,
        overflow: scroll,
        show_scrollbar: true
    ) [
        // Children using expressions or spread
        (child_node),
        ...(child_nodes)
    ]
}
```

### 7. Virtual DOM (`lib/vdom.rs`)

Manages UI state and efficient updates:

#### Core Operations

1. **Render**: Accept new VNode tree
2. **Diff**: Compare with current tree
3. **Patch**: Apply changes to render tree
4. **Layout**: Calculate positions based on constraints
5. **Draw**: Output to terminal

#### Diffing Algorithm (`lib/diff.rs`)

Generates minimal patches:
```rust
pub enum Patch {
    Replace {
        old: Rc<RefCell<RenderNode>>,
        new: VNode,
    },
    UpdateText {
        node: Rc<RefCell<RenderNode>>,
        new_text: String,
        new_style: Option<TextStyle>,
    },
    UpdateRichText {
        node: Rc<RefCell<RenderNode>>,
        new_spans: Vec<TextSpan>,
    },
    UpdateProps {
        node: Rc<RefCell<RenderNode>>,
        div: Div<VNode>,
    },
    AddChild {
        parent: Rc<RefCell<RenderNode>>,
        child: VNode,
        index: usize,
    },
    RemoveChild {
        parent: Rc<RefCell<RenderNode>>,
        index: usize,
    },
    ReorderChildren {
        parent: Rc<RefCell<RenderNode>>,
        moves: Vec<Move>,
    },
}
```

### 8. Layout System (`lib/render_tree/tree.rs`)

Sophisticated layout engine supporting multiple sizing modes:

#### Dimension Types
```rust
pub enum Dimension {
    Fixed(u16),       // Exact size in cells
    Percentage(f32),  // Percentage of parent (stored 0.0-1.0)
    Auto,            // Share remaining space equally
    Content,         // Size based on children
}
```

#### Layout Algorithm

1. **Fixed**: Use exact size
2. **Percentage**: Calculate from parent size (content box after padding)
3. **Content**:
   - Horizontal: width = sum of children + gaps, height = max child
   - Vertical: width = max child, height = sum of children + gaps
4. **Auto**: Divide remaining space equally among auto-sized elements

#### Text Wrapping
Multiple wrapping modes supported:
- `None`: No wrapping
- `Character`: Break at any character
- `Word`: Break at word boundaries
- `WordBreak`: Try words, break if necessary

#### Scrolling Support
- **Vertical scrolling**: Implemented with scroll_y offset
- **Scrollbar rendering**: Optional visual indicator showing position
- **Keyboard navigation**: Up/Down arrows, PageUp/PageDown, Home/End
- **Mouse wheel**: ScrollUp/ScrollDown events
- **Content tracking**: content_height vs container height
- **Focus requirement**: Container must be focusable for keyboard scrolling
- **Note**: Horizontal scrolling not yet implemented

### 9. Rendering Pipeline (`lib/app/renderer.rs`)

Converts render tree to terminal output:

#### Rendering Steps

1. **Clear Background**: Fill with parent background color or inherit
2. **Draw Borders**: Render border characters if present (single, double, rounded, thick)
3. **Apply Padding**: Adjust content area based on Spacing
4. **Handle Scrolling**: Apply scroll_y offset for scrollable containers
5. **Render Content**:
   - For containers: Recurse into children respecting z-index
   - For text: Draw text with wrapping and style
   - For rich text: Draw styled segments preserving individual styles
6. **Apply Clipping**: Ensure content stays within bounds using clip_rect
7. **Draw Scrollbar**: Show position indicator if enabled and scrollable

#### Style Inheritance
- Text nodes inherit parent's background if not specified
- Focus styles override normal styles when focused
- Children can override parent styles
- Rich text spans maintain individual styles

### 10. Terminal Output System

#### Double Buffering (`lib/buffer.rs`)

Eliminates flicker completely:

```rust
pub struct DoubleBuffer {
    front_buffer: ScreenBuffer,  // Currently displayed
    back_buffer: ScreenBuffer,   // Next frame
    width: u16,
    height: u16,
}
```

**Cell Structure:**
```rust
pub struct Cell {
    pub char: char,
    pub fg: Option<Color>,
    pub bg: Option<Color>,
    pub style: TextStyle,  // Bitflags for bold, italic, etc.
}
```

**Diff Process:**
1. Render to back buffer
2. Compare with front buffer cell-by-cell
3. Generate list of changed cells with positions
4. Apply updates to terminal in optimal order
5. Swap buffers

#### Terminal Renderer (`lib/terminal.rs`)

Optimized output with multiple strategies:

1. **Batch Updates**: Group cells with same colors
2. **Skip Unchanged**: Only update modified cells
3. **Optimize Movements**: Minimize cursor jumps using manhattan distance
4. **Style Batching**: Combine style changes
5. **ANSI Escape Sequences**: Direct terminal control

### 11. Event System (`lib/app/events.rs`)

Comprehensive input handling using crossterm:

#### Keyboard Events

**Focus Navigation:**
- Tab: Next focusable element
- Shift+Tab: Previous focusable element

**Scrolling (for focused scrollable elements):**
- Up/Down arrows: Scroll by 1 line
- PageUp/PageDown: Scroll by container height
- Home/End: Jump to top/bottom

**Event Routing:**
1. Global handlers always receive events (marked with `_global`)
2. Focused element receives local events
3. Character and key handlers triggered with modifiers support

#### Mouse Events

**Click Handling:**
1. Find node at click position using tree traversal
2. Set focus if focusable
3. Trigger click handler

**Scroll Handling:**
1. Find scrollable node under cursor
2. Apply scroll delta (3 lines per wheel event)
3. Clamp to content bounds

### 12. RichText System (`lib/node/rich_text.rs`)

Provides inline text styling with multiple spans:

#### Core Structure
```rust
pub struct RichText {
    pub spans: Vec<TextSpan>,
    pub style: Option<TextStyle>,  // Top-level style for wrapping, etc.
}

pub struct TextSpan {
    pub content: String,
    pub style: Option<TextStyle>,
}
```

#### Builder API
```rust
RichText::new()
    .text("Normal text ")
    .colored("red text", Color::Red)
    .bold("bold text")
    .italic("italic text")
    .styled("custom", TextStyle { ... })
    .wrap(TextWrap::Word)
```

#### Special Features
- **Multiple Spans**: Each span can have different styling
- **Top-Level Styling**: Apply wrapping or common styles to all spans
- **Helper Methods**: `bold_all()`, `color()` for all spans
- **Text Wrapping**: Preserves span styles across wrapped lines
- **Cursor Support**: `with_cursor()` for text input components

### 13. Style System (`lib/style.rs`)

Rich styling capabilities:

#### Colors
- 16 standard terminal colors (Black, Red, Green, Yellow, Blue, Magenta, Cyan, White)
- Bright variants (BrightBlack through BrightWhite)
- RGB support (24-bit color) via `Rgb(u8, u8, u8)`
- Hex color parsing support

#### Text Styles
```rust
pub struct TextStyle {
    pub color: Option<Color>,
    pub background: Option<Color>,
    pub bold: Option<bool>,
    pub italic: Option<bool>,
    pub underline: Option<bool>,
    pub strikethrough: Option<bool>,
    pub wrap: Option<TextWrap>,
}
```

Style merging support with `TextStyle::merge()` for inheritance.

#### Borders
```rust
pub struct Border {
    pub enabled: bool,
    pub style: BorderStyle,  // Single, Double, Rounded, Thick
    pub color: Color,
    pub edges: BorderEdges,  // Bitflags for TOP, RIGHT, BOTTOM, LEFT
}
```

#### Position
```rust
pub enum Position {
    Relative,  // Normal flow
    Absolute,  // Positioned relative to parent
}
```

With top, right, bottom, left offsets for absolute positioning.

#### Overflow
```rust
pub enum Overflow {
    None,   // Content not clipped
    Hidden, // Content clipped at boundaries
    Scroll, // Content clipped but scrollable
    Auto,   // Auto show scrollbars
}
```

### 14. Macro System

Provides ergonomic APIs for building UIs:

#### node! Macro (`lib/macros/node.rs`)
Declarative syntax for building UI trees:
```rust
node! {
    div(bg: blue, pad: 2, @click: ctx.handler(Msg::Click), @key(enter): ctx.handler(Msg::Enter)) [
        text("Hello", color: white),
        div(border: white) [
            text("Nested")
        ]
    ]
}
```

Features:
- Property shortcuts (bg, pad, w, h, etc.)
- Color literals (red, blue, "#FF5733")
- Event handler syntax with @ prefix
- Optional properties with ! suffix
- Stack helpers (hstack, vstack)

#### Attribute Macros (from rxtui-macros crate)

**#[derive(Component)]**: Auto-implements Component trait with providers pattern

**#[component]**: Collects #[effect] methods for async support, implements `__component_effects_impl`

**#[update]**: Handles message downcasting and state management, supports topic routing

**#[view]**: Automatically fetches component state via `ctx.get_state()`

**#[effect]**: Marks async methods as effects, collected by #[component]

### 15. Effects System (`lib/effect/`, requires feature flag)

Supports async background tasks:

#### Effect Runtime (`lib/effect/runtime.rs`)
- Spawns Tokio runtime for async execution
- Manages effect lifecycle per component with JoinHandle tracking
- Automatic cleanup on component unmount via abort()
- Effects stored in HashMap<ComponentId, Vec<JoinHandle>>

#### Effect Type
```rust
pub type Effect = Pin<Box<dyn Future<Output = ()> + Send>>;
```

#### Effect Definition with Macros
```rust
#[component]
impl MyComponent {
    #[effect]
    async fn background_task(&self, ctx: &Context) {
        loop {
            tokio::time::sleep(Duration::from_secs(1)).await;
            ctx.send(MyMsg::Tick);
        }
    }

    #[effect]
    async fn with_state(&self, ctx: &Context, state: MyState) {
        // State automatically fetched via ctx.get_state()
        if state.should_process {
            // Do work
        }
    }
}
```

#### Common Use Cases
- Timers and periodic updates
- Network requests with reqwest/hyper
- File system monitoring with notify
- WebSocket connections
- Background computations

### 16. Built-in Components

#### TextInput (`lib/components/text_input.rs`)

Full-featured text input component with:
- Text editing operations (insert, delete, backspace)
- Cursor movement (arrows, Home/End, word navigation)
- Word operations (Ctrl+W delete word, Alt+B/F word movement)
- Line operations (Ctrl+U/K delete to start/end)
- Password mode for masked input
- Placeholder text with customizable styling
- Focus management and styling
- Selection support (partial implementation)
- Builder pattern for configuration

State management:
```rust
pub struct TextInputState {
    pub focused: bool,
    pub content: String,
    pub cursor_position: usize,
    pub selection_start: Option<usize>,
    pub selection_end: Option<usize>,
}
```

## Performance Optimizations

### 1. Virtual DOM
- Minimal patch generation with path-based updates
- Short-circuit unchanged subtrees via equality checks
- Efficient tree traversal with indexed paths

### 2. Double Buffering
- Zero flicker guaranteed
- Cell-level diffing reduces writes
- Only changed cells updated to terminal

### 3. Terminal Renderer
- Batch color changes to reduce escape sequences
- Optimize cursor movements with distance calculations
- Skip unchanged regions entirely

### 4. Message System
- Zero-copy message routing where possible using Arc
- Lazy state cloning only on modification
- Efficient topic distribution with ownership tracking

### 5. Memory Management
- Rc/RefCell for shared ownership in render tree
- Weak references prevent cycles
- Minimal allocations during render
- Arc for thread-safe component sharing

## Configuration

### RenderConfig
Controls rendering behavior for debugging:
```rust
pub struct RenderConfig {
    pub poll_duration_ms: u64,        // Event poll timeout (default 16ms)
    pub use_double_buffer: bool,      // Enable/disable double buffering
    pub use_diffing: bool,            // Enable/disable cell diffing
    pub use_alternate_screen: bool,   // Use alternate screen buffer
}
```

## Testing Support

### Unit Testing
- Components can be tested in isolation
- Mock Context for state and message testing
- VNode equality for view testing

### Integration Testing
- Test harness for full app testing (planned)
- Event simulation support
- Buffer inspection for render verification

## Platform Compatibility

- **Unix/Linux**: Full support via crossterm
- **macOS**: Full support including iTerm2 features
- **Windows**: Support via Windows Terminal and ConPTY

## Future Enhancements

### Planned Features
- Horizontal scrolling support
- More built-in components (Button, Select, Table, List)
- Animation system with interpolation
- Layout constraints and flexbox-like model
- Accessibility features (screen reader support)
- Hot reload for development


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: QUICK_REFERENCE.md
================================================
# RxTUI Quick Reference

## Component Template

```rust
use rxtui::prelude::*;

#[derive(Debug, Clone)]
enum MyMsg {
    Click,
    Exit,
}

#[derive(Debug, Clone, Default)]
struct MyState {
    counter: i32,
}

#[derive(Component)]
struct MyComponent;

impl MyComponent {
    #[update]
    fn update(&self, _ctx: &Context, msg: MyMsg, mut state: MyState) -> Action {
        match msg {
            MyMsg::Click => {
                state.counter += 1;
                Action::update(state)
            }
            MyMsg::Exit => Action::exit(),
        }
    }

    #[view]
    fn view(&self, ctx: &Context, state: MyState) -> Node {
        node! {
            div(bg: black, pad: 2, @click: ctx.handler(MyMsg::Click), @key_global(esc): ctx.handler(MyMsg::Exit)) [
                text(format!("Count: {}", state.counter))
            ]
        }
    }
}

fn main() -> std::io::Result<()> {
    App::new()?.run(MyComponent)
}
```

## node! Macro Syntax

Declarative UI building with a Rust-native DSL:

### Elements

```rust
node! {
    // Containers
    div(...) [...],
    vstack(...) [...],    // Vertical stack
    hstack(...) [...],    // Horizontal stack

    // Text
    text("content", ...),
    richtext(align: center) [    // supports align property
        text("span1"),
        text("span2", color: red)
    ],

    // Components
    node(MyComponent::new()),

    // Input
    input(placeholder: "...", focusable),

    // Spacer
    spacer(2),
}

// Shorthand commas are optional at end of prop lists
```

### Dynamic Content

```rust
node! {
    div [
        // Expression: Any expression that returns a Node
        (if state.show {
            node! { text("Visible") }
        } else {
            node! { spacer(0) }
        }),

        // Spread: Expand a Vec<Node> as children
        ...(vec![
            node! { text("Item 1") },
            node! { text("Item 2") },
        ])
    ]
}
```

### Div Properties

```rust
div(
    // Layout
    dir: vertical,        // horizontal, v, h
    gap: 2,              // space between children
    wrap: wrap,          // wrap, nowrap

    // Sizing
    w: 50,               // fixed width
    h: 20,               // fixed height
    w_frac: 0.5,          // 50% width
    h_frac: 0.8,          // 80% height
    w_auto,              // auto width
    h_auto,              // auto height
    w_content,           // fit content width
    h_content,           // fit content height

    // Styling
    bg: blue,            // background
    pad: 2,              // padding all
    pad_h: 1,            // padding horizontal
    pad_v: 1,            // padding vertical

    // Border
    border: white,       // border color
    border_style: (BorderStyle::Rounded, cyan),
    border_edges: BorderEdges::TOP | BorderEdges::BOTTOM,

    // Scrolling
    overflow: scroll,    // hidden, auto
    show_scrollbar: true,

    // Focus
    focusable,           // can receive focus
    focus_style: (Style::default().background(Color::Blue)),

    // Position
    absolute,            // absolute positioning
    pos: absolute,       // same as above
    top: 5,
    left: 10,
    bottom: 5,
    right: 10,
    z: 100,             // z-index
)
```

### Input Properties

```rust
input(
    // Sizing
    w: 40,
    h: 3,
    w_frac: 0.5,
    h_frac: 0.4,
    w_auto,
    h_auto,
    w_content,
    h_content,

    // Container styling
    bg: blue,
    pad: 1,
    border: cyan,
    border_style: (BorderStyle::Rounded, cyan),
    border_edges: BorderEdges::TOP | BorderEdges::BOTTOM,
    border_full: (BorderStyle::Double, yellow, BorderEdges::ALL),

    // Positioning
    absolute,
    top: 2,
    left: 4,
    z: 10,

    // Focus
    focusable,
    focus_style: (Style::new().background(Color::Blue)),
    focus_border: magenta,
    focus_border_style: (BorderStyle::Rounded, yellow),
    focus_background: green,
    focus_padding: (Spacing::all(2)),

    // Text + cursor styling
    placeholder: "Search...",
    placeholder_color: gray,
    placeholder_italic: true,
    placeholder_bold: false,
    content_color: white,
    cursor_color: yellow,
    wrap: word,

    // Behavior
    password,
    clear_on_submit,
    @submit: ctx.handler(Msg::Submit),
)
```

### Text Properties

```rust
text(
    "content",

    // Colors
    color: red,          // text color
    bg: blue,           // background

    // Styles
    bold,
    italic,
    underline,
    strikethrough,

    // Wrapping
    wrap: word,         // none, character, word, word_break

    // Alignment
    align: center,      // left, center, right
)
```

### Event Handlers

```rust
div(
    focusable,
    // Mouse
    @click: handler,
    // Keyboard (requires focus)
    @char('a'): handler,
    @key(enter): handler,
    @key(backspace): handler,
    @key(ctrl + 'c'): handler,
    @char('-'): handler,  // For character keys, use @char
    // Global (no focus needed)
    @char_global('q'): handler,
    @key_global(esc): handler,
    @key_global(ctrl + enter): handler,
    // Focus
    @focus: handler,
    @blur: handler,
    // Any character
    @any_char: |ch| handler(ch)
) []
```

Use `ctrl`, `alt`, `shift`, or `meta`/`cmd` with `+` to target modifier-aware shortcuts.

### Programmatic Focus

```rust
#[view]
fn view(&self, ctx: &Context, state: MyState) -> Node {
    if ctx.is_first_render() {
        ctx.focus_self();      // focus first focusable inside this component
        // ctx.focus_first();  // or focus the first focusable in the whole app
    }

    // Inside an event handler you can call ctx.blur_focus() to drop focus manually.

    node! { div(focusable) [] }
}
```

### Optional Properties

```rust
div(
    // Use ! suffix for Option<T> values
    bg: (optional_color)!,
    w: (optional_width)!,
    border: (if selected { Some(yellow) } else { None })!,
)

input(
    placeholder: (maybe_placeholder)!,
    w: (state.width)!,
    focus_border: (state.focus_color)!,
)
```

## Colors

### Named Colors

Basic: `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`

Bright: `bright_black`, `bright_red`, `bright_green`, `bright_yellow`, `bright_blue`, `bright_magenta`, `bright_cyan`, `bright_white`

### Color Formats

```rust
// Named (no prefix)
color: red
color: bright_blue

// Hex string
color: "#FF5733"
color: "#F50"

// RGB expression
color: (Color::Rgb(255, 128, 0))

// Variable
color: (my_color)

// Conditional
color: (if ok { green } else { red })
```

## Common Patterns

### Loading State

Use expressions in parentheses for dynamic content:

```rust
node! {
    div [
        (match state.status {
            Loading => node! { text("Loading...", color: yellow) },
            Error(e) => node! { text(format!("Error: {}", e), color: red) },
            Success(data) => node! { text(format!("Data: {}", data)) },
        })
    ]
}
```

### List Rendering

Use the spread operator `...` to expand collections:

```rust
// Spread a Vec<Node> as children
node! {
    div [
        ...(state.items.iter().map(|item| {
            node! {
                div [
                    text(&item.name)
                ]
            }
        }).collect::<Vec<Node>>())
    ]
}

// Or prepare the list first
let item_nodes: Vec<Node> = state.items.iter()
    .map(|item| node! {
        div [
            text(&item.name)
        ]
    })
    .collect();

node! {
    div [
        text("Items:", bold),
        ...(item_nodes)
    ]
}
```

### Conditional Rendering

Use expressions for conditional content:

```rust
node! {
    div [
        (if state.show_header {
            node! { text("Header", bold) }
        } else {
            node! { spacer(0) }  // Empty placeholder
        }),

        text("Always visible"),

        (if let Some(message) = &state.message {
            node! { text(message, color: yellow) }
        } else {
            node! { spacer(0) }
        })
    ]
}
```

### Keyboard Shortcuts

```rust
#[view]
fn view(&self, ctx: &Context) -> Node {
    node! {
        div(focusable, @key(ctrl + 'c'): ctx.handler(Msg::Exit)) [
            text("Press Ctrl+C to exit", color: bright_red)
        ]
    }
}
```

### Scrollable Container

```rust
div(
    h: 10,               // fixed height
    overflow: scroll,
    show_scrollbar: true,
    focusable           // for keyboard scrolling
) [
    // content taller than container
]
```

### Modal Overlay

```rust
div [
    // Main content
    div [ /* ... */ ],

    // Modal
    if state.show_modal {
        div(absolute, top: 0, left: 0, w_frac: 1.0, h_frac: 1.0, bg: black, z: 1000) [
            div(w: 40, h: 10, bg: white, border: black, pad: 2) [
                text("Modal Content", color: black)
            ]
        ]
    }
]
```

## Update Patterns

### Basic Update

```rust
#[update]
fn update(&self, ctx: &Context, msg: MyMsg, mut state: MyState) -> Action {
    match msg {
        MyMsg::Increment => {
            state.count += 1;
            Action::update(state)
        }
    }
}
```

### Topic Messaging

```rust
// Send to topic
ctx.send_to_topic("my.topic", MyMessage);

// Receive from topic
#[update(msg = LocalMsg, topics = ["my.topic" => TopicMsg])]
fn update(&self, ctx: &Context, messages: Messages, mut state: State) -> Action {
    match messages {
        Messages::LocalMsg(msg) => { /* local */ }
        Messages::TopicMsg(msg) => { /* from topic */ }
    }
}
```

### Dynamic Topics

```rust
struct Component {
    topic: String,
}

#[update(msg = Msg, topics = [self.topic => TopicMsg])]
fn update(&self, ctx: &Context, messages: Messages, state: State) -> Action {
    // Topic name from field
}
```

## Effects (Async)

Effects are enabled by default. Just add tokio:
```toml
[dependencies]
rxtui = "0.1"
tokio = { version = "1", features = ["full"] }
```

### Timer Effect

```rust
#[component]
impl Timer {
    #[effect]
    async fn tick(&self, ctx: &Context) {
        loop {
            tokio::time::sleep(Duration::from_secs(1)).await;
            ctx.send(TimerMsg::Tick);
        }
    }
}
```

### Effect with State

```rust
#[effect]
async fn monitor(&self, ctx: &Context, state: MyState) {
    if state.should_monitor {
        // Do async work
    }
}
```

## TextInput

### Basic Usage

```rust
node! {
    div [
        input(placeholder: "Enter text...", focusable)
    ]
}
```

### Customized

```rust
node! {
    div [
        input(
            placeholder: "Password",
            password,           // mask input
            border: yellow,
            w: 40,
            content_color: green,
            cursor_color: white,
            focusable
        )
    ]
}
```

### Builder API

```rust
node(
    TextInput::new()
        .placeholder("Email...")
        .width(50)
        .border(Color::Cyan)
        .focus_border(Color::Yellow)
)
```

## Layout Tips

### Responsive Layout

```rust
div(w_frac: 1.0, h_frac: 1.0) [  // Full screen
    div(w_frac: 0.3) [ /* 30% sidebar */ ],
    div(w_frac: 0.7) [ /* 70% main */ ]
]
```

### Auto Sizing

```rust
hstack [
    div(w: 20) [ /* fixed */ ],
    div(w_auto) [ /* expands */ ],
    div(w: 20) [ /* fixed */ ]
]
```

### Content Sizing

```rust
div(w_content, h_content) [
    // Size fits children
]
```

## Keyboard Shortcuts

### Focus Navigation
- `Tab` - Next focusable
- `Shift+Tab` - Previous focusable

### Scrolling (when focused)
- `↑/↓` - Scroll up/down
- `Page Up/Down` - Page scroll
- `Home/End` - Jump to top/bottom

### TextInput
- `←/→` - Move cursor
- `Home/End` - Line start/end
- `Alt+B/F` - Word left/right
- `Ctrl+W` - Delete word backward
- `Alt+D` - Delete word forward
- `Ctrl+U` - Delete to line start
- `Ctrl+K` - Delete to line end

## Actions

```rust
Action::update(state)        // Update component state
Action::update_topic(topic, state)  // Update topic state
Action::none()              // No action
Action::exit()              // Exit app
```

## App Configuration

### Terminal Modes

```rust
// Alternate screen mode (default) - full-screen, content disappears on exit
App::new()?.run(MyComponent)?;

// Inline mode - renders in terminal, content persists after exit
App::inline()?.run(MyComponent)?;

// Custom inline configuration
use rxtui::{InlineConfig, InlineHeight};

let config = InlineConfig {
    height: InlineHeight::Fixed(10),      // Fixed 10 lines
    // height: InlineHeight::Content { max: Some(24) },  // Grow to fit, max 24
    // height: InlineHeight::Fill { min: 5 },            // Fill remaining space
    cursor_visible: false,
    preserve_on_exit: true,               // Keep output after exit
    mouse_capture: false,                 // Allow terminal scrolling
};
App::inline_with_config(config)?.run(MyComponent)?;
```

### Render Config

```rust
let mut app = App::new()?
    .render_config(RenderConfig {
        poll_duration_ms: 16,      // Event poll timeout
        use_double_buffer: true,   // Flicker-free rendering
        use_diffing: true,         // Optimize updates
        use_alternate_screen: true, // Separate screen
    });
app.run(MyComponent)?;
```

## Debugging

```rust
// Disable optimizations for debugging
let mut app = App::new()?
    .render_config(RenderConfig {
        use_double_buffer: false,
        use_diffing: false,
        poll_duration_ms: 100,
    });
app.run(MyComponent)?;
```

## Performance Tips

1. Minimize state updates
2. Use topics only when needed
3. Avoid recreating large trees
4. Use `w_content`/`h_content` sparingly
5. Profile with `RenderConfig`

## Common Gotchas

1. **Focus required**: Most events need `focusable`
2. **State cloning**: State is cloned on update
3. **Topic ownership**: First updater owns topic
4. **Scrolling**: Container must be `focusable`

## Import Everything

```rust
use rxtui::prelude::*;
```

Includes:
- Core: `App`, `Context`, `Component`, `Node`, `Action`
- State: `State`, `Message`
- Style: `Color`, `Style`, `Direction`, `Spacing`, `Border`, `BorderStyle`
- Macros: `node!`, `#[component]`, `#[update]`, `#[view]`, `#[effect]`
- Components: `TextInput`
- Keys: `Key`, `KeyWithModifiers`
- Terminal Modes: `TerminalMode`, `InlineConfig`, `InlineHeight`


================================================
FILE: README.md
================================================
<div align="center">
  <a href="./#gh-dark-mode-only" target="_blank">
    <img width="500" alt="rxtui-dark" src="https://github.com/user-attachments/assets/3e3235bc-3792-44eb-88d5-e847631c0086" />
  </a>
  <a href="./#gh-light-mode-only" target="_blank">
    <img width="500" alt="rxtui-light" src="https://github.com/user-attachments/assets/3d1e00f4-39ac-4053-b45b-c4bab7de1361" />
  </a>

  <br />

<b>———&nbsp;&nbsp;&nbsp;reactive terminal UI framework for rust&nbsp;&nbsp;&nbsp;———</b>

</div>

<br />

<div align='center'>
  <a href="https://crates.io/crates/rxtui">
    <img src="https://img.shields.io/crates/v/rxtui?style=for-the-badge&logo=rust&logoColor=white" alt="crates.io version"/>
  </a>
  <a href="./LICENSE">
    <img src="https://img.shields.io/badge/license-Apache%202.0-blue?style=for-the-badge" alt="license"/>
  </a>
  <a href="./DOCS.md">
    <img src="https://img.shields.io/badge/docs-comprehensive-%2300acee.svg?color=ff4500&style=for-the-badge&logo=gitbook&logoColor=white" alt="documentation"/>
  </a>
</div>

<br />

> [!WARNING]
>
> This project is in early development. APIs may change, and bugs may exist.

# <sub>WHY RXTUI?</sub>

Terminal UIs have traditionally been painful to build. You either work with low-level escape sequences (error-prone and tedious) or use immediate-mode libraries that require you to manage all state manually. **RxTUI** takes a different approach.

We bring the retained-mode, component-based architecture that revolutionized web development to the terminal:

- [x] **Declarative UI** - Describe what your UI should look like, not how to change it
- [x] **True Composability** - Build complex apps from simple, reusable components
- [x] **Best of Both Worlds** - Elm's message architecture meets React's components
- [x] **TUI Optimizations** - Automatic diffing, dirty tracking, and minimal redraws
- [x] **Inline Mode** - Render directly in terminal with persistent output for CLI tools

<br />

<div align='center'>
  <img width="100%" alt="align demo" src="https://github.com/user-attachments/assets/bff6886f-7d38-4e90-a512-04d79a3e6246" />
</div>

<br />

# <sub>QUICK START</sub>

### <span>1</span>&nbsp;&nbsp;Install RxTUI

Add to your `Cargo.toml`:

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

### <span>2</span>&nbsp;&nbsp;Create Your First App

A simple working example showing separation of state management and UI building:

```rust
use rxtui::prelude::*;

#[derive(Component)]
struct Counter;

impl Counter {
    #[update]
    fn update(&self, _ctx: &Context, msg: &str, mut count: i32) -> Action {
        match msg {
            "inc" => Action::update(count + 1),
            "dec" => Action::update(count - 1),
            _ => Action::exit(),
        }
    }

    #[view]
    fn view(&self, ctx: &Context, count: i32) -> Node {
        node! {
            div(
                pad: 2,
                align: center,
                w_frac: 1.0,
                gap: 1,
                @key(up): ctx.handler("inc"),
                @key(down): ctx.handler("dec"),
                @key(esc): ctx.handler("exit")
            ) [
                text(format!("Count: {count}"), color: white, bold),
                text("use ↑/↓ to change, esc to exit", color: bright_black)
            ]
        }
    }
}

fn main() -> std::io::Result<()> {
    App::new()?.run(Counter)
}
```

### <span>3</span>&nbsp;&nbsp;Run Your App

```bash
cargo run
```

<img width="100%" alt="counter demo" src="https://github.com/user-attachments/assets/c841f1e6-8bf9-4b5a-bed5-97bc31cc3537" />

<div align='center'>• • •</div>

# <sub>DOCUMENTATION</sub>

| Document                                  | Description                                |
| ----------------------------------------- | ------------------------------------------ |
| **[Examples](./examples)**                | Collection of example apps                 |
| **[Documentation](DOCS.md)**              | Complete framework documentation           |
| **[Tutorial](TUTORIAL.md)**               | Step-by-step guide from basics to advanced |
| **[API Reference](API_REFERENCE.md)**     | Detailed API documentation                 |
| **[Quick Reference](QUICK_REFERENCE.md)** | Handy cheat sheet for common patterns      |
| **[Implementation](IMPLEMENTATION.md)**   | Internal architecture details              |

<div align='center'>• • •</div>

# <sub>DEVELOPMENT</sub>

Want to contribute? We'd love to have you!

- **[Development Guide](DEVELOPMENT.md)** - Set up your dev environment
- **[Contributing](CONTRIBUTING.md)** - Contribution guidelines
- **[GitHub Issues](https://github.com/microsandbox/rxtui/issues)** - Report bugs or request features

<div align='center'>• • •</div>

# <sub>LICENSE</sub>

This project is licensed under the [Apache License 2.0](./LICENSE).


================================================
FILE: TUTORIAL.md
================================================
# RxTUI Tutorial

Learn RxTUI step by step, from basics to advanced features.

## Prerequisites

- Basic Rust knowledge
- A terminal that supports colors and mouse input
- Rust toolchain installed

## Chapter 1: Your First Component

Let's start with the simplest possible RxTUI app.

### Hello World

```rust
use rxtui::prelude::*;

// Define a component
#[derive(Component)]
struct HelloWorld;

impl HelloWorld {
    // Define how it looks
    #[view]
    fn view(&self, ctx: &Context) -> Node {
        node! {
            div(bg: blue, pad: 2, @key_global(esc): ctx.handler(())) [
                text("Hello, RxTUI!", color: white, bold),
                text("Press Esc to exit", color: white)
            ]
        }
    }
}

fn main() -> std::io::Result<()> {
    App::new()?.run(HelloWorld)
}
```

Run it:
```bash
cargo run
```

Press `Esc` to exit.

### What's happening?

1. **Component**: We define a struct and derive `Component`
2. **View**: The `#[view]` method returns what to display
3. **node! macro**: Creates the UI tree declaratively
4. **App**: Manages the terminal and event loop

## Chapter 2: Adding State

Most UIs need to manage data. Let's add state to our component.

### Counter with State

```rust
use rxtui::prelude::*;

// State holds our data
#[derive(Debug, Clone, Default)]
struct CounterState {
    count: i32,
}

#[derive(Component)]
struct Counter;

impl Counter {
    #[view]
    fn view(&self, _ctx: &Context, state: CounterState) -> Node {
        node! {
            div(bg: black, pad: 2) [
                text(format!("Count: {}", state.count), color: white)
            ]
        }
    }
}

fn main() -> std::io::Result<()> {
    App::new()?.run(Counter)
}
```

The `#[view]` macro automatically fetches the state and passes it as a parameter.

## Chapter 3: Handling Events

Now let's make it interactive by adding messages and updates.

### Interactive Counter

```rust
use rxtui::prelude::*;

// Messages represent events
#[derive(Debug, Clone)]
enum CounterMsg {
    Increment,
    Decrement,
    Exit,
}

#[derive(Debug, Clone, Default)]
struct CounterState {
    count: i32,
}

#[derive(Component)]
struct Counter;

impl Counter {
    // Handle messages and update state
    #[update]
    fn update(&self, _ctx: &Context, msg: CounterMsg, mut state: CounterState) -> Action {
        match msg {
            CounterMsg::Increment => {
                state.count += 1;
                Action::update(state)  // Save new state
            }
            CounterMsg::Decrement => {
                state.count -= 1;
                Action::update(state)
            }
            CounterMsg::Exit => Action::exit(),  // Exit app
        }
    }

    #[view]
    fn view(&self, ctx: &Context, state: CounterState) -> Node {
        node! {
            div(bg: black, pad: 2, @char_global('+'): ctx.handler(CounterMsg::Increment), @char_global('-'): ctx.handler(CounterMsg::Decrement), @char_global('q'): ctx.handler(CounterMsg::Exit)) [
                text(format!("Count: {}", state.count), color: white),
                text("Press +/- to change, q to quit", color: gray)
            ]
        }
    }
}
```

### The Update Cycle

1. User presses a key
2. Event handler creates a message
3. `update` processes the message
4. State changes
5. View re-renders with new state

## Chapter 4: Building UIs with node!

The `node!` macro is how you build UIs. Let's explore its features.

### Layout and Styling

```rust
#[view]
fn view(&self, ctx: &Context, state: MyState) -> Node {
    node! {
        // Vertical layout with padding
        div(bg: "#1a1a1a", pad: 2, gap: 1) [
            // Title with styling
            text("My App", color: cyan, bold, underline),

            // Horizontal layout
            hstack(gap: 2) [
                // Fixed width box
                div(w: 20, h: 5, border: white) [
                    text("Left panel")
                ],

                // Percentage width
                div(w_frac: 0.5, border: blue) [
                    text("Center (50%)")
                ],

                // Auto-sizing
                div(w_auto, border: green) [
                    text("Right (auto)")
                ]
            ],

            // Spacer
            spacer(2),

            // Footer
            text("Status: Ready", color: bright_green)
        ]
    }
}
```

### Rich Text

```rust
node! {
    div [
        // Inline styled text
        richtext [
            text("Status: "),
            text("SUCCESS", color: green, bold),
            text(" - "),
            text("5 items", color: yellow),
            text(" processed")
        ]
    ]
}
```

## Chapter 5: Interactive Elements

Let's make clickable buttons and focusable elements.

### Buttons and Focus

```rust
#[derive(Debug, Clone)]
enum AppMsg {
    ButtonClicked(String),
    InputFocused,
}

#[view]
fn view(&self, ctx: &Context, state: AppState) -> Node {
    node! {
        div(pad: 2) [
            text("Click buttons or use Tab to navigate:", color: yellow),

            hstack(gap: 2) [
                // Clickable button
                div(
                    border: white,
                    pad: 1,
                    focusable,  // Can receive focus
                    focus_style: ({
                        Style::default()
                            .background(Color::Blue)
                            .border(Color::Yellow)
                    }),
                    @click: ctx.handler(AppMsg::ButtonClicked("One".into())),
                    @key(enter): ctx.handler(AppMsg::ButtonClicked("One".into()))
                ) [
                    text("Button 1")
                ],

                // Another button
                div(border: white, pad: 1, focusable, @click: ctx.handler(AppMsg::ButtonClicked("Two".into())), @key(enter): ctx.handler(AppMsg::ButtonClicked("Two".into()))) [
                    text("Button 2")
                ]
            ],

            // Display which was clicked
            text(format!("Last clicked: {}", state.last_clicked))
        ]
    }
}
```

### Focus Navigation

- **Tab**: Move to next focusable element
- **Shift+Tab**: Move to previous
- **Enter**: Activate focused element

## Chapter 6: Text Input

RxTUI includes a built-in TextInput component.

### Using TextInput

```rust
use rxtui::prelude::*;
use rxtui::components::TextInput;

#[derive(Debug, Clone)]
enum FormMsg {
    Submit,
    Exit,
}

#[derive(Debug, Clone, Default)]
struct FormState {
    submitted: bool,
}

#[derive(Component)]
struct Form;

impl Form {
    #[update]
    fn update(&self, _ctx: &Context, msg: FormMsg, mut state: FormState) -> Action {
        match msg {
            FormMsg::Submit => {
                state.submitted = true;
                Action::update(state)
            }
            FormMsg::Exit => Action::exit(),
        }
    }

    #[view]
    fn view(&self, ctx: &Context, state: FormState) -> Node {
        node! {
            div(pad: 2, @key_global(esc): ctx.handler(FormMsg::Exit)) [
                text("User Form", bold, color: cyan),

                // Text inputs
                text("Name:"),
                input(placeholder: "Enter your name...", focusable),

                spacer(1),

                text("Email:"),
                input(
                    placeholder: "user@example.com",
                    w: 40,
                    border: cyan,
                    focusable
                ),

                spacer(1),

                // Password input
                text("Password:"),
                input(
                    placeholder: "********",
                    password,  // Masks input
                    border: yellow,
                    focusable
                ),

                spacer(2),

                // Submit button
                div(border: green, pad: 1, focusable, @click: ctx.handler(FormMsg::Submit), @key(enter): ctx.handler(FormMsg::Submit)) [
                    text("Submit")
                ],

                // Status
                if state.submitted {
                    text("Form submitted!", color: green)
                }
            ]
        }
    }
}
```

## Chapter 7: Component Communication

Components can communicate using topics - a pub/sub system.

### Parent-Child with Topics

```rust
// Shared message type
#[derive(Debug, Clone)]
struct UpdateRequest {
    value: String,
}

// Child component that sends updates
#[derive(Component)]
struct Child {
    id: String,
}

impl Child {
    fn new(id: impl Into<String>) -> Self {
        Self { id: id.into() }
    }

    #[update]
    fn update(&self, ctx: &Context, msg: ChildMsg, state: ChildState) -> Action {
        match msg {
            ChildMsg::SendUpdate => {
                // Send to parent via topic
                ctx.send_to_topic("parent.updates", UpdateRequest {
                    value: format!("Update from {}", self.id)
                });
                Action::none()
            }
        }
    }

    #[view]
    fn view(&self, ctx: &Context, _state: ChildState) -> Node {
        node! {
            div(border: white, pad: 1, @click: ctx.handler(ChildMsg::SendUpdate)) [
                text(format!("Child: {}", self.id))
            ]
        }
    }
}

// Parent that receives updates
#[derive(Component)]
struct Parent;

impl Parent {
    // Listen to topic messages
    #[update(msg = ParentMsg, topics = ["parent.updates" => UpdateRequest])]
    fn update(&self, _ctx: &Context, messages: Messages, mut state: ParentState) -> Action {
        match messages {
            Messages::ParentMsg(msg) => {
                // Handle own messages
                Action::none()
            }
            Messages::UpdateRequest(req) => {
                // Handle topic messages
                state.last_update = req.value;
                Action::update(state)  // Claim topic ownership
            }
        }
    }

    #[view]
    fn view(&self, ctx: &Context, state: ParentState) -> Node {
        node! {
            div(pad: 2) [
                text("Parent Component", bold),
                text(format!("Last update: {}", state.last_update)),

                hstack(gap: 2) [
                    node(Child::new("A")),
                    node(Child::new("B")),
                    node(Child::new("C"))
                ]
            ]
        }
    }
}
```

## Chapter 8: Scrollable Content

Handle content that exceeds the viewport.

### Scrollable List

```rust
#[view]
fn view(&self, ctx: &Context, state: ListState) -> Node {
    node! {
        div(pad: 2) [
            text("Scrollable List (use arrows when focused):", color: yellow),

            // Scrollable container
            div(
                h: 10,               // Fixed height
                border: white,
                overflow: scroll,    // Enable scrolling
                show_scrollbar: true,
                focusable           // Must be focusable for keyboard control
            ) [
                // Generate many items
                {state.items.iter().enumerate().map(|(i, item)| {
                    node! {
                        div [
                            text(format!("{}: {}", i + 1, item))
                        ]
                    }
                }).collect::<Vec<_>>()}
            ],

            text("Arrow keys: scroll, Page Up/Down: page, Home/End: jump", color: gray)
        ]
    }
}
```

## Chapter 9: Async Effects

Use effects for background tasks like timers or API calls.

### Timer with Effects

```rust
use rxtui::prelude::*;
use std::time::Duration;

#[derive(Debug, Clone)]
enum ClockMsg {
    Tick,
    Reset,
    Exit,
}

#[derive(Debug, Clone, Default)]
struct ClockState {
    seconds: u32,
}

#[derive(Component)]
struct Clock;

// Enable the #[effect] macro by adding `#[component]` attribute
#[component]
impl Clock {
    #[update]
    fn update(&self, _ctx: &Context, msg: ClockMsg, mut state: ClockState) -> Action {
        match msg {
            ClockMsg::Tick => {
                state.seconds += 1;
                Action::update(state)
            }
            ClockMsg::Reset => Action::update(ClockState::default()),
            ClockMsg::Exit => Action::exit(),
        }
    }

    #[view]
    fn view(&self, ctx: &Context, state: ClockState) -> Node {
        let time = format!("{:02}:{:02}", state.seconds / 60, state.seconds % 60);

        node! {
            div(bg: black, pad: 2, @char_global('r'): ctx.handler(ClockMsg::Reset), @char_global('q'): ctx.handler(ClockMsg::Exit)) [
                text(&time, color: cyan, bold),
                text("Press r to reset, q to quit", color: gray)
            ]
        }
    }

    // Async effect that runs in background
    #[effect]
    async fn tick(&self, ctx: &Context) {
        loop {
            tokio::time::sleep(Duration::from_secs(1)).await;
            ctx.send(ClockMsg::Tick);
        }
    }
}

fn main() -> std::io::Result<()> {
    App::new()?.run(Clock)
}
```

Remember to add tokio to your dependencies:
```toml
[dependencies]
rxtui = { path = "rxtui", features = ["effects"] }
tokio = { version = "1.0", features = ["full"] }
```

## Chapter 10: Complete Application

Let's build a todo list app combining everything we've learned.

### Todo List App

```rust
use rxtui::prelude::*;
use rxtui::components::TextInput;

#[derive(Debug, Clone)]
enum TodoMsg {
    AddTodo,
    ToggleTodo(usize),
    DeleteTodo(usize),
    ClearCompleted,
    Exit,
}

#[derive(Debug, Clone)]
struct Todo {
    text: String,
    completed: bool,
}

#[derive(Debug, Clone, Default)]
struct TodoState {
    todos: Vec<Todo>,
    filter: Filter,
}

#[derive(Debug, Clone, PartialEq)]
enum Filter {
    All,
    Active,
    Completed,
}

impl Default for Filter {
    fn default() -> Self { Filter::All }
}

#[derive(Component)]
struct TodoApp;

impl TodoApp {
    #[update]
    fn update(&self, _ctx: &Context, msg: TodoMsg, mut state: TodoState) -> Action {
        match msg {
            TodoMsg::AddTodo => {
                // Note: In real app, get text from input component
                state.todos.push(Todo {
                    text: "New todo".into(),
                    completed: false,
                });
                Action::update(state)
            }
            TodoMsg::ToggleTodo(idx) => {
                if let Some(todo) = state.todos.get_mut(idx) {
                    todo.completed = !todo.completed;
                }
                Action::update(state)
            }
            TodoMsg::DeleteTodo(idx) => {
                state.todos.remove(idx);
                Action::update(state)
            }
            TodoMsg::ClearCompleted => {
                state.todos.retain(|t| !t.completed);
                Action::update(state)
            }
            TodoMsg::Exit => Action::exit(),
        }
    }

    #[view]
    fn view(&self, ctx: &Context, state: TodoState) -> Node {
        let visible_todos: Vec<_> = state.todos.iter().enumerate()
            .filter(|(_, t)| match state.filter {
                Filter::All => true,
                Filter::Active => !t.completed,
                Filter::Completed => t.completed,
            })
            .collect();

        let active_count = state.todos.iter().filter(|t| !t.completed).count();

        node! {
            div(bg: black, pad: 2, @key_global(esc): ctx.handler(TodoMsg::Exit)) [
                // Header
                div(bg: blue, pad: 1, w_frac: 1.0) [
                    text("TODO LIST", color: white, bold)
                ],

                spacer(1),

                // Input area
                hstack(gap: 1) [
                    input(
                        placeholder: "What needs to be done?",
                        w: 40,
                        focusable
                    ),
                    div(border: green, pad: 1, focusable, @click: ctx.handler(TodoMsg::AddTodo)) [
                        text("Add")
                    ]
                ],

                spacer(1),

                // Todo list
                div(
                    h: 15,
                    overflow: scroll,
                    show_scrollbar: true,
                    border: white
                ) [
                    ...(visible_todos.iter().map(|(idx, todo)| {
                        let idx = *idx;
                        let style = if todo.completed {
                            TextStyle::default()
                                .color(Color::Gray)
                                .strikethrough(true)
                        } else {
                            TextStyle::default()
                        };

                        node! {
                            hstack(gap: 1) [
                                // Checkbox
                                div(
                                    w: 3,
                                    focusable,
                                    border: (if todo.completed { green } else { white }),
                                    @click: ctx.handler(TodoMsg::ToggleTodo(idx))
                                ) [
                                    text(if todo.completed { "✓" } else { " " })
                                ],

                                // Todo text
                                text(&todo.text, style: style),

                                // Delete button
                                div(border: red, pad_h: 1, focusable, @click: ctx.handler(TodoMsg::DeleteTodo(idx))) [
                                    text("×")
                                ]
                            ]
                        }
                    }).collect::<Vec<Node>>())
                ],

                spacer(1),

                // Footer
                hstack(gap: 2) [
                    text(format!("{} items left", active_count)),

                    div(border: yellow, pad: 1, focusable, @click: ctx.handler(TodoMsg::ClearCompleted)) [
                        text("Clear completed")
                    ]
                ],

                spacer(1),
                text("Press ESC to exit", color: gray)
            ]
        }
    }
}

fn main() -> std::io::Result<()> {
    App::new()?.run(TodoApp)
}
```

## Next Steps

You've learned the fundamentals of RxTUI! Here's what to explore next:

1. **Read the full documentation**: Check `DOCS.md` for complete API details
2. **Study the examples**: Run and modify the example apps
3. **Build something**: Create your own TUI application
4. **Explore advanced features**:
   - Custom components
   - Complex layouts
   - Performance optimization
   - Custom rendering

## Tips for Success

1. **Start simple**: Build basic components first, then combine them
2. **Use the type system**: Let Rust's types guide your design
3. **Think in components**: Break complex UIs into reusable pieces
4. **Handle errors gracefully**: Always provide feedback to users
5. **Test interactively**: TUIs are best tested by using them

## Common Patterns

### Loading States

```rust
#[view]
fn view(&self, ctx: &Context, state: DataState) -> Node {
    node! {
        div [
            match &state.data {
                Loading => text("Loading...", color: yellow),
                Error(e) => text(format!("Error: {}", e), color: red),
                Success(data) => text(format!("Data: {}", data)),
            }
        ]
    }
}
```

### Modal Dialogs

```rust
#[view]
fn view(&self, ctx: &Context, state: AppState) -> Node {
    node! {
        div [
            // Main content
            div [ /* ... */ ],

            // Modal overlay
            if state.show_modal {
                div(
                    absolute,
                    top: 0, left: 0,
                    w_frac: 1.0, h_frac: 1.0,
                    bg: (Color::Black.with_alpha(128)),  // Semi-transparent
                    z: 1000
                ) [
                    // Modal content
                    div(
                        w: 40, h: 10,
                        bg: white,
                        border: black,
                        pad: 2
                    ) [
                        text("Modal Dialog", color: black, bold),
                        // Modal content...
                    ]
                ]
            }
        ]
    }
}
```

Happy coding with RxTUI!


================================================
FILE: examples/README.md
================================================
# RxTUI Examples

This directory contains example applications demonstrating various features and patterns of the RxTUI framework.

## Examples

### [counter.rs](./counter.rs)
```bash
cargo run --example counter
```

<img width="100%" alt="counter demo" src="https://github.com/user-attachments/assets/c841f1e6-8bf9-4b5a-bed5-97bc31cc3537" />

A minimal counter demonstrating:
- Basic component structure with `#[update]` and `#[view]` macros
- State management and message handling
- Keyboard event handlers (`↑`/`↓` keys)
- The absolute minimum code needed for an RxTUI app

<br />

### [form.rs](./form.rs)
```bash
cargo run --example form
```

<img width="100%" alt="form demo" src="https://github.com/user-attachments/assets/5c675ab4-144d-4ef1-8545-7921a537bb23" />

Demonstrates form building capabilities:
- Text input fields with focus management
- Form validation and state management
- Submit/cancel actions
- Keyboard navigation between fields
- Error display and user feedback

<br />

### [stopwatch.rs](./stopwatch.rs)
```bash
cargo run --example stopwatch
```

<img width="100%" alt="stopwatch demo" src="https://github.com/user-attachments/assets/98b5702c-cc98-4845-9dbe-e03ac43104f6" />

Time-based UI updates:
- Effects system for side effects
- Timer implementation with start/stop/reset
- Formatting time display
- Combining user actions with background updates

<br />

### [align.rs](./align.rs)
```bash
cargo run --example align
```

<img width="100%" alt="align demo" src="https://github.com/user-attachments/assets/bff6886f-7d38-4e90-a512-04d79a3e6246" />

CSS Flexbox-style alignment demonstration:
- **JustifyContent**: Controls main axis distribution (Start, Center, End, SpaceBetween, SpaceAround, SpaceEvenly)
- **AlignItems**: Controls cross axis alignment (Start, Center, End)
- **AlignSelf**: Per-child alignment override
- Interactive controls to test different combinations
- Support for both horizontal and vertical directions
- Shows how justify and align work on perpendicular axes

<br />

### [hover.rs](./hover.rs)
```bash
cargo run --example hover
```

Demonstrates pointer-driven styling:
- Cards highlight with `hover_style` overlays and animated borders
- Keyboard tabbing still works via `focus_style` fallbacks
- Shows how to compose base, focus, and hover layers without extra event wiring
- Includes a `TextInput` with hover/focus styling via `hover_*` helpers
- Great starting point for interactive menus and dashboards

<br />

### [progressbar.rs](./progressbar.rs)
```bash
cargo run --example progressbar
```

<img width="100%" alt="progressbar demo" src="https://github.com/user-attachments/assets/092d84db-66ea-431c-be72-cf48a043e7f6" />

Animated progress bar with visual flair:
- Smooth multi-stop gradient with peachy colors (Coral → Peach → Salmon → Pink)
- Automatic animation using effects system
- Percentage display with real-time updates
- Demonstrates dynamic content generation with iterators
- Shows how to create visually appealing terminal graphics

<br />

### [shimmer_text.rs](./shimmer_text.rs)
```bash
cargo run --example shimmer_text
```

Animated text highlight inspired by shimmer loading placeholders:
- Continuous, reactive highlight sweeping across text
- Demonstrates color blending and per-character styling
- Ships a reusable `ShimmerText` component that takes the message and speed
- Uses the async effects system for smooth animation
- Includes exit shortcuts wired through the context handlers

<br />

### [scroll.rs](./scroll.rs)
```bash
cargo run --example scroll
```

Interactive overview of scroll behaviors:
- Dual vertical panels comparing visible and hidden scrollbars
- Nested scrollable containers with independent focus and overflow control
- Horizontal gallery demonstrating sideways panning without a scrollbar track
- Contextual hint banner that updates as different surfaces receive focus

<br />

### [scroll2.rs](./scroll2.rs)
```bash
cargo run --example scroll2
```

Single-panel reading view:
- Large article body contained within one scrollable surface
- Keyboard, mouse, and touchpad scrolling supported out of the box
- Fixed viewport keeps the layout stable on smaller terminals
- Helpful instructions for focusing and navigating the text

<br />

### [components.rs](./components.rs)
```bash
cargo run --example components
```

<img width="100%" alt="components demo" src="https://github.com/user-attachments/assets/9ad3e411-0ffe-487b-a0c1-93a3271284fc" />

Shows how to build complex UIs from reusable components:
- Multiple independent counter components with different colors
- Inter-component communication via topics
- Dynamic topic names in `#[update]` macro
- Nested component structure (Dashboard → Counter components)
- Both stateful (Counter) and stateless (Dashboard) components

### [spinner.rs](./spinner.rs)
```bash
cargo run --example spinner
```

<img width="100%" alt="spinner demo" src="https://github.com/user-attachments/assets/f791a987-b460-4053-ae7e-36d86534726f" />

Simple loading animation demonstration:
- Animated spinner using Unicode braille characters
- Automatic animation using `#[effect]` attribute
- Clean purple color scheme with rounded borders
- Shows how to create smooth animations with async effects
- Minimal code for animated UI elements

<br />

### [inline.rs](./inline.rs)
```bash
cargo run --example inline
```

Demonstrates inline rendering mode:
- Renders directly in terminal without alternate screen
- Content persists in terminal history after app exits
- Multiple interactive widgets (counter, status, scrollable log)
- Tab-based focus navigation between components
- Ideal for CLI tools that want persistent inline output
- Shows `App::inline()` usage with content-based height

<br />

## Feature Showcase

### [demo.rs](./demo.rs)
```bash
cargo run --example demo
```
Multi-page demo application showcasing:
- Tab-based navigation system
- 15 different pages each demonstrating specific features
- Component communication via topics
- Complex layouts and styling
- Everything RxTUI can do in one app

The demo includes specialized pages for:
1. **Overflow** - Text overflow and truncation handling
2. **Direction** - Vertical/horizontal layouts and flow
3. **Percentages** - Percentage-based sizing
4. **Borders** - Border styles and selective edges
5. **Absolute** - Absolute positioning and modals
6. **Text Styles** - Colors, bold, underline, etc.
7. **Auto Sizing** - Content-based sizing
8. **Text Wrap** - Word wrapping and text flow
9. **Element Wrap** - Flexbox-like element wrapping
10. **Unicode** - Unicode and emoji support
11. **Content Size** - Dynamic content sizing
12. **Focus** - Focus management and keyboard navigation
13. **Rich Text** - Mixed styles within text
14. **Text Input** - Interactive text input fields
15. **Scrollable** - Scrollable regions and overflow


================================================
FILE: examples/align.rs
================================================
use rxtui::prelude::*;

//--------------------------------------------------------------------------------------------------
// Types
//--------------------------------------------------------------------------------------------------

#[derive(Debug, Clone)]
pub struct DemoState {
    justify: JustifyContent,
    align: AlignItems,
    vertical: bool,
    show_align_self: bool,
}

#[derive(Component)]
pub struct DivAlignmentDemo;

//--------------------------------------------------------------------------------------------------
// Trait Implementations
//--------------------------------------------------------------------------------------------------

impl Default for DemoState {
    fn default() -> Self {
        Self {
            justify: JustifyContent::Start,
            align: AlignItems::Start,
            vertical: false,
            show_align_self: false,
        }
    }
}

//--------------------------------------------------------------------------------------------------
// Methods
//--------------------------------------------------------------------------------------------------

impl DivAlignmentDemo {
    #[update]
    fn update(&self, _ctx: &Context, event: &str, mut state: DemoState) -> Action {
        match event {
            "justify_start" => state.justify = JustifyContent::Start,
            "justify_center" => state.justify = JustifyContent::Center,
            "justify_end" => state.justify = JustifyContent::End,
            "justify_space_between" => state.justify = JustifyContent::SpaceBetween,
            "justify_space_around" => state.justify = JustifyContent::SpaceAround,
            "justify_space_evenly" => state.justify = JustifyContent::SpaceEvenly,
            "align_start" => state.align = AlignItems::Start,
            "align_center" => state.align = AlignItems::Center,
            "align_end" => state.align = AlignItems::End,
            "toggle_direction" => state.vertical = !state.vertical,
            "toggle_align_self" => state.show_align_self = !state.show_align_self,
            "exit" => return Action::exit(),
            _ => return Action::none(),
        }
        Action::update(state)
    }

    #[view]
    fn view(&self, ctx: &Context, state: DemoState) -> Node {
        let dir = if state.vertical {
            Direction::Vertical
        } else {
            Direction::Horizontal
        };
        let justify = state.justify;
        let align = state.align;

        // Build children - varying sizes to demonstrate alignment
        let children = if state.show_align_self {
            // Show align_self overrides - mixed sizes and alignment
            vec![
                node! { div(bg: red, w: 10, h: 3) [text("1", color: white)] },
                node! { div(bg: green, w: 12, h: 5, align_self: end) [text("2(end)", color: white)] },
                node! { div(bg: blue, w: 14, h: 7) [text("3", color: white)] },
                node! { div(bg: yellow, w: 10, h: 4, align_self: start) [text("4(start)", color: black)] },
            ]
        } else {
            // Normal mode - varying sizes to show alignment effects
            vec![
                node! { div(bg: red, w: 10, h: 3) [text("1", color: white)] },
                node! { div(bg: green, w: 12, h: 5) [text("2", color: white)] },
                node! { div(bg: blue, w: 14, h: 7) [text("3", color: white)] },
            ]
        };

        node! {
            div(
                pad: 2,
                w_frac: 1.0,
                h_frac: 1.0,
                align: center,
                @char_global('1'): ctx.handler("justify_start"),
                @char_global('2'): ctx.handler("justify_center"),
                @char_global('3'): ctx.handler("justify_end"),
                @char_global('4'): ctx.handler("justify_space_between"),
                @char_global('5'): ctx.handler("justify_space_around"),
                @char_global('6'): ctx.handler("justify_space_evenly"),
                @char_global('q'): ctx.handler("align_start"),
                @char_global('w'): ctx.handler("align_center"),
                @char_global('e'): ctx.handler("align_end"),
                @char_global('a'): ctx.handler("toggle_align_self"),
                @char_global('d'): ctx.handler("toggle_direction"),
                @key_global(esc): ctx.handler("exit")
            ) [
                // Title
                text("Div Alignment Demo - Mix & Match!", color: yellow, bold),
                text("Justify and Align work on perpendicular axes and can be freely combined", color: bright_black),
                spacer(1),

                // Current settings display
                text(format!(
                    "Direction: {} | Justify: {:?} | Align: {:?} | AlignSelf: {}",
                    if state.vertical { "Vertical" } else { "Horizontal" },
                    state.justify,
                    state.align,
                    if state.show_align_self { "ON" } else { "OFF" }
                ), color: cyan),
                spacer(1),

                // Demo container
                div(
                    bg: "#333",
                    border: white,
                    dir: dir,
                    justify: justify,
                    align: align,
                    w: 56,
                    h: 21
                ) [...(children)],
                spacer(1),

                // Instructions
                div(border: bright_black, pad: 1, w: 56) [
                    text("JUSTIFY (Main Axis):", color: yellow, bold),
                    text(if state.vertical {
                        "  Controls vertical distribution"
                    } else {
                        "  Controls horizontal distribution"
                    }, color: bright_black),
                    text("  [1] Start        [2] Center       [3] End", color: white),
                    text("  [4] SpaceBetween [5] SpaceAround  [6] SpaceEvenly", color: white),
                    spacer(1),

                    text("ALIGN (Cross Axis):", color: yellow, bold),
                    text(if state.vertical {
                        "  Controls horizontal alignment"
                    } else {
                        "  Controls vertical alignment"
                    }, color: bright_black),
                    text("  [Q] Start        [W] Center       [E] End", color: white),
                    spacer(1),

                    text("OTHER:", color: yellow, bold),
                    text("  [D] Toggle Direction - Switch horizontal/vertical", color: white),
                    text("  [A] Toggle AlignSelf - Show per-child overrides", color: white),
                    text("  [ESC] Exit", color: white)
                ]
            ]
        }
    }
}

//--------------------------------------------------------------------------------------------------
// Functions
//--------------------------------------------------------------------------------------------------

fn main() -> std::io::Result<()> {
    App::new()?.run(DivAlignmentDemo)
}


================================================
FILE: examples/components.rs
================================================
use rxtui::prelude::*;

//--------------------------------------------------------------------------------------------------
// Types
//--------------------------------------------------------------------------------------------------

#[derive(Debug, Clone)]
enum CounterMsg {
    Increment,
    Decrement,
}

#[derive(Debug, Clone, Default)]
struct CounterState {
    count: i32,
}

#[derive(Debug, Clone)]
struct ResetSignal;

#[derive(Component)]
struct Counter {
    topic_name: String,
    label: String,
    color: Color,
}

#[derive(Debug, Clone)]
enum DashboardMsg {
    ResetAll,
    Exit,
}

#[derive(Component)]
struct Dashboard;

//--------------------------------------------------------------------------------------------------
// Methods
//--------------------------------------------------------------------------------------------------

impl Counter {
    fn new(topic: impl Into<String>, label: impl Into<String>, color: Color) -> Self {
        Self {
            topic_name: topic.into(),
            label: label.into(),
            color,
        }
    }

    /// Using the new #[update] macro with dynamic topic support!
    #[update(msg = CounterMsg, topics = [self.topic_name => ResetSignal])]
    fn update(&self, _ctx: &Context, messages: Messages, mut state: CounterState) -> Action {
        match messages {
            Messages::CounterMsg(msg) => {
                match msg {
                    CounterMsg::Increment => state.count += 1,
                    CounterMsg::Decrement => state.count -= 1,
                }
                Action::update(state)
            }
            Messages::ResetSignal(_) => Action::update(CounterState::default()),
        }
    }

    #[view]
    fn view(&self, ctx: &Context, state: CounterState) -> Node {
        // Create a darker version of the color for the label background
        let label_bg = match self.color {
            Color::Rgb(147, 112, 219) => Color::hex("#7B68AA"), // Darker purple for #9370DB
            Color::Rgb(255, 165, 0) => Color::hex("#CC8400"),   // Darker amber for #FFA500
            Color::Rgb(32, 178, 170) => Color::hex("#1A8D88"),  // Darker teal for #20B2AA
            _ => Color::hex("#333333"),                         // Fallback dark gray
        };

        // Create a darker version of the color for focus background
        let focus_bg = match self.color {
            Color::Rgb(147, 112, 219) => Color::hex("#6B4C9A"), // Darker purple for #9370DB
            Color::Rgb(255, 165, 0) => Color::hex("#CC6600"),   // Darker amber for #FFA500
            Color::Rgb(32, 178, 170) => Color::hex("#156B66"),  // Darker teal for #20B2AA
            _ => Color::hex("#222222"),                         // Fallback dark gray
        };

        node! {
            div(
                border: (self.color),
                pad: 2,
                w: 25,
                dir: vertical,
                align: center,
                focusable,
                focus_style: (Style::default().background(focus_bg)),
                @key(down): ctx.handler(CounterMsg::Decrement),
                @key(up): ctx.handler(CounterMsg::Increment)
            ) [
                div(bg: (label_bg), pad_h: 1) [
                    text(&self.label, color: black, bold, align: center)
                ],

                spacer(1),

                text(format!("Count: {}", state.count), color: white, bold, align: center),

                spacer(1),

                hstack(gap: 2, justify: center) [
                    div(bg: "#D32F2F", pad_h: 2, @click: ctx.handler(CounterMsg::Decrement)) [
                        text("-", color: white, bold)
                    ],
                    div(bg: "#388E3C", pad_h: 2, @click: ctx.handler(CounterMsg::Increment)) [
                        text("+", color: white, bold)
                    ]
                ]
            ]
        }
    }
}

impl Dashboard {
    #[update]
    fn update(&self, ctx: &Context, msg: DashboardMsg) -> Action {
        match msg {
            DashboardMsg::ResetAll => {
                // Send reset signal to all counter topics
                ctx.send_to_topic("counter_1", ResetSignal);
                ctx.send_to_topic("counter_2", ResetSignal);
                ctx.send_to_topic("counter_3", ResetSignal);
                Action::none()
            }
            DashboardMsg::Exit => Action::exit(),
        }
    }

    #[view]
    fn view(&self, ctx: &Context) -> Node {
        node! {
            div(
                pad: 2,
                align: center,
                w_frac: 1.0,
                @char_global('q'): ctx.handler(DashboardMsg::Exit),
                @key_global(esc): ctx.handler(DashboardMsg::Exit)
            ) [
                // Header
                richtext(align: center) [
                    text("Counter Dashboard", color: "#20B2AA", bold),
                    text(" - Topic Communication Demo", color: bright_white)
                ],

                spacer(1),

                // Instructions
                text(
                    "tab to focus • ↑/↓ to change • r to reset all • q to quit",
                    color: bright_black,
                    align: center
                ),

                spacer(2),

                // Counters
                hstack(gap: 2, justify: center) [
                    node(Counter::new("counter_1", "Alpha", Color::hex("#9370DB"))),
                    node(Counter::new("counter_2", "Beta", Color::hex("#FFA500"))),
                    node(Counter::new("counter_3", "Gamma", Color::hex("#20B2AA")))
                ],

                spacer(2),

                // Reset button
                div(align: center) [
                    div(
                        bg: black,
                        border: white,
                        focusable,
                        focus_style: (Style::default().background(Color::hex("#333")).border(Color::White)),
                        @click: ctx.handler(DashboardMsg::ResetAll),
                        pad_h: 1,
                        @char('r'): ctx.handler(DashboardMsg::ResetAll)
                    ) [
                        text("Reset All Counters (R)", color: white, bold)
                    ]
                ]
            ]
        }
    }
}

//--------------------------------------------------------------------------------------------------
// Functions
//--------------------------------------------------------------------------------------------------

fn main() -> std::io::Result<()> {
    App::new()?.run(Dashboard)
}


================================================
FILE: examples/counter.rs
================================================
use rxtui::prelude::*;

//--------------------------------------------------------------------------------------------------
// Types
//--------------------------------------------------------------------------------------------------

#[derive(Component)]
struct Counter;

//--------------------------------------------------------------------------------------------------
// Methods
//--------------------------------------------------------------------------------------------------

impl Counter {
    #[update]
    fn update(&self, _ctx: &Context, msg: &str, mut count: i32) -> Action {
        match msg {
            "inc" => Action::update(count + 1),
            "dec" => Action::update(count - 1),
            _ => Action::exit(),
        }
    }

    #[view]
    fn view(&self, ctx: &Context, count: i32) -> Node {
        node! {
            div(
                pad: 2,
                align: center,
                w_frac: 1.0,
                gap: 1,
                @key(up): ctx.handler("inc"),
                @key(down): ctx.handler("dec"),
                @key(esc): ctx.handler("exit")
            ) [
                text(format!("Count: {count}"), color: white, bold),
                text("use ↑/↓ to change, esc to exit", color: bright_black)
            ]
        }
    }
}

//--------------------------------------------------------------------------------------------------
// Functions
//--------------------------------------------------------------------------------------------------

fn main() -> std::io::Result<()> {
    App::new()?.run(Counter)
}


================================================
FILE: examples/demo.rs
================================================
mod demo_pages;

use demo_pages::*;
use rxtui::prelude::*;

//--------------------------------------------------------------------------------------------------
// Types
//--------------------------------------------------------------------------------------------------

#[derive(Debug, Clone)]
enum DemoMessage {
    SetPage(i32),
    NextPage,
    PrevPage,
    Exit,
}

#[derive(Debug, Clone)]
enum NavMsg {
    SetPage(i32),
}

#[derive(Debug, Clone)]
struct DemoState {
    current_page: i32,
}

#[derive(Component)]
struct Demo;

//--------------------------------------------------------------------------------------------------
// Trait Implementations
//--------------------------------------------------------------------------------------------------

impl Default for DemoState {
    fn default() -> Self {
        Self { current_page: 1 }
    }
}

//--------------------------------------------------------------------------------------------------
// Methods
//--------------------------------------------------------------------------------------------------

impl Demo {
    #[update(msg = DemoMessage, topics = ["navigation" => NavMsg])]
    fn update(&self, ctx: &Context, messages: Messages, mut state: DemoState) -> Action {
        let msg = match messages {
            Messages::DemoMessage(msg) => msg,
            Messages::NavMsg(NavMsg::SetPage(page)) => DemoMessage::SetPage(page),
        };

        match msg {
            DemoMessage::SetPage(page) => {
                state.current_page = page;
            }
            DemoMessage::NextPage => {
                state.current_page = (state.current_page % 16) + 1;
            }
            DemoMessage::PrevPage => {
                state.current_page = if state.current_page == 1 {
                    16
                } else {
                    state.current_page - 1
                };
            }
            DemoMessage::Exit => {
                return Action::exit();
            }
        }

        Action::update(state)
    }

    #[view]
    fn view(&self, ctx: &Context, state: DemoState) -> Node {
        let page_content = match state.current_page {
            1 => node! { node(page1_overflow::Page1OverflowDemo) },
            2 => node! { node(page2_direction::Page2DirectionDemo) },
            3 => node! { node(page3_percentages::Page3PercentagesDemo) },
            4 => node! { node(page4_borders::Page4BordersDemo) },
            5 => node! { node(page5_absolute::Page5AbsoluteDemo) },
            6 => node! { node(page6_text_styles::Page6TextStylesDemo) },
            7 => node! { node(page7_auto_sizing::Page7AutoSizingDemo) },
            8 => node! { node(page8_text_wrap::Page8TextWrapDemo) },
            9 => node! { node(page9_element_wrap::Page9ElementWrapDemo) },
            10 => node! { node(page10_unicode::Page10UnicodeDemo) },
            11 => node! { node(page11_content_sizing::Page11ContentSizingDemo) },
            12 => node! { node(page12_focus::Page12FocusDemo) },
            13 => node! { node(page13_rich_text::Page13) },
            14 => node! { node(page14_text_input::Page14TextInputDemo) },
            15 => node! { node(page15_scrollable::Page15ScrollableDemo) },
            16 => node! { node(page16_text_alignment::Page16TextAlignmentDemo) },
            _ => node! { node(page1_overflow::Page1OverflowDemo) },
        };

        // Now we can use expressions in the node! macro
        node! {
            div(
                bg: black, dir: vertical, pad: 1, w_frac: 1.0, h_frac: 1.0,
                @char_global('q'): ctx.handler(DemoMessage::Exit),
                @key_global(esc): ctx.handler(DemoMessage::Exit),
                @char('1'): ctx.handler(DemoMessage::SetPage(1)),
                @char('2'): ctx.handler(DemoMessage::SetPage(2)),
                @char('3'): ctx.handler(DemoMessage::SetPage(3)),
                @char('4'): ctx.handler(DemoMessage::SetPage(4)),
                @char('5'): ctx.handler(DemoMessage::SetPage(5)),
                @char('6'): ctx.handler(DemoMessage::SetPage(6)),
                @char('7'): ctx.handler(DemoMessage::SetPage(7)),
                @char('8'): ctx.handler(DemoMessage::SetPage(8)),
                @char('9'): ctx.handler(DemoMessage::SetPage(9)),
                @char('0'): ctx.handler(DemoMessage::SetPage(10)),
                @char('-'): ctx.handler(DemoMessage::SetPage(11)),
                @char('='): ctx.handler(DemoMessage::SetPage(12)),
                @char('['): ctx.handler(DemoMessage::SetPage(13)),
                @char(']'): ctx.handler(DemoMessage::SetPage(14)),
                @char('\\'): ctx.handler(DemoMessage::SetPage(15)),
                @char(';'): ctx.handler(DemoMessage::SetPage(16)),
                @key(right): ctx.handler(DemoMessage::NextPage),
                @key(left): ctx.handler(DemoMessage::PrevPage)
            ) [
                // Header
                div(bg: bright_black, dir: horizontal, pad: 1, w_frac: 1.0, h: 3) [
                    text("Radical TUI Demo", color: bright_cyan),
                    div(w: 10) [],
                    text("Use ← → or 1-9 to navigate, 'q' to quit", color: bright_yellow)
                ],

                // Tab bar
                node(TabBar::new(state.current_page)),

                // Page content using expression
                (page_content)
            ]
        }
    }
}

//--------------------------------------------------------------------------------------------------
// Types: Tab Bar
//--------------------------------------------------------------------------------------------------

#[derive(Component)]
struct TabBar {
    current_page: i32,
}

//--------------------------------------------------------------------------------------------------
// Methods: Tab Bar
//--------------------------------------------------------------------------------------------------

impl TabBar {
    fn new(current_page: i32) -> Self {
        Self { current_page }
    }

    #[update]
    fn update(&self, _ctx: &Context, _msg: ()) -> Action {
        Action::none()
    }

    #[view]
    fn view(&self, _ctx: &Context) -> Node {
        node! {
            div(bg: blue, dir: horizontal, h: 3, w_frac: 1.0) [
                node(Tab::new(1, "[1] Overflow", self.current_page)),
                node(Tab::new(2, "[2] Direction", self.current_page)),
                node(Tab::new(3, "[3] Percentages", self.current_page)),
                node(Tab::new(4, "[4] Borders", self.current_page)),
                node(Tab::new(5, "[5] Absolute", self.current_page)),
                node(Tab::new(6, "[6] Text Styles", self.current_page)),
                node(Tab::new(7, "[7] Auto Sizing", self.current_page)),
                node(Tab::new(8, "[8] Text Wrap", self.current_page)),
                node(Tab::new(9, "[9] Element Wrap", self.current_page)),
                node(Tab::new(10, "[0] Unicode", self.current_page)),
                node(Tab::new(11, "[-] Content Size", self.current_page)),
                node(Tab::new(12, "[=] Focus", self.current_page)),
                node(Tab::new(13, "[[] RichText", self.current_page)),
                node(Tab::new(14, "[]] TextInput", self.current_page)),
                node(Tab::new(15, "[\\] Scrollable", self.current_page)),
                node(Tab::new(16, "[;] Alignment", self.current_page))
            ]
        }
    }
}

//--------------------------------------------------------------------------------------------------
// Types: Tab
//--------------------------------------------------------------------------------------------------

#[derive(Component, Default)]
struct Tab {
    page_num: i32,
    label: String,
    current_page: i32,
}

//--------------------------------------------------------------------------------------------------
// Methods: Tab
//--------------------------------------------------------------------------------------------------

impl Tab {
    fn new(page_num: i32, label: &str, current_page: i32) -> Self {
        Self {
            page_num,
            label: label.to_string(),
            current_page,
        }
    }

    #[update]
    fn update(&self, _ctx: &Context, _msg: ()) -> Action {
        Action::none()
    }

    #[view]
    fn view(&self, ctx: &Context) -> Node {
        let is_current = self.current_page == self.page_num;
        let bg_color = if is_current { Color::Cyan } else { Color::Blue };
        let text_color = if is_current {
            Color::Black
        } else {
            Color::White
        };
        let label = self.label.clone();
        let page_num = self.page_num;

        node! {
            div(bg: (bg_color), pad: 1, h: 3, w_auto, @click: ctx.topic_handler("navigation", NavMsg::SetPage(page_num))) [
                text(label, color: (text_color))
            ]
        }
    }
}

//--------------------------------------------------------------------------------------------------
// Functions
//--------------------------------------------------------------------------------------------------

fn main() -> std::io::Result<()> {
    App::new()?.run(Demo)
}


================================================
FILE: examples/demo_pages/mod.rs
================================================
pub mod page10_unicode;
pub mod page11_content_sizing;
pub mod page12_focus;
pub mod page13_rich_text;
pub mod page14_text_input;
pub mod page15_scrollable;
pub mod page16_text_alignment;
pub mod page1_overflow;
pub mod page2_direction;
pub mod page3_percentages;
pub mod page4_borders;
pub mod page5_absolute;
pub mod page6_text_styles;
pub mod page7_auto_sizing;
pub mod page8_text_wrap;
pub mod page9_element_wrap;


================================================
FILE: examples/demo_pages/page10_unicode.rs
================================================
use rxtui::prelude::*;

//--------------------------------------------------------------------------------------------------
// Types
//--------------------------------------------------------------------------------------------------

#[derive(Component)]
pub struct Page10UnicodeDemo;

//--------------------------------------------------------------------------------------------------
// Methods
//--------------------------------------------------------------------------------------------------

impl Page10UnicodeDemo {
    #[update]
    fn update(&self, _ctx: &Context, _msg: ()) -> Action {
        Action::none()
    }

    #[view]
    fn view(&self, _ctx: &Context) -> Node {
        node! {
            div(bg: black, dir: vertical, pad: 2, w_frac: 1.0, h_frac: 1.0) [
                // Title
                text("Page 10: Unicode Text Rendering", color: cyan, bold, underline),
                text("Support for CJK characters, emojis, and full-width text", color: bright_black),
                spacer(2),

                // Example 1: Character width comparison
                text("Example 1: Character Width Comparison", color: yellow, bold),
                spacer(1),
                hstack(gap: 2) [
                    // ASCII
                    vstack() [
                        text("ASCII (1 column each):", color: green),
                        div(bg: (Color::Rgb(20, 30, 20)), border: bright_black, w: 25, h: 3, pad: 1) [
                            text("ABCD 1234 !@#$", color: white)
                        ]
                    ],

                    // CJK
                    vstack() [
                        text("CJK (2 columns each):", color: cyan),
                        div(bg: (Color::Rgb(20, 20, 30)), border: bright_black, w: 25, h: 3, pad: 1) [
                            text("中文 日本語 한글", color: white)
                        ]
                    ],

                    // Full-width
                    vstack() [
                        text("Full-width (2 cols):", color: magenta),
                        div(bg: (Color::Rgb(30, 20, 30)), border: bright_black, w: 25, h: 3, pad: 1) [
                            text("ABCD 1234", color: white)
                        ]
                    ]
                ],
                spacer(2),

                // Example 2: Mixed content with wrapping
                text("Example 2: Mixed Content with Text Wrapping", color: yellow, bold),
                spacer(1),
                hstack(gap: 2) [
                    vstack() [
                        text("Mixed ASCII + CJK:", color: bright_black),
                        div(bg: (Color::Rgb(30, 30, 30)), border: bright_black, overflow: hidden, w: 28, h: 5, pad: 1) [
                            text(
                                "Hello 世界! This is 混合文本 with both English and 中文 characters mixed together.",
                                color: white,
                                wrap: word
                            )
                        ]
                    ],

                    vstack() [
                        text("Long CJK text:", color: bright_black),
                        div(bg: (Color::Rgb(30, 30, 30)), border: bright_black, overflow: hidden, w: 28, h: 5, pad: 1) [
                            text(
                                "这是一段很长的中文文本用来测试文字换行功能是否正常工作。",
                                color: white,
                                wrap: character
                            )
                        ]
                    ]
                ],
                spacer(2),

                // Example 3: Emoji rendering
                text("Example 3: Emoji Support", color: yellow, bold),
                spacer(1),
                hstack(gap: 2) [
                    vstack() [
                        text("Basic emojis:", color: bright_black),
                        div(bg: (Color::Rgb(25, 25, 35)), border: bright_black, w: 20, h: 4, pad: 1) [
                            text("😀 😃 😄 😁 😅 😂 🤣 😊 😇 🙂", color: white, wrap: character)
                        ]
                    ],

                    vstack() [
                        text("Symbols:", color: bright_black),
                        div(bg: (Color::Rgb(25, 25, 35)), border: bright_black, w: 20, h: 4, pad: 1) [
                            text("❤️ 💚 💙 💜 ⭐ ✨ 🌟 ⚡ 🔥 💧", color: white, wrap: character)
                        ]
                    ],

                    vstack() [
                        text("Flags:", color: bright_black),
                        div(bg: (Color::Rgb(25, 25, 35)), border: bright_black, w: 20, h: 4, pad: 1) [
                            text("🇺🇸 🇬🇧 🇯🇵 🇰🇷 🇨🇳 🇩🇪 🇫🇷 🇮🇹 🇪🇸 🇧🇷", color: white, wrap: character)
                        ]
                    ]
                ],
                spacer(2),

                // Example 4: Wrapping mode comparison with Unicode
                text("Example 4: Text Wrapping Modes with Unicode", color: yellow, bold),
                spacer(1),
                hstack(gap: 2) [
                    // Character wrap
                    vstack() [
                        text("Character wrap:", color: green),
                        div(bg: (Color::Rgb(20, 30, 20)), border: bright_black, overflow: hidden, w: 18, h: 5, pad: 1) [
                            text(
                                "Hello世界Testing文字wrapping功能verification",
                                color: white,
                                wrap: character
                            )
                        ]
                    ],

                    // Word wrap
                    vstack() [
                        text("Word wrap:", color: blue),
                        div(bg: (Color::Rgb(20, 20, 30)), border: bright_black, overflow: hidden, w: 18, h: 5, pad: 1) [
                            text(
                                "Hello世界 Testing文字 wrapping功能 verification",
                                color: white,
                                wrap: word
                            )
                        ]
                    ],

                    // Word-break wrap
                    vstack() [
                        text("Word-break:", color: magenta),
                        div(bg: (Color::Rgb(30, 20, 30)), border: bright_black, overflow: hidden, w: 18, h: 5, pad: 1) [
                            text(
                                "Hello世界VeryLongWord文字wrapping功能verification",
                                color: white,
                                wrap: word_break
                            )
                        ]
                    ]
                ],
                spacer(2),

                // Info note
                div(bg: (Color::Rgb(20, 20, 30)), border: bright_black, pad: 1) [
                    text("Note:", color: yellow, bold),
                    text("• CJK characters and emojis typically occupy 2 terminal columns", color: bright_black),
                    text("• Terminal font and emulator affect emoji rendering", color: bright_black),
                    text("• Text wrapping respects display width, not byte count", color: bright_black)
                ]
            ]
        }
    }
}


================================================
FILE: examples/demo_pages/page11_content_sizing.rs
================================================
use rxtui::prelude::*;

//--------------------------------------------------------------------------------------------------
// Types
//--------------------------------------------------------------------------------------------------

#[derive(Component)]
pub struct Page11ContentSizingDemo;

//--------------------------------------------------------------------------------------------------
// Methods
//--------------------------------------------------------------------------------------------------

impl Page11ContentSizingDemo {
    #[update]
    fn update(&self, _ctx: &Context, _msg: ()) -> Action {
        Action::none()
    }

    #[view]
    fn view(&self, _ctx: &Context) -> Node {
        node! {
            div(bg: black, dir: vertical, pad: 2, w_frac: 1.0, h: 60) [
                // Title
                text("Page 11: Content-Based Sizing", color: bright_white, bold),
                spacer(1),
                text("Elements without dimensions grow to fit their content!", color: bright_cyan),
                spacer(2),

                // Example 1: Simple text in container
                text("Example 1 - Container grows to text:", color: white),
                spacer(1),
                div(bg: bright_black, pad: 1) [
                    // No width/height - sizes to content!
                    div(bg: red, pad: 1) [
                        text("This container fits the text perfectly!", color: white)
                    ]
                ],
                spacer(2),

                // Example 2: Horizontal layout grows to children
                text("Example 2 - Horizontal container (width = sum of children):", color: white),
                spacer(1),
                div(bg: bright_black, dir: horizontal, pad: 1) [
                    // No dimensions - automatically sizes to children
                    div(bg: blue, pad: 1) [
                        text("Box 1", color: white)
                    ],
                    div(bg: green, pad: 1) [
                        text("Box 2 is wider", color: black)
                    ],
                    div(bg: magenta, pad: 1) [
                        text("Box 3", color: white)
                    ]
                ],
                spacer(2),

                // Example 3: Vertical layout grows to children
                text("Example 3 - Vertical container (height = sum, width = max):", color: white),
                spacer(1),
                div(bg: bright_black, dir: vertical, pad: 1) [
                    // No dimensions specified
                    div(bg: cyan, pad_h: 1) [
                        text("Short line", color: black)
                    ],
                    div(bg: yellow, pad_h: 1) [
                        text("This is the longest line in the stack", color: black)
                    ],
                    div(bg: bright_red, pad_h: 1) [
                        text("Medium line here", color: white)
                    ]
                ],
                spacer(2),

                // Example 4: Mixed sizing modes
                text("Example 4 - Mixed sizing (content + fixed + percentage):", color: white),
                spacer(1),
                div(bg: bright_black, dir: horizontal, pad: 1, w: 80, h: 5) [
                    // Parent has fixed width
                    // Content-based width
                    div(bg: bright_green, h_frac: 1.0, pad: 1) [
                        text("Content", color: black)
                    ],
                    // Fixed width
                    div(bg: bright_blue, w: 15, h_frac: 1.0, pad: 1) [
                        text("Fixed 15", color: white)
                    ],
                    // Auto width (remaining space)
                    div(bg: bright_magenta, w_auto, h_frac: 1.0, pad: 1) [
                        text("Auto (fills remaining)", color: white)
                    ]
                ],
                spacer(2),

                // Example 5: Deeply nested content sizing
                text("Example 5 - Nested containers all size to content:", color: white),
                spacer(1),
                div(bg: bright_black, pad: 1) [
                    div(bg: bright_cyan, pad: 1) [
                        div(bg: bright_yellow, pad: 1) [
                            div(bg: black, pad: 1) [
                                text("Deeply nested content", color: bright_white, bold)
                            ]
                        ]
                    ]
                ],
                spacer(2),

                // Example 6: Explicit content dimension
                text("Example 6 - Explicit .width_content() and .height_content():", color: white),
                spacer(1),
                div(bg: bright_black, pad: 1) [
                    div(bg: bright_red, w_content, h: 5, pad: 1, dir: vertical) [
                        // Explicitly use content width
                        // But fixed height
                        text("Width from content", color: white),
                        text("Height is fixed at 5", color: bright_white)
                    ]
                ],
                spacer(2),

                // Example 7: Fixed width with text wrapping
                text("Example 7 - Fixed width with text wrapping (height grows):", color: white),
                spacer(1),
                div(bg: bright_black, pad: 1) [
                    div(bg: bright_cyan, w: 30, pad: 1) [
                        // Fixed width of 30
                        // No height specified - grows to fit wrapped text
                        text(
                            "This is a long piece of text that will wrap when it exceeds the fixed width of 30 characters. The container height will automatically grow to accommodate all the wrapped lines!",
                            color: black,
                            wrap: word
                        )
                    ]
                ],
                spacer(2),

                // Example 8: Multiple wrapped text blocks in horizontal layout
                text("Example 8 - Multiple wrapped texts side by side:", color: white),
                spacer(1),
                div(bg: bright_black, dir: horizontal, pad: 1) [
                    // Parent has no dimensions - grows to fit children
                    div(bg: bright_green, w: 25, pad: 1) [
                        // Fixed width, height will grow to fit wrapped content
                        text(
                            "This text wraps within a 25 character width container.",
                            color: black,
                            wrap: word
                        )
                    ],
                    div(bg: bright_yellow, w: 20, pad: 1) [
                        // Fixed width, height grows to content
                        text(
                            "Shorter width means more wrapping needed here.",
                            color: black,
                            wrap: word
                        )
                    ],
                    div(bg: bright_magenta, w: 15, pad: 1) [
                        // Fixed width
                        text(
                            "Very narrow column with lots of text wrapping.",
                            color: white,
                            wrap: character
                        )
                    ]
                ],
                spacer(2),

                // Example 9: Element wrapping with fixed width
                text("Example 9 - Element wrapping (fixed width, content height):", color: white),
                spacer(1),
                div(bg: bright_black, pad: 1) [
                    div(bg: bright_blue, w: 40, dir: horizontal, wrap: wrap, gap: 1, pad: 1) [
                        // Fixed width, no height - grows to fit wrapped elements
                        div(bg: red, pad_h: 2) [
                            text("Item 1", color: white)
                        ],
                        div(bg: green, pad_h: 2) [
                            text("Item 2", color: black)
                        ],
                        div(bg: yellow, pad_h: 2) [
                            text("Item 3", color: black)
                        ],
                        div(bg: magenta, pad_h: 2) [
                            text("Item 4", color: white)
                        ],
                        div(bg: cyan, pad_h: 2) [
                            text("Item 5", color: black)
                        ]
                    ]
                ]
            ]
        }
    }
}


================================================
FILE: examples/demo_pages/page12_focus.rs
================================================
use rxtui::prelude::*;

//--------------------------------------------------------------------------------------------------
// Types
//--------------------------------------------------------------------------------------------------

#[derive(Component)]
pub struct Page12FocusDemo;

//--------------------------------------------------------------------------------------------------
// Methods
//--------------------------------------------------------------------------------------------------

impl Page12FocusDemo {
    #[update]
    fn update(&self, _ctx: &Context, _msg: ()) -> Action {
        Action::none()
    }

    #[view]
    fn view(&self, _ctx: &Context) -> Node {
        node! {
            div(bg: black, dir: vertical, pad: 2, w_frac: 1.0, h: 50) [
                // Title
                text("Page 12: Focus Management Demo", color: bright_white, bold),
                spacer(1),

                // Instructions
                vstack() [
                    text("• Tab: Navigate forward between focusable elements", color: bright_black),
                    text("• Shift+Tab: Navigate backward between focusable elements", color: bright_black),
                    text("• Click: Focus an element directly", color: bright_black),
                    text("• Enter: Activate focused button", color: bright_black),
                    text("• Focused elements have white borders", color: bright_black)
                ],
                spacer(2),

                // Buttons row
                hstack(gap: 2) [
                    node(FocusButton::new(
                        "Button 1",
                        Color::Red
                    )),
                    node(FocusButton::new(
                        "Button 2",
                        Color::Green
                    )),
                    node(FocusButton::new(
                        "Button 3",
                        Color::Blue
                    ))
                ],
                spacer(2),

                // Text Input with actual TextInput component
                vstack() [
                    text("Text Input (cyan border when focused):", color: yellow),
                    input(
                        placeholder: "Type something...",
                        cursor_color: cyan,
                        border: cyan,
                        focusable
                    ),
                ],
                spacer(2),

                // Focus event history
                vstack() [
                    text("Focus Events:", color: yellow, bold),
                    spacer(1),
                    text("Event display simplified due to macro limitations", color: cyan)
                ]
            ]
        }
    }
}

//--------------------------------------------------------------------------------------------------
// Helper Component
//--------------------------------------------------------------------------------------------------

#[derive(Debug, Clone, Default)]
struct FocusButtonState {
    count: u32,
}

#[derive(Debug, Clone)]
enum FocusButtonMsg {
    Increment,
    Focused,
    Blurred,
}

#[derive(Component)]
struct FocusButton {
    label: String,
    color: Color,
}

impl FocusButton {
    fn new(label: &str, color: Color) -> Self {
        Self {
            label: label.to_string(),
            color,
        }
    }

    #[update]
    fn update(&self, ctx: &Context, msg: FocusButtonMsg, mut state: FocusButtonState) -> Action {
        match msg {
            FocusButtonMsg::Increment => {
                state.count += 1;
                Action::update(state)
            }
            FocusButtonMsg::Focused | FocusButtonMsg::Blurred => Action::none(),
        }
    }

    #[view]
    fn view(&self, ctx: &Context, state: FocusButtonState) -> Node {
        let label = self.label.clone();
        let color = self.color;

        node! {
            div(
                border_style: single,
                border_color: (color),
                pad: 1,
                w: 15,
                focusable,
                focus_style: ({
                    Style::default()
                        .border(Color::White)
                        .background(Color::Rgb(30, 30, 40))
                        .padding(Spacing::all(1))
                }),
                @click: ctx.handler(FocusButtonMsg::Increment),
                @key(enter): ctx.handler(FocusButtonMsg::Increment),
                @focus: ctx.handler(FocusButtonMsg::Focused),
                @blur: ctx.handler(FocusButtonMsg::Blurred)
            ) [
                text(label, color: (color)),
                text(format!("Count: {}", state.count), color: white)
            ]
        }
    }
}


================================================
FILE: examples/demo_pages/page13_rich_text.rs
================================================
//! Page 13: RichText Demo
//!
//! Demonstrates the RichText type for creating styled text with multiple spans
//! and various formatting options.

use rxtui::prelude::*;

#[derive(Component)]
pub struct Page13;

impl Page13 {
    #[update]
    fn update(&self, _ctx: &Context, _msg: ()) -> Action {
        Action::none()
    }

    #[view]
    fn view(&self, _ctx: &Context) -> Node {
        node! {
            div(bg: black, dir: vertical, pad: 1, w_frac: 1.0) [
                // Title
                text("Page 13: RichText Demo", color: bright_white),
                spacer(1),

                // Description
                text("RichText allows inline styling with multiple spans", color: white),
                spacer(1),

                // Scrollable content area
                div(dir: vertical, gap: 1) [
                    // Example 1: Basic colored text
                    text("1. Basic Colored Text:", color: yellow, bold),
                    richtext [
                        text("This is "),
                        text("red", color: red),
                        text(", "),
                        text("green", color: green),
                        text(", and "),
                        text("blue", color: blue),
                        text(" text!"),
                    ],

                    // Example 2: Text formatting
                    text("2. Text Formatting:", color: yellow, bold),
                    richtext [
                        text("Normal text, "),
                        text("bold text", bold),
                        text(", "),
                        text("italic text", italic),
                        text(", and "),
                        text("underlined text", underline),
                    ],

                    // Example 3: Combined styles
                    text("3. Combined Styles:", color: yellow, bold),
                    richtext [
                        text("Here's "),
                        text("bold red text", color: red, bold),
                        text(" and "),
                        text("italic blue on yellow", color: blue, bg: yellow, italic),
                    ],

                    // Example 4: Status indicators
                    text("4. Status Indicators:", color: yellow, bold),
                    hstack(gap: 2) [
                        richtext [
                            text(" SUCCESS ", color: black, bg: green, bold),
                        ],
                        richtext [
                            text(" WARNING ", color: black, bg: yellow, bold),
                        ],
                        richtext [
                            text(" ERROR ", color: white, bg: red, bold),
                        ]
                    ],

                    // Example 5: Text wrapping modes
                    text("5. Text Wrapping Modes:", color: yellow, bold),

                    div(pad: 1) [
                        text("Character Wrapping (w: 30):", color: cyan),
                        div(w: 30) [
                            richtext(wrap: character) [
                                text("This is "),
                                text("character", color: magenta),
                                text(" wrapping. "),
                                text("Words can be ", bold),
                                text("broken anywhere", italic),
                                text(" to fit width."),
                            ]
                        ]
                    ],

                    div(pad: 1) [
                        text("Word Wrapping (w: 30):", color: cyan),
                        div(w: 30) [
                            richtext(wrap: word) [
                                text("This is "),
                                text("word", color: cyan),
                                text(" wrapping. "),
                                text("Words stay intact", bold),
                                text(" and "),
                                text("wrap at spaces", italic),
                                text(" when possible."),
                            ]
                        ]
                    ],

                    div(pad: 1) [
                        text("WordBreak Wrapping (w: 30):", color: cyan),
                        div(w: 30) [
                            richtext(wrap: word_break) [
                                text("This uses
Download .txt
gitextract_sx7sm9zf/

├── .gitignore
├── .pre-commit-config.yaml
├── API_REFERENCE.md
├── CONTRIBUTING.md
├── Cargo.toml
├── DEVELOPMENT.md
├── DOCS.md
├── IMPLEMENTATION.md
├── LICENSE
├── QUICK_REFERENCE.md
├── README.md
├── TUTORIAL.md
├── examples/
│   ├── README.md
│   ├── align.rs
│   ├── components.rs
│   ├── counter.rs
│   ├── demo.rs
│   ├── demo_pages/
│   │   ├── mod.rs
│   │   ├── page10_unicode.rs
│   │   ├── page11_content_sizing.rs
│   │   ├── page12_focus.rs
│   │   ├── page13_rich_text.rs
│   │   ├── page14_text_input.rs
│   │   ├── page15_scrollable.rs
│   │   ├── page16_text_alignment.rs
│   │   ├── page1_overflow.rs
│   │   ├── page2_direction.rs
│   │   ├── page3_percentages.rs
│   │   ├── page4_borders.rs
│   │   ├── page5_absolute.rs
│   │   ├── page6_text_styles.rs
│   │   ├── page7_auto_sizing.rs
│   │   ├── page8_text_wrap.rs
│   │   └── page9_element_wrap.rs
│   ├── form.rs
│   ├── gap.rs
│   ├── hover.rs
│   ├── inline.rs
│   ├── progressbar.rs
│   ├── rxtui.rs
│   ├── scroll.rs
│   ├── scroll_nested.rs
│   ├── shimmer_text.rs
│   ├── spinner.rs
│   ├── spinner_custom.rs
│   ├── stopwatch.rs
│   └── textinput.rs
├── plan.md
├── rxtui/
│   ├── Cargo.toml
│   ├── LICENSE
│   ├── README.md
│   ├── lib/
│   │   ├── app/
│   │   │   ├── config.rs
│   │   │   ├── context.rs
│   │   │   ├── core.rs
│   │   │   ├── events.rs
│   │   │   ├── inline.rs
│   │   │   ├── mod.rs
│   │   │   └── renderer.rs
│   │   ├── bounds.rs
│   │   ├── buffer.rs
│   │   ├── component.rs
│   │   ├── components/
│   │   │   ├── mod.rs
│   │   │   ├── shimmer_text.rs
│   │   │   ├── spinner.rs
│   │   │   └── text_input.rs
│   │   ├── diff.rs
│   │   ├── effect/
│   │   │   ├── mod.rs
│   │   │   ├── runtime.rs
│   │   │   └── types.rs
│   │   ├── key.rs
│   │   ├── lib.rs
│   │   ├── macros/
│   │   │   ├── internal.rs
│   │   │   ├── mod.rs
│   │   │   └── node.rs
│   │   ├── node/
│   │   │   ├── div.rs
│   │   │   ├── mod.rs
│   │   │   ├── rich_text.rs
│   │   │   └── text.rs
│   │   ├── prelude.rs
│   │   ├── providers.rs
│   │   ├── render_tree/
│   │   │   ├── mod.rs
│   │   │   ├── node.rs
│   │   │   ├── tests/
│   │   │   │   ├── layout_tests.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── rich_text_tests.rs
│   │   │   │   ├── sizing_tests.rs
│   │   │   │   └── wrapping_tests.rs
│   │   │   └── tree.rs
│   │   ├── style.rs
│   │   ├── terminal.rs
│   │   ├── tests/
│   │   │   └── rich_text_tests.rs
│   │   ├── utils.rs
│   │   ├── vdom.rs
│   │   └── vnode.rs
│   └── tests/
│       └── macro_tests.rs
└── rxtui-macros/
    ├── Cargo.toml
    ├── LICENSE
    ├── README.md
    └── src/
        └── lib.rs
Download .txt
SYMBOL INDEX (1097 symbols across 69 files)

FILE: examples/align.rs
  type DemoState (line 8) | pub struct DemoState {
  type DivAlignmentDemo (line 16) | pub struct DivAlignmentDemo;
    method update (line 39) | fn update(&self, _ctx: &Context, event: &str, mut state: DemoState) ->...
    method view (line 59) | fn view(&self, ctx: &Context, state: DemoState) -> Node {
  method default (line 23) | fn default() -> Self {
  function main (line 167) | fn main() -> std::io::Result<()> {

FILE: examples/components.rs
  type CounterMsg (line 8) | enum CounterMsg {
  type CounterState (line 14) | struct CounterState {
  type ResetSignal (line 19) | struct ResetSignal;
  type Counter (line 22) | struct Counter {
    method new (line 42) | fn new(topic: impl Into<String>, label: impl Into<String>, color: Colo...
    method update (line 52) | fn update(&self, _ctx: &Context, messages: Messages, mut state: Counte...
    method view (line 66) | fn view(&self, ctx: &Context, state: CounterState) -> Node {
  type DashboardMsg (line 29) | enum DashboardMsg {
  type Dashboard (line 35) | struct Dashboard;
    method update (line 120) | fn update(&self, ctx: &Context, msg: DashboardMsg) -> Action {
    method view (line 134) | fn view(&self, ctx: &Context) -> Node {
  function main (line 192) | fn main() -> std::io::Result<()> {

FILE: examples/counter.rs
  type Counter (line 8) | struct Counter;
    method update (line 16) | fn update(&self, _ctx: &Context, msg: &str, mut count: i32) -> Action {
    method view (line 25) | fn view(&self, ctx: &Context, count: i32) -> Node {
  function main (line 47) | fn main() -> std::io::Result<()> {

FILE: examples/demo.rs
  type DemoMessage (line 11) | enum DemoMessage {
  type NavMsg (line 19) | enum NavMsg {
  type DemoState (line 24) | struct DemoState {
  type Demo (line 29) | struct Demo;
    method update (line 47) | fn update(&self, ctx: &Context, messages: Messages, mut state: DemoSta...
    method view (line 76) | fn view(&self, ctx: &Context, state: DemoState) -> Node {
  method default (line 36) | fn default() -> Self {
  type TabBar (line 144) | struct TabBar {
    method new (line 153) | fn new(current_page: i32) -> Self {
    method update (line 158) | fn update(&self, _ctx: &Context, _msg: ()) -> Action {
    method view (line 163) | fn view(&self, _ctx: &Context) -> Node {
  type Tab (line 192) | struct Tab {
    method new (line 203) | fn new(page_num: i32, label: &str, current_page: i32) -> Self {
    method update (line 212) | fn update(&self, _ctx: &Context, _msg: ()) -> Action {
    method view (line 217) | fn view(&self, ctx: &Context) -> Node {
  function main (line 240) | fn main() -> std::io::Result<()> {

FILE: examples/demo_pages/page10_unicode.rs
  type Page10UnicodeDemo (line 8) | pub struct Page10UnicodeDemo;
    method update (line 16) | fn update(&self, _ctx: &Context, _msg: ()) -> Action {
    method view (line 21) | fn view(&self, _ctx: &Context) -> Node {

FILE: examples/demo_pages/page11_content_sizing.rs
  type Page11ContentSizingDemo (line 8) | pub struct Page11ContentSizingDemo;
    method update (line 16) | fn update(&self, _ctx: &Context, _msg: ()) -> Action {
    method view (line 21) | fn view(&self, _ctx: &Context) -> Node {

FILE: examples/demo_pages/page12_focus.rs
  type Page12FocusDemo (line 8) | pub struct Page12FocusDemo;
    method update (line 16) | fn update(&self, _ctx: &Context, _msg: ()) -> Action {
    method view (line 21) | fn view(&self, _ctx: &Context) -> Node {
  type FocusButtonState (line 83) | struct FocusButtonState {
  type FocusButtonMsg (line 88) | enum FocusButtonMsg {
  type FocusButton (line 95) | struct FocusButton {
    method new (line 101) | fn new(label: &str, color: Color) -> Self {
    method update (line 109) | fn update(&self, ctx: &Context, msg: FocusButtonMsg, mut state: FocusB...
    method view (line 120) | fn view(&self, ctx: &Context, state: FocusButtonState) -> Node {

FILE: examples/demo_pages/page13_rich_text.rs
  type Page13 (line 9) | pub struct Page13;
    method update (line 13) | fn update(&self, _ctx: &Context, _msg: ()) -> Action {
    method view (line 18) | fn view(&self, _ctx: &Context) -> Node {

FILE: examples/demo_pages/page14_text_input.rs
  type Page14TextInputDemo (line 8) | pub struct Page14TextInputDemo;
    method update (line 16) | fn update(&self, _ctx: &Context, _msg: ()) -> Action {
    method view (line 21) | fn view(&self, _ctx: &Context) -> Node {

FILE: examples/demo_pages/page15_scrollable.rs
  type ScrollDemoMsg (line 9) | enum ScrollDemoMsg {
  type ScrollDemoState (line 18) | struct ScrollDemoState {
  type Page15ScrollableDemo (line 23) | pub struct Page15ScrollableDemo;
    method update (line 44) | fn update(&self, ctx: &Context, msg: ScrollDemoMsg, mut state: ScrollD...
    method view (line 67) | fn view(&self, _ctx: &Context) -> Node {
  method default (line 30) | fn default() -> Self {

FILE: examples/demo_pages/page16_text_alignment.rs
  type AlignmentState (line 9) | struct AlignmentState {
  type Page16TextAlignmentDemo (line 18) | pub struct Page16TextAlignmentDemo;
    method update (line 26) | fn update(&self, _ctx: &Context, event: &str, mut state: AlignmentStat...
    method view (line 52) | fn view(&self, ctx: &Context, state: AlignmentState) -> Node {

FILE: examples/demo_pages/page1_overflow.rs
  type OverflowDemoMsg (line 9) | enum OverflowDemoMsg {
  type OverflowDemoState (line 22) | struct OverflowDemoState {
  type Page1OverflowDemo (line 35) | pub struct Page1OverflowDemo;
    method get_colors (line 62) | fn get_colors() -> [Color; 12] {
    method update (line 80) | fn update(&self, ctx: &Context, msg: OverflowDemoMsg, mut state: Overf...
    method view (line 117) | fn view(&self, ctx: &Context, state: OverflowDemoState) -> Node {
  method default (line 42) | fn default() -> Self {

FILE: examples/demo_pages/page2_direction.rs
  type Page2DirectionDemo (line 8) | pub struct Page2DirectionDemo;
    method update (line 16) | fn update(&self, _ctx: &Context, _msg: ()) -> Action {
    method view (line 21) | fn view(&self, _ctx: &Context) -> Node {

FILE: examples/demo_pages/page3_percentages.rs
  type Page3PercentagesDemo (line 8) | pub struct Page3PercentagesDemo;
    method update (line 16) | fn update(&self, _ctx: &Context, _msg: ()) -> Action {
    method view (line 21) | fn view(&self, _ctx: &Context) -> Node {

FILE: examples/demo_pages/page4_borders.rs
  type Page4BordersDemo (line 8) | pub struct Page4BordersDemo;
    method update (line 16) | fn update(&self, _ctx: &Context, _msg: ()) -> Action {
    method view (line 21) | fn view(&self, _ctx: &Context) -> Node {

FILE: examples/demo_pages/page5_absolute.rs
  type AbsoluteDemoMsg (line 8) | enum AbsoluteDemoMsg {
  type AbsoluteDemoState (line 14) | struct AbsoluteDemoState {
  type Page5AbsoluteDemo (line 20) | pub struct Page5AbsoluteDemo;
    method update (line 28) | fn update(&self, ctx: &Context, msg: AbsoluteDemoMsg, mut state: Absol...
    method view (line 42) | fn view(&self, ctx: &Context, state: AbsoluteDemoState) -> Node {

FILE: examples/demo_pages/page6_text_styles.rs
  type Page6TextStylesDemo (line 8) | pub struct Page6TextStylesDemo;
    method update (line 16) | fn update(&self, _ctx: &Context, _msg: ()) -> Action {
    method view (line 21) | fn view(&self, _ctx: &Context) -> Node {

FILE: examples/demo_pages/page7_auto_sizing.rs
  type Page7AutoSizingDemo (line 8) | pub struct Page7AutoSizingDemo;
    method update (line 16) | fn update(&self, _ctx: &Context, _msg: ()) -> Action {
    method view (line 21) | fn view(&self, _ctx: &Context) -> Node {

FILE: examples/demo_pages/page8_text_wrap.rs
  type Page8TextWrapDemo (line 8) | pub struct Page8TextWrapDemo;
    method update (line 16) | fn update(&self, _ctx: &Context, _msg: ()) -> Action {
    method view (line 21) | fn view(&self, _ctx: &Context) -> Node {

FILE: examples/demo_pages/page9_element_wrap.rs
  type Page9ElementWrapDemo (line 8) | pub struct Page9ElementWrapDemo;
    method update (line 16) | fn update(&self, _ctx: &Context, _msg: ()) -> Action {
    method view (line 21) | fn view(&self, _ctx: &Context) -> Node {

FILE: examples/form.rs
  type Msg (line 8) | enum Msg {
  type FormState (line 17) | struct FormState {
  type Form (line 24) | struct Form;
    method update (line 32) | fn update(&self, ctx: &Context, msg: Msg, mut state: FormState) -> Act...
    method view (line 52) | fn view(&self, ctx: &Context, state: FormState) -> Node {
  function main (line 157) | fn main() -> std::io::Result<()> {

FILE: examples/gap.rs
  type GapDemo (line 8) | struct GapDemo;
    method update (line 21) | fn update(&self, _ctx: &Context, msg: GapMsg) -> Action {
    method view (line 28) | fn view(&self, ctx: &Context) -> Node {
  type GapMsg (line 11) | enum GapMsg {
  function main (line 60) | fn main() -> std::io::Result<()> {

FILE: examples/hover.rs
  constant ITEMS (line 7) | const ITEMS: &[(&str, &str)] = &[
  constant ACCENTS (line 14) | const ACCENTS: [Color; 4] = [Color::Cyan, Color::Magenta, Color::Yellow,...
  type HoverShowcase (line 21) | struct HoverShowcase;
    method update (line 29) | fn update(&self, _ctx: &Context, msg: &str) -> Action {
    method view (line 38) | fn view(&self, ctx: &Context) -> Node {
  function main (line 116) | fn main() -> std::io::Result<()> {

FILE: examples/inline.rs
  constant LOG_ENTRIES (line 13) | const LOG_ENTRIES: &[&str] = &[
  type Msg (line 42) | enum Msg {
  type AppState (line 50) | struct AppState {
  type InlineDemo (line 57) | struct InlineDemo;
    method update (line 65) | fn update(&self, _ctx: &Context, msg: Msg, mut state: AppState) -> Act...
    method view (line 84) | fn view(&self, ctx: &Context, state: AppState) -> Node {
  function main (line 189) | fn main() -> std::io::Result<()> {

FILE: examples/progressbar.rs
  type Msg (line 8) | enum Msg {
  type ProgressState (line 14) | struct ProgressState {
  type ProgressBar (line 19) | struct ProgressBar;
    method update (line 38) | fn update(&self, _ctx: &Context, msg: Msg, mut state: ProgressState) -...
    method view (line 49) | fn view(&self, ctx: &Context, state: ProgressState) -> Node {
    method animate_progress (line 120) | async fn animate_progress(&self, ctx: &Context) {
  method default (line 26) | fn default() -> Self {
  function main (line 137) | fn main() -> std::io::Result<()> {

FILE: examples/rxtui.rs
  type RxTuiLogo (line 8) | struct RxTuiLogo;
    method view (line 16) | fn view(&self, ctx: &Context) -> Node {
  function main (line 47) | fn main() -> std::io::Result<()> {

FILE: examples/scroll.rs
  constant BODY_LINES (line 7) | const BODY_LINES: &[&str] = &[
  type ScrollViewMsg (line 50) | enum ScrollViewMsg {
  type ScrollViewState (line 55) | struct ScrollViewState;
  type ScrollTextExample (line 58) | pub struct ScrollTextExample;
    method update (line 66) | fn update(&self, _ctx: &Context, msg: ScrollViewMsg, _state: ScrollVie...
    method view (line 73) | fn view(&self, ctx: &Context, _state: ScrollViewState) -> Node {
  function main (line 116) | fn main() -> std::io::Result<()> {

FILE: examples/scroll_nested.rs
  constant DEFAULT_HINT (line 7) | const DEFAULT_HINT: &str = "Focus a panel with Tab or a mouse click, the...
  type ScrollMsg (line 14) | enum ScrollMsg {
  type ScrollState (line 21) | struct ScrollState {
  type ScrollExample (line 26) | pub struct ScrollExample;
    method update (line 44) | fn update(&self, _ctx: &Context, msg: ScrollMsg, mut state: ScrollStat...
    method view (line 55) | fn view(&self, ctx: &Context, state: ScrollState) -> Node {
  method default (line 33) | fn default() -> Self {
  function main (line 237) | fn main() -> std::io::Result<()> {

FILE: examples/shimmer_text.rs
  constant SHIMMER_TITLE (line 8) | const SHIMMER_TITLE: &str = "Reactive Shimmer Text";
  constant SHIMMER_PRIMARY (line 9) | const SHIMMER_PRIMARY: &str = "Glow through the terminal with reactive s...
  constant SHIMMER_SECONDARY (line 10) | const SHIMMER_SECONDARY: &str = "Gentle shimmer with a calmer sweep";
  type ExampleMsg (line 17) | enum ExampleMsg {
  type ShimmerExample (line 22) | struct ShimmerExample;
    method update (line 31) | fn update(&self, _ctx: &Context, msg: ExampleMsg) -> Action {
    method view (line 38) | fn view(&self, ctx: &Context) -> Node {
  function main (line 84) | fn main() -> std::io::Result<()> {

FILE: examples/spinner.rs
  type Msg (line 9) | enum Msg {
  type SpinnerGalleryState (line 16) | struct SpinnerGalleryState {
  type SpinnerGallery (line 21) | struct SpinnerGallery;
    method update (line 30) | fn update(&self, ctx: &Context, msg: Msg, mut state: SpinnerGallerySta...
    method view (line 47) | fn view(&self, ctx: &Context, state: SpinnerGalleryState) -> Node {
    method spinner_list (line 103) | fn spinner_list() -> Vec<SpinnerType> {
    method spinner_name (line 156) | fn spinner_name(spinner_type: &SpinnerType) -> &'static str {
  function main (line 215) | fn main() -> std::io::Result<()> {

FILE: examples/spinner_custom.rs
  type Msg (line 9) | enum Msg {
  type CustomSpinnerDemo (line 14) | struct CustomSpinnerDemo;
    method update (line 23) | fn update(&self, _ctx: &Context, msg: Msg) -> Action {
    method view (line 30) | fn view(&self, ctx: &Context) -> Node {
  function main (line 123) | fn main() -> std::io::Result<()> {

FILE: examples/stopwatch.rs
  type Stopwatch (line 8) | struct Stopwatch;
    method update (line 17) | fn update(&self, _ctx: &Context, tick: bool, state: u64) -> Action {
    method view (line 26) | fn view(&self, ctx: &Context, state: u64) -> Node {
    method tick (line 55) | async fn tick(&self, ctx: &Context) {
  function main (line 67) | fn main() -> std::io::Result<()> {

FILE: examples/textinput.rs
  type Msg (line 8) | enum Msg {
  type TextInputTestState (line 23) | struct TextInputTestState {
  type TextInputTest (line 36) | struct TextInputTest;
    method update (line 44) | fn update(&self, ctx: &Context, msg: Msg, mut state: TextInputTestStat...
    method view (line 87) | fn view(&self, ctx: &Context, state: TextInputTestState) -> Node {
  function main (line 227) | fn main() -> Result<(), Box<dyn std::error::Error>> {

FILE: rxtui-macros/src/lib.rs
  type TopicKey (line 14) | enum TopicKey {
  type TopicMapping (line 19) | struct TopicMapping {
  type UpdateArgs (line 26) | struct UpdateArgs {
  method parse (line 36) | fn parse(input: ParseStream) -> syn::Result<Self> {
  method parse (line 54) | fn parse(input: ParseStream) -> syn::Result<Self> {
  function extract_param_info (line 93) | fn extract_param_info(arg: &FnArg) -> Option<(Ident, Type)> {
  function derive_component (line 132) | pub fn derive_component(input: TokenStream) -> TokenStream {
  function update (line 276) | pub fn update(args: TokenStream, input: TokenStream) -> TokenStream {
  function view (line 456) | pub fn view(_args: TokenStream, input: TokenStream) -> TokenStream {
  function effect (line 562) | pub fn effect(_args: TokenStream, input: TokenStream) -> TokenStream {
  function component (line 646) | pub fn component(_args: TokenStream, input: TokenStream) -> TokenStream {

FILE: rxtui/lib/app/config.rs
  type TerminalMode (line 7) | pub enum TerminalMode {
  type InlineConfig (line 20) | pub struct InlineConfig {
  type InlineHeight (line 41) | pub enum InlineHeight {
  type RenderConfig (line 54) | pub struct RenderConfig {
    method debug (line 75) | pub fn debug() -> Self {
  method default (line 90) | fn default() -> Self {
  method default (line 103) | fn default() -> Self {
  method default (line 109) | fn default() -> Self {

FILE: rxtui/lib/app/context.rs
  type MessageQueueMap (line 14) | type MessageQueueMap = Arc<RwLock<HashMap<ComponentId, VecDeque<Box<dyn ...
  type TopicMessageQueueMap (line 17) | type TopicMessageQueueMap = Arc<RwLock<HashMap<String, VecDeque<Box<dyn ...
  type Dispatcher (line 21) | pub struct Dispatcher {
    method new (line 106) | pub fn new(queues: MessageQueueMap, topic_queues: TopicMessageQueueMap...
    method send_to_id (line 113) | pub fn send_to_id(&self, component_id: ComponentId, message: impl Mess...
    method send_to_topic (line 121) | pub fn send_to_topic(&self, topic: String, message: impl Message) {
  type StateMap (line 28) | pub struct StateMap {
    method new (line 131) | pub fn new() -> Self {
    method get_or_init (line 137) | pub fn get_or_init<T: State + Default + Clone + 'static>(
    method insert (line 162) | pub fn insert(&self, component_id: ComponentId, state: Box<dyn State>) {
    method remove (line 166) | pub fn remove(&self, component_id: &ComponentId) -> Option<Box<dyn Sta...
  type FocusTarget (line 34) | pub(crate) enum FocusTarget {
  type FocusRequest (line 44) | pub(crate) struct FocusRequest {
  type TopicStore (line 49) | pub struct TopicStore {
    method new (line 172) | pub fn new() -> Self {
    method update_topic (line 179) | pub(crate) fn update_topic(
    method claim_topic (line 206) | pub(crate) fn claim_topic(&self, topic: String, component_id: Componen...
    method read_topic (line 219) | pub fn read_topic<T: State + Clone + 'static>(&self, topic: &str) -> O...
    method get_topic_owner (line 226) | pub fn get_topic_owner(&self, topic: &str) -> Option<ComponentId> {
    method get_owned_topics (line 230) | pub fn get_owned_topics(&self, component_id: &ComponentId) -> Vec<Stri...
  type ComponentInstanceTracker (line 59) | pub struct ComponentInstanceTracker {
    method new (line 247) | pub fn new() -> Self {
    method has_effects (line 254) | pub fn has_effects(&self, component_id: &ComponentId, type_id: TypeId)...
    method mark_spawned (line 262) | pub fn mark_spawned(&self, component_id: ComponentId, type_id: TypeId) {
    method remove (line 270) | pub fn remove(&self, component_id: &ComponentId, type_id: TypeId) -> b...
    method get_all (line 278) | pub fn get_all(&self) -> HashSet<(ComponentId, TypeId)> {
  type Context (line 66) | pub struct Context {
    method new (line 290) | pub fn new(pending_focus_clear: Arc<AtomicBool>) -> Self {
    method id (line 310) | pub fn id(&self) -> &ComponentId {
    method handler (line 315) | pub fn handler<T: Message + Clone + 'static>(&self, msg: T) -> Box<dyn...
    method handler_with_value (line 324) | pub fn handler_with_value<T, M, F>(&self, msg_fn: F) -> Box<dyn Fn(T) ...
    method get_state (line 338) | pub fn get_state<T: State + Default + Clone + 'static>(&self) -> T {
    method set_state (line 343) | pub fn set_state(&self, state: Box<dyn State>) {
    method read_topic (line 348) | pub fn read_topic<T: State + Clone + 'static>(&self, topic: &str) -> O...
    method send (line 353) | pub fn send(&self, message: impl Message) {
    method send_to (line 359) | pub fn send_to(&self, component_id: ComponentId, message: impl Message) {
    method send_to_topic (line 364) | pub fn send_to_topic(&self, topic: impl Into<String>, message: impl Me...
    method topic_handler (line 369) | pub fn topic_handler<T: Message + Clone + 'static>(
    method topic_handler_with_value (line 382) | pub fn topic_handler_with_value<T, M, F>(
    method child (line 400) | pub fn child(&self, index: usize) -> Self {
    method focus_self (line 417) | pub fn focus_self(&self) {
    method focus_first (line 425) | pub fn focus_first(&self) {
    method blur_focus (line 433) | pub fn blur_focus(&self) {
    method take_focus_requests (line 438) | pub(crate) fn take_focus_requests(&self) -> Vec<FocusRequest> {
    method take_focus_clear_request (line 444) | pub(crate) fn take_focus_clear_request(&self) -> bool {
    method cancel_focus_clear (line 449) | pub(crate) fn cancel_focus_clear(&self) {
    method begin_component_render (line 454) | pub(crate) fn begin_component_render(&self) -> bool {
    method end_component_render (line 462) | pub(crate) fn end_component_render(&self) {
    method is_first_render (line 467) | pub fn is_first_render(&self) -> bool {
    method drain_messages (line 472) | pub fn drain_messages(&self, component_id: &ComponentId) -> Vec<Box<dy...
    method drain_topic_messages (line 482) | pub fn drain_topic_messages(&self, topic: &str) -> Vec<Box<dyn Message...
    method drain_all_messages (line 492) | pub fn drain_all_messages(&self) -> Vec<(Box<dyn Message>, Option<Stri...
    method get_unassigned_topic_messages (line 518) | fn get_unassigned_topic_messages(&self) -> Vec<(String, Box<dyn Messag...
    method drain_topic_if_claimed (line 536) | pub fn drain_topic_if_claimed(&self, topic: &str, component_id: &Compo...
    method has_pending_messages (line 550) | pub fn has_pending_messages(&self) -> bool {
  method default (line 284) | fn default() -> Self {
  method default (line 580) | fn default() -> Self {
  method default (line 586) | fn default() -> Self {
  method default (line 592) | fn default() -> Self {

FILE: rxtui/lib/app/core.rs
  type RenderLogFn (line 39) | type RenderLogFn = Box<dyn Fn(&str)>;
  type ExitSignal (line 43) | pub struct ExitSignal;
  type App (line 88) | pub struct App {
    method new (line 135) | pub fn new() -> io::Result<Self> {
    method inline (line 147) | pub fn inline() -> io::Result<Self> {
    method inline_with_config (line 166) | pub fn inline_with_config(config: InlineConfig) -> io::Result<Self> {
    method with_mode (line 173) | pub fn with_mode(mode: TerminalMode) -> io::Result<Self> {
    method run (line 239) | pub fn run<C>(&mut self, root_component: C) -> io::Result<()>
    method render_config (line 247) | pub fn render_config(mut self, config: RenderConfig) -> Self {
    method disable_all_optimizations (line 254) | pub fn disable_all_optimizations(mut self) -> Self {
    method disable_double_buffering (line 261) | pub fn disable_double_buffering(mut self) -> Self {
    method disable_terminal_optimizations (line 268) | pub fn disable_terminal_optimizations(mut self) -> Self {
    method disable_cell_diffing (line 275) | pub fn disable_cell_diffing(mut self) -> Self {
    method poll_duration (line 283) | pub fn poll_duration(mut self, duration_ms: u64) -> Self {
    method fast_polling (line 290) | pub fn fast_polling(mut self) -> Self {
    method slow_polling (line 297) | pub fn slow_polling(mut self) -> Self {
    method run_loop (line 312) | fn run_loop<C>(&mut self, root_component: C) -> io::Result<()>
    method expand_component_tree (line 499) | fn expand_component_tree(
    method node_to_vnode (line 560) | fn node_to_vnode(
    method render_tree_debug_string (line 630) | pub fn render_tree_debug_string(&self) -> String {
    method set_render_log_fn (line 637) | pub fn set_render_log_fn<F: Fn(&str) + 'static>(&mut self, log_fn: F) {
    method apply_focus_requests (line 642) | fn apply_focus_requests(&self, context: &Context, requests: Vec<FocusR...
    method draw (line 679) | fn draw(&mut self) -> io::Result<()> {
    method draw_inline (line 697) | fn draw_inline(&mut self, config: &InlineConfig) -> io::Result<()> {
    method draw_with_double_buffer (line 781) | fn draw_with_double_buffer(&mut self) -> io::Result<()> {
    method draw_direct (line 821) | fn draw_direct(&mut self) -> io::Result<()> {
  method drop (line 888) | fn drop(&mut self) {

FILE: rxtui/lib/app/events.rs
  function handle_key_event (line 17) | pub fn handle_key_event(vdom: &VDom, key_event: KeyEvent) {
  function broadcast_key (line 114) | pub fn broadcast_key(node: &Rc<RefCell<RenderNode>>, key: Key) {
  function broadcast_global_key (line 125) | pub fn broadcast_global_key(node: &Rc<RefCell<RenderNode>>, key: Key) {
  function broadcast_key_with_modifiers (line 138) | pub fn broadcast_key_with_modifiers(
  function broadcast_global_key_with_modifiers (line 152) | pub fn broadcast_global_key_with_modifiers(
  function handle_mouse_event (line 172) | pub fn handle_mouse_event(vdom: &VDom, mouse_event: MouseEvent) {
  function find_scrollable_ancestor (line 239) | fn find_scrollable_ancestor(node: &Rc<RefCell<RenderNode>>) -> Option<Rc...
  function handle_scroll_key (line 259) | fn handle_scroll_key(node: &Rc<RefCell<RenderNode>>, key: Key) -> bool {

FILE: rxtui/lib/app/inline.rs
  type InlineState (line 12) | pub(crate) struct InlineState {
    method new (line 31) | pub fn new() -> Self {
    method reserve_space (line 51) | pub fn reserve_space(&mut self, stdout: &mut impl Write, height: u16) ...
    method clear_area (line 91) | fn clear_area(&self, stdout: &mut impl Write, height: u16) -> io::Resu...
    method expand_space (line 105) | pub fn expand_space(&mut self, stdout: &mut impl Write, new_height: u1...
    method move_to_origin (line 142) | pub fn move_to_origin(&self, stdout: &mut impl Write) -> io::Result<()> {
    method move_to_end (line 151) | pub fn move_to_end(&self, stdout: &mut impl Write) -> io::Result<()> {
    method translate_row (line 161) | pub fn translate_row(&self, terminal_row: u16) -> Option<u16> {
  method default (line 176) | fn default() -> Self {

FILE: rxtui/lib/app/renderer.rs
  function render_node_to_buffer (line 43) | pub fn render_node_to_buffer(
  function render_node_with_offset (line 53) | fn render_node_with_offset(
  function test_text_inherits_parent_background (line 885) | fn test_text_inherits_parent_background() {
  function test_text_own_background_takes_precedence (line 927) | fn test_text_own_background_takes_precedence() {
  function test_multi_level_background_inheritance (line 972) | fn test_multi_level_background_inheritance() {
  function test_border_background_inheritance (line 1026) | fn test_border_background_inheritance() {
  function test_border_uses_element_bg_when_available (line 1090) | fn test_border_uses_element_bg_when_available() {
  function test_selective_border_edges_background (line 1154) | fn test_selective_border_edges_background() {
  function test_element_with_own_bg_overrides_inheritance (line 1215) | fn test_element_with_own_bg_overrides_inheritance() {
  function test_text_center_alignment (line 1271) | fn test_text_center_alignment() {
  function test_text_right_alignment (line 1303) | fn test_text_right_alignment() {
  function test_justify_content_start (line 1336) | fn test_justify_content_start() {
  function test_justify_content_center (line 1373) | fn test_justify_content_center() {
  function test_justify_content_end (line 1411) | fn test_justify_content_end() {
  function test_justify_content_space_between (line 1449) | fn test_justify_content_space_between() {
  function test_align_items_center (line 1490) | fn test_align_items_center() {
  function test_align_items_end (line 1530) | fn test_align_items_end() {
  function test_align_self_override (line 1570) | fn test_align_self_override() {
  function test_wrap_with_justify_content (line 1617) | fn test_wrap_with_justify_content() {
  function test_wrap_with_align_items (line 1668) | fn test_wrap_with_align_items() {
  function test_wrap_with_space_between (line 1730) | fn test_wrap_with_space_between() {
  function render_scrollbars (line 1781) | fn render_scrollbars(

FILE: rxtui/lib/bounds.rs
  type Rect (line 31) | pub struct Rect {
    method new (line 51) | pub fn new(x: u16, y: u16, width: u16, height: u16) -> Self {
    method empty (line 61) | pub fn empty() -> Self {
    method right (line 71) | pub fn right(&self) -> u16 {
    method bottom (line 76) | pub fn bottom(&self) -> u16 {
    method contains_point (line 89) | pub fn contains_point(&self, x: u16, y: u16) -> bool {
    method is_empty (line 94) | pub fn is_empty(&self) -> bool {
    method intersection (line 113) | pub fn intersection(&self, other: &Rect) -> Rect {
    method intersects (line 127) | pub fn intersects(&self, other: &Rect) -> bool {
    method union (line 144) | pub fn union(&self, other: &Rect) -> Rect {
    method clip_to (line 163) | pub fn clip_to(&self, bounds: &Rect) -> Rect {
    method expand (line 170) | pub fn expand(&self, amount: u16) -> Rect {
    method contract (line 182) | pub fn contract(&self, amount: u16) -> Rect {
  function test_rect_edges (line 205) | fn test_rect_edges() {
  function test_contains_point (line 212) | fn test_contains_point() {
  function test_intersection (line 221) | fn test_intersection() {
  function test_union (line 233) | fn test_union() {

FILE: rxtui/lib/buffer.rs
  type Cell (line 31) | pub struct Cell {
    method new (line 127) | pub fn new(char: char) -> Self {
    method empty (line 137) | pub fn empty() -> Self {
    method with_fg (line 142) | pub fn with_fg(mut self, color: Color) -> Self {
    method with_bg (line 148) | pub fn with_bg(mut self, color: Color) -> Self {
    method with_style (line 154) | pub fn with_style(mut self, style: CellStyle) -> Self {
    method fmt (line 399) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  type CellStyle (line 47) | pub struct CellStyle {
    method from_text_style (line 105) | pub fn from_text_style(text_style: &TextStyle) -> Self {
    method merge_with (line 115) | pub fn merge_with(self, other: &CellStyle) -> Self {
  type ScreenBuffer (line 65) | pub struct ScreenBuffer {
    method new (line 164) | pub fn new(width: u16, height: u16) -> Self {
    method get_cell (line 176) | pub fn get_cell(&self, x: u16, y: u16) -> Option<&Cell> {
    method get_cell_mut (line 186) | pub fn get_cell_mut(&mut self, x: u16, y: u16) -> Option<&mut Cell> {
    method set_cell (line 196) | pub fn set_cell(&mut self, x: u16, y: u16, cell: Cell) {
    method clear (line 203) | pub fn clear(&mut self) {
    method resize (line 215) | pub fn resize(&mut self, width: u16, height: u16) {
    method dimensions (line 233) | pub fn dimensions(&self) -> (u16, u16) {
    method fill_rect (line 238) | pub fn fill_rect(&mut self, x: u16, y: u16, width: u16, height: u16, c...
    method write_str (line 250) | pub fn write_str(&mut self, x: u16, y: u16, text: &str, fg: Option<Col...
    method write_styled_str (line 284) | pub fn write_styled_str(&mut self, x: u16, y: u16, text: &str, text_st...
  type DoubleBuffer (line 84) | pub struct DoubleBuffer {
    method new (line 329) | pub fn new(width: u16, height: u16) -> Self {
    method swap (line 341) | pub fn swap(&mut self) {
    method back_buffer_mut (line 346) | pub fn back_buffer_mut(&mut self) -> &mut ScreenBuffer {
    method reset (line 351) | pub fn reset(&mut self) {
    method resize (line 357) | pub fn resize(&mut self, width: u16, height: u16) {
    method diff (line 367) | pub fn diff(&self) -> Vec<CellUpdate> {
    method clear_back (line 393) | pub fn clear_back(&mut self) {
  type CellUpdate (line 94) | pub enum CellUpdate {
  method default (line 409) | fn default() -> Self {
  function test_double_buffer_diff_empty (line 423) | fn test_double_buffer_diff_empty() {
  function test_double_buffer_diff_single_change (line 431) | fn test_double_buffer_diff_single_change() {
  function test_screen_buffer_write_str (line 462) | fn test_screen_buffer_write_str() {
  function test_no_flicker_scenario (line 474) | fn test_no_flicker_scenario() {

FILE: rxtui/lib/component.rs
  type Action (line 13) | pub enum Action {
    method update (line 308) | pub fn update(state: impl State) -> Self {
    method update_topic (line 314) | pub fn update_topic(topic: impl Into<String>, state: impl State) -> Se...
    method none (line 320) | pub fn none() -> Self {
    method exit (line 326) | pub fn exit() -> Self {
  type ComponentId (line 30) | pub struct ComponentId(pub String);
    method new (line 332) | pub fn new(id: impl Into<String>) -> Self {
    method child (line 336) | pub fn child(&self, index: usize) -> Self {
  type Message (line 33) | pub trait Message: Any + Send + Sync + 'static {
    method as_any (line 34) | fn as_any(&self) -> &dyn Any;
    method clone_box (line 35) | fn clone_box(&self) -> Box<dyn Message>;
    method as_any (line 355) | fn as_any(&self) -> &dyn Any {
    method clone_box (line 359) | fn clone_box(&self) -> Box<dyn Message> {
  type MessageExt (line 39) | pub trait MessageExt {
    method downcast (line 41) | fn downcast<T: Any>(&self) -> Option<&T>;
    method downcast (line 45) | fn downcast<T: Any>(&self) -> Option<&T> {
    method downcast (line 51) | fn downcast<T: Any>(&self) -> Option<&T> {
  type State (line 57) | pub trait State: Any + Send + Sync + 'static {
    method as_any (line 58) | fn as_any(&self) -> &dyn Any;
    method as_any_mut (line 59) | fn as_any_mut(&mut self) -> &mut dyn Any;
    method clone_box (line 60) | fn clone_box(&self) -> Box<dyn State>;
    method as_any (line 86) | fn as_any(&self) -> &dyn Any {
    method as_any_mut (line 90) | fn as_any_mut(&mut self) -> &mut dyn Any {
    method clone_box (line 94) | fn clone_box(&self) -> Box<dyn State> {
  type StateExt (line 64) | pub trait StateExt {
    method downcast (line 66) | fn downcast<T: Any>(&self) -> Option<&T>;
    method downcast (line 70) | fn downcast<T: Any>(&self) -> Option<&T> {
    method downcast (line 76) | fn downcast<T: Any>(&self) -> Option<&T> {
  type Component (line 232) | pub trait Component: 'static {
    method update (line 234) | fn update(&self, ctx: &Context, msg: Box<dyn Message>, topic: Option<&...
    method view (line 238) | fn view(&self, ctx: &Context) -> Node;
    method effects (line 287) | fn effects(&self, _ctx: &Context) -> Vec<Effect> {
    method type_id (line 292) | fn type_id(&self) -> TypeId {
    method as_any (line 296) | fn as_any(&self) -> &dyn Any;
    method as_any_mut (line 298) | fn as_any_mut(&mut self) -> &mut dyn Any;
  method default (line 346) | fn default() -> Self {

FILE: rxtui/lib/components/shimmer_text.rs
  type ShimmerMsg (line 13) | enum ShimmerMsg {
  type ShimmerState (line 18) | struct ShimmerState {
  type ShimmerSpeed (line 28) | pub struct ShimmerSpeed {
    method new (line 79) | pub const fn new(frame_delay_ms: u64, phase_step: usize) -> Self {
    method slow (line 87) | pub const fn slow() -> Self {
    method medium (line 92) | pub const fn medium() -> Self {
    method fast (line 97) | pub const fn fast() -> Self {
    method frame_delay (line 101) | fn frame_delay(&self) -> Duration {
    method phase_step (line 105) | fn phase_step(&self) -> usize {
  type ShimmerText (line 48) | pub struct ShimmerText {
    method new (line 116) | pub fn new(content: impl Into<String>) -> Self {
    method speed (line 127) | pub fn speed(mut self, speed: ShimmerSpeed) -> Self {
    method highlight_band (line 134) | pub fn highlight_band(mut self, band: usize) -> Self {
    method base_color (line 140) | pub fn base_color(mut self, color: Color) -> Self {
    method highlight_color (line 146) | pub fn highlight_color(mut self, color: Color) -> Self {
    method gradient (line 152) | pub fn gradient(mut self, base: Color, highlight: Color) -> Self {
    method update (line 164) | fn update(&self, ctx: &Context, msg: Box<dyn Message>, _topic: Option<...
    method view (line 183) | fn view(&self, ctx: &Context) -> Node {
    method effects (line 213) | fn effects(&self, ctx: &Context) -> Vec<Effect> {
    method char_count (line 227) | fn char_count(&self) -> usize {
    method intensity_for_index (line 231) | fn intensity_for_index(&self, index: usize, phase: usize, total: usize...
    method circular_distance (line 249) | fn circular_distance(&self, a: usize, b: usize, total: usize) -> usize {
    method blend_color (line 254) | fn blend_color(&self, intensity: f32) -> Color {
  constant DEFAULT_HIGHLIGHT_BAND (line 60) | const DEFAULT_HIGHLIGHT_BAND: usize = 6;
  constant DEFAULT_BASE_COLOR (line 61) | const DEFAULT_BASE_COLOR: (u8, u8, u8) = (70, 90, 130);
  constant DEFAULT_HIGHLIGHT_COLOR (line 62) | const DEFAULT_HIGHLIGHT_COLOR: (u8, u8, u8) = (210, 225, 255);
  method default (line 69) | fn default() -> Self {
  method update (line 270) | fn update(&self, ctx: &Context, msg: Box<dyn Message>, topic: Option<&st...
  method view (line 274) | fn view(&self, ctx: &Context) -> Node {
  method effects (line 278) | fn effects(&self, ctx: &Context) -> Vec<Effect> {
  method as_any (line 282) | fn as_any(&self) -> &dyn std::any::Any {
  method as_any_mut (line 286) | fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
  function blend_channel (line 295) | fn blend_channel(start: u8, end: u8, factor: f32) -> u8 {
  function color_to_rgb (line 301) | fn color_to_rgb(color: Color) -> (u8, u8, u8) {

FILE: rxtui/lib/components/spinner.rs
  type SpinnerMsg (line 14) | pub enum SpinnerMsg {
  type SpinnerState (line 21) | struct SpinnerState {
  type SpinnerPattern (line 27) | struct SpinnerPattern {
  type SpinnerSpeed (line 37) | pub enum SpinnerSpeed {
    method interval (line 140) | fn interval(&self) -> u64 {
  type SpinnerType (line 50) | pub enum SpinnerType {
  type Spinner (line 123) | pub struct Spinner {
    method get_frames (line 449) | fn get_frames(&self) -> Vec<String> {
    method new (line 510) | pub fn new() -> Self {
    method spinner_type (line 519) | pub fn spinner_type(mut self, spinner_type: SpinnerType) -> Self {
    method speed (line 525) | pub fn speed(mut self, speed: SpinnerSpeed) -> Self {
    method color (line 531) | pub fn color(mut self, color: Color) -> Self {
    method custom_pattern (line 544) | pub fn custom_pattern<S>(mut self, frames: Vec<S>) -> Self
    method update (line 553) | fn update(&self, ctx: &Context, msg: Box<dyn Message>, _topic: Option<...
    method view (line 567) | fn view(&self, ctx: &Context) -> Node {
    method effects (line 587) | fn effects(&self, ctx: &Context) -> Vec<Effect> {
  method default (line 134) | fn default() -> Self {
  method default (line 155) | fn default() -> Self {
  constant DOTS (line 165) | const DOTS: SpinnerPattern = SpinnerPattern {
  constant DOTS2 (line 170) | const DOTS2: SpinnerPattern = SpinnerPattern {
  constant DOTS3 (line 175) | const DOTS3: SpinnerPattern = SpinnerPattern {
  constant LINE (line 180) | const LINE: SpinnerPattern = SpinnerPattern {
  constant LINE2 (line 185) | const LINE2: SpinnerPattern = SpinnerPattern {
  constant PIPE (line 190) | const PIPE: SpinnerPattern = SpinnerPattern {
  constant SIMPLE_DOTS (line 195) | const SIMPLE_DOTS: SpinnerPattern = SpinnerPattern {
  constant SIMPLE_DOTS_SCROLLING (line 200) | const SIMPLE_DOTS_SCROLLING: SpinnerPattern = SpinnerPattern {
  constant STAR (line 205) | const STAR: SpinnerPattern = SpinnerPattern {
  constant STAR2 (line 210) | const STAR2: SpinnerPattern = SpinnerPattern {
  constant FLIP (line 215) | const FLIP: SpinnerPattern = SpinnerPattern {
  constant HAMBURGER (line 220) | const HAMBURGER: SpinnerPattern = SpinnerPattern {
  constant GROW_VERTICAL (line 225) | const GROW_VERTICAL: SpinnerPattern = SpinnerPattern {
  constant GROW_HORIZONTAL (line 230) | const GROW_HORIZONTAL: SpinnerPattern = SpinnerPattern {
  constant BALLOON (line 235) | const BALLOON: SpinnerPattern = SpinnerPattern {
  constant BALLOON2 (line 240) | const BALLOON2: SpinnerPattern = SpinnerPattern {
  constant NOISE (line 245) | const NOISE: SpinnerPattern = SpinnerPattern {
  constant BOUNCE (line 250) | const BOUNCE: SpinnerPattern = SpinnerPattern {
  constant BOX_BOUNCE (line 255) | const BOX_BOUNCE: SpinnerPattern = SpinnerPattern {
  constant BOX_BOUNCE2 (line 260) | const BOX_BOUNCE2: SpinnerPattern = SpinnerPattern {
  constant TRIANGLE (line 265) | const TRIANGLE: SpinnerPattern = SpinnerPattern {
  constant BINARY (line 270) | const BINARY: SpinnerPattern = SpinnerPattern {
  constant ARC (line 278) | const ARC: SpinnerPattern = SpinnerPattern {
  constant CIRCLE (line 283) | const CIRCLE: SpinnerPattern = SpinnerPattern {
  constant SQUARE_CORNERS (line 288) | const SQUARE_CORNERS: SpinnerPattern = SpinnerPattern {
  constant CIRCLE_QUARTERS (line 293) | const CIRCLE_QUARTERS: SpinnerPattern = SpinnerPattern {
  constant CIRCLE_HALVES (line 298) | const CIRCLE_HALVES: SpinnerPattern = SpinnerPattern {
  constant SQUISH (line 303) | const SQUISH: SpinnerPattern = SpinnerPattern {
  constant TOGGLE (line 308) | const TOGGLE: SpinnerPattern = SpinnerPattern {
  constant TOGGLE2 (line 313) | const TOGGLE2: SpinnerPattern = SpinnerPattern {
  constant TOGGLE3 (line 318) | const TOGGLE3: SpinnerPattern = SpinnerPattern {
  constant ARROW (line 323) | const ARROW: SpinnerPattern = SpinnerPattern {
  constant ARROW2 (line 328) | const ARROW2: SpinnerPattern = SpinnerPattern {
  constant ARROW3 (line 333) | const ARROW3: SpinnerPattern = SpinnerPattern {
  constant BOUNCING_BAR (line 338) | const BOUNCING_BAR: SpinnerPattern = SpinnerPattern {
  constant BOUNCING_BALL (line 346) | const BOUNCING_BALL: SpinnerPattern = SpinnerPattern {
  constant CLOCK (line 362) | const CLOCK: SpinnerPattern = SpinnerPattern {
  constant EARTH (line 369) | const EARTH: SpinnerPattern = SpinnerPattern {
  constant MOON (line 374) | const MOON: SpinnerPattern = SpinnerPattern {
  constant HEARTS (line 379) | const HEARTS: SpinnerPattern = SpinnerPattern {
  constant SMILEY (line 384) | const SMILEY: SpinnerPattern = SpinnerPattern {
  constant MONKEY (line 389) | const MONKEY: SpinnerPattern = SpinnerPattern {
  constant WEATHER (line 394) | const WEATHER: SpinnerPattern = SpinnerPattern {
  constant CHRISTMAS (line 402) | const CHRISTMAS: SpinnerPattern = SpinnerPattern {
  constant POINT (line 407) | const POINT: SpinnerPattern = SpinnerPattern {
  constant LAYER (line 412) | const LAYER: SpinnerPattern = SpinnerPattern {
  constant BETA_WAVE (line 417) | const BETA_WAVE: SpinnerPattern = SpinnerPattern {
  constant AESTHETIC (line 430) | const AESTHETIC: SpinnerPattern = SpinnerPattern {
  method update (line 607) | fn update(&self, ctx: &Context, msg: Box<dyn Message>, topic: Option<&st...
  method view (line 611) | fn view(&self, ctx: &Context) -> Node {
  method effects (line 615) | fn effects(&self, ctx: &Context) -> Vec<Effect> {
  method as_any (line 619) | fn as_any(&self) -> &dyn std::any::Any {
  method as_any_mut (line 623) | fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
  method default (line 629) | fn default() -> Self {

FILE: rxtui/lib/components/text_input.rs
  type TextInputMsg (line 19) | pub enum TextInputMsg {
  type TextInputState (line 76) | pub struct TextInputState {
  type TextInput (line 155) | pub struct TextInput {
    method delete_selection (line 181) | fn delete_selection(&self, state: &mut TextInputState) {
    method find_word_boundary_left (line 198) | fn find_word_boundary_left(&self, text: &str, pos: usize) -> usize {
    method find_word_boundary_right (line 223) | fn find_word_boundary_right(&self, text: &str, pos: usize) -> usize {
    method delete_word_backward (line 252) | fn delete_word_backward(&self, state: &mut TextInputState) {
    method delete_word_forward (line 265) | fn delete_word_forward(&self, state: &mut TextInputState) {
    method delete_to_line_start (line 278) | fn delete_to_line_start(&self, state: &mut TextInputState) {
    method delete_to_line_end (line 290) | fn delete_to_line_end(&self, state: &mut TextInputState) {
    method default_style (line 301) | fn default_style() -> Style {
    method default_placeholder_style (line 318) | fn default_placeholder_style() -> TextStyle {
    method default_content_style (line 332) | fn default_content_style() -> TextStyle {
    method default_cursor_style (line 346) | fn default_cursor_style() -> TextStyle {
    method default_selection_style (line 360) | fn default_selection_style() -> TextStyle {
    method new (line 374) | pub fn new() -> Self {
    method placeholder (line 401) | pub fn placeholder(mut self, text: impl Into<String>) -> Self {
    method focusable (line 407) | pub fn focusable(mut self, focusable: bool) -> Self {
    method password (line 413) | pub fn password(mut self, password: bool) -> Self {
    method clear_on_submit (line 419) | pub fn clear_on_submit(mut self, clear: bool) -> Self {
    method on_change (line 425) | pub fn on_change(mut self, callback: impl Fn(String) + 'static) -> Self {
    method on_submit (line 431) | pub fn on_submit(mut self, callback: impl Fn() + 'static) -> Self {
    method on_blur (line 437) | pub fn on_blur(mut self, callback: impl Fn() + 'static) -> Self {
    method on_key (line 443) | pub fn on_key(mut self, key: Key, handler: impl Fn() + 'static) -> Self {
    method on_key_global (line 449) | pub fn on_key_global(mut self, key: Key, handler: impl Fn() + 'static)...
    method on_key_with_modifiers (line 455) | pub fn on_key_with_modifiers(
    method on_key_with_modifiers_global (line 466) | pub fn on_key_with_modifiers_global(
    method update (line 476) | fn update(&self, ctx: &Context, msg: Box<dyn Message>, _topic: Option<...
    method view (line 703) | fn view(&self, ctx: &Context) -> Node {
    method background (line 921) | pub fn background(mut self, color: Color) -> Self {
    method border (line 929) | pub fn border(self, color: Color) -> Self {
    method border_with (line 934) | pub fn border_with(mut self, border: Border) -> Self {
    method border_style (line 942) | pub fn border_style(mut self, border_style: BorderStyle, color: Color)...
    method border_edges (line 955) | pub fn border_edges(mut self, edges: BorderEdges) -> Self {
    method border_full (line 968) | pub fn border_full(
    method padding (line 986) | pub fn padding(mut self, padding: Spacing) -> Self {
    method width (line 994) | pub fn width(mut self, width: u16) -> Self {
    method width_fraction (line 1002) | pub fn width_fraction(mut self, fraction: f32) -> Self {
    method width_auto (line 1010) | pub fn width_auto(mut self) -> Self {
    method width_content (line 1018) | pub fn width_content(mut self) -> Self {
    method height (line 1026) | pub fn height(mut self, height: u16) -> Self {
    method height_fraction (line 1034) | pub fn height_fraction(mut self, fraction: f32) -> Self {
    method height_auto (line 1042) | pub fn height_auto(mut self) -> Self {
    method height_content (line 1050) | pub fn height_content(mut self) -> Self {
    method focus_style (line 1058) | pub fn focus_style(mut self, style: Style) -> Self {
    method hover_style (line 1064) | pub fn hover_style(mut self, style: Style) -> Self {
    method focus_border (line 1070) | pub fn focus_border(self, color: Color) -> Self {
    method focus_border_style (line 1075) | pub fn focus_border_style(self, border_style: BorderStyle, color: Colo...
    method focus_border_with (line 1085) | pub fn focus_border_with(mut self, border: Border) -> Self {
    method focus_background (line 1093) | pub fn focus_background(mut self, color: Color) -> Self {
    method focus_padding (line 1101) | pub fn focus_padding(mut self, padding: Spacing) -> Self {
    method hover_border (line 1109) | pub fn hover_border(mut self, color: Color) -> Self {
    method hover_border_style (line 1123) | pub fn hover_border_style(mut self, border_style: BorderStyle, color: ...
    method hover_background (line 1136) | pub fn hover_background(mut self, color: Color) -> Self {
    method hover_padding (line 1144) | pub fn hover_padding(mut self, padding: Spacing) -> Self {
    method position (line 1152) | pub fn position(mut self, position: Position) -> Self {
    method absolute (line 1160) | pub fn absolute(self) -> Self {
    method top (line 1165) | pub fn top(mut self, top: i16) -> Self {
    method right (line 1173) | pub fn right(mut self, right: i16) -> Self {
    method bottom (line 1181) | pub fn bottom(mut self, bottom: i16) -> Self {
    method left (line 1189) | pub fn left(mut self, left: i16) -> Self {
    method z_index (line 1197) | pub fn z_index(mut self, z_index: i32) -> Self {
    method placeholder_style (line 1205) | pub fn placeholder_style(mut self, style: TextStyle) -> Self {
    method placeholder_color (line 1211) | pub fn placeholder_color(mut self, color: Color) -> Self {
    method placeholder_background (line 1222) | pub fn placeholder_background(mut self, color: Color) -> Self {
    method placeholder_bold (line 1233) | pub fn placeholder_bold(mut self, bold: bool) -> Self {
    method placeholder_italic (line 1244) | pub fn placeholder_italic(mut self, italic: bool) -> Self {
    method placeholder_underline (line 1255) | pub fn placeholder_underline(mut self, underline: bool) -> Self {
    method content_style (line 1266) | pub fn content_style(mut self, style: TextStyle) -> Self {
    method content_color (line 1272) | pub fn content_color(mut self, color: Color) -> Self {
    method content_background (line 1283) | pub fn content_background(mut self, color: Color) -> Self {
    method content_bold (line 1294) | pub fn content_bold(mut self, bold: bool) -> Self {
    method content_italic (line 1305) | pub fn content_italic(mut self, italic: bool) -> Self {
    method content_underline (line 1316) | pub fn content_underline(mut self, underline: bool) -> Self {
    method cursor_style (line 1327) | pub fn cursor_style(mut self, style: TextStyle) -> Self {
    method cursor_color (line 1333) | pub fn cursor_color(mut self, color: Color) -> Self {
    method selection_style (line 1349) | pub fn selection_style(mut self, style: TextStyle) -> Self {
    method selection_color (line 1355) | pub fn selection_color(mut self, color: Color) -> Self {
    method wrap (line 1366) | pub fn wrap(mut self, wrap: TextWrap) -> Self {
  method update (line 1377) | fn update(&self, ctx: &Context, msg: Box<dyn Message>, topic: Option<&st...
  method view (line 1381) | fn view(&self, ctx: &Context) -> Node {
  method as_any (line 1385) | fn as_any(&self) -> &dyn Any {
  method as_any_mut (line 1389) | fn as_any_mut(&mut self) -> &mut dyn Any {
  method default (line 1395) | fn default() -> Self {

FILE: rxtui/lib/diff.rs
  type Patch (line 45) | pub enum Patch {
  type DiffContext (line 91) | pub struct DiffContext {
  function diff (line 113) | pub fn diff(old: &Rc<RefCell<RenderNode>>, new: &VNode) -> Vec<Patch> {
  function diff_node (line 126) | fn diff_node(context: &mut DiffContext, old: &Rc<RefCell<RenderNode>>, n...
  function diff_div (line 175) | fn diff_div(
  function diff_children (line 228) | fn diff_children(

FILE: rxtui/lib/effect/runtime.rs
  type EffectRuntime (line 13) | pub struct EffectRuntime {
    method new (line 35) | pub fn new() -> Self {
    method handle (line 51) | fn handle(&self) -> &Handle {
    method spawn (line 60) | pub fn spawn(&self, component_id: ComponentId, effects: Vec<Effect>) {
    method cleanup (line 76) | pub fn cleanup(&self, component_id: &ComponentId) {
    method cleanup_all (line 86) | pub fn cleanup_all(&self) {
    method has_effects (line 96) | pub fn has_effects(&self, component_id: &ComponentId) -> bool {
  type RuntimeHandle (line 22) | enum RuntimeHandle {
  method default (line 106) | fn default() -> Self {
  method drop (line 112) | fn drop(&mut self) {

FILE: rxtui/lib/effect/types.rs
  type Effect (line 10) | pub type Effect = Pin<Box<dyn Future<Output = ()> + Send + 'static>>;

FILE: rxtui/lib/key.rs
  type KeyWithModifiers (line 12) | pub struct KeyWithModifiers {
    method new (line 35) | pub fn new(key: Key) -> Self {
    method with_ctrl (line 46) | pub fn with_ctrl(key: Key) -> Self {
    method with_alt (line 57) | pub fn with_alt(key: Key) -> Self {
    method with_shift (line 68) | pub fn with_shift(key: Key) -> Self {
    method from_key_event (line 79) | pub fn from_key_event(event: crossterm::event::KeyEvent) -> Option<Sel...
    method is_primary_modifier (line 93) | pub fn is_primary_modifier(&self) -> bool {
  type Key (line 120) | pub enum Key {
    method from_key_code (line 177) | pub fn from_key_code(code: crossterm::event::KeyCode) -> Option<Self> {
    method fmt (line 218) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {

FILE: rxtui/lib/lib.rs
  type Effect (line 402) | pub struct Effect;
    method none (line 406) | pub fn none() -> Vec<Self> {

FILE: rxtui/lib/node/div.rs
  type KeyHandler (line 16) | pub type KeyHandler = (Key, Rc<dyn Fn()>, bool);
  type KeyWithModifiersHandler (line 19) | pub type KeyWithModifiersHandler = (KeyWithModifiers, Rc<dyn Fn()>, bool);
  type Div (line 23) | pub struct Div<T> {
  type DivStyles (line 48) | pub struct DivStyles {
  type EventCallbacks (line 61) | pub struct EventCallbacks {
  function new (line 92) | pub fn new() -> Self {
  function children (line 105) | pub fn children(mut self, children: Vec<T>) -> Self {
  function child (line 111) | pub fn child(mut self, child: T) -> Self {
  function focusable (line 117) | pub fn focusable(mut self, focusable: bool) -> Self {
  function direction (line 123) | pub fn direction(mut self, direction: Direction) -> Self {
  function position (line 129) | pub fn position(mut self, position: Position) -> Self {
  function overflow (line 135) | pub fn overflow(mut self, overflow: Overflow) -> Self {
  function padding (line 141) | pub fn padding(mut self, padding: Spacing) -> Self {
  function margin (line 147) | pub fn margin(mut self, margin: Spacing) -> Self {
  function gap (line 153) | pub fn gap(mut self, gap: u16) -> Self {
  function wrap (line 159) | pub fn wrap(mut self, wrap: WrapMode) -> Self {
  function width (line 165) | pub fn width(mut self, width: u16) -> Self {
  function width_dim (line 171) | pub fn width_dim(mut self, width: Dimension) -> Self {
  function height (line 177) | pub fn height(mut self, height: u16) -> Self {
  function height_dim (line 183) | pub fn height_dim(mut self, height: Dimension) -> Self {
  function width_fraction (line 189) | pub fn width_fraction(mut self, fraction: f32) -> Self {
  function height_fraction (line 197) | pub fn height_fraction(mut self, fraction: f32) -> Self {
  function width_auto (line 205) | pub fn width_auto(mut self) -> Self {
  function height_auto (line 211) | pub fn height_auto(mut self) -> Self {
  function height_content (line 217) | pub fn height_content(mut self) -> Self {
  function width_content (line 223) | pub fn width_content(mut self) -> Self {
  function min_width (line 229) | pub fn min_width(mut self, width: u16) -> Self {
  function min_height (line 235) | pub fn min_height(mut self, height: u16) -> Self {
  function max_width (line 241) | pub fn max_width(mut self, width: u16) -> Self {
  function max_height (line 247) | pub fn max_height(mut self, height: u16) -> Self {
  function background (line 253) | pub fn background(mut self, color: Color) -> Self {
  function border (line 259) | pub fn border(mut self, border: BorderStyle) -> Self {
  function border_with (line 270) | pub fn border_with(mut self, border: Border) -> Self {
  function border_color (line 276) | pub fn border_color(mut self, color: Color) -> Self {
  function border_style (line 287) | pub fn border_style(self, style: BorderStyle) -> Self {
  function border_style_with_color (line 292) | pub fn border_style_with_color(mut self, style: BorderStyle, color: Colo...
  function border_edges (line 303) | pub fn border_edges(mut self, edges: BorderEdges) -> Self {
  function show_scrollbar (line 319) | pub fn show_scrollbar(mut self, show: bool) -> Self {
  function absolute_position (line 328) | pub fn absolute_position(mut self) -> Self {
  function absolute (line 334) | pub fn absolute(mut self, x: u16, y: u16) -> Self {
  function x (line 343) | pub fn x(mut self, x: u16) -> Self {
  function y (line 349) | pub fn y(mut self, y: u16) -> Self {
  function top (line 355) | pub fn top(mut self, top: i16) -> Self {
  function right (line 361) | pub fn right(mut self, right: i16) -> Self {
  function bottom (line 367) | pub fn bottom(mut self, bottom: i16) -> Self {
  function left (line 373) | pub fn left(mut self, left: i16) -> Self {
  function z_index (line 379) | pub fn z_index(mut self, z: i32) -> Self {
  function justify_content (line 385) | pub fn justify_content(mut self, justify: JustifyContent) -> Self {
  function align_items (line 394) | pub fn align_items(mut self, align: AlignItems) -> Self {
  function align_self (line 400) | pub fn align_self(mut self, align: AlignSelf) -> Self {
  function focus_style (line 406) | pub fn focus_style(mut self, style: Style) -> Self {
  function focus_border (line 412) | pub fn focus_border(self, color: Color) -> Self {
  function focus_border_style (line 417) | pub fn focus_border_style(self, border_style: BorderStyle, color: Color)...
  function focus_border_with (line 422) | pub fn focus_border_with(mut self, border: Border) -> Self {
  function hover_style (line 430) | pub fn hover_style(mut self, style: Style) -> Self {
  function style (line 436) | pub fn style(mut self, style: Style) -> Self {
  function on_key (line 442) | pub fn on_key(mut self, key: Key, handler: impl Fn() + 'static) -> Self {
  function on_char (line 448) | pub fn on_char(mut self, ch: char, handler: impl Fn() + 'static) -> Self {
  function on_key_global (line 456) | pub fn on_key_global(mut self, key: Key, handler: impl Fn() + 'static) -...
  function on_char_global (line 462) | pub fn on_char_global(mut self, ch: char, handler: impl Fn() + 'static) ...
  function on_key_with_modifiers (line 470) | pub fn on_key_with_modifiers(
  function on_key_with_modifiers_global (line 482) | pub fn on_key_with_modifiers_global(
  function on_any_char (line 494) | pub fn on_any_char(mut self, handler: impl Fn(char) + 'static) -> Self {
  function on_any_key (line 500) | pub fn on_any_key(mut self, handler: impl Fn(Key) + 'static) -> Self {
  function on_click (line 506) | pub fn on_click(mut self, handler: impl Fn() + 'static) -> Self {
  function on_focus (line 512) | pub fn on_focus(mut self, handler: impl Fn() + 'static) -> Self {
  function on_blur (line 518) | pub fn on_blur(mut self, handler: impl Fn() + 'static) -> Self {
  function map (line 524) | pub fn map<U, F>(self, f: F) -> Div<U>
  function active_style (line 540) | pub fn active_style(&self) -> Option<&Style> {
  method default (line 552) | fn default() -> Self {
  method eq (line 562) | fn eq(&self, other: &Self) -> bool {
  method eq (line 573) | fn eq(&self, other: &Self) -> bool {
  method fmt (line 579) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  method fmt (line 589) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  method fmt (line 606) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  type ElementBuilder (line 619) | pub struct ElementBuilder<T> {
  function new (line 625) | pub fn new(element: T) -> Self {
  function build (line 632) | pub fn build(self) -> T {

FILE: rxtui/lib/node/mod.rs
  type Node (line 18) | pub enum Node {
    method text (line 39) | pub fn text(content: impl Into<String>) -> Node {
    method div (line 45) | pub fn div() -> Node {
    method rich_text (line 51) | pub fn rich_text() -> Node {
    method child (line 63) | pub fn child(mut self, child: impl Into<Node>) -> Self {
    method fmt (line 87) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    method from (line 109) | fn from(text: Text) -> Self {
    method from (line 115) | fn from(rich: RichText) -> Self {
    method from (line 121) | fn from(component: Arc<dyn Component>) -> Self {
    method from (line 127) | fn from(div: Div<Node>) -> Self {
  method clone (line 76) | fn clone(&self) -> Self {
  method eq (line 98) | fn eq(&self, other: &Self) -> bool {

FILE: rxtui/lib/node/rich_text.rs
  type TextSpan (line 10) | pub struct TextSpan {
  type RichText (line 20) | pub struct RichText {
    method new (line 31) | pub fn new() -> Self {
    method with_cursor (line 41) | pub fn with_cursor(text: &str, cursor_pos: usize, cursor_style: TextSt...
    method text (line 86) | pub fn text(mut self, content: impl Into<String>) -> Self {
    method colored (line 96) | pub fn colored(mut self, content: impl Into<String>, color: Color) -> ...
    method bold (line 109) | pub fn bold(mut self, content: impl Into<String>) -> Self {
    method italic (line 122) | pub fn italic(mut self, content: impl Into<String>) -> Self {
    method styled (line 135) | pub fn styled(mut self, content: impl Into<String>, style: TextStyle) ...
    method wrap (line 145) | pub fn wrap(mut self, wrap: TextWrap) -> Self {
    method align (line 151) | pub fn align(mut self, align: TextAlign) -> Self {
    method color (line 157) | pub fn color(mut self, color: Color) -> Self {
    method background (line 168) | pub fn background(mut self, color: Color) -> Self {
    method bold_all (line 179) | pub fn bold_all(mut self) -> Self {
    method italic_all (line 190) | pub fn italic_all(mut self) -> Self {
    method underline_all (line 201) | pub fn underline_all(mut self) -> Self {
    method content (line 212) | pub fn content(&self) -> String {
    method is_empty (line 220) | pub fn is_empty(&self) -> bool {
    method clear (line 225) | pub fn clear(&mut self) {
    method append (line 230) | pub fn append(&mut self, other: &mut RichText) {
    method from (line 246) | fn from(s: String) -> Self {
    method from (line 252) | fn from(s: &str) -> Self {
  method default (line 240) | fn default() -> Self {
  function test_rich_text_creation (line 266) | fn test_rich_text_creation() {
  function test_rich_text_bold_italic (line 283) | fn test_rich_text_bold_italic() {
  function test_rich_text_with_cursor (line 296) | fn test_rich_text_with_cursor() {
  function test_top_level_styling_methods (line 336) | fn test_top_level_styling_methods() {
  function test_rich_text_bold_all (line 352) | fn test_rich_text_bold_all() {
  function test_rich_text_wrap (line 371) | fn test_rich_text_wrap() {
  function test_rich_text_helper_methods (line 381) | fn test_rich_text_helper_methods() {
  function test_rich_text_from_traits (line 405) | fn test_rich_text_from_traits() {
  function test_rich_text_default (line 418) | fn test_rich_text_default() {

FILE: rxtui/lib/node/text.rs
  type Text (line 10) | pub struct Text {
    method new (line 21) | pub fn new(content: impl Into<String>) -> Self {
    method color (line 29) | pub fn color(mut self, color: Color) -> Self {
    method background (line 35) | pub fn background(mut self, color: Color) -> Self {
    method bold (line 41) | pub fn bold(mut self) -> Self {
    method italic (line 47) | pub fn italic(mut self) -> Self {
    method underline (line 53) | pub fn underline(mut self) -> Self {
    method strikethrough (line 59) | pub fn strikethrough(mut self) -> Self {
    method wrap (line 65) | pub fn wrap(mut self, wrap: TextWrap) -> Self {
    method align (line 71) | pub fn align(mut self, align: TextAlign) -> Self {
    method from (line 82) | fn from(content: String) -> Self {
    method from (line 88) | fn from(content: &str) -> Self {

FILE: rxtui/lib/providers.rs
  type UpdateProvider (line 19) | pub trait UpdateProvider {
    method __component_update_impl (line 22) | fn __component_update_impl(
  type ViewProvider (line 38) | pub trait ViewProvider {
    method __component_view_impl (line 41) | fn __component_view_impl(&self, _ctx: &Context) -> Node {
  type EffectsProvider (line 52) | pub trait EffectsProvider {
    method __component_effects_impl (line 55) | fn __component_effects_impl(&self, _ctx: &Context) -> Vec<Effect> {

FILE: rxtui/lib/render_tree/node.rs
  type RenderNode (line 35) | pub struct RenderNode {
    method new (line 175) | pub fn new(node_type: RenderNodeType) -> Self {
    method element (line 204) | pub fn element() -> Self {
    method text (line 209) | pub fn text(content: impl Into<String>) -> Self {
    method text_wrapped (line 214) | pub fn text_wrapped(lines: Vec<String>) -> Self {
    method set_position (line 219) | pub fn set_position(&mut self, x: u16, y: u16) {
    method set_size (line 225) | pub fn set_size(&mut self, width: u16, height: u16) {
    method add_child_with_parent (line 231) | pub fn add_child_with_parent(
    method bounds (line 240) | pub fn bounds(&self) -> Rect {
    method mark_dirty (line 248) | pub fn mark_dirty(&mut self) {
    method clear_dirty (line 255) | pub fn clear_dirty(&mut self) {
    method compose_state_style (line 260) | pub fn compose_state_style(
    method apply_computed_style (line 286) | fn apply_computed_style(&mut self, style: Option<Style>) {
    method refresh_state_style (line 305) | pub fn refresh_state_style(&mut self) {
    method is_positioned (line 317) | pub fn is_positioned(&self) -> bool {
    method update_scroll (line 324) | pub fn update_scroll(&mut self, delta_y: i16) -> bool {
    method set_scroll_y (line 344) | pub fn set_scroll_y(&mut self, y: u16) {
    method get_max_scroll_y (line 354) | pub fn get_max_scroll_y(&self) -> u16 {
    method calculate_intrinsic_size (line 360) | pub fn calculate_intrinsic_size(&self) -> (u16, u16) {
    method calculate_intrinsic_size_multipass (line 367) | fn calculate_intrinsic_size_multipass(
    method calculate_intrinsic_size_single_pass (line 391) | fn calculate_intrinsic_size_single_pass(&self, hint: Option<(u16, u16)...
    method calculate_standard_intrinsic_size (line 526) | fn calculate_standard_intrinsic_size(
    method calculate_wrapped_intrinsic_size (line 652) | fn calculate_wrapped_intrinsic_size(
    method apply_text_wrapping (line 820) | pub fn apply_text_wrapping(&mut self, available_width: u16) {
    method layout (line 945) | pub fn layout(&mut self) {
    method layout_with_parent (line 960) | pub fn layout_with_parent(&mut self, parent_width: u16, parent_height:...
    method layout_children (line 1104) | fn layout_children(&mut self, direction: Direction) {
    method layout_children_with_wrap (line 1150) | fn layout_children_with_wrap(
    method layout_children_with_parent (line 1511) | pub(crate) fn layout_children_with_parent(&mut self, direction: Direct...
    method calculate_content_dimensions (line 2196) | fn calculate_content_dimensions(&mut self) {
    method position_absolute_child (line 2264) | fn position_absolute_child(
    method handle_click (line 2302) | pub fn handle_click(&self) {
    method handle_key (line 2312) | pub fn handle_key(&self, key: Key) {
    method handle_global_key (line 2337) | pub fn handle_global_key(&self, key: Key) {
    method handle_key_with_modifiers (line 2348) | pub fn handle_key_with_modifiers(&self, key_with_modifiers: crate::key...
    method handle_global_key_with_modifiers (line 2360) | pub fn handle_global_key_with_modifiers(
  type RenderNodeType (line 108) | pub enum RenderNodeType {
  function calculate_justify_offsets (line 130) | fn calculate_justify_offsets(

FILE: rxtui/lib/render_tree/tests/layout_tests.rs
  function test_child_respects_parent_content_area (line 7) | fn test_child_respects_parent_content_area() {
  function test_auto_sizing_horizontal (line 66) | fn test_auto_sizing_horizontal() {
  function test_auto_sizing_vertical (line 139) | fn test_auto_sizing_vertical() {
  function test_multiple_auto_sizing (line 214) | fn test_multiple_auto_sizing() {
  function test_auto_sizing_with_padding (line 310) | fn test_auto_sizing_with_padding() {
  function test_no_space_for_auto (line 374) | fn test_no_space_for_auto() {

FILE: rxtui/lib/render_tree/tests/rich_text_tests.rs
  function test_rich_text_render_node_creation (line 9) | fn test_rich_text_render_node_creation() {
  function test_rich_text_width_calculation (line 25) | fn test_rich_text_width_calculation() {
  function test_rich_text_wrapping_application (line 39) | fn test_rich_text_wrapping_application() {
  function test_rich_text_wrapping_preserves_styles (line 59) | fn test_rich_text_wrapping_preserves_styles() {
  function test_syntax_highlighting_with_word_break (line 91) | fn test_syntax_highlighting_with_word_break() {
  function test_leading_spaces_preserved_in_richtext (line 162) | fn test_leading_spaces_preserved_in_richtext() {
  function test_richtext_unicode_handling (line 204) | fn test_richtext_unicode_handling() {
  function test_wrapped_richtext_height_in_vertical_layout (line 259) | fn test_wrapped_richtext_height_in_vertical_layout() {

FILE: rxtui/lib/render_tree/tests/sizing_tests.rs
  function test_content_based_sizing_text (line 8) | fn test_content_based_sizing_text() {
  function test_content_based_sizing_vertical_stack (line 41) | fn test_content_based_sizing_vertical_stack() {
  function test_content_based_sizing_horizontal_stack (line 82) | fn test_content_based_sizing_horizontal_stack() {
  function test_content_sizing_with_border (line 123) | fn test_content_sizing_with_border() {
  function test_explicit_content_dimension (line 164) | fn test_explicit_content_dimension() {
  function test_nested_content_sizing (line 200) | fn test_nested_content_sizing() {
  function test_complex_nested_convergence (line 244) | fn test_complex_nested_convergence() {

FILE: rxtui/lib/render_tree/tests/wrapping_tests.rs
  function test_content_sizing_with_wrapped_text (line 8) | fn test_content_sizing_with_wrapped_text() {
  function test_horizontal_layout_with_wrapped_text (line 31) | fn test_horizontal_layout_with_wrapped_text() {
  function test_element_wrap_with_fixed_width (line 93) | fn test_element_wrap_with_fixed_width() {
  function test_element_wrap_with_percentage_children (line 145) | fn test_element_wrap_with_percentage_children() {
  function test_nested_wrapping_containers (line 206) | fn test_nested_wrapping_containers() {
  function test_text_wrapping_with_parent_fixed_width (line 279) | fn test_text_wrapping_with_parent_fixed_width() {
  function test_multiple_wrapped_texts_horizontal (line 324) | fn test_multiple_wrapped_texts_horizontal() {

FILE: rxtui/lib/render_tree/tree.rs
  type RenderTree (line 20) | pub struct RenderTree {
    method new (line 40) | pub fn new() -> Self {
    method focus_clear_flag (line 50) | pub fn focus_clear_flag(&self) -> Arc<AtomicBool> {
    method debug_string (line 58) | pub fn debug_string(&self) -> String {
    method debug_node (line 72) | fn debug_node(node: &RenderNode, output: &mut String, depth: usize) {
    method set_root (line 196) | pub fn set_root(&mut self, root: Rc<RefCell<RenderNode>>) {
    method layout (line 204) | pub fn layout(&mut self, viewport_width: u16, viewport_height: u16) {
    method layout_with_options (line 212) | pub fn layout_with_options(
    method find_node_at (line 316) | pub fn find_node_at(&self, x: u16, y: u16) -> Option<Rc<RefCell<Render...
    method find_node_at_recursive (line 332) | fn find_node_at_recursive(
    method collect_dirty_regions (line 429) | pub fn collect_dirty_regions(&self) -> Vec<Rect> {
    method collect_dirty_regions_recursive (line 439) | fn collect_dirty_regions_recursive(node: &Rc<RefCell<RenderNode>>, reg...
    method merge_regions (line 450) | fn merge_regions(&self, mut regions: Vec<Rect>) -> Vec<Rect> {
    method are_adjacent (line 473) | fn are_adjacent(&self, a: &Rect, b: &Rect) -> bool {
    method clear_all_dirty (line 483) | pub fn clear_all_dirty(&self) {
    method clear_dirty_recursive (line 490) | fn clear_dirty_recursive(node: &Rc<RefCell<RenderNode>>) {
    method collect_focusable_nodes (line 505) | pub fn collect_focusable_nodes(&self) -> Vec<Rc<RefCell<RenderNode>>> {
    method find_component_root (line 514) | pub fn find_component_root(
    method find_first_focusable_in (line 524) | pub fn find_first_focusable_in(
    method find_first_focusable_global (line 532) | pub fn find_first_focusable_global(&self) -> Option<Rc<RefCell<RenderN...
    method collect_focusable_recursive (line 539) | fn collect_focusable_recursive(
    method find_component_root_recursive (line 559) | fn find_component_root_recursive(
    method find_first_focusable_recursive (line 589) | fn find_first_focusable_recursive(
    method get_focused_node (line 611) | pub fn get_focused_node(&self) -> Option<Rc<RefCell<RenderNode>>> {
    method set_focused_node (line 616) | pub fn set_focused_node(&self, node: Option<Rc<RefCell<RenderNode>>>) {
    method set_hovered_node (line 655) | pub fn set_hovered_node(&self, node: Option<Rc<RefCell<RenderNode>>>) {
    method focus_next (line 683) | pub fn focus_next(&self) {
    method focus_prev (line 708) | pub fn focus_prev(&self) {
  method default (line 744) | fn default() -> Self {

FILE: rxtui/lib/style.rs
  type Dimension (line 33) | pub enum Dimension {
  type Spacing (line 80) | pub struct Spacing {
    method all (line 1110) | pub fn all(value: u16) -> Self {
    method vertical (line 1131) | pub fn vertical(value: u16) -> Self {
    method horizontal (line 1148) | pub fn horizontal(value: u16) -> Self {
  type Color (line 112) | pub enum Color {
    method from_hex (line 597) | pub fn from_hex(hex: &str) -> Result<Self, &'static str> {
    method hex (line 651) | pub fn hex(hex: &str) -> Self {
    method rgb (line 665) | pub fn rgb(r: u8, g: u8, b: u8) -> Self {
  type Direction (line 187) | pub enum Direction {
  type Overflow (line 199) | pub enum Overflow {
  type TextAlign (line 217) | pub enum TextAlign {
  type TextWrap (line 233) | pub enum TextWrap {
  type WrapMode (line 254) | pub enum WrapMode {
  type Position (line 269) | pub enum Position {
  type JustifyContent (line 289) | pub enum JustifyContent {
  type AlignItems (line 316) | pub enum AlignItems {
  type AlignSelf (line 333) | pub enum AlignSelf {
  type BorderStyle (line 388) | pub enum BorderStyle {
  type Border (line 412) | pub struct Border {
    method new (line 875) | pub fn new(color: Color) -> Self {
    method none (line 885) | pub fn none() -> Self {
    method with_style (line 895) | pub fn with_style(style: BorderStyle, color: Color) -> Self {
    method with_edges (line 905) | pub fn with_edges(style: BorderStyle, color: Color, edges: BorderEdges...
  type Style (line 431) | pub struct Style {
    method default_focus (line 686) | pub fn default_focus() -> Style {
    method merge (line 702) | pub fn merge(base: Option<Style>, overlay: Option<Style>) -> Option<St...
    method background (line 772) | pub fn background(mut self, color: Color) -> Self {
    method direction (line 778) | pub fn direction(mut self, direction: Direction) -> Self {
    method padding (line 784) | pub fn padding(mut self, padding: Spacing) -> Self {
    method overflow (line 790) | pub fn overflow(mut self, overflow: Overflow) -> Self {
    method width (line 796) | pub fn width(mut self, width: Dimension) -> Self {
    method height (line 802) | pub fn height(mut self, height: Dimension) -> Self {
    method border (line 808) | pub fn border(mut self, color: Color) -> Self {
    method position (line 819) | pub fn position(mut self, position: Position) -> Self {
    method z_index (line 825) | pub fn z_index(mut self, z_index: i32) -> Self {
    method top (line 831) | pub fn top(mut self, top: i16) -> Self {
    method right (line 837) | pub fn right(mut self, right: i16) -> Self {
    method bottom (line 843) | pub fn bottom(mut self, bottom: i16) -> Self {
    method left (line 849) | pub fn left(mut self, left: i16) -> Self {
    method wrap (line 855) | pub fn wrap(mut self, wrap: WrapMode) -> Self {
    method gap (line 861) | pub fn gap(mut self, gap: u16) -> Self {
    method show_scrollbar (line 867) | pub fn show_scrollbar(mut self, show: bool) -> Self {
    method builder (line 918) | pub fn builder() -> StyleBuilder {
  type TextStyle (line 519) | pub struct TextStyle {
    method merge (line 930) | pub fn merge(base: Option<TextStyle>, overlay: Option<TextStyle>) -> O...
    method builder (line 968) | pub fn builder() -> TextStyleBuilder {
    method color (line 984) | pub fn color(mut self, color: Color) -> Self {
    method background (line 990) | pub fn background(mut self, color: Color) -> Self {
    method bold (line 996) | pub fn bold(mut self, bold: bool) -> Self {
    method italic (line 1002) | pub fn italic(mut self, italic: bool) -> Self {
    method underline (line 1008) | pub fn underline(mut self, underline: bool) -> Self {
    method strikethrough (line 1014) | pub fn strikethrough(mut self, strikethrough: bool) -> Self {
    method wrap (line 1020) | pub fn wrap(mut self, wrap: TextWrap) -> Self {
    method align (line 1026) | pub fn align(mut self, align: TextAlign) -> Self {
  type StyleBuilder (line 555) | pub struct StyleBuilder {
    method background (line 1160) | pub fn background(mut self, color: Color) -> Self {
    method direction (line 1166) | pub fn direction(mut self, direction: Direction) -> Self {
    method padding (line 1172) | pub fn padding(mut self, padding: Spacing) -> Self {
    method overflow (line 1178) | pub fn overflow(mut self, overflow: Overflow) -> Self {
    method width (line 1184) | pub fn width(mut self, width: Dimension) -> Self {
    method height (line 1190) | pub fn height(mut self, height: Dimension) -> Self {
    method border (line 1196) | pub fn border(mut self, color: Color) -> Self {
    method position (line 1207) | pub fn position(mut self, position: Position) -> Self {
    method z_index (line 1213) | pub fn z_index(mut self, z_index: i32) -> Self {
    method top (line 1219) | pub fn top(mut self, top: i16) -> Self {
    method right (line 1225) | pub fn right(mut self, right: i16) -> Self {
    method bottom (line 1231) | pub fn bottom(mut self, bottom: i16) -> Self {
    method left (line 1237) | pub fn left(mut self, left: i16) -> Self {
    method wrap (line 1243) | pub fn wrap(mut self, wrap: WrapMode) -> Self {
    method gap (line 1249) | pub fn gap(mut self, gap: u16) -> Self {
    method build (line 1255) | pub fn build(self) -> Style {
  type TextStyleBuilder (line 570) | pub struct TextStyleBuilder {
    method color (line 1034) | pub fn color(mut self, color: Color) -> Self {
    method background (line 1040) | pub fn background(mut self, color: Color) -> Self {
    method bold (line 1046) | pub fn bold(mut self) -> Self {
    method italic (line 1052) | pub fn italic(mut self) -> Self {
    method underline (line 1058) | pub fn underline(mut self) -> Self {
    method strikethrough (line 1064) | pub fn strikethrough(mut self) -> Self {
    method strong (line 1070) | pub fn strong(self) -> Self {
    method emphasis (line 1075) | pub fn emphasis(self) -> Self {
    method wrap (line 1080) | pub fn wrap(mut self, wrap: TextWrap) -> Self {
    method align (line 1086) | pub fn align(mut self, align: TextAlign) -> Self {
    method build (line 1092) | pub fn build(self) -> TextStyle {
  function parse_hex_digit (line 671) | fn parse_hex_digit(c: char) -> Result<u8, &'static str> {
  method default (line 1266) | fn default() -> Self {
  method default (line 1301) | fn default() -> Self {
  function test_hex_color_parsing (line 1324) | fn test_hex_color_parsing() {
  function test_hex_panic_method (line 1363) | fn test_hex_panic_method() {
  function test_hex_panic_on_invalid (line 1371) | fn test_hex_panic_on_invalid() {
  function test_rgb_constructor (line 1376) | fn test_rgb_constructor() {

FILE: rxtui/lib/terminal.rs
  type TerminalRenderer (line 39) | pub struct TerminalRenderer {
    method new (line 103) | pub fn new() -> Self {
    method detect_synchronized_output (line 115) | fn detect_synchronized_output() -> bool {
    method apply_updates (line 142) | pub fn apply_updates(&mut self, updates: Vec<CellUpdate>) -> io::Resul...
    method apply_updates_direct (line 156) | pub fn apply_updates_direct(&mut self, updates: Vec<CellUpdate>) -> io...
    method clear_screen (line 175) | pub fn clear_screen(&mut self) -> io::Result<()> {
    method draw_full_buffer (line 192) | pub fn draw_full_buffer(&mut self, buffer: &crate::buffer::ScreenBuffe...
    method color_to_crossterm (line 212) | pub fn color_to_crossterm(&self, color: Color) -> crossterm::style::Co...
    method apply_cell_style (line 235) | fn apply_cell_style(&mut self, cell: &Cell) -> io::Result<()> {
    method apply_updates_synchronized (line 282) | fn apply_updates_synchronized(&mut self, updates: Vec<CellUpdate>) -> ...
    method apply_updates_optimized (line 296) | fn apply_updates_optimized(&mut self, updates: Vec<CellUpdate>) -> io:...
    method apply_command (line 311) | fn apply_command(&mut self, cmd: TerminalCommand) -> io::Result<()> {
    method set_colors (line 346) | fn set_colors(&mut self, fg: Option<Color>, bg: Option<Color>) -> io::...
    method set_style (line 385) | fn set_style(&mut self, style: CellStyle) -> io::Result<()> {
    method reset (line 411) | pub fn reset(&mut self) -> io::Result<()> {
    method clear_lines (line 418) | pub fn clear_lines(&mut self, start_row: u16, count: u16) -> io::Resul...
    method apply_updates_inline (line 433) | pub fn apply_updates_inline(
  type TerminalCommand (line 61) | enum TerminalCommand {
  type UpdateBatcher (line 82) | struct UpdateBatcher {
    method new (line 461) | pub fn new(updates: Vec<CellUpdate>) -> Self {
    method optimize (line 482) | pub fn optimize(mut self) -> Vec<TerminalCommand> {
    method group_into_runs (line 518) | fn group_into_runs(self) -> Vec<Run> {
  type Run (line 88) | struct Run {
    method new (line 553) | fn new(x: u16, y: u16, cell: Cell) -> Self {
    method can_append (line 587) | fn can_append(&self, x: u16, y: u16, cell: &Cell) -> bool {
    method into_commands (line 597) | fn into_commands(self) -> Vec<TerminalCommand> {
  function to_crossterm_color (line 627) | fn to_crossterm_color(color: Color) -> crossterm::style::Color {
  method default (line 654) | fn default() -> Self {
  function test_update_batcher_single_cell (line 670) | fn test_update_batcher_single_cell() {
  function test_update_batcher_consecutive_cells_same_style (line 699) | fn test_update_batcher_consecutive_cells_same_style() {
  function test_update_batcher_different_styles (line 764) | fn test_update_batcher_different_styles() {
  function test_update_batcher_sorting (line 822) | fn test_update_batcher_sorting() {
  function test_run_can_append (line 849) | fn test_run_can_append() {
  function test_run_with_bold_style (line 885) | fn test_run_with_bold_style() {
  function test_terminal_command_types (line 913) | fn test_terminal_command_types() {
  function test_to_crossterm_color (line 941) | fn test_to_crossterm_color() {
  function test_empty_updates (line 961) | fn test_empty_updates() {
  function test_multiple_runs_different_lines (line 969) | fn test_multiple_runs_different_lines() {

FILE: rxtui/lib/tests/rich_text_tests.rs
  function test_rich_text_creation (line 14) | fn test_rich_text_creation() {
  function test_rich_text_bold_italic (line 31) | fn test_rich_text_bold_italic() {
  function test_rich_text_with_cursor (line 44) | fn test_rich_text_with_cursor() {
  function test_top_level_styling_methods (line 84) | fn test_top_level_styling_methods() {
  function test_rich_text_bold_all (line 100) | fn test_rich_text_bold_all() {
  function test_rich_text_wrap (line 119) | fn test_rich_text_wrap() {
  function test_rich_text_helper_methods (line 129) | fn test_rich_text_helper_methods() {
  function test_rich_text_from_traits (line 153) | fn test_rich_text_from_traits() {
  function test_rich_text_default (line 166) | fn test_rich_text_default() {
  function test_rich_text_render_node_creation (line 178) | fn test_rich_text_render_node_creation() {
  function test_rich_text_width_calculation (line 198) | fn test_rich_text_width_calculation() {
  function test_rich_text_wrapping_application (line 212) | fn test_rich_text_wrapping_application() {
  function test_rich_text_wrapping_preserves_styles (line 251) | fn test_rich_text_wrapping_preserves_styles() {
  function test_rich_text_in_div (line 300) | fn test_rich_text_in_div() {
  function test_rich_text_with_parent_width (line 315) | fn test_rich_text_with_parent_width() {
  function test_rich_text_mixed_with_regular_text (line 356) | fn test_rich_text_mixed_with_regular_text() {
  function test_rich_text_from_node (line 390) | fn test_rich_text_from_node() {

FILE: rxtui/lib/utils.rs
  function display_width (line 56) | pub fn display_width(s: &str) -> usize {
  function char_width (line 66) | pub fn char_width(c: char) -> usize {
  function substring_by_columns (line 75) | pub fn substring_by_columns(s: &str, start_col: usize, end_col: usize) -...
  function wrap_text (line 126) | pub fn wrap_text(text: &str, width: u16, mode: TextWrap) -> Vec<String> {
  function wrap_character (line 154) | fn wrap_character(text: &str, width: u16) -> Vec<String> {
  function wrap_word (line 200) | fn wrap_word(text: &str, width: u16) -> Vec<String> {
  function wrap_word_break (line 325) | fn wrap_word_break(text: &str, width: u16) -> Vec<String> {
  function test_display_width_ascii (line 493) | fn test_display_width_ascii() {
  function test_display_width_unicode (line 500) | fn test_display_width_unicode() {
  function test_char_width (line 511) | fn test_char_width() {
  function test_substring_by_columns (line 519) | fn test_substring_by_columns() {
  function test_wrap_none (line 550) | fn test_wrap_none() {
  function test_wrap_character (line 557) | fn test_wrap_character() {
  function test_wrap_character_exact (line 564) | fn test_wrap_character_exact() {
  function test_wrap_word (line 571) | fn test_wrap_word() {
  function test_wrap_word_long_word (line 579) | fn test_wrap_word_long_word() {
  function test_wrap_word_break (line 590) | fn test_wrap_word_break() {
  function test_wrap_word_break_preserves_leading_spaces (line 598) | fn test_wrap_word_break_preserves_leading_spaces() {
  function test_wrap_empty_text (line 605) | fn test_wrap_empty_text() {
  function test_wrap_zero_width (line 612) | fn test_wrap_zero_width() {
  function test_wrap_unicode (line 622) | fn test_wrap_unicode() {
  function test_wrap_emoji (line 638) | fn test_wrap_emoji() {
  function test_wrap_word_multiple_spaces (line 649) | fn test_wrap_word_multiple_spaces() {
  function test_wrap_preserves_leading_spaces (line 657) | fn test_wrap_preserves_leading_spaces() {
  function test_wrap_preserves_trailing_spaces (line 664) | fn test_wrap_preserves_trailing_spaces() {

FILE: rxtui/lib/vdom.rs
  type VDom (line 58) | pub struct VDom {
    method new (line 72) | pub fn new() -> Self {
    method render (line 99) | pub fn render(&mut self, vnode: VNode) {
    method layout (line 117) | pub fn layout(&mut self, width: u16, height: u16) {
    method layout_with_options (line 125) | pub fn layout_with_options(&mut self, width: u16, height: u16, unclamp...
    method get_render_tree (line 133) | pub fn get_render_tree(&self) -> &RenderTree {
    method focus_clear_flag (line 138) | pub fn focus_clear_flag(&self) -> Arc<AtomicBool> {
    method create_render_node (line 146) | fn create_render_node(&self, vnode: &VNode) -> Rc<RefCell<RenderNode>> {
    method create_div_node (line 161) | fn create_div_node(&self, div: &crate::node::Div<VNode>) -> Rc<RefCell...
    method create_text_node (line 231) | fn create_text_node(&self, text: &crate::node::Text) -> Rc<RefCell<Ren...
    method create_rich_text_node (line 251) | fn create_rich_text_node(&self, rich: &crate::node::RichText) -> Rc<Re...
    method apply_patches (line 284) | fn apply_patches(&mut self, patches: Vec<Patch>) {
    method apply_patch (line 299) | fn apply_patch(&mut self, patch: Patch) {
  method default (line 420) | fn default() -> Self {

FILE: rxtui/lib/vnode.rs
  type VNode (line 10) | pub enum VNode {
    method text (line 28) | pub fn text(content: impl Into<String>) -> VNode {
    method div (line 34) | pub fn div() -> VNode {
    method rich_text (line 40) | pub fn rich_text() -> VNode {
    method child (line 52) | pub fn child(mut self, child: impl Into<VNode>) -> Self {
    method fmt (line 65) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    method from (line 87) | fn from(text: Text) -> Self {
    method from (line 94) | fn from(div: Div<VNode>) -> Self {
    method from (line 101) | fn from(content: String) -> Self {
    method from (line 108) | fn from(content: &str) -> Self {
    method from (line 115) | fn from(rich: RichText) -> Self {
  method eq (line 75) | fn eq(&self, other: &Self) -> bool {

FILE: rxtui/tests/macro_tests.rs
  function test_empty_div (line 10) | fn test_empty_div() {
  function test_div_with_basic_props (line 22) | fn test_div_with_basic_props() {
  function test_div_with_hex_color (line 34) | fn test_div_with_hex_color() {
  function test_div_with_percentage_dimensions (line 46) | fn test_div_with_percentage_dimensions() {
  function test_container_with_auto_dimensions (line 58) | fn test_container_with_auto_dimensions() {
  function test_div_focus_border_none (line 70) | fn test_div_focus_border_none() {
  function test_div_focus_border_color (line 86) | fn test_div_focus_border_color() {
  function test_simple_text (line 107) | fn test_simple_text() {
  function test_text_with_color (line 123) | fn test_text_with_color() {
  function test_text_with_multiple_styles (line 139) | fn test_text_with_multiple_styles() {
  function test_text_with_bright_colors (line 155) | fn test_text_with_bright_colors() {
  function test_text_with_wrap (line 171) | fn test_text_with_wrap() {
  function test_vbox_layout (line 191) | fn test_vbox_layout() {
  function test_hbox_layout (line 213) | fn test_hbox_layout() {
  function test_nested_layouts (line 234) | fn test_nested_layouts() {
  function test_spacer (line 263) | fn test_spacer() {
  function test_dynamic_text (line 285) | fn test_dynamic_text() {
  function test_conditional_color (line 302) | fn test_conditional_color() {
  function test_conditional_text (line 322) | fn test_conditional_text() {
  function test_absolute_positioning (line 346) | fn test_absolute_positioning() {
  function test_absolute_shorthand (line 364) | fn test_absolute_shorthand() {
  function test_deeply_nested_structure (line 385) | fn test_deeply_nested_structure() {
  function test_direction_shortcuts (line 425) | fn test_direction_shortcuts() {
  function test_all_color_names (line 450) | fn test_all_color_names() {
  function test_wrap_and_overflow_modes (line 473) | fn test_wrap_and_overflow_modes() {
  function test_focusable_div (line 495) | fn test_focusable_div() {
  function test_focusable_with_value (line 509) | fn test_focusable_with_value() {
  function test_empty_text (line 528) | fn test_empty_text() {
  function test_multiple_children_with_trailing_comma (line 544) | fn test_multiple_children_with_trailing_comma() {
  function test_expression_in_dimensions (line 562) | fn test_expression_in_dimensions() {
Condensed preview — 99 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,261K chars).
[
  {
    "path": ".gitignore",
    "chars": 257,
    "preview": "# Rust\ntarget/**\n**/*.rs.bk\nCargo.lock\n\n# IDE\n.idea/\n.vscode/\n*.swp\n*.swo\n*~\n\n# OS\n.DS_Store\nThumbs.db\n\n# Environment\n.e"
  },
  {
    "path": ".pre-commit-config.yaml",
    "chars": 821,
    "preview": "repos:\n  # Standard pre-commit hooks\n  - repo: https://github.com/pre-commit/pre-commit-hooks\n    rev: v4.4.0\n    hooks:"
  },
  {
    "path": "API_REFERENCE.md",
    "chars": 25013,
    "preview": "# RxTUI API Reference\n\nComplete API documentation for the RxTUI framework.\n\n## Module Structure\n\n```\nrxtui\n├── prelude  "
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1961,
    "preview": "# Contributing to RxTUI\n\nThank you for your interest in contributing to RxTUI! We welcome contributions from everyone.\n\n"
  },
  {
    "path": "Cargo.toml",
    "chars": 879,
    "preview": "[package]\nname = \"rxtui-workspace\"\nversion = \"0.1.8\"\nedition = \"2021\"\npublish = false\n\n[features]\ndefault = [\"effects\", "
  },
  {
    "path": "DEVELOPMENT.md",
    "chars": 4531,
    "preview": "# Development Guide\n\nThis guide will help you set up your development environment for working on RxTUI.\n\n## Prerequisite"
  },
  {
    "path": "DOCS.md",
    "chars": 29561,
    "preview": "# RxTUI Documentation\n\nRxTUI is a reactive terminal user interface framework for Rust that brings modern component-based"
  },
  {
    "path": "IMPLEMENTATION.md",
    "chars": 26757,
    "preview": "# RxTUI - Implementation Details\n\n## Overview\n\nRxTUI is a reactive terminal user interface framework inspired by Elm's m"
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "QUICK_REFERENCE.md",
    "chars": 14122,
    "preview": "# RxTUI Quick Reference\n\n## Component Template\n\n```rust\nuse rxtui::prelude::*;\n\n#[derive(Debug, Clone)]\nenum MyMsg {\n   "
  },
  {
    "path": "README.md",
    "chars": 4805,
    "preview": "<div align=\"center\">\n  <a href=\"./#gh-dark-mode-only\" target=\"_blank\">\n    <img width=\"500\" alt=\"rxtui-dark\" src=\"https:"
  },
  {
    "path": "TUTORIAL.md",
    "chars": 20426,
    "preview": "# RxTUI Tutorial\n\nLearn RxTUI step by step, from basics to advanced features.\n\n## Prerequisites\n\n- Basic Rust knowledge\n"
  },
  {
    "path": "examples/README.md",
    "chars": 6853,
    "preview": "# RxTUI Examples\n\nThis directory contains example applications demonstrating various features and patterns of the RxTUI "
  },
  {
    "path": "examples/align.rs",
    "chars": 7073,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/components.rs",
    "chars": 6588,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/counter.rs",
    "chars": 1585,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/demo.rs",
    "chars": 9156,
    "preview": "mod demo_pages;\n\nuse demo_pages::*;\nuse rxtui::prelude::*;\n\n//----------------------------------------------------------"
  },
  {
    "path": "examples/demo_pages/mod.rs",
    "chars": 418,
    "preview": "pub mod page10_unicode;\npub mod page11_content_sizing;\npub mod page12_focus;\npub mod page13_rich_text;\npub mod page14_te"
  },
  {
    "path": "examples/demo_pages/page10_unicode.rs",
    "chars": 7223,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/demo_pages/page11_content_sizing.rs",
    "chars": 8628,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/demo_pages/page12_focus.rs",
    "chars": 4739,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/demo_pages/page13_rich_text.rs",
    "chars": 9760,
    "preview": "//! Page 13: RichText Demo\n//!\n//! Demonstrates the RichText type for creating styled text with multiple spans\n//! and v"
  },
  {
    "path": "examples/demo_pages/page14_text_input.rs",
    "chars": 3515,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/demo_pages/page15_scrollable.rs",
    "chars": 10110,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/demo_pages/page16_text_alignment.rs",
    "chars": 7285,
    "preview": "use rxtui::prelude::*;\nuse rxtui::style::Direction;\n\n//-----------------------------------------------------------------"
  },
  {
    "path": "examples/demo_pages/page1_overflow.rs",
    "chars": 8633,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/demo_pages/page2_direction.rs",
    "chars": 4303,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/demo_pages/page3_percentages.rs",
    "chars": 4771,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/demo_pages/page4_borders.rs",
    "chars": 9319,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/demo_pages/page5_absolute.rs",
    "chars": 8019,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/demo_pages/page6_text_styles.rs",
    "chars": 2966,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/demo_pages/page7_auto_sizing.rs",
    "chars": 4980,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/demo_pages/page8_text_wrap.rs",
    "chars": 4311,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/demo_pages/page9_element_wrap.rs",
    "chars": 6774,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/form.rs",
    "chars": 5673,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/gap.rs",
    "chars": 2049,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/hover.rs",
    "chars": 4963,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/inline.rs",
    "chars": 7132,
    "preview": "//! Inline Mode Example\n//!\n//! Demonstrates rendering directly in the terminal without alternate screen.\n//! Features m"
  },
  {
    "path": "examples/progressbar.rs",
    "chars": 5119,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/rxtui.rs",
    "chars": 1952,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/scroll.rs",
    "chars": 4949,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/scroll_nested.rs",
    "chars": 8950,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/shimmer_text.rs",
    "chars": 2929,
    "preview": "use rxtui::components::{ShimmerSpeed, ShimmerText};\nuse rxtui::prelude::*;\n\n//------------------------------------------"
  },
  {
    "path": "examples/spinner.rs",
    "chars": 7724,
    "preview": "use rxtui::components::{Spinner, SpinnerType};\nuse rxtui::prelude::*;\n\n//-----------------------------------------------"
  },
  {
    "path": "examples/spinner_custom.rs",
    "chars": 4100,
    "preview": "use rxtui::components::{Spinner, SpinnerSpeed};\nuse rxtui::prelude::*;\n\n//----------------------------------------------"
  },
  {
    "path": "examples/stopwatch.rs",
    "chars": 2067,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "examples/textinput.rs",
    "chars": 7872,
    "preview": "use rxtui::prelude::*;\n\n//----------------------------------------------------------------------------------------------"
  },
  {
    "path": "plan.md",
    "chars": 19186,
    "preview": "# Inline Rendering Mode for rxtui\n\n## Problem Statement\n\nrxtui currently renders exclusively to the terminal's alternate"
  },
  {
    "path": "rxtui/Cargo.toml",
    "chars": 970,
    "preview": "[package]\nname = \"rxtui\"\nversion.workspace = true\nedition.workspace = true\nauthors.workspace = true\nlicense.workspace = "
  },
  {
    "path": "rxtui/LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "rxtui/README.md",
    "chars": 6074,
    "preview": "<div align=\"center\">\n  <a href=\"./#gh-dark-mode-only\" target=\"_blank\">\n    <img width=\"500\" alt=\"rxtui-dark\" src=\"https:"
  },
  {
    "path": "rxtui/lib/app/config.rs",
    "chars": 3568,
    "preview": "//--------------------------------------------------------------------------------------------------\n// Types\n//--------"
  },
  {
    "path": "rxtui/lib/app/context.rs",
    "chars": 19904,
    "preview": "use crate::component::{ComponentId, Message, State};\nuse std::any::TypeId;\nuse std::collections::{HashMap, HashSet, VecD"
  },
  {
    "path": "rxtui/lib/app/core.rs",
    "chars": 36124,
    "preview": "use crate::app::Context;\nuse crate::bounds::Rect;\nuse crate::buffer::{DoubleBuffer, ScreenBuffer};\nuse crate::component:"
  },
  {
    "path": "rxtui/lib/app/events.rs",
    "chars": 11956,
    "preview": "use crate::key::{Key, KeyWithModifiers};\nuse crate::render_tree::RenderNode;\nuse crate::vdom::VDom;\nuse crossterm::event"
  },
  {
    "path": "rxtui/lib/app/inline.rs",
    "chars": 6679,
    "preview": "use crossterm::{ExecutableCommand, cursor, style::Print, terminal};\nuse std::io::{self, Write};\n\n//---------------------"
  },
  {
    "path": "rxtui/lib/app/mod.rs",
    "chars": 424,
    "preview": "pub mod config;\npub mod context;\npub mod core;\npub mod events;\npub(crate) mod inline;\npub mod renderer;\n\n//-------------"
  },
  {
    "path": "rxtui/lib/app/renderer.rs",
    "chars": 74324,
    "preview": "use crate::bounds::Rect;\nuse crate::buffer::{Cell, ScreenBuffer};\nuse crate::render_tree::RenderNode;\nuse crate::render_"
  },
  {
    "path": "rxtui/lib/bounds.rs",
    "chars": 6772,
    "preview": "//! Bounds and rectangle operations for dirty region tracking.\n//!\n//! This module provides types and operations for tra"
  },
  {
    "path": "rxtui/lib/buffer.rs",
    "chars": 16768,
    "preview": "//! Double buffering and cell-level diffing for flicker-free rendering.\n//!\n//! This module implements a double-bufferin"
  },
  {
    "path": "rxtui/lib/component.rs",
    "chars": 10021,
    "preview": "use crate::app::Context;\nuse crate::effect::Effect;\nuse crate::node::Node;\nuse std::any::{Any, TypeId};\nuse std::fmt::De"
  },
  {
    "path": "rxtui/lib/components/mod.rs",
    "chars": 922,
    "preview": "//! Reusable UI components for rxtui\n//!\n//! This module provides pre-built components that can be easily composed\n//! t"
  },
  {
    "path": "rxtui/lib/components/shimmer_text.rs",
    "chars": 10222,
    "preview": "use crate::Context;\nuse crate::component::{Action, Component, Message, MessageExt};\nuse crate::effect::Effect;\nuse crate"
  },
  {
    "path": "rxtui/lib/components/spinner.rs",
    "chars": 17650,
    "preview": "use crate::Context;\nuse crate::component::{Action, Component, Message, MessageExt};\nuse crate::effect::Effect;\nuse crate"
  },
  {
    "path": "rxtui/lib/components/text_input.rs",
    "chars": 49333,
    "preview": "use crate::component::{Action, Component, Message, MessageExt};\nuse crate::key::{Key, KeyWithModifiers};\nuse crate::node"
  },
  {
    "path": "rxtui/lib/diff.rs",
    "chars": 8694,
    "preview": "//! Virtual DOM diffing algorithm for efficient UI updates.\n//!\n//! This module implements a diffing algorithm that comp"
  },
  {
    "path": "rxtui/lib/effect/mod.rs",
    "chars": 5180,
    "preview": "//! Async effects system for running background tasks in components\n//!\n//! Effects allow components to spawn async task"
  },
  {
    "path": "rxtui/lib/effect/runtime.rs",
    "chars": 3748,
    "preview": "use super::Effect;\nuse crate::component::ComponentId;\nuse std::collections::HashMap;\nuse std::sync::{Arc, RwLock};\nuse t"
  },
  {
    "path": "rxtui/lib/effect/types.rs",
    "chars": 444,
    "preview": "use std::future::Future;\nuse std::pin::Pin;\n\n//-------------------------------------------------------------------------"
  },
  {
    "path": "rxtui/lib/key.rs",
    "chars": 7391,
    "preview": "//! Key representation for keyboard input handling.\n//!\n//! This module provides a Key enum that represents both regular"
  },
  {
    "path": "rxtui/lib/lib.rs",
    "chars": 14991,
    "preview": "//! # RxTUI - Reactive Terminal User Interface Framework\n//!\n//! A modern terminal UI framework for Rust that brings Rea"
  },
  {
    "path": "rxtui/lib/macros/internal.rs",
    "chars": 10509,
    "preview": "//! Internal macros used by the node! macro\n//! These are not part of the public API\n\n/// Converts color values to the C"
  },
  {
    "path": "rxtui/lib/macros/mod.rs",
    "chars": 2064,
    "preview": "//! Macro-based DSL for building TUI components\n//!\n//! This module provides the `node!` macro for composing rxtui compo"
  },
  {
    "path": "rxtui/lib/macros/node.rs",
    "chars": 99192,
    "preview": "//! Implementation of the node! macro\n//!\n//! This file contains the main node! macro and its internal parsing/building "
  },
  {
    "path": "rxtui/lib/node/div.rs",
    "chars": 19966,
    "preview": "use crate::component::ComponentId;\nuse crate::key::{Key, KeyWithModifiers};\nuse crate::style::{\n    AlignItems, AlignSel"
  },
  {
    "path": "rxtui/lib/node/mod.rs",
    "chars": 3747,
    "preview": "use crate::component::Component;\nuse std::sync::Arc;\n\npub mod div;\npub mod rich_text;\npub mod text;\n\npub use div::{Div, "
  },
  {
    "path": "rxtui/lib/node/rich_text.rs",
    "chars": 12592,
    "preview": "use crate::style::{TextAlign, TextStyle};\nuse crate::{Color, TextWrap};\n\n//---------------------------------------------"
  },
  {
    "path": "rxtui/lib/node/text.rs",
    "chars": 2707,
    "preview": "use crate::style::{TextAlign, TextStyle};\nuse crate::{Color, TextWrap};\n\n//---------------------------------------------"
  },
  {
    "path": "rxtui/lib/prelude.rs",
    "chars": 1018,
    "preview": "//! Prelude module for convenient imports.\n//!\n//! This module re-exports commonly used types and traits for easier usag"
  },
  {
    "path": "rxtui/lib/providers.rs",
    "chars": 2885,
    "preview": "//! Provider traits for Component macro system\n//!\n//! These traits use Rust's method resolution order where inherent me"
  },
  {
    "path": "rxtui/lib/render_tree/mod.rs",
    "chars": 982,
    "preview": "//! Render tree and layout engine for terminal UI.\n//!\n//! This module transforms virtual nodes into a render tree with "
  },
  {
    "path": "rxtui/lib/render_tree/node.rs",
    "chars": 98899,
    "preview": "use crate::bounds::Rect;\nuse crate::component::ComponentId;\nuse crate::key::Key;\nuse crate::node::{DivStyles, EventCallb"
  },
  {
    "path": "rxtui/lib/render_tree/tests/layout_tests.rs",
    "chars": 13225,
    "preview": "use crate::render_tree::RenderNode;\nuse crate::style::{Border, BorderStyle, Color, Dimension, Direction, Spacing, Style}"
  },
  {
    "path": "rxtui/lib/render_tree/tests/mod.rs",
    "chars": 77,
    "preview": "mod layout_tests;\nmod rich_text_tests;\nmod sizing_tests;\nmod wrapping_tests;\n"
  },
  {
    "path": "rxtui/lib/render_tree/tests/rich_text_tests.rs",
    "chars": 11075,
    "preview": "use crate::Color;\nuse crate::node::RichText;\nuse crate::render_tree::{RenderNode, RenderNodeType};\nuse crate::style::{Di"
  },
  {
    "path": "rxtui/lib/render_tree/tests/sizing_tests.rs",
    "chars": 10514,
    "preview": "use crate::render_tree::{RenderNode, RenderNodeType};\nuse crate::style::{Border, BorderStyle, Color, Dimension, Directio"
  },
  {
    "path": "rxtui/lib/render_tree/tests/wrapping_tests.rs",
    "chars": 12827,
    "preview": "use crate::render_tree::{RenderNode, RenderNodeType};\nuse crate::style::{Dimension, Direction, Style, TextStyle, TextWra"
  },
  {
    "path": "rxtui/lib/render_tree/tree.rs",
    "chars": 26682,
    "preview": "use crate::bounds::Rect;\nuse crate::component::ComponentId;\nuse crate::render_tree::node::{RenderNode, RenderNodeType};\n"
  },
  {
    "path": "rxtui/lib/style.rs",
    "chars": 39258,
    "preview": "//! Styling system for terminal UI models.\n//!\n//! This module provides types and builders for styling terminal UI eleme"
  },
  {
    "path": "rxtui/lib/terminal.rs",
    "chars": 34346,
    "preview": "//! Optimized terminal renderer that applies cell updates efficiently.\n//!\n//! This module is responsible for translatin"
  },
  {
    "path": "rxtui/lib/tests/rich_text_tests.rs",
    "chars": 12834,
    "preview": "use crate::node::RichText;\nuse crate::render_tree::{RenderNode, RenderNodeType};\nuse crate::style::{Dimension, Style, Te"
  },
  {
    "path": "rxtui/lib/utils.rs",
    "chars": 24299,
    "preview": "//! Utility functions for terminal rendering and text manipulation.\n//!\n//! This module provides helper functions for va"
  },
  {
    "path": "rxtui/lib/vdom.rs",
    "chars": 16904,
    "preview": "//! Virtual DOM implementation for efficient UI updates.\n//!\n//! The Virtual DOM (VDom) is the core of the reactive rend"
  },
  {
    "path": "rxtui/lib/vnode.rs",
    "chars": 3257,
    "preview": "use crate::node::{Div, RichText, Text};\n\n//-----------------------------------------------------------------------------"
  },
  {
    "path": "rxtui/tests/macro_tests.rs",
    "chars": 14240,
    "preview": "//! Tests for the node! macro DSL\n\nuse rxtui::prelude::*;\n\n//-----------------------------------------------------------"
  },
  {
    "path": "rxtui-macros/Cargo.toml",
    "chars": 535,
    "preview": "[package]\nname = \"rxtui-macros\"\nversion.workspace = true\nedition.workspace = true\nauthors.workspace = true\nlicense.works"
  },
  {
    "path": "rxtui-macros/LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "rxtui-macros/README.md",
    "chars": 5380,
    "preview": "# rxtui-macros\n\n[![Crates.io](https://img.shields.io/crates/v/rxtui-macros?style=for-the-badge&logo=rust&logoColor=white"
  },
  {
    "path": "rxtui-macros/src/lib.rs",
    "chars": 26527,
    "preview": "use proc_macro::TokenStream;\nuse quote::{format_ident, quote};\nuse syn::parse::{Parse, ParseStream};\nuse syn::{\n    Deri"
  }
]

About this extraction

This page contains the full source code of the microsandbox/rxtui GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 99 files (1.1 MB), approximately 265.0k tokens, and a symbol index with 1097 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!