From 0140394db7cc9e042fe923bc0aa9bd25aaa0f3c4 Mon Sep 17 00:00:00 2001 From: luoxiao Date: Sun, 19 Nov 2023 14:06:23 +0800 Subject: [PATCH] fix: provide context --- demo/src/app.rs | 158 ++++++++++++------------ demo/src/pages/theme/mod.rs | 69 ++++++----- src/auto_complete/mod.rs | 12 +- src/breadcrumb/mod.rs | 15 ++- src/checkbox/checkbox_group.rs | 5 +- src/components/binder/mod.rs | 4 +- src/components/wave/mod.rs | 1 + src/grid/mod.rs | 12 +- src/input/mod.rs | 7 +- src/loading_bar/loading_bar_provider.rs | 17 ++- src/menu/mod.rs | 8 +- src/message/message_provider.rs | 39 +++--- src/mobile/tabbar/mod.rs | 16 ++- src/progress/mod.rs | 28 +++-- src/select/mod.rs | 20 +-- src/tabs/mod.rs | 123 +++++++++--------- src/theme/mod.rs | 5 +- src/utils/mod.rs | 2 + src/utils/provider.rs | 13 ++ 19 files changed, 311 insertions(+), 243 deletions(-) create mode 100644 src/utils/provider.rs diff --git a/demo/src/app.rs b/demo/src/app.rs index e067884..e1ba969 100644 --- a/demo/src/app.rs +++ b/demo/src/app.rs @@ -6,6 +6,85 @@ use thaw::*; #[component] pub fn App() -> impl IntoView { + let is_routing = create_rw_signal(false); + let set_is_routing = SignalSetter::map(move |is_routing_data| { + is_routing.set(is_routing_data); + }); + provide_meta_context(); + + view! { + + + + + + } +} + +#[component] +fn TheRouter(is_routing: RwSignal) -> impl IntoView { + let loading_bar = use_loading_bar(); + _ = is_routing.watch(move |is_routing| { + if *is_routing { + loading_bar.start(); + } else { + loading_bar.finish(); + } + }); + + view! { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } +} + +#[component] +fn TheProvider(children: Children) -> impl IntoView { fn use_query_value(key: &str) -> Option { let href = window().location().href().ok()?; let url = Url::try_from(href.as_str()).ok()?; @@ -22,86 +101,11 @@ pub fn App() -> impl IntoView { }); let theme = create_rw_signal(theme); - provide_meta_context(); - view! { - - - - } -} - -#[component] -fn TheRouter() -> impl IntoView { - let loading_bar = use_loading_bar(); - let set_is_routing = SignalSetter::map(move |is_routing| { - if is_routing { - loading_bar.start(); - } else { - loading_bar.finish(); - } - }); - view! { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } -} - -#[component] -fn Provider(theme: RwSignal, children: Children) -> impl IntoView { view! { - + - - {children()} - + {children()} } diff --git a/demo/src/pages/theme/mod.rs b/demo/src/pages/theme/mod.rs index ae2aa1c..dd21ec6 100644 --- a/demo/src/pages/theme/mod.rs +++ b/demo/src/pages/theme/mod.rs @@ -5,6 +5,7 @@ use thaw::*; #[component] pub fn ThemePage() -> impl IntoView { + let theme = create_rw_signal(Theme::light()); let customize_theme = create_rw_signal(Theme::light()); let on_customize_theme = move |_| { customize_theme.update(|theme| { @@ -16,7 +17,40 @@ pub fn ThemePage() -> impl IntoView { view! {

"Theme"

- +

"ThemeProvider"

+ + + + + + + + + + + + + + + + + + } + "#, + "rust" + ) + > + + "" + +

"GlobalStyle"

"You can use GlobalStyle to sync common global style to the body element."

@@ -106,36 +140,3 @@ pub fn ThemePage() -> impl IntoView {
} } - -#[component] -fn ThemeProviderPage() -> impl IntoView { - view! { -

"ThemeProvider"

- - "" - - - - - - - - - } - "#, - "rust" - ) - > - - "" - - - } -} diff --git a/src/auto_complete/mod.rs b/src/auto_complete/mod.rs index fb84c11..8179b7a 100644 --- a/src/auto_complete/mod.rs +++ b/src/auto_complete/mod.rs @@ -61,11 +61,13 @@ pub fn AutoComplete( allow_value /> - -
+ +
{move || { options diff --git a/src/breadcrumb/mod.rs b/src/breadcrumb/mod.rs index 9a4c3d2..6950495 100644 --- a/src/breadcrumb/mod.rs +++ b/src/breadcrumb/mod.rs @@ -1,7 +1,11 @@ mod breadcrumb_item; mod theme; -use crate::{use_theme, utils::mount_style, Theme}; +use crate::{ + use_theme, + utils::{mount_style, Provider}, + Theme, +}; pub use breadcrumb_item::BreadcrumbItem; use leptos::*; pub use theme::BreadcrumbTheme; @@ -31,11 +35,12 @@ pub fn Breadcrumb( }); css_vars }); - provide_context(BreadcrumbSeparatorInjection(separator)); view! { - + + + } } diff --git a/src/checkbox/checkbox_group.rs b/src/checkbox/checkbox_group.rs index adefcb8..90a0ed5 100644 --- a/src/checkbox/checkbox_group.rs +++ b/src/checkbox/checkbox_group.rs @@ -1,3 +1,4 @@ +use crate::utils::Provider; use leptos::*; use std::collections::HashSet; @@ -6,9 +7,7 @@ pub fn CheckboxGroup( #[prop(optional, into)] value: RwSignal>, children: Children, ) -> impl IntoView { - provide_context(CheckboxGroupInjection(value)); - - children() + view! { } } #[derive(Clone)] diff --git a/src/components/binder/mod.rs b/src/components/binder/mod.rs index 134bb52..36b7359 100644 --- a/src/components/binder/mod.rs +++ b/src/components/binder/mod.rs @@ -204,9 +204,7 @@ fn FollowerContainer( .attr("style", move || content_style.get()) .child(children()), ); - view! { - - } + view! { } } fn get_scroll_parent(element: Option>) -> Option> { diff --git a/src/components/wave/mod.rs b/src/components/wave/mod.rs index 2922ec9..0772b3b 100644 --- a/src/components/wave/mod.rs +++ b/src/components/wave/mod.rs @@ -50,6 +50,7 @@ pub fn Wave(#[prop(optional)] comp_ref: ComponentRef) -> impl IntoView "thaw-wave--active", move || animation_timeout_handle.with(|handle| handle.is_some()), ) + ref=wave_ref >
} diff --git a/src/grid/mod.rs b/src/grid/mod.rs index b058427..db7c331 100644 --- a/src/grid/mod.rs +++ b/src/grid/mod.rs @@ -1,5 +1,6 @@ mod grid_item; +use crate::utils::Provider; pub use grid_item::*; use leptos::*; @@ -10,9 +11,6 @@ pub fn Grid( #[prop(optional, into)] y_gap: MaybeSignal, children: Children, ) -> impl IntoView { - let grid_injection_key = GridInjection::new(x_gap); - provide_context(grid_injection_key); - let style = create_memo(move |_| { let mut style = String::from("display: grid;"); style.push_str(&format!( @@ -24,9 +22,11 @@ pub fn Grid( }); view! { -
- {children()} -
+ +
+ {children()} +
+
} } diff --git a/src/input/mod.rs b/src/input/mod.rs index d91396e..119676e 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -97,12 +97,17 @@ pub fn Input( css_vars }); view! { -
+
{if let Some(prefix) = input_prefix { view! {
{(prefix.children)()}
}.into() } else { None }} + impl IntoView { let loading_bar_ref = ComponentRef::::default(); - provide_context(LoadingBarInjection { loading_bar_ref }); view! { - {children()} - - - + + {children()} + + + } } diff --git a/src/menu/mod.rs b/src/menu/mod.rs index 8a9af71..2208d08 100644 --- a/src/menu/mod.rs +++ b/src/menu/mod.rs @@ -2,6 +2,7 @@ mod menu_group; mod menu_item; mod theme; +use crate::utils::Provider; use leptos::*; pub use menu_group::MenuGroup; pub use menu_item::*; @@ -9,8 +10,11 @@ pub use theme::MenuTheme; #[component] pub fn Menu(#[prop(optional, into)] value: RwSignal, children: Children) -> impl IntoView { - provide_context(MenuInjection(value)); - view! {
{children()}
} + view! { + +
{children()}
+
+ } } #[derive(Clone)] diff --git a/src/message/message_provider.rs b/src/message/message_provider.rs index 1367f4b..4639dc8 100644 --- a/src/message/message_provider.rs +++ b/src/message/message_provider.rs @@ -1,7 +1,10 @@ use std::time::Duration; use super::{message_environment::MessageEnvironment, MessageVariant}; -use crate::{components::Teleport, utils::mount_style}; +use crate::{ + components::Teleport, + utils::{mount_style, Provider}, +}; use leptos::*; use uuid::Uuid; @@ -10,7 +13,6 @@ pub fn MessageProvider(children: Children) -> impl IntoView { mount_style("message", include_str!("./message.css")); let message_list = create_rw_signal::>(vec![]); - provide_context(MessageInjection::new(message_list)); let handle_after_leave = move |id| { message_list.update(move |message_list| { @@ -22,21 +24,28 @@ pub fn MessageProvider(children: Children) -> impl IntoView { }; view! { - {children()} - -
- + + {children()} + +
+ + } } - } - /> + /> -
-
+
+
+ } } diff --git a/src/mobile/tabbar/mod.rs b/src/mobile/tabbar/mod.rs index a5c84be..dadb135 100644 --- a/src/mobile/tabbar/mod.rs +++ b/src/mobile/tabbar/mod.rs @@ -1,7 +1,11 @@ mod tabbar_item; mod theme; -use crate::{use_theme, utils::mount_style, Theme}; +use crate::{ + use_theme, + utils::{mount_style, Provider}, + Theme, +}; use leptos::*; pub use tabbar_item::*; pub use theme::TabbarTheme; @@ -21,11 +25,13 @@ pub fn Tabbar( ) }) }); - provide_context(TabbarInjection(value)); + view! { -
- {children()} -
+ +
+ {children()} +
+
} } diff --git a/src/progress/mod.rs b/src/progress/mod.rs index 8095637..d815b65 100644 --- a/src/progress/mod.rs +++ b/src/progress/mod.rs @@ -89,27 +89,29 @@ pub fn Progress( }; view! { -
+
- +
- { - move || { - format!("{}%", percentage.get()) - } - } + + {move || { format!("{}%", percentage.get()) }} +
- +
- { - move || { - format!("{}%", percentage.get()) - } - } + + {move || { format!("{}%", percentage.get()) }} +
diff --git a/src/select/mod.rs b/src/select/mod.rs index e765999..240bff7 100644 --- a/src/select/mod.rs +++ b/src/select/mod.rs @@ -104,17 +104,23 @@ where }); view! { -
+
{move || select_option_label.get()}
- -
+ +
, children: Children) -> impl IntoView { mount_style("tabs", include_str!("./tabs.css")); let tab_options_vec = create_rw_signal(vec![]); - provide_context(TabsInjection { - active_key: value, - tab_options_vec, - }); let theme = use_theme(Theme::light); let css_vars = create_memo(move |_| { let mut css_vars = String::new(); @@ -36,66 +36,71 @@ pub fn Tabs(#[prop(optional, into)] value: RwSignal, children: Children) let label_list_ref = create_node_ref::(); view! { -
-
- (); - let TabOption { key, label } = option; - create_effect({ - let key = key.clone(); - move |_| { - let Some(label) = label_ref.get() else { - return; - }; - let Some(label_list) = label_list_ref.get() else { - return; - }; - if key.clone() == value.get() { - request_animation_frame(move || { - let list_rect = label_list.get_bounding_client_rect(); - let rect = label.get_bounding_client_rect(); - label_line - .set( - Some(TabsLabelLine { - width: rect.width(), - left: rect.left() - list_rect.left(), - }), - ); - }); + +
+
+ (); + let TabOption { key, label } = option; + create_effect({ + let key = key.clone(); + move |_| { + let Some(label) = label_ref.get() else { + return; + }; + let Some(label_list) = label_list_ref.get() else { + return; + }; + if key.clone() == value.get() { + request_animation_frame(move || { + let list_rect = label_list.get_bounding_client_rect(); + let rect = label.get_bounding_client_rect(); + label_line + .set( + Some(TabsLabelLine { + width: rect.width(), + left: rect.left() - list_rect.left(), + }), + ); + }); + } } - } - }); - view! { - - {label} - + ref=label_ref + > + {label} + + } } - } - /> + /> - + +
+
{children()}
-
{children()}
-
+ } } diff --git a/src/theme/mod.rs b/src/theme/mod.rs index 5fdf504..e2f8d75 100644 --- a/src/theme/mod.rs +++ b/src/theme/mod.rs @@ -3,6 +3,7 @@ mod common; use self::common::CommonTheme; use crate::{ mobile::{NavBarTheme, TabbarTheme}, + utils::Provider, AlertTheme, AutoCompleteTheme, AvatarTheme, BreadcrumbTheme, ButtonTheme, ColorPickerTheme, InputTheme, MenuTheme, MessageTheme, ProgressTheme, SelectTheme, SkeletionTheme, SliderTheme, SwitchTheme, TableTheme, TagTheme, UploadTheme, @@ -111,8 +112,8 @@ pub fn ThemeProvider( } else { create_rw_signal(Theme::light()) }; - provide_context(theme); - children() + + view! { } } pub fn use_theme(default: impl Fn() -> Theme) -> ReadSignal { diff --git a/src/utils/mod.rs b/src/utils/mod.rs index d304890..83bf0e2 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -2,6 +2,7 @@ mod component_ref; mod event_listener; mod mount_style; +mod provider; mod signal; mod stored_maybe_signal; @@ -9,5 +10,6 @@ mod stored_maybe_signal; pub(crate) use component_ref::ComponentRef; pub(crate) use event_listener::*; pub(crate) use mount_style::mount_style; +pub(crate) use provider::Provider; pub use signal::SignalWatch; pub(crate) use stored_maybe_signal::*; diff --git a/src/utils/provider.rs b/src/utils/provider.rs new file mode 100644 index 0000000..cf8840f --- /dev/null +++ b/src/utils/provider.rs @@ -0,0 +1,13 @@ +/// https://github.com/leptos-rs/leptos/issues/2038 +use leptos::*; + +#[component] +pub fn Provider(value: T, children: Children) -> impl IntoView +where + T: Clone + 'static, +{ + run_as_child(move || { + provide_context(value); + children() + }) +}