radio.rs

 1use std::sync::Arc;
 2
 3use crate::prelude::*;
 4
 5/// A [`Checkbox`] that has a [`Label`].
 6#[derive(IntoElement)]
 7pub struct RadioWithLabel {
 8    id: ElementId,
 9    label: Label,
10    selected: bool,
11    on_click: Arc<dyn Fn(&bool, &mut WindowContext) + 'static>,
12}
13
14impl RadioWithLabel {
15    pub fn new(
16        id: impl Into<ElementId>,
17        label: Label,
18        selected: bool,
19        on_click: impl Fn(&bool, &mut WindowContext) + 'static,
20    ) -> Self {
21        Self {
22            id: id.into(),
23            label,
24            selected,
25            on_click: Arc::new(on_click),
26        }
27    }
28}
29
30impl RenderOnce for RadioWithLabel {
31    fn render(self, cx: &mut WindowContext) -> impl IntoElement {
32        let inner_diameter = rems_from_px(6.);
33        let outer_diameter = rems_from_px(16.);
34        let border_width = rems_from_px(1.);
35        h_flex()
36            .id(self.id)
37            .gap(Spacing::Large.rems(cx))
38            .group("")
39            .child(
40                div()
41                    .size(outer_diameter)
42                    .rounded(outer_diameter / 2.)
43                    .border_color(cx.theme().colors().border)
44                    .border(border_width)
45                    .group_hover("", |el| el.bg(cx.theme().colors().element_hover))
46                    .when(self.selected, |el| {
47                        el.child(
48                            div()
49                                .m((outer_diameter - inner_diameter) / 2. - border_width)
50                                .size(inner_diameter)
51                                .rounded(inner_diameter / 2.)
52                                .bg(cx.theme().colors().icon_accent),
53                        )
54                    }),
55            )
56            .child(self.label)
57            .on_click(move |_event, cx| {
58                (self.on_click)(&true, cx);
59            })
60    }
61}