$ rezi
Widgets

Grid

Arranges children in a two-dimensional grid with configurable columns, rows, and gap spacing.

Arranges children in a two-dimensional grid with configurable columns, rows, and gap spacing.

Usage

ui.grid({ columns: 3, gap: 1 }, [
  ui.text("Cell 1"),
  ui.text("Cell 2"),
  ui.text("Cell 3"),
  ui.text("Cell 4"),
  ui.text("Cell 5"),
  ui.text("Cell 6"),
])

Props

PropTypeDefaultDescription
columnsnumber | stringrequiredNumber of equal-width columns, or a track string (e.g. "1fr 2fr auto")
rowsnumber | string-Number of rows or a track string. When explicit, grid capacity is fixed and extra children are not rendered
gapnumber0Default gap for both row and column axes
rowGapnumber-Row gap override (takes precedence over gap)
columnGapnumber-Column gap override (takes precedence over gap)

Track Syntax

The columns and rows props accept either a positive number or a track definition string. Track strings are space-separated lists of track sizes:

TokenMeaningExample
Fixed numberColumn/row width in cells12, 24
autoSize to contentauto
fr fractionShare of remaining space1fr, 2fr

Note: fr tracks have a natural size of 0 and grow from remaining space after fixed and auto tracks are resolved.

Behavior

  • Numeric columns (e.g. columns: 3) create equal-width columns that divide the available space evenly.
  • Placement is auto-flow, row-major: children fill cells left-to-right, then wrap to the next row.
  • Explicit rows cap grid capacity. If rows is set and the grid is full, extra children are not rendered.

Examples

Dashboard Cards

A three-column dashboard layout with info cards:

ui.grid({ columns: 3, gap: 1 },
  ui.box({ border: "rounded", p: 1 }, [
    ui.text("CPU", { style: { bold: true } }),
    ui.text("42%"),
  ]),
  ui.box({ border: "rounded", p: 1 }, [
    ui.text("Memory", { style: { bold: true } }),
    ui.text("3.2 GB / 16 GB"),
  ]),
  ui.box({ border: "rounded", p: 1 }, [
    ui.text("Disk", { style: { bold: true } }),
    ui.text("120 GB free"),
  ]),
  ui.box({ border: "rounded", p: 1 }, [
    ui.text("Network", { style: { bold: true } }),
    ui.text("12 Mbps"),
  ]),
  ui.box({ border: "rounded", p: 1 }, [
    ui.text("Uptime", { style: { bold: true } }),
    ui.text("14d 6h"),
  ]),
  ui.box({ border: "rounded", p: 1 }, [
    ui.text("Processes", { style: { bold: true } }),
    ui.text("284 running"),
  ]),
])

Mixed Tracks

A sidebar-content layout using fr tracks:

ui.grid({ columns: "1fr 3fr", gap: 1 }, [
  ui.box({ border: "single", p: 1 }, [
    ui.column({ gap: 0 }, [
      ui.text("Nav Item 1"),
      ui.text("Nav Item 2"),
      ui.text("Nav Item 3"),
    ]),
  ]),
  ui.box({ border: "rounded", p: 1 }, [
    ui.text("Main content area"),
  ]),
])

Status Grid

A fixed 2x3 status grid with explicit rows:

ui.grid({ columns: 2, rows: 3, gap: 1 }, [
  ui.text("Service A"),  ui.text("OK"),
  ui.text("Service B"),  ui.text("WARN"),
  ui.text("Service C"),  ui.text("OK"),
])

If additional children were added beyond the 6-cell capacity (2 * 3), they would not be rendered.

Auto-sized Columns

Using auto to size columns to their content:

ui.grid({ columns: "auto 1fr auto", gap: 1 }, [
  ui.text("Label:"),
  ui.input({
    id: "name-input",
    value: state.name,
    onInput: (value) => app.update((s) => ({ ...s, name: value })),
  }),
  ui.button("save", "Save"),
])

Stability

stable

On this page