feat: optional native pull-to-refresh on iOS and Android
Merged
RI
1d ago+625+625+012345678901234567890123456789-74-74-01234567890123456789
Summary
Opt-in native pull-to-refresh. Off by default: nothing is attached to the WebView until setPullToRefresh({ enabled: true }), and enabled: false restores the original view setup.
await NativeNavigation.setPullToRefresh({ enabled: true, tintColor: '#007aff' });
NativeNavigation.addListener('pullToRefresh', async () => {
await reloadData();
await NativeNavigation.endPullToRefresh();
});
| iOS | Android |
|---|---|
![]() | ![]() |
- iOS: simultaneous pan gesture on the WebView plus the system
UIActivityIndicatorView, placed below the native navbar, with a haptic when the pull arms.UIRefreshControlwas tried first, but it never fires when the page scrolls an inner element (#app, Ionic content), which is the usual Capacitor setup. - Android: the WebView is wrapped in a
SwipeRefreshLayoutonly while enabled (new dependencyandroidx.swiperefreshlayout:1.1.0, overridable withandroidxSwipeRefreshLayoutVersion). The spinner sits below the status bar and navbar. - Both platforms use the scroll offset the page already reports (
window,#app,[data-cap-native-navigation-scroll]), so the gesture only starts when the list is at the top. The offset resets onfinishTransition. - Web: no-op.
- Example app: "Pull to refresh" toggle in the Navbar playground.
- README: new section with both demo clips.
Test plan
-
bun run build,bun run lint(ESLint + Prettier) - iOS
xcodebuild test: 15 tests pass, including the new pull-to-refresh tests - Android
./gradlew build test - Recorded on the iPhone 17 simulator and the Android API 36 emulator with the example app: the refresh fires, the spinner shows below the navbar, and
endPullToRefresh()hides it - Physical device check
- SwiftLint: two errors in existing code (
setTabbarlength, large tuple); the new files lint clean
🤖 Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by CodeRabbit
- New Features
- Added opt-in pull-to-refresh on iOS and Android. Configure spinner colors, listen for refresh events, and stop the spinner when content is ready.
- Added pull-to-refresh controls to the example app. On the web, these controls leave refresh behavior to the browser.
- Documentation
- Added setup instructions, platform notes, and API references for pull-to-refresh.

