GPUI Box GitHub

Components / display

AnimatedNumber builder

A numeric readout that animates between values.

A builder is RenderOnce. Construct and mount it in one expression.

use gpui_kit::display::animated_number::AnimatedNumber;

Reviewed in animated-number.

Construct
new(ident: impl Into<Ident>, value: f64) -> Self
Options

Chain onto the value.

format(format: impl Fn(f64) -> String + 'static) -> Self
spec(spec: MotionSpec) -> Self
type_scale(scale: TypeScale) -> Self
Example · animated-number
fn animated_number(_window: &mut Window, cx: &mut App) -> AnyElement {
    if !cx.has_global::<SceneCounts>() {
        cx.set_global(SceneCounts {
            runs: 1204.0,
            seconds: 18.4,
        });
    }
    let counts = cx.global::<SceneCounts>();
    let (runs, seconds) = (counts.runs, counts.seconds);
    let theme = cx.theme().clone();

    // A readout is a reading, so it is drawn as one: the same card, caption
    // and hierarchy a KPI gets. A number floating on the canvas beside its
    // label is a debug print of the value, not a report of it.
    let readout = |label: &'static str, detail: &'static str, number: AnimatedNumber| {
        div()
            .column()
            .flex_1()
            .min_w_0()
            .gap(px(theme.space(Space::Xs)))
            .p(px(theme.space(Space::Md)))
            .card_surface(&theme, CardVariant::Filled)
            .child(
                crate::foundation::text(&theme, TypeScale::Caption, label)
                    .text_tone(&theme, TextTone::Muted),
            )
            .child(number)
            .child(
                crate::foundation::text(&theme, TypeScale::Caption, detail)
                    .text_tone(&theme, TextTone::Faint),
            )
    };

    stack(&theme)
        .w(px(520.0))
        .child(caption(
            &theme,
            "the published value is the target, from the frame it changes",
        ))
        .child(
            div()
                .row()
                .items_stretch()
                .w_full()
                .gap(px(theme.space(Space::Md)))
                .child(readout(
                    "Runs this week",
                    "counted by the host",
                    AnimatedNumber::new("scene.number.runs", runs)
                        .format(grouped)
                        .type_scale(TypeScale::Title),
                ))
                .child(readout(
                    "Median duration",
                    "one decimal, the host's choice",
                    AnimatedNumber::new("scene.number.seconds", seconds)
                        .format(|value| format!("{value:.1}s"))
                        .type_scale(TypeScale::Title),
                )),
        )
        .child(
            div().row().child(
                Button::new("scene.number.recount")
                    .label("Recount")
                    .on_click(|_, cx| {
                        cx.update_global::<SceneCounts, ()>(|counts, _| {
                            counts.runs += 318.0;
                            counts.seconds += 4.7;
                        });
                        cx.refresh_windows();
                    }),
            ),
        )
        .into_any_element()
}

Source: crates/gpui-kit/src/display/animated_number.rs