From e9c8fee4ef82ee3dfd8dc4b7cdc159c4a4f4f005 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Wed, 14 May 2025 10:11:03 -0700 Subject: [PATCH] Add Example for InteropLayer on RNTester (#51260) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/51260 This is a preparatory change that adds an example to RNTester for the Fabric interop layer on iOS. This example is needed to create a Jest E2E tests that will make sure that the Fabric Interop Layer can properly add views as subviews. We discovered the bug thanks to react-native-maps. ## Changelog: [Internal] - Add Example for the Fabric Interop Layer to RNTester iOS Reviewed By: cortinico Differential Revision: D74579737 fbshipit-source-id: 0c1bbb06790b01313cd98aa4b7152d8aba0cded3 --- .../ios/RCTInteropTestView.h | 15 ++ .../ios/RCTInteropTestView.m | 18 +++ .../ios/RCTInteropTestViewManager.h | 14 ++ .../ios/RCTInteropTestViewManager.m | 20 +++ .../FabricInteropLayer/FabricInteropLayer.js | 149 ++++++++++++++++++ .../rn-tester/js/utils/RNTesterList.ios.js | 5 + 6 files changed, 221 insertions(+) create mode 100644 packages/rn-tester/NativeComponentExample/ios/RCTInteropTestView.h create mode 100644 packages/rn-tester/NativeComponentExample/ios/RCTInteropTestView.m create mode 100644 packages/rn-tester/NativeComponentExample/ios/RCTInteropTestViewManager.h create mode 100644 packages/rn-tester/NativeComponentExample/ios/RCTInteropTestViewManager.m create mode 100644 packages/rn-tester/js/examples/FabricInteropLayer/FabricInteropLayer.js diff --git a/packages/rn-tester/NativeComponentExample/ios/RCTInteropTestView.h b/packages/rn-tester/NativeComponentExample/ios/RCTInteropTestView.h new file mode 100644 index 00000000000..ec8b4cc5e8f --- /dev/null +++ b/packages/rn-tester/NativeComponentExample/ios/RCTInteropTestView.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface InteropTestView : UIView +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/rn-tester/NativeComponentExample/ios/RCTInteropTestView.m b/packages/rn-tester/NativeComponentExample/ios/RCTInteropTestView.m new file mode 100644 index 00000000000..6760cf28225 --- /dev/null +++ b/packages/rn-tester/NativeComponentExample/ios/RCTInteropTestView.m @@ -0,0 +1,18 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import "RCTInteropTestView.h" + +@implementation InteropTestView + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + return self; +} + +@end diff --git a/packages/rn-tester/NativeComponentExample/ios/RCTInteropTestViewManager.h b/packages/rn-tester/NativeComponentExample/ios/RCTInteropTestViewManager.h new file mode 100644 index 00000000000..23bc1be1cc4 --- /dev/null +++ b/packages/rn-tester/NativeComponentExample/ios/RCTInteropTestViewManager.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface InteropTestViewManager : RCTViewManager +@end +NS_ASSUME_NONNULL_END diff --git a/packages/rn-tester/NativeComponentExample/ios/RCTInteropTestViewManager.m b/packages/rn-tester/NativeComponentExample/ios/RCTInteropTestViewManager.m new file mode 100644 index 00000000000..ac76554a849 --- /dev/null +++ b/packages/rn-tester/NativeComponentExample/ios/RCTInteropTestViewManager.m @@ -0,0 +1,20 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import "RCTInteropTestViewManager.h" +#import "RCTInteropTestView.h" + +@implementation InteropTestViewManager + +RCT_EXPORT_MODULE(InteropTestView) + +- (UIView *)view +{ + return [[InteropTestView alloc] init]; +} + +@end diff --git a/packages/rn-tester/js/examples/FabricInteropLayer/FabricInteropLayer.js b/packages/rn-tester/js/examples/FabricInteropLayer/FabricInteropLayer.js new file mode 100644 index 00000000000..2025cadd787 --- /dev/null +++ b/packages/rn-tester/js/examples/FabricInteropLayer/FabricInteropLayer.js @@ -0,0 +1,149 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * @flow + */ + +'use strict'; +import type {ViewProps} from 'react-native'; + +import React, {useState} from 'react'; +import { + Button, + StyleSheet, + Text, + View, + requireNativeComponent, + useColorScheme, +} from 'react-native'; + +type SectionProps = { + title: string, + children?: React.Node, +}; + +const WHITE = '#ffffff'; +const BLACK = '#000000'; + +// ========== JS Definition of the Native RCTInteropTestView component ======== +type InteropTestViewProps = { + // Add custom props here if needed + ...ViewProps, +}; + +const NativeInteropTestView = + requireNativeComponent('InteropTestView'); + +const InteropTestView = (props: InteropTestViewProps) => { + return ; +}; + +// ============================================================================= + +function Section({children, title}: SectionProps): React.Node { + const isDarkMode = useColorScheme() === 'dark'; + return ( + + + {title} + + + {children} + + + ); +} + +function AddChildrenForInteropLayer() { + const isDarkMode = useColorScheme() === 'dark'; + const [squares, setSquares] = useState>([0, 1, 2, 3, 4]); + const addMarker = () => { + setSquares(p => [...p, p.length + 1]); + }; + return ( + +
+
+
+ + {squares.map((_, index) => ( + + ))} + +
+
+ + {squares.map((_, index) => ( + + ))} + +
+
+ ); +} + +const styles = StyleSheet.create({ + sectionContainer: { + marginTop: 32, + paddingHorizontal: 24, + }, + sectionTitle: { + fontSize: 24, + fontWeight: '600', + }, + sectionDescription: { + marginTop: 8, + fontSize: 18, + fontWeight: '400', + }, + highlight: { + fontWeight: '700', + }, + customView: { + width: 300, + height: 200, + backgroundColor: 'yellow', + flexWrap: 'wrap', + gap: 10, + }, + customViewChild: { + width: 50, + height: 50, + backgroundColor: 'blue', + }, +}); + +exports.title = 'Fabric Interop Layer'; +exports.category = 'UI'; +exports.description = 'A set test cases for the Fabric Interop Layer.'; +exports.examples = [ + { + title: 'Add children to Interop Layer', + description: 'Add children to Interop Layer', + name: 'Add Children to interop layer', + render(): React.Node { + return ; + }, + }, +]; diff --git a/packages/rn-tester/js/utils/RNTesterList.ios.js b/packages/rn-tester/js/utils/RNTesterList.ios.js index 7b6bc93da6b..85c2b01983e 100644 --- a/packages/rn-tester/js/utils/RNTesterList.ios.js +++ b/packages/rn-tester/js/utils/RNTesterList.ios.js @@ -146,6 +146,11 @@ const Components: Array = [ category: 'UI', module: require('../examples/NewArchitecture/NewArchitectureExample'), }, + { + key: 'FabricInteropLayer', + category: 'UI', + module: require('../examples/FabricInteropLayer/FabricInteropLayer'), + }, { key: 'PerformanceComparisonExample', category: 'Basic',