From a44d8a0f8a9b6533b50ac6318fa5993bd41d444b Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Wed, 29 Mar 2023 15:30:26 -0700 Subject: [PATCH] Add Examples for Direct Manipulation in the Interop Layer (#36610) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/36610 This change add to RNTester examples of a legacy Native Component, loaded in the New Architecture through the Interop Layer, that uses the APIs described in the [Direct Manipulation](https://reactnative.dev/docs/direct-manipulation) sectioon of the website. ## Changelog: [iOS][Added] - Added examples of direct manipulation Reviewed By: sammy-SC Differential Revision: D43978674 fbshipit-source-id: 1cbc56f28034f84f309166e3e392ad97a8164e64 --- .../Libraries/ReactNative/UIManager.js | 1 - .../ios/RNTMyLegacyNativeViewManager.mm | 7 ++ .../NativeComponentExample/js/MyNativeView.js | 90 ++++++++++++++++++- 3 files changed, 94 insertions(+), 4 deletions(-) diff --git a/packages/react-native/Libraries/ReactNative/UIManager.js b/packages/react-native/Libraries/ReactNative/UIManager.js index d9d5440729634d..e830b96971891a 100644 --- a/packages/react-native/Libraries/ReactNative/UIManager.js +++ b/packages/react-native/Libraries/ReactNative/UIManager.js @@ -9,7 +9,6 @@ */ import type {RootTag} from '../Types/RootTagTypes'; -import type {Spec as FabricUIManagerSpec} from './FabricUIManager'; import type {Spec} from './NativeUIManager'; import {getFabricUIManager} from './FabricUIManager'; diff --git a/packages/rn-tester/NativeComponentExample/ios/RNTMyLegacyNativeViewManager.mm b/packages/rn-tester/NativeComponentExample/ios/RNTMyLegacyNativeViewManager.mm index fb5cdf809f233e..2125e36313f678 100644 --- a/packages/rn-tester/NativeComponentExample/ios/RNTMyLegacyNativeViewManager.mm +++ b/packages/rn-tester/NativeComponentExample/ios/RNTMyLegacyNativeViewManager.mm @@ -30,6 +30,13 @@ + (BOOL)requiresMainQueueSetup RCT_EXPORT_VIEW_PROPERTY(onColorChanged, RCTBubblingEventBlock) +RCT_CUSTOM_VIEW_PROPERTY(cornerRadius, CGFloat, RNTLegacyView) +{ + view.clipsToBounds = true; + NSNumber *cornerRadius = (NSNumber *)json; + view.layer.cornerRadius = [cornerRadius floatValue]; +} + RCT_EXPORT_METHOD(changeBackgroundColor : (nonnull NSNumber *)reactTag color : (NSString *)color) { [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { diff --git a/packages/rn-tester/NativeComponentExample/js/MyNativeView.js b/packages/rn-tester/NativeComponentExample/js/MyNativeView.js index 65e5924fb01022..2f5ed092a21532 100644 --- a/packages/rn-tester/NativeComponentExample/js/MyNativeView.js +++ b/packages/rn-tester/NativeComponentExample/js/MyNativeView.js @@ -27,6 +27,8 @@ const colors = [ '#000033', ]; +const cornerRadiuses = [0, 20, 40, 60, 80, 100, 120]; + class HSBA { hue: number; saturation: number; @@ -50,14 +52,51 @@ class HSBA { } } +function beautify(number: number): string { + if (number % 1 === 0) { + return number.toFixed(); + } + return number.toFixed(2); +} + +type MeasureStruct = { + x: number, + y: number, + width: number, + height: number, +}; + +const MeasureStructZero: MeasureStruct = { + x: 0, + y: 0, + width: 0, + height: 0, +}; + +function getTextFor(measureStruct: MeasureStruct): string { + return `x: ${beautify(measureStruct.x)}, y: ${beautify( + measureStruct.y, + )}, width: ${beautify(measureStruct.width)}, height: ${beautify( + measureStruct.height, + )}`; +} + // This is an example component that migrates to use the new architecture. export default function MyNativeView(props: {}): React.Node { + const containerRef = useRef(null); const ref = useRef | null>(null); const legacyRef = useRef | null>(null); const [opacity, setOpacity] = useState(1.0); const [hsba, setHsba] = useState(new HSBA()); + const [cornerRadiusIndex, setCornerRadiusIndex] = useState(0); + const [legacyMeasure, setLegacyMeasure] = + useState(MeasureStructZero); + const [legacyMeasureInWindow, setLegacyMeasureInWindow] = + useState(MeasureStructZero); + const [legacyMeasureLayout, setLegacyMeasureLayout] = + useState(MeasureStructZero); return ( - + Fabric View Legacy View @@ -76,8 +115,10 @@ export default function MyNativeView(props: {}): React.Node { ) } /> - HSBA: {hsba.toString()} - + + HSBA: {hsba.toString()} + + Constants From Interop Layer:{' '} {UIManager.RNTMyLegacyNativeView.Constants.PI} @@ -106,6 +147,49 @@ export default function MyNativeView(props: {}): React.Node { ref.current?.measure((x, y, width, height) => { console.log(x, y, width, height); }); + + legacyRef.current?.measure((x, y, width, height) => { + setLegacyMeasure({x, y, width, height}); + }); + legacyRef.current?.measureInWindow((x, y, width, height) => { + setLegacyMeasureInWindow({x, y, width, height}); + }); + + if (containerRef.current) { + legacyRef.current?.measureLayout( + // $FlowFixMe[incompatible-call] + containerRef.current, + (x, y, width, height) => { + setLegacyMeasureLayout({x, y, width, height}); + }, + ); + } + }} + /> + + + > Interop Layer Measurements < + + + measure {getTextFor(legacyMeasure)} + + + InWindow {getTextFor(legacyMeasureInWindow)} + + + InLayout {getTextFor(legacyMeasureLayout)} + +