Grid
A responsive grid where the column count is a decision, not a class soup.
@luc/ui/layoutExamples
Column counts
The column count is a prop, and the breakpoint stack behind it is the component's decision — each count collapses one step before it has to.
Return
Volatility
Return
Volatility
Sharpe
Return
Volatility
Sharpe
Drawdown
Return
Volatility
Sharpe
Drawdown
Exposure
Turnover
<Grid columns={2} gap="md">…</Grid>
<Grid columns={3} gap="md">…</Grid>
<Grid columns={4} gap="md">…</Grid>
<Grid columns={6} gap="md">…</Grid>Gap scale
One scale, shared with `Stack` and `Inline`, so a page cannot end up with four different ideas of what a gap is.
Return
Volatility
Sharpe
Return
Volatility
Sharpe
Return
Volatility
Sharpe
Return
Volatility
Sharpe
<Grid columns={3} gap="sm">…</Grid>
<Grid columns={3} gap="md">…</Grid>
<Grid columns={3} gap="lg">…</Grid>
<Grid columns={3} gap="xl">…</Grid>Auto-fit tracks
`minItemWidth` is the other way to decide a grid: instead of a column count, a minimum cell width, and the browser fits as many as will go. Narrow the window and the count changes on its own.
Return
Volatility
Sharpe
Drawdown
Exposure
Turnover
Return
Volatility
Sharpe
Drawdown
Exposure
Turnover
Return
Volatility
Sharpe
Drawdown
Exposure
Turnover
<Grid minItemWidth="sm">…</Grid>
<Grid minItemWidth="md">…</Grid>
<Grid minItemWidth="lg">…</Grid>A cell that spans
A grid has no span prop, and it does not need one: a cell is an ordinary element, so `sm:col-span-2` on the thing inside it is the whole mechanism.
Risk report
Three of four columns
One column
<Grid columns={4} gap="md">
<Panel className="sm:col-span-2 lg:col-span-3">…</Panel>
<Panel>…</Panel>
</Grid>A card wall
The composition the component exists for: equal cards, one gap, and a cell that grows with its own content instead of a fixed height.
Momentum
12-1 total return
+4.8%
Value
Book to price
-1.2%
Quality
Gross profitability
+0.9%
<Grid columns={3} gap="md">
{factors.map((factor) => (
<Card key={factor.name} className="gap-1 p-4">…</Card>
))}
</Grid>Usage
import { Grid } from "@luc/ui/layout";<Grid columns={3} gap="md">
{items.map((item) => <Card key={item.id} … />)}
</Grid>`columns` fixes the count, `minItemWidth` fits as many as will go; `gap` is the same scale `Stack` and `Inline` use.
Package setup — peer requirements, the stylesheet and the provider — is on installation.
API
Read from the published TypeScript API, so a prop that is not listed here does not exist and a default that is listed is the one the compiler sees.
| Export | Kind | Signature |
|---|---|---|
Grid | 3 documented props | ({ className, columns, minItemWidth, gap, ...props }: GridProps) => import("@types/react").JSX.Element |
Grid props
Type: GridProps
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
columns? | Columns | undefined | — | |
gap? | Gap | undefined | — | |
minItemWidth? | "none" | "sm" | "md" | "lg" | "xl" | undefined | — | Auto-fit track sizing. Overrides `columns` when set. |
Guidelines
Do
- Reach for `columns` when the number is known and stable — a four-metric summary — and `minItemWidth` when it is not, such as a filter result or a card catalogue.
- Keep the grid's gap on the same scale as the `Stack` around it: the two scales are one scale, and mixing them looks hand-built.
- Give a cell its own span with a class on the child (`sm:col-span-2`); the grid deliberately has no span prop.
Don't
- Do not lay a two-column form out with a grid: `FieldGroup` already does that, with the labels and the error messages in the right order.
- Do not set a fixed height on a cell to make a row line up — let the tallest cell define the row.
- Do not use `columns={6}` near a phone: every count collapses on the way down, and six columns at 390px is unreadable.
Accessibility
CSS Grid on a `div`: no semantics and no keyboard behaviour, so the reading order is the source order — which is why a wall of cards has to be written in the order a screen reader should read it. Nothing here is tabular; data that is a table belongs in `DataTable`, which renders real table markup with scoped headers.
Family
Layout
Space, rhythm and the surfaces a page is made of.
10 documented entries in this family. Open the family index
Related