1use std::io::{self, BufRead as _, Write as _};
6
7use tern_sdk::{
8 Answer, AskOptions, Font,
9 ui::{
10 self, Actions, Bound, Extent, View,
11 html::{self, El},
12 },
13};
14
15const SIZES: [(&str, &str); 3] = [("s", "Small"), ("m", "Medium"), ("l", "Large")];
17
18fn choice(value: &str, label: &str) -> El<()> {
20 html::label()
21 .key(value)
22 .child(html::radio("size", value).key("r"))
23 .child(html::span(label).key("t"))
24}
25
26fn view() -> View<()> {
29 let sizes = SIZES.iter().map(|(value, label)| choice(value, label));
30 View::new().main([html::form().key("ask").child(
31 ui::card()
32 .key("card")
33 .head("Which size?")
34 .max(Bound::w(Extent::Ch(48.0)))
35 .child(ui::row().key("sizes").gap("lg").children(sizes))
36 .child(
37 ui::button("Create")
38 .key("go")
39 .variant("primary")
40 .actions(Actions::new().click("submit")),
41 ),
42 )])
43}
44
45fn label(value: &str) -> &str {
47 SIZES
48 .iter()
49 .find(|(v, _)| *v == value)
50 .map_or(value, |(_, l)| l)
51}
52
53fn ask_plainly() -> io::Result<()> {
55 print!("Which size? [s/m/l] ");
56 io::stdout().flush()?;
57 let mut line = String::new();
58 if io::stdin().lock().read_line(&mut line)? == 0 {
59 println!("\nNo size picked.");
60 return Ok(());
61 }
62 match line.trim() {
63 v @ ("s" | "m" | "l") => println!("Size: {} ({v})", label(v)),
64 _ => println!("No size picked."),
65 }
66 Ok(())
67}
68
69fn main() -> Result<(), tern_sdk::Error> {
70 let answer = tern_sdk::ask(view(), AskOptions::new().font(Font::Sans))?;
71 match answer {
72 Answer::Submitted(submission) => {
73 let size = submission.values.get("size").and_then(|v| v.as_str());
74 match size {
75 Some(v) => println!("Size: {} ({v})", label(v)),
76 None => println!("No size picked."),
77 }
78 },
79 Answer::Cancelled => println!("Cancelled."),
80 Answer::Unsupported => ask_plainly()?,
81 }
82 Ok(())
83}