1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//! # rnk - React-like Terminal UI for Rust
//!
//! A terminal UI framework inspired by [Ink](https://github.com/vadimdemedes/ink)
//! and [Bubbletea](https://github.com/charmbracelet/bubbletea).
//!
//! ## Features
//!
//! - Declarative UI with flexbox layout
//! - Reactive state management with hooks
//! - Keyboard and mouse input handling
//! - ANSI color and style support
//! - **Inline mode** (default): Output persists in terminal history
//! - **Fullscreen mode**: Uses alternate screen buffer
//! - **Cross-thread render requests** for async/multi-threaded apps
//! - **Runtime mode switching** between inline and fullscreen
//! - **Println** for persistent messages above the UI
//!
//! ## Quick Start
//!
//! ```rust,no_run
//! use rnk::prelude::*;
//!
//! fn main() -> std::io::Result<()> {
//! render(app).run()
//! }
//!
//! fn app() -> Element {
//! Box::new()
//! .padding(1)
//! .child(Text::new("Hello, rnk!").bold().into_element())
//! .into_element()
//! }
//! ```
//!
//! ## Render Modes
//!
//! ### Inline Mode (Default)
//!
//! Output appears at the current cursor position and persists in terminal history.
//! This is the default mode, matching Ink and Bubbletea's behavior.
//!
//! ```rust,ignore
//! render(app).run()?; // Inline mode (default)
//! render(app).inline().run()?; // Explicit inline mode
//! ```
//!
//! ### Fullscreen Mode
//!
//! Uses the alternate screen buffer. Content is cleared when the app exits.
//!
//! ```rust,ignore
//! render(app).fullscreen().run()?;
//! ```
//!
//! ## Runtime Mode Switching
//!
//! Switch between modes at runtime (like Bubbletea):
//!
//! ```rust,ignore
//! let app = use_app();
//!
//! use_input(move |key| {
//! if key == Key::Char(' ') {
//! if app.is_alt_screen() {
//! app.exit_alt_screen(); // Switch to inline
//! } else {
//! app.enter_alt_screen(); // Switch to fullscreen
//! }
//! }
//! });
//! ```
//!
//! ## Println for Persistent Messages
//!
//! In inline mode, use `println()` to output messages above the UI:
//!
//! ```rust,ignore
//! use rnk::println;
//!
//! // In an input handler
//! rnk::println("Task completed!");
//! rnk::println(format!("Downloaded {} files", count));
//!
//! // Or via AppContext
//! let app = use_app();
//! app.println("Another message");
//! ```
//!
//! ## Cross-Thread Rendering
//!
//! When updating state from a background thread, use `request_render()` to
//! notify the UI to refresh:
//!
//! ```rust,ignore
//! use std::thread;
//! use std::sync::{Arc, RwLock};
//! use rnk::request_render;
//!
//! let state = Arc::new(RwLock::new(0));
//! let state_clone = Arc::clone(&state);
//!
//! thread::spawn(move || {
//! *state_clone.write().unwrap() += 1;
//! request_render(); // Notify rnk to re-render
//! });
//! ```
/// Testing utilities for verifying UI components
// Re-export prelude
// Re-export main types
pub use crate;
pub use crate;
// Re-export rendering APIs
pub use crate;