1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
use crate::{
    style_class,
    view::View,
    views::{self, container, empty, h_stack, Decorators},
};
use floem_reactive::ReadSignal;

style_class!(pub RadioButtonClass);
style_class!(pub RadioButtonDotClass);
style_class!(pub RadioButtonDotSelectedClass);
style_class!(pub LabeledRadioButtonClass);

fn radio_button_svg<T>(represented_value: T, actual_value: ReadSignal<T>) -> impl View
where
    T: Eq + PartialEq + Clone + 'static,
{
    container(empty().class(RadioButtonDotClass).style(move |s| {
        s.apply_if(actual_value.get() != represented_value, |s| {
            s.display(taffy::style::Display::None)
        })
    }))
    .class(RadioButtonClass)
}

/// Renders a radio button that appears as selected if the signal equals the given enum value.
/// Can be combined with a label and a stack with a click event (as in `examples/widget-gallery`).
pub fn radio_button<T>(represented_value: T, actual_value: ReadSignal<T>) -> impl View
where
    T: Eq + PartialEq + Clone + 'static,
{
    radio_button_svg(represented_value, actual_value).keyboard_navigatable()
}

/// Renders a radio button that appears as selected if the signal equals the given enum value.
pub fn labeled_radio_button<S: std::fmt::Display + 'static, T>(
    represented_value: T,
    actual_value: ReadSignal<T>,
    label: impl Fn() -> S + 'static,
) -> impl View
where
    T: Eq + PartialEq + Clone + 'static,
{
    h_stack((
        radio_button_svg(represented_value, actual_value),
        views::label(label),
    ))
    .class(LabeledRadioButtonClass)
    .style(|s| s.items_center())
    .keyboard_navigatable()
}