mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-22 22:09:22 -05:00
feat: change checkbox prop
This commit is contained in:
parent
74a5a3b7b0
commit
e98a649154
6 changed files with 70 additions and 36 deletions
|
@ -19,9 +19,11 @@ pub fn CheckboxPage() -> impl IntoView {
|
|||
<DemoCode slot html=highlight_str!(r#"
|
||||
let checked = create_rw_signal(false);
|
||||
|
||||
<Checkbox checked>
|
||||
"Click"
|
||||
</Checkbox>
|
||||
view! {
|
||||
<Checkbox checked>
|
||||
"Click"
|
||||
</Checkbox>
|
||||
}
|
||||
"#, "rust")>
|
||||
""
|
||||
</DemoCode>
|
||||
|
@ -29,9 +31,9 @@ pub fn CheckboxPage() -> impl IntoView {
|
|||
<h3>"group"</h3>
|
||||
<Demo>
|
||||
<CheckboxGroup value>
|
||||
<CheckboxItem label="apple" value="a" />
|
||||
<CheckboxItem label="b" value="b" />
|
||||
<CheckboxItem label="c" value="c" />
|
||||
<CheckboxItem label="apple" key="a" />
|
||||
<CheckboxItem label="b" key="b" />
|
||||
<CheckboxItem label="c" key="c" />
|
||||
</CheckboxGroup>
|
||||
<div style="margin-top: 1rem">
|
||||
"value: " { move || format!("{:?}", value.get()) }
|
||||
|
@ -39,11 +41,13 @@ pub fn CheckboxPage() -> impl IntoView {
|
|||
<DemoCode slot html=highlight_str!(r#"
|
||||
let value = create_rw_signal(HashSet::new());
|
||||
|
||||
<CheckboxGroup value>
|
||||
<CheckboxItem label="apple" value="a" />
|
||||
<CheckboxItem label="b" value="b" />
|
||||
<CheckboxItem label="c" value="c" />
|
||||
</CheckboxGroup>
|
||||
view! {
|
||||
<CheckboxGroup value>
|
||||
<CheckboxItem label="apple" key="a" />
|
||||
<CheckboxItem label="b" key="b" />
|
||||
<CheckboxItem label="c" key="c" />
|
||||
</CheckboxGroup>
|
||||
}
|
||||
"#, "rust")>
|
||||
""
|
||||
</DemoCode>
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use crate::utils::maybe_rw_signal::MaybeRwSignal;
|
||||
use leptos::*;
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[component]
|
||||
pub fn CheckboxGroup(
|
||||
#[prop(into)] value: RwSignal<HashSet<String>>,
|
||||
#[prop(optional, into)] value: MaybeRwSignal<HashSet<String>>,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
let injection_key = CheckboxGroupInjectionKey::new(value);
|
||||
let injection_key = CheckboxGroupInjectionKey::new(value.into());
|
||||
provide_context(injection_key);
|
||||
|
||||
children()
|
||||
|
|
|
@ -1,28 +1,36 @@
|
|||
use crate::checkbox::{checkbox_group::use_checkbox_group, Checkbox};
|
||||
use crate::{
|
||||
checkbox::{checkbox_group::use_checkbox_group, Checkbox},
|
||||
SignalWatch,
|
||||
};
|
||||
use leptos::*;
|
||||
|
||||
#[component]
|
||||
pub fn CheckboxItem(#[prop(into)] label: String, #[prop(into)] value: String) -> impl IntoView {
|
||||
pub fn CheckboxItem(
|
||||
#[prop(optional, into)] label: Option<String>,
|
||||
#[prop(into)] key: String,
|
||||
) -> impl IntoView {
|
||||
let checkbox_group = use_checkbox_group();
|
||||
let checked = checkbox_group
|
||||
.value
|
||||
.with_untracked(|checkbox_group| checkbox_group.contains(&value));
|
||||
.with_untracked(|checkbox_group| checkbox_group.contains(&key));
|
||||
let checked = create_rw_signal(checked);
|
||||
let item_value = store_value(value);
|
||||
let item_key = store_value(key);
|
||||
|
||||
_ = watch(
|
||||
move || checked.get(),
|
||||
move |checked, _prev, _| {
|
||||
checkbox_group.value.update(move |checkbox_group| {
|
||||
if *checked {
|
||||
checkbox_group.insert(item_value.get_value());
|
||||
} else {
|
||||
checkbox_group.remove(&item_value.get_value());
|
||||
}
|
||||
});
|
||||
},
|
||||
false,
|
||||
);
|
||||
_ = checked.watch(move |checked| {
|
||||
checkbox_group.value.update(move |checkbox_group| {
|
||||
if *checked {
|
||||
checkbox_group.insert(item_key.get_value());
|
||||
} else {
|
||||
checkbox_group.remove(&item_key.get_value());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let label = if let Some(label) = label {
|
||||
label
|
||||
} else {
|
||||
item_key.get_value()
|
||||
};
|
||||
|
||||
view! {
|
||||
<Checkbox checked>
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
mod checkbox_group;
|
||||
mod checkbox_item;
|
||||
|
||||
use crate::{components::*, icon::*, theme::use_theme, utils::mount_style::mount_style, Theme};
|
||||
use crate::{
|
||||
components::*,
|
||||
icon::*,
|
||||
theme::use_theme,
|
||||
utils::{maybe_rw_signal::MaybeRwSignal, mount_style::mount_style},
|
||||
Theme,
|
||||
};
|
||||
pub use checkbox_group::CheckboxGroup;
|
||||
pub use checkbox_item::CheckboxItem;
|
||||
use icondata::AiIcon;
|
||||
|
@ -9,7 +15,10 @@ use leptos::*;
|
|||
use stylers::style_sheet_str;
|
||||
|
||||
#[component]
|
||||
pub fn Checkbox(#[prop(into)] checked: RwSignal<bool>, children: Children) -> impl IntoView {
|
||||
pub fn Checkbox(
|
||||
#[prop(optional, into)] checked: MaybeRwSignal<bool>,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
let theme = use_theme(Theme::light);
|
||||
let class_name = mount_style("checkbox", || {
|
||||
style_sheet_str!("./src/checkbox/checkbox.css")
|
||||
|
@ -23,12 +32,12 @@ pub fn Checkbox(#[prop(into)] checked: RwSignal<bool>, children: Children) -> im
|
|||
css_vars
|
||||
});
|
||||
|
||||
view! { class=class_name,
|
||||
view! {class=class_name,
|
||||
<div class:melt-checkbox=true class=("melt-checkbox--checked", move || checked.get()) style=move || css_vars.get()
|
||||
on:click=move |_| checked.set(!checked.get_untracked())>
|
||||
<input class="melt-checkbox__input" type="checkbox" />
|
||||
<div class="melt-checkbox__dot">
|
||||
<If cond=checked>
|
||||
<If cond=checked.clone_into()>
|
||||
<Then slot>
|
||||
<Icon icon=Icon::from(AiIcon::AiCheckOutlined) style="color: white"/>
|
||||
</Then>
|
||||
|
|
|
@ -33,10 +33,10 @@ pub fn Tabs(active_key: RwSignal<&'static str>, children: Children) -> impl Into
|
|||
});
|
||||
let label_list_ref = create_node_ref::<html::Div>();
|
||||
|
||||
view! { class=class_name,
|
||||
view! {class=class_name,
|
||||
<div class="melt-tabs" style=move || css_vars.get()>
|
||||
<div class="melt-tabs__label-list" ref=label_list_ref>
|
||||
<For each=move || tab_options_vec.get() key=move |v| v.key.clone() children=move | options| {
|
||||
<For each=move || tab_options_vec.get() key=move |v| v.key children=move | options| {
|
||||
let label_ref = create_node_ref::<html::Span>();
|
||||
create_effect( move |_| {
|
||||
let Some(label) = label_ref.get() else {
|
||||
|
|
|
@ -3,6 +3,12 @@ use std::ops::Deref;
|
|||
|
||||
pub struct MaybeRwSignal<T: Default + 'static>(RwSignal<T>);
|
||||
|
||||
impl<T: Default> MaybeRwSignal<T> {
|
||||
pub fn clone_into(&self) -> RwSignal<T> {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> Default for MaybeRwSignal<T> {
|
||||
fn default() -> Self {
|
||||
Self(RwSignal::new(Default::default()))
|
||||
|
@ -30,3 +36,9 @@ impl<T: Default> From<RwSignal<T>> for MaybeRwSignal<T> {
|
|||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> From<MaybeRwSignal<T>> for RwSignal<T> {
|
||||
fn from(value: MaybeRwSignal<T>) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue