gpui-kit GitHub

Scenes

motion-flip

Builds Badge Button Card ListRow

motion-flip in the dark theme
studio-dark
motion-flip in the light theme
studio-light

The code that drew it

A still frame holds a repeating animation at its first frame and a one-shot at its last, because a still of a moving thing is not reproducible. Run the gallery to review motion.

fn motion_flip(window: &mut Window, cx: &mut App) -> AnyElement {
    if !cx.has_global::<SceneQueue>() {
        cx.set_global(SceneQueue {
            steps: vec![
                ("render", "Render frames"),
                ("upload", "Upload artifacts"),
                ("verify", "Verify checksums"),
                ("publish", "Publish release"),
            ],
        });
    }
    let steps = cx.global::<SceneQueue>().steps.clone();
    let theme = cx.theme().clone();

    let mut queue = Card::new().id("scene.motion.queue");
    for (index, (id, label)) in steps.iter().enumerate() {
        let ident = format!("scene.motion.{id}");
        let handle = flip(ident.clone(), cx);
        queue = queue.child(
            ListRow::new()
                .id(ident)
                .child(div().flex_1().child(*label))
                .child(Badge::new(format!("{}", index + 1)).neutral())
                .flip(&handle, window, cx),
        );
    }

    stack(&theme)
        .w(px(420.0))
        .child(
            row(&theme).child(
                Button::new("scene.motion.reorder")
                    .label("Move the last step first")
                    .secondary()
                    .on_click(|_, cx| {
                        cx.update_global::<SceneQueue, ()>(|queue, _| queue.steps.rotate_right(1));
                        cx.refresh_windows();
                    }),
            ),
        )
        .child(queue)
        .child(
            div()
                .text_size(px(theme.typography.caption.size))
                .text_color(theme.colors.text_muted)
                .child("Rows land in their new slot at once and slide into it."),
        )
        .into_any_element()
}