use leptos::component;
use leptos_dom::{Fragment, IntoView};
use leptos_reactive::{create_memo, signal_prelude::*, Scope, ScopeDisposer};
use std::{cell::RefCell, rc::Rc};
#[cfg_attr(
any(debug_assertions, feature = "ssr"),
tracing::instrument(level = "info", skip_all)
)]
#[component]
pub fn Show<F, W, IV>(
cx: Scope,
children: Box<dyn Fn(Scope) -> Fragment>,
when: W,
fallback: F,
) -> impl IntoView
where
W: Fn() -> bool + 'static,
F: Fn(Scope) -> IV + 'static,
IV: IntoView,
{
let memoized_when = create_memo(cx, move |_| when());
let prev_disposer = Rc::new(RefCell::new(None::<ScopeDisposer>));
move || {
if let Some(disposer) = prev_disposer.take() {
disposer.dispose();
}
let (view, disposer) =
cx.run_child_scope(|cx| match memoized_when.get() {
true => children(cx).into_view(cx),
false => fallback(cx).into_view(cx),
});
*prev_disposer.borrow_mut() = Some(disposer);
view
}
}