guise
Docs / Components
Previewrendered with guise's palette
Pro planEverything, unlimited.
$12/mo
Stack & GroupThemed spacing tokens.
PaperCardDivider

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
Note

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.