Components

LazyVGrid

A measured, virtualized vertical grid. Only the viewport and a small overscan window mount, including when scrolling the page.

Example

Requires React 18.2+ or 19 and shared styles. See setup.

In Scroll View

Loading preview…

Code
'use client';
import { ScrollView } from '@swiftuijs/ui';
import { LazyVGrid } from '@swiftuijs/ui';
export default function Example() {
    return ((<ScrollView style={{ height: 320 }}>
      <LazyVGrid columns={2} spacing={8} estimatedItemHeight={64}>
        {Array.from({ length: 1000 }, (_, index) => <div key={index} style={{ padding: 16, minWidth: 120, background: 'var(--sw-color-background-secondary)' }}>Item {index + 1}</div>)}
      </LazyVGrid>
    </ScrollView>));
}

Usage and limitations

  • Use a bounded ScrollView or any ancestor with overflow: auto/scroll; otherwise the page is the scrolling surface.
  • estimatedItemHeight defaults to 48 pixels and is corrected with ResizeObserver measurements. A grid virtualizes complete rows or columns; their size is the largest item in that group.
  • overscan defaults to four extra rows or columns on each side. Focused items and their neighbors remain mounted for keyboard navigation.
  • Use stable React keys. Keep editable state in your application: off-screen items unmount and their local state resets.
  • SSR renders an initial 640-pixel window with estimated dimensions; hydration measures the actual viewport and items. It does not emit every item into server HTML.
  • Creating the children array still costs O(n); virtualization limits mounted components and DOM nodes. For small collections, use ordinary stacks or grids.

API reference

PropTypeRequiredDescription
columnsnumberNoNumber of columns. Default: 2
spacingnumberNoGap between items in pixels. Default: 0
estimatedItemHeightnumberNoInitial row height in pixels, corrected after measurement. Default: 48

Inherits additional props from IBaseComponent, Pick<VirtualLayoutOptions, 'overscan'>.