Conversation
Let custom feedback follow built-in press targets after native scroll deferral while preserving existing interaction callbacks. Cover quick taps, cancellation, disabled state, callback replacement and cleanup.
Add a card that exposes feedback and activation counters for scroll deferral, quick taps, re-entry and disabling during feedback.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (17)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 SummarySummary by CodeRabbit
WalkthroughChangesVisual press callback
Sequence Diagram(s)sequenceDiagram
participant Touchable
participant GestureHandlerButton
participant NativeButton
participant JavaScriptCallback
NativeButton->>GestureHandlerButton: emit pressed state event
GestureHandlerButton->>Touchable: forward native event
Touchable->>JavaScriptCallback: call onVisualPressChange(pressed)
Suggested reviewers: Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to The callback lifecycle behavior matches its documented contract, with no actionable merge risk identified. 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
Warning Some tools did not complete. Review the errors below. 🔧 ESLint
packages/docs-gesture-handler/docs/components/touchable.mdxParsing error: ESLint was configured to run on Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🟡 Changes recommended
Critical Android and iOS handler-reset paths can leave pending long-press callbacks and stale native press state after handler removal or replacement.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds onVisualPressChange(pressed) to v3 Touchable, exposing native and web visual press transitions for custom feedback.
Changes:
- Adds callback typing and native/web event plumbing.
- Implements platform visual-state tracking with lifecycle tests.
- Adds documentation and a Basic Example demonstration.
File summaries
| File | Summary |
|---|---|
packages/react-native-gesture-handler/src/v3/components/Touchable/TouchableProps.ts |
Defines the public callback type and documentation. |
packages/react-native-gesture-handler/src/v3/components/Touchable/Touchable.tsx |
Forwards visual press events. |
packages/react-native-gesture-handler/src/v3/components/GestureButtonsProps.ts |
Updates internal interaction props. |
packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts |
Adds native event typing. |
packages/react-native-gesture-handler/src/components/GestureHandlerButton.web.tsx |
Implements web visual press tracking. |
packages/react-native-gesture-handler/src/components/GestureHandlerButton.tsx |
Adds shared native button prop support. |
packages/react-native-gesture-handler/src/__tests__/webButtonVisualPress.test.tsx |
Tests web visual press behavior and teardown. |
packages/react-native-gesture-handler/src/__tests__/touchableVisualPress.test.tsx |
Tests Touchable event forwarding. |
packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm |
Dispatches iOS visual press events. |
packages/react-native-gesture-handler/apple/RNGestureHandlerButton.mm |
Tracks iOS visual state. Critical (2 votes): the handler reset does not cancel _pendingLongPressBlock, allowing a stale long-press event after handler removal or replacement. |
packages/react-native-gesture-handler/apple/RNGestureHandlerButton.h |
Declares iOS button APIs. |
packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt |
Tracks Android visual state. Critical (2 votes): handler reset does not cancel pending long presses or clear pressed/touched state, allowing stale callbacks and recycled-view state. |
packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/events/RNGestureHandlerButtonVisualPressEvent.kt |
Defines the Android visual press event. |
packages/react-native-gesture-handler/__typetests__/buttonEventTest.ts |
Verifies the TypeScript API shape. |
packages/docs-gesture-handler/docs/components/touchable.mdx |
Documents the callback. |
apps/basic-example/src/VisualPress.tsx |
Adds the visual press example. |
apps/basic-example/src/App.tsx |
Registers the example screen. |
Review details
- Files reviewed: 17/17 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| pendingPressOut?.let { handler?.removeCallbacks(it) } | ||
| pendingPressOut = null | ||
| pressInTimestamp = 0L | ||
| setVisualPressed(false) | ||
| animateTo(restingOpacity, restingScale, restingUnderlayOpacity, 0) |
|
|
||
| - (void)resetVisualPressState | ||
| { | ||
| [self cancelPendingPressOutAnimation]; |
Why
On Android,
Touchable.onPressIncan run before a parent scroll view permits native press feedback. Custom animations driven by that callback can highlight a button while the user starts to scroll, even when the built-in animation correctly waits.Add
onVisualPressChange(pressed)so custom feedback can follow Touchable's built-in feedback. The reproduction compares the two paths. This exposes the missing feedback signal; #4441 already fixes Android scroll takeover cancellation.Scope
Touchable, with native and web event support.Visual Pressexample inbasic-example.Tradeoffs
The callback runs in JavaScript and reports target changes, not animation completion. It follows existing feedback timing and adds no press-in delay. Native scroll deferral still belongs to the native control.
Verification