Infinite Scroll

Loads more items as the end of a list comes into view, with loading, error and end states.
Beta
Web
iOS
Android
@advui/data
Source

Activity feed

Thiri Aung updated the Bago sheet2 min ago
Kyaw Zin closed a task3 min ago
May Phyu uploaded a map4 min ago
Htet Naing commented on the 5W round5 min ago
Su Su updated the Bago sheet6 min ago
Thiri Aung closed a task7 min ago
Kyaw Zin uploaded a map8 min ago
May Phyu commented on the 5W round9 min ago
Htet Naing updated the Bago sheet10 min ago
Su Su closed a task11 min ago
Thiri Aung uploaded a map12 min ago
Kyaw Zin commented on the 5W round13 min ago

Installation

pnpm
pnpm add @advui/data
npm
npm install @advui/data

Usage

import { Text } from '@advui/core'
import { InfiniteScroll } from '@advui/data'

<InfiniteScroll
  aria-label="Activity"
  height="80"
  hasMore={hasMore}
  loading={loading}
  onLoadMore={loadNextPage}
  endMessage="You're all caught up"
>
  {items.map((item) => <Text key={item.id}>{item.text}</Text>)}
</InfiniteScroll>

Examples

Load more button

`mode="button"` loads only when asked, so content after the list stays in reach.
Comment 1The township totals match the July sheet now.
Comment 2Can we add the partner names to the map legend?
Comment 3Uploaded the corrected file.
Comment 4Thanks, that fixed the duplicate rows.
Comment 5Reviewed: ready to publish.

A page that fails

The second page fails once; Try again loads it.
Report 001
Report 002
Report 003
Report 004
Report 005
Report 006
Report 007
Report 008
Report 009
Report 010

API reference

InfiniteScroll

A ScrollArea: give it a height to scroll on its own. On web, without one it grows and the page scrolls.
PropTypeDefaultDescription
hasMore requiredboolean—More items remain to load.
onLoadMore required() => void—Loads the next page: called near the end, or from Load more or Try again.
loadingbooleanfalseA page is loading. Shows the loading row; no other load starts.
mode'auto' | 'button''auto'`auto` loads as the end comes near; `button` waits for Load more.
thresholdnumber0.5How near the end loading starts, in visible heights.
itemCountnumber—The number of loaded items, when they sit in one element such as a VStack. Default: the number of children.
errorReactNode—Why the last page failed. Shown with Try again; loading pauses until it is cleared.
endMessageReactNode—Shown once nothing remains.
aria-labelstring—Names the area for screen readers. Recommended.
loadingLabelstring'Loading more…'Text of the loading row.
loadMoreLabelstring'Load more'The button in `button` mode.
retryLabelstring'Try again'The button after an error.
loadedLabel(count: number) => string—Announced after a page loads. Default: “10 more loaded”.
children requiredReactNode—The loaded items.

Accessibility

  • While a page loads the area has aria-busy, and the loading row says so in words (its spinner is hidden).
  • After a page, the number of new items is announced (“10 more loaded”): through a polite live region on web, with AccessibilityInfo.announceForAccessibility on iOS and Android. A text error is announced the same way.
  • In button mode, Load more stays focusable while it loads (aria-busy and aria-disabled, not disabled, which would drop focus) and ignores presses; use it when content after the list must stay in reach.
  • The items keep their own semantics: put a List inside, or rows with their own roles.
Keyboard interactions
KeyAction
TabMoves through the items, then to Load more or Try again.
Enter / SpacePresses Load more or Try again.
Arrow keys / Page Up / Page DownScroll the area while it has focus.

Platform notes

Web
An IntersectionObserver watches the end, so it works in a ScrollArea of its own height, inside another scrolling box, or on the page.
iOS
The ScrollView’s scroll, content size and layout events: give it a height, as a screen does not scroll around it. Content shorter than the area loads more until it fills it.
Android
Same as iOS, with nested scrolling on.
Since v0.14.0Last updated Nov 2, 2026Edit this page on GitHub