[General] Implement basic button interactions using native primitives#4032
[General] Implement basic button interactions using native primitives#4032j-piasecki wants to merge 25 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds configurable “pressed” interactions (opacity, scale, underlay) to GestureHandlerButton implemented with platform-native animation primitives (Android ObjectAnimator, Apple CoreAnimation/layer animation, web CSS transitions), and adjusts web pointer-capture behavior for button-role views.
Changes:
- Introduces new button interaction props (
animationDuration,activeOpacity/Scale/UnderlayOpacity,startOpacity/Scale/UnderlayOpacity,underlayColor) in the JS types and native codegen spec. - Implements press-in / press-out animations natively on Android and Apple (including an underlay layer/drawable).
- Implements web press visuals via pointer events + CSS transitions, and updates pointer-capture logic to treat role="button" differently.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/react-native-gesture-handler/src/web/tools/PointerEventManager.ts | Skips pointer capture when the managed view is role="button". |
| packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts | Adds codegen props for interaction animations and underlay. |
| packages/react-native-gesture-handler/src/components/GestureHandlerButton.web.tsx | Adds pressed state handling + CSS transitions + underlay rendering on web. |
| packages/react-native-gesture-handler/src/components/GestureHandlerButton.tsx | Exposes new interaction props on the public ButtonProps interface. |
| packages/react-native-gesture-handler/apple/RNGestureHandlerButtonManager.mm | Removes legacy iOS view manager implementation. |
| packages/react-native-gesture-handler/apple/RNGestureHandlerButtonManager.h | Removes legacy iOS view manager header. |
| packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm | Wires new props into the Fabric component view and applies initial animation state. |
| packages/react-native-gesture-handler/apple/RNGestureHandlerButton.mm | Implements Apple-side press animations and underlay layer handling. |
| packages/react-native-gesture-handler/apple/RNGestureHandlerButton.h | Declares new interaction/underlay properties and helpers. |
| packages/react-native-gesture-handler/apple/RNGHUIKit.h | Adds a cross-platform RNGHColor typedef for UIColor/NSColor. |
| packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt | Implements Android-side press animations and underlay drawable layering. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts
Outdated
Show resolved
Hide resolved
...ndroid/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt
Show resolved
Hide resolved
...ndroid/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt
Outdated
Show resolved
Hide resolved
packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm
Show resolved
Hide resolved
packages/react-native-gesture-handler/apple/RNGestureHandlerButton.mm
Outdated
Show resolved
Hide resolved
packages/react-native-gesture-handler/src/web/tools/PointerEventManager.ts
Show resolved
Hide resolved
packages/react-native-gesture-handler/src/components/GestureHandlerButton.web.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
This PR adds native-driven (or platform-primitive) press feedback for GestureHandlerButton by introducing new animation/underlay props and implementing the corresponding behavior on Android, Apple platforms, and web, along with a small web pointer-capture adjustment to support button-like interactions.
Changes:
- Add new press-animation props (
animationDuration,active*,start*,underlayColor) to the button spec/types and propagate them into native implementations. - Implement press animations using native primitives (Android
ObjectAnimator/Drawable, AppleCALayer/CoreAnimation, web CSS transitions). - Adjust web pointer-capture behavior to avoid capturing pointers for elements with
role="button".
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/react-native-gesture-handler/src/web/tools/PointerEventManager.ts | Skip pointer capture when the managed view has role="button". |
| packages/react-native-gesture-handler/src/v3/components/GestureButtonsProps.ts | Update v3 RawButtonProps typing to omit new animation props. |
| packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx | Type RawButton wrapper with RawButtonProps. |
| packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts | Add new codegen props with defaults for native button interactions. |
| packages/react-native-gesture-handler/src/components/GestureHandlerButton.web.tsx | Implement pressed-state visuals via CSS transitions + optional underlay. |
| packages/react-native-gesture-handler/src/components/GestureHandlerButton.tsx | Add wrapper “resting” style derived from startOpacity/startScale. |
| packages/react-native-gesture-handler/apple/RNGestureHandlerButtonManager.mm | Remove legacy view manager implementation (file deleted). |
| packages/react-native-gesture-handler/apple/RNGestureHandlerButtonManager.h | Remove legacy view manager header (file deleted). |
| packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm | Wire new props into the native button view and apply initial state. |
| packages/react-native-gesture-handler/apple/RNGestureHandlerButton.mm | Implement underlay + press animations using CoreAnimation/UIView/NSAnimationContext. |
| packages/react-native-gesture-handler/apple/RNGestureHandlerButton.h | Declare new animation/underlay properties and applyStartAnimationState. |
| packages/react-native-gesture-handler/apple/RNGHUIKit.h | Add cross-platform RNGHColor typedef (UIColor/NSColor). |
| packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt | Add animation/underlay props + implement press animations with animators/drawables. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
packages/react-native-gesture-handler/src/v3/components/GestureButtonsProps.ts
Show resolved
Hide resolved
packages/react-native-gesture-handler/apple/RNGestureHandlerButton.mm
Outdated
Show resolved
Hide resolved
...ndroid/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt
Outdated
Show resolved
Hide resolved
| shouldCancelWhenOutside: false, | ||
| shouldActivateOnStart: false, | ||
| }); | ||
| export const RawButton = createNativeWrapper<unknown, RawButtonProps>( |
There was a problem hiding this comment.
This is the type that was previously being resolved. I don't think we have an explicit "bare" button ref, no?
There was a problem hiding this comment.
There's this discussion in Clickable, but I guess we can change that there.
Description
Implements basic button interactions (scale, opacity, underlay) using the native primitives and animations instead of relying on JS:
ObjectAnimatorandDrawableon AndroidCALayeron iOS/macOSTest plan
Tested on this