radio.rs

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