glassy_ui/motion/
stagger.rs1use std::time::Duration;
2
3use gpui::{
4 div, AnyElement, App, IntoElement, ParentElement, RenderOnce, SharedString, StyleRefinement,
5 Styled, Window,
6};
7
8use super::component::Motion;
9use super::slot::StyledSlot;
10use super::style::MotionStyle;
11use super::transition::Transition;
12
13#[derive(IntoElement, Default)]
26pub struct Stagger {
27 style: StyleRefinement,
28 transition: Transition,
29 motions: Vec<Motion>,
30 children: Vec<AnyElement>,
31}
32
33impl Stagger {
34 pub fn new() -> Self {
35 Self {
36 style: StyleRefinement::default(),
37 transition: Transition::spring()
38 .delay_children(Duration::from_millis(30))
39 .stagger_children(Duration::from_millis(55)),
40 motions: Vec::new(),
41 children: Vec::new(),
42 }
43 }
44
45 pub fn transition(mut self, transition: Transition) -> Self {
46 self.transition = transition;
47 self
48 }
49
50 pub fn motion(mut self, motion: Motion) -> Self {
52 self.motions.push(motion);
53 self
54 }
55}
56
57impl Styled for Stagger {
58 fn style(&mut self) -> &mut StyleRefinement {
59 &mut self.style
60 }
61}
62
63impl ParentElement for Stagger {
64 fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
65 self.children.extend(elements);
66 }
67}
68
69impl RenderOnce for Stagger {
70 fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
71 let base_delay = self.transition.delay_children;
72 let stagger = self.transition.stagger_children;
73 let child_transition = self.transition.clone();
74
75 div()
76 .refine_style(&self.style)
77 .children(self.motions.into_iter().enumerate().map(|(index, motion)| {
78 let delay = base_delay + stagger * (index as u32);
79 let transition = child_transition.clone().with_extra_delay(delay);
80 motion.transition(transition).into_any_element()
81 }))
82 .children(self.children)
83 }
84}
85
86#[allow(dead_code)]
88pub fn stagger_item(id: impl Into<SharedString>, _style: MotionStyle) -> Motion {
89 Motion::new().id(id).fade_up()
90}