fix: Teleport component cleanup

This commit is contained in:
luoxiao 2023-11-11 11:49:47 +08:00
parent 7b44974533
commit f5e6eae558
2 changed files with 28 additions and 23 deletions

View file

@ -158,20 +158,19 @@ fn FollowerContainer<El: ElementDescriptor + Clone + 'static>(
} }
is_show is_show
}); });
let children = html::div()
.classes("thaw-binder-follower-container")
.style("display", move || (!is_show.get()).then_some("none"))
.child(
html::div()
.classes("thaw-binder-follower-content")
.node_ref(content_ref)
.attr("style", move || content_style.get())
.child(children()),
);
view! { view! {
<Teleport> <Teleport element=children />
<div class="thaw-binder-follower-container" style=move || {
if is_show.get() {
""
} else {
"display: none;"
}
}>
<div class="thaw-binder-follower-content" ref=content_ref style=move || content_style.get()>
{children()}
</div>
</div>
</Teleport>
} }
} }

View file

@ -1,30 +1,36 @@
use cfg_if::cfg_if; use cfg_if::cfg_if;
use leptos::*; 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(into, optional)] mount: Option<web_sys::Element>, #[prop(into, optional)] mount: Option<web_sys::Element>,
children: Children, #[prop(optional, into)] element: Option<HtmlElement<AnyElement>>,
#[prop(optional)] children: Option<Children>,
) -> impl IntoView { ) -> impl IntoView {
cfg_if! { if #[cfg(target_arch = "wasm32")] { cfg_if! { if #[cfg(target_arch = "wasm32")] {
use leptos::{ use leptos::wasm_bindgen::JsCast;
wasm_bindgen::JsCast,
leptos_dom::Mountable
};
let mount = mount.unwrap_or_else(|| { let mount = mount.unwrap_or_else(|| {
document() document()
.body() .body()
.expect("body element not to exist") .expect("body element not to exist")
.unchecked_into() .unchecked_into()
}); });
let node = children().into_view();
let node = node.get_mountable_node(); let render_root = if let Some(element) = element {
_ = mount.append_child(&node); element
} else if let Some(children) = children {
html::div().child(children()).into_any()
} else {
return;
};
_ = mount.append_child(&render_root);
on_cleanup(move || { on_cleanup(move || {
_ = mount.remove_child(&node); _ = mount.remove_child(&render_root);
}); });
} else { } else {
_ = mount; _ = mount;
_ = element;
_ = children; _ = children;
}} }}
} }