From 4c16a51d14e3d98bb1635b08dfc3860bd5360ba2 Mon Sep 17 00:00:00 2001 From: luoxiao Date: Thu, 9 Nov 2023 14:43:30 +0800 Subject: [PATCH 1/2] feat: upgrade leptos and remove MaybeRwSignal --- Cargo.toml | 4 +- demo/Cargo.toml | 4 +- src/auto_complete/mod.rs | 10 +---- src/checkbox/checkbox_group.rs | 3 +- src/checkbox/mod.rs | 12 ++--- src/color_picker/mod.rs | 6 +-- src/input/mod.rs | 4 +- src/input_number/mod.rs | 6 +-- src/loading_bar/mod.rs | 6 +-- src/menu/mod.rs | 6 +-- src/mobile/tabbar/mod.rs | 8 +--- src/radio/mod.rs | 11 +---- src/select/mod.rs | 9 +--- src/slider/mod.rs | 8 +--- src/switch/mod.rs | 4 +- src/tabs/mod.rs | 14 ++---- src/utils/maybe_rw_signal.rs | 44 ------------------- src/utils/mod.rs | 5 +-- ...signal_store.rs => stored_maybe_signal.rs} | 0 src/wave/mod.rs | 6 +++ 20 files changed, 41 insertions(+), 129 deletions(-) delete mode 100644 src/utils/maybe_rw_signal.rs rename src/utils/{maybe_signal_store.rs => stored_maybe_signal.rs} (100%) diff --git a/Cargo.toml b/Cargo.toml index 7dd4b55..d9c7909 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,8 +13,8 @@ license = "MIT" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -leptos = { version = "0.5.1", features = ["csr"] } -web-sys = { version = "0.3.62", features = [ +leptos = { version = "0.5.2", features = ["csr"] } +web-sys = { version = "0.3.63", features = [ "DomRect", "File", "FileList", diff --git a/demo/Cargo.toml b/demo/Cargo.toml index fcdca8e..47ee7f8 100644 --- a/demo/Cargo.toml +++ b/demo/Cargo.toml @@ -7,14 +7,14 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -leptos = { version = "0.5.1", features = ["csr"] } +leptos = { version = "0.5.2", features = ["csr"] } thaw = { path = "../" } icondata = { version = "0.1.0", features = [ "AiCloseOutlined", "AiCheckOutlined", "AiGithubOutlined", ] } -leptos_router = { version = "0.5.1", features = ["csr"] } +leptos_router = { version = "0.5.2", features = ["csr"] } leptos_devtools = "0.0.1" prisms = { git = "https://github.com/luoxiaozero/prisms", rev = "16d4d34b93fc20578ebf03137d54ecc7eafa4d4b" } diff --git a/src/auto_complete/mod.rs b/src/auto_complete/mod.rs index 2f34d12..b3c068b 100644 --- a/src/auto_complete/mod.rs +++ b/src/auto_complete/mod.rs @@ -1,12 +1,6 @@ mod theme; -use crate::{ - mount_style, - teleport::Teleport, - use_theme, - utils::{maybe_rw_signal::MaybeRwSignal, StoredMaybeSignal}, - Input, Theme, -}; +use crate::{mount_style, teleport::Teleport, use_theme, utils::StoredMaybeSignal, Input, Theme}; use leptos::*; pub use theme::AutoCompleteTheme; @@ -18,7 +12,7 @@ pub struct AutoCompleteOption { #[component] pub fn AutoComplete( - #[prop(optional, into)] value: MaybeRwSignal, + #[prop(optional, into)] value: RwSignal, #[prop(optional, into)] placeholder: MaybeSignal, #[prop(optional, into)] options: MaybeSignal>, #[prop(optional, into)] clear_after_select: MaybeSignal, diff --git a/src/checkbox/checkbox_group.rs b/src/checkbox/checkbox_group.rs index 212b2f2..916809e 100644 --- a/src/checkbox/checkbox_group.rs +++ b/src/checkbox/checkbox_group.rs @@ -1,10 +1,9 @@ -use crate::utils::maybe_rw_signal::MaybeRwSignal; use leptos::*; use std::collections::HashSet; #[component] pub fn CheckboxGroup( - #[prop(optional, into)] value: MaybeRwSignal>, + #[prop(optional, into)] value: RwSignal>, children: Children, ) -> impl IntoView { let injection_key = CheckboxGroupInjectionKey::new(value.into()); diff --git a/src/checkbox/mod.rs b/src/checkbox/mod.rs index f83363a..f3129d4 100644 --- a/src/checkbox/mod.rs +++ b/src/checkbox/mod.rs @@ -1,13 +1,7 @@ mod checkbox_group; mod checkbox_item; -use crate::{ - components::*, - icon::*, - theme::use_theme, - utils::{maybe_rw_signal::MaybeRwSignal, mount_style::mount_style}, - Theme, -}; +use crate::{components::*, icon::*, theme::use_theme, utils::mount_style::mount_style, Theme}; pub use checkbox_group::CheckboxGroup; pub use checkbox_item::CheckboxItem; use icondata::AiIcon; @@ -15,7 +9,7 @@ use leptos::*; #[component] pub fn Checkbox( - #[prop(optional, into)] value: MaybeRwSignal, + #[prop(optional, into)] value: RwSignal, children: Children, ) -> impl IntoView { let theme = use_theme(Theme::light); @@ -41,7 +35,7 @@ pub fn Checkbox( >
- + diff --git a/src/color_picker/mod.rs b/src/color_picker/mod.rs index deed2b5..d74c5da 100644 --- a/src/color_picker/mod.rs +++ b/src/color_picker/mod.rs @@ -1,16 +1,14 @@ mod color; mod theme; -use crate::{ - mount_style, teleport::Teleport, use_theme, utils::maybe_rw_signal::MaybeRwSignal, Theme, -}; +use crate::{mount_style, teleport::Teleport, use_theme, Theme}; pub use color::*; use leptos::*; use leptos::{leptos_dom::helpers::WindowListenerHandle, wasm_bindgen::__rt::IntoJsResult}; pub use theme::ColorPickerTheme; #[component] -pub fn ColorPicker(#[prop(optional, into)] value: MaybeRwSignal) -> impl IntoView { +pub fn ColorPicker(#[prop(optional, into)] value: RwSignal) -> impl IntoView { mount_style("color-picker", include_str!("./color-picker.css")); let theme = use_theme(Theme::light); let popover_css_vars = create_memo(move |_| { diff --git a/src/input/mod.rs b/src/input/mod.rs index 1611b07..f2a1070 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -2,7 +2,7 @@ mod theme; use crate::{ theme::{use_theme, Theme}, - utils::{maybe_rw_signal::MaybeRwSignal, mount_style::mount_style}, + utils::mount_style::mount_style, }; use leptos::*; pub use theme::InputTheme; @@ -30,7 +30,7 @@ pub struct InputSuffix { #[component] pub fn Input( - #[prop(optional, into)] value: MaybeRwSignal, + #[prop(optional, into)] value: RwSignal, #[prop(optional, into)] allow_value: Option>, #[prop(optional, into)] variant: MaybeSignal, #[prop(optional, into)] placeholder: MaybeSignal, diff --git a/src/input_number/mod.rs b/src/input_number/mod.rs index 4125ba0..debf729 100644 --- a/src/input_number/mod.rs +++ b/src/input_number/mod.rs @@ -1,14 +1,12 @@ use crate::utils::StoredMaybeSignal; -use crate::{ - utils::maybe_rw_signal::MaybeRwSignal, AiIcon, Button, ButtonVariant, Icon, Input, InputSuffix, -}; +use crate::{AiIcon, Button, ButtonVariant, Icon, Input, InputSuffix}; use leptos::*; use std::ops::{Add, Sub}; use std::str::FromStr; #[component] pub fn InputNumber( - #[prop(optional, into)] value: MaybeRwSignal, + #[prop(optional, into)] value: RwSignal, #[prop(optional, into)] placeholder: MaybeSignal, #[prop(into)] step: MaybeSignal, ) -> impl IntoView diff --git a/src/loading_bar/mod.rs b/src/loading_bar/mod.rs index 3db30ec..d205a93 100644 --- a/src/loading_bar/mod.rs +++ b/src/loading_bar/mod.rs @@ -52,7 +52,7 @@ pub(crate) fn LoadingBar(#[prop(optional)] comp_ref: ComponentRef .style("transition", "none") .style("max-width", "0"); _ = loading_bar_ref.offset_width(); - loading_bar_ref + _ = loading_bar_ref .style("transition", "max-width 4s linear") .style("max-width", "80%"); } @@ -66,7 +66,7 @@ pub(crate) fn LoadingBar(#[prop(optional)] comp_ref: ComponentRef }; let finish = Callback::new(move |_| { if let Some(loading_bar_ref) = loading_bar_ref.get_untracked() { - loading_bar_ref + _ = loading_bar_ref .style("background-color", "var(--thaw-background-color)") .style("transition", "max-width 0.5s linear") .style("max-width", "100%"); @@ -83,7 +83,7 @@ pub(crate) fn LoadingBar(#[prop(optional)] comp_ref: ComponentRef .style("max-width", "0"); _ = loading_bar_ref.offset_width(); } - loading_bar_ref + _ = loading_bar_ref .style("background-color", "var(--thaw-background-color-error)") .style("transition", "max-width 0.5s linear") .style("max-width", "100%"); diff --git a/src/menu/mod.rs b/src/menu/mod.rs index 0043b0b..7ffe8bb 100644 --- a/src/menu/mod.rs +++ b/src/menu/mod.rs @@ -2,17 +2,13 @@ mod menu_group; mod menu_item; mod theme; -use crate::utils::maybe_rw_signal::MaybeRwSignal; use leptos::*; pub use menu_group::MenuGroup; pub use menu_item::*; pub use theme::MenuTheme; #[component] -pub fn Menu( - #[prop(optional, into)] value: MaybeRwSignal, - children: Children, -) -> impl IntoView { +pub fn Menu(#[prop(optional, into)] value: RwSignal, children: Children) -> impl IntoView { let menu_injection_key = create_rw_signal(MenuInjectionKey::new(value.get_untracked())); create_effect(move |_| { let selected_key = value.get(); diff --git a/src/mobile/tabbar/mod.rs b/src/mobile/tabbar/mod.rs index e11303c..1b60e05 100644 --- a/src/mobile/tabbar/mod.rs +++ b/src/mobile/tabbar/mod.rs @@ -1,18 +1,14 @@ mod tabbar_item; mod theme; -use crate::{ - use_theme, - utils::{maybe_rw_signal::MaybeRwSignal, mount_style::mount_style}, - Theme, -}; +use crate::{use_theme, utils::mount_style::mount_style, Theme}; use leptos::*; pub use tabbar_item::*; pub use theme::TabbarTheme; #[component] pub fn Tabbar( - #[prop(optional, into)] value: MaybeRwSignal, + #[prop(optional, into)] value: RwSignal, children: Children, ) -> impl IntoView { mount_style("tabbar", include_str!("./tabbar.css")); diff --git a/src/radio/mod.rs b/src/radio/mod.rs index 0f703f0..bde3d63 100644 --- a/src/radio/mod.rs +++ b/src/radio/mod.rs @@ -1,15 +1,8 @@ -use crate::{ - theme::use_theme, - utils::{maybe_rw_signal::MaybeRwSignal, mount_style::mount_style}, - Theme, -}; +use crate::{theme::use_theme, utils::mount_style::mount_style, Theme}; use leptos::*; #[component] -pub fn Radio( - #[prop(optional, into)] value: MaybeRwSignal, - children: Children, -) -> impl IntoView { +pub fn Radio(#[prop(optional, into)] value: RwSignal, children: Children) -> impl IntoView { let theme = use_theme(Theme::light); mount_style("radio", include_str!("./radio.css")); diff --git a/src/select/mod.rs b/src/select/mod.rs index 3e91128..4aa86df 100644 --- a/src/select/mod.rs +++ b/src/select/mod.rs @@ -1,11 +1,6 @@ mod theme; -use crate::{ - teleport::Teleport, - theme::use_theme, - utils::{maybe_rw_signal::MaybeRwSignal, mount_style::mount_style}, - Theme, -}; +use crate::{teleport::Teleport, theme::use_theme, utils::mount_style::mount_style, Theme}; use leptos::wasm_bindgen::__rt::IntoJsResult; use leptos::*; use std::hash::Hash; @@ -19,7 +14,7 @@ pub struct SelectOption { #[component] pub fn Select( - #[prop(optional, into)] value: MaybeRwSignal>, + #[prop(optional, into)] value: RwSignal>, #[prop(optional, into)] options: MaybeSignal>>, ) -> impl IntoView where diff --git a/src/slider/mod.rs b/src/slider/mod.rs index 841c3ee..cd0b3b2 100644 --- a/src/slider/mod.rs +++ b/src/slider/mod.rs @@ -1,16 +1,12 @@ mod theme; -use crate::{ - theme::use_theme, - utils::{maybe_rw_signal::MaybeRwSignal, mount_style::mount_style}, - Theme, -}; +use crate::{theme::use_theme, utils::mount_style::mount_style, Theme}; use leptos::*; pub use theme::SliderTheme; #[component] pub fn Slider( - #[prop(optional, into)] value: MaybeRwSignal, + #[prop(optional, into)] value: RwSignal, #[prop(default = MaybeSignal::Static(100f64), into)] max: MaybeSignal, ) -> impl IntoView { mount_style("slider", include_str!("./slider.css")); diff --git a/src/switch/mod.rs b/src/switch/mod.rs index 0bf1098..fdd3792 100644 --- a/src/switch/mod.rs +++ b/src/switch/mod.rs @@ -1,11 +1,11 @@ mod theme; -use crate::{mount_style, theme::use_theme, utils::maybe_rw_signal::MaybeRwSignal, Theme}; +use crate::{mount_style, theme::use_theme, Theme}; use leptos::*; pub use theme::SwitchTheme; #[component] -pub fn Switch(#[prop(optional, into)] value: MaybeRwSignal) -> impl IntoView { +pub fn Switch(#[prop(optional, into)] value: RwSignal) -> impl IntoView { mount_style("switch", include_str!("./switch.css")); let theme = use_theme(Theme::light); let css_vars = create_memo(move |_| { diff --git a/src/tabs/mod.rs b/src/tabs/mod.rs index ec4b8f1..4ee18af 100644 --- a/src/tabs/mod.rs +++ b/src/tabs/mod.rs @@ -1,24 +1,16 @@ mod tab; -use std::ops::Deref; -use crate::{ - theme::use_theme, - utils::{maybe_rw_signal::MaybeRwSignal, mount_style::mount_style}, - Theme, -}; +use crate::{theme::use_theme, utils::mount_style::mount_style, Theme}; use leptos::*; pub use tab::*; #[component] -pub fn Tabs( - #[prop(optional, into)] value: MaybeRwSignal, - children: Children, -) -> impl IntoView { +pub fn Tabs(#[prop(optional, into)] value: RwSignal, children: Children) -> impl IntoView { mount_style("tabs", include_str!("./tabs.css")); let tab_options_vec = create_rw_signal(vec![]); provide_context(TabsInjectionKey { - active_key: *value.deref(), + active_key: value, tab_options_vec, }); let theme = use_theme(Theme::light); diff --git a/src/utils/maybe_rw_signal.rs b/src/utils/maybe_rw_signal.rs deleted file mode 100644 index 22b043a..0000000 --- a/src/utils/maybe_rw_signal.rs +++ /dev/null @@ -1,44 +0,0 @@ -use leptos::RwSignal; -use std::ops::Deref; - -pub struct MaybeRwSignal(RwSignal); - -impl MaybeRwSignal { - pub fn clone_into(&self) -> RwSignal { - self.0 - } -} - -impl Default for MaybeRwSignal { - fn default() -> Self { - Self(RwSignal::new(Default::default())) - } -} - -impl Clone for MaybeRwSignal { - fn clone(&self) -> Self { - *self - } -} - -impl Copy for MaybeRwSignal {} - -impl Deref for MaybeRwSignal { - type Target = RwSignal; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl From> for MaybeRwSignal { - fn from(value: RwSignal) -> Self { - Self(value) - } -} - -impl From> for RwSignal { - fn from(value: MaybeRwSignal) -> Self { - value.0 - } -} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 2a7fb34..5c7526e 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,10 +1,9 @@ // mod callback; mod component_ref; -pub mod maybe_rw_signal; -mod maybe_signal_store; pub mod mount_style; pub mod signal; +mod stored_maybe_signal; // pub use callback::AsyncCallback; pub use component_ref::ComponentRef; -pub use maybe_signal_store::*; +pub use stored_maybe_signal::*; diff --git a/src/utils/maybe_signal_store.rs b/src/utils/stored_maybe_signal.rs similarity index 100% rename from src/utils/maybe_signal_store.rs rename to src/utils/stored_maybe_signal.rs diff --git a/src/wave/mod.rs b/src/wave/mod.rs index 9bb727a..2fc1b9d 100644 --- a/src/wave/mod.rs +++ b/src/wave/mod.rs @@ -37,6 +37,12 @@ pub fn Wave(#[prop(optional)] comp_ref: ComponentRef) -> impl IntoView } }); comp_ref.load(WaveRef { play }); + on_cleanup(move || { + if let Some(handle) = animation_timeout_handle.get() { + handle.clear(); + animation_timeout_handle.set(None); + } + }); view! {
Date: Thu, 9 Nov 2023 16:46:14 +0800 Subject: [PATCH 2/2] feat: functional optimization --- Cargo.toml | 1 + src/button/mod.rs | 4 +- src/checkbox/checkbox_group.rs | 17 ++------ src/checkbox/checkbox_item.rs | 4 +- src/grid/mod.rs | 10 ++--- src/loading_bar/loading_bar_provider.rs | 1 + src/loading_bar/mod.rs | 2 +- src/menu/menu_item.rs | 9 ++-- src/menu/mod.rs | 32 ++------------ src/message/message.rs | 54 ------------------------ src/message/message_environment.rs | 2 +- src/message/message_provider.rs | 2 +- src/message/mod.rs | 56 ++++++++++++++++++++++++- src/mobile/tabbar/mod.rs | 33 ++------------- src/mobile/tabbar/tabbar_item.rs | 9 ++-- src/mobile/toast/mod.rs | 29 +++++-------- src/tabs/mod.rs | 10 ++--- src/teleport/mod.rs | 46 ++++++++++---------- 18 files changed, 129 insertions(+), 192 deletions(-) delete mode 100644 src/message/message.rs diff --git a/Cargo.toml b/Cargo.toml index d9c7909..d7b38d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ icondata = { version = "0.1.0", features = [ ] } icondata_core = "0.0.2" uuid = { version = "1.5.0", features = ["v4"] } +cfg-if = "1.0.0" [workspace] members = ["demo"] diff --git a/src/button/mod.rs b/src/button/mod.rs index 8b8a839..1d8eba7 100644 --- a/src/button/mod.rs +++ b/src/button/mod.rs @@ -95,12 +95,12 @@ pub fn Button( "--thaw-background-color-active: {};", theme.button.color_text_active )); - css_vars.push_str(&format!("--thaw-ripple-color: #0000;")); + css_vars.push_str("--thaw-ripple-color: #0000;"); } else { css_vars.push_str(&format!("--thaw-font-color-hover: {bg_color};")); css_vars.push_str("--thaw-border-color: #555a;"); css_vars.push_str("--thaw-border-color-hover: #555;"); - css_vars.push_str(&format!("--thaw-ripple-color: #0000;")); + css_vars.push_str("--thaw-ripple-color: #0000;"); } }); diff --git a/src/checkbox/checkbox_group.rs b/src/checkbox/checkbox_group.rs index 916809e..adefcb8 100644 --- a/src/checkbox/checkbox_group.rs +++ b/src/checkbox/checkbox_group.rs @@ -6,23 +6,14 @@ pub fn CheckboxGroup( #[prop(optional, into)] value: RwSignal>, children: Children, ) -> impl IntoView { - let injection_key = CheckboxGroupInjectionKey::new(value.into()); - provide_context(injection_key); + provide_context(CheckboxGroupInjection(value)); children() } #[derive(Clone)] -pub struct CheckboxGroupInjectionKey { - pub value: RwSignal>, -} +pub(crate) struct CheckboxGroupInjection(pub RwSignal>); -impl CheckboxGroupInjectionKey { - pub fn new(value: RwSignal>) -> Self { - Self { value } - } -} - -pub fn use_checkbox_group() -> CheckboxGroupInjectionKey { - expect_context::() +pub(crate) fn use_checkbox_group() -> CheckboxGroupInjection { + expect_context() } diff --git a/src/checkbox/checkbox_item.rs b/src/checkbox/checkbox_item.rs index aa6d827..a31e178 100644 --- a/src/checkbox/checkbox_item.rs +++ b/src/checkbox/checkbox_item.rs @@ -11,13 +11,13 @@ pub fn CheckboxItem( ) -> impl IntoView { let checkbox_group = use_checkbox_group(); let checked = checkbox_group - .value + .0 .with_untracked(|checkbox_group| checkbox_group.contains(&key)); let checked = create_rw_signal(checked); let item_key = store_value(key); _ = checked.watch(move |checked| { - checkbox_group.value.update(move |checkbox_group| { + checkbox_group.0.update(move |checkbox_group| { if *checked { checkbox_group.insert(item_key.get_value()); } else { diff --git a/src/grid/mod.rs b/src/grid/mod.rs index 6821b8f..16b5dfd 100644 --- a/src/grid/mod.rs +++ b/src/grid/mod.rs @@ -10,7 +10,7 @@ pub fn Grid( #[prop(optional, into)] y_gap: MaybeSignal, children: Children, ) -> impl IntoView { - let grid_injection_key = GridInjectionKey::new(x_gap); + let grid_injection_key = GridInjection::new(x_gap); provide_context(grid_injection_key); let style = create_memo(move |_| { @@ -31,16 +31,16 @@ pub fn Grid( } #[derive(Clone)] -pub struct GridInjectionKey { +pub(crate) struct GridInjection { x_gap: MaybeSignal, } -impl GridInjectionKey { +impl GridInjection { pub fn new(x_gap: MaybeSignal) -> Self { Self { x_gap } } } -pub fn use_grid() -> GridInjectionKey { - expect_context::() +pub(crate) fn use_grid() -> GridInjection { + expect_context() } diff --git a/src/loading_bar/loading_bar_provider.rs b/src/loading_bar/loading_bar_provider.rs index 7f085ef..e4640ec 100644 --- a/src/loading_bar/loading_bar_provider.rs +++ b/src/loading_bar/loading_bar_provider.rs @@ -19,6 +19,7 @@ pub fn LoadingBarProvider(children: Children) -> impl IntoView { pub struct LoadingBarInjection { loading_bar_ref: ComponentRef, } + impl Copy for LoadingBarInjection {} impl LoadingBarInjection { diff --git a/src/loading_bar/mod.rs b/src/loading_bar/mod.rs index d205a93..f18e704 100644 --- a/src/loading_bar/mod.rs +++ b/src/loading_bar/mod.rs @@ -99,7 +99,7 @@ pub(crate) fn LoadingBar(#[prop(optional)] comp_ref: ComponentRef view! {
diff --git a/src/menu/mod.rs b/src/menu/mod.rs index 7ffe8bb..8a9af71 100644 --- a/src/menu/mod.rs +++ b/src/menu/mod.rs @@ -9,37 +9,13 @@ pub use theme::MenuTheme; #[component] pub fn Menu(#[prop(optional, into)] value: RwSignal, children: Children) -> impl IntoView { - let menu_injection_key = create_rw_signal(MenuInjectionKey::new(value.get_untracked())); - create_effect(move |_| { - let selected_key = value.get(); - let key = menu_injection_key.get_untracked(); - if selected_key != key.value { - menu_injection_key.set(MenuInjectionKey::new(selected_key)); - } - }); - - create_effect(move |_| { - let selected_key = value.get_untracked(); - let key = menu_injection_key.get(); - if selected_key != key.value { - value.set(key.value); - } - }); - provide_context(menu_injection_key); + provide_context(MenuInjection(value)); view! {
{children()}
} } #[derive(Clone)] -pub struct MenuInjectionKey { - value: String, -} +pub(crate) struct MenuInjection(pub RwSignal); -impl MenuInjectionKey { - pub fn new(value: String) -> Self { - Self { value } - } -} - -pub fn use_menu() -> RwSignal { - expect_context::>() +pub(crate) fn use_menu() -> MenuInjection { + expect_context() } diff --git a/src/message/message.rs b/src/message/message.rs deleted file mode 100644 index 3f2fd50..0000000 --- a/src/message/message.rs +++ /dev/null @@ -1,54 +0,0 @@ -use crate::{theme::use_theme, Icon, Theme}; -use icondata::*; -use leptos::*; - -#[derive(Default, Clone)] -pub enum MessageVariant { - #[default] - Success, - Warning, - Error, -} - -impl MessageVariant { - fn icon(&self) -> Icon { - match self { - MessageVariant::Success => icondata::Icon::Ai(AiCloseCircleFilled), - MessageVariant::Warning => icondata::Icon::Ai(AiExclamationCircleFilled), - MessageVariant::Error => icondata::Icon::Ai(AiCheckCircleFilled), - } - } - fn theme_color(&self, theme: &Theme) -> String { - match self { - MessageVariant::Success => theme.common.color_success.clone(), - MessageVariant::Warning => theme.common.color_warning.clone(), - MessageVariant::Error => theme.common.color_error.clone(), - } - } -} - -#[component] -pub(crate) fn Message(variant: MessageVariant, content: String) -> impl IntoView { - let theme = use_theme(Theme::light); - let css_vars = create_memo(move |_| { - let mut css_vars = String::new(); - theme.with(|theme| { - css_vars.push_str(&format!( - "--thaw-background-color: {}", - theme.message.background_color - )) - }); - css_vars - }); - let style = theme.with_untracked(|theme| format!("color: {};", variant.theme_color(theme))); - view! { -
-
-
- -
-
{content}
-
-
- } -} diff --git a/src/message/message_environment.rs b/src/message/message_environment.rs index 5533cdd..f015d94 100644 --- a/src/message/message_environment.rs +++ b/src/message/message_environment.rs @@ -1,4 +1,4 @@ -use super::{message::Message, message_provider::MessageType}; +use super::{message_provider::MessageType, Message}; use leptos::*; use uuid::Uuid; diff --git a/src/message/message_provider.rs b/src/message/message_provider.rs index 85fb156..f7268e3 100644 --- a/src/message/message_provider.rs +++ b/src/message/message_provider.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use super::{message::MessageVariant, message_environment::MessageEnvironment}; +use super::{message_environment::MessageEnvironment, MessageVariant}; use crate::{mount_style, teleport::Teleport}; use leptos::*; use uuid::Uuid; diff --git a/src/message/mod.rs b/src/message/mod.rs index 861e9c9..a4dd7b6 100644 --- a/src/message/mod.rs +++ b/src/message/mod.rs @@ -1,8 +1,60 @@ -mod message; mod message_environment; mod message_provider; mod theme; -pub use message::*; +use crate::{theme::use_theme, Icon, Theme}; +use icondata::*; +use leptos::*; pub use message_provider::*; pub use theme::MessageTheme; + +#[derive(Default, Clone)] +pub enum MessageVariant { + #[default] + Success, + Warning, + Error, +} + +impl MessageVariant { + fn icon(&self) -> Icon { + match self { + MessageVariant::Success => icondata::Icon::Ai(AiCloseCircleFilled), + MessageVariant::Warning => icondata::Icon::Ai(AiExclamationCircleFilled), + MessageVariant::Error => icondata::Icon::Ai(AiCheckCircleFilled), + } + } + fn theme_color(&self, theme: &Theme) -> String { + match self { + MessageVariant::Success => theme.common.color_success.clone(), + MessageVariant::Warning => theme.common.color_warning.clone(), + MessageVariant::Error => theme.common.color_error.clone(), + } + } +} + +#[component] +pub(crate) fn Message(variant: MessageVariant, content: String) -> impl IntoView { + let theme = use_theme(Theme::light); + let css_vars = create_memo(move |_| { + let mut css_vars = String::new(); + theme.with(|theme| { + css_vars.push_str(&format!( + "--thaw-background-color: {}", + theme.message.background_color + )) + }); + css_vars + }); + let style = theme.with_untracked(|theme| format!("color: {};", variant.theme_color(theme))); + view! { +
+
+
+ +
+
{content}
+
+
+ } +} diff --git a/src/mobile/tabbar/mod.rs b/src/mobile/tabbar/mod.rs index 1b60e05..84414f9 100644 --- a/src/mobile/tabbar/mod.rs +++ b/src/mobile/tabbar/mod.rs @@ -21,24 +21,7 @@ pub fn Tabbar( ) }) }); - - let tabbar_injection_key = create_rw_signal(TabbarInjectionKey::new(value.get())); - create_effect(move |_| { - let selected_key = value.get(); - let key = tabbar_injection_key.get_untracked(); - if selected_key != key.value { - tabbar_injection_key.set(TabbarInjectionKey::new(selected_key)); - } - }); - - create_effect(move |_| { - let selected_key = value.get_untracked(); - let key = tabbar_injection_key.get(); - if selected_key != key.value { - value.set(key.value); - } - }); - provide_context(tabbar_injection_key); + provide_context(TabbarInjection(value)); view! {
{children()} @@ -47,16 +30,8 @@ pub fn Tabbar( } #[derive(Clone)] -pub struct TabbarInjectionKey { - value: String, -} +pub(crate) struct TabbarInjection(pub RwSignal); -impl TabbarInjectionKey { - pub fn new(value: String) -> Self { - Self { value } - } -} - -pub fn use_tabbar() -> RwSignal { - use_context::>().expect("TabbarInjectionKey not exist") +pub(crate) fn use_tabbar() -> TabbarInjection { + expect_context() } diff --git a/src/mobile/tabbar/tabbar_item.rs b/src/mobile/tabbar/tabbar_item.rs index ff88678..b7c47a2 100644 --- a/src/mobile/tabbar/tabbar_item.rs +++ b/src/mobile/tabbar/tabbar_item.rs @@ -1,4 +1,4 @@ -use super::{use_tabbar, TabbarInjectionKey}; +use super::use_tabbar; use crate::components::*; use crate::utils::StoredMaybeSignal; use crate::{icon::*, theme::use_theme, utils::mount_style::mount_style, Theme}; @@ -15,7 +15,10 @@ pub fn TabbarItem( let tabbar = use_tabbar(); let key: StoredMaybeSignal<_> = key.into(); let on_click = move |_| { - tabbar.set(TabbarInjectionKey::new(key.get())); + let click_key = key.get(); + if tabbar.0.with(|key| key != &click_key) { + tabbar.0.set(click_key); + } }; let css_vars = create_memo(move |_| { @@ -30,7 +33,7 @@ pub fn TabbarItem( view! {
diff --git a/src/mobile/toast/mod.rs b/src/mobile/toast/mod.rs index e816e50..cb0aa61 100644 --- a/src/mobile/toast/mod.rs +++ b/src/mobile/toast/mod.rs @@ -1,7 +1,6 @@ use crate::utils::mount_style::mount_style; -use leptos::*; +use cfg_if::cfg_if; use std::time::Duration; -use web_sys::Element; pub struct ToastOptions { pub message: String, @@ -10,26 +9,20 @@ pub struct ToastOptions { pub fn show_toast(options: ToastOptions) { mount_style("toast", include_str!("./toast.css")); - - let parent = Element::from(document().body().expect("body element not to exist")); - let children = view! {
{options.message}
}; - let node = children.into_view(); - - #[cfg(target_arch = "wasm32")] - { - use leptos::leptos_dom::Mountable; + cfg_if! { if #[cfg(target_arch = "wasm32")] { + use leptos::{leptos_dom::Mountable, *}; + let mount = document().body().expect("body element not to exist"); + let children = view! {
{options.message}
}; + let node = children.into_view(); let node = node.get_mountable_node(); - parent.append_child(&node).unwrap(); + _ = mount.append_child(&node); set_timeout( move || { - _ = parent.remove_child(&node); + _ = mount.remove_child(&node); }, options.duration, ); - } - #[cfg(not(target_arch = "wasm32"))] - { - _ = parent; - _ = node; - } + } else { + _ = options; + }} } diff --git a/src/tabs/mod.rs b/src/tabs/mod.rs index 4ee18af..b6a7e3f 100644 --- a/src/tabs/mod.rs +++ b/src/tabs/mod.rs @@ -9,7 +9,7 @@ pub use tab::*; pub fn Tabs(#[prop(optional, into)] value: RwSignal, children: Children) -> impl IntoView { mount_style("tabs", include_str!("./tabs.css")); let tab_options_vec = create_rw_signal(vec![]); - provide_context(TabsInjectionKey { + provide_context(TabsInjection { active_key: value, tab_options_vec, }); @@ -106,12 +106,12 @@ pub(crate) struct TabsLabelLine { } #[derive(Clone)] -pub struct TabsInjectionKey { +pub(crate) struct TabsInjection { active_key: RwSignal, tab_options_vec: RwSignal>, } -impl TabsInjectionKey { +impl TabsInjection { pub fn get_key(&self) -> String { self.active_key.get() } @@ -123,6 +123,6 @@ impl TabsInjectionKey { } } -pub fn use_tabs() -> TabsInjectionKey { - use_context::().expect("TabsInjectionKey not exist") +pub(crate) fn use_tabs() -> TabsInjection { + expect_context() } diff --git a/src/teleport/mod.rs b/src/teleport/mod.rs index 8747075..777c49b 100644 --- a/src/teleport/mod.rs +++ b/src/teleport/mod.rs @@ -1,34 +1,30 @@ +use cfg_if::cfg_if; use leptos::*; -use web_sys::Element; - /// https://github.com/solidjs/solid/blob/main/packages/solid/web/src/index.ts#L56 #[component] -pub fn Teleport(#[prop(optional)] to: Option<&'static str>, children: Children) -> impl IntoView { - let parent = if let Some(to) = to { - document() - .query_selector(to) - .expect("element not to exist") - .expect("element not to exist") - } else { - Element::from(document().body().expect("body element not to exist")) - }; - - #[cfg(target_arch = "wasm32")] - { - use leptos::leptos_dom::Mountable; +pub fn Teleport( + #[prop(into, optional)] mount: Option, + children: Children, +) -> impl IntoView { + cfg_if! { if #[cfg(target_arch = "wasm32")] { + use leptos::{ + wasm_bindgen::JsCast, + leptos_dom::Mountable + }; + let mount = mount.unwrap_or_else(|| { + document() + .body() + .expect("body element not to exist") + .unchecked_into() + }); let node = children().into_view(); let node = node.get_mountable_node(); - parent.append_child(&node).unwrap(); + _ = mount.append_child(&node); on_cleanup(move || { - _ = parent.remove_child(&node); + _ = mount.remove_child(&node); }); - } - - #[cfg(not(target_arch = "wasm32"))] - { - _ = parent; + } else { + _ = mount; _ = children; - } - - view! { <> } + }} }