Grid
2D layout primitive. The partner to Stack and Row — for tile grids, stat cards, feature columns, anything that needs to collapse gracefully on mobile.
Installation
import { Grid } from "@gradeui/ui"Usage
Reach for Grid when Stack (vertical) and Row (horizontal) don't fit — anywhere you'd hand-roll grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4. The cols prop bakes in a sensible responsive ladder so you pick the desktop column count and let mobile break down automatically.
Cols
Each cols value is a baked-in responsive ladder — not a fixed column count. Resize your viewport to see the grid adapt.
cols="2"
grid-cols-1 md:grid-cols-2
cols="3" (default)
grid-cols-1 sm:grid-cols-2 md:grid-cols-3
cols="4"
grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 — the canonical stat-card grid.
cols="6"
grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 — denser, good for icon or thumbnail grids.
Gap
Same seven-step scale as Stack and Row — so the prop transfers cleanly if you switch a region's layout type.
gap="sm"
gap="xl"
Composition
The classic 4-up stat-card grid. Drop Cards directly into Grid cells — no wrappers needed.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| cols | "1" | "2" | "3" | "4" | "5" | "6" | "12" | "3" | Desired desktop column count. Each value has a baked-in responsive ladder — e.g. `4` produces `grid-cols-1 sm:grid-cols-2 lg:grid-cols-4`, the canonical stat-card pattern. |
| gap | "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "md" | Gap between grid cells. Same scale as Stack and Row, so the prop transfers cleanly when switching layout types. |
| align | "start" | "center" | "end" | "stretch" | "stretch" | Cross-axis alignment of each cell's content. |
| asChild | boolean | false | Render as the single child element via Radix Slot — stamps Grid's layout classes onto an existing semantic tag (e.g. <section>) without nesting a wrapper div. |
| className | string | — | Extra classes merged onto the root element. Use this if you need bespoke breakpoints beyond the `cols` ladder. |
When to use
- Stat-card dashboards —
cols="4"is the canonical shape. - Feature-tile grids on marketing pages — usually
cols="3". - Pricing columns, testimonial tiles, product cards.
- For purely vertical layouts, reach for Stack. For a single horizontal row (button groups, nav bars), reach for Row.
- For bespoke breakpoints beyond the
colsladder, passclassNamewith your own grid classes — Grid will merge them correctly via tailwind-merge.
Sidecar
The Markdown sidecar Studio (and the Grade MCP server, when it ships) reads to understand this component — frontmatter, when- to-use guidance, and canonical examples. Authored once at packages/ui/components/ui/grid.md and shipped inside the published @gradeui/ui tarball.
---
name: Grid
import: "@gradeui/ui"
role: layout
props:
- cols?: "1" | "2" | "3" | "4" | "5" | "6" | "12" (default "3") — desktop column count; each value has a baked-in responsive ladder (e.g. "4" → 1 col mobile, 2 tablet, 4 desktop)
- gap?: "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" (default "md") — gap between grid cells (same scale as Stack/Row)
- align?: "start" | "center" | "end" | "stretch" (default "stretch") — cross-axis alignment of cells
- asChild?: boolean (default false) — render as the child element via Slot
- className?: string
- children: React.ReactNode
when_to_use: 2D layouts where Stack (vertical) and Row (horizontal) don't fit — stat-card grids, feature tiles, pricing columns, photo grids. Reach for Grid over hand-rolled `grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4` so the column count is a prop the settings panel can mutate and the responsive ladder stays consistent across designs.
composes_with: [Card, Stack (inside each cell), Row, Button, any content component]
aliases: [grid, tiles, cards grid, stat grid, columns, feature grid, grid view, lazy v grid, lazyvgrid, lazy h grid, lazyhgrid, tile grid, masonry]
notes: |
`cols` values and their responsive ladders:
"1" → grid-cols-1 (single column at all breakpoints)
"2" → grid-cols-1 md:grid-cols-2
"3" → grid-cols-1 sm:grid-cols-2 md:grid-cols-3
"4" → grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 (the canonical stat-card grid)
"5" → grid-cols-1 sm:grid-cols-2 lg:grid-cols-5
"6" → grid-cols-2 sm:grid-cols-3 lg:grid-cols-6
"12" → grid-cols-4 md:grid-cols-6 lg:grid-cols-12
Prefer Grid over bespoke Tailwind grid classes — "gap-md" etc. are NOT real Tailwind classes (the gap scale is numeric: gap-4, gap-6) so hand-rolled grids often end up with zero gap.
---
```jsx
// Stat-card grid — the canonical 4-up.
<Grid cols="4" gap="md">
<Card>…</Card>
<Card>…</Card>
<Card>…</Card>
<Card>…</Card>
</Grid>
```
```jsx
// Three-column feature grid with larger gaps.
<Grid cols="3" gap="lg">
<FeatureCard />
<FeatureCard />
<FeatureCard />
</Grid>
```