feat: change checkbox prop

This commit is contained in:
luoxiao 2023-10-07 15:43:39 +08:00
parent 74a5a3b7b0
commit e98a649154
6 changed files with 70 additions and 36 deletions

View file

@ -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>

View file

@ -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()

View file

@ -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>

View file

@ -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>

View file

@ -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 {

View file

@ -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
}
}