Fluxo UIFluxo UIv0.4.93

Virtual List

Windowed scrolling list that keeps render cost flat regardless of dataset size — essential for long mobile lists.

Basic Usage

10,000-row virtual list

Only the rows in the visible window are rendered, so scrolling stays smooth even with very long lists.

Customer 1
customer1@example.com
Customer 2
customer2@example.com
Customer 3
customer3@example.com
Customer 4
customer4@example.com
Customer 5
customer5@example.com
Customer 6
customer6@example.com
Customer 7
customer7@example.com
Customer 8
customer8@example.com
Customer 9
customer9@example.com
Customer 10
customer10@example.com
Customer 11
customer11@example.com
import { VirtualList } from 'fluxo-ui';

<VirtualList
    items={items}
    itemHeight={48}
    height={400}
    renderItem={(item) => <div>{item.name}</div>}
    keyExtractor={(item) => item.id}
/>

Variants

variant="plain"

No separators — pair with custom border styling on each row.

Row 1
Lorem ipsum dolor sit amet
Row 2
Lorem ipsum dolor sit amet
Row 3
Lorem ipsum dolor sit amet
Row 4
Lorem ipsum dolor sit amet
Row 5
Lorem ipsum dolor sit amet
Row 6
Lorem ipsum dolor sit amet
Row 7
Lorem ipsum dolor sit amet
Row 8
Lorem ipsum dolor sit amet
Row 9
Lorem ipsum dolor sit amet

variant="divided"

A subtle hairline between rows.

Row 1
Lorem ipsum dolor sit amet
Row 2
Lorem ipsum dolor sit amet
Row 3
Lorem ipsum dolor sit amet
Row 4
Lorem ipsum dolor sit amet
Row 5
Lorem ipsum dolor sit amet
Row 6
Lorem ipsum dolor sit amet
Row 7
Lorem ipsum dolor sit amet
Row 8
Lorem ipsum dolor sit amet
Row 9
Lorem ipsum dolor sit amet

variant="card"

Each row rendered as a rounded card with breathing room.

Row 1
Lorem ipsum dolor sit amet
Row 2
Lorem ipsum dolor sit amet
Row 3
Lorem ipsum dolor sit amet
Row 4
Lorem ipsum dolor sit amet
Row 5
Lorem ipsum dolor sit amet
Row 6
Lorem ipsum dolor sit amet
Row 7
Lorem ipsum dolor sit amet
<VirtualList variant="divided" ... />
<VirtualList variant="card" ... />

Infinite Loading

Infinite scroll via onEndReached

Fires when scrolled within endReachedThreshold of the bottom. Pair with VirtualList for unbounded feeds.

Notification 1
Notification 2
Notification 3
Notification 4
Notification 5
Notification 6
Notification 7
Notification 8
Notification 9
Notification 10
Notification 11
Loaded 30 items
<VirtualList
    items={items}
    itemHeight={48}
    height={360}
    endReachedThreshold={150}
    onEndReached={() => loadMore()}
    renderItem={(item) => <Row item={item} />}
/>

Import

import { VirtualList } from 'fluxo-ui';
import type { VirtualListProps, VirtualListHandle, VirtualListVariant } from 'fluxo-ui';

Props

itemsreq
T[]

Source array. Only the rows in the visible window are rendered.

itemHeight
number | (index: number, item: T) => number

Row height. Pass a number for uniform rows or a function for per-row heights. When omitted, estimatedItemHeight is used.

renderItemreq
(item: T, index: number) => ReactNode

Renderer for each row.

keyExtractor
(item: T, index: number) => Key

Optional key extractor for stable row identity.

overscan
number"4"

Number of rows to render before/after the visible window.

height
string | number"'100%'"

CSS height of the scrollable container.

estimatedItemHeight
number"56"

Fallback row height when itemHeight is not provided.

variant
'plain' | 'divided' | 'card'"'plain'"

Visual style. 'divided' draws a separator between rows; 'card' renders each row in a card with margin.

emptyState
ReactNode

Optional content rendered when items is empty.

onEndReached
() => void

Fired when the scroll position is within endReachedThreshold of the bottom. Pairs with infinite loading.

endReachedThreshold
number"200"

Pixels from the bottom at which onEndReached should fire.

className
string

Additional CSS class for the scroller.

ariaLabel
string

Accessible name for the list landmark.

Features

Windowed rendering

Only rows visible in the viewport (plus overscan) are mounted.

Fixed or dynamic heights

Pass a number for uniform rows or a function for per-row heights.

Imperative scroll API

scrollToIndex / scrollToOffset / getScrollOffset via ref.

Infinite loading hook

onEndReached fires when the user nears the bottom — perfect for paged feeds.

Three variants

plain, divided (subtle separators), and card (rounded rows).

Theme-aware

Uses --eui-* variables so it adopts every brand theme and dark mode.