impulse_thaw/radio/
mod.rs1mod 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 #[prop(optional, into)]
14 value: String,
15 #[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}