diff --git a/demo_markdown/docs/checkbox/mod.md b/demo_markdown/docs/checkbox/mod.md index 0e26a48..d67d59a 100644 --- a/demo_markdown/docs/checkbox/mod.md +++ b/demo_markdown/docs/checkbox/mod.md @@ -4,7 +4,7 @@ let checked = RwSignal::new(false); view! { - "Click" + } ``` @@ -18,9 +18,9 @@ let value = RwSignal::new(HashSet::new()); view! { - - - + + +
"value: " {move || format!("{:?}", value.get())}
} diff --git a/thaw/src/checkbox/checkbox_group.rs b/thaw/src/checkbox/checkbox_group.rs index 44bed97..e701b9b 100644 --- a/thaw/src/checkbox/checkbox_group.rs +++ b/thaw/src/checkbox/checkbox_group.rs @@ -19,8 +19,10 @@ pub fn CheckboxGroup( #[derive(Clone)] pub(crate) struct CheckboxGroupInjection(pub Model>); +impl Copy for CheckboxGroupInjection {} + impl CheckboxGroupInjection { - pub fn use_() -> Self { - expect_context() + pub fn use_() -> Option { + use_context() } } diff --git a/thaw/src/checkbox/checkbox_item.rs b/thaw/src/checkbox/checkbox_item.rs deleted file mode 100644 index e5812fc..0000000 --- a/thaw/src/checkbox/checkbox_item.rs +++ /dev/null @@ -1,44 +0,0 @@ -use super::{checkbox_group::CheckboxGroupInjection, Checkbox}; -use leptos::*; -use thaw_utils::OptionalProp; - -#[component] -pub fn CheckboxItem( - #[prop(optional, into)] label: Option, - #[prop(optional, into)] class: OptionalProp>, - #[prop(into)] value: String, -) -> impl IntoView { - let group_value = CheckboxGroupInjection::use_().0; - let checked = RwSignal::new(false); - let item_value = StoredValue::new(value); - - let is_checked = Memo::new(move |_| { - group_value.with(|group_value| item_value.with_value(|value| group_value.contains(value))) - }); - - Effect::new(move |_| { - checked.track(); - - if is_checked.get_untracked() { - group_value.update(move |group_value| { - item_value.with_value(|value| { - group_value.remove(value); - }); - }); - } else if checked.get_untracked() { - group_value.update(move |group_value| { - group_value.insert(item_value.get_value()); - }); - } - }); - - if let Some(label) = label { - view! { - - {label} - - } - } else { - view! { } - } -} diff --git a/thaw/src/checkbox/mod.rs b/thaw/src/checkbox/mod.rs index acabd1e..e506cf5 100644 --- a/thaw/src/checkbox/mod.rs +++ b/thaw/src/checkbox/mod.rs @@ -1,33 +1,64 @@ mod checkbox_group; -mod checkbox_item; pub use checkbox_group::CheckboxGroup; -pub use checkbox_item::CheckboxItem; +use checkbox_group::CheckboxGroupInjection; use leptos::*; -use thaw_components::*; use thaw_utils::{class_list, mount_style, Model, OptionalProp}; #[component] pub fn Checkbox( #[prop(optional, into)] checked: Model, #[prop(optional, into)] class: OptionalProp>, - #[prop(optional)] children: Option, + #[prop(optional, into)] value: Option, + #[prop(optional, into)] label: MaybeProp, ) -> impl IntoView { mount_style("checkbox", include_str!("./checkbox.css")); let id = uuid::Uuid::new_v4().to_string(); let input_ref = NodeRef::::new(); + let group = CheckboxGroupInjection::use_(); + let item_value = StoredValue::new(value); + + let group_checked = Memo::new(move |_| { + let Some(group) = group.as_ref() else { + return None; + }; + group.0.with(|group_value| { + item_value.with_value(|value| { + let Some(value) = value else { + return None; + }; + Some(group_value.contains(value)) + }) + }) + }); let on_change = move |_| { let input = input_ref.get_untracked().unwrap(); - checked.set(input.checked()) + if group_checked.get_untracked().is_some() { + if input.checked() { + group.as_ref().unwrap().0.update(move |group_value| { + group_value.insert(item_value.get_value().unwrap()); + }); + } else { + group.as_ref().unwrap().0.update(move |group_value| { + item_value.with_value(|value| { + group_value.remove(value.as_ref().unwrap()); + }); + }); + } + } else { + checked.set(input.checked()) + } }; + let checked = move || group_checked.get().unwrap_or_else(|| checked.get()); + view! { @@ -35,13 +66,13 @@ pub fn Checkbox( class="thaw-checkbox__input" type="checkbox" id=id.clone() - checked=checked.get_untracked() + checked=checked ref=input_ref on:change=on_change /> - - - + { + move || if let Some(label) = label.get() { + view! { + + }.into() + } else { + None + } + } } } diff --git a/thaw/src/radio/mod.rs b/thaw/src/radio/mod.rs index 048af83..ef21e92 100644 --- a/thaw/src/radio/mod.rs +++ b/thaw/src/radio/mod.rs @@ -43,6 +43,7 @@ pub fn Radio( class="thaw-radio__input" type="radio" id=id.clone() + value=item_value.get_value() prop:checked=move || checked.get() on:change=on_change />