From 3f1ee478bbb7a9286f1db22bf834516474cca22d Mon Sep 17 00:00:00 2001 From: Dmitry Rykun Date: Mon, 25 Sep 2023 14:23:56 -0700 Subject: [PATCH] Native view configs in bridgeless mode: constantsToExport support (#39519) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/39519 If the `constantsToExport` method is overridden by RCTViewManager subclass, we'll out those constants in "Constants" property of the view config. This diff also defines a property on UIManager for every view configs. This add support for `UIManager.RNTMyLegacyNativeView.Constants.PI` syntax in bridgeless mode. Changelog: [Internal] Reviewed By: cipolleschi Differential Revision: D49372561 fbshipit-source-id: e9333c94ad882ee38a5a3729ccc19330d7736657 --- .../Libraries/ReactNative/BridgelessUIManager.js | 10 +++++++++- packages/react-native/React/Modules/RCTUIManager.m | 3 +-- packages/react-native/React/Views/RCTComponentData.m | 9 +++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js b/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js index 38b63e7baa0..8b9a746815e 100644 --- a/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js +++ b/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js @@ -29,7 +29,7 @@ function getCachedConstants(): Object { return cachedConstants; } -module.exports = { +const UIManagerJS: {[string]: $FlowFixMe} = { getViewManagerConfig: (viewManagerName: string): mixed => { if (ReactNativeFeatureFlags.enableNativeViewConfigsInBridgelessMode()) { return getCachedConstants()[viewManagerName]; @@ -178,3 +178,11 @@ module.exports = { dismissPopupMenu: (): void => console.error(errorMessageForMethod('dismissPopupMenu')), }; + +if (ReactNativeFeatureFlags.enableNativeViewConfigsInBridgelessMode()) { + Object.keys(getCachedConstants()).forEach(viewConfigName => { + UIManagerJS[viewConfigName] = getCachedConstants()[viewConfigName]; + }); +} + +module.exports = UIManagerJS; diff --git a/packages/react-native/React/Modules/RCTUIManager.m b/packages/react-native/React/Modules/RCTUIManager.m index 209c1326e00..14963e7d4a6 100644 --- a/packages/react-native/React/Modules/RCTUIManager.m +++ b/packages/react-native/React/Modules/RCTUIManager.m @@ -1490,8 +1490,7 @@ NSMutableDictionary *RCTModuleConstantsForDestructuredComponent( // New Architecture. To make native view configs work in the New Architecture we will populate these properties in // native. moduleConstants[@"Commands"] = viewConfig[@"Commands"]; - // In the Old Architecture "Constants" are empty. - moduleConstants[@"Constants"] = [NSDictionary new]; + moduleConstants[@"Constants"] = viewConfig[@"Constants"]; // Add direct events for (NSString *eventName in viewConfig[@"directEvents"]) { diff --git a/packages/react-native/React/Views/RCTComponentData.m b/packages/react-native/React/Views/RCTComponentData.m index da9f8206138..2c627b6cbef 100644 --- a/packages/react-native/React/Views/RCTComponentData.m +++ b/packages/react-native/React/Views/RCTComponentData.m @@ -414,6 +414,14 @@ static RCTPropBlock createNSInvocationSetter(NSMethodSignature *typeSignature, S return commands; } ++ (NSDictionary *)constantsForViewMangerClass:(Class)managerClass +{ + if ([managerClass instancesRespondToSelector:@selector(constantsToExport)]) { + return [[managerClass new] constantsToExport]; + } + return @{}; +} + + (NSDictionary *)viewConfigForViewMangerClass:(Class)managerClass { NSMutableArray *bubblingEvents = [NSMutableArray new]; @@ -498,6 +506,7 @@ static RCTPropBlock createNSInvocationSetter(NSMethodSignature *typeSignature, S @"capturingEvents" : capturingEvents, @"baseModuleName" : superClass == [NSObject class] ? (id)kCFNull : RCTViewManagerModuleNameForClass(superClass), @"Commands" : commands, + @"Constants" : [self constantsForViewMangerClass:managerClass], }; }