Skip to main content

cranpose_ui/modifier/
selectable.rs

1use std::rc::Rc;
2
3use cranpose_foundation::SemanticsWidgetRole;
4
5use super::{Modifier, SemanticsConfiguration, inspector_metadata};
6
7impl Modifier {
8    /// Makes the component one choice among several, of which one is picked
9    /// at a time: a tab, a radio row, an entry in a segmented control.
10    ///
11    /// This is Compose's `Modifier.selectable(selected, enabled, role,
12    /// onClick)`. A screen reader reads the role, whether the choice is
13    /// picked, and offers the click; a person who cannot see the screen hears
14    /// "Receipts, tab, selected" rather than a bare word.
15    ///
16    /// `role` is what the reader announces the control **as**; a tab row
17    /// passes `Some(SemanticsWidgetRole::Tab)`, a radio list
18    /// `Some(SemanticsWidgetRole::RadioButton)`. The picked state is published
19    /// either way, as Compose's `selected` semantics.
20    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)]
52#[path = "tests/selectable_tests.rs"]
53mod tests;