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 #[prop(into, optional)]
25 style: String,
26) -> impl IntoView {
27 let show_handle: StoredValue<Option<TimeoutHandle>> = StoredValue::new(None);
28 let hide_handle: StoredValue<Option<TimeoutHandle>> = StoredValue::new(None);
29 let cls = RwSignal::new(if when.get_untracked() {
30 show_class.clone()
31 } else {
32 hide_class.clone()
33 });
34 let show = RwSignal::new(when.get_untracked());
35
36 let eff = RenderEffect::new(move |_| {
37 let show_class = show_class.clone();
38 if when.get() {
39 if let Some(h) = show_handle.get_value() {
41 h.clear();
42 }
43 if let Some(h) = hide_handle.get_value() {
44 h.clear();
45 }
46
47 let h = leptos_dom::helpers::set_timeout_with_handle(
48 move || cls.set(show_class.clone()),
49 Duration::from_millis(1),
50 )
51 .expect("set timeout in AnimatedShow");
52 show_handle.set_value(Some(h));
53
54 cls.set(hide_class.clone());
55 show.set(true);
56 } else {
57 cls.set(hide_class.clone());
58
59 let h =
60 leptos_dom::helpers::set_timeout_with_handle(move || show.set(false), hide_delay)
61 .expect("set timeout in AnimatedShow");
62 hide_handle.set_value(Some(h));
63 }
64 });
65
66 on_cleanup(move || {
67 if let Some(Some(h)) = show_handle.try_get_value() {
68 h.clear();
69 }
70 if let Some(Some(h)) = hide_handle.try_get_value() {
71 h.clear();
72 }
73 drop(eff);
74 });
75
76 view! {
77 <Show when={move || show.get()} fallback={|| ()}>
78 <div class={move || cls.get()} style={style.clone()}>
79 {children()}
80 </div>
81 </Show>
82 }
83}