cranpose_ui/modifier/
selectable.rs1use std::rc::Rc;
2
3use cranpose_foundation::SemanticsWidgetRole;
4
5use super::{Modifier, SemanticsConfiguration, inspector_metadata};
6
7impl Modifier {
8 pub fn selectable(
21 self,
22 selected: bool,
23 role: Option<SemanticsWidgetRole>,
24 on_click: impl Fn() + 'static,
25 ) -> Self {
26 let on_click = Rc::new(on_click);
27 let modifier = Modifier::empty()
28 .clickable(move |_point| on_click())
29 .with_inspector_metadata(inspector_metadata("selectable", move |info| {
30 info.add_property("selected", if selected { "true" } else { "false" });
31 info.add_property("onClick", "provided");
32 }))
33 .then(Modifier::empty().semantics(selectable_semantics(selected, role)));
34 self.then(modifier)
35 }
36}
37
38fn selectable_semantics(
39 selected: bool,
40 role: Option<SemanticsWidgetRole>,
41) -> impl Fn(&mut SemanticsConfiguration) {
42 move |config| {
43 config.is_clickable = true;
44 config.selected = Some(selected);
45 if let Some(role) = role {
46 config.role = Some(role);
47 }
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54
55 #[test]
56 fn a_picked_tab_says_so_and_takes_a_click() {
57 let mut config = SemanticsConfiguration::default();
58
59 selectable_semantics(true, Some(SemanticsWidgetRole::Tab))(&mut config);
60
61 assert_eq!(config.selected, Some(true));
62 assert_eq!(config.role, Some(SemanticsWidgetRole::Tab));
63 assert!(config.is_clickable);
64 }
65
66 #[test]
67 fn a_choice_with_no_role_still_says_whether_it_is_picked() {
68 let mut config = SemanticsConfiguration::default();
69
70 selectable_semantics(false, None)(&mut config);
71
72 assert_eq!(config.selected, Some(false));
73 assert_eq!(config.role, None);
74 }
75}