From b4a827a02ac9e6a581afbc8c15e9af1368420eb4 Mon Sep 17 00:00:00 2001 From: Yamin Yassin <22322875+yaminyassin@users.noreply.github.com> Date: Sat, 20 Jun 2026 13:50:14 +0100 Subject: [PATCH] Wire pointer capture event props through the Fabric view config Fabric declared onGotPointerCapture / onLostPointerCapture and the capture-phase pointer handlers in its view config, but never parsed them. Fill in both prop parsing paths (convertRawProp and the iterator setProp), add the two missing capture phase offsets, and register the got/lost-capture bubbling event types and validAttributes on iOS and Android. Android was also missing the bubble-phase onPointerDown, onPointerUp and onPointerCancel attributes. --- .../NativeComponent/BaseViewConfig.android.js | 6 +++++ .../NativeComponent/BaseViewConfig.ios.js | 18 ++++++++++--- .../react/uimanager/BaseViewManager.java | 12 +++++++++ .../components/view/BaseViewProps.cpp | 2 ++ .../renderer/components/view/primitives.h | 2 ++ .../components/view/propsConversions.h | 25 ++++++++++++++++++- .../api-snapshots/ReactAndroidDebugCxx.api | 2 ++ .../api-snapshots/ReactAndroidNewarchCxx.api | 2 ++ .../api-snapshots/ReactAndroidReleaseCxx.api | 2 ++ .../api-snapshots/ReactAppleDebugCxx.api | 2 ++ .../api-snapshots/ReactAppleNewarchCxx.api | 2 ++ .../api-snapshots/ReactAppleReleaseCxx.api | 2 ++ .../api-snapshots/ReactCommonDebugCxx.api | 2 ++ .../api-snapshots/ReactCommonNewarchCxx.api | 2 ++ .../api-snapshots/ReactCommonReleaseCxx.api | 2 ++ 15 files changed, 78 insertions(+), 5 deletions(-) diff --git a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js index 0f93c41709c3..573410380255 100644 --- a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js +++ b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js @@ -427,8 +427,14 @@ const validAttributesForEventProps = { // Pointer events onClick: true, onClickCapture: true, + onPointerCancel: true, + onPointerCancelCapture: true, + onPointerDown: true, + onPointerDownCapture: true, onPointerEnter: true, onPointerEnterCapture: true, + onPointerUp: true, + onPointerUpCapture: true, onPointerLeave: true, onPointerLeaveCapture: true, onPointerMove: true, diff --git a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.ios.js b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.ios.js index d22a68642194..4745b8cf0be3 100644 --- a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.ios.js +++ b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.ios.js @@ -411,16 +411,26 @@ const validAttributesForEventProps = ConditionallyIgnoredEventHandlers({ // Pointer events onClick: true, onClickCapture: true, - onPointerUp: true, - onPointerDown: true, onPointerCancel: true, + onPointerCancelCapture: true, + onPointerDown: true, + onPointerDownCapture: true, onPointerEnter: true, - onPointerMove: true, + onPointerEnterCapture: true, + onPointerUp: true, + onPointerUpCapture: true, onPointerLeave: true, - onPointerOver: true, + onPointerLeaveCapture: true, + onPointerMove: true, + onPointerMoveCapture: true, onPointerOut: true, + onPointerOutCapture: true, + onPointerOver: true, + onPointerOverCapture: true, onGotPointerCapture: true, + onGotPointerCaptureCapture: true, onLostPointerCapture: true, + onLostPointerCaptureCapture: true, }); /** diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java index d2747ebda577..88ad3dda0f71 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java @@ -779,6 +779,18 @@ protected void onAfterUpdateTransaction(@NonNull T view) { MapBuilder.of( "phasedRegistrationNames", MapBuilder.of("bubbled", "onPointerOver", "captured", "onPointerOverCapture"))) + .put( + "topGotPointerCapture", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of( + "bubbled", "onGotPointerCapture", "captured", "onGotPointerCaptureCapture"))) + .put( + "topLostPointerCapture", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of( + "bubbled", "onLostPointerCapture", "captured", "onLostPointerCaptureCapture"))) .put( "topClick", MapBuilder.of( diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp index 83d9e5eb5663..b43cb3e19b82 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp @@ -455,7 +455,9 @@ void BaseViewProps::setProp( VIEW_EVENT_CASE(PointerUp); VIEW_EVENT_CASE(PointerUpCapture); VIEW_EVENT_CASE(GotPointerCapture); + VIEW_EVENT_CASE(GotPointerCaptureCapture); VIEW_EVENT_CASE(LostPointerCapture); + VIEW_EVENT_CASE(LostPointerCaptureCapture); VIEW_EVENT_CASE(MoveShouldSetResponder); VIEW_EVENT_CASE(MoveShouldSetResponderCapture); VIEW_EVENT_CASE(StartShouldSetResponder); diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h b/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h index aa7e385229f6..0854db90ca54 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h @@ -67,6 +67,8 @@ struct ViewEvents { PointerDownCapture = 35, PointerUp = 36, PointerUpCapture = 37, + GotPointerCaptureCapture = 38, + LostPointerCaptureCapture = 39, }; constexpr bool operator[](const Offset offset) const diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/propsConversions.h b/packages/react-native/ReactCommon/react/renderer/components/view/propsConversions.h index 985a3bbffb8c..b4718651f38f 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/propsConversions.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/propsConversions.h @@ -517,7 +517,30 @@ static inline ViewEvents convertRawProp( "onPointerUpCapture", sourceValue[Offset::PointerUpCapture], defaultValue[Offset::PointerUpCapture]); - // TODO: gotPointerCapture & lostPointerCapture + result[Offset::GotPointerCapture] = convertRawProp( + context, + rawProps, + "onGotPointerCapture", + sourceValue[Offset::GotPointerCapture], + defaultValue[Offset::GotPointerCapture]); + result[Offset::GotPointerCaptureCapture] = convertRawProp( + context, + rawProps, + "onGotPointerCaptureCapture", + sourceValue[Offset::GotPointerCaptureCapture], + defaultValue[Offset::GotPointerCaptureCapture]); + result[Offset::LostPointerCapture] = convertRawProp( + context, + rawProps, + "onLostPointerCapture", + sourceValue[Offset::LostPointerCapture], + defaultValue[Offset::LostPointerCapture]); + result[Offset::LostPointerCaptureCapture] = convertRawProp( + context, + rawProps, + "onLostPointerCaptureCapture", + sourceValue[Offset::LostPointerCaptureCapture], + defaultValue[Offset::LostPointerCaptureCapture]); // PanResponder callbacks result[Offset::MoveShouldSetResponder] = convertRawProp( diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api index a85c1f0c88b4..f25ef2b3abb5 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api @@ -8060,7 +8060,9 @@ enum facebook::react::ViewEvents::Offset : std::size_t { Click, ClickCapture, GotPointerCapture, + GotPointerCaptureCapture, LostPointerCapture, + LostPointerCaptureCapture, MoveShouldSetResponder, MoveShouldSetResponderCapture, PointerDown, diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api index 837ff53d1b61..80054b4f1274 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api @@ -7824,7 +7824,9 @@ enum facebook::react::ViewEvents::Offset : std::size_t { Click, ClickCapture, GotPointerCapture, + GotPointerCaptureCapture, LostPointerCapture, + LostPointerCaptureCapture, MoveShouldSetResponder, MoveShouldSetResponderCapture, PointerDown, diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api index 3a0800477f40..7c8c617ea0f2 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api @@ -8051,7 +8051,9 @@ enum facebook::react::ViewEvents::Offset : std::size_t { Click, ClickCapture, GotPointerCapture, + GotPointerCaptureCapture, LostPointerCapture, + LostPointerCaptureCapture, MoveShouldSetResponder, MoveShouldSetResponderCapture, PointerDown, diff --git a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api index 5ef595005d8a..286ba25e1a93 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api @@ -10083,7 +10083,9 @@ enum facebook::react::ViewEvents::Offset : std::size_t { Click, ClickCapture, GotPointerCapture, + GotPointerCaptureCapture, LostPointerCapture, + LostPointerCaptureCapture, MoveShouldSetResponder, MoveShouldSetResponderCapture, PointerDown, diff --git a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api index 80f834aa2350..1d591cae2744 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api @@ -9899,7 +9899,9 @@ enum facebook::react::ViewEvents::Offset : std::size_t { Click, ClickCapture, GotPointerCapture, + GotPointerCaptureCapture, LostPointerCapture, + LostPointerCaptureCapture, MoveShouldSetResponder, MoveShouldSetResponderCapture, PointerDown, diff --git a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api index bc1b98fae6e6..b00552096a1f 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api @@ -10074,7 +10074,9 @@ enum facebook::react::ViewEvents::Offset : std::size_t { Click, ClickCapture, GotPointerCapture, + GotPointerCaptureCapture, LostPointerCapture, + LostPointerCaptureCapture, MoveShouldSetResponder, MoveShouldSetResponderCapture, PointerDown, diff --git a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api index 4c3b5750c2a3..1e96d8849ede 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api @@ -6192,7 +6192,9 @@ enum facebook::react::ViewEvents::Offset : std::size_t { Click, ClickCapture, GotPointerCapture, + GotPointerCaptureCapture, LostPointerCapture, + LostPointerCaptureCapture, MoveShouldSetResponder, MoveShouldSetResponderCapture, PointerDown, diff --git a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api index 2492570e8064..1eafe172d521 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api @@ -6020,7 +6020,9 @@ enum facebook::react::ViewEvents::Offset : std::size_t { Click, ClickCapture, GotPointerCapture, + GotPointerCaptureCapture, LostPointerCapture, + LostPointerCaptureCapture, MoveShouldSetResponder, MoveShouldSetResponderCapture, PointerDown, diff --git a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api index 6f46c2322b79..74c9f63f19f3 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api @@ -6183,7 +6183,9 @@ enum facebook::react::ViewEvents::Offset : std::size_t { Click, ClickCapture, GotPointerCapture, + GotPointerCaptureCapture, LostPointerCapture, + LostPointerCaptureCapture, MoveShouldSetResponder, MoveShouldSetResponderCapture, PointerDown,