biji_ui/
custom_animated_show.rs1use std::time::Duration;
2
3use leptos::{
4 leptos_dom::{self, helpers::TimeoutHandle},
5 prelude::*,
6};
7
8#[component]
9pub fn CustomAnimatedShow(
10 children: ChildrenFn,
12 #[prop(into)]
14 when: Signal<bool>,
15 #[prop(into, optional)]
17 show_class: String,
18 #[prop(into, optional)]
20 hide_class: String,
21 hide_delay: Duration,
23) -> impl IntoView {
24 let show_handle: StoredValue<Option<TimeoutHandle>> = StoredValue::new(None);
25 let hide_handle: StoredValue<Option<TimeoutHandle>> = StoredValue::new(None);
26 let cls = RwSignal::new(if when.get_untracked() {
27 show_class.clone()
28 } else {
29 hide_class.clone()
30 });
31 let show = RwSignal::new(when.get_untracked());
32
33 let eff = RenderEffect::new(move |_| {
34 let show_class = show_class.clone();
35 if when.get() {
36 if let Some(h) = show_handle.get_value() {
38 h.clear();
39 }
40 if let Some(h) = hide_handle.get_value() {
41 h.clear();
42 }
43
44 let h = leptos_dom::helpers::set_timeout_with_handle(
45 move || cls.set(show_class.clone()),
46 Duration::from_millis(1),
47 )
48 .expect("set timeout in AnimatedShow");
49 show_handle.set_value(Some(h));
50
51 cls.set(hide_class.clone());
52 show.set(true);
53 } else {
54 cls.set(hide_class.clone());
55
56 let h =
57 leptos_dom::helpers::set_timeout_with_handle(move || show.set(false), hide_delay)
58 .expect("set timeout in AnimatedShow");
59 hide_handle.set_value(Some(h));
60 }
61 });
62
63 on_cleanup(move || {
64 if let Some(Some(h)) = show_handle.try_get_value() {
65 h.clear();
66 }
67 if let Some(Some(h)) = hide_handle.try_get_value() {
68 h.clear();
69 }
70 drop(eff);
71 });
72
73 view! {
74 <Show when={move || show.get()} fallback={|| ()}>
75 <div class={move || cls.get()}>{children()}</div>
76 </Show>
77 }
78}