GPUI Box GitHub

Components / display

ListRow builder

One row inside a Card.

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

use gpui_kit::display::card::ListRow;

Reviewed in card.

Also drawn by motion-flip, which arranges components rather than reviewing them.

Construct
new() -> Self
Options

Chain onto the value.

id(ident: impl Into<Ident>) -> Self
leading(leading: impl IntoElement) -> Self
trailing(trailing: impl IntoElement) -> Self
on_click(handler: impl Fn(&mut Window, &mut App) + 'static) -> Self
Example · card
fn card(_window: &mut Window, cx: &mut App) -> AnyElement {
    let theme = cx.theme().clone();
    let label = |content: &'static str| {
        div()
            .flex_1()
            .min_w_0()
            .child(crate::foundation::text(&theme, TypeScale::Label, content))
    };
    let caption = |content: &'static str| {
        crate::foundation::text(&theme, TypeScale::Caption, content)
            .text_tone(&theme, TextTone::Muted)
    };
    let column = |card: Card| div().flex_1().min_w_0().child(card);

    stack(&theme)
        .child(
            Card::new()
                .id("scene.card")
                .header(
                    CardHeader::new("Workspace services")
                        .subtitle("Four checked a moment ago")
                        .action(|_window, _cx| {
                            Button::new("scene.card.refresh")
                                .label("Refresh")
                                .secondary()
                                .small()
                                .into_any_element()
                        }),
                )
                .child(
                    ListRow::new()
                        .id("scene.card.runtime")
                        .leading(StatusDot::new(Tone::Success))
                        .child(label("Native runtime"))
                        .trailing(Badge::new("Ready").success()),
                )
                .child(
                    ListRow::new()
                        .id("scene.card.catalog")
                        .leading(StatusDot::new(Tone::Warning))
                        .child(label("Model catalog"))
                        .trailing(Badge::new("Stale").warning()),
                )
                .child(
                    ListRow::new()
                        .id("scene.card.index")
                        .selected(true)
                        .leading(StatusDot::new(Tone::Success))
                        .child(label("Search index"))
                        .trailing(Badge::new("Ready").success()),
                )
                .child(
                    ListRow::new()
                        .id("scene.card.telemetry")
                        .disabled(true)
                        .leading(StatusDot::new(Tone::Neutral))
                        .child(label("Telemetry export"))
                        .trailing(Badge::new("Off")),
                )
                .footer(|_window, cx| {
                    let theme = cx.theme().clone();
                    div()
                        .row()
                        .w_full()
                        .gap(px(theme.spacing.sm))
                        .child(
                            Button::new("scene.card.restart")
                                .label("Restart all")
                                .secondary()
                                .small(),
                        )
                        .child(div().flex_1())
                        .child(
                            crate::foundation::text(&theme, TypeScale::Caption, "4 services")
                                .text_tone(&theme, TextTone::Faint),
                        )
                        .into_any_element()
                }),
        )
        .child(
            row(&theme)
                .items_start()
                .child(column(
                    Card::new()
                        .id("scene.card.elevated")
                        .variant(CardVariant::Elevated)
                        .padding(Space::Lg)
                        .child(crate::foundation::text(
                            &theme,
                            TypeScale::Strong,
                            "Elevated",
                        ))
                        .child(caption("A shadow. One card on a page.")),
                ))
                .child(column(
                    Card::new()
                        .id("scene.card.filled")
                        .variant(CardVariant::Filled)
                        .padding(Space::Lg)
                        .child(crate::foundation::text(&theme, TypeScale::Strong, "Filled"))
                        .child(caption("A tonal plane for a dense grid.")),
                ))
                .child(column(
                    Card::new()
                        .id("scene.card.ghost")
                        .variant(CardVariant::Ghost)
                        .padding(Space::Lg)
                        .child(crate::foundation::text(&theme, TypeScale::Strong, "Ghost"))
                        .child(caption("Neither. Structure without a plane.")),
                )),
        )
        .child(
            row(&theme)
                .items_start()
                .child(column(
                    Card::new()
                        .id("scene.card.actionable")
                        .padding(Space::Lg)
                        .on_click(|_window, _cx| {})
                        .header(CardHeader::new("Open the run").subtitle("The whole card acts"))
                        .child(caption("Enter and space reach it from the keyboard.")),
                ))
                .child(column(
                    // The pairing the rows above never put together, which is
                    // how a card with no plane came to be lifted off one.
                    Card::new()
                        .id("scene.card.actionable-ghost")
                        .variant(CardVariant::Ghost)
                        .padding(Space::Lg)
                        .on_click(|_window, _cx| {})
                        .header(CardHeader::new("Open the line").subtitle("A ghost card acts too"))
                        .child(caption("No plane to rise off, so the pointer gets a wash.")),
                ))
                .child(column(
                    Card::new()
                        .id("scene.card.chosen")
                        .padding(Space::Lg)
                        .selected(true)
                        .header(CardHeader::new("Selected").subtitle("A stronger material wash"))
                        .child(caption(
                            "Fill carries selection without moving the content.",
                        )),
                ))
                .child(column(
                    Card::new()
                        .id("scene.card.unavailable")
                        .padding(Space::Lg)
                        .disabled(true)
                        .on_click(|_window, _cx| {})
                        .header(CardHeader::new("Unavailable").subtitle("Says so, and stays read"))
                        .child(caption("A disabled card installs no handler at all.")),
                )),
        )
        .into_any_element()
}

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