4.3k

Card

card is the bordered, elevated surface container. It is a stacking container — children layer on top of each other and gap is rejected — so put a single column (or row) inside for flow. Cards carry 24px of content padding by default (the house inset; 16 at size="sm") — set padding explicitly to override it. Binding on-press makes the whole surface pressable, the list-of-cards pattern. For the plain surface with the same stacking contract, see panel.

card
A card rendered by the engine (light theme)

Markup

<card width="340">
  <column gap="12">
    <text>Deploy your app</text>
    <text wrap="true" foreground="text_muted">The runtime packages your views, commands, and assets into one native binary.</text>
    <row gap="8">
      <button variant="primary" on-press="deploy">Deploy</button>
      <button variant="ghost" on-press="cancel">Cancel</button>
    </row>
  </column>
</card>

Zig builder

ui.el(.card, .{ .width = 340 }, .{
    ui.column(.{ .gap = 12 }, .{
        ui.text(.{}, "Deploy your app"),
        ui.text(.{ .wrap = true, .style_tokens = .{ .foreground = .text_muted } }, "The runtime packages your views, commands, and assets into one native binary."),
        ui.row(.{ .gap = 8 }, .{
            ui.button(.{ .variant = .primary, .on_press = .deploy }, "Deploy"),
            ui.button(.{ .variant = .ghost, .on_press = .cancel }, "Cancel"),
        }),
    }),
})

Attributes

AttributeDescription
textText value for text-bearing elements; a literal or one {binding}.
paddingUniform padding (plain number).
widthDefinite width (plain number): the element is exactly this wide; content neither shrinks nor overflows it. On resizable it is the initial width.
on-pressDispatch a Msg on press: tag or tag:{payload}. Legal on any element — a bound press handler makes it pressable, and presses on plain text/icons inside it fall through to it (dragging still selects text).