mirror of
https://github.com/adoyle0/thaw.git
synced 2025-02-08 19:03:09 -05:00
feat: Adds RadioGroup component (#117)
* feat: Adds RadioGroup component * fix: RadioItem select
This commit is contained in:
parent
4779eb2d24
commit
4690b8d95d
4 changed files with 107 additions and 3 deletions
|
@ -8,10 +8,45 @@ view! {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Group
|
||||||
|
|
||||||
|
```rust demo
|
||||||
|
let value = create_rw_signal(None);
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<RadioGroup value>
|
||||||
|
<RadioItem key="a">
|
||||||
|
"Apple"
|
||||||
|
</RadioItem>
|
||||||
|
<RadioItem key="o">
|
||||||
|
"Orange"
|
||||||
|
</RadioItem>
|
||||||
|
</RadioGroup>
|
||||||
|
<div style="margin-top: 1rem">
|
||||||
|
"value: " {move || format!("{:?}", value.get())}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Radio Props
|
### Radio Props
|
||||||
|
|
||||||
| Name | Type | Default | Description |
|
| Name | Type | Default | Description |
|
||||||
| -------- | ----------------------------------- | -------------------- | ---------------------------------------- |
|
| -------- | ----------------------------------- | -------------------- | ---------------------------------------- |
|
||||||
| class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Addtional classes for the radio element. |
|
| class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Addtional classes for the radio element. |
|
||||||
| value | `Model<bool>` | `false` | Checked value. |
|
| value | `Model<bool>` | `false` | Checked value. |
|
||||||
| children | `Children` | | Radio's content. |
|
| children | `Option<Children>` | `None` | Radio's content. |
|
||||||
|
|
||||||
|
### RadioGroup Props
|
||||||
|
|
||||||
|
| Name | Type | Default | Description |
|
||||||
|
| -------- | ----------------------- | -------------------- | ---------------------------------- |
|
||||||
|
| value | `Model<Option<String>>` | `Default::default()` | Sets the value of the radio group. |
|
||||||
|
| children | `Children` | | RadioGroup's content. |
|
||||||
|
|
||||||
|
### RadioItem Props
|
||||||
|
|
||||||
|
| Name | Type | Default | Description |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Addtional classes for the radio element. |
|
||||||
|
| key | `String` | | The key of the radio to be used in a radio group. |
|
||||||
|
| children | `Option<Children>` | `None` | Radio's content. |
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
mod radio_group;
|
||||||
|
mod radio_item;
|
||||||
|
|
||||||
|
pub use radio_group::RadioGroup;
|
||||||
|
pub use radio_item::RadioItem;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
theme::use_theme,
|
theme::use_theme,
|
||||||
utils::{class_list::class_list, mount_style, Model, OptionalProp},
|
utils::{class_list::class_list, mount_style, Model, OptionalProp},
|
||||||
|
@ -9,7 +15,7 @@ use leptos::*;
|
||||||
pub fn Radio(
|
pub fn Radio(
|
||||||
#[prop(optional, into)] value: Model<bool>,
|
#[prop(optional, into)] value: Model<bool>,
|
||||||
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
|
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
|
||||||
children: Children,
|
#[prop(optional)] children: Option<Children>,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
let theme = use_theme(Theme::light);
|
let theme = use_theme(Theme::light);
|
||||||
mount_style("radio", include_str!("./radio.css"));
|
mount_style("radio", include_str!("./radio.css"));
|
||||||
|
@ -36,7 +42,9 @@ pub fn Radio(
|
||||||
>
|
>
|
||||||
<input class="thaw-radio__input" type="radio" prop:value=move || value.get()/>
|
<input class="thaw-radio__input" type="radio" prop:value=move || value.get()/>
|
||||||
<div class="thaw-radio__dot"></div>
|
<div class="thaw-radio__dot"></div>
|
||||||
<div class="thaw-radio__label">{children()}</div>
|
<div class="thaw-radio__label">
|
||||||
|
{children.map(|children| children())}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
17
thaw/src/radio/radio_group.rs
Normal file
17
thaw/src/radio/radio_group.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
use crate::utils::Model;
|
||||||
|
use leptos::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn RadioGroup(
|
||||||
|
#[prop(optional, into)] value: Model<Option<String>>,
|
||||||
|
children: Children,
|
||||||
|
) -> impl IntoView {
|
||||||
|
view! { <Provider value=RadioGroupInjection(value) children/> }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub(crate) struct RadioGroupInjection(pub Model<Option<String>>);
|
||||||
|
|
||||||
|
pub(crate) fn use_radio_group() -> RadioGroupInjection {
|
||||||
|
expect_context()
|
||||||
|
}
|
44
thaw/src/radio/radio_item.rs
Normal file
44
thaw/src/radio/radio_item.rs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
use crate::{
|
||||||
|
radio::{radio_group::use_radio_group, Radio},
|
||||||
|
utils::OptionalProp,
|
||||||
|
};
|
||||||
|
use leptos::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn RadioItem(
|
||||||
|
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
|
||||||
|
#[prop(into)] key: String,
|
||||||
|
#[prop(optional)] children: Option<Children>,
|
||||||
|
) -> impl IntoView {
|
||||||
|
let radio_group_value = use_radio_group().0;
|
||||||
|
let checked = RwSignal::new(false);
|
||||||
|
let item_key = store_value(key);
|
||||||
|
|
||||||
|
let is_checked = Memo::new(move |_| {
|
||||||
|
radio_group_value.with(|value| item_key.with_value(|key| value.as_ref() == Some(key)))
|
||||||
|
});
|
||||||
|
|
||||||
|
Effect::new(move |prev| {
|
||||||
|
let checked = checked.get();
|
||||||
|
if prev.is_some() {
|
||||||
|
if !is_checked.get_untracked() {
|
||||||
|
radio_group_value.set(Some(item_key.get_value()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checked
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(children) = children {
|
||||||
|
view! {
|
||||||
|
<Radio class value=(is_checked, checked.write_only())>
|
||||||
|
{children()}
|
||||||
|
</Radio>
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
view! {
|
||||||
|
<Radio class value=(is_checked, checked.write_only())>
|
||||||
|
</Radio>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue