Layout (themed)
The guise::layout components use the theme's spacing tokens. They cover the
common cases; for a full Flutter-style box model see Flex layout, and
for terse construction see Layout macros.
All container components implement ParentElement, so .child(...) /
.children(...) work.
Stack
A vertical flex column with token-based spacing.
Stack::new()
.gap(Size::Md)
.align(Align::Stretch)
.child(Title::new("Heading").order(3))
.child(Text::new("Body").dimmed())
| Method | Default |
|---|---|
gap(Size) |
Md |
align(Align) |
Stretch |
justify(Justify) |
Start |
Group
A horizontal flex row.
Group::new()
.justify(Justify::Between)
.child(Title::new("Title").order(4))
.child(Button::new("more", "More"))
| Method | Default |
|---|---|
gap(Size) |
Md |
align(Align) |
Center |
justify(Justify) |
Start |
wrap(bool) |
true |
grow(bool) |
false — stretch children to share width |
Center
Centers its children on both axes.
Center::new().child(Loader::new())
inline(bool) (default false) shrinks to content instead of filling the parent.
Space
A fixed gap on one axis, sized by the theme spacing scale — for the places a
parent gap doesn't cover.
Stack::new()
.child(Title::new("Heading").order(3))
.child(Space::y(Size::Md))
.child(Text::new("Body copy."))
Methods: Space::x(Size) (horizontal, for rows), Space::y(Size) (vertical,
for columns). The block is flex_none, so flex parents never squash it.
Align & Justify enums
pub enum Align { Start, Center, End, Stretch }
pub enum Justify { Start, Center, End, Between, Around }
SimpleGrid
Equal-width columns that wrap into rows. gpui's flexbox has no CSS-grid track
system, so this lays children out as a column of flex rows, each holding up to
cols equal-weight cells (the final short row is padded so columns stay aligned).
Implements ParentElement.
SimpleGrid::new(3)
.spacing(Size::Md)
.child(card_a)
.child(card_b)
.child(card_c)
.child(card_d)
Methods: new(cols), spacing(Size) (default Md).
Container
A centered column with a capped width — Mantine's Container, for readable
line lengths on any window width. Implements ParentElement.
Container::new()
.size(Size::Sm)
.padding(Size::Md)
.child(Title::new("Article").order(2))
.child(Text::new("Readable line lengths on any window width."))
| Method | Default | Notes |
|---|---|---|
size(Size) |
Md |
max width: Xs..Xl → 540 / 720 / 960 / 1140 / 1320 px |
padding(Size) |
Md |
horizontal padding inside the capped column |
guise::layout::Container intentionally shares its name with
guise::flex::Container, the Flutter-style pixel box — one more
reason flex is not glob-exported. If both are in scope, name this one as
guise::layout::Container.
ScrollArea
A bounded, scrollable container — desktop UIs scroll, but most builders assume
their content fits. Each instance needs a unique id so gpui can track its scroll
offset. Implements ParentElement.
ScrollArea::new("log")
.max_height(240.0)
.children(rows)
Methods: new(id), max_height(f32), horizontal(bool) (scroll the x axis
instead).
Paper
A raised surface: themed background, radius, padding, optional border and shadow.
Paper::new()
.padding(Size::Lg)
.radius(Size::Md)
.with_border(true)
.shadow(Size::Sm)
.child(content)
| Method | Default |
|---|---|
padding(Size) |
Md |
radius(Size) |
theme default |
with_border(bool) |
false |
shadow(Size) |
none |
Card
A Paper preset: bordered, padded, lightly raised, column layout.
Card::new().child(
Stack::new().gap(Size::Sm).child(Title::new("Title").order(4)).child(body),
)
Defaults: padding Lg, radius Md, with_border true, shadow Sm.
Same setter methods as Paper.
Divider
A separating line; horizontal by default.
Divider::new() // full-width hairline
Divider::new().label("Section") // centered label
Divider::vertical() // 1px tall divider for rows
Orientation is Horizontal | Vertical.
AppShell
The application frame: header, navbar, aside, and footer regions around a
scrollable main area. Regions take a fixed px size plus a content closure
re-invoked every render (live data, like Tabs panels); the main area is the
shell's children, laid out as a scrollable column. The shell fills its parent —
place it at the window root (or inside a sized box for a framed demo). Regions
get the theme surface background and a hairline border on their inner edge.
Implements ParentElement for the main area.
AppShell::new()
.header(48.0, |_window, _cx| Text::new("guise"))
.navbar(220.0, |_window, _cx| Text::new("nav links"))
.footer(28.0, |_window, _cx| Text::new("status").size(Size::Xs))
.child(Title::new("Main content").order(2))
| Method | Default | Notes |
|---|---|---|
header(f32, closure) |
none | height in px; full width, top |
navbar(f32, closure) |
none | width in px; left column |
aside(f32, closure) |
none | width in px; right column |
footer(f32, closure) |
none | height in px; full width, bottom |
Region closures take (&mut Window, &mut App) and return any IntoElement.
Every region is a flex column with overflow_hidden, so oversized content
clips instead of breaking the frame.