Skip to main content

impulse_thaw/radio/
mod.rs

1mod radio_group;
2
3pub use radio_group::{RadioGroup, RadioGroupRule, RadioGroupRuleTrigger};
4
5use leptos::prelude::*;
6use radio_group::RadioGroupInjection;
7use thaw_utils::{class_list, mount_style, OptionModelWithValue};
8
9#[component]
10pub fn Radio(
11    #[prop(optional, into)] class: MaybeProp<String>,
12    /// The value of the radio to be used in a radio group.
13    #[prop(optional, into)]
14    value: String,
15    /// The Radio's label.
16    #[prop(optional, into)]
17    label: MaybeProp<String>,
18) -> impl IntoView {
19    mount_style("radio", include_str!("./radio.css"));
20
21    let id = uuid::Uuid::new_v4().to_string();
22    let group = RadioGroupInjection::expect_context();
23    let item_value = StoredValue::new(value);
24
25    let checked = Memo::new({
26        let group = group.clone();
27        move |_| {
28            item_value.with_value(|value| {
29                group.value.with(|group_value| match group_value {
30                    OptionModelWithValue::T(v) => v == value,
31                    OptionModelWithValue::Option(v) => v.as_ref() == Some(value),
32                })
33            })
34        }
35    });
36
37    let on_change = move |_| {
38        group.value.set(Some(item_value.get_value()));
39    };
40
41    view! {
42        <span class=class_list!["thaw-radio", class]>
43            <input
44                class="thaw-radio__input"
45                type="radio"
46                id=id.clone()
47                name=group.name
48                value=item_value.get_value()
49                prop:checked=move || checked.get()
50                on:change=on_change
51            />
52            <div aria-hidden="true" class="thaw-radio__indicator"></div>
53            {move || {
54                if let Some(label) = label.get() {
55                    view! {
56                        <label class="thaw-radio__label" for=id.clone()>
57                            {label}
58                        </label>
59                    }
60                        .into()
61                } else {
62                    None
63                }
64            }}
65        </span>
66    }
67}