diff --git a/packages/rn-tester/NativeComponentExample/ios/RNTMyNativeViewComponentView.h b/packages/rn-tester/NativeComponentExample/ios/RNTMyNativeViewComponentView.h index 6d7adce1eabb5b..60f930debdfbed 100644 --- a/packages/rn-tester/NativeComponentExample/ios/RNTMyNativeViewComponentView.h +++ b/packages/rn-tester/NativeComponentExample/ios/RNTMyNativeViewComponentView.h @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +#import #import #import @@ -12,6 +13,8 @@ NS_ASSUME_NONNULL_BEGIN @interface RNTMyNativeViewComponentView : RCTViewComponentView +@property (nonatomic, copy) RCTBubblingEventBlock onIntArrayChanged; + - (UIColor *)UIColorFromHexString:(const std::string)hexString; @end diff --git a/packages/rn-tester/NativeComponentExample/ios/RNTMyNativeViewComponentView.mm b/packages/rn-tester/NativeComponentExample/ios/RNTMyNativeViewComponentView.mm index 7fe66d4050d776..33e7a7f2e8b263 100644 --- a/packages/rn-tester/NativeComponentExample/ios/RNTMyNativeViewComponentView.mm +++ b/packages/rn-tester/NativeComponentExample/ios/RNTMyNativeViewComponentView.mm @@ -58,6 +58,44 @@ - (UIColor *)UIColorFromHexString:(const std::string)hexString - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps { + const auto &oldViewProps = *std::static_pointer_cast(_props); + const auto &newViewProps = *std::static_pointer_cast(props); + + if (oldViewProps.values != newViewProps.values) { + if (_eventEmitter) { + std::vector newVector = {}; + std::vector newBoolVector = {}; + std::vector newFloatVector = {}; + std::vector newDoubleVector = {}; + std::vector newYesNoVector = {}; + std::vector newStringVector = {}; + std::vector newLatLonVector = {}; + std::vector> newIntVectorVector = {}; + for (auto val : newViewProps.values) { + newVector.push_back(val * 2); + newBoolVector.push_back(val % 2 ? true : false); + newFloatVector.push_back(val * 3.14); + newDoubleVector.push_back(val / 3.14); + newYesNoVector.push_back( + val % 2 ? RNTMyNativeViewEventEmitter::OnIntArrayChangedYesNos::Yep + : RNTMyNativeViewEventEmitter::OnIntArrayChangedYesNos::Nope); + newStringVector.push_back(std::to_string(val)); + newLatLonVector.push_back({-1.0 * val, 2.0 * val}); + newIntVectorVector.push_back({val, val, val}); + } + RNTMyNativeViewEventEmitter::OnIntArrayChanged value = { + newVector, + newBoolVector, + newFloatVector, + newDoubleVector, + newYesNoVector, + newStringVector, + newLatLonVector, + newIntVectorVector}; + std::static_pointer_cast(_eventEmitter)->onIntArrayChanged(value); + } + } + [super updateProps:props oldProps:oldProps]; } diff --git a/packages/rn-tester/NativeComponentExample/ios/RNTMyNativeViewManager.mm b/packages/rn-tester/NativeComponentExample/ios/RNTMyNativeViewManager.mm index 83d8f231d4259d..6729d8f12cb071 100644 --- a/packages/rn-tester/NativeComponentExample/ios/RNTMyNativeViewManager.mm +++ b/packages/rn-tester/NativeComponentExample/ios/RNTMyNativeViewManager.mm @@ -18,6 +18,10 @@ @implementation RNTMyNativeViewManager RCT_EXPORT_VIEW_PROPERTY(backgroundColor, UIColor) +RCT_EXPORT_VIEW_PROPERTY(onIntArrayChanged, RCTBubblingEventBlock) + +RCT_EXPORT_VIEW_PROPERTY(values, NSArray *) + RCT_EXPORT_METHOD(callNativeMethodToChangeBackgroundColor : (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 51a31ae468b3f8..c74c0f084e7648 100644 --- a/packages/rn-tester/NativeComponentExample/js/MyNativeView.js +++ b/packages/rn-tester/NativeComponentExample/js/MyNativeView.js @@ -98,7 +98,22 @@ export default function MyNativeView(props: {}): React.Node { return ( Fabric View - + { + console.log(event.nativeEvent.values); + console.log(event.nativeEvent.boolValues); + console.log(event.nativeEvent.floats); + console.log(event.nativeEvent.doubles); + console.log(event.nativeEvent.yesNos); + console.log(event.nativeEvent.strings); + console.log(event.nativeEvent.latLons); + console.log(event.nativeEvent.multiArrays); + }} + /> Legacy View , + boolValues: $ReadOnlyArray, + floats: $ReadOnlyArray, + doubles: $ReadOnlyArray, + yesNos: $ReadOnlyArray<'yep' | 'nope'>, + strings: $ReadOnlyArray, + latLons: $ReadOnlyArray<{|lat: Double, lon: Double|}>, + multiArrays: $ReadOnlyArray<$ReadOnlyArray>, +}>; + type NativeProps = $ReadOnly<{| ...ViewProps, opacity?: Float, + values: $ReadOnlyArray, + + // Events + onIntArrayChanged?: ?BubblingEventHandler, |}>; export type MyNativeViewType = HostComponent; diff --git a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/component/MyNativeView.java b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/component/MyNativeView.java index c9d57fd4d46bc0..1a3992536e0ed8 100644 --- a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/component/MyNativeView.java +++ b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/component/MyNativeView.java @@ -13,8 +13,13 @@ import android.view.View; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableMap; +import com.facebook.react.uimanager.UIManagerHelper; +import com.facebook.react.uimanager.events.Event; +import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.react.uimanager.events.RCTEventEmitter; +import java.util.List; class MyNativeView extends View { @@ -54,4 +59,75 @@ private void emitNativeEvent(int color) { ReactContext reactContext = (ReactContext) getContext(); reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "onColorChanged", event); } + + void emitOnArrayChangedEvent(List ints) { + WritableMap payload = Arguments.createMap(); + + WritableArray newIntArray = Arguments.createArray(); + WritableArray newBoolArray = Arguments.createArray(); + WritableArray newFloatArray = Arguments.createArray(); + WritableArray newDoubleArray = Arguments.createArray(); + WritableArray newYesNoArray = Arguments.createArray(); + WritableArray newStringArray = Arguments.createArray(); + WritableArray newObjectArray = Arguments.createArray(); + WritableArray newArrayArray = Arguments.createArray(); + + for (Integer i : ints) { + newIntArray.pushInt(i * 2); + newBoolArray.pushBoolean(i % 2 == 1); + newFloatArray.pushDouble(i * 3.14); + newDoubleArray.pushDouble(i / 3.14); + newYesNoArray.pushString(i % 2 == 1 ? "yep" : "nope"); + newStringArray.pushString(i.toString()); + + WritableMap latLon = Arguments.createMap(); + latLon.putDouble("lat", -1.0 * i); + latLon.putDouble("lon", 2.0 * i); + newObjectArray.pushMap(latLon); + + WritableArray innerArray = Arguments.createArray(); + innerArray.pushInt(i); + innerArray.pushInt(i); + innerArray.pushInt(i); + newArrayArray.pushArray(innerArray); + } + + payload.putArray("values", newIntArray); + payload.putArray("boolValues", newBoolArray); + payload.putArray("floats", newFloatArray); + payload.putArray("doubles", newDoubleArray); + payload.putArray("yesNos", newYesNoArray); + payload.putArray("strings", newStringArray); + payload.putArray("latLons", newObjectArray); + payload.putArray("multiArrays", newArrayArray); + + ReactContext reactContext = (ReactContext) getContext(); + int surfaceId = UIManagerHelper.getSurfaceId(reactContext); + EventDispatcher eventDispatcher = + UIManagerHelper.getEventDispatcherForReactTag(reactContext, getId()); + Event event = new OnIntArrayChangedEvent(surfaceId, getId(), payload); + + if (eventDispatcher != null) { + eventDispatcher.dispatchEvent(event); + } + } + + class OnIntArrayChangedEvent extends Event { + private WritableMap mPayload; + + public OnIntArrayChangedEvent(int surfaceId, int viewId, WritableMap payload) { + super(surfaceId, viewId); + this.mPayload = payload; + } + + @Override + public String getEventName() { + return "onIntArrayChanged"; + } + + @Override + protected WritableMap getEventData() { + return mPayload; + } + } } diff --git a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/component/MyNativeViewManager.java b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/component/MyNativeViewManager.java index d8c8b731acb3cf..05d23b978aad00 100644 --- a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/component/MyNativeViewManager.java +++ b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/component/MyNativeViewManager.java @@ -11,6 +11,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.common.MapBuilder; import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.uimanager.SimpleViewManager; import com.facebook.react.uimanager.ThemedReactContext; @@ -19,6 +20,10 @@ import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.viewmanagers.RNTMyNativeViewManagerDelegate; import com.facebook.react.viewmanagers.RNTMyNativeViewManagerInterface; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** View manager for {@link MyNativeView} components. */ @ReactModule(name = MyNativeViewManager.REACT_CLASS) @@ -67,4 +72,29 @@ public void callNativeMethodToChangeBackgroundColor(MyNativeView view, String co public void setOpacity(@NonNull MyNativeView view, float opacity) { super.setOpacity(view, opacity); } + + @Override + @ReactProp(name = "values") + public void setValues(@NonNull MyNativeView view, @Nullable ReadableArray value) { + List mValues = new ArrayList(); + for (int i = 0; i < value.size(); i++) { + mValues.add(value.getInt(i)); + } + view.emitOnArrayChangedEvent(mValues); + } + + @Override + public final Map getExportedCustomBubblingEventTypeConstants() { + Map eventTypeConstants = new HashMap(); + eventTypeConstants.putAll( + MapBuilder.builder() + .put( + "onIntArrayChanged", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of( + "bubbled", "onIntArrayChanged", "captured", "onIntArrayChangedCapture"))) + .build()); + return eventTypeConstants; + } }