gpui_component/
skeleton.rs

1use crate::{ActiveTheme, StyledExt};
2use gpui::{
3    bounce, div, ease_in_out, Animation, AnimationExt, IntoElement, RenderOnce, StyleRefinement,
4    Styled,
5};
6use std::time::Duration;
7
8/// A skeleton loading placeholder element.
9#[derive(IntoElement)]
10pub struct Skeleton {
11    style: StyleRefinement,
12    secondary: bool,
13}
14
15impl Skeleton {
16    /// Create a new Skeleton element.
17    pub fn new() -> Self {
18        Self {
19            style: StyleRefinement::default(),
20            secondary: false,
21        }
22    }
23
24    /// Set use secondary color.
25    pub fn secondary(mut self) -> Self {
26        self.secondary = true;
27        self
28    }
29}
30
31impl Styled for Skeleton {
32    fn style(&mut self) -> &mut gpui::StyleRefinement {
33        &mut self.style
34    }
35}
36
37impl RenderOnce for Skeleton {
38    fn render(self, _: &mut gpui::Window, cx: &mut gpui::App) -> impl IntoElement {
39        div()
40            .w_full()
41            .h_4()
42            .bg(if self.secondary {
43                cx.theme().skeleton.opacity(0.5)
44            } else {
45                cx.theme().skeleton
46            })
47            .refine_style(&self.style)
48            .with_animation(
49                "skeleton",
50                Animation::new(Duration::from_secs(2))
51                    .repeat()
52                    .with_easing(bounce(ease_in_out)),
53                move |this, delta| {
54                    let v = 1.0 - delta * 0.5;
55                    this.opacity(v)
56                },
57            )
58    }
59}