Skip to content

Commit

Permalink
Add Examples for Direct Manipulation in the Interop Layer (#36610)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #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: 177f546618350f656b07033757513afa45e02d1c
  • Loading branch information
cipolleschi authored and facebook-github-bot committed Mar 29, 2023
1 parent e07d7d5 commit 08a4e3b
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 4 deletions.
1 change: 0 additions & 1 deletion packages/react-native/Libraries/ReactNative/UIManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<NSNumber *, UIView *> *viewRegistry) {
Expand Down
90 changes: 87 additions & 3 deletions packages/rn-tester/NativeComponentExample/js/MyNativeView.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const colors = [
'#000033',
];

const cornerRadiuses = [0, 20, 40, 60, 80, 100, 120];

class HSBA {
hue: number;
saturation: number;
Expand All @@ -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<typeof View | null>(null);
const ref = useRef<React.ElementRef<MyNativeViewType> | null>(null);
const legacyRef = useRef<React.ElementRef<MyLegacyViewType> | null>(null);
const [opacity, setOpacity] = useState(1.0);
const [hsba, setHsba] = useState<HSBA>(new HSBA());
const [cornerRadiusIndex, setCornerRadiusIndex] = useState<number>(0);
const [legacyMeasure, setLegacyMeasure] =
useState<MeasureStruct>(MeasureStructZero);
const [legacyMeasureInWindow, setLegacyMeasureInWindow] =
useState<MeasureStruct>(MeasureStructZero);
const [legacyMeasureLayout, setLegacyMeasureLayout] =
useState<MeasureStruct>(MeasureStructZero);
return (
<View style={{flex: 1}}>
<View ref={containerRef} style={{flex: 1}}>
<Text style={{color: 'red'}}>Fabric View</Text>
<RNTMyNativeView ref={ref} style={{flex: 1}} opacity={opacity} />
<Text style={{color: 'red'}}>Legacy View</Text>
Expand All @@ -76,8 +115,10 @@ export default function MyNativeView(props: {}): React.Node {
)
}
/>
<Text style={{color: 'green'}}>HSBA: {hsba.toString()}</Text>
<Text style={{color: 'green'}}>
<Text style={{color: 'green', textAlign: 'center'}}>
HSBA: {hsba.toString()}
</Text>
<Text style={{color: 'green', textAlign: 'center'}}>
Constants From Interop Layer:{' '}
{UIManager.RNTMyLegacyNativeView.Constants.PI}
</Text>
Expand Down Expand Up @@ -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});
},
);
}
}}
/>

<Text style={{textAlign: 'center'}}>
&gt; Interop Layer Measurements &lt;
</Text>
<Text style={{textAlign: 'center'}}>
measure {getTextFor(legacyMeasure)}
</Text>
<Text style={{textAlign: 'center'}}>
InWindow {getTextFor(legacyMeasureInWindow)}
</Text>
<Text style={{textAlign: 'center'}}>
InLayout {getTextFor(legacyMeasureLayout)}
</Text>
<Button
title="Test setNativeProps"
onPress={() => {
const newCRIndex =
cornerRadiusIndex + 1 >= cornerRadiuses.length
? 0
: cornerRadiusIndex + 1;
setCornerRadiusIndex(newCRIndex);
legacyRef.current?.setNativeProps({
cornerRadius: cornerRadiuses[newCRIndex],
});
}}
/>
</View>
Expand Down

0 comments on commit 08a4e3b

Please sign in to comment.