GPUI Box GitHub

Components / data

Flow builder

Rows drawn by their caller, laid out only where the viewport reaches.

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

use gpui_kit::data::Flow;

Reviewed in flow.

Construct
new(ident: impl Into<Ident>, count: usize, render_row: impl Fn(usize, &mut Window, &mut App) -> AnyElement + 'static) -> Self
Options

Chain onto the value.

keys(keys: impl IntoIterator<Item = impl Into<SharedString>>) -> Self
revisions(revisions: Vec<u64>) -> Self
estimate(height: f32) -> Self
anchored_to_end() -> Self
visible_rows(rows: usize) -> Self
fills() -> Self
content_inset(top: f32, bottom: f32) -> Self
Example ยท flow
fn flow(_window: &mut Window, cx: &mut App) -> AnyElement {
    let theme = cx.theme().clone();
    stack(&theme)
        .w(px(560.0))
        .child(caption(
            &theme,
            "rows drawn by the caller, laid out only where the viewport reaches; \
             a row is as tall as what it holds",
        ))
        .child(
            div()
                .column()
                .surface(&theme, Surface::Panel)
                .radius(&theme, Radius::Card)
                .overflow_hidden()
                .child(
                    // A row is as tall as its prose, so the viewport's edge
                    // falls wherever it falls โ€” through a line of text as
                    // often as between two. The fade is what turns that from
                    // a glyph sliced in half into a statement that the entries
                    // carry on past the edge.
                    ScrollFade::new("scene.flow.edge")
                        .bottom(true)
                        .fit_height()
                        .child({
                            let theme = theme.clone();
                            div()
                                .w_full()
                                .child(
                                    Flow::new(
                                        "scene.flow.entries",
                                        FIXTURE_RECORDS,
                                        move |index, _, cx| {
                                            let (id, body) = fixture_entry(index);
                                            // A flow publishes nothing of its own, so the rows say
                                            // what they are โ€” which is the arrangement any caller
                                            // drawing its own rows ends up with.
                                            div()
                                                .w_full()
                                                .column()
                                                .gap_token(&theme, Space::Xs)
                                                .px_token(&theme, Space::Md)
                                                .py_token(&theme, Space::Sm)
                                                .child(
                                                    crate::foundation::text(
                                                        &theme,
                                                        TypeScale::Caption,
                                                        id.clone(),
                                                    )
                                                    .text_tone(&theme, TextTone::Muted),
                                                )
                                                .child(crate::foundation::text(
                                                    &theme,
                                                    TypeScale::Body,
                                                    body.clone(),
                                                ))
                                                .semantic_in(
                                                    cx,
                                                    NodeSpec::new(
                                                        format!("scene.flow.entries.{id}"),
                                                        Role::Row,
                                                    )
                                                    .parent("scene.flow.entries")
                                                    .text(body),
                                                )
                                                .into_any_element()
                                        },
                                    )
                                    .estimate(72.0)
                                    .visible_rows(FLOW_VISIBLE_ROWS),
                                )
                                .semantic_in(
                                    cx,
                                    NodeSpec::new("scene.flow.entries", Role::List)
                                        .value(FIXTURE_RECORDS.to_string()),
                                )
                        }),
                )
                .child(rule(&theme))
                // How much is past the edge, and something to do about it. A
                // count on its own states the overflow and leaves the reader
                // to find the rest by dragging.
                .child(
                    div()
                        .row()
                        .w_full()
                        .gap_token(&theme, Space::Sm)
                        .px_token(&theme, Space::Md)
                        .py_token(&theme, Space::Xs)
                        .child(caption(
                            &theme,
                            SharedString::from(format!(
                                "{} more below",
                                FIXTURE_RECORDS - FLOW_VISIBLE_ROWS
                            )),
                        ))
                        .child(div().flex_1())
                        .child(
                            Button::new("scene.flow.end")
                                .label("Go to the end")
                                .ghost()
                                .small()
                                .on_click(|window, cx| {
                                    crate::data::glide_to_row(
                                        &Ident::from("scene.flow.entries"),
                                        FIXTURE_RECORDS - 1,
                                        window,
                                        cx,
                                    );
                                }),
                        ),
                ),
        )
        .into_any_element()
}

Source: crates/gpui-kit/src/data/flow.rs