Pull Refresh Island
A gooey pull-to-refresh where a water drop is pulled out of the Dynamic Island.
Prerequisites
This animation is built on the following libraries. expo install pins the versions that match your SDK, and the CLI tells you exactly which ones are missing when you add the component.
npx expo install react-native-reanimated react-native-gesture-handler @shopify/react-native-skia expo-haptics react-native-safe-area-context react-native-cssInstall
npx @rslab/cli add pull-refresh-islandUsage
import { PullRefreshIsland } from '@/components/PullRefreshIsland';
<PullRefreshIsland onRefresh={async () => await reload()}>
{/* scrollable content */}
</PullRefreshIsland>;Props
| Prop | Type | Default | Description |
|---|---|---|---|
onRefresh | () => Promise<void> | void | none | Called on release past the threshold. |
threshold | number | 100 | Pull distance (pt) that triggers a refresh. |
className | string | none | Container classes (NativeWind). |
contentContainerClassName | string | none | Classes for the scroll content wrapper. |
How it works
- Metaballs. The island and the drop are plain black shapes on a Skia canvas, inside a layer that applies a
Blurthen aColorMatrixthat sharpens the blurred alpha back into a hard edge. When the shapes are close their blurred alphas overlap and survive the threshold: that overlap is the liquid neck, and it snaps on its own as the drop travels away. - Gesture. A
Pangesture runs simultaneously with the ScrollView and only accumulates at the top of the scroll, with progressive resistance. Past the threshold, release holds the drop in place, runsonRefresh, then springs everything back. - Dynamic Island detection. Island devices report a top inset of 59pt or more, and the island sits 48pt above the bottom of that inset. On devices without an island the drop drips from the top edge instead.
Tuning
Blur blur={6}: how far the liquid reaches, higher means thicker gooGOO_MATRIX(40, -18): edge sharpness of the thresholded alphaDROP_RADIUS: size of the detached dropholdY: where the drop rests while refreshing