Pull To Refresh
Wrap any scrollable list to add the standard mobile pull-down-to-refresh gesture with promise-aware progress indicators.
Basic Usage
Pull down to refresh
Touch the panel below, drag down past the threshold, and release. Promise-aware indicator stays visible until refresh resolves.
import { PullToRefresh } from 'fluxo-ui';
<PullToRefresh onRefresh={async () => {
await fetchLatest();
}}>
{/* scrollable content */}
</PullToRefresh>Indicator Variants
Spinner (default)
A refresh icon that rotates with pull progress and spins while refreshing.
Arrow
An arrow that flips upside down once the threshold is reached.
Dots
Three bouncing dots — minimal and unobtrusive.
Minimal
Just a thin progress bar with no text label.
<PullToRefresh variant="dots" onRefresh={refresh}>
{/* scrollable content */}
</PullToRefresh>Custom Thresholds & Labels
Custom thresholds & labels
Raise the threshold to require a longer pull, cap the maxPull travel, and customize each indicator label.
<PullToRefresh
threshold={90}
maxPull={160}
refreshingText="Syncing your inbox…"
pullingText="Keep pulling"
releaseText="Release to sync"
onRefresh={sync}
>{...}</PullToRefresh>Import
import { PullToRefresh } from 'fluxo-ui';
import type { PullToRefreshProps, PullToRefreshVariant } from 'fluxo-ui';Props
onRefreshreq() => void | Promise<void>Called when the user releases past the threshold. Return a Promise to keep the spinner visible until the work completes.
onRefreshreq() => void | Promise<void>Called when the user releases past the threshold. Return a Promise to keep the spinner visible until the work completes.
childrenreqReactNodeScrollable content to wrap.
childrenreqReactNodeScrollable content to wrap.
thresholdnumber"64"Distance in pixels the user must pull before a refresh is triggered.
thresholdnumber"64"Distance in pixels the user must pull before a refresh is triggered.
maxPullnumber"120"Maximum visual pull distance (after drag resistance).
maxPullnumber"120"Maximum visual pull distance (after drag resistance).
disabledboolean"false"Disable the gesture entirely.
disabledboolean"false"Disable the gesture entirely.
variant'spinner' | 'arrow' | 'dots' | 'minimal'"'spinner'"Indicator style. 'spinner' rotates with pull progress, 'arrow' flips on threshold, 'dots' shows three bouncing dots, 'minimal' shows a plain bar.
variant'spinner' | 'arrow' | 'dots' | 'minimal'"'spinner'"Indicator style. 'spinner' rotates with pull progress, 'arrow' flips on threshold, 'dots' shows three bouncing dots, 'minimal' shows a plain bar.
refreshingTextstring"'Refreshing…'"Indicator label shown while the promise is pending.
refreshingTextstring"'Refreshing…'"Indicator label shown while the promise is pending.
pullingTextstring"'Pull to refresh'"Indicator label shown while pulling but before threshold.
pullingTextstring"'Pull to refresh'"Indicator label shown while pulling but before threshold.
releaseTextstring"'Release to refresh'"Indicator label shown once the threshold is reached.
releaseTextstring"'Release to refresh'"Indicator label shown once the threshold is reached.
classNamestringAdditional CSS class for the wrapper.
classNamestringAdditional CSS class for the wrapper.
scrollContainerHTMLElement | nullExternal scroll container to observe instead of the wrapper. Useful when the scrollable element lives below this wrapper.
scrollContainerHTMLElement | nullExternal scroll container to observe instead of the wrapper. Useful when the scrollable element lives below this wrapper.
Features
Touch & promise-aware
Indicator stays visible until the returned promise resolves.
Velocity dismissal
A fast flick triggers refresh even without crossing the full threshold.
Four indicator variants
spinner, arrow, dots, or a minimal bar — pick what fits the screen.
Custom labels
Localize pulling, release, and refreshing text.
External scroll container
Point at any scrollable element via scrollContainer when the scroller lives below the wrapper.
Reduced motion
Animation and inertial transitions disable themselves under prefers-reduced-motion.