PullToRefresh
Wraps a scrollable region and triggers a refresh when pulled down past a threshold at the top
Category: feedback · WCAG 2.2-AA · feedback, pull-to-refresh, mobile, gesture, scroll, refresh
States
- idle
- pulling
- ready
- refreshing
Props
| Prop | Type | Default | Description |
|---|---|---|---|
onRefresh | () => Promise<unknown> | unknown | — | Called when the pull passes the threshold; the spinner shows until it settles |
children | React.ReactNode | — | Content rendered inside the component. |
threshold | number | 64 | Pull distance (px) required to trigger a refresh. |
disabled | boolean | false | When true, disables the control and removes it from the tab order. |
labels | { pull?: string; release?: string; refreshing?: string } | — | Overrides for the component’s user-visible strings (i18n). |
className | string | — | Additional CSS class names merged onto the root element. |
Design tokens
--cascivo-color-text-muted--cascivo-motion-enter
When to use
- A scrollable list or feed on touch devices that the user refreshes by pulling down from the top
- Mobile screens where a dedicated refresh button would be redundant or out of reach
- Content that updates on demand and benefits from a familiar pull gesture
When not to use
- Desktop, pointer-first surfaces — provide an explicit Refresh button
- Content that auto-refreshes or paginates on scroll — use infinite scroll instead
- Regions that are not the primary scroll container of the screen
How to build an accessible PullToRefresh in React →
Examples
Basic
The spinner shows until the returned promise settles.
<PullToRefresh onRefresh={() => refetch()}>
<FeedList items={items} />
</PullToRefresh>Custom threshold
Requires a longer pull before a refresh is triggered.
<PullToRefresh onRefresh={loadLatest} threshold={96}>
<MessageList />
</PullToRefresh>Related components
- Spinner — Shows the Spinner while the refresh promise settles
- ScrollArea — Wraps a scrollable region; pair with the app’s scroll container