diff --git a/packages/react-native/Libraries/Components/View/ViewNativeComponent.js b/packages/react-native/Libraries/Components/View/ViewNativeComponent.js index 01013e279933..192456169e75 100644 --- a/packages/react-native/Libraries/Components/View/ViewNativeComponent.js +++ b/packages/react-native/Libraries/Components/View/ViewNativeComponent.js @@ -21,12 +21,14 @@ const ViewNativeComponent: HostComponent = })); interface NativeCommands { + +focus: () => void; + +blur: () => void; +hotspotUpdate: (viewRef: HostInstance, x: number, y: number) => void; +setPressed: (viewRef: HostInstance, pressed: boolean) => void; } export const Commands: NativeCommands = codegenNativeCommands({ - supportedCommands: ['hotspotUpdate', 'setPressed'], + supportedCommands: ['focus', 'blur', 'hotspotUpdate', 'setPressed'], }); /** diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm index 2b219f3a62bc..eda8cacb542f 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm @@ -1540,6 +1540,62 @@ - (void)transferVisualPropertiesFromView:(UIView *)sourceView toView:(UIView *)d } } +- (BOOL)canBecomeFirstResponder +{ + return YES; +} + +- (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args +{ + if ([commandName isEqualToString:@"focus"]) { + [self focus]; + return; + } + + if ([commandName isEqualToString:@"blur"]) { + [self blur]; + return; + } +} + +- (void)focus +{ + [self becomeFirstResponder]; +} + +- (void)blur +{ + [self resignFirstResponder]; +} + +#pragma mark - Focus Events + +- (BOOL)becomeFirstResponder +{ + if (![super becomeFirstResponder]) { + return NO; + } + + if (_eventEmitter && ReactNativeFeatureFlags::enableImperativeFocus()) { + _eventEmitter->onFocus(); + } + + return YES; +} + +- (BOOL)resignFirstResponder +{ + if (![super resignFirstResponder]) { + return NO; + } + + if (_eventEmitter && ReactNativeFeatureFlags::enableImperativeFocus()) { + _eventEmitter->onBlur(); + } + + return YES; +} + @end #ifdef __cplusplus 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 6fd9fc212b58..bf1a86854dc7 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<> */ /** @@ -192,6 +192,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean = accessor.enableImmediateUpdateModeForContentOffsetChanges() + /** + * Enable ref.focus() and ref.blur() for all views, not just TextInput. + */ + @JvmStatic + public fun enableImperativeFocus(): Boolean = accessor.enableImperativeFocus() + /** * This is to fix the issue with interop view manager where component descriptor lookup is causing ViewManager to preload. */ 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 fc36977ae13c..61b4b60513a5 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<<912dec895495052328e7e52b94a6738a>> + * @generated SignedSource<> */ /** @@ -47,6 +47,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var enableImagePrefetchingAndroidCache: Boolean? = null private var enableImagePrefetchingOnUiThreadAndroidCache: Boolean? = null private var enableImmediateUpdateModeForContentOffsetChangesCache: Boolean? = null + private var enableImperativeFocusCache: Boolean? = null private var enableInteropViewManagerClassLookUpOptimizationIOSCache: Boolean? = null private var enableLayoutAnimationsOnAndroidCache: Boolean? = null private var enableLayoutAnimationsOnIOSCache: Boolean? = null @@ -337,6 +338,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableImperativeFocus(): Boolean { + var cached = enableImperativeFocusCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableImperativeFocus() + enableImperativeFocusCache = cached + } + return cached + } + override fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean { var cached = enableInteropViewManagerClassLookUpOptimizationIOSCache 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 9fd0b7fde5f8..5fef6dfb4b9b 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<> */ /** @@ -82,6 +82,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean + @DoNotStrip @JvmStatic public external fun enableImperativeFocus(): Boolean + @DoNotStrip @JvmStatic public external fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean @DoNotStrip @JvmStatic public external fun enableLayoutAnimationsOnAndroid(): 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 f15e0d86a6eb..3f98049620be 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<<7601cbcde75ff19ef0fe67f6faef2549>> + * @generated SignedSource<<4fa15189361a6c92bdd44bafc9356167>> */ /** @@ -77,6 +77,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean = false + override fun enableImperativeFocus(): Boolean = false + override fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean = false override fun enableLayoutAnimationsOnAndroid(): 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 2fb3aed7a84a..b418295b880f 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<<3a13f8e35423b634ed4ef46fbac3c1e9>> + * @generated SignedSource<<962c60d1761b0a1f4945b44767aa7b02>> */ /** @@ -51,6 +51,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var enableImagePrefetchingAndroidCache: Boolean? = null private var enableImagePrefetchingOnUiThreadAndroidCache: Boolean? = null private var enableImmediateUpdateModeForContentOffsetChangesCache: Boolean? = null + private var enableImperativeFocusCache: Boolean? = null private var enableInteropViewManagerClassLookUpOptimizationIOSCache: Boolean? = null private var enableLayoutAnimationsOnAndroidCache: Boolean? = null private var enableLayoutAnimationsOnIOSCache: Boolean? = null @@ -368,6 +369,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun enableImperativeFocus(): Boolean { + var cached = enableImperativeFocusCache + if (cached == null) { + cached = currentProvider.enableImperativeFocus() + accessedFeatureFlags.add("enableImperativeFocus") + enableImperativeFocusCache = cached + } + return cached + } + override fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean { var cached = enableInteropViewManagerClassLookUpOptimizationIOSCache 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 93eda3e18875..b38c61d3a6d4 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<<143b568248e68033efaefc3f178ff6db>> + * @generated SignedSource<> */ /** @@ -77,6 +77,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean + @DoNotStrip public fun enableImperativeFocus(): Boolean + @DoNotStrip public fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean @DoNotStrip public fun enableLayoutAnimationsOnAndroid(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.kt index d987635b424a..c47f67ce0361 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.kt @@ -416,6 +416,14 @@ public open class ReactViewGroup public constructor(context: Context?) : updateClippingToRect(clippingRect, excludedViews) } + internal fun requestFocusFromJS() { + super.requestFocus(FOCUS_DOWN, null) + } + + internal fun clearFocusFromJS() { + super.clearFocus() + } + override fun endViewTransition(view: View) { super.endViewTransition(view) childrenRemovedWhileTransitioning?.remove(view.id) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt index 6c2d3bd52dc7..424b724abe2b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt @@ -404,6 +404,8 @@ public open class ReactViewManager : ReactClippingViewManager() when (commandId) { HOTSPOT_UPDATE_KEY -> handleHotspotUpdate(root, args) "setPressed" -> handleSetPressed(root, args) + "focus" -> handleFocus(root) + "blur" -> handleBlur(root) else -> {} } } @@ -428,4 +430,16 @@ public open class ReactViewManager : ReactClippingViewManager() val y = args.getDouble(1).dpToPx() root.drawableHotspotChanged(x, y) } + + private fun handleFocus(root: ReactViewGroup) { + if (ReactNativeFeatureFlags.enableImperativeFocus()) { + root.requestFocusFromJS() + } + } + + private fun handleBlur(root: ReactViewGroup) { + if (ReactNativeFeatureFlags.enableImperativeFocus()) { + root.clearFocusFromJS() + } + } } 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 8d1070c9cf4c..8fe12981ba24 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<<92c9aa29df580c6d12faa14e60b00e4f>> + * @generated SignedSource<> */ /** @@ -201,6 +201,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + bool enableImperativeFocus() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableImperativeFocus"); + return method(javaProvider_); + } + bool enableInteropViewManagerClassLookUpOptimizationIOS() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableInteropViewManagerClassLookUpOptimizationIOS"); @@ -616,6 +622,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableImmediateUpdateModeForContentOffs return ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges(); } +bool JReactNativeFeatureFlagsCxxInterop::enableImperativeFocus( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableImperativeFocus(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableInteropViewManagerClassLookUpOptimizationIOS( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableInteropViewManagerClassLookUpOptimizationIOS(); @@ -958,6 +969,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableImmediateUpdateModeForContentOffsetChanges", JReactNativeFeatureFlagsCxxInterop::enableImmediateUpdateModeForContentOffsetChanges), + makeNativeMethod( + "enableImperativeFocus", + JReactNativeFeatureFlagsCxxInterop::enableImperativeFocus), makeNativeMethod( "enableInteropViewManagerClassLookUpOptimizationIOS", JReactNativeFeatureFlagsCxxInterop::enableInteropViewManagerClassLookUpOptimizationIOS), 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 77ff9a6034b7..df9508488905 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<<124d1378990fdd09a4d97f9103f81a6a>> + * @generated SignedSource<> */ /** @@ -111,6 +111,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableImmediateUpdateModeForContentOffsetChanges( facebook::jni::alias_ref); + static bool enableImperativeFocus( + facebook::jni::alias_ref); + static bool enableInteropViewManagerClassLookUpOptimizationIOS( 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 ed3deaa53c60..46024295c8c3 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<<42bea10b4b62a91dce8fde7674f76ceb>> + * @generated SignedSource<<50f81f60d4c2d2e08fde98f4a2d841ea>> */ /** @@ -134,6 +134,10 @@ bool ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges() return getAccessor().enableImmediateUpdateModeForContentOffsetChanges(); } +bool ReactNativeFeatureFlags::enableImperativeFocus() { + return getAccessor().enableImperativeFocus(); +} + bool ReactNativeFeatureFlags::enableInteropViewManagerClassLookUpOptimizationIOS() { return getAccessor().enableInteropViewManagerClassLookUpOptimizationIOS(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 54c5b14bca38..34b9c6329b75 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<<40421ac664927693136a8e3197e3c07c>> + * @generated SignedSource<<3446eebd26c1142fd78cd5413771569d>> */ /** @@ -174,6 +174,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableImmediateUpdateModeForContentOffsetChanges(); + /** + * Enable ref.focus() and ref.blur() for all views, not just TextInput. + */ + RN_EXPORT static bool enableImperativeFocus(); + /** * This is to fix the issue with interop view manager where component descriptor lookup is causing ViewManager to preload. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 7ec0b2b5aed5..cc960f7f57c2 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<> + * @generated SignedSource<<891375f88b3f48b324de29e31c8936cf>> */ /** @@ -515,6 +515,24 @@ bool ReactNativeFeatureFlagsAccessor::enableImmediateUpdateModeForContentOffsetC return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableImperativeFocus() { + auto flagValue = enableImperativeFocus_.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(27, "enableImperativeFocus"); + + flagValue = currentProvider_->enableImperativeFocus(); + enableImperativeFocus_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableInteropViewManagerClassLookUpOptimizationIOS() { auto flagValue = enableInteropViewManagerClassLookUpOptimizationIOS_.load(); @@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::enableInteropViewManagerClassLookUpOptimiz // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(27, "enableInteropViewManagerClassLookUpOptimizationIOS"); + markFlagAsAccessed(28, "enableInteropViewManagerClassLookUpOptimizationIOS"); flagValue = currentProvider_->enableInteropViewManagerClassLookUpOptimizationIOS(); enableInteropViewManagerClassLookUpOptimizationIOS_ = flagValue; @@ -542,7 +560,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(28, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(29, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -560,7 +578,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(29, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(30, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMainQueueCoordinatorOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "enableMainQueueCoordinatorOnIOS"); + markFlagAsAccessed(31, "enableMainQueueCoordinatorOnIOS"); flagValue = currentProvider_->enableMainQueueCoordinatorOnIOS(); enableMainQueueCoordinatorOnIOS_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::enableModuleArgumentNSNullConversionIOS() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "enableModuleArgumentNSNullConversionIOS"); + markFlagAsAccessed(32, "enableModuleArgumentNSNullConversionIOS"); flagValue = currentProvider_->enableModuleArgumentNSNullConversionIOS(); enableModuleArgumentNSNullConversionIOS_ = flagValue; @@ -614,7 +632,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(32, "enableNativeCSSParsing"); + markFlagAsAccessed(33, "enableNativeCSSParsing"); flagValue = currentProvider_->enableNativeCSSParsing(); enableNativeCSSParsing_ = flagValue; @@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNetworkEventReporting() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "enableNetworkEventReporting"); + markFlagAsAccessed(34, "enableNetworkEventReporting"); flagValue = currentProvider_->enableNetworkEventReporting(); enableNetworkEventReporting_ = flagValue; @@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreparedTextLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "enablePreparedTextLayout"); + markFlagAsAccessed(35, "enablePreparedTextLayout"); flagValue = currentProvider_->enablePreparedTextLayout(); enablePreparedTextLayout_ = flagValue; @@ -668,7 +686,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(35, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(36, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::enableResourceTimingAPI() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "enableResourceTimingAPI"); + markFlagAsAccessed(37, "enableResourceTimingAPI"); flagValue = currentProvider_->enableResourceTimingAPI(); enableResourceTimingAPI_ = flagValue; @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSwiftUIBasedFilters() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "enableSwiftUIBasedFilters"); + markFlagAsAccessed(38, "enableSwiftUIBasedFilters"); flagValue = currentProvider_->enableSwiftUIBasedFilters(); enableSwiftUIBasedFilters_ = flagValue; @@ -722,7 +740,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(38, "enableViewCulling"); + markFlagAsAccessed(39, "enableViewCulling"); flagValue = currentProvider_->enableViewCulling(); enableViewCulling_ = flagValue; @@ -740,7 +758,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(39, "enableViewRecycling"); + markFlagAsAccessed(40, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForImage() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "enableViewRecyclingForImage"); + markFlagAsAccessed(41, "enableViewRecyclingForImage"); flagValue = currentProvider_->enableViewRecyclingForImage(); enableViewRecyclingForImage_ = flagValue; @@ -776,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForScrollView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "enableViewRecyclingForScrollView"); + markFlagAsAccessed(42, "enableViewRecyclingForScrollView"); flagValue = currentProvider_->enableViewRecyclingForScrollView(); enableViewRecyclingForScrollView_ = flagValue; @@ -794,7 +812,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(42, "enableViewRecyclingForText"); + markFlagAsAccessed(43, "enableViewRecyclingForText"); flagValue = currentProvider_->enableViewRecyclingForText(); enableViewRecyclingForText_ = flagValue; @@ -812,7 +830,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(43, "enableViewRecyclingForView"); + markFlagAsAccessed(44, "enableViewRecyclingForView"); flagValue = currentProvider_->enableViewRecyclingForView(); enableViewRecyclingForView_ = flagValue; @@ -830,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewDebugFeatures() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(44, "enableVirtualViewDebugFeatures"); + markFlagAsAccessed(45, "enableVirtualViewDebugFeatures"); flagValue = currentProvider_->enableVirtualViewDebugFeatures(); enableVirtualViewDebugFeatures_ = flagValue; @@ -848,7 +866,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewRenderState() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(45, "enableVirtualViewRenderState"); + markFlagAsAccessed(46, "enableVirtualViewRenderState"); flagValue = currentProvider_->enableVirtualViewRenderState(); enableVirtualViewRenderState_ = flagValue; @@ -866,7 +884,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewWindowFocusDetection() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(46, "enableVirtualViewWindowFocusDetection"); + markFlagAsAccessed(47, "enableVirtualViewWindowFocusDetection"); flagValue = currentProvider_->enableVirtualViewWindowFocusDetection(); enableVirtualViewWindowFocusDetection_ = flagValue; @@ -884,7 +902,7 @@ bool ReactNativeFeatureFlagsAccessor::enableWebPerformanceAPIsByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(47, "enableWebPerformanceAPIsByDefault"); + markFlagAsAccessed(48, "enableWebPerformanceAPIsByDefault"); flagValue = currentProvider_->enableWebPerformanceAPIsByDefault(); enableWebPerformanceAPIsByDefault_ = flagValue; @@ -902,7 +920,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(48, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(49, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -920,7 +938,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(49, "fuseboxEnabledRelease"); + markFlagAsAccessed(50, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -938,7 +956,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(50, "fuseboxNetworkInspectionEnabled"); + markFlagAsAccessed(51, "fuseboxNetworkInspectionEnabled"); flagValue = currentProvider_->fuseboxNetworkInspectionEnabled(); fuseboxNetworkInspectionEnabled_ = flagValue; @@ -956,7 +974,7 @@ bool ReactNativeFeatureFlagsAccessor::hideOffscreenVirtualViewsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(51, "hideOffscreenVirtualViewsOnIOS"); + markFlagAsAccessed(52, "hideOffscreenVirtualViewsOnIOS"); flagValue = currentProvider_->hideOffscreenVirtualViewsOnIOS(); hideOffscreenVirtualViewsOnIOS_ = flagValue; @@ -974,7 +992,7 @@ bool ReactNativeFeatureFlagsAccessor::overrideBySynchronousMountPropsAtMountingA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(52, "overrideBySynchronousMountPropsAtMountingAndroid"); + markFlagAsAccessed(53, "overrideBySynchronousMountPropsAtMountingAndroid"); flagValue = currentProvider_->overrideBySynchronousMountPropsAtMountingAndroid(); overrideBySynchronousMountPropsAtMountingAndroid_ = flagValue; @@ -992,7 +1010,7 @@ bool ReactNativeFeatureFlagsAccessor::perfMonitorV2Enabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(53, "perfMonitorV2Enabled"); + markFlagAsAccessed(54, "perfMonitorV2Enabled"); flagValue = currentProvider_->perfMonitorV2Enabled(); perfMonitorV2Enabled_ = flagValue; @@ -1010,7 +1028,7 @@ double ReactNativeFeatureFlagsAccessor::preparedTextCacheSize() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(54, "preparedTextCacheSize"); + markFlagAsAccessed(55, "preparedTextCacheSize"); flagValue = currentProvider_->preparedTextCacheSize(); preparedTextCacheSize_ = flagValue; @@ -1028,7 +1046,7 @@ bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustion() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(55, "preventShadowTreeCommitExhaustion"); + markFlagAsAccessed(56, "preventShadowTreeCommitExhaustion"); flagValue = currentProvider_->preventShadowTreeCommitExhaustion(); preventShadowTreeCommitExhaustion_ = flagValue; @@ -1046,7 +1064,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldPressibilityUseW3CPointerEventsForHo // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(56, "shouldPressibilityUseW3CPointerEventsForHover"); + markFlagAsAccessed(57, "shouldPressibilityUseW3CPointerEventsForHover"); flagValue = currentProvider_->shouldPressibilityUseW3CPointerEventsForHover(); shouldPressibilityUseW3CPointerEventsForHover_ = flagValue; @@ -1064,7 +1082,7 @@ bool ReactNativeFeatureFlagsAccessor::skipActivityIdentityAssertionOnHostPause() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(57, "skipActivityIdentityAssertionOnHostPause"); + markFlagAsAccessed(58, "skipActivityIdentityAssertionOnHostPause"); flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause(); skipActivityIdentityAssertionOnHostPause_ = flagValue; @@ -1082,7 +1100,7 @@ bool ReactNativeFeatureFlagsAccessor::sweepActiveTouchOnChildNativeGesturesAndro // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(58, "sweepActiveTouchOnChildNativeGesturesAndroid"); + markFlagAsAccessed(59, "sweepActiveTouchOnChildNativeGesturesAndroid"); flagValue = currentProvider_->sweepActiveTouchOnChildNativeGesturesAndroid(); sweepActiveTouchOnChildNativeGesturesAndroid_ = flagValue; @@ -1100,7 +1118,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(59, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(60, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -1118,7 +1136,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(60, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(61, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -1136,7 +1154,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(61, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(62, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -1154,7 +1172,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(62, "useFabricInterop"); + markFlagAsAccessed(63, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -1172,7 +1190,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeEqualsInNativeReadableArrayAndroi // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(63, "useNativeEqualsInNativeReadableArrayAndroid"); + markFlagAsAccessed(64, "useNativeEqualsInNativeReadableArrayAndroid"); flagValue = currentProvider_->useNativeEqualsInNativeReadableArrayAndroid(); useNativeEqualsInNativeReadableArrayAndroid_ = flagValue; @@ -1190,7 +1208,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeTransformHelperAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(64, "useNativeTransformHelperAndroid"); + markFlagAsAccessed(65, "useNativeTransformHelperAndroid"); flagValue = currentProvider_->useNativeTransformHelperAndroid(); useNativeTransformHelperAndroid_ = flagValue; @@ -1208,7 +1226,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(65, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(66, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -1226,7 +1244,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(66, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(67, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -1244,7 +1262,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(67, "useRawPropsJsiValue"); + markFlagAsAccessed(68, "useRawPropsJsiValue"); flagValue = currentProvider_->useRawPropsJsiValue(); useRawPropsJsiValue_ = flagValue; @@ -1262,7 +1280,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(68, "useShadowNodeStateOnClone"); + markFlagAsAccessed(69, "useShadowNodeStateOnClone"); flagValue = currentProvider_->useShadowNodeStateOnClone(); useShadowNodeStateOnClone_ = flagValue; @@ -1280,7 +1298,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(69, "useTurboModuleInterop"); + markFlagAsAccessed(70, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1298,7 +1316,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(70, "useTurboModules"); + markFlagAsAccessed(71, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; @@ -1316,7 +1334,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewHysteresisRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(71, "virtualViewHysteresisRatio"); + markFlagAsAccessed(72, "virtualViewHysteresisRatio"); flagValue = currentProvider_->virtualViewHysteresisRatio(); virtualViewHysteresisRatio_ = flagValue; @@ -1334,7 +1352,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(72, "virtualViewPrerenderRatio"); + markFlagAsAccessed(73, "virtualViewPrerenderRatio"); flagValue = currentProvider_->virtualViewPrerenderRatio(); virtualViewPrerenderRatio_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 7b4ed017e8a8..802d599e1e14 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<<6f05211b44f2be076b37ef9178e5ef43>> + * @generated SignedSource<<53981e017d681009b240ad6b5d09d4d8>> */ /** @@ -59,6 +59,7 @@ class ReactNativeFeatureFlagsAccessor { bool enableImagePrefetchingAndroid(); bool enableImagePrefetchingOnUiThreadAndroid(); bool enableImmediateUpdateModeForContentOffsetChanges(); + bool enableImperativeFocus(); bool enableInteropViewManagerClassLookUpOptimizationIOS(); bool enableLayoutAnimationsOnAndroid(); bool enableLayoutAnimationsOnIOS(); @@ -116,7 +117,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 73> accessedFeatureFlags_; + std::array, 74> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cdpInteractionMetricsEnabled_; @@ -145,6 +146,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableImagePrefetchingAndroid_; std::atomic> enableImagePrefetchingOnUiThreadAndroid_; std::atomic> enableImmediateUpdateModeForContentOffsetChanges_; + std::atomic> enableImperativeFocus_; std::atomic> enableInteropViewManagerClassLookUpOptimizationIOS_; std::atomic> enableLayoutAnimationsOnAndroid_; std::atomic> enableLayoutAnimationsOnIOS_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 91a78a881246..d5a67e812873 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<> + * @generated SignedSource<<6c1c050029f105d0075fb83ca21aa48b>> */ /** @@ -135,6 +135,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool enableImperativeFocus() override { + return false; + } + bool enableInteropViewManagerClassLookUpOptimizationIOS() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 0d485f5a231b..76ff2d8420e3 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<<737e882a924b2730d0c67cc8dc27c8a7>> + * @generated SignedSource<<0bef63a074aa6b67787c2ca30706a847>> */ /** @@ -288,6 +288,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::enableImmediateUpdateModeForContentOffsetChanges(); } + bool enableImperativeFocus() override { + auto value = values_["enableImperativeFocus"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::enableImperativeFocus(); + } + bool enableInteropViewManagerClassLookUpOptimizationIOS() override { auto value = values_["enableInteropViewManagerClassLookUpOptimizationIOS"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index fdf753a9f6b9..a32ad655eea2 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<<4045a760f000400d47117728119f0d21>> + * @generated SignedSource<<40ea902a1d376324f75680d651f3eff6>> */ /** @@ -52,6 +52,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableImagePrefetchingAndroid() = 0; virtual bool enableImagePrefetchingOnUiThreadAndroid() = 0; virtual bool enableImmediateUpdateModeForContentOffsetChanges() = 0; + virtual bool enableImperativeFocus() = 0; virtual bool enableInteropViewManagerClassLookUpOptimizationIOS() = 0; virtual bool enableLayoutAnimationsOnAndroid() = 0; virtual bool enableLayoutAnimationsOnIOS() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index c09f653c3793..35e3977b5336 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<<5042321d7d0da40cc0436ffaeedda168>> + * @generated SignedSource<> */ /** @@ -179,6 +179,11 @@ bool NativeReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetCha return ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges(); } +bool NativeReactNativeFeatureFlags::enableImperativeFocus( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableImperativeFocus(); +} + bool NativeReactNativeFeatureFlags::enableInteropViewManagerClassLookUpOptimizationIOS( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableInteropViewManagerClassLookUpOptimizationIOS(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 07b07ed68374..6f2cb0ff337a 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<> + * @generated SignedSource<> */ /** @@ -90,6 +90,8 @@ class NativeReactNativeFeatureFlags bool enableImmediateUpdateModeForContentOffsetChanges(jsi::Runtime& runtime); + bool enableImperativeFocus(jsi::Runtime& runtime); + bool enableInteropViewManagerClassLookUpOptimizationIOS(jsi::Runtime& runtime); bool enableLayoutAnimationsOnAndroid(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewEventEmitter.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewEventEmitter.cpp index 506041daf320..4e981efd3f80 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewEventEmitter.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewEventEmitter.cpp @@ -112,4 +112,13 @@ void BaseViewEventEmitter::onLayout(const LayoutMetrics& layoutMetrics) const { }); } +#pragma mark - Focus +void BaseViewEventEmitter::onFocus() const { + dispatchEvent("focus"); +} + +void BaseViewEventEmitter::onBlur() const { + dispatchEvent("blur"); +} + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewEventEmitter.h b/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewEventEmitter.h index 584bc01239ce..4b3c59b95bfc 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewEventEmitter.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewEventEmitter.h @@ -32,6 +32,10 @@ class BaseViewEventEmitter : public TouchEventEmitter { void onLayout(const LayoutMetrics& layoutMetrics) const; +#pragma mark - Focus + void onFocus() const; + void onBlur() const; + private: /* * Contains the most recent `frame` and a `mutex` protecting access to it. diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 4541d1f08a06..237963ebbea3 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -336,6 +336,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + enableImperativeFocus: { + defaultValue: false, + metadata: { + dateAdded: '2024-09-13', + description: + 'Enable ref.focus() and ref.blur() for all views, not just TextInput.', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, enableInteropViewManagerClassLookUpOptimizationIOS: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index a6de5f894c32..eeafd333a840 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<<054add14ea0c9a96d3c3e32af8995437>> + * @generated SignedSource<> * @flow strict * @noformat */ @@ -77,6 +77,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ enableImagePrefetchingAndroid: Getter, enableImagePrefetchingOnUiThreadAndroid: Getter, enableImmediateUpdateModeForContentOffsetChanges: Getter, + enableImperativeFocus: Getter, enableInteropViewManagerClassLookUpOptimizationIOS: Getter, enableLayoutAnimationsOnAndroid: Getter, enableLayoutAnimationsOnIOS: Getter, @@ -312,6 +313,10 @@ export const enableImagePrefetchingOnUiThreadAndroid: Getter = createNa * Dispatches state updates for content offset changes synchronously on the main thread. */ export const enableImmediateUpdateModeForContentOffsetChanges: Getter = createNativeFlagGetter('enableImmediateUpdateModeForContentOffsetChanges', false); +/** + * Enable ref.focus() and ref.blur() for all views, not just TextInput. + */ +export const enableImperativeFocus: Getter = createNativeFlagGetter('enableImperativeFocus', false); /** * This is to fix the issue with interop view manager where component descriptor lookup is causing ViewManager to preload. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 021cdf0c1537..fc36f715b189 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<> + * @generated SignedSource<> * @flow strict * @noformat */ @@ -52,6 +52,7 @@ export interface Spec extends TurboModule { +enableImagePrefetchingAndroid?: () => boolean; +enableImagePrefetchingOnUiThreadAndroid?: () => boolean; +enableImmediateUpdateModeForContentOffsetChanges?: () => boolean; + +enableImperativeFocus?: () => boolean; +enableInteropViewManagerClassLookUpOptimizationIOS?: () => boolean; +enableLayoutAnimationsOnAndroid?: () => boolean; +enableLayoutAnimationsOnIOS?: () => boolean;