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