Skip to main content

yggdrasil/components/skeletons/
delayed_skeleton.rs

1//! 延迟骨架屏包装组件
2//!
3//! 200ms 内完全不渲染骨架屏,避免快速加载时骨架屏一闪而过;
4//! 超过 200ms 后渲染骨架屏并带有 pulse 动画,提示正在加载。
5
6use crate::utils::time::sleep_ms;
7use dioxus::prelude::*;
8
9/// 骨架屏显示延迟(毫秒)。
10///
11/// 加载时间低于此值时完全不显示骨架屏,避免闪烁。
12const SKELETON_DELAY_MS: u32 = 200;
13
14/// 延迟渲染的骨架屏包装组件。
15///
16/// 前 `SKELETON_DELAY_MS` 毫秒内不渲染任何内容;
17/// 超过延迟后渲染子元素并启动 pulse 动画。
18///
19/// 快加载(< 200ms):组件在渲染前就被卸载,用户完全看不到骨架屏。
20/// 慢加载:骨架屏正常显示并 pulse,提示正在加载。
21/// `pulse = false` 可保留延迟、关闭外层呼吸动画,供自带扫光的骨架使用。
22#[component]
23pub fn DelayedSkeleton(children: Element, #[props(default = true)] pulse: bool) -> Element {
24    let mut visible = use_signal(|| false);
25
26    use_effect(move || {
27        spawn(async move {
28            sleep_ms(SKELETON_DELAY_MS).await;
29            visible.set(true);
30        });
31    });
32
33    if visible() {
34        rsx! {
35            div { class: if pulse { "animate-pulse" } else { "" }, {children} }
36        }
37    } else {
38        rsx! {}
39    }
40}