Grid Components
Grid Columns
2 Columns
3 Columns
4 Columns
Grid Rows & Columns
2 Rows × 2 Cols
3 Rows × 3 Cols
Grid Flow
Flow Row (default)
Flow Column
Grid Alignment
Place Items - Center
Align Items - Stretch
Gap Variations
No Gap
Large Gap (gap=6)
Gap X=6, Y=2
Complex: Center + Padding
Shadow & Background Pattern
Shadow
Shadow on hover
Background pattern
Pattern + shadow
Custom Component (as prop)
Grid as Article
Grid Item Component
Spans
How far a cell reaches. colSpan takes 1–12, full or auto ; rowSpan takes 1–6, full or auto.
rowSpan 2
Explicit placement
Where a cell starts. colStart counts grid lines, not columns — a 12 column grid has 13 of them, and the 13th is what pins a cell to the right edge.
A sidebar pinned to the last three columns
Two cells on the same lines overlap
colStart / rowStart — and flow="dense" below — move a cell on screen without moving it in the DOM. The DOM is what a screen reader reads and what the tab key follows. Reorder the children when you can, and place them only when you cannot.Responsive
Every placement property takes a scalar or a breakpoint object. Narrow the window : the hero gives up its span and everything stacks.
rowSpan { lg: 2 }
Holes, and flow="dense"
The same six cells twice. A cell too wide for the room left on a line pushes to the next one and leaves a hole ; dense sends a later, narrower cell back to fill it — which is also what makes the visual order stop matching the DOM order.
Default flow — the hole stays
flow="dense" — cell 6 backfills
Cell alignment
alignSelf, justifySelf and placeSelfoverride, for one cell, what the container aligns for all of them. The generator has carried them since the beginning ; until now no component could reach them.
A bento, without a bento component
as takes a component, not just a tag : the cell is the card, its props travel through rest. There is nothing left for a BentoCard to do.
Featured
Two columns, two rows. The cell carries the placement, the card carries the shell.
Wide
Two columns.
One
A single cell.
Two
Another one.
Footer
The whole width, whatever the column count is.
Container queries
Spans answer to the viewport ; a cell's content answers to the cell. Both cells below sit at the same viewport width and at two very different widths of their own — container is what lets their content tell the difference, in @md: rather than md:. Off by default.
Shadow & background pattern, per cell
A container carries these two for all of its children at once. On a cell they say something else : this tile is raised, that one is textured. It is what turns a flat bento into one with a lead tile — and the lift on hover costs a { value , hover } object, not a class written by hand.
The tint a pattern needs is scoped to the pseudo-element it is painted on, so the two textured cells below hold ordinary, readable text without stating a colour of their own.
Both properties come from getLayoutClassNames, so a cell reaches them on exactly the terms a Grid or a Flex does.
Props Reference
| Prop | Type | Description |
|---|---|---|
alignSelf | string | object | Align this cell along the block axis, overriding the container |
as | ElementType | Element or component to render (default div) — takes Card, Grid, anything |
colSpan | 1–12 | full | auto | object | Columns the cell covers |
colStart | 1–13 | auto | object | Grid line the cell starts at (13 lines for 12 columns) |
container | boolean | Turn the cell into a container query context (default false) |
justifySelf | string | object | Justify this cell along the inline axis |
placeSelf | string | object | align + justify shorthand |
rowSpan | 1–6 | full | auto | object | Rows the cell covers |
rowStart | 1–7 | auto | object | Grid line the cell starts at |
padding* / margin* | number | string | object | The usual spacing set, RTL aware through Start / End |
width / height / min* / max* / size | number | string | object | Sizing utilities |
backgroundColor / borderColor / borderRadius | string | Surface utilities |
backgroundPattern | string | object | Pattern name, or { pattern , baseColor , color , withColor } |
shadow | string | true | object | Box shadow depth — accepts { value , hover } like every pseudo-class property |
overflow / position / zIndex | string | number | Stacking and clipping |
Every property marked object takes a breakpoint object — { xs, sm, md, lg, xl, xxl } — as well as a scalar.
Sortable Grid Component
Sortable Photo Gallery (whole cards draggable, responsive columns)
<SortableGrid cols={ { xs : 2 , md : 3 , xl : 4 } } gap={ 4 } defaultItems={ photos } renderItem={ photo => ( <SortableGridItem><img draggable={ false } ... /></SortableGridItem> )}/>Controlled Sortable Grid
<SortableGrid cols={ 3 } gap={ 4 } items={ cards } onReorder={ next => setCards( next ) } renderItem={ card => <SortableGridItem ... /> }/>Overlay Drag Handles (cards with interactive content)
<SortableGrid handle defaultItems={ photos } renderItem={ photo => <SortableGridItem>...</SortableGridItem> }/>// handle : items drag only from the overlay button (top-right corner)Async Reorder with API Call (optimistic revert on failure)
<SortableGrid defaultItems={ photos } onReorder={ ( items ) => api.saveOrder( items ) } renderItem={ photo => <SortableGridItem>...</SortableGridItem> }/>// onReorder may return a promise : a rejection restores the previous orderProps Reference
| Prop | Type | Description |
|---|---|---|
items / defaultItems | Array | Controlled / uncontrolled items (each needs a stable id) |
onReorder | function | (items, { from, to, item }) => void | Promise — a rejected promise reverts the order (uncontrolled) |
renderItem | function | (item, index) => SortableGridItem element |
handle | boolean | Show an overlay drag handle (default false : whole items draggable) |
getItemId | function | Custom accessor for item identity (defaults to item.id) |
disabled | boolean | Disable dragging for all items |
cols / gap / ... | Grid props | Every other prop is forwarded to Grid (responsive cols, gaps, alignment, ...) |