bezel

Components / Layout & organisation

Group box

Markdown crates/ui/src/widgets/scaffolding.rs docs.rs

use ui::{icons, widgets::Scaffolding};

theme
    .group_box()
    .child(
        theme
            .card_row(true)
            .child(theme.row_icon(icons::glyph::Monitor))
            .child(theme.row_title("Appearance")),
    )
    .child(
        theme
            .card_row(false)
            .child(theme.row_icon(icons::glyph::Folder))
            .child(theme.row_title("Storage")),
    )

first suppresses the top hairline on the opening row — CSS writes that as first:border-t-0, and gpui has no sibling selectors.

Page rhythm

theme.page_column()
    .child(theme.page_header("Devices", Some(3)))
    .child(theme.page_subtitle("Signed in on three machines."))
    .child(theme.field_label("Theme"))

API

pub trait Scaffolding: ThemeExt {
    /// The plate. Fill is `Theme::card_glass_bg` — the opaque card tone,
    /// thinned to a tint over glass.
    fn group_box(&self) -> Div;

    /// One row, split from the one above by a hairline.
    fn card_row(&self, first: bool) -> Div;

    /// The leading glyph, sized to the text beside it.
    fn row_icon(&self, icon: impl Into<Icon>) -> Div;

    /// Clipped rather than ellipsised, which keeps it in gpui's measure cache.
    fn row_title(&self, title: impl Into<SharedString>) -> Div;

    /// The quiet second line, joined by dots.
    fn meta_line(&self, fragments: Vec<AnyElement>) -> Div;

    // The rhythm around the card.
    fn page_column(&self) -> Div;
    fn page_header(&self, title: impl Into<SharedString>, count: Option<usize>) -> Div;
    fn page_subtitle(&self, copy: impl Into<SharedString>) -> Div;
    fn field_label(&self, label: impl Into<SharedString>) -> Div;

    /// A preview frame carrying the selection ring. The preview must round
    /// itself to `OPTION_CARD_RADIUS`.
    fn option_card(
        &self,
        label: impl Into<SharedString>,
        selected: bool,
        preview: AnyElement,
    ) -> Div;

    // ...
}

Hover is caller-owned — gpui panics on a second hover, so the wash to chain is Theme::element_hover.

Group box