suiss/uim · Pattern

Paged List

A FlatList that shows items one page at a time and loads the next page on scroll or with a button.

Paged List is an open-source mobile pattern from suiss/uim: components composed into a flow for React Native and Expo, with SwiftUI and Jetpack Compose versions built from the same design tokens. The @esuiss/uim CLI copies its source into your project, so you own the code.

iOS
Paged List on iOS in light mode

PagedList takes the full items array and renders only the first pageSize items. When the user scrolls near the end, or presses the Load more button in the footer, the next page is appended.

The button disappears once every item is shown. Use it for long local lists where rendering everything at once is not needed.

Installation

$ pnpm dlx @esuiss/uim@latest add paged-list

The CLI also adds what it builds on: Button, Text.

Manual

  1. Install the dependencies:
npx expo install cn
  1. Add the pieces it builds on: Button, Text.

  2. Copy the source into components/patterns/paged-list.tsx:

uniwind/components/patterns/paged-list.tsx
import { cn } from "cn"
import * as React from "react"
import { FlatList, type FlatListProps, View } from "react-native"
import { Button } from "@/components/ui/button"
import { Text } from "@/components/ui/text"

function PagedList<T>({
  items,
  pageSize = 10,
  getKey = (_, index) => index,
  renderItem,
  loadMoreLabel = "Load more",
  className,
  listClassName,
  ...props
}: Omit<
  1. Update the import paths to match your project.

Usage

import { PagedList } from "@/components/patterns/paged-list"
<PagedList<Topic> items={topics} pageSize={10} getKey={(topic: Topic) => topic.id} renderItem={(topic: Topic) => <TopicRow topic={topic} />} />

Pass items, renderItem and a getKey that returns a stable key for each item. renderItem receives the item and its index, not the FlatList info object.

Other FlatList props pass through, except data, keyExtractor, onEndReached and ListFooterComponent, which the list manages. Use listClassName to style the content container.

Examples

Small pages

Uses a pageSize of 3 so pages load sooner.

iOS
Paged List (small pages) on iOS in light mode

Single page

Fewer items than one page, so no Load more button appears.

iOS
Paged List (single page) on iOS in light mode

Custom labels

Renames the button with loadMoreLabel.

iOS
Paged List (custom labels) on iOS in light mode

API Reference

PagedList

ExtendsFlatListProps<T>
PropType
About
The full array of items.
Type
T[]
Default
required
About
Items added per page. Defaults to 10.
Type
number
Default
10
About
Returns a unique key for an item. Defaults to the index.
Type
(item: T, index: number) => React.Key
Default
(_, index) => index
About
Renders one item from the item and its index.
Type
(item: T, index: number) => React.ReactNode
Default
required
About
Text of the footer button. Defaults to Load more.
Type
string
Default
"Load more"
About
Classes for the FlatList.
Type
string
Default
—
About
Classes for the list's content container.
Type
string
Default
—

Accessibility

  • The Load more button is a Button, so screen reader users can load the next page without scrolling to the end.

Notes

  • The next page loads when the scroll position is within half a screen of the end (onEndReachedThreshold of 0.5).
  • The footer is a full-width secondary button.