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