mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-22 22:09:22 -05:00
feat: Lazy mount (#161)
* feat: Drawer lazy mount * feat: Binder lazy mount
This commit is contained in:
parent
f1c3882b72
commit
1af5b2573a
11 changed files with 64 additions and 41 deletions
|
@ -204,6 +204,7 @@ pub fn AutoComplete(
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
node_ref=menu_ref
|
node_ref=menu_ref
|
||||||
name="fade-in-scale-up-transition"
|
name="fade-in-scale-up-transition"
|
||||||
|
appear=is_show_menu.get_untracked()
|
||||||
show=is_show_menu
|
show=is_show_menu
|
||||||
let:display
|
let:display
|
||||||
>
|
>
|
||||||
|
|
|
@ -152,6 +152,7 @@ pub fn ColorPicker(
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
node_ref=popover_ref
|
node_ref=popover_ref
|
||||||
name="fade-in-scale-up-transition"
|
name="fade-in-scale-up-transition"
|
||||||
|
appear=is_show_popover.get_untracked()
|
||||||
show=is_show_popover
|
show=is_show_popover
|
||||||
let:display
|
let:display
|
||||||
>
|
>
|
||||||
|
|
|
@ -93,6 +93,7 @@ pub fn Panel(
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
node_ref=panel_ref
|
node_ref=panel_ref
|
||||||
name="fade-in-scale-up-transition"
|
name="fade-in-scale-up-transition"
|
||||||
|
appear=is_show_panel.get_untracked()
|
||||||
show=is_show_panel
|
show=is_show_panel
|
||||||
let:display
|
let:display
|
||||||
>
|
>
|
||||||
|
|
|
@ -87,6 +87,7 @@ pub fn Drawer(
|
||||||
<div class="thaw-drawer-container" style=move || style.get()>
|
<div class="thaw-drawer-container" style=move || style.get()>
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
node_ref=mask_ref
|
node_ref=mask_ref
|
||||||
|
appear=show.get_untracked()
|
||||||
show=show.signal()
|
show=show.signal()
|
||||||
name="fade-in-transition"
|
name="fade-in-transition"
|
||||||
let:display
|
let:display
|
||||||
|
@ -100,6 +101,7 @@ pub fn Drawer(
|
||||||
</CSSTransition>
|
</CSSTransition>
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
node_ref=drawer_ref
|
node_ref=drawer_ref
|
||||||
|
appear=show.get_untracked()
|
||||||
show=show.signal()
|
show=show.signal()
|
||||||
name=Memo::new(move |_| {
|
name=Memo::new(move |_| {
|
||||||
format!("slide-in-from-{}-transition", placement.get())
|
format!("slide-in-from-{}-transition", placement.get())
|
||||||
|
@ -137,7 +139,7 @@ pub fn Drawer(
|
||||||
view! { <DrawerInnr show mask_closeable close_on_esc title placement class style children/> }
|
view! { <DrawerInnr show mask_closeable close_on_esc title placement class style children/> }
|
||||||
}
|
}
|
||||||
DrawerMount::Body => view! {
|
DrawerMount::Body => view! {
|
||||||
<Teleport>
|
<Teleport immediate=show.signal()>
|
||||||
<DrawerInnr show mask_closeable close_on_esc title placement class style children/>
|
<DrawerInnr show mask_closeable close_on_esc title placement class style children/>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
},
|
},
|
||||||
|
|
|
@ -64,7 +64,7 @@ pub fn Modal(
|
||||||
});
|
});
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<Teleport>
|
<Teleport immediate=show.signal()>
|
||||||
<FocusTrap disabled=!close_on_esc active=show.signal() on_esc>
|
<FocusTrap disabled=!close_on_esc active=show.signal() on_esc>
|
||||||
<div
|
<div
|
||||||
class="thaw-modal-container"
|
class="thaw-modal-container"
|
||||||
|
@ -78,6 +78,7 @@ pub fn Modal(
|
||||||
>
|
>
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
node_ref=mask_ref
|
node_ref=mask_ref
|
||||||
|
appear=show.get_untracked()
|
||||||
show=show.signal()
|
show=show.signal()
|
||||||
name="fade-in-transition"
|
name="fade-in-transition"
|
||||||
let:display
|
let:display
|
||||||
|
@ -91,6 +92,7 @@ pub fn Modal(
|
||||||
</CSSTransition>
|
</CSSTransition>
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
node_ref=modal_ref
|
node_ref=modal_ref
|
||||||
|
appear=show.get_untracked()
|
||||||
show=show.signal()
|
show=show.signal()
|
||||||
name="fade-in-scale-up-transition"
|
name="fade-in-scale-up-transition"
|
||||||
on_enter
|
on_enter
|
||||||
|
|
|
@ -110,7 +110,6 @@ pub fn Popover(
|
||||||
children: trigger_children,
|
children: trigger_children,
|
||||||
} = popover_trigger;
|
} = popover_trigger;
|
||||||
|
|
||||||
let follower_enabled = RwSignal::new(false);
|
|
||||||
view! {
|
view! {
|
||||||
<Binder target_ref>
|
<Binder target_ref>
|
||||||
<div
|
<div
|
||||||
|
@ -121,13 +120,12 @@ pub fn Popover(
|
||||||
>
|
>
|
||||||
{trigger_children()}
|
{trigger_children()}
|
||||||
</div>
|
</div>
|
||||||
<Follower slot show=follower_enabled placement>
|
<Follower slot show=is_show_popover placement>
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
node_ref=popover_ref
|
node_ref=popover_ref
|
||||||
name="popover-transition"
|
name="popover-transition"
|
||||||
|
appear=is_show_popover.get_untracked()
|
||||||
show=is_show_popover
|
show=is_show_popover
|
||||||
on_enter=move |_| follower_enabled.set(true)
|
|
||||||
on_after_leave=move |_| follower_enabled.set(false)
|
|
||||||
let:display
|
let:display
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -337,6 +337,6 @@ pub struct ScrollbarRef {
|
||||||
|
|
||||||
impl ScrollbarRef {
|
impl ScrollbarRef {
|
||||||
pub fn container_scroll_top(&self) -> i32 {
|
pub fn container_scroll_top(&self) -> i32 {
|
||||||
self.container_scroll_top.get()
|
self.container_scroll_top.get_untracked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,7 @@ where
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
node_ref=menu_ref
|
node_ref=menu_ref
|
||||||
name="fade-in-scale-up-transition"
|
name="fade-in-scale-up-transition"
|
||||||
|
appear=is_show_menu.get_untracked()
|
||||||
show=is_show_menu
|
show=is_show_menu
|
||||||
let:display
|
let:display
|
||||||
>
|
>
|
||||||
|
|
|
@ -178,6 +178,7 @@ fn Panel(
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
node_ref=panel_ref
|
node_ref=panel_ref
|
||||||
name="fade-in-scale-up-transition"
|
name="fade-in-scale-up-transition"
|
||||||
|
appear=is_show_panel.get_untracked()
|
||||||
show=is_show_panel
|
show=is_show_panel
|
||||||
let:display
|
let:display
|
||||||
>
|
>
|
||||||
|
|
|
@ -239,7 +239,7 @@ fn FollowerContainer<El: ElementDescriptor + Clone + 'static>(
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
view! { <Teleport element=children/> }
|
view! { <Teleport element=children immediate=show/> }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_scroll_parent(element: Option<HtmlElement<AnyElement>>) -> Option<HtmlElement<AnyElement>> {
|
fn get_scroll_parent(element: Option<HtmlElement<AnyElement>>) -> Option<HtmlElement<AnyElement>> {
|
||||||
|
|
|
@ -4,46 +4,62 @@ use leptos::{html::AnyElement, *};
|
||||||
/// https://github.com/solidjs/solid/blob/main/packages/solid/web/src/index.ts#L56
|
/// https://github.com/solidjs/solid/blob/main/packages/solid/web/src/index.ts#L56
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Teleport(
|
pub fn Teleport(
|
||||||
|
#[prop(default = true.into(), into)] immediate: MaybeSignal<bool>,
|
||||||
#[prop(into, optional)] mount: Option<web_sys::Element>,
|
#[prop(into, optional)] mount: Option<web_sys::Element>,
|
||||||
#[prop(optional, into)] element: Option<HtmlElement<AnyElement>>,
|
#[prop(optional, into)] element: Option<HtmlElement<AnyElement>>,
|
||||||
#[prop(optional)] children: Option<Children>,
|
#[prop(optional)] children: Option<Children>,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
cfg_if! { if #[cfg(all(target_arch = "wasm32", any(feature = "csr", feature = "hydrate")))] {
|
cfg_if! { if #[cfg(all(target_arch = "wasm32", any(feature = "csr", feature = "hydrate")))] {
|
||||||
use leptos::wasm_bindgen::JsCast;
|
let mount_fn = StoredValue::new(None::<Box<dyn FnOnce() -> ()>>);
|
||||||
use leptos::leptos_dom::Mountable;
|
|
||||||
use thaw_utils::with_hydration_off;
|
|
||||||
|
|
||||||
let mount = mount.unwrap_or_else(|| {
|
mount_fn.set_value(Some(Box::new(move || {
|
||||||
document()
|
let mount = mount.unwrap_or_else(|| {
|
||||||
.body()
|
use leptos::wasm_bindgen::JsCast;
|
||||||
.expect("body element to exist")
|
document()
|
||||||
.unchecked_into()
|
.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 {
|
} else {
|
||||||
let _ = mount;
|
let _ = mount;
|
||||||
|
let _ = immediate;
|
||||||
#[cfg(not(feature = "ssr"))]
|
#[cfg(not(feature = "ssr"))]
|
||||||
{
|
{
|
||||||
let _ = element;
|
let _ = element;
|
||||||
|
@ -51,9 +67,9 @@ pub fn Teleport(
|
||||||
}
|
}
|
||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
if element.is_none() {
|
if element.is_none() {
|
||||||
if let Some(children) = children {
|
if let Some(children) = children {
|
||||||
// Consumed hydration `id`
|
// Consumed hydration `id`
|
||||||
let _ = children();
|
let _ = children();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
Loading…
Add table
Reference in a new issue