|
1 | 1 | use crate::{
|
2 | 2 | children::{TypedChildrenFn, ViewFn},
|
3 |
| - prelude::{FunctionMarker, SignalMarker}, |
4 | 3 | IntoView,
|
5 | 4 | };
|
6 | 5 | use leptos_macro::component;
|
7 | 6 | use reactive_graph::{computed::ArcMemo, traits::Get};
|
8 |
| -use std::{marker::PhantomData, sync::Arc}; |
9 | 7 | use tachys::either::Either;
|
10 | 8 |
|
11 |
| -/// Shows its children whenever the condition `when` prop is `true`. |
12 |
| -/// Otherwise it renders the `fallback` prop, which defaults to the empty view. |
13 |
| -/// |
14 |
| -/// The prop `when` can be a closure that returns a bool, a signal of type bool, or a boolean value. |
15 |
| -/// |
16 |
| -/// ## Usage |
17 |
| -/// |
18 |
| -/// ``` |
19 |
| -/// # use leptos::prelude::*; |
20 |
| -/// # |
21 |
| -/// # #[component] |
22 |
| -/// # pub fn Demo() -> impl IntoView { |
23 |
| -/// let (condition, set_condition) = signal(true); |
24 |
| -/// |
25 |
| -/// view! { |
26 |
| -/// <Show when=condition> |
27 |
| -/// <p>"Hello, world!"</p> |
28 |
| -/// </Show> |
29 |
| -/// } |
30 |
| -/// # } |
31 |
| -/// ``` |
32 |
| -/// |
33 |
| -/// Or with a closure as the `when` condition: |
34 |
| -/// |
35 |
| -/// ``` |
36 |
| -/// # use leptos::prelude::*; |
37 |
| -/// # |
38 |
| -/// # #[component] |
39 |
| -/// # pub fn Demo() -> impl IntoView { |
40 |
| -/// let (condition, set_condition) = signal(true); |
41 |
| -/// |
42 |
| -/// view! { |
43 |
| -/// <Show when=move || condition.get()> |
44 |
| -/// <p>"Hello, world!"</p> |
45 |
| -/// </Show> |
46 |
| -/// } |
47 |
| -/// # } |
48 |
| -/// ``` |
49 | 9 | #[component]
|
50 |
| -pub fn Show<M, C>( |
| 10 | +pub fn Show<W, C>( |
51 | 11 | /// The children will be shown whenever the condition in the `when` closure returns `true`.
|
52 | 12 | children: TypedChildrenFn<C>,
|
53 |
| - /// When true the children are shown, otherwise the fallback. |
54 |
| - /// It accepts a closure that returns a boolean value as well as a boolean signal or plain boolean value. |
55 |
| - when: impl IntoCondition<M>, |
| 13 | + /// A closure that returns a bool that determines whether this thing runs |
| 14 | + when: W, |
56 | 15 | /// A closure that returns what gets rendered if the when statement is false. By default this is the empty view.
|
57 | 16 | #[prop(optional, into)]
|
58 | 17 | fallback: ViewFn,
|
59 |
| - |
60 |
| - /// Marker for generic parameters. Ignore this. |
61 |
| - #[prop(optional)] |
62 |
| - _marker: PhantomData<M>, |
63 | 18 | ) -> impl IntoView
|
64 | 19 | where
|
| 20 | + W: Fn() -> bool + Send + Sync + 'static, |
65 | 21 | C: IntoView + 'static,
|
66 | 22 | {
|
67 |
| - let when = when.into_condition(); |
68 |
| - let memoized_when = ArcMemo::new(move |_| when.run()); |
| 23 | + let memoized_when = ArcMemo::new(move |_| when()); |
69 | 24 | let children = children.into_inner();
|
70 | 25 |
|
71 | 26 | move || match memoized_when.get() {
|
72 | 27 | true => Either::Left(children()),
|
73 | 28 | false => Either::Right(fallback.run()),
|
74 | 29 | }
|
75 | 30 | }
|
76 |
| - |
77 |
| -/// A closure that returns a bool. Can be converted from a closure, a signal, or a boolean value. |
78 |
| -pub struct Condition(Arc<dyn Fn() -> bool + Send + Sync + 'static>); |
79 |
| - |
80 |
| -impl Condition { |
81 |
| - /// Evaluates the condition and returns its result. |
82 |
| - pub fn run(&self) -> bool { |
83 |
| - (self.0)() |
84 |
| - } |
85 |
| -} |
86 |
| - |
87 |
| -/// Trait to convert various types into a `Condition`. |
88 |
| -/// Implemented for closures, signals, and boolean values. |
89 |
| -pub trait IntoCondition<M> { |
90 |
| - /// Does the conversion |
91 |
| - fn into_condition(self) -> Condition; |
92 |
| -} |
93 |
| - |
94 |
| -impl<S> IntoCondition<SignalMarker> for S |
95 |
| -where |
96 |
| - S: Get<Value = bool> + Send + Sync + 'static, |
97 |
| -{ |
98 |
| - fn into_condition(self) -> Condition { |
99 |
| - Condition(Arc::new(move || self.get())) |
100 |
| - } |
101 |
| -} |
102 |
| - |
103 |
| -impl<F> IntoCondition<FunctionMarker> for F |
104 |
| -where |
105 |
| - F: Fn() -> bool + Send + Sync + 'static, |
106 |
| -{ |
107 |
| - fn into_condition(self) -> Condition { |
108 |
| - Condition(Arc::new(self)) |
109 |
| - } |
110 |
| -} |
111 |
| - |
112 |
| -impl IntoCondition<Condition> for Condition { |
113 |
| - fn into_condition(self) -> Condition { |
114 |
| - self |
115 |
| - } |
116 |
| -} |
0 commit comments