Skip to main content

Grid Layout

The Grid component provides a two-dimensional layout system where you can position children at specific rows and columns with optional spanning.

Basic Usage

import { Grid, Label, Entry, Button } from "@gtkx/react";

const LoginForm = () => (
<Grid.Root columnSpacing={12} rowSpacing={8}>
<Grid.Child row={0} column={0}>
<Label.Root label="Username:" halign={2} />
</Grid.Child>
<Grid.Child row={0} column={1}>
<Entry hexpand />
</Grid.Child>

<Grid.Child row={1} column={0}>
<Label.Root label="Password:" halign={2} />
</Grid.Child>
<Grid.Child row={1} column={1}>
<Entry visibility={false} hexpand />
</Grid.Child>

<Grid.Child row={2} column={0} columnSpan={2}>
<Button label="Login" cssClasses={["suggested-action"]} />
</Grid.Child>
</Grid.Root>
);

Grid.Root Props

PropTypeDescription
columnSpacingnumberGap between columns in pixels
rowSpacingnumberGap between rows in pixels
columnHomogeneousbooleanIf true, all columns have equal width
rowHomogeneousbooleanIf true, all rows have equal height

Grid.Child Props

PropTypeDefaultDescription
rownumber0Row position (0-indexed)
columnnumber0Column position (0-indexed)
rowSpannumber1Number of rows to span
columnSpannumber1Number of columns to span

How It Works

Grid.Child is a virtual node that:

  1. Stores the row, column, and span metadata
  2. Calls grid.attach(widget, column, row, columnSpan, rowSpan) when mounted
  3. Calls grid.remove(widget) when unmounted
  4. Re-attaches with new position if props change

Spanning Cells

Use rowSpan and columnSpan to create cells that span multiple rows or columns:

<Grid.Root columnSpacing={8} rowSpacing={8}>
{/* Header spanning all 3 columns */}
<Grid.Child row={0} column={0} columnSpan={3}>
<Label.Root label="Settings" cssClasses={["title-2"]} />
</Grid.Child>

{/* Sidebar spanning 2 rows */}
<Grid.Child row={1} column={0} rowSpan={2}>
<Box cssClasses={["card"]} vexpand>
<Label.Root label="Navigation" />
</Box>
</Grid.Child>

{/* Content areas */}
<Grid.Child row={1} column={1} columnSpan={2}>
<Label.Root label="Main content" />
</Grid.Child>
<Grid.Child row={2} column={1} columnSpan={2}>
<Label.Root label="Secondary content" />
</Grid.Child>
</Grid.Root>

Dynamic Grid Content

Grid children can be rendered conditionally or from arrays:

import { Grid, Label } from "@gtkx/react";

interface Cell {
id: string;
row: number;
column: number;
content: string;
}

const DynamicGrid = ({ cells }: { cells: Cell[] }) => (
<Grid.Root columnSpacing={8} rowSpacing={8}>
{cells.map(cell => (
<Grid.Child key={cell.id} row={cell.row} column={cell.column}>
<Label.Root label={cell.content} />
</Grid.Child>
))}
</Grid.Root>
);

Form Layouts

Grids are ideal for form layouts with aligned labels and inputs:

import { Grid, Label, Entry, Switch, Button, Box } from "@gtkx/react";
import { Align } from "@gtkx/ffi/gtk";

const SettingsForm = () => (
<Grid.Root columnSpacing={16} rowSpacing={12}>
{/* Row 0: Name */}
<Grid.Child row={0} column={0}>
<Label.Root label="Display Name" halign={Align.END} />
</Grid.Child>
<Grid.Child row={0} column={1}>
<Entry hexpand placeholderText="Enter your name" />
</Grid.Child>

{/* Row 1: Email */}
<Grid.Child row={1} column={0}>
<Label.Root label="Email" halign={Align.END} />
</Grid.Child>
<Grid.Child row={1} column={1}>
<Entry hexpand placeholderText="you@example.com" />
</Grid.Child>

{/* Row 2: Notifications toggle */}
<Grid.Child row={2} column={0}>
<Label.Root label="Notifications" halign={Align.END} />
</Grid.Child>
<Grid.Child row={2} column={1}>
<Switch halign={Align.START} />
</Grid.Child>

{/* Row 3: Buttons */}
<Grid.Child row={3} column={1}>
<Box orientation={0} spacing={8} halign={Align.END}>
<Button label="Cancel" />
<Button label="Save" cssClasses={["suggested-action"]} />
</Box>
</Grid.Child>
</Grid.Root>
);

Grid vs Box

FeatureGridBox
Dimensions2D (rows and columns)1D (horizontal or vertical)
PositioningExplicit row/columnSequential order
SpanningSupports rowSpan/columnSpanNot applicable
Use caseForms, complex layoutsSimple lists, toolbars

Use Box for simple sequential layouts and Grid when you need precise 2D positioning.