Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.metabind.ai/llms.txt

Use this file to discover all available pages before exploring further.

These layout containers extend the core stack primitives with two-dimensional and adaptive behavior, and are currently iOS-only. Grid arranges children in a row-and-column matrix, with GridRow defining each row. ViewThatFits picks the first of several alternative layouts that fits the available space, useful for responsive designs without a manual geometry reader.

Grid

Arranges children in a two-dimensional grid of rows and columns.
Grid(children: Component[]): Component;
Grid(props: { alignment?: Alignment; horizontalSpacing?: number; verticalSpacing?: number }, children: Component[]): Component;
children
Component[]
required
An array of GridRow components. Each GridRow defines one row in the grid. The number of columns is determined by the row with the most children.
props
object
Configuration options for the grid.
Basic grid
Grid([
    GridRow([Text("Name"), Text("Value")]),
    GridRow([Text("Width"), Text("100")]),
    GridRow([Text("Height"), Text("200")])
])
With spacing
Grid({ horizontalSpacing: 16, verticalSpacing: 8 }, [
    GridRow([
        Text("Label").bold(),
        Text("Amount").bold()
    ]),
    Divider(),
    GridRow([Text("Apples"), Text("$3.00")]),
    GridRow([Text("Oranges"), Text("$2.50")])
])
Spanning columns Use the .gridCellColumns() modifier to span a cell across multiple columns:
Grid({ horizontalSpacing: 12, verticalSpacing: 8 }, [
    GridRow([
        Text("Full width header")
            .font("headline")
            .gridCellColumns(2)
    ]),
    GridRow([Text("Left"), Text("Right")])
])
With alignment
Grid({ alignment: "leading", verticalSpacing: 12 }, [
    GridRow([
        Image({ systemName: "star.fill" }),
        Text("Favorites")
    ]),
    GridRow([
        Image({ systemName: "heart.fill" }),
        Text("Liked")
    ])
])
Grid determines the number of columns from the row with the most children. Rows with fewer children leave trailing cells empty. Use Divider directly as a child (not inside a GridRow) to insert a horizontal separator that spans the full grid width. Grid cell modifiers (.gridCellColumns(), .gridCellAnchor(), .gridCellUnsizedAxes(), .gridColumnAlignment()) control individual cell layout behavior.

GridRow

Defines a row of cells within a Grid layout.
GridRow(children: Component[]): Component;
GridRow(props: { alignment?: VerticalAlignment }, children: Component[]): Component;
children
Component[]
required
An array of components, one per column cell. Each child aligns with the corresponding column in the parent Grid.
props
object
Configuration options for the row.
Basic row
Grid([
    GridRow([Text("Cell 1"), Text("Cell 2")]),
    GridRow([Text("Cell 3"), Text("Cell 4")])
])
With row alignment
Grid({ horizontalSpacing: 12 }, [
    GridRow({ alignment: "top" }, [
        Text("Short"),
        Text("This cell has\nmuch more\ncontent")
    ]),
    GridRow({ alignment: "bottom" }, [
        Text("Also short"),
        Text("Another\ntall cell")
    ])
])
Spanning columns Use .gridCellColumns() on a child to span multiple columns:
Grid([
    GridRow([Text("A"), Text("B"), Text("C")]),
    GridRow([
        Text("Spans two columns")
            .gridCellColumns(2),
        Text("C")
    ])
])
GridRow must be a direct child of Grid. Using GridRow outside a Grid has no effect. The number of children in the widest GridRow determines the column count for the entire grid. Apply .gridCellColumns(), .gridCellAnchor(), or .gridCellUnsizedAxes() to individual children to control cell layout.

ViewThatFits

Picks the first child that fits in the available space for adaptive layouts.
ViewThatFits(children: Component[]): Component;
ViewThatFits(props: { axes?: Axis }, children: Component[]): Component;
children
Component[]
required
An array of alternative layouts, ordered from most preferred to least preferred. The first child that fits in the available space is rendered.
props
object
Configuration options.
Responsive layout Provide a wide layout and a narrow fallback. ViewThatFits selects the first one that fits:
ViewThatFits([
    HStack({ spacing: 12 }, [
        Image({ systemName: "star.fill" }),
        Text("Favorites"),
        Text("View all your saved items")
    ]),
    VStack({ spacing: 8 }, [
        Image({ systemName: "star.fill" }),
        Text("Favorites")
    ])
])
Horizontal axis only Test fit only along the horizontal axis:
ViewThatFits({ axes: "horizontal" }, [
    HStack([
        Text("Full Label Text"),
        Spacer(),
        Text("Value")
    ]),
    HStack([
        Text("Label"),
        Spacer(),
        Text("Value")
    ]),
    Text("Value")
])
Adaptive button bar
ViewThatFits([
    HStack({ spacing: 8 }, [
        Button("Save", () => {}),
        Button("Cancel", () => {}),
        Button("Reset", () => {})
    ]),
    VStack({ spacing: 8 }, [
        Button("Save", () => {}),
        Button("Cancel", () => {}),
        Button("Reset", () => {})
    ])
])
Children are tested in order. The first child whose ideal size fits within the available space is rendered; all others are discarded. If no child fits, the last child is used as the fallback. This is useful for building responsive layouts that adapt to different screen sizes without using GeometryReader.

See also