From 1af5b2573a5181a040ed0b8cfd5943d398a28d04 Mon Sep 17 00:00:00 2001 From: luoxiaozero <48741584+luoxiaozero@users.noreply.github.com> Date: Tue, 9 Apr 2024 21:46:22 +0800 Subject: [PATCH] feat: Lazy mount (#161) * feat: Drawer lazy mount * feat: Binder lazy mount --- thaw/src/auto_complete/mod.rs | 1 + thaw/src/color_picker/mod.rs | 1 + thaw/src/date_picker/panel/mod.rs | 1 + thaw/src/drawer/mod.rs | 4 +- thaw/src/modal/mod.rs | 4 +- thaw/src/popover/mod.rs | 6 +-- thaw/src/scrollbar/mod.rs | 2 +- thaw/src/select/mod.rs | 1 + thaw/src/time_picker/mod.rs | 1 + thaw_components/src/binder/mod.rs | 2 +- thaw_components/src/teleport/mod.rs | 82 +++++++++++++++++------------ 11 files changed, 64 insertions(+), 41 deletions(-) diff --git a/thaw/src/auto_complete/mod.rs b/thaw/src/auto_complete/mod.rs index cb8ea8b..4e3bbd5 100644 --- a/thaw/src/auto_complete/mod.rs +++ b/thaw/src/auto_complete/mod.rs @@ -204,6 +204,7 @@ pub fn AutoComplete( diff --git a/thaw/src/color_picker/mod.rs b/thaw/src/color_picker/mod.rs index 269c0f6..c7d4b5f 100644 --- a/thaw/src/color_picker/mod.rs +++ b/thaw/src/color_picker/mod.rs @@ -152,6 +152,7 @@ pub fn ColorPicker( diff --git a/thaw/src/date_picker/panel/mod.rs b/thaw/src/date_picker/panel/mod.rs index 9442d7a..30e42ca 100644 --- a/thaw/src/date_picker/panel/mod.rs +++ b/thaw/src/date_picker/panel/mod.rs @@ -93,6 +93,7 @@ pub fn Panel( diff --git a/thaw/src/drawer/mod.rs b/thaw/src/drawer/mod.rs index fa33ebe..cca2b93 100644 --- a/thaw/src/drawer/mod.rs +++ b/thaw/src/drawer/mod.rs @@ -87,6 +87,7 @@ pub fn Drawer(
} } DrawerMount::Body => view! { - + }, diff --git a/thaw/src/modal/mod.rs b/thaw/src/modal/mod.rs index 7000d20..4d94be2 100644 --- a/thaw/src/modal/mod.rs +++ b/thaw/src/modal/mod.rs @@ -64,7 +64,7 @@ pub fn Modal( }); view! { - +
{trigger_children()}
- +
i32 { - self.container_scroll_top.get() + self.container_scroll_top.get_untracked() } } diff --git a/thaw/src/select/mod.rs b/thaw/src/select/mod.rs index efacb81..26c0214 100644 --- a/thaw/src/select/mod.rs +++ b/thaw/src/select/mod.rs @@ -127,6 +127,7 @@ where diff --git a/thaw/src/time_picker/mod.rs b/thaw/src/time_picker/mod.rs index 121fd10..52df461 100644 --- a/thaw/src/time_picker/mod.rs +++ b/thaw/src/time_picker/mod.rs @@ -178,6 +178,7 @@ fn Panel( diff --git a/thaw_components/src/binder/mod.rs b/thaw_components/src/binder/mod.rs index 4003a4b..d19c720 100644 --- a/thaw_components/src/binder/mod.rs +++ b/thaw_components/src/binder/mod.rs @@ -239,7 +239,7 @@ fn FollowerContainer( ) }); - view! { } + view! { } } fn get_scroll_parent(element: Option>) -> Option> { diff --git a/thaw_components/src/teleport/mod.rs b/thaw_components/src/teleport/mod.rs index 698757d..afd547c 100644 --- a/thaw_components/src/teleport/mod.rs +++ b/thaw_components/src/teleport/mod.rs @@ -4,46 +4,62 @@ use leptos::{html::AnyElement, *}; /// https://github.com/solidjs/solid/blob/main/packages/solid/web/src/index.ts#L56 #[component] pub fn Teleport( + #[prop(default = true.into(), into)] immediate: MaybeSignal, #[prop(into, optional)] mount: Option, #[prop(optional, into)] element: Option>, #[prop(optional)] children: Option, ) -> impl IntoView { cfg_if! { if #[cfg(all(target_arch = "wasm32", any(feature = "csr", feature = "hydrate")))] { - use leptos::wasm_bindgen::JsCast; - use leptos::leptos_dom::Mountable; - use thaw_utils::with_hydration_off; + let mount_fn = StoredValue::new(None:: ()>>); - let mount = mount.unwrap_or_else(|| { - document() - .body() - .expect("body element to exist") - .unchecked_into() + mount_fn.set_value(Some(Box::new(move || { + let mount = mount.unwrap_or_else(|| { + use leptos::wasm_bindgen::JsCast; + document() + .body() + .expect("body element to exist") + .unchecked_into() + }); + + if let Some(element) = element { + let render_root = element; + let _ = mount.append_child(&render_root); + on_cleanup(move || { + let _ = mount.remove_child(&render_root); + }); + } else if let Some(children) = children { + let container = document() + .create_element("div") + .expect("element creation to work"); + + thaw_utils::with_hydration_off(|| { + use leptos::leptos_dom::Mountable; + let _ = container.append_child(&children().into_view().get_mountable_node()); + }); + + let render_root = container; + let _ = mount.append_child(&render_root); + on_cleanup(move || { + let _ = mount.remove_child(&render_root); + }); + } + }))); + + let owner = Owner::current(); + Effect::new(move |_| { + if immediate.get() { + mount_fn.update_value(|mount_fn| { + if let Some(f) = mount_fn.take() { + with_owner(owner.unwrap(), move || { + f(); + }); + } + }); + } }); - - if let Some(element) = element { - let render_root = element; - let _ = mount.append_child(&render_root); - on_cleanup(move || { - let _ = mount.remove_child(&render_root); - }); - } else if let Some(children) = children { - let container = document() - .create_element("div") - .expect("element creation to work"); - with_hydration_off(|| { - let _ = container.append_child(&children().into_view().get_mountable_node()); - }); - - let render_root = container; - let _ = mount.append_child(&render_root); - on_cleanup(move || { - let _ = mount.remove_child(&render_root); - }); - } else { - return; - }; } else { let _ = mount; + let _ = immediate; #[cfg(not(feature = "ssr"))] { let _ = element; @@ -51,9 +67,9 @@ pub fn Teleport( } #[cfg(feature = "ssr")] if element.is_none() { - if let Some(children) = children { + if let Some(children) = children { // Consumed hydration `id` - let _ = children(); + let _ = children(); } } }}