LayoutBuilder
LayoutBuilder is the layout-aware counterpart to Builder.
It gives your closure the current BoxConstraints so you can branch on available space and build a different subtree. This is the widget you reach for when responsive structure really depends on width or height, such as swapping between a one-column phone layout and a two-pane desktop layout.
Use LayoutBuilder when layout-dependent branching is the point of the component. Do not use it for every tiny spacing tweak. If a layout can stay the same with only different padding, gap, or flex values, ordinary composition is usually clearer.
Example
use fission::core::ui::{Column, Row, Text};
use fission::core::ui::widgets::builder::LayoutBuilder;
let node = LayoutBuilder::new(|_ctx, _view, constraints| {
if constraints.max_w > 720.0 {
Row {
gap: Some(24.0),
children: vec![
Text::new("Sidebar").into_node(),
Text::new("Main content").into_node(),
],
..Default::default()
}
.into_node()
} else {
Column {
gap: Some(16.0),
children: vec![
Text::new("Main content").into_node(),
Text::new("Sidebar").into_node(),
],
..Default::default()
}
.into_node()
}
})
.flex_grow(1.0)
.build(ctx, view);
Field table
| Field | Type | Meaning | Notes / default behavior |
|---|---|---|---|
LayoutBuilder::new(...) | Fn(&mut BuildCtx<S>, &View | Creates the responsive closure. | Required. The closure should stay pure and deterministic. |
id | Option<WidgetNodeId> | Stable widget identity for reading stored constraints. | Defaults to None. When present, the built child is wrapped in a Container with that id. |
flex_grow | f32 | Extra space the wrapped result can absorb. | Defaults to 0.0. Only applied when id is set and the helper wraps the result. |
flex_shrink | f32 | How much the wrapped result may shrink. | Defaults to 1.0. |
How constraint lookup works
LayoutBuilder reads constraints from the previous layout pass when it has a stable id and those constraints are available. If not, it falls back to loose constraints derived from the viewport size. That means it is responsive, but still consistent with the deterministic build model.
In plain language, you use it when the shape of the layout truly depends on space, not when you merely want to read the viewport for curiosity.
When it becomes a code smell
LayoutBuilder is powerful, but it is easy to overuse. If every branch of your app starts switching on width and emitting very different ad hoc trees, the code quickly becomes hard to reason about.
A good rule is this: use LayoutBuilder for meaningful structural breakpoints, not for general product logic. If the branching becomes large, split the layouts into named widgets and let LayoutBuilder only choose between them.
Related
Builder, Row, Column, and SimpleGrid.