scroll_list/
scroll_list.rs1use aetna_core::prelude::*;
11use aetna_core::{UiState, layout};
14
15fn scroll_list_fixture() -> El {
16 let rows: Vec<El> = (0..20)
17 .map(|i| {
18 row([
19 badge(format!("#{i}")).info(),
20 text(format!("Notification {i}")).bold(),
21 spacer(),
22 text(format!("{}m ago", i + 1)).muted(),
23 ])
24 .gap(tokens::SPACE_2)
25 .height(Size::Fixed(44.0))
26 .padding(Sides::xy(tokens::SPACE_3, tokens::SPACE_2))
27 })
28 .collect();
29
30 let list = scroll(rows)
31 .key("notifications")
32 .height(Size::Fixed(420.0))
33 .padding(tokens::SPACE_2);
34
35 column([
36 h2("Notifications"),
37 text("Roll the wheel inside the panel to scroll. The content is taller than the viewport.")
38 .muted(),
39 list,
40 ])
41 .gap(tokens::SPACE_4)
42 .padding(tokens::SPACE_7)
43}
44
45fn main() -> std::io::Result<()> {
46 let mut root = scroll_list_fixture();
52 layout::assign_ids(&mut root);
53 let scroll_id = find_id(&root, "notifications").expect("scroll node id");
54 let mut ui_state = UiState::new();
55 ui_state.set_scroll_offset(scroll_id, 220.0);
56
57 let viewport = Rect::new(0.0, 0.0, 720.0, 600.0);
58 let bundle = render_bundle_with(&mut root, &mut ui_state, viewport);
59
60 let out_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("out");
61 let written = write_bundle(&bundle, &out_dir, "scroll_list")?;
62 for p in &written {
63 println!("wrote {}", p.display());
64 }
65
66 if !bundle.lint.findings.is_empty() {
67 eprintln!("\nlint findings ({}):", bundle.lint.findings.len());
68 eprint!("{}", bundle.lint.text());
69 }
70
71 Ok(())
72}
73
74fn find_id(node: &El, key: &str) -> Option<String> {
77 if node.key.as_deref() == Some(key) {
78 return Some(node.computed_id.clone());
79 }
80 node.children.iter().find_map(|c| find_id(c, key))
81}