use rnk::prelude::*;
fn main() -> std::io::Result<()> {
render(app).run()
}
fn app() -> Element {
let app = use_app();
let selected = use_signal(|| 0usize);
let confirmed = use_signal(|| Option::<String>::None);
let items = [
("red", "Red", Color::Red),
("green", "Green", Color::Green),
("blue", "Blue", Color::Blue),
("yellow", "Yellow", Color::Yellow),
("magenta", "Magenta", Color::Magenta),
("cyan", "Cyan", Color::Cyan),
];
let items_len = items.len();
let selected_clone = selected.clone();
let confirmed_clone = confirmed.clone();
use_input(move |ch, key| {
if ch == "q" {
app.exit();
} else if key.up_arrow || ch == "k" {
selected_clone.update(|s| {
if *s == 0 {
*s = items_len - 1;
} else {
*s -= 1;
}
});
} else if key.down_arrow || ch == "j" {
selected_clone.update(|s| {
*s = (*s + 1) % items_len;
});
} else if key.return_key {
let idx = selected_clone.get();
let items = ["Red", "Green", "Blue", "Yellow", "Magenta", "Cyan"];
confirmed_clone.set(Some(items[idx].to_string()));
}
});
let current_selected = selected.get();
let current_confirmed = confirmed.get();
Box::new()
.flex_direction(FlexDirection::Column)
.padding(1)
.child(
Text::new("Select a color:")
.color(Color::White)
.bold()
.into_element(),
)
.child(Newline::new().into_element())
.children(items.iter().enumerate().map(|(idx, (_id, label, color))| {
let is_selected = idx == current_selected;
let indicator = if is_selected { "> " } else { " " };
Box::new()
.flex_direction(FlexDirection::Row)
.child(
Text::new(indicator)
.color(Color::Cyan)
.bold()
.into_element(),
)
.child(
Text::new(*label)
.color(if is_selected {
*color
} else {
Color::Ansi256(245)
})
.bold()
.into_element(),
)
.into_element()
}))
.child(Newline::new().into_element())
.child(if let Some(color) = current_confirmed {
Box::new()
.border_style(BorderStyle::Round)
.border_color(Color::Green)
.padding(1)
.child(
Text::new(format!("You selected: {}", color))
.color(Color::Green)
.bold()
.into_element(),
)
.into_element()
} else {
Box::new().into_element()
})
.child(Newline::new().into_element())
.child(
Text::new("Use j/k or arrows to navigate, Enter to select, q to quit")
.dim()
.into_element(),
)
.into_element()
}