Oihana Next UI - 0.48.0

Application logo

Grid Components

Grid Columns

2 Columns

1
2
3
4

3 Columns

1
2
3
4
5
6

4 Columns

1
2
3
4
5
6
7
8

Grid Rows & Columns

2 Rows × 2 Cols

1
2
3
4

3 Rows × 3 Cols

1
2
3
4
5
6
7
8
9

Grid Flow

Flow Row (default)

1
2
3
4
5

Flow Column

1
2
3
4
5

Grid Alignment

Place Items - Center

1
2
3
4

Align Items - Stretch

1
2
3
4

Gap Variations

No Gap

1
2
3
4
5
6

Large Gap (gap=6)

1
2
3
4
5
6

Gap X=6, Y=2

1
2
3
4
5
6

Complex: Center + Padding

A
B
C
D

Shadow & Background Pattern

Shadow

sm
md
lg
xl

Shadow on hover

hover me

Background pattern

A
B

Pattern + shadow

A
B

Custom Component (as prop)

Grid as Article

Header
Main Content
Sidebar
Article
Footer

Grid Item Component

Spans

How far a cell reaches. colSpan takes 1–12, full or auto ; rowSpan takes 1–6, full or auto.

colSpan 2
rowSpan 2
colSpan 2
1
1
colSpan "full"

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

Main — colSpan 9
Sidebar — colStart 10

Two cells on the same lines overlap

colStart 1 · rowStart 1 · 3×2
colStart 3 · rowStart 2 · zIndex 10
Reading order. 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.

colSpan { xs: 1, sm: 2 }
rowSpan { lg: 2 }
colSpan { lg: 2 }
1
1
colSpan { sm: 2, lg: 1 }

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

1 — span 2
2
3 — span 3
4 — span 2
5
6

flow="dense" — cell 6 backfills

1 — span 2
2
3 — span 3
4 — span 2
5
6

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.

alignSelf start
alignSelf center
alignSelf end
justifySelf center

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.

Row past @md
because the cell is wide
Still stacked
same viewport, narrow cell

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.

lead tileshadow md, 2xl on hover
backgroundPattern topography
hexagons, primary
shadow xl

Both properties come from getLayoutClassNames, so a cell reaches them on exactly the terms a Grid or a Flex does.

Props Reference

PropTypeDescription
alignSelfstring | objectAlign this cell along the block axis, overriding the container
asElementTypeElement or component to render (default div) — takes Card, Grid, anything
colSpan1–12 | full | auto | objectColumns the cell covers
colStart1–13 | auto | objectGrid line the cell starts at (13 lines for 12 columns)
containerbooleanTurn the cell into a container query context (default false)
justifySelfstring | objectJustify this cell along the inline axis
placeSelfstring | objectalign + justify shorthand
rowSpan1–6 | full | auto | objectRows the cell covers
rowStart1–7 | auto | objectGrid line the cell starts at
padding* / margin*number | string | objectThe usual spacing set, RTL aware through Start / End
width / height / min* / max* / sizenumber | string | objectSizing utilities
backgroundColor / borderColor / borderRadiusstringSurface utilities
backgroundPatternstring | objectPattern name, or { pattern , baseColor , color , withColor }
shadowstring | true | objectBox shadow depth — accepts { value , hover } like every pseudo-class property
overflow / position / zIndexstring | numberStacking 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)

Photo 1
Photo 1
Photo 2
Photo 2
Photo 3
Photo 3
Photo 4
Photo 4
Photo 5
Photo 5
Photo 6
Photo 6
Photo 7
Photo 7
Photo 8
Photo 8
<SortableGrid
    cols={ { xs : 2 , md : 3 , xl : 4 } } gap={ 4 }
    defaultItems={ photos }
    renderItem={ photo => (
        <SortableGridItem><img draggable={ false } ... /></SortableGridItem>
    )}
/>

Controlled Sortable Grid

Current order :ABCDEF
A
B
C
D
E
F
<SortableGrid
    cols={ 3 } gap={ 4 }
    items={ cards }
    onReorder={ next => setCards( next ) }
    renderItem={ card => <SortableGridItem ... /> }
/>

Overlay Drag Handles (cards with interactive content)

Photo 1
Photo 1
Photo 2
Photo 2
Photo 3
Photo 3
Photo 4
Photo 4
Photo 5
Photo 5
Photo 6
Photo 6
<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)

Photo 1
Photo 2
Photo 3
Photo 4
Photo 5
Photo 6
<SortableGrid
    defaultItems={ photos }
    onReorder={ ( items ) => api.saveOrder( items ) }
    renderItem={ photo => <SortableGridItem>...</SortableGridItem> }
/>
// onReorder may return a promise : a rejection restores the previous order

Props Reference

PropTypeDescription
items / defaultItemsArrayControlled / uncontrolled items (each needs a stable id)
onReorderfunction(items, { from, to, item }) => void | Promise — a rejected promise reverts the order (uncontrolled)
renderItemfunction(item, index) => SortableGridItem element
handlebooleanShow an overlay drag handle (default false : whole items draggable)
getItemIdfunctionCustom accessor for item identity (defaults to item.id)
disabledbooleanDisable dragging for all items
cols / gap / ...Grid propsEvery other prop is forwarded to Grid (responsive cols, gaps, alignment, ...)