From 5e56d33f342cf97279084a904b2897065ff238b5 Mon Sep 17 00:00:00 2001 From: luoxiao Date: Fri, 5 Jul 2024 11:15:37 +0800 Subject: [PATCH] feat: leptos-v0.7 --- thaw/src/accordion/accordion_item.rs | 4 +- thaw/src/auto_complete/mod.rs | 2 - thaw/src/back_top/mod.rs | 2 +- thaw/src/color_picker/mod.rs | 4 +- thaw/src/combobox/combobox.rs | 4 +- thaw/src/combobox/combobox_option.rs | 4 +- thaw/src/date_picker/mod.rs | 5 +- thaw/src/date_picker/panel/mod.rs | 6 +- thaw/src/drawer/mod.rs | 2 +- thaw/src/drawer/overlay_drawer.rs | 2 +- thaw/src/layout/layout_header.rs | 2 - thaw/src/layout/layout_sider.rs | 2 - thaw/src/popover/mod.rs | 10 +++- thaw/src/progress_bar/progress_bar.rs | 2 +- thaw/src/table/mod.rs | 5 +- thaw/src/text/mod.rs | 36 ++++++------ thaw/src/textarea/mod.rs | 17 +++--- thaw/src/time_picker/mod.rs | 9 ++- thaw/src/toast/mod.rs | 5 +- thaw/src/toast/toaster.rs | 18 +++--- thaw/src/upload/mod.rs | 7 ++- thaw_components/src/binder/mod.rs | 4 +- thaw_utils/src/lib.rs | 1 + thaw_utils/src/macros.rs | 82 +++++++++++++++++++++++++++ 24 files changed, 158 insertions(+), 77 deletions(-) create mode 100644 thaw_utils/src/macros.rs diff --git a/thaw/src/accordion/accordion_item.rs b/thaw/src/accordion/accordion_item.rs index b490d2a..4698ab5 100644 --- a/thaw/src/accordion/accordion_item.rs +++ b/thaw/src/accordion/accordion_item.rs @@ -1,7 +1,7 @@ use crate::AccordionInjection; use leptos::{prelude::*, html}; use thaw_components::CSSTransition; -use thaw_utils::{mount_style, StoredMaybeSignal}; +use thaw_utils::{mount_style, update, with, StoredMaybeSignal}; #[component] pub fn AccordionItem( @@ -59,7 +59,7 @@ pub fn AccordionItem(
{children()}
diff --git a/thaw/src/auto_complete/mod.rs b/thaw/src/auto_complete/mod.rs index b8c334d..b61f663 100644 --- a/thaw/src/auto_complete/mod.rs +++ b/thaw/src/auto_complete/mod.rs @@ -33,7 +33,6 @@ pub fn AutoComplete( #[prop(optional)] auto_complete_prefix: Option, #[prop(optional)] auto_complete_suffix: Option, #[prop(optional)] comp_ref: ComponentRef, - #[prop(attrs)] attrs: Vec<(&'static str, Attribute)>, #[prop(optional)] children: Option, ) -> impl IntoView { mount_style("auto-complete", include_str!("./auto-complete.css")); @@ -145,7 +144,6 @@ pub fn AutoComplete( // on:keydown=on_keydown > - } + }.into_any() } else { view! { - } + }.into_any() } } diff --git a/thaw/src/date_picker/mod.rs b/thaw/src/date_picker/mod.rs index 56ecff5..55203c1 100644 --- a/thaw/src/date_picker/mod.rs +++ b/thaw/src/date_picker/mod.rs @@ -1,7 +1,7 @@ mod panel; use crate::{Icon, Input, InputSuffix, SignalWatch}; use chrono::NaiveDate; -use leptos::{prelude::*, html}; +use leptos::{html, prelude::*}; use panel::{Panel, PanelRef}; use thaw_components::{Binder, Follower, FollowerPlacement}; use thaw_utils::{mount_style, now_date, ComponentRef, Model, OptionalProp}; @@ -10,7 +10,6 @@ use thaw_utils::{mount_style, now_date, ComponentRef, Model, OptionalProp}; pub fn DatePicker( #[prop(optional, into)] value: Model>, #[prop(optional, into)] class: OptionalProp>, - #[prop(attrs)] attrs: Vec<(&'static str, Attribute)>, ) -> impl IntoView { mount_style("date-picker", include_str!("./date-picker.css")); let date_picker_ref = NodeRef::::new(); @@ -69,7 +68,7 @@ pub fn DatePicker( view! {
- + diff --git a/thaw/src/date_picker/panel/mod.rs b/thaw/src/date_picker/panel/mod.rs index e502c36..311571c 100644 --- a/thaw/src/date_picker/panel/mod.rs +++ b/thaw/src/date_picker/panel/mod.rs @@ -39,9 +39,9 @@ pub fn Panel( if panel_ref.get().is_none() { return; } - if current_el == ***panel_ref.get_untracked().unwrap() - || current_el == ***date_picker_ref.get_untracked().unwrap() - { + let panel_el = panel_ref.get_untracked().unwrap(); + let date_picker_el = date_picker_ref.get_untracked().unwrap(); + if current_el == **panel_el || current_el == **date_picker_el { return; } el = current_el.parent_element(); diff --git a/thaw/src/drawer/mod.rs b/thaw/src/drawer/mod.rs index e36aa03..97bea06 100644 --- a/thaw/src/drawer/mod.rs +++ b/thaw/src/drawer/mod.rs @@ -10,7 +10,7 @@ pub use drawer_header_title::*; pub use inline_drawer::*; pub use overlay_drawer::*; -use leptos::prelude::MaybeSignal; +use leptos::prelude::{MaybeSignal, With}; #[derive(Clone, Default, Copy)] pub enum DrawerPosition { diff --git a/thaw/src/drawer/overlay_drawer.rs b/thaw/src/drawer/overlay_drawer.rs index 2a52918..3ff7b60 100644 --- a/thaw/src/drawer/overlay_drawer.rs +++ b/thaw/src/drawer/overlay_drawer.rs @@ -1,6 +1,6 @@ use super::{DrawerPosition, DrawerSize}; use crate::ConfigInjection; -use leptos::prelude::*; +use leptos::{ev, html, prelude::*}; use thaw_components::{CSSTransition, FocusTrap, Teleport}; use thaw_utils::{class_list, mount_style, use_lock_html_scroll, Model}; diff --git a/thaw/src/layout/layout_header.rs b/thaw/src/layout/layout_header.rs index 29ba006..075bb3f 100644 --- a/thaw/src/layout/layout_header.rs +++ b/thaw/src/layout/layout_header.rs @@ -4,13 +4,11 @@ use thaw_utils::{class_list, OptionalProp}; #[component] pub fn LayoutHeader( #[prop(optional, into)] class: OptionalProp>, - #[prop(optional, into)] style: OptionalProp>, children: Children, ) -> impl IntoView { view! {
{children()}
diff --git a/thaw/src/layout/layout_sider.rs b/thaw/src/layout/layout_sider.rs index fd605b1..20ebbcf 100644 --- a/thaw/src/layout/layout_sider.rs +++ b/thaw/src/layout/layout_sider.rs @@ -5,7 +5,6 @@ use thaw_utils::{class_list, mount_style, OptionalProp}; #[component] pub fn LayoutSider( #[prop(optional, into)] class: OptionalProp>, - #[prop(optional, into)] style: OptionalProp>, #[prop(optional, into)] content_class: OptionalProp>, #[prop(optional, into)] content_style: OptionalProp>, children: Children, @@ -14,7 +13,6 @@ pub fn LayoutSider( view! {
{children()} diff --git a/thaw/src/popover/mod.rs b/thaw/src/popover/mod.rs index da17e1f..ff7738b 100644 --- a/thaw/src/popover/mod.rs +++ b/thaw/src/popover/mod.rs @@ -77,7 +77,7 @@ pub fn Popover( let Some(popover_el) = popover_ref.get_untracked() else { break; }; - if current_el == popover_el { + if current_el == **popover_el { return; } el = current_el.parent_element(); @@ -87,8 +87,11 @@ pub fn Popover( on_cleanup(move || handle.remove()); } - target_ref.on_load(move |target_el| { - add_event_listener(target_el.into_any(), ev::click, move |event| { + Effect::new(move |_| { + let Some(target_el) = target_ref.get() else { + return; + }; + add_event_listener(target_el.into(), ev::click, move |event| { if trigger_type != PopoverTriggerType::Click { return; } @@ -96,6 +99,7 @@ pub fn Popover( is_show_popover.update(|show| *show = !*show); }); }); + let PopoverTrigger { class: trigger_class, children: trigger_children, diff --git a/thaw/src/progress_bar/progress_bar.rs b/thaw/src/progress_bar/progress_bar.rs index d0b3afb..5e7b94b 100644 --- a/thaw/src/progress_bar/progress_bar.rs +++ b/thaw/src/progress_bar/progress_bar.rs @@ -22,7 +22,7 @@ pub fn ProgressBar( move || format!("thaw-progress-bar--{}", color.get().as_str()) ] role="progressbar" - aria-valuemax=move || max.get() + aria_valuemax=move || max.get() aria-valuemin="0" aria-valuenow=move || value.get() > diff --git a/thaw/src/table/mod.rs b/thaw/src/table/mod.rs index 5ee04b2..3afeaa2 100644 --- a/thaw/src/table/mod.rs +++ b/thaw/src/table/mod.rs @@ -11,10 +11,7 @@ pub fn Table( mount_style("table", include_str!("./table.css")); view! { - +
{children()}
} diff --git a/thaw/src/text/mod.rs b/thaw/src/text/mod.rs index 52b5d8b..9bb6ef3 100644 --- a/thaw/src/text/mod.rs +++ b/thaw/src/text/mod.rs @@ -4,7 +4,6 @@ use thaw_utils::{class_list, mount_style}; #[component] pub fn Caption1( #[prop(optional, into)] class: MaybeProp, - #[prop(optional, into)] style: MaybeProp, #[prop(optional)] tag: TextTag, children: Children, ) -> impl IntoView { @@ -12,14 +11,13 @@ pub fn Caption1( Signal::derive(move || format!("thaw-caption-1 {}", class.get().unwrap_or_default())); view! { - + } } #[component] pub fn Caption1Strong( #[prop(optional, into)] class: MaybeProp, - #[prop(optional, into)] style: MaybeProp, #[prop(optional)] tag: TextTag, children: Children, ) -> impl IntoView { @@ -28,28 +26,26 @@ pub fn Caption1Strong( }); view! { - + } } #[component] pub fn Body1( #[prop(optional, into)] class: MaybeProp, - #[prop(optional, into)] style: MaybeProp, #[prop(optional)] tag: TextTag, children: Children, ) -> impl IntoView { let class = Signal::derive(move || format!("thaw-body-1 {}", class.get().unwrap_or_default())); view! { - + } } #[component] pub fn Text( #[prop(optional, into)] class: MaybeProp, - #[prop(optional, into)] style: MaybeProp, #[prop(optional)] tag: TextTag, #[prop(optional)] code: bool, children: Children, @@ -58,79 +54,79 @@ pub fn Text( match tag { TextTag::B => view! { - + {children()} } .into_any(), TextTag::Em => view! { - + {children()} } .into_any(), TextTag::H1 => view! { -

+

{children()}

} .into_any(), TextTag::H2 => view! { -

+

{children()}

} .into_any(), TextTag::H3 => view! { -

+

{children()}

} .into_any(), TextTag::H4 => view! { -

+

{children()}

} .into_any(), TextTag::H5 => view! { -
+
{children()}
} .into_any(), TextTag::H6 => view! { -
+
{children()}
} .into_any(), TextTag::I => view! { - + {children()} } .into_any(), TextTag::P => view! { -

+

{children()}

} .into_any(), TextTag::Pre => view! { -
+            
                 {children()}
             
} .into_any(), TextTag::Span => view! { - + {children()} } .into_any(), TextTag::Strong => view! { - + {children()} } diff --git a/thaw/src/textarea/mod.rs b/thaw/src/textarea/mod.rs index 8a64703..1e3ece5 100644 --- a/thaw/src/textarea/mod.rs +++ b/thaw/src/textarea/mod.rs @@ -19,15 +19,18 @@ pub fn Textarea( mount_style("textarea", include_str!("./textarea.css")); let value_trigger = ArcTrigger::new(); - let on_input = move |ev| { - let input_value = event_target_value(&ev); - if let Some(allow_value) = allow_value.as_ref() { - if !allow_value.call(input_value.clone()) { - value_trigger.trigger(); - return; + let on_input = { + let value_trigger = value_trigger.clone(); + move |ev| { + let input_value = event_target_value(&ev); + if let Some(allow_value) = allow_value.as_ref() { + if !allow_value.call(input_value.clone()) { + value_trigger.trigger(); + return; + } } + value.set(input_value); } - value.set(input_value); }; let on_internal_focus = move |ev| { if let Some(on_focus) = on_focus.as_ref() { diff --git a/thaw/src/time_picker/mod.rs b/thaw/src/time_picker/mod.rs index 148cb49..40b4a6a 100644 --- a/thaw/src/time_picker/mod.rs +++ b/thaw/src/time_picker/mod.rs @@ -119,12 +119,11 @@ fn Panel( if current_el == *body { break; }; - if panel_ref.get().is_none() { + let Some(panel_el) = panel_ref.get() else { return; - } - if current_el == ***panel_ref.get_untracked().unwrap() - || current_el == ***time_picker_ref.get_untracked().unwrap() - { + }; + let time_picker_el = time_picker_ref.get().unwrap(); + if current_el == **panel_el || current_el == **time_picker_el { return; } el = current_el.parent_element(); diff --git a/thaw/src/toast/mod.rs b/thaw/src/toast/mod.rs index a18d2fc..2f95975 100644 --- a/thaw/src/toast/mod.rs +++ b/thaw/src/toast/mod.rs @@ -29,7 +29,10 @@ impl ToasterInjection { let trigger = ArcTrigger::new(); ( - Self { sender, trigger }, + Self { + sender, + trigger: trigger.clone(), + }, ToasterReceiver::new(receiver, trigger), ) } diff --git a/thaw/src/toast/toaster.rs b/thaw/src/toast/toaster.rs index dde151f..26dd1ad 100644 --- a/thaw/src/toast/toaster.rs +++ b/thaw/src/toast/toaster.rs @@ -21,15 +21,15 @@ pub fn Toaster( view! {
- -
- {toast.0} -
-
+ // + //
+ // {toast.0} + //
+ //
} diff --git a/thaw/src/upload/mod.rs b/thaw/src/upload/mod.rs index c70a78a..84dce3c 100644 --- a/thaw/src/upload/mod.rs +++ b/thaw/src/upload/mod.rs @@ -18,8 +18,11 @@ pub fn Upload( let input_ref = NodeRef::::new(); let trigger_ref = NodeRef::::new(); - trigger_ref.on_load(move |trigger_ref| { - let handle = add_event_listener(trigger_ref.into_any(), ev::click, move |_| { + Effect::new(move |_| { + let Some(trigger_el) = trigger_ref.get() else { + return; + }; + let handle = add_event_listener(trigger_el.into(), ev::click, move |_| { if let Some(input_ref) = input_ref.get_untracked() { input_ref.click(); } diff --git a/thaw_components/src/binder/mod.rs b/thaw_components/src/binder/mod.rs index 5b84851..7d8a5e4 100644 --- a/thaw_components/src/binder/mod.rs +++ b/thaw_components/src/binder/mod.rs @@ -71,7 +71,7 @@ pub fn Binder( ) -> impl IntoView where E: ElementType + 'static, - E::Output: JsCast + Clone + Deref + 'static, + E::Output: JsCast + Clone + Deref + 'static, { mount_style("binder", include_str!("./binder.css")); let Follower { @@ -186,7 +186,7 @@ fn FollowerContainer( ) -> impl IntoView where E: ElementType + 'static, - E::Output: JsCast + Clone + Deref + 'static, + E::Output: JsCast + Clone + Deref + 'static, { let content_ref = NodeRef::::new(); let content_style = RwSignal::new(String::new()); diff --git a/thaw_utils/src/lib.rs b/thaw_utils/src/lib.rs index fe39c01..5f1ed92 100644 --- a/thaw_utils/src/lib.rs +++ b/thaw_utils/src/lib.rs @@ -2,6 +2,7 @@ pub mod class_list; mod dom; mod event_listener; mod hooks; +pub mod macros; mod optional_prop; mod signals; mod throttle; diff --git a/thaw_utils/src/macros.rs b/thaw_utils/src/macros.rs new file mode 100644 index 0000000..53ffe6c --- /dev/null +++ b/thaw_utils/src/macros.rs @@ -0,0 +1,82 @@ +#[macro_export] +macro_rules! with { + (|$ident:ident $(,)?| $body:expr) => { + $crate::macros::__private::Withable::call_with(&$ident, |$ident| $body) + }; + (move |$ident:ident $(,)?| $body:expr) => { + $crate::macros::__private::Withable::call_with(&$ident, move |$ident| $body) + }; + (|$first:ident, $($rest:ident),+ $(,)? | $body:expr) => { + $crate::macros::__private::Withable::call_with( + &$first, + |$first| with!(|$($rest),+| $body) + ) + }; + (move |$first:ident, $($rest:ident),+ $(,)? | $body:expr) => { + $crate::macros::__private::Withable::call_with( + &$first, + move |$first| with!(|$($rest),+| $body) + ) + }; +} + +#[macro_export] +macro_rules! update { + (|$ident:ident $(,)?| $body:expr) => { + $crate::macros::__private::Updatable::call_update(&$ident, |$ident| $body) + }; + (move |$ident:ident $(,)?| $body:expr) => { + $crate::macros::__private::Updatable::call_update(&$ident, move |$ident| $body) + }; + (|$first:ident, $($rest:ident),+ $(,)? | $body:expr) => { + $crate::macros::__private::Updatable::call_update( + &$first, + |$first| update!(|$($rest),+| $body) + ) + }; + (move |$first:ident, $($rest:ident),+ $(,)? | $body:expr) => { + $crate::macros::__private::Updatable::call_update( + &$first, + move |$first| update!(|$($rest),+| $body) + ) + }; +} + +pub mod __private { + use leptos::prelude::{Update, With}; + + pub trait Withable { + type Value; + + #[track_caller] + fn call_with(item: &Self, f: impl FnOnce(&Self::Value) -> O) -> O; + } + + impl Withable for S + where + ::Value: Sized, + { + type Value = S::Value; + + #[inline(always)] + fn call_with(item: &Self, f: impl FnOnce(&Self::Value) -> O) -> O { + item.with(f) + } + } + + pub trait Updatable { + type Value; + + #[track_caller] + fn call_update(item: &Self, f: impl FnOnce(&mut Self::Value)); + } + + impl Updatable for S { + type Value = S::Value; + + #[inline(always)] + fn call_update(item: &Self, f: impl FnOnce(&mut Self::Value)) { + item.update(f) + } + } +}