You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
let items = use_signal(|| vec![1,2,3,4,5]);// Only recomputes when items changelet sum = use_memo(move || items.get().iter().sum::<i32>(),vec![items.get().len()],);
// Execute external process (suspends TUI)Cmd::exec_cmd("vim",&["file.txt"], |result| {match result {ExecResult::Success(code) => {/* process exited */}ExecResult::Error(err) => {/* error */}}})
Type-safe Commands (Cmd)
use rnk::cmd::Cmd;#[derive(Clone)]enumMsg{Loaded(String),}// Compiler ensures all callbacks return Msglet cmd:Cmd<Msg> = Cmd::perform(|| async{Msg::Loaded("data".to_string())});
Declarative Macros
use rnk::{col, row, text, styled_text, spacer, box_element, when, list};// Vertical layoutcol!{
text!("Line 1"),
text!("Line 2"),}// Horizontal layoutrow!{
text!("Left"),
spacer!(),
text!("Right"),}// Formatted texttext!("Count: {}", count)// Styled textstyled_text!("Error!", color:Color::Red)// Conditional renderingwhen!(show_error => text!("Error occurred!"))// List from iteratorlist!(items.iter(), |item| text!("{}", item))// List with indexlist_indexed!(items.iter(), |idx, item| text!("[{}] {}", idx, item))
Theme System
use rnk::components::{Theme,ThemeBuilder, set_theme, get_theme, with_theme};// Create custom themelet theme = ThemeBuilder::new().primary(Color::Cyan).secondary(Color::Magenta).success(Color::Green).warning(Color::Yellow).error(Color::Red).build();// Set global themeset_theme(theme);// Use theme colorslet color = get_theme().semantic_color(SemanticColor::Primary);// Scoped themewith_theme(dark_theme, || {// Components here use dark_theme});
Cross-thread Rendering
use std::thread;fnmain() -> std::io::Result<()>{
thread::spawn(|| {loop{// Update state...// Notify rnk to re-render
rnk::request_render();// Print persistent message
rnk::println("Background task completed");
thread::sleep(Duration::from_secs(1));}});render(app).run()}
Testing
use rnk::testing::{TestRenderer, assert_layout_valid};#[test]fntest_component(){let element = my_component();// Validate layoutlet renderer = TestRenderer::new(80,24);
renderer.validate_layout(&element).expect("valid layout");// Check rendered outputlet output = rnk::render_to_string(&element,80);assert!(output.contains("expected text"));}
Running Examples
# Basic examples
cargo run --example hello
cargo run --example counter
cargo run --example todo_app
# Showcase applications
cargo run --example rnk_top # htop-like system monitor
cargo run --example rnk_git # lazygit-style Git UI
cargo run --example rnk_chat # Terminal chat client# Component demos
cargo run --example tree_demo
cargo run --example multi_select_demo
cargo run --example notification_demo
cargo run --example textarea_demo
cargo run --example file_picker_demo
cargo run --example theme_demo
# Advanced examples
cargo run --example typed_cmd_demo
cargo run --example macros_demo
cargo run --example streaming_demo
cargo run --example glm_chat
# Note: use `--example` (not `cargo run example <name>`)