diff --git a/.gitignore b/.gitignore index 626d954cfa3f18..919d110e1bd216 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,7 @@ project.xcworkspace /packages/react-native/template/android/app/build/ /packages/react-native/template/android/build/ /packages/react-native-popup-menu-android/android/build/ +/packages/react-native-test-library/android/build/ # Buck .buckd diff --git a/packages/react-native-test-library/OSSLibraryExample.podspec b/packages/react-native-test-library/OSSLibraryExample.podspec new file mode 100644 index 00000000000000..9d2a3aaeb05c37 --- /dev/null +++ b/packages/react-native-test-library/OSSLibraryExample.podspec @@ -0,0 +1,24 @@ +# 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. + +require 'json' + +package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) + +Pod::Spec.new do |s| + s.name = 'OSSLibraryExample' + s.version = package['version'] + s.summary = package['description'] + s.description = package['description'] + s.homepage = package['homepage'] + s.license = package['license'] + s.platforms = min_supported_versions + s.author = 'Meta Platforms, Inc. and its affiliates' + s.source = { :git => package['repository'], :tag => "#{s.version}" } + + s.source_files = 'ios/**/*.{h,m,mm,cpp}' + + install_modules_dependencies(s) +end diff --git a/packages/react-native-test-library/README.md b/packages/react-native-test-library/README.md new file mode 100644 index 00000000000000..77df8a6791b313 --- /dev/null +++ b/packages/react-native-test-library/README.md @@ -0,0 +1,9 @@ +## Important +This package is for testing only. It is a subject to frequent change. It does not represent the recomended structure for React native libraries. It should not be used as a referece for such purposes. + +## Building +``` +yarn install +yarn build +npx react-native codegen +``` diff --git a/packages/react-native-test-library/android/build.gradle.kts b/packages/react-native-test-library/android/build.gradle.kts new file mode 100644 index 00000000000000..211f237a5e8f74 --- /dev/null +++ b/packages/react-native-test-library/android/build.gradle.kts @@ -0,0 +1,35 @@ +/* + * 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. + */ + +plugins { + id("com.facebook.react") + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) +} + +android { + compileSdk = libs.versions.compileSdk.get().toInt() + buildToolsVersion = libs.versions.buildTools.get() + namespace = "com.facebook.react.osslibraryexample" + + defaultConfig { + minSdk = libs.versions.minSdk.get().toInt() + targetSdk = libs.versions.targetSdk.get().toInt() + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlinOptions { jvmTarget = "17" } +} + +dependencies { + // Build React Native from source + implementation(project(":packages:react-native:ReactAndroid")) +} diff --git a/packages/react-native-test-library/android/gradle.properties b/packages/react-native-test-library/android/gradle.properties new file mode 100644 index 00000000000000..92a0f87956c8c7 --- /dev/null +++ b/packages/react-native-test-library/android/gradle.properties @@ -0,0 +1,4 @@ + +# We want to have more fine grained control on the Java version for +# ReactAndroid, therefore we disable RGNP Java version alignment mechanism +react.internal.disableJavaVersionAlignment=true diff --git a/packages/react-native-test-library/android/src/main/java/com/facebook/fbreact/specs/NativeSampleModuleSpec.java b/packages/react-native-test-library/android/src/main/java/com/facebook/fbreact/specs/NativeSampleModuleSpec.java new file mode 100644 index 00000000000000..94148064208997 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/java/com/facebook/fbreact/specs/NativeSampleModuleSpec.java @@ -0,0 +1,37 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleJavaSpec.js + * + * @nolint + */ + +package com.facebook.fbreact.specs; + +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.turbomodule.core.interfaces.TurboModule; +import javax.annotation.Nonnull; + +public abstract class NativeSampleModuleSpec extends ReactContextBaseJavaModule implements TurboModule { + public static final String NAME = "NativeSampleModule"; + + public NativeSampleModuleSpec(ReactApplicationContext reactContext) { + super(reactContext); + } + + @Override + public @Nonnull String getName() { + return NAME; + } + + @ReactMethod(isBlockingSynchronousMethod = true) + @DoNotStrip + public abstract double getRandomNumber(); +} diff --git a/packages/react-native-test-library/android/src/main/java/com/facebook/react/viewmanagers/SampleNativeComponentManagerDelegate.java b/packages/react-native-test-library/android/src/main/java/com/facebook/react/viewmanagers/SampleNativeComponentManagerDelegate.java new file mode 100644 index 00000000000000..e25a276cda9898 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/java/com/facebook/react/viewmanagers/SampleNativeComponentManagerDelegate.java @@ -0,0 +1,44 @@ +/** +* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). +* +* Do not edit this file as changes may cause incorrect behavior and will be lost +* once the code is regenerated. +* +* @generated by codegen project: GeneratePropsJavaDelegate.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import androidx.annotation.Nullable; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.uimanager.BaseViewManagerDelegate; +import com.facebook.react.uimanager.BaseViewManagerInterface; + +public class SampleNativeComponentManagerDelegate & SampleNativeComponentManagerInterface> extends BaseViewManagerDelegate { + public SampleNativeComponentManagerDelegate(U viewManager) { + super(viewManager); + } + @Override + public void setProperty(T view, String propName, @Nullable Object value) { + switch (propName) { + case "opacity": + mViewManager.setOpacity(view, value == null ? 0f : ((Double) value).floatValue()); + break; + case "values": + mViewManager.setValues(view, (ReadableArray) value); + break; + default: + super.setProperty(view, propName, value); + } + } + + @Override + public void receiveCommand(T view, String commandName, ReadableArray args) { + switch (commandName) { + case "changeBackgroundColor": + mViewManager.changeBackgroundColor(view, args.getString(0)); + break; + } + } +} diff --git a/packages/react-native-test-library/android/src/main/java/com/facebook/react/viewmanagers/SampleNativeComponentManagerInterface.java b/packages/react-native-test-library/android/src/main/java/com/facebook/react/viewmanagers/SampleNativeComponentManagerInterface.java new file mode 100644 index 00000000000000..83cdf8fbfa3bc9 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/java/com/facebook/react/viewmanagers/SampleNativeComponentManagerInterface.java @@ -0,0 +1,20 @@ +/** +* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). +* +* Do not edit this file as changes may cause incorrect behavior and will be lost +* once the code is regenerated. +* +* @generated by codegen project: GeneratePropsJavaInterface.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import androidx.annotation.Nullable; +import com.facebook.react.bridge.ReadableArray; + +public interface SampleNativeComponentManagerInterface { + void setOpacity(T view, float value); + void setValues(T view, @Nullable ReadableArray value); + void changeBackgroundColor(T view, String color); +} diff --git a/packages/react-native-test-library/android/src/main/java/com/reactnative/osslibraryexample/NativeSampleModule.kt b/packages/react-native-test-library/android/src/main/java/com/reactnative/osslibraryexample/NativeSampleModule.kt new file mode 100644 index 00000000000000..e9154478094fb5 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/java/com/reactnative/osslibraryexample/NativeSampleModule.kt @@ -0,0 +1,30 @@ +/* + * 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. + */ + +package com.reactnative.osslibraryexample + +import com.facebook.fbreact.specs.NativeSampleModuleSpec +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.bridge.ReactContextBaseJavaModule +import com.facebook.react.bridge.ReactMethod +import com.facebook.react.module.annotations.ReactModule + +@ReactModule(name = NativeSampleModuleSpec.NAME) +public class NativeSampleModule(reactContext: ReactApplicationContext?) : + ReactContextBaseJavaModule(reactContext) { + + override fun getName(): String = NAME + + private companion object { + const val NAME = "NativeSampleModule" + } + + @ReactMethod + public fun getRandomNumber(): Int { + return (0..99).random() + } +} diff --git a/packages/react-native-test-library/android/src/main/java/com/reactnative/osslibraryexample/OSSLibraryExamplePackage.kt b/packages/react-native-test-library/android/src/main/java/com/reactnative/osslibraryexample/OSSLibraryExamplePackage.kt new file mode 100644 index 00000000000000..a8da27f7fe49e0 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/java/com/reactnative/osslibraryexample/OSSLibraryExamplePackage.kt @@ -0,0 +1,21 @@ +/* + * 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. + */ + +package com.reactnative.osslibraryexample + +import com.facebook.react.ReactPackage +import com.facebook.react.bridge.NativeModule +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.uimanager.ViewManager + +public class OSSLibraryExamplePackage : ReactPackage { + override fun createNativeModules(reactContext: ReactApplicationContext): List = + listOf(NativeSampleModule(reactContext)) + + override fun createViewManagers(reactContext: ReactApplicationContext): List> = + listOf(SampleNativeComponentViewManager()) +} diff --git a/packages/react-native-test-library/android/src/main/java/com/reactnative/osslibraryexample/SampleNativeComponentViewManager.kt b/packages/react-native-test-library/android/src/main/java/com/reactnative/osslibraryexample/SampleNativeComponentViewManager.kt new file mode 100644 index 00000000000000..c9acc3c6877846 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/java/com/reactnative/osslibraryexample/SampleNativeComponentViewManager.kt @@ -0,0 +1,98 @@ +/* + * 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. + */ + +package com.reactnative.osslibraryexample + +import android.graphics.Color +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 +import com.facebook.react.uimanager.ViewProps +import com.facebook.react.uimanager.annotations.ReactProp +import com.facebook.react.viewmanagers.SampleNativeComponentManagerInterface + +/** Legacy View manager (non Fabric compatible) for {@link SampleNativeView} components. */ +@ReactModule(name = SampleNativeComponentViewManager.REACT_CLASS) +internal class SampleNativeComponentViewManager : + SimpleViewManager(), SampleNativeComponentManagerInterface { + + override fun getName(): String = REACT_CLASS + + // @ReactProp(name = ViewProps.OPACITY, defaultFloat = 1f) + override fun setOpacity(view: SampleNativeView, opacity: Float) { + super.setOpacity(view, opacity) + } + + @ReactProp(name = ViewProps.COLOR) + fun setColor(view: SampleNativeView, color: String) { + view.setBackgroundColor(Color.parseColor(color)) + } + + @ReactProp(name = "cornerRadius") + fun setCornerRadius(view: SampleNativeView, cornerRadius: Float) { + view.setCornerRadius(cornerRadius) + } + + override fun createViewInstance(reactContext: ThemedReactContext): SampleNativeView = + SampleNativeView(reactContext) + + override fun changeBackgroundColor(view: SampleNativeView, color: String) { + view.setBackgroundColor(Color.parseColor(color)) + } + + override fun getExportedViewConstants(): Map = mapOf("PI" to 3.14) + + override fun getExportedCustomBubblingEventTypeConstants(): Map { + return MapBuilder.builder() + .put( + "onColorChanged", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of("bubbled", "onColorChanged", "captured", "onColorChangedCapture"))) + .put( + "topIntArrayChanged", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of( + "bubbled", "topIntArrayChanged", "captured", "topIntArrayChangedCapture"))) + .build() + } + + override fun receiveCommand(view: SampleNativeView, commandId: String, args: ReadableArray?) { + if (commandId.contentEquals("changeBackgroundColor")) { + val sentColor: Int = Color.parseColor(args?.getString(0)) + view.setBackgroundColor(sentColor) + } + } + + @Suppress("DEPRECATION") // We intentionally want to test against the legacy API here. + override fun receiveCommand(view: SampleNativeView, commandId: Int, args: ReadableArray?) { + when (commandId) { + COMMAND_CHANGE_BACKGROUND_COLOR -> { + val sentColor: Int = Color.parseColor(args?.getString(0)) + view.setBackgroundColor(sentColor) + } + } + } + + override fun getCommandsMap(): Map = + mapOf("changeBackgroundColor" to COMMAND_CHANGE_BACKGROUND_COLOR) + + companion object { + const val REACT_CLASS = "SampleNativeComponent" + const val COMMAND_CHANGE_BACKGROUND_COLOR = 42 + } + + @ReactProp(name = "values") + override fun setValues(view: SampleNativeView, value: ReadableArray?) { + val values = mutableListOf() + value?.toArrayList()?.forEach { values.add((it as Double).toInt()) } + view.emitOnArrayChangedEvent(values) + } +} diff --git a/packages/react-native-test-library/android/src/main/java/com/reactnative/osslibraryexample/SampleNativeView.kt b/packages/react-native-test-library/android/src/main/java/com/reactnative/osslibraryexample/SampleNativeView.kt new file mode 100644 index 00000000000000..34ea4b8ea5b48c --- /dev/null +++ b/packages/react-native-test-library/android/src/main/java/com/reactnative/osslibraryexample/SampleNativeView.kt @@ -0,0 +1,97 @@ +/* + * 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. + */ + +package com.reactnative.osslibraryexample + +import android.graphics.drawable.GradientDrawable +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.ThemedReactContext +import com.facebook.react.uimanager.UIManagerHelper +import com.facebook.react.uimanager.events.Event + +public class SampleNativeView(context: ThemedReactContext) : View(context) { + private var currentColor = 0 + private var background: GradientDrawable = GradientDrawable() + private val reactContext: ReactContext = context.reactApplicationContext + + override fun setBackgroundColor(color: Int) { + if (color != currentColor) { + background.setColor(color) + currentColor = color + setBackground(background) + } + } + + public fun setCornerRadius(cornerRadius: Float) { + background.cornerRadius = cornerRadius + setBackground(background) + } + + public fun emitOnArrayChangedEvent(ints: List) { + val newIntArray = Arguments.createArray() + val newBoolArray = Arguments.createArray() + val newFloatArray = Arguments.createArray() + val newDoubleArray = Arguments.createArray() + val newYesNoArray = Arguments.createArray() + val newStringArray = Arguments.createArray() + val newObjectArray = Arguments.createArray() + val newArrayArray = Arguments.createArray() + + for (i in ints) { + newIntArray.pushInt(i * 2) + newBoolArray.pushBoolean(i % 2 == 1) + newFloatArray.pushDouble(i * 3.14) + newDoubleArray.pushDouble(i / 3.14) + newYesNoArray.pushString(if (i % 2 == 1) "yep" else "nope") + newStringArray.pushString(i.toString()) + + val latLon = Arguments.createMap() + latLon.putDouble("lat", -1.0 * i) + latLon.putDouble("lon", 2.0 * i) + newObjectArray.pushMap(latLon) + + val innerArray: WritableArray = Arguments.createArray() + innerArray.pushInt(i) + innerArray.pushInt(i) + innerArray.pushInt(i) + newArrayArray.pushArray(innerArray) + } + + val payload = + Arguments.createMap().apply { + putArray("values", newIntArray) + putArray("boolValues", newBoolArray) + putArray("floats", newFloatArray) + putArray("doubles", newDoubleArray) + putArray("yesNos", newYesNoArray) + putArray("strings", newStringArray) + putArray("latLons", newObjectArray) + putArray("multiArrays", newArrayArray) + } + + val reactContext = context as ReactContext + val surfaceId = UIManagerHelper.getSurfaceId(reactContext) + val eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, id) + val event = OnIntArrayChangedEvent(surfaceId, id, payload) + + eventDispatcher?.dispatchEvent(event) + } + + private inner class OnIntArrayChangedEvent( + surfaceId: Int, + viewId: Int, + private val payload: WritableMap + ) : Event(surfaceId, viewId) { + override fun getEventName() = "topIntArrayChanged" + + override fun getEventData() = payload + } +} diff --git a/packages/react-native-test-library/android/src/main/jni/CMakeLists.txt b/packages/react-native-test-library/android/src/main/jni/CMakeLists.txt new file mode 100644 index 00000000000000..ab02a2a4a4170d --- /dev/null +++ b/packages/react-native-test-library/android/src/main/jni/CMakeLists.txt @@ -0,0 +1,49 @@ +# 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. + +cmake_minimum_required(VERSION 3.13) +set(CMAKE_VERBOSE_MAKEFILE on) + +file(GLOB react_codegen_SRCS CONFIGURE_DEPENDS *.cpp react/renderer/components/OSSLibraryExampleSpec/*.cpp) + +add_library( + react_codegen_OSSLibraryExampleSpec + SHARED + ${react_codegen_SRCS} +) + +target_include_directories(react_codegen_OSSLibraryExampleSpec PUBLIC . react/renderer/components/OSSLibraryExampleSpec) + +target_link_libraries( + react_codegen_OSSLibraryExampleSpec + fbjni + folly_runtime + glog + jsi + react_codegen_rncore + react_debug + react_nativemodule_core + react_render_componentregistry + react_render_core + react_render_debug + react_render_graphics + react_render_imagemanager + react_render_mapbuffer + react_utils + rrc_image + rrc_view + turbomodulejsijni + yoga +) + +target_compile_options( + react_codegen_OSSLibraryExampleSpec + PRIVATE + -DLOG_TAG=\"ReactNative\" + -fexceptions + -frtti + -std=c++20 + -Wall +) diff --git a/packages/react-native-test-library/android/src/main/jni/OSSLibraryExampleSpec-generated.cpp b/packages/react-native-test-library/android/src/main/jni/OSSLibraryExampleSpec-generated.cpp new file mode 100644 index 00000000000000..b940af418aa7a2 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/jni/OSSLibraryExampleSpec-generated.cpp @@ -0,0 +1,32 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleJniCpp.js + */ + +#include "OSSLibraryExampleSpec.h" + +namespace facebook::react { + +static facebook::jsi::Value __hostFunction_NativeSampleModuleSpecJSI_getRandomNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, NumberKind, "getRandomNumber", "()D", args, count, cachedMethodId); +} + +NativeSampleModuleSpecJSI::NativeSampleModuleSpecJSI(const JavaTurboModule::InitParams ¶ms) + : JavaTurboModule(params) { + methodMap_["getRandomNumber"] = MethodMetadata {0, __hostFunction_NativeSampleModuleSpecJSI_getRandomNumber}; +} + +std::shared_ptr OSSLibraryExampleSpec_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams ¶ms) { + if (moduleName == "NativeSampleModule") { + return std::make_shared(params); + } + return nullptr; +} + +} // namespace facebook::react diff --git a/packages/react-native-test-library/android/src/main/jni/OSSLibraryExampleSpec.h b/packages/react-native-test-library/android/src/main/jni/OSSLibraryExampleSpec.h new file mode 100644 index 00000000000000..6d39f6b6de3dbf --- /dev/null +++ b/packages/react-native-test-library/android/src/main/jni/OSSLibraryExampleSpec.h @@ -0,0 +1,31 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleJniH.js + */ + +#pragma once + +#include +#include +#include + +namespace facebook::react { + +/** + * JNI C++ class for module 'NativeSampleModule' + */ +class JSI_EXPORT NativeSampleModuleSpecJSI : public JavaTurboModule { +public: + NativeSampleModuleSpecJSI(const JavaTurboModule::InitParams ¶ms); +}; + + +JSI_EXPORT +std::shared_ptr OSSLibraryExampleSpec_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams ¶ms); + +} // namespace facebook::react diff --git a/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/ComponentDescriptors.cpp b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/ComponentDescriptors.cpp new file mode 100644 index 00000000000000..385369e4c052a3 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/ComponentDescriptors.cpp @@ -0,0 +1,22 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateComponentDescriptorCpp.js + */ + +#include "ComponentDescriptors.h" +#include +#include + +namespace facebook::react { + +void OSSLibraryExampleSpec_registerComponentDescriptorsFromCodegen( + std::shared_ptr registry) { +registry->add(concreteComponentDescriptorProvider()); +} + +} // namespace facebook::react diff --git a/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/ComponentDescriptors.h b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/ComponentDescriptors.h new file mode 100644 index 00000000000000..eac078b81d9d74 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/ComponentDescriptors.h @@ -0,0 +1,24 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateComponentDescriptorH.js + */ + +#pragma once + +#include "ShadowNodes.h" +#include +#include + +namespace facebook::react { + +using SampleNativeComponentComponentDescriptor = ConcreteComponentDescriptor; + +void OSSLibraryExampleSpec_registerComponentDescriptorsFromCodegen( + std::shared_ptr registry); + +} // namespace facebook::react diff --git a/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/EventEmitters.cpp b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/EventEmitters.cpp new file mode 100644 index 00000000000000..c5746ac5306da6 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/EventEmitters.cpp @@ -0,0 +1,95 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateEventEmitterCpp.js + */ + +#include "EventEmitters.h" + + +namespace facebook::react { + +void SampleNativeComponentEventEmitter::onIntArrayChanged(OnIntArrayChanged $event) const { + dispatchEvent("intArrayChanged", [$event=std::move($event)](jsi::Runtime &runtime) { + auto $payload = jsi::Object(runtime); + + auto values = jsi::Array(runtime, $event.values.size()); + size_t valuesIndex = 0; + for (auto valuesValue : $event.values) { + values.setValueAtIndex(runtime, valuesIndex++, valuesValue); + } + $payload.setProperty(runtime, "values", values); + + + auto boolValues = jsi::Array(runtime, $event.boolValues.size()); + size_t boolValuesIndex = 0; + for (auto boolValuesValue : $event.boolValues) { + boolValues.setValueAtIndex(runtime, boolValuesIndex++, (bool)boolValuesValue); + } + $payload.setProperty(runtime, "boolValues", boolValues); + + + auto floats = jsi::Array(runtime, $event.floats.size()); + size_t floatsIndex = 0; + for (auto floatsValue : $event.floats) { + floats.setValueAtIndex(runtime, floatsIndex++, floatsValue); + } + $payload.setProperty(runtime, "floats", floats); + + + auto doubles = jsi::Array(runtime, $event.doubles.size()); + size_t doublesIndex = 0; + for (auto doublesValue : $event.doubles) { + doubles.setValueAtIndex(runtime, doublesIndex++, doublesValue); + } + $payload.setProperty(runtime, "doubles", doubles); + + + auto yesNos = jsi::Array(runtime, $event.yesNos.size()); + size_t yesNosIndex = 0; + for (auto yesNosValue : $event.yesNos) { + yesNos.setValueAtIndex(runtime, yesNosIndex++, toString(yesNosValue)); + } + $payload.setProperty(runtime, "yesNos", yesNos); + + + auto strings = jsi::Array(runtime, $event.strings.size()); + size_t stringsIndex = 0; + for (auto stringsValue : $event.strings) { + strings.setValueAtIndex(runtime, stringsIndex++, stringsValue); + } + $payload.setProperty(runtime, "strings", strings); + + + auto latLons = jsi::Array(runtime, $event.latLons.size()); + size_t latLonsIndex = 0; + for (auto latLonsValue : $event.latLons) { + auto latLonsObject = jsi::Object(runtime); + latLonsObject.setProperty(runtime, "lat", latLonsValue.lat); +latLonsObject.setProperty(runtime, "lon", latLonsValue.lon); + latLons.setValueAtIndex(runtime, latLonsIndex++, latLonsObject); + } + $payload.setProperty(runtime, "latLons", latLons); + + + auto multiArrays = jsi::Array(runtime, $event.multiArrays.size()); + size_t multiArraysIndex = 0; + for (auto multiArraysValue : $event.multiArrays) { + auto multiArraysArray = jsi::Array(runtime, multiArraysValue.size()); + size_t multiArraysIndexInternal = 0; + for (auto multiArraysValueInternal : multiArraysValue) { + multiArraysArray.setValueAtIndex(runtime, multiArraysIndexInternal++, multiArraysValueInternal); + } + multiArrays.setValueAtIndex(runtime, multiArraysIndex++, multiArraysArray); + } + $payload.setProperty(runtime, "multiArrays", multiArrays); + + return $payload; + }); +} + +} // namespace facebook::react diff --git a/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/EventEmitters.h b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/EventEmitters.h new file mode 100644 index 00000000000000..bfb9cc27ae82e1 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/EventEmitters.h @@ -0,0 +1,49 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateEventEmitterH.js + */ +#pragma once + +#include + + +namespace facebook::react { +class SampleNativeComponentEventEmitter : public ViewEventEmitter { + public: + using ViewEventEmitter::ViewEventEmitter; + + enum class OnIntArrayChangedYesNos { + Yep, + Nope + }; + + static char const *toString(const OnIntArrayChangedYesNos value) { + switch (value) { + case OnIntArrayChangedYesNos::Yep: return "yep"; + case OnIntArrayChangedYesNos::Nope: return "nope"; + } + } + + struct OnIntArrayChangedLatLons { + double lat; + double lon; + }; + + struct OnIntArrayChanged { + std::vector values; + std::vector boolValues; + std::vector floats; + std::vector doubles; + std::vector yesNos; + std::vector strings; + std::vector latLons; + std::vector> multiArrays; + }; + void onIntArrayChanged(OnIntArrayChanged value) const; +}; +} // namespace facebook::react diff --git a/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/OSSLibraryExampleSpecJSI-generated.cpp b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/OSSLibraryExampleSpecJSI-generated.cpp new file mode 100644 index 00000000000000..fc734d9e6f30e6 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/OSSLibraryExampleSpecJSI-generated.cpp @@ -0,0 +1,26 @@ +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleCpp.js + */ + +#include "OSSLibraryExampleSpecJSI.h" + +namespace facebook::react { + +static jsi::Value __hostFunction_NativeSampleModuleCxxSpecJSI_getRandomNumber(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getRandomNumber( + rt + ); +} + +NativeSampleModuleCxxSpecJSI::NativeSampleModuleCxxSpecJSI(std::shared_ptr jsInvoker) + : TurboModule("NativeSampleModule", jsInvoker) { + methodMap_["getRandomNumber"] = MethodMetadata {0, __hostFunction_NativeSampleModuleCxxSpecJSI_getRandomNumber}; +} + + +} // namespace facebook::react diff --git a/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/OSSLibraryExampleSpecJSI.h b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/OSSLibraryExampleSpecJSI.h new file mode 100644 index 00000000000000..7955b323295eec --- /dev/null +++ b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/OSSLibraryExampleSpecJSI.h @@ -0,0 +1,63 @@ +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleH.js + */ + +#pragma once + +#include +#include + +namespace facebook::react { + + + class JSI_EXPORT NativeSampleModuleCxxSpecJSI : public TurboModule { +protected: + NativeSampleModuleCxxSpecJSI(std::shared_ptr jsInvoker); + +public: + virtual double getRandomNumber(jsi::Runtime &rt) = 0; + +}; + +template +class JSI_EXPORT NativeSampleModuleCxxSpec : public TurboModule { +public: + jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override { + return delegate_.get(rt, propName); + } + + static constexpr std::string_view kModuleName = "NativeSampleModule"; + +protected: + NativeSampleModuleCxxSpec(std::shared_ptr jsInvoker) + : TurboModule(std::string{NativeSampleModuleCxxSpec::kModuleName}, jsInvoker), + delegate_(reinterpret_cast(this), jsInvoker) {} + +private: + class Delegate : public NativeSampleModuleCxxSpecJSI { + public: + Delegate(T *instance, std::shared_ptr jsInvoker) : + NativeSampleModuleCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {} + + double getRandomNumber(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::getRandomNumber) == 1, + "Expected getRandomNumber(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::getRandomNumber, jsInvoker_, instance_); + } + + private: + T *instance_; + }; + + Delegate delegate_; +}; + +} // namespace facebook::react diff --git a/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/Props.cpp b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/Props.cpp new file mode 100644 index 00000000000000..595766f26bd083 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/Props.cpp @@ -0,0 +1,26 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GeneratePropsCpp.js + */ + +#include "Props.h" +#include +#include + +namespace facebook::react { + +SampleNativeComponentProps::SampleNativeComponentProps( + const PropsParserContext &context, + const SampleNativeComponentProps &sourceProps, + const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), + + opacity(convertRawProp(context, rawProps, "opacity", sourceProps.opacity, {0.0})), + values(convertRawProp(context, rawProps, "values", sourceProps.values, {})) + {} + +} // namespace facebook::react diff --git a/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/Props.h b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/Props.h new file mode 100644 index 00000000000000..fd7ad9642bcb22 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/Props.h @@ -0,0 +1,29 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GeneratePropsH.js + */ +#pragma once + +#include +#include +#include + +namespace facebook::react { + +class SampleNativeComponentProps final : public ViewProps { + public: + SampleNativeComponentProps() = default; + SampleNativeComponentProps(const PropsParserContext& context, const SampleNativeComponentProps &sourceProps, const RawProps &rawProps); + +#pragma mark - Props + + Float opacity{0.0}; + std::vector values{}; +}; + +} // namespace facebook::react diff --git a/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/ShadowNodes.cpp b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/ShadowNodes.cpp new file mode 100644 index 00000000000000..790189cffd6e1e --- /dev/null +++ b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/ShadowNodes.cpp @@ -0,0 +1,17 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateShadowNodeCpp.js + */ + +#include "ShadowNodes.h" + +namespace facebook::react { + +extern const char SampleNativeComponentComponentName[] = "SampleNativeComponent"; + +} // namespace facebook::react diff --git a/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/ShadowNodes.h b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/ShadowNodes.h new file mode 100644 index 00000000000000..20b9db3837a1c7 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/ShadowNodes.h @@ -0,0 +1,32 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateShadowNodeH.js + */ + +#pragma once + +#include "EventEmitters.h" +#include "Props.h" +#include "States.h" +#include +#include + +namespace facebook::react { + +JSI_EXPORT extern const char SampleNativeComponentComponentName[]; + +/* + * `ShadowNode` for component. + */ +using SampleNativeComponentShadowNode = ConcreteViewShadowNode< + SampleNativeComponentComponentName, + SampleNativeComponentProps, + SampleNativeComponentEventEmitter, + SampleNativeComponentState>; + +} // namespace facebook::react diff --git a/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/States.cpp b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/States.cpp new file mode 100644 index 00000000000000..1dbb184cbddb62 --- /dev/null +++ b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/States.cpp @@ -0,0 +1,16 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateStateCpp.js + */ +#include "States.h" + +namespace facebook::react { + + + +} // namespace facebook::react diff --git a/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/States.h b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/States.h new file mode 100644 index 00000000000000..f4d6efa82c0acf --- /dev/null +++ b/packages/react-native-test-library/android/src/main/jni/react/renderer/components/OSSLibraryExampleSpec/States.h @@ -0,0 +1,34 @@ +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateStateH.js + */ +#pragma once + +#ifdef ANDROID +#include +#include +#include +#endif + +namespace facebook::react { + +class SampleNativeComponentState { +public: + SampleNativeComponentState() = default; + +#ifdef ANDROID + SampleNativeComponentState(SampleNativeComponentState const &previousState, folly::dynamic data){}; + folly::dynamic getDynamic() const { + return {}; + }; + MapBuffer getMapBuffer() const { + return MapBufferBuilder::EMPTY(); + }; +#endif +}; + +} // namespace facebook::react \ No newline at end of file diff --git a/packages/react-native-test-library/babel.config.js b/packages/react-native-test-library/babel.config.js new file mode 100644 index 00000000000000..3bcc1e3d56e200 --- /dev/null +++ b/packages/react-native-test-library/babel.config.js @@ -0,0 +1,10 @@ +/** + * 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. + */ + +module.exports = { + presets: [['module:@react-native/babel-preset', {disableStaticViewConfigsCodegen: false}]], +}; diff --git a/packages/react-native-test-library/index.js b/packages/react-native-test-library/index.js new file mode 100644 index 00000000000000..a623cdc1ef00de --- /dev/null +++ b/packages/react-native-test-library/index.js @@ -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. + * + * @flow strict-local + * @format + */ + +export {default as SampleNativeComponent} from './src/SampleNativeComponent'; +export type {NativeComponentType} from './src/SampleNativeComponent'; +import {Commands as SampleNativeComponentCommands} from './src/SampleNativeComponent'; +export {SampleNativeComponentCommands}; +export {default as NativeSampleModule} from './src/NativeSampleModule'; diff --git a/packages/react-native-test-library/ios/OSSLibraryExampleSpec/ComponentDescriptors.cpp b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/ComponentDescriptors.cpp new file mode 100644 index 00000000000000..385369e4c052a3 --- /dev/null +++ b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/ComponentDescriptors.cpp @@ -0,0 +1,22 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateComponentDescriptorCpp.js + */ + +#include "ComponentDescriptors.h" +#include +#include + +namespace facebook::react { + +void OSSLibraryExampleSpec_registerComponentDescriptorsFromCodegen( + std::shared_ptr registry) { +registry->add(concreteComponentDescriptorProvider()); +} + +} // namespace facebook::react diff --git a/packages/react-native-test-library/ios/OSSLibraryExampleSpec/ComponentDescriptors.h b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/ComponentDescriptors.h new file mode 100644 index 00000000000000..eac078b81d9d74 --- /dev/null +++ b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/ComponentDescriptors.h @@ -0,0 +1,24 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateComponentDescriptorH.js + */ + +#pragma once + +#include "ShadowNodes.h" +#include +#include + +namespace facebook::react { + +using SampleNativeComponentComponentDescriptor = ConcreteComponentDescriptor; + +void OSSLibraryExampleSpec_registerComponentDescriptorsFromCodegen( + std::shared_ptr registry); + +} // namespace facebook::react diff --git a/packages/react-native-test-library/ios/OSSLibraryExampleSpec/EventEmitters.cpp b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/EventEmitters.cpp new file mode 100644 index 00000000000000..c5746ac5306da6 --- /dev/null +++ b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/EventEmitters.cpp @@ -0,0 +1,95 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateEventEmitterCpp.js + */ + +#include "EventEmitters.h" + + +namespace facebook::react { + +void SampleNativeComponentEventEmitter::onIntArrayChanged(OnIntArrayChanged $event) const { + dispatchEvent("intArrayChanged", [$event=std::move($event)](jsi::Runtime &runtime) { + auto $payload = jsi::Object(runtime); + + auto values = jsi::Array(runtime, $event.values.size()); + size_t valuesIndex = 0; + for (auto valuesValue : $event.values) { + values.setValueAtIndex(runtime, valuesIndex++, valuesValue); + } + $payload.setProperty(runtime, "values", values); + + + auto boolValues = jsi::Array(runtime, $event.boolValues.size()); + size_t boolValuesIndex = 0; + for (auto boolValuesValue : $event.boolValues) { + boolValues.setValueAtIndex(runtime, boolValuesIndex++, (bool)boolValuesValue); + } + $payload.setProperty(runtime, "boolValues", boolValues); + + + auto floats = jsi::Array(runtime, $event.floats.size()); + size_t floatsIndex = 0; + for (auto floatsValue : $event.floats) { + floats.setValueAtIndex(runtime, floatsIndex++, floatsValue); + } + $payload.setProperty(runtime, "floats", floats); + + + auto doubles = jsi::Array(runtime, $event.doubles.size()); + size_t doublesIndex = 0; + for (auto doublesValue : $event.doubles) { + doubles.setValueAtIndex(runtime, doublesIndex++, doublesValue); + } + $payload.setProperty(runtime, "doubles", doubles); + + + auto yesNos = jsi::Array(runtime, $event.yesNos.size()); + size_t yesNosIndex = 0; + for (auto yesNosValue : $event.yesNos) { + yesNos.setValueAtIndex(runtime, yesNosIndex++, toString(yesNosValue)); + } + $payload.setProperty(runtime, "yesNos", yesNos); + + + auto strings = jsi::Array(runtime, $event.strings.size()); + size_t stringsIndex = 0; + for (auto stringsValue : $event.strings) { + strings.setValueAtIndex(runtime, stringsIndex++, stringsValue); + } + $payload.setProperty(runtime, "strings", strings); + + + auto latLons = jsi::Array(runtime, $event.latLons.size()); + size_t latLonsIndex = 0; + for (auto latLonsValue : $event.latLons) { + auto latLonsObject = jsi::Object(runtime); + latLonsObject.setProperty(runtime, "lat", latLonsValue.lat); +latLonsObject.setProperty(runtime, "lon", latLonsValue.lon); + latLons.setValueAtIndex(runtime, latLonsIndex++, latLonsObject); + } + $payload.setProperty(runtime, "latLons", latLons); + + + auto multiArrays = jsi::Array(runtime, $event.multiArrays.size()); + size_t multiArraysIndex = 0; + for (auto multiArraysValue : $event.multiArrays) { + auto multiArraysArray = jsi::Array(runtime, multiArraysValue.size()); + size_t multiArraysIndexInternal = 0; + for (auto multiArraysValueInternal : multiArraysValue) { + multiArraysArray.setValueAtIndex(runtime, multiArraysIndexInternal++, multiArraysValueInternal); + } + multiArrays.setValueAtIndex(runtime, multiArraysIndex++, multiArraysArray); + } + $payload.setProperty(runtime, "multiArrays", multiArrays); + + return $payload; + }); +} + +} // namespace facebook::react diff --git a/packages/react-native-test-library/ios/OSSLibraryExampleSpec/EventEmitters.h b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/EventEmitters.h new file mode 100644 index 00000000000000..bfb9cc27ae82e1 --- /dev/null +++ b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/EventEmitters.h @@ -0,0 +1,49 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateEventEmitterH.js + */ +#pragma once + +#include + + +namespace facebook::react { +class SampleNativeComponentEventEmitter : public ViewEventEmitter { + public: + using ViewEventEmitter::ViewEventEmitter; + + enum class OnIntArrayChangedYesNos { + Yep, + Nope + }; + + static char const *toString(const OnIntArrayChangedYesNos value) { + switch (value) { + case OnIntArrayChangedYesNos::Yep: return "yep"; + case OnIntArrayChangedYesNos::Nope: return "nope"; + } + } + + struct OnIntArrayChangedLatLons { + double lat; + double lon; + }; + + struct OnIntArrayChanged { + std::vector values; + std::vector boolValues; + std::vector floats; + std::vector doubles; + std::vector yesNos; + std::vector strings; + std::vector latLons; + std::vector> multiArrays; + }; + void onIntArrayChanged(OnIntArrayChanged value) const; +}; +} // namespace facebook::react diff --git a/packages/react-native-test-library/ios/OSSLibraryExampleSpec/OSSLibraryExampleSpec-generated.mm b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/OSSLibraryExampleSpec-generated.mm new file mode 100644 index 00000000000000..faf7056af985a4 --- /dev/null +++ b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/OSSLibraryExampleSpec-generated.mm @@ -0,0 +1,29 @@ +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleObjCpp + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. + */ + +#import "OSSLibraryExampleSpec.h" + + +namespace facebook::react { + + static facebook::jsi::Value __hostFunction_NativeSampleModuleSpecJSI_getRandomNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, "getRandomNumber", @selector(getRandomNumber), args, count); + } + + NativeSampleModuleSpecJSI::NativeSampleModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_["getRandomNumber"] = MethodMetadata {0, __hostFunction_NativeSampleModuleSpecJSI_getRandomNumber}; + + } +} // namespace facebook::react diff --git a/packages/react-native-test-library/ios/OSSLibraryExampleSpec/OSSLibraryExampleSpec.h b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/OSSLibraryExampleSpec.h new file mode 100644 index 00000000000000..462a85d5c430e4 --- /dev/null +++ b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/OSSLibraryExampleSpec.h @@ -0,0 +1,43 @@ +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleObjCpp + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. + */ + +#ifndef __cplusplus +#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm. +#endif +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + + +@protocol NativeSampleModuleSpec + +- (NSNumber *)getRandomNumber; + +@end +namespace facebook::react { + /** + * ObjC++ class for module 'NativeSampleModule' + */ + class JSI_EXPORT NativeSampleModuleSpecJSI : public ObjCTurboModule { + public: + NativeSampleModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; +} // namespace facebook::react + diff --git a/packages/react-native-test-library/ios/OSSLibraryExampleSpec/Props.cpp b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/Props.cpp new file mode 100644 index 00000000000000..595766f26bd083 --- /dev/null +++ b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/Props.cpp @@ -0,0 +1,26 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GeneratePropsCpp.js + */ + +#include "Props.h" +#include +#include + +namespace facebook::react { + +SampleNativeComponentProps::SampleNativeComponentProps( + const PropsParserContext &context, + const SampleNativeComponentProps &sourceProps, + const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), + + opacity(convertRawProp(context, rawProps, "opacity", sourceProps.opacity, {0.0})), + values(convertRawProp(context, rawProps, "values", sourceProps.values, {})) + {} + +} // namespace facebook::react diff --git a/packages/react-native-test-library/ios/OSSLibraryExampleSpec/Props.h b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/Props.h new file mode 100644 index 00000000000000..fd7ad9642bcb22 --- /dev/null +++ b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/Props.h @@ -0,0 +1,29 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GeneratePropsH.js + */ +#pragma once + +#include +#include +#include + +namespace facebook::react { + +class SampleNativeComponentProps final : public ViewProps { + public: + SampleNativeComponentProps() = default; + SampleNativeComponentProps(const PropsParserContext& context, const SampleNativeComponentProps &sourceProps, const RawProps &rawProps); + +#pragma mark - Props + + Float opacity{0.0}; + std::vector values{}; +}; + +} // namespace facebook::react diff --git a/packages/react-native-test-library/ios/OSSLibraryExampleSpec/RCTComponentViewHelpers.h b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/RCTComponentViewHelpers.h new file mode 100644 index 00000000000000..d6e5a3531eedff --- /dev/null +++ b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/RCTComponentViewHelpers.h @@ -0,0 +1,50 @@ +/** +* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). +* +* Do not edit this file as changes may cause incorrect behavior and will be lost +* once the code is regenerated. +* +* @generated by codegen project: GenerateComponentHObjCpp.js +*/ + +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol RCTSampleNativeComponentViewProtocol +- (void)changeBackgroundColor:(NSString *)color; +@end + +RCT_EXTERN inline void RCTSampleNativeComponentHandleCommand( + id componentView, + NSString const *commandName, + NSArray const *args) +{ + if ([commandName isEqualToString:@"changeBackgroundColor"]) { +#if RCT_DEBUG + if ([args count] != 1) { + RCTLogError(@"%@ command %@ received %d arguments, expected %d.", @"SampleNativeComponent", commandName, (int)[args count], 1); + return; + } +#endif + + NSObject *arg0 = args[0]; +#if RCT_DEBUG + if (!RCTValidateTypeOfViewCommandArgument(arg0, [NSString class], @"string", @"SampleNativeComponent", commandName, @"1st")) { + return; + } +#endif + NSString * color = (NSString *)arg0; + + [componentView changeBackgroundColor:color]; + return; +} + +#if RCT_DEBUG + RCTLogError(@"%@ received command %@, which is not a supported command.", @"SampleNativeComponent", commandName); +#endif +} + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/packages/react-native-test-library/ios/OSSLibraryExampleSpec/ShadowNodes.cpp b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/ShadowNodes.cpp new file mode 100644 index 00000000000000..790189cffd6e1e --- /dev/null +++ b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/ShadowNodes.cpp @@ -0,0 +1,17 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateShadowNodeCpp.js + */ + +#include "ShadowNodes.h" + +namespace facebook::react { + +extern const char SampleNativeComponentComponentName[] = "SampleNativeComponent"; + +} // namespace facebook::react diff --git a/packages/react-native-test-library/ios/OSSLibraryExampleSpec/ShadowNodes.h b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/ShadowNodes.h new file mode 100644 index 00000000000000..20b9db3837a1c7 --- /dev/null +++ b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/ShadowNodes.h @@ -0,0 +1,32 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateShadowNodeH.js + */ + +#pragma once + +#include "EventEmitters.h" +#include "Props.h" +#include "States.h" +#include +#include + +namespace facebook::react { + +JSI_EXPORT extern const char SampleNativeComponentComponentName[]; + +/* + * `ShadowNode` for component. + */ +using SampleNativeComponentShadowNode = ConcreteViewShadowNode< + SampleNativeComponentComponentName, + SampleNativeComponentProps, + SampleNativeComponentEventEmitter, + SampleNativeComponentState>; + +} // namespace facebook::react diff --git a/packages/react-native-test-library/ios/OSSLibraryExampleSpec/States.cpp b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/States.cpp new file mode 100644 index 00000000000000..1dbb184cbddb62 --- /dev/null +++ b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/States.cpp @@ -0,0 +1,16 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateStateCpp.js + */ +#include "States.h" + +namespace facebook::react { + + + +} // namespace facebook::react diff --git a/packages/react-native-test-library/ios/OSSLibraryExampleSpec/States.h b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/States.h new file mode 100644 index 00000000000000..f4d6efa82c0acf --- /dev/null +++ b/packages/react-native-test-library/ios/OSSLibraryExampleSpec/States.h @@ -0,0 +1,34 @@ +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateStateH.js + */ +#pragma once + +#ifdef ANDROID +#include +#include +#include +#endif + +namespace facebook::react { + +class SampleNativeComponentState { +public: + SampleNativeComponentState() = default; + +#ifdef ANDROID + SampleNativeComponentState(SampleNativeComponentState const &previousState, folly::dynamic data){}; + folly::dynamic getDynamic() const { + return {}; + }; + MapBuffer getMapBuffer() const { + return MapBufferBuilder::EMPTY(); + }; +#endif +}; + +} // namespace facebook::react \ No newline at end of file diff --git a/packages/react-native-test-library/ios/OSSLibraryExampleSpecJSI-generated.cpp b/packages/react-native-test-library/ios/OSSLibraryExampleSpecJSI-generated.cpp new file mode 100644 index 00000000000000..fc734d9e6f30e6 --- /dev/null +++ b/packages/react-native-test-library/ios/OSSLibraryExampleSpecJSI-generated.cpp @@ -0,0 +1,26 @@ +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleCpp.js + */ + +#include "OSSLibraryExampleSpecJSI.h" + +namespace facebook::react { + +static jsi::Value __hostFunction_NativeSampleModuleCxxSpecJSI_getRandomNumber(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getRandomNumber( + rt + ); +} + +NativeSampleModuleCxxSpecJSI::NativeSampleModuleCxxSpecJSI(std::shared_ptr jsInvoker) + : TurboModule("NativeSampleModule", jsInvoker) { + methodMap_["getRandomNumber"] = MethodMetadata {0, __hostFunction_NativeSampleModuleCxxSpecJSI_getRandomNumber}; +} + + +} // namespace facebook::react diff --git a/packages/react-native-test-library/ios/OSSLibraryExampleSpecJSI.h b/packages/react-native-test-library/ios/OSSLibraryExampleSpecJSI.h new file mode 100644 index 00000000000000..7955b323295eec --- /dev/null +++ b/packages/react-native-test-library/ios/OSSLibraryExampleSpecJSI.h @@ -0,0 +1,63 @@ +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleH.js + */ + +#pragma once + +#include +#include + +namespace facebook::react { + + + class JSI_EXPORT NativeSampleModuleCxxSpecJSI : public TurboModule { +protected: + NativeSampleModuleCxxSpecJSI(std::shared_ptr jsInvoker); + +public: + virtual double getRandomNumber(jsi::Runtime &rt) = 0; + +}; + +template +class JSI_EXPORT NativeSampleModuleCxxSpec : public TurboModule { +public: + jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override { + return delegate_.get(rt, propName); + } + + static constexpr std::string_view kModuleName = "NativeSampleModule"; + +protected: + NativeSampleModuleCxxSpec(std::shared_ptr jsInvoker) + : TurboModule(std::string{NativeSampleModuleCxxSpec::kModuleName}, jsInvoker), + delegate_(reinterpret_cast(this), jsInvoker) {} + +private: + class Delegate : public NativeSampleModuleCxxSpecJSI { + public: + Delegate(T *instance, std::shared_ptr jsInvoker) : + NativeSampleModuleCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {} + + double getRandomNumber(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::getRandomNumber) == 1, + "Expected getRandomNumber(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::getRandomNumber, jsInvoker_, instance_); + } + + private: + T *instance_; + }; + + Delegate delegate_; +}; + +} // namespace facebook::react diff --git a/packages/react-native-test-library/ios/RCTNativeSampleModule.mm b/packages/react-native-test-library/ios/RCTNativeSampleModule.mm new file mode 100644 index 00000000000000..b5a059b7f6e61a --- /dev/null +++ b/packages/react-native-test-library/ios/RCTNativeSampleModule.mm @@ -0,0 +1,47 @@ +/* + * 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. + */ + +#ifdef RCT_NEW_ARCH_ENABLED +#import "OSSLibraryExampleSpec/OSSLibraryExampleSpec.h" +#else +#import +#endif + +#import +#include +#include + +#ifdef RCT_NEW_ARCH_ENABLED +@interface RCTNativeSampleModule : NSObject +#else +@interface RCTNativeSampleModule : NSObject +#endif + +@end + +@implementation RCTNativeSampleModule + +RCT_EXPORT_MODULE(); + +#ifdef RCT_NEW_ARCH_ENABLED +- (std::shared_ptr)getTurboModule: + (const facebook::react::ObjCTurboModule::InitParams &)params +{ + return std::make_shared(params); +} +#endif + +#ifdef RCT_NEW_ARCH_ENABLED +- (NSNumber *)getRandomNumber +#else +RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, getRandomNumber) +#endif +{ + return @(arc4random_uniform(99)); +} + +@end diff --git a/packages/react-native-test-library/ios/RCTSampleNativeComponentComponentView.mm b/packages/react-native-test-library/ios/RCTSampleNativeComponentComponentView.mm new file mode 100644 index 00000000000000..13dca042838eab --- /dev/null +++ b/packages/react-native-test-library/ios/RCTSampleNativeComponentComponentView.mm @@ -0,0 +1,139 @@ +/* + * 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 "OSSLibraryExampleSpec/ComponentDescriptors.h" +#import "OSSLibraryExampleSpec/EventEmitters.h" +#import "OSSLibraryExampleSpec/Props.h" +#import "OSSLibraryExampleSpec/RCTComponentViewHelpers.h" + +#import "RCTFabricComponentsPlugins.h" + +#import +#import +#import + +using namespace facebook::react; + +static UIColor *UIColorFromHexString(const std::string hexString) +{ + unsigned rgbValue = 0; + NSString *colorString = [NSString stringWithCString:hexString.c_str() encoding:[NSString defaultCStringEncoding]]; + NSScanner *scanner = [NSScanner scannerWithString:colorString]; + [scanner setScanLocation:1]; // bypass '#' character + [scanner scanHexInt:&rgbValue]; + return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16) / 255.0 + green:((rgbValue & 0xFF00) >> 8) / 255.0 + blue:(rgbValue & 0xFF) / 255.0 + alpha:1.0]; +} + +@interface RCTSampleNativeComponentComponentView : RCTViewComponentView + +@property (nonatomic, copy) RCTBubblingEventBlock onIntArrayChanged; + +@end + +@implementation RCTSampleNativeComponentComponentView { + UIView *_view; +} + ++ (ComponentDescriptorProvider)componentDescriptorProvider +{ + return concreteComponentDescriptorProvider(); +} + +// Load is not invoked if it is not defined, therefore, we must ask to update this. +// See the Apple documentation: https://developer.apple.com/documentation/objectivec/nsobject/1418815-load?language=objc +// "[...] but only if the newly loaded class or category implements a method that can respond." ++ (void)load +{ + [super load]; +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = std::make_shared(); + _props = defaultProps; + + _view = [[UIView alloc] init]; + _view.backgroundColor = [UIColor redColor]; + + self.contentView = _view; + } + + return self; +} + +- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)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 ? SampleNativeComponentEventEmitter::OnIntArrayChangedYesNos::Yep + : SampleNativeComponentEventEmitter::OnIntArrayChangedYesNos::Nope); + newStringVector.push_back(std::to_string(val)); + newLatLonVector.push_back({-1.0 * val, 2.0 * val}); + newIntVectorVector.push_back({val, val, val}); + } + SampleNativeComponentEventEmitter::OnIntArrayChanged value = { + newVector, + newBoolVector, + newFloatVector, + newDoubleVector, + newYesNoVector, + newStringVector, + newLatLonVector, + newIntVectorVector}; + std::static_pointer_cast(_eventEmitter)->onIntArrayChanged(value); + } + } + + [super updateProps:props oldProps:oldProps]; +} + +- (void)onChange:(UIView *)sender +{ + // No-op + // std::dynamic_pointer_cast(_eventEmitter) + // ->onChange(ViewEventEmitter::OnChange{.value = static_cast(sender.on)}); +} + +#pragma mark - Native Commands + +- (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args +{ + RCTSampleNativeComponentHandleCommand(self, commandName, args); +} + +- (void)changeBackgroundColor:(NSString *)color +{ + _view.backgroundColor = UIColorFromHexString(std::string(color.UTF8String)); +} + +@end + +Class SampleNativeComponentCls(void) +{ + return RCTSampleNativeComponentComponentView.class; +} diff --git a/packages/react-native-test-library/ios/RCTSampleNativeComponentViewManager.mm b/packages/react-native-test-library/ios/RCTSampleNativeComponentViewManager.mm new file mode 100644 index 00000000000000..ffe7c6c9e013bc --- /dev/null +++ b/packages/react-native-test-library/ios/RCTSampleNativeComponentViewManager.mm @@ -0,0 +1,70 @@ +/* + * 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 +#import +#import + +static UIColor *UIColorFromHexString(const std::string hexString) +{ + unsigned rgbValue = 0; + NSString *colorString = [NSString stringWithCString:hexString.c_str() encoding:[NSString defaultCStringEncoding]]; + NSScanner *scanner = [NSScanner scannerWithString:colorString]; + [scanner setScanLocation:1]; // bypass '#' character + [scanner scanHexInt:&rgbValue]; + return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16) / 255.0 + green:((rgbValue & 0xFF00) >> 8) / 255.0 + blue:(rgbValue & 0xFF) / 255.0 + alpha:1.0]; +} + +@interface RCTSampleNativeComponentViewManager : RCTViewManager +@end + +@implementation RCTSampleNativeComponentViewManager + +RCT_EXPORT_MODULE(SampleNativeComponent) + +RCT_REMAP_VIEW_PROPERTY(color, backgroundColor, UIColor) + +RCT_REMAP_VIEW_PROPERTY(opacity, alpha, CGFloat) + +RCT_EXPORT_VIEW_PROPERTY(onColorChanged, RCTBubblingEventBlock) + +RCT_CUSTOM_VIEW_PROPERTY(cornerRadius, CGFloat, UIView) +{ + 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) { + if (UIView *view = [RCTSampleNativeComponentViewManager getViewByTag:viewRegistry reactTag:reactTag]) { + view.backgroundColor = UIColorFromHexString(std::string(color.UTF8String)); + } + }]; +} + ++ (UIView *)getViewByTag:(NSDictionary *)viewRegistry reactTag:(nonnull NSNumber *)reactTag +{ + UIView *view = viewRegistry[reactTag]; + if (view == nil) { + RCTLogError(@"Cannot find view with tag #%@", reactTag); + } + return view; +} + +- (UIView *)view +{ + UIView *view = [UIView new]; + view.backgroundColor = UIColor.redColor; + return view; +} + +@end diff --git a/packages/react-native-test-library/package.json b/packages/react-native-test-library/package.json new file mode 100644 index 00000000000000..570f625463fc24 --- /dev/null +++ b/packages/react-native-test-library/package.json @@ -0,0 +1,49 @@ +{ + "name": "@react-native/oss-library-example", + "version": "0.0.1", + "private": true, + "description": "Package that includes native module exapmle, native component example, targets both the old and the new architecture. It should serve as an example of a real-world OSS library.", + "license": "MIT", + "homepage": "https://github.com/facebook/react-native.git", + "repository": { + "type": "git", + "url": "https://github.com/facebook/react-native.git", + "directory": "packages/react-native-test-library" + }, + "main": "./index.js", + "exports": { + "./": "./index.js", + "./package.json": "./package.json" + }, + "scripts": { + "build": "yarn clean && babel --out-dir lib src", + "clean": "rimraf lib", + "codegen": "npx react-native codegen", + "prepare": "yarn run codegen && yarn run build" + }, + "files": [ + "generated" + ], + "devDependencies": { + "@babel/core": "^7.20.0", + "@react-native/babel-preset": "0.75.0-main", + "react-native": "*" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + }, + "codegenConfig": { + "name": "OSSLibraryExampleSpec", + "type": "all", + "jsSrcsDir": "src", + "outputDir": { + "ios": "ios", + "android": "android/src/main" + }, + "includesGeneratedCode": true, + "android": { + "javaPackageName": "com.reactnative.osslibraryexample" + } + } +} diff --git a/packages/react-native-test-library/src/NativeSampleModule.js b/packages/react-native-test-library/src/NativeSampleModule.js new file mode 100644 index 00000000000000..de546b74e53d62 --- /dev/null +++ b/packages/react-native-test-library/src/NativeSampleModule.js @@ -0,0 +1,19 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport'; + +import {TurboModuleRegistry} from 'react-native'; + +export interface Spec extends TurboModule { + +getRandomNumber: () => number; +} + +export default (TurboModuleRegistry.get('NativeSampleModule'): ?Spec); diff --git a/packages/react-native-test-library/src/SampleNativeComponent.js b/packages/react-native-test-library/src/SampleNativeComponent.js new file mode 100644 index 00000000000000..b70a4947ee5bb3 --- /dev/null +++ b/packages/react-native-test-library/src/SampleNativeComponent.js @@ -0,0 +1,59 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes'; +import type {HostComponent} from 'react-native/Libraries/Renderer/shims/ReactNativeTypes'; +import type { + BubblingEventHandler, + Double, + Float, + Int32, +} from 'react-native/Libraries/Types/CodegenTypes'; + +import * as React from 'react'; +import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands'; +import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; + +type Event = $ReadOnly<{ + values: $ReadOnlyArray, + 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 NativeComponentType = HostComponent; + +interface NativeCommands { + +changeBackgroundColor: ( + viewRef: React.ElementRef, + color: string, + ) => void; +} + +export const Commands: NativeCommands = codegenNativeCommands({ + supportedCommands: ['changeBackgroundColor'], +}); + +export default (codegenNativeComponent( + 'SampleNativeComponent', +): NativeComponentType); diff --git a/packages/rn-tester/Podfile b/packages/rn-tester/Podfile index 38b8c251da3862..7e723ec52341e6 100644 --- a/packages/rn-tester/Podfile +++ b/packages/rn-tester/Podfile @@ -60,6 +60,7 @@ def pods(target_name, options = {}) pod 'ScreenshotManager', :path => "NativeModuleExample" pod 'MyNativeView', :path => "NativeComponentExample" pod 'NativeCxxModuleExample', :path => "NativeCxxModuleExample" + pod 'OSSLibraryExample', :path => '../react-native-test-library' end target 'RNTester' do diff --git a/packages/rn-tester/android/app/build.gradle.kts b/packages/rn-tester/android/app/build.gradle.kts index e2c69a64985e34..30b5ad58d5c7a8 100644 --- a/packages/rn-tester/android/app/build.gradle.kts +++ b/packages/rn-tester/android/app/build.gradle.kts @@ -152,6 +152,7 @@ dependencies { // Build React Native from source implementation(project(":packages:react-native:ReactAndroid")) implementation(project(":packages:react-native-popup-menu-android:android")) + implementation(project(":packages:react-native-test-library:android")) // Consume Hermes as built from source only for the Hermes variant. "hermesImplementation"(project(":packages:react-native:ReactAndroid:hermes-engine")) diff --git a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.kt b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.kt index 8d863a242ca2cf..fdda006ee5534a 100644 --- a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.kt +++ b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.kt @@ -32,6 +32,7 @@ import com.facebook.react.uiapp.component.MyNativeViewManager import com.facebook.react.uimanager.ReactShadowNode import com.facebook.react.uimanager.ViewManager import com.facebook.soloader.SoLoader +import com.reactnative.osslibraryexample.OSSLibraryExamplePackage class RNTesterApplication : Application(), ReactApplication { override val reactNativeHost: ReactNativeHost by lazy { @@ -46,6 +47,7 @@ class RNTesterApplication : Application(), ReactApplication { return listOf( MainReactPackage(), PopupMenuPackage(), + OSSLibraryExamplePackage(), object : TurboReactPackage() { override fun getModule( name: String, diff --git a/packages/rn-tester/js/examples/OSSLibraryExample/OSSLibraryExample.js b/packages/rn-tester/js/examples/OSSLibraryExample/OSSLibraryExample.js new file mode 100644 index 00000000000000..9ba8408a6a0cdc --- /dev/null +++ b/packages/rn-tester/js/examples/OSSLibraryExample/OSSLibraryExample.js @@ -0,0 +1,127 @@ +/** + * 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 {NativeComponentType} from '@react-native/oss-library-example'; + +import { + SampleNativeComponent, + SampleNativeComponentCommands, +} from '@react-native/oss-library-example'; +import {NativeSampleModule} from '@react-native/oss-library-example'; +import * as React from 'react'; +import {useRef, useState} from 'react'; +import {Button, Text, View} from 'react-native'; +import {StyleSheet} from 'react-native'; + +const colors = [ + '#0000FF', + '#FF0000', + '#00FF00', + '#003300', + '#330000', + '#000033', +]; + +// $FlowFixMe[value-as-type] +const styles: StyleSheet = StyleSheet.create({ + container: { + flex: 1, + }, + column: { + flex: 2, + justifyContent: 'center', + paddingLeft: 5, + paddingRight: 5, + }, +}); + +function SampleNativeComponentContainer(props: {}): React.Node { + const containerRef = useRef(null); + const ref = useRef | null>(null); + const [opacity, setOpacity] = useState(1.0); + const [arrayValues, setArrayValues] = useState([1, 2, 3]); + return ( + + { + 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); + }} + /> +