Oihana Next UI - 0.9.0

Application logo

Masonry Components

Real-world Examples

Photo Gallery

Placeholder 1

Photo 1

Placeholder 3

Photo 3

Placeholder 5

Photo 5

Placeholder 7

Photo 7

Placeholder 2

Photo 2

Placeholder 4

Photo 4

Placeholder 6

Photo 6

Placeholder 8

Photo 8

Content Cards

Card Title 1

Short description.

Card Title 2

This card has more content and will be taller than the others. Lorem ipsum dolor sit amet.

Card Title 3

Medium content here.

Card Title 4

Another card.

Card Title 5

This one has a bit more text to show the masonry effect working properly with different heights.

Card Title 6

Short text.

Basic Masonry Layout

2 Columns

1
3
5
2
4
6

3 Columns

1
4
7
2
5
8
3
6
9

4 Columns

1
5
2
6
3
7
4
8

Responsive Masonry

1 → 2 → 3 → 4 Columns

Try resizing your browser: 1 col on mobile, 2 on small, 3 on medium, 4 on xl screens

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12

2 → 3 → 4 Columns

Starts at 2 columns on mobile

01
03
05
07
02
04
06
08

Gap Variations

Small Gap (gap=1)

1
4
2
5
3
6

Large Gap (gap=6)

1
4
2
5
3
6

Custom Gap (X=6, Y=2)

1
4
2
5
3
6

Responsive Gap

Gap increases with screen size

1
3
5
2
4
6

Custom Column Styling

Columns with Background

1
4
2
5
3
6

Sortable Masonry Component

Sortable Masonry (variable heights, drag across columns)

The flat order is the concatenation of the columns (top to bottom, left to right). After a drop the list is evenly redistributed — an item close to a column boundary may shift to the neighbouring column : the invariant is the order, not the column.

1
2
3
4
5
6
7
8
9
10
<SortableMasonry
    columns={ { xs : 2 , md : 3 } } gap={ 4 }
    defaultItems={ cards }
    renderItem={ card => <SortableGridItem>...</SortableGridItem> }
/>

Controlled Masonry (live flat order)

Flat order :1 , 2 , 3 , 4 , 5 , 6 , 7 , 8
1
2
3
4
5
6
7
8
<SortableMasonry
    items={ cards }
    onReorder={ next => setCards( next ) }
/>

Disabled Dragging (global toggle + per-item locks)

The 🔒 cards are always locked (per-item disabled).
1
2
3
4
5
6
<SortableMasonry
    disabled={ saving }  // container level : freezes every item
    renderItem={ card => (
        <SortableGridItem disabled={ card.locked }>  // item level : explicit value wins
    )}
/>
// note : a disabled item cannot be grabbed, but it is not pinned —
// it still shifts when its neighbours are reordered

Async Reorder with API Call (optimistic revert on failure)

1
2
3
4
5
6
<SortableMasonry
    defaultItems={ cards }
    onReorder={ ( items ) => api.saveOrder( items ) }
/>
// onReorder may return a promise : a rejection restores the previous order

Props Reference

PropTypeDescription
items / defaultItemsArrayControlled / uncontrolled flat list (each item needs a stable id)
onReorderfunction(items, { from, to, item }) => void | Promise — flat indexes ; a rejected promise reverts the order (uncontrolled)
renderItemfunction(item, indexInColumn) => SortableGridItem element
columnsnumber | objectColumn count or responsive object { xs, sm, md, lg, xl, xxl } (sequential distribution)
handlebooleanShow an overlay drag handle (default false : whole items draggable)
getItemId / disabled / gap / ...Same contract as SortableGrid ; other props forwarded to the Grid container