diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 8f8558e84bd..a4f1e4ebb40 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -2344,10 +2344,10 @@ public class com/facebook/react/fabric/FabricUIManager : com/facebook/react/brid public fun dispatchCommand (IILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V public fun dispatchCommand (ILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V public fun findNextFocusableElement (III)Ljava/lang/Integer; - public fun findRelativeTopMostParent (II)Ljava/lang/Integer; public fun getColor (I[Ljava/lang/String;)I public fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher; public fun getPerformanceCounters ()Ljava/util/Map; + public fun getRelativeAncestorList (II)[I public fun getThemeData (I[F)Z public fun initialize ()V public fun invalidate ()V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 2dd7615a067..14b4439b6ca 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -305,8 +305,8 @@ public class FabricUIManager return serializedNextFocusableNodeMetrics; } - public @Nullable Integer findRelativeTopMostParent(int rootTag, int childTag) { - return mBinding != null ? mBinding.findRelativeTopMostParent(rootTag, childTag) : null; + public @Nullable int[] getRelativeAncestorList(int rootTag, int childTag) { + return mBinding != null ? mBinding.getRelativeAncestorList(rootTag, childTag) : null; } @Override diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManagerBinding.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManagerBinding.kt index f76c676af87..f22661f1d7e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManagerBinding.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManagerBinding.kt @@ -57,7 +57,7 @@ internal class FabricUIManagerBinding : HybridClassBase() { external fun findNextFocusableElement(parentTag: Int, focusedTag: Int, direction: Int): Int - external fun findRelativeTopMostParent(rootTag: Int, childTag: Int): Int + external fun getRelativeAncestorList(rootTag: Int, childTag: Int): IntArray external fun stopSurface(surfaceId: Int) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 9b747dd0250..e68d497babd 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -84,6 +84,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableCppPropsIteratorSetter(): Boolean = accessor.enableCppPropsIteratorSetter() + /** + * This enables the fabric implementation of focus search so that we can focus clipped elements + */ + @JvmStatic + public fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean = accessor.enableCustomFocusSearchOnClippedElementsAndroid() + /** * Feature flag to configure eager attachment of the root view/initialisation of the JS code. */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index 234056e7e23..8236a9d552d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<7394c9300cb0cf05727c57379320810b>> */ /** @@ -29,6 +29,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null private var enableCppPropsIteratorSetterCache: Boolean? = null + private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null private var enableEagerRootViewAttachmentCache: Boolean? = null private var enableFabricLogsCache: Boolean? = null private var enableFabricRendererCache: Boolean? = null @@ -144,6 +145,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean { + var cached = enableCustomFocusSearchOnClippedElementsAndroidCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableCustomFocusSearchOnClippedElementsAndroid() + enableCustomFocusSearchOnClippedElementsAndroidCache = cached + } + return cached + } + override fun enableEagerRootViewAttachment(): Boolean { var cached = enableEagerRootViewAttachmentCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index 504d71efb7f..9032486ce4b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -46,6 +46,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableCppPropsIteratorSetter(): Boolean + @DoNotStrip @JvmStatic public external fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean + @DoNotStrip @JvmStatic public external fun enableEagerRootViewAttachment(): Boolean @DoNotStrip @JvmStatic public external fun enableFabricLogs(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index e240f056b54..a006beb4d27 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -41,6 +41,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableCppPropsIteratorSetter(): Boolean = false + override fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean = true + override fun enableEagerRootViewAttachment(): Boolean = false override fun enableFabricLogs(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index 7e3680912dd..3a30fbd3db6 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<5ea02b7c6aa699b226b7c44e52d8e484>> */ /** @@ -33,6 +33,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null private var enableCppPropsIteratorSetterCache: Boolean? = null + private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null private var enableEagerRootViewAttachmentCache: Boolean? = null private var enableFabricLogsCache: Boolean? = null private var enableFabricRendererCache: Boolean? = null @@ -157,6 +158,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean { + var cached = enableCustomFocusSearchOnClippedElementsAndroidCache + if (cached == null) { + cached = currentProvider.enableCustomFocusSearchOnClippedElementsAndroid() + accessedFeatureFlags.add("enableCustomFocusSearchOnClippedElementsAndroid") + enableCustomFocusSearchOnClippedElementsAndroidCache = cached + } + return cached + } + override fun enableEagerRootViewAttachment(): Boolean { var cached = enableEagerRootViewAttachmentCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index 01d9b41901a..08ced185216 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<76da11369c2f7b8955a154a63af374a3>> + * @generated SignedSource<> */ /** @@ -41,6 +41,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableCppPropsIteratorSetter(): Boolean + @DoNotStrip public fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean + @DoNotStrip public fun enableEagerRootViewAttachment(): Boolean @DoNotStrip public fun enableFabricLogs(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java index 0c3ed4e7b25..82c60e7b8fc 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java @@ -41,6 +41,7 @@ import com.facebook.react.animated.NativeAnimatedModule; import com.facebook.react.bridge.ReactContext; import com.facebook.react.common.ReactConstants; import com.facebook.react.common.build.ReactBuildConfig; +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; import com.facebook.react.uimanager.BackgroundStyleApplicator; import com.facebook.react.uimanager.LengthPercentage; import com.facebook.react.uimanager.LengthPercentageType; @@ -776,10 +777,12 @@ public class ReactHorizontalScrollView extends HorizontalScrollView @Override public @Nullable View focusSearch(View focused, @FocusRealDirection int direction) { - @Nullable View nextfocusableView = findNextFocusableView(this, focused, direction, true); + if (ReactNativeFeatureFlags.enableCustomFocusSearchOnClippedElementsAndroid()) { + @Nullable View nextfocusableView = findNextFocusableView(this, focused, direction, true); - if (nextfocusableView != null) { - return nextfocusableView; + if (nextfocusableView != null) { + return nextfocusableView; + } } return super.focusSearch(focused, direction); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java index 8cdbcae3d8a..2e0c20dfa0d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java @@ -41,6 +41,7 @@ import com.facebook.react.animated.NativeAnimatedModule; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.common.ReactConstants; +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; import com.facebook.react.uimanager.BackgroundStyleApplicator; import com.facebook.react.uimanager.LengthPercentage; import com.facebook.react.uimanager.LengthPercentageType; @@ -364,11 +365,12 @@ public class ReactScrollView extends ScrollView @Override public @Nullable View focusSearch(View focused, @FocusRealDirection int direction) { + if (ReactNativeFeatureFlags.enableCustomFocusSearchOnClippedElementsAndroid()) { + @Nullable View nextfocusableView = findNextFocusableView(this, focused, direction, false); - @Nullable View nextfocusableView = findNextFocusableView(this, focused, direction, false); - - if (nextfocusableView != null) { - return nextfocusableView; + if (nextfocusableView != null) { + return nextfocusableView; + } } return super.focusSearch(focused, direction); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt index a86e571c612..9714d323aa2 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt @@ -499,11 +499,14 @@ public object ReactScrollViewHelper { (uimanager as FabricUIManager).findNextFocusableElement( host.getChildAt(0).id, focused.id, absDir) ?: return null - val nextFocusTopMostParentId = - uimanager.findRelativeTopMostParent(host.getChildAt(0).id, nextFocusableViewId) - ?: return null + val ancestorIdList = + uimanager + .getRelativeAncestorList(host.getChildAt(0).id, nextFocusableViewId) + ?.toMutableSet() ?: return null - host.updateClippingRect(setOf(nextFocusableViewId, nextFocusTopMostParentId)) + ancestorIdList.add(nextFocusableViewId) + + host.updateClippingRect(ancestorIdList) return host.findViewById(nextFocusableViewId) } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java index c2996ed2056..c2801edd45b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java @@ -507,9 +507,6 @@ public class ReactViewGroup extends ViewGroup Animation animation = child.getAnimation(); boolean isAnimating = animation != null && !animation.hasEnded(); boolean shouldSkipView = excludedViewsSet != null && excludedViewsSet.contains(child.getId()); - if (excludedViewsSet != null) { - needUpdateClippingRecursive = true; - } // We don't want to clip a view that is currently focused at that might break focus navigation if (!intersects && !isViewClipped(child, idx) @@ -521,7 +518,7 @@ public class ReactViewGroup extends ViewGroup // therefore invalidation is not necessary. removeViewInLayout(child); needUpdateClippingRecursive = true; - } else if (shouldSkipView || (intersects && isViewClipped(child, idx))) { + } else if ((shouldSkipView || intersects) && isViewClipped(child, idx)) { int adjustedIdx = idx - clippedSoFar; Assertions.assertCondition(adjustedIdx >= 0); setViewClipped(child, false); diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp index 50f20e19aa3..2abaa0a06b7 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp @@ -253,9 +253,11 @@ jint FabricUIManagerBinding::findNextFocusableElement( return nextNode->getTag(); } -jint FabricUIManagerBinding::findRelativeTopMostParent( +jintArray FabricUIManagerBinding::getRelativeAncestorList( jint rootTag, jint childTag) { + JNIEnv* env = jni::Environment::current(); + std::shared_ptr uimanager = getScheduler()->getUIManager(); ShadowNode::Shared childShadowNode = @@ -264,27 +266,33 @@ jint FabricUIManagerBinding::findRelativeTopMostParent( uimanager->findShadowNodeByTag_DEPRECATED(rootTag); if (childShadowNode == nullptr || rootShadowNode == nullptr) { - return -1; + return nullptr; } ShadowNode::AncestorList ancestorList = childShadowNode->getFamily().getAncestors(*rootShadowNode); if (ancestorList.empty() || ancestorList.size() < 2) { - return -1; + return nullptr; } // ignore the first ancestor as it is the rootShadowNode itself + std::vector ancestorTags; for (auto it = std::next(ancestorList.begin()); it != ancestorList.end(); ++it) { auto& ancestor = *it; if (ancestor.first.get().getTraits().check( ShadowNodeTraits::Trait::FormsStackingContext)) { - return ancestor.first.get().getTag(); + ancestorTags.push_back(ancestor.first.get().getTag()); } } - return -1; + jintArray result = env->NewIntArray(static_cast(ancestorTags.size())); + + env->SetIntArrayRegion( + result, 0, static_cast(ancestorTags.size()), ancestorTags.data()); + + return result; } // Used by non-bridgeless+Fabric @@ -763,8 +771,8 @@ void FabricUIManagerBinding::registerNatives() { "findNextFocusableElement", FabricUIManagerBinding::findNextFocusableElement), makeNativeMethod( - "findRelativeTopMostParent", - FabricUIManagerBinding::findRelativeTopMostParent), + "getRelativeAncestorList", + FabricUIManagerBinding::getRelativeAncestorList), }); } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h index e045425269d..4cd9f26cd05 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h @@ -135,7 +135,7 @@ class FabricUIManagerBinding : public jni::HybridClass, jint findNextFocusableElement(jint parentTag, jint focusedTag, jint direction); - jint findRelativeTopMostParent(jint rootTag, jint childTag); + jintArray getRelativeAncestorList(jint rootTag, jint childTag); void uninstallFabricUIManager(); diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index 786a2c461ba..334038c855d 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<4c4d84c0af6906301c32d59c129b90f8>> */ /** @@ -93,6 +93,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + bool enableCustomFocusSearchOnClippedElementsAndroid() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableCustomFocusSearchOnClippedElementsAndroid"); + return method(javaProvider_); + } + bool enableEagerRootViewAttachment() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableEagerRootViewAttachment"); @@ -340,6 +346,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableCppPropsIteratorSetter( return ReactNativeFeatureFlags::enableCppPropsIteratorSetter(); } +bool JReactNativeFeatureFlagsCxxInterop::enableCustomFocusSearchOnClippedElementsAndroid( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableCustomFocusSearchOnClippedElementsAndroid(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableEagerRootViewAttachment( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableEagerRootViewAttachment(); @@ -563,6 +574,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableCppPropsIteratorSetter", JReactNativeFeatureFlagsCxxInterop::enableCppPropsIteratorSetter), + makeNativeMethod( + "enableCustomFocusSearchOnClippedElementsAndroid", + JReactNativeFeatureFlagsCxxInterop::enableCustomFocusSearchOnClippedElementsAndroid), makeNativeMethod( "enableEagerRootViewAttachment", JReactNativeFeatureFlagsCxxInterop::enableEagerRootViewAttachment), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index a8e7ddce1bb..f010efc3849 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -57,6 +57,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableCppPropsIteratorSetter( facebook::jni::alias_ref); + static bool enableCustomFocusSearchOnClippedElementsAndroid( + facebook::jni::alias_ref); + static bool enableEagerRootViewAttachment( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 86384b2a14b..fa92cafa5aa 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<5ee10cdf8f5e3695ce4f73373291935e>> + * @generated SignedSource<<59350280417b80ed92aa7eacf3223c4e>> */ /** @@ -62,6 +62,10 @@ bool ReactNativeFeatureFlags::enableCppPropsIteratorSetter() { return getAccessor().enableCppPropsIteratorSetter(); } +bool ReactNativeFeatureFlags::enableCustomFocusSearchOnClippedElementsAndroid() { + return getAccessor().enableCustomFocusSearchOnClippedElementsAndroid(); +} + bool ReactNativeFeatureFlags::enableEagerRootViewAttachment() { return getAccessor().enableEagerRootViewAttachment(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 89a641961e7..7dc1d7b54aa 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<7f2965f0a6e4fbed816795866623cfb3>> */ /** @@ -84,6 +84,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableCppPropsIteratorSetter(); + /** + * This enables the fabric implementation of focus search so that we can focus clipped elements + */ + RN_EXPORT static bool enableCustomFocusSearchOnClippedElementsAndroid(); + /** * Feature flag to configure eager attachment of the root view/initialisation of the JS code. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index fb424a14633..18b849b9432 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<4c18c271811129f1e1411fc2666aeb38>> + * @generated SignedSource<> */ /** @@ -191,6 +191,24 @@ bool ReactNativeFeatureFlagsAccessor::enableCppPropsIteratorSetter() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableCustomFocusSearchOnClippedElementsAndroid() { + auto flagValue = enableCustomFocusSearchOnClippedElementsAndroid_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(9, "enableCustomFocusSearchOnClippedElementsAndroid"); + + flagValue = currentProvider_->enableCustomFocusSearchOnClippedElementsAndroid(); + enableCustomFocusSearchOnClippedElementsAndroid_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableEagerRootViewAttachment() { auto flagValue = enableEagerRootViewAttachment_.load(); @@ -200,7 +218,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEagerRootViewAttachment() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(9, "enableEagerRootViewAttachment"); + markFlagAsAccessed(10, "enableEagerRootViewAttachment"); flagValue = currentProvider_->enableEagerRootViewAttachment(); enableEagerRootViewAttachment_ = flagValue; @@ -218,7 +236,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricLogs() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(10, "enableFabricLogs"); + markFlagAsAccessed(11, "enableFabricLogs"); flagValue = currentProvider_->enableFabricLogs(); enableFabricLogs_ = flagValue; @@ -236,7 +254,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRenderer() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(11, "enableFabricRenderer"); + markFlagAsAccessed(12, "enableFabricRenderer"); flagValue = currentProvider_->enableFabricRenderer(); enableFabricRenderer_ = flagValue; @@ -254,7 +272,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFixForParentTagDuringReparenting() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(12, "enableFixForParentTagDuringReparenting"); + markFlagAsAccessed(13, "enableFixForParentTagDuringReparenting"); flagValue = currentProvider_->enableFixForParentTagDuringReparenting(); enableFixForParentTagDuringReparenting_ = flagValue; @@ -272,7 +290,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFontScaleChangesUpdatingLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(13, "enableFontScaleChangesUpdatingLayout"); + markFlagAsAccessed(14, "enableFontScaleChangesUpdatingLayout"); flagValue = currentProvider_->enableFontScaleChangesUpdatingLayout(); enableFontScaleChangesUpdatingLayout_ = flagValue; @@ -290,7 +308,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(14, "enableIOSViewClipToPaddingBox"); + markFlagAsAccessed(15, "enableIOSViewClipToPaddingBox"); flagValue = currentProvider_->enableIOSViewClipToPaddingBox(); enableIOSViewClipToPaddingBox_ = flagValue; @@ -308,7 +326,7 @@ bool ReactNativeFeatureFlagsAccessor::enableJSRuntimeGCOnMemoryPressureOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(15, "enableJSRuntimeGCOnMemoryPressureOnIOS"); + markFlagAsAccessed(16, "enableJSRuntimeGCOnMemoryPressureOnIOS"); flagValue = currentProvider_->enableJSRuntimeGCOnMemoryPressureOnIOS(); enableJSRuntimeGCOnMemoryPressureOnIOS_ = flagValue; @@ -326,7 +344,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(16, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(17, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -344,7 +362,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(17, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(18, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -362,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMainQueueModulesOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(18, "enableMainQueueModulesOnIOS"); + markFlagAsAccessed(19, "enableMainQueueModulesOnIOS"); flagValue = currentProvider_->enableMainQueueModulesOnIOS(); enableMainQueueModulesOnIOS_ = flagValue; @@ -380,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNativeCSSParsing() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(19, "enableNativeCSSParsing"); + markFlagAsAccessed(20, "enableNativeCSSParsing"); flagValue = currentProvider_->enableNativeCSSParsing(); enableNativeCSSParsing_ = flagValue; @@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNewBackgroundAndBorderDrawables() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(20, "enableNewBackgroundAndBorderDrawables"); + markFlagAsAccessed(21, "enableNewBackgroundAndBorderDrawables"); flagValue = currentProvider_->enableNewBackgroundAndBorderDrawables(); enableNewBackgroundAndBorderDrawables_ = flagValue; @@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePropsUpdateReconciliationAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(21, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(22, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(22, "enableSynchronousStateUpdates"); + markFlagAsAccessed(23, "enableSynchronousStateUpdates"); flagValue = currentProvider_->enableSynchronousStateUpdates(); enableSynchronousStateUpdates_ = flagValue; @@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewCulling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(23, "enableViewCulling"); + markFlagAsAccessed(24, "enableViewCulling"); flagValue = currentProvider_->enableViewCulling(); enableViewCulling_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "enableViewRecycling"); + markFlagAsAccessed(25, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForText() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "enableViewRecyclingForText"); + markFlagAsAccessed(26, "enableViewRecyclingForText"); flagValue = currentProvider_->enableViewRecyclingForText(); enableViewRecyclingForText_ = flagValue; @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "enableViewRecyclingForView"); + markFlagAsAccessed(27, "enableViewRecyclingForView"); flagValue = currentProvider_->enableViewRecyclingForView(); enableViewRecyclingForView_ = flagValue; @@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(27, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(28, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "fuseboxEnabledRelease"); + markFlagAsAccessed(29, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxNetworkInspectionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "fuseboxNetworkInspectionEnabled"); + markFlagAsAccessed(30, "fuseboxNetworkInspectionEnabled"); flagValue = currentProvider_->fuseboxNetworkInspectionEnabled(); fuseboxNetworkInspectionEnabled_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::removeTurboModuleManagerDelegateMutex() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "removeTurboModuleManagerDelegateMutex"); + markFlagAsAccessed(31, "removeTurboModuleManagerDelegateMutex"); flagValue = currentProvider_->removeTurboModuleManagerDelegateMutex(); removeTurboModuleManagerDelegateMutex_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(32, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(33, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(34, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::useEditTextStockAndroidFocusBehavior() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "useEditTextStockAndroidFocusBehavior"); + markFlagAsAccessed(35, "useEditTextStockAndroidFocusBehavior"); flagValue = currentProvider_->useEditTextStockAndroidFocusBehavior(); useEditTextStockAndroidFocusBehavior_ = flagValue; @@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "useFabricInterop"); + markFlagAsAccessed(36, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(37, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(38, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "useRawPropsJsiValue"); + markFlagAsAccessed(39, "useRawPropsJsiValue"); flagValue = currentProvider_->useRawPropsJsiValue(); useRawPropsJsiValue_ = flagValue; @@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::useShadowNodeStateOnClone() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "useShadowNodeStateOnClone"); + markFlagAsAccessed(40, "useShadowNodeStateOnClone"); flagValue = currentProvider_->useShadowNodeStateOnClone(); useShadowNodeStateOnClone_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "useTurboModuleInterop"); + markFlagAsAccessed(41, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -776,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "useTurboModules"); + markFlagAsAccessed(42, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 8455dc8a56b..e8be4deb576 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<4338d98b457f8f70a9f8bbe8ab245ce8>> + * @generated SignedSource<<775dea42ec82d31964c9614d86b3e107>> */ /** @@ -41,6 +41,7 @@ class ReactNativeFeatureFlagsAccessor { bool enableAccumulatedUpdatesInRawPropsAndroid(); bool enableBridgelessArchitecture(); bool enableCppPropsIteratorSetter(); + bool enableCustomFocusSearchOnClippedElementsAndroid(); bool enableEagerRootViewAttachment(); bool enableFabricLogs(); bool enableFabricRenderer(); @@ -85,7 +86,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 42> accessedFeatureFlags_; + std::array, 43> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> animatedShouldSignalBatch_; @@ -96,6 +97,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableAccumulatedUpdatesInRawPropsAndroid_; std::atomic> enableBridgelessArchitecture_; std::atomic> enableCppPropsIteratorSetter_; + std::atomic> enableCustomFocusSearchOnClippedElementsAndroid_; std::atomic> enableEagerRootViewAttachment_; std::atomic> enableFabricLogs_; std::atomic> enableFabricRenderer_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 61cd622c4f9..fca3f21c7b0 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<2eb8786fbcf716f02200770bba667f48>> + * @generated SignedSource<<213ad9500f8da21c569e104f7c5381c6>> */ /** @@ -63,6 +63,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool enableCustomFocusSearchOnClippedElementsAndroid() override { + return true; + } + bool enableEagerRootViewAttachment() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 8ae69f91b90..8d57b08ea5a 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<74978e3a2abd1ec238127003e33b51bd>> + * @generated SignedSource<<20c21d98c3794f426f0146023ba9fa3d>> */ /** @@ -126,6 +126,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::enableCppPropsIteratorSetter(); } + bool enableCustomFocusSearchOnClippedElementsAndroid() override { + auto value = values_["enableCustomFocusSearchOnClippedElementsAndroid"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::enableCustomFocusSearchOnClippedElementsAndroid(); + } + bool enableEagerRootViewAttachment() override { auto value = values_["enableEagerRootViewAttachment"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index e44ad9f1c95..b7541d79cb0 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<49c3003d551dc87d22811c92ad16a76c>> + * @generated SignedSource<<7078d82e6af6271cab490fd017dd9ae0>> */ /** @@ -34,6 +34,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableAccumulatedUpdatesInRawPropsAndroid() = 0; virtual bool enableBridgelessArchitecture() = 0; virtual bool enableCppPropsIteratorSetter() = 0; + virtual bool enableCustomFocusSearchOnClippedElementsAndroid() = 0; virtual bool enableEagerRootViewAttachment() = 0; virtual bool enableFabricLogs() = 0; virtual bool enableFabricRenderer() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 20ef94ed163..111af74a4f9 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<48fbc60de3ca7d6e9c106f451fd0683c>> + * @generated SignedSource<<712f8a51c657c519e19f79ae3d374930>> */ /** @@ -89,6 +89,11 @@ bool NativeReactNativeFeatureFlags::enableCppPropsIteratorSetter( return ReactNativeFeatureFlags::enableCppPropsIteratorSetter(); } +bool NativeReactNativeFeatureFlags::enableCustomFocusSearchOnClippedElementsAndroid( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableCustomFocusSearchOnClippedElementsAndroid(); +} + bool NativeReactNativeFeatureFlags::enableEagerRootViewAttachment( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableEagerRootViewAttachment(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 22b13ba1f67..2c98187556b 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<5bd90040747e90e28f36243cf6c473d0>> + * @generated SignedSource<> */ /** @@ -55,6 +55,8 @@ class NativeReactNativeFeatureFlags bool enableCppPropsIteratorSetter(jsi::Runtime& runtime); + bool enableCustomFocusSearchOnClippedElementsAndroid(jsi::Runtime& runtime); + bool enableEagerRootViewAttachment(jsi::Runtime& runtime); bool enableFabricLogs(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 562016036b3..9f9c55333d2 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -145,6 +145,16 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + enableCustomFocusSearchOnClippedElementsAndroid: { + defaultValue: true, + metadata: { + description: + 'This enables the fabric implementation of focus search so that we can focus clipped elements', + expectedReleaseValue: true, + purpose: 'operational', + }, + ossReleaseStage: 'none', + }, enableEagerRootViewAttachment: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index c4cc7849e8c..437a346de60 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<95280f033ae8492b6fdf610d0d94fff6>> + * @generated SignedSource<> * @flow strict */ @@ -55,6 +55,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ enableAccumulatedUpdatesInRawPropsAndroid: Getter, enableBridgelessArchitecture: Getter, enableCppPropsIteratorSetter: Getter, + enableCustomFocusSearchOnClippedElementsAndroid: Getter, enableEagerRootViewAttachment: Getter, enableFabricLogs: Getter, enableFabricRenderer: Getter, @@ -190,6 +191,10 @@ export const enableBridgelessArchitecture: Getter = createNativeFlagGet * Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java). */ export const enableCppPropsIteratorSetter: Getter = createNativeFlagGetter('enableCppPropsIteratorSetter', false); +/** + * This enables the fabric implementation of focus search so that we can focus clipped elements + */ +export const enableCustomFocusSearchOnClippedElementsAndroid: Getter = createNativeFlagGetter('enableCustomFocusSearchOnClippedElementsAndroid', true); /** * Feature flag to configure eager attachment of the root view/initialisation of the JS code. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 115c5b213ca..fcb329eaeeb 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<7526f36924ba650136380fa0fbd2ee60>> + * @generated SignedSource<<19d3a50e060220a7e0619eceddac025d>> * @flow strict */ @@ -33,6 +33,7 @@ export interface Spec extends TurboModule { +enableAccumulatedUpdatesInRawPropsAndroid?: () => boolean; +enableBridgelessArchitecture?: () => boolean; +enableCppPropsIteratorSetter?: () => boolean; + +enableCustomFocusSearchOnClippedElementsAndroid?: () => boolean; +enableEagerRootViewAttachment?: () => boolean; +enableFabricLogs?: () => boolean; +enableFabricRenderer?: () => boolean;