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