NativePHP for Mobile v4 is here — build real native UIs from Blade with SuperNative

Lazy Grid


Overview#

A self-scrolling grid that only materializes the cells currently in — or about to enter — the viewport. On iOS it maps to SwiftUI ScrollView { LazyVGrid }; on Android to Compose LazyVerticalGrid. Both platforms build and lay out just the visible rows, so a grid of thousands of cells paints instantly and stays smooth.

Reach for it in place of a <native:scroll-view> wrapping a manually-chunked <native:row> grid whenever the cell count is large enough to be felt at parse or layout time — a good rule of thumb is around 50 or more cells.

Copied!
<native:lazy-grid :columns="4" :gap="12" class="w-full">
@foreach (['star', 'heart', 'bell', 'bookmark', 'camera', 'paperplane', 'flag', 'gearshape'] as $icon)
<native:column class="items-center p-3 rounded-lg bg-theme-surface-variant">
<native:icon :ios="$icon" :size="28" />
</native:column>
@endforeach
</native:lazy-grid>

In a real app you would typically loop a collection property on your component ($icons) rather than a literal list.

Props#

  • columns - Number of equal-width tracks the cells flow across. When horizontal is set, this becomes the number of fixed rows instead (optional, int, default: 2, minimum 1)
  • gap - Spacing in dp applied to both axes — between rows and between columns. Match the surrounding column's gap-N if you want flush alignment with neighbouring content (optional, float, default: 0)
  • horizontal - Flip the scroll orientation. Rows become the cross axis, columns is the number of fixed-height rows, and the grid scrolls horizontally (SwiftUI LazyHGrid / Compose LazyHorizontalGrid) (optional, boolean, default: false)

Children#

Each child becomes one grid cell. Cells fill their column width by default and size to their intrinsic height — wrap a child in a <native:column> with explicit sizing if you need uniform cell heights.

Examples#

Photo grid#

Copied!
<native:lazy-grid :columns="3" :gap="2" class="w-full">
@foreach (range(1, 9) as $i)
<native:column :height="120">
<native:image src="https://picsum.photos/seed/grid{{ $i }}/300" class="w-full h-full" :fit="2" />
</native:column>
@endforeach
</native:lazy-grid>

Swap range(1, 9) for your own $photos collection and bind src from each item (e.g. $photo->url).

Horizontal category shelves#

Copied!
<native:lazy-grid :columns="2" :gap="12" horizontal>
@foreach($products as $product)
<native:column :width="160" class="p-3 gap-2 rounded-lg bg-theme-surface">
<native:image src="{{ $product->image }}" :width="136" :height="100" class="rounded-lg" :fit="2" />
<native:text class="text-sm font-medium">{{ $product->name }}</native:text>
</native:column>
@endforeach
</native:lazy-grid>

Element#

Copied!
use Native\Mobile\Edge\Elements\LazyGrid;
use Native\Mobile\Edge\Elements\Column;
use Native\Mobile\Edge\Elements\Icon;
 
LazyGrid::make(
Column::make(Icon::make(ios: 'star')),
Column::make(Icon::make(ios: 'heart')),
)
->columns(4)
->gap(12);
  • make(Element ...$children) - Create a lazy grid with children
  • columns(int $count) - Number of tracks (clamped to a minimum of 1)
  • gap(float $gap) - Spacing applied to both axes
  • horizontal(bool $value = true) - Scroll horizontally with fixed rows