1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use leptos::component;
use leptos_dom::{Fragment, IntoView};
use leptos_reactive::{create_memo, signal_prelude::*, Scope};

/// A component that will show its children when the `when` condition is `true`,
/// and show the fallback when it is `false`, without rerendering every time
/// the condition changes.
///
/// *Note*: Because of the nature of generic arguments, it’s not really possible
/// to make the `fallback` optional. If you want an empty fallback state—in other
/// words, if you want to show the children if `when` is true and noting otherwise—use
/// `fallback=|_| ()` (i.e., a fallback function that returns the unit type `()`).
///
/// ```rust
/// # use leptos_reactive::*;
/// # use leptos_macro::*;
/// # use leptos_dom::*; use leptos::*;
/// # run_scope(create_runtime(), |cx| {
/// let (value, set_value) = create_signal(cx, 0);
///
/// view! { cx,
///   <Show
///     when=move || value() < 5
///     fallback=|cx| view! { cx, "Big number!" }
///   >
///     "Small number!"
///   </Show>
/// }
/// # });
/// ```
#[component]
pub fn Show<F, W, IV>(
    /// The scope the component is running in
    cx: Scope,
    /// The components Show wraps
    children: Box<dyn Fn(Scope) -> Fragment>,
    /// A closure that returns a bool that determines whether this thing runs
    when: W,
    /// A closure that returns what gets rendered if the when statement is false
    fallback: F,
) -> impl IntoView
where
    W: Fn() -> bool + 'static,
    F: Fn(Scope) -> IV + 'static,
    IV: IntoView,
{
    let memoized_when = create_memo(cx, move |_| when());

    move || match memoized_when.get() {
        true => children(cx).into_view(cx),
        false => fallback(cx).into_view(cx),
    }
}