Pull to Refresh
Refreshes a scrolling list when the user pulls it down.
Installation
pnpm dlx shadcn@latest add @paneui/pull-to-refreshUsage
Examples
Scrollbars
Scrolls in a Scroll Area, so its scrollbar stays inside the rounded frame and holds still while the content is pulled. The pull never changes the scroll range.
Motion
Content springs back once onRefresh resolves. With reduced motion it jumps into place and the arrow doesn't rotate.
Accessibility
The root sets aria-busy while refreshing and a polite live region announces refreshingLabel. Pull is a touch, pen and mouse gesture only, so give keyboard users another way to refresh.
PullToRefresh
Scroll container that arms a refresh when pulled down from the top. Give it a height. Also accepts every prop of div.
- children*
- ReactNode
- The scrolling content.
- onRefresh*
- () => void | Promise<void>
- Runs when the pull is released past
threshold. Return a promise to keep the spinner until it settles, or return nothing and setrefreshinginstead. - refreshing
- boolean
- Hold the refreshing state for a refresh managed outside the gesture. The content stays open until both this and any
onRefreshpromise are done. - disabled= false
- boolean
- Turn the pull gesture off.
- threshold= 64
- number
- Resisted pull distance (px) that arms the refresh.
- maxPull= 120
- number
- Ceiling of the resisted pull (px).
- holdDistance= 56
- number
- Content offset (px) while refreshing.
- pullingLabel= "Pull to refresh"
- ReactNode
- Shown while pulling, before the threshold.
- releaseLabel= "Release to refresh"
- ReactNode
- Shown once the pull is armed.
- refreshingLabel= "Refreshing…"
- ReactNode
- Shown and announced while refreshing.
- onStatusChange
- (status: "idle" | "pulling" | "ready" | "refreshing") => void
- Called whenever the gesture status changes.
- contentClassName
- string
- Classes for the content that moves with the pull.
| Prop | Type | Default | Description |
|---|---|---|---|
| children* | ReactNode | — | The scrolling content. |
| onRefresh* | () => void | Promise<void> | — | Runs when the pull is released past threshold. Return a promise to keep the spinner until it settles, or return nothing and set refreshing instead. |
| refreshing | boolean | — | Hold the refreshing state for a refresh managed outside the gesture. The content stays open until both this and any onRefresh promise are done. |
| disabled | boolean | false | Turn the pull gesture off. |
| threshold | number | 64 | Resisted pull distance (px) that arms the refresh. |
| maxPull | number | 120 | Ceiling of the resisted pull (px). |
| holdDistance | number | 56 | Content offset (px) while refreshing. |
| pullingLabel | ReactNode | "Pull to refresh" | Shown while pulling, before the threshold. |
| releaseLabel | ReactNode | "Release to refresh" | Shown once the pull is armed. |
| refreshingLabel | ReactNode | "Refreshing…" | Shown and announced while refreshing. |
| onStatusChange | (status: "idle" | "pulling" | "ready" | "refreshing") => void | — | Called whenever the gesture status changes. |
| contentClassName | string | — | Classes for the content that moves with the pull. |
- data-status
idle,pulling,readyorrefreshingon the root.
| Data attribute | Description |
|---|---|
| data-status | idle, pulling, ready or refreshing on the root. |