diff --git a/.gitignore b/.gitignore index 7e334430180887..626d954cfa3f18 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ project.xcworkspace /packages/react-native/ReactAndroid/hermes-engine/.cxx/ /packages/react-native/template/android/app/build/ /packages/react-native/template/android/build/ +/packages/react-native-popup-menu-android/android/build/ # Buck .buckd diff --git a/packages/react-native-popup-menu-android/android/build.gradle.kts b/packages/react-native-popup-menu-android/android/build.gradle.kts new file mode 100644 index 00000000000000..d861b977491ea5 --- /dev/null +++ b/packages/react-native-popup-menu-android/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.popupmenu" + + 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-popup-menu-android/android/gradle.properties b/packages/react-native-popup-menu-android/android/gradle.properties new file mode 100644 index 00000000000000..f436a7474fed62 --- /dev/null +++ b/packages/react-native-popup-menu-android/android/gradle.properties @@ -0,0 +1,3 @@ +# 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-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/ComponentDescriptors.h b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/ComponentDescriptors.h new file mode 100644 index 00000000000000..af069cd67fc885 --- /dev/null +++ b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/ComponentDescriptors.h @@ -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: GenerateComponentDescriptorH.js + */ + +#pragma once + +#include "ShadowNodes.h" +#include + +namespace facebook::react { + +using AndroidPopupMenuComponentDescriptor = ConcreteComponentDescriptor; + +} // namespace facebook::react diff --git a/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/EventEmitters.cpp b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/EventEmitters.cpp new file mode 100644 index 00000000000000..0c18d59e3a63db --- /dev/null +++ b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/EventEmitters.cpp @@ -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: GenerateEventEmitterCpp.js + */ + +#include "EventEmitters.h" + + +namespace facebook::react { + +void AndroidPopupMenuEventEmitter::onSelectionChange(OnSelectionChange $event) const { + dispatchEvent("selectionChange", [$event=std::move($event)](jsi::Runtime &runtime) { + auto $payload = jsi::Object(runtime); + $payload.setProperty(runtime, "item", $event.item); + return $payload; + }); +} + +} // namespace facebook::react diff --git a/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/EventEmitters.h b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/EventEmitters.h new file mode 100644 index 00000000000000..a0387907710fe0 --- /dev/null +++ b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/EventEmitters.h @@ -0,0 +1,25 @@ + +/** + * 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 AndroidPopupMenuEventEmitter : public ViewEventEmitter { + public: + using ViewEventEmitter::ViewEventEmitter; + + struct OnSelectionChange { + int item; + }; + void onSelectionChange(OnSelectionChange value) const; +}; +} // namespace facebook::react diff --git a/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/Props.cpp b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/Props.cpp new file mode 100644 index 00000000000000..ddcdcff88ebfef --- /dev/null +++ b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/Props.cpp @@ -0,0 +1,25 @@ + +/** + * 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 { + +AndroidPopupMenuProps::AndroidPopupMenuProps( + const PropsParserContext &context, + const AndroidPopupMenuProps &sourceProps, + const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), + + menuItems(convertRawProp(context, rawProps, "menuItems", sourceProps.menuItems, {})) + {} + +} // namespace facebook::react diff --git a/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/Props.h b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/Props.h new file mode 100644 index 00000000000000..191f0b15776bc5 --- /dev/null +++ b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/Props.h @@ -0,0 +1,28 @@ + +/** + * 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 AndroidPopupMenuProps final : public ViewProps { + public: + AndroidPopupMenuProps() = default; + AndroidPopupMenuProps(const PropsParserContext& context, const AndroidPopupMenuProps &sourceProps, const RawProps &rawProps); + +#pragma mark - Props + + std::vector menuItems{}; +}; + +} // namespace facebook::react diff --git a/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/ShadowNodes.cpp b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/ShadowNodes.cpp new file mode 100644 index 00000000000000..5fd96dbbadaacf --- /dev/null +++ b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/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 AndroidPopupMenuComponentName[] = "AndroidPopupMenu"; + +} // namespace facebook::react diff --git a/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/ShadowNodes.h b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/ShadowNodes.h new file mode 100644 index 00000000000000..0fd9852b1bca57 --- /dev/null +++ b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/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 AndroidPopupMenuComponentName[]; + +/* + * `ShadowNode` for component. + */ +using AndroidPopupMenuShadowNode = ConcreteViewShadowNode< + AndroidPopupMenuComponentName, + AndroidPopupMenuProps, + AndroidPopupMenuEventEmitter, + AndroidPopupMenuState>; + +} // namespace facebook::react diff --git a/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/States.cpp b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/States.cpp new file mode 100644 index 00000000000000..1dbb184cbddb62 --- /dev/null +++ b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/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-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/States.h b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/States.h new file mode 100644 index 00000000000000..62c048033b7021 --- /dev/null +++ b/packages/react-native-popup-menu-android/android/src/jni/react/renderer/components/ReactPopupMenuAndroidSpecs/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 AndroidPopupMenuState { +public: + AndroidPopupMenuState() = default; + +#ifdef ANDROID + AndroidPopupMenuState(AndroidPopupMenuState const &previousState, folly::dynamic data){}; + folly::dynamic getDynamic() const { + return {}; + }; + MapBuffer getMapBuffer() const { + return MapBufferBuilder::EMPTY(); + }; +#endif +}; + +} // namespace facebook::react diff --git a/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/PopupMenuPackage.kt b/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/PopupMenuPackage.kt new file mode 100644 index 00000000000000..0a351d28643ee0 --- /dev/null +++ b/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/PopupMenuPackage.kt @@ -0,0 +1,56 @@ +/* + * 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.facebook.react.popupmenu + +import com.facebook.react.BaseReactPackage +import com.facebook.react.ViewManagerOnDemandReactPackage +import com.facebook.react.bridge.ModuleSpec +import com.facebook.react.bridge.NativeModule +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.module.annotations.ReactModuleList +import com.facebook.react.module.model.ReactModuleInfoProvider +import com.facebook.react.uimanager.ViewManager + +@ReactModuleList(nativeModules = arrayOf()) +class PopupMenuPackage() : BaseReactPackage(), ViewManagerOnDemandReactPackage { + private var viewManagersMap: Map? = null + + override fun getModule(name: String, context: ReactApplicationContext): NativeModule? { + return null + } + + private fun getViewManagersMap(): Map { + val viewManagers = + viewManagersMap + ?: mapOf( + ReactPopupMenuManager.REACT_CLASS to + ModuleSpec.viewManagerSpec({ ReactPopupMenuManager() })) + viewManagersMap = viewManagers + return viewManagers + } + + protected override fun getViewManagers(context: ReactApplicationContext): List { + return ArrayList(getViewManagersMap().values) + } + + override fun getViewManagerNames(context: ReactApplicationContext): Collection { + return getViewManagersMap().keys + } + + override fun createViewManager( + reactContext: ReactApplicationContext, + viewManagerName: String + ): ViewManager<*, *>? { + val spec: ModuleSpec? = getViewManagersMap().get(viewManagerName) + return if (spec != null) (spec.getProvider().get() as ViewManager<*, *>) else null + } + + override fun getReactModuleInfoProvider(): ReactModuleInfoProvider { + return ReactModuleInfoProvider { emptyMap() } + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/popupmenu/PopupMenuSelectionEvent.kt b/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/PopupMenuSelectionEvent.kt similarity index 89% rename from packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/popupmenu/PopupMenuSelectionEvent.kt rename to packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/PopupMenuSelectionEvent.kt index f0195e6d29ff4d..289b70d566c870 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/popupmenu/PopupMenuSelectionEvent.kt +++ b/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/PopupMenuSelectionEvent.kt @@ -5,9 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -@file:Suppress("DEPRECATION") // We want to use RCTEventEmitter for interop purposes - -package com.facebook.react.views.popupmenu +package com.facebook.react.popupmenu import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.WritableMap diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/popupmenu/ReactPopupMenuContainer.kt b/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/ReactPopupMenuContainer.kt similarity index 97% rename from packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/popupmenu/ReactPopupMenuContainer.kt rename to packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/ReactPopupMenuContainer.kt index 57574290bacbe3..6be3bfc916d059 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/popupmenu/ReactPopupMenuContainer.kt +++ b/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/ReactPopupMenuContainer.kt @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.react.views.popupmenu +package com.facebook.react.popupmenu import android.content.Context import android.os.Build diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/popupmenu/ReactPopupMenuManager.kt b/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/ReactPopupMenuManager.kt similarity index 97% rename from packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/popupmenu/ReactPopupMenuManager.kt rename to packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/ReactPopupMenuManager.kt index 99dd6b72aa3c92..3758f154c8741e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/popupmenu/ReactPopupMenuManager.kt +++ b/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/ReactPopupMenuManager.kt @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.react.views.popupmenu +package com.facebook.react.popupmenu import com.facebook.react.bridge.ReadableArray import com.facebook.react.module.annotations.ReactModule diff --git a/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/viewmanagers/AndroidPopupMenuManagerDelegate.java b/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/viewmanagers/AndroidPopupMenuManagerDelegate.java new file mode 100644 index 00000000000000..736b778e5948f5 --- /dev/null +++ b/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/viewmanagers/AndroidPopupMenuManagerDelegate.java @@ -0,0 +1,41 @@ +/** +* 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 AndroidPopupMenuManagerDelegate & AndroidPopupMenuManagerInterface> extends BaseViewManagerDelegate { + public AndroidPopupMenuManagerDelegate(U viewManager) { + super(viewManager); + } + @Override + public void setProperty(T view, String propName, @Nullable Object value) { + switch (propName) { + case "menuItems": + mViewManager.setMenuItems(view, (ReadableArray) value); + break; + default: + super.setProperty(view, propName, value); + } + } + + @Override + public void receiveCommand(T view, String commandName, ReadableArray args) { + switch (commandName) { + case "show": + mViewManager.show(view); + break; + } + } +} diff --git a/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/viewmanagers/AndroidPopupMenuManagerInterface.java b/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/viewmanagers/AndroidPopupMenuManagerInterface.java new file mode 100644 index 00000000000000..83e94ab5e295a2 --- /dev/null +++ b/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/viewmanagers/AndroidPopupMenuManagerInterface.java @@ -0,0 +1,19 @@ +/** +* 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 AndroidPopupMenuManagerInterface { + void setMenuItems(T view, @Nullable ReadableArray value); + void show(T view); +} diff --git a/packages/react-native-popup-menu-android/index.d.ts b/packages/react-native-popup-menu-android/index.d.ts new file mode 100644 index 00000000000000..9caa4c385a77e4 --- /dev/null +++ b/packages/react-native-popup-menu-android/index.d.ts @@ -0,0 +1,11 @@ +/** + * 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 + */ + +export type {default} from './PopupMenuAndroid'; +export type {PopupMenuAndroidInstance} from './PopupMenuAndroid'; diff --git a/packages/react-native-popup-menu-android/index.js b/packages/react-native-popup-menu-android/index.js new file mode 100644 index 00000000000000..f433cc1331389f --- /dev/null +++ b/packages/react-native-popup-menu-android/index.js @@ -0,0 +1,12 @@ +/** + * 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} from './js/PopupMenuAndroid'; +export type {PopupMenuAndroidInstance} from './js/PopupMenuAndroid'; diff --git a/packages/react-native/Libraries/Components/PopupMenuAndroid/PopupMenuAndroid.android.js b/packages/react-native-popup-menu-android/js/PopupMenuAndroid.android.js similarity index 91% rename from packages/react-native/Libraries/Components/PopupMenuAndroid/PopupMenuAndroid.android.js rename to packages/react-native-popup-menu-android/js/PopupMenuAndroid.android.js index 035a1da5b150d6..b7ab6e0bf2b933 100644 --- a/packages/react-native/Libraries/Components/PopupMenuAndroid/PopupMenuAndroid.android.js +++ b/packages/react-native-popup-menu-android/js/PopupMenuAndroid.android.js @@ -8,9 +8,9 @@ * @flow strict-local */ -import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; -import type {SyntheticEvent} from '../../Types/CoreEventTypes'; import type {RefObject} from 'react'; +import type {HostComponent} from 'react-native'; +import type {SyntheticEvent} from 'react-native/Libraries/Types/CoreEventTypes'; import PopupMenuAndroidNativeComponent, { Commands, diff --git a/packages/react-native/Libraries/Components/PopupMenuAndroid/PopupMenuAndroid.d.ts b/packages/react-native-popup-menu-android/js/PopupMenuAndroid.d.ts similarity index 89% rename from packages/react-native/Libraries/Components/PopupMenuAndroid/PopupMenuAndroid.d.ts rename to packages/react-native-popup-menu-android/js/PopupMenuAndroid.d.ts index 435df11d487fe7..8eab4875f38347 100644 --- a/packages/react-native/Libraries/Components/PopupMenuAndroid/PopupMenuAndroid.d.ts +++ b/packages/react-native-popup-menu-android/js/PopupMenuAndroid.d.ts @@ -8,7 +8,7 @@ */ import type * as React from 'react'; -import {HostComponent} from '../../../types/public/ReactNativeTypes'; +import {HostComponent} from 'react-native'; type PopupMenuAndroidInstance = { show: () => void; diff --git a/packages/react-native/Libraries/Components/PopupMenuAndroid/PopupMenuAndroid.js b/packages/react-native-popup-menu-android/js/PopupMenuAndroid.js similarity index 50% rename from packages/react-native/Libraries/Components/PopupMenuAndroid/PopupMenuAndroid.js rename to packages/react-native-popup-menu-android/js/PopupMenuAndroid.js index 94677cd6b8d23d..1331d32bd29722 100644 --- a/packages/react-native/Libraries/Components/PopupMenuAndroid/PopupMenuAndroid.js +++ b/packages/react-native-popup-menu-android/js/PopupMenuAndroid.js @@ -12,8 +12,29 @@ import type {RefObject} from 'react'; import type {Node} from 'react'; import * as React from 'react'; +import {StyleSheet, View} from 'react-native'; -const UnimplementedView = require('../UnimplementedViews/UnimplementedView'); +/** + * Common implementation for a simple stubbed view. Simply applies the view's styles to the inner + * View component and renders its children. + */ +class UnimplementedView extends React.Component<{children: Node}> { + render(): React.Node { + return ( + {this.props.children} + ); + } +} + +const styles = StyleSheet.create({ + unimplementedView: __DEV__ + ? { + alignSelf: 'flex-start', + borderColor: 'red', + borderWidth: 1, + } + : {}, +}); export type PopupMenuAndroidInstance = { +show: () => void, @@ -27,7 +48,7 @@ type Props = { }; function PopupMenuAndroid(props: Props): Node { - return ; + return {props.children}; } export default PopupMenuAndroid; diff --git a/packages/react-native/src/private/specs/components/PopupMenuAndroidNativeComponent.js b/packages/react-native-popup-menu-android/js/PopupMenuAndroidNativeComponent.js similarity index 68% rename from packages/react-native/src/private/specs/components/PopupMenuAndroidNativeComponent.js rename to packages/react-native-popup-menu-android/js/PopupMenuAndroidNativeComponent.js index 81801f65f4d0dd..7558d75415bfb0 100644 --- a/packages/react-native/src/private/specs/components/PopupMenuAndroidNativeComponent.js +++ b/packages/react-native-popup-menu-android/js/PopupMenuAndroidNativeComponent.js @@ -8,16 +8,16 @@ * @format */ -import type {ViewProps} from '../../../../Libraries/Components/View/ViewPropTypes'; -import type {HostComponent} from '../../../../Libraries/Renderer/shims/ReactNativeTypes'; +import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes'; +import type {HostComponent} from 'react-native/Libraries/Renderer/shims/ReactNativeTypes'; import type { DirectEventHandler, Int32, -} from '../../../../Libraries/Types/CodegenTypes'; +} from 'react-native/Libraries/Types/CodegenTypes'; -import codegenNativeCommands from '../../../../Libraries/Utilities/codegenNativeCommands'; -import codegenNativeComponent from '../../../../Libraries/Utilities/codegenNativeComponent'; import * as React from 'react'; +import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands'; +import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; type PopupMenuSelectionEvent = $ReadOnly<{ item: Int32, diff --git a/packages/react-native-popup-menu-android/package.json b/packages/react-native-popup-menu-android/package.json new file mode 100644 index 00000000000000..9be32ece5c1cf1 --- /dev/null +++ b/packages/react-native-popup-menu-android/package.json @@ -0,0 +1,39 @@ +{ + "name": "@react-native/popup-menu-android", + "version": "0.74.0", + "description": "PopupMenu for the Android platform", + "react-native": "js/PopupMenuAndroid", + "source": "js/PopupMenuAndroid", + "files": [ + "js", + "android", + "!android/build", + "!**/__tests__", + "!**/__fixtures__", + "!**/__mocks__" + ], + "keywords": ["react-native", "android"], + "license": "MIT", + "devDependencies": { + "@react-native/codegen": "*" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + }, + "dependencies": { + "nullthrows": "^1.1.1" + }, + "codegenConfig": { + "name": "ReactPopupMenuAndroidSpecs", + "type": "components", + "jsSrcsDir": "js", + "outputDir": { + "android": "android" + }, + "includesGeneratedCode": true, + "android": { + "javaPackageName": "com.facebook.react.viewmanagers" + } + } +} diff --git a/packages/react-native/Libraries/Components/PopupMenuAndroid/PopupMenuAndroidNativeComponent.js b/packages/react-native/Libraries/Components/PopupMenuAndroid/PopupMenuAndroidNativeComponent.js deleted file mode 100644 index 05bbd5693155c5..00000000000000 --- a/packages/react-native/Libraries/Components/PopupMenuAndroid/PopupMenuAndroidNativeComponent.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * 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 strict-local - */ - -export * from '../../../src/private/specs/components/PopupMenuAndroidNativeComponent'; -import PopupMenuAndroidNativeComponent from '../../../src/private/specs/components/PopupMenuAndroidNativeComponent'; -export default PopupMenuAndroidNativeComponent; diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index de27ba219ed603..bf6a0a0b61f928 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -1773,41 +1773,6 @@ declare export default typeof NativeKeyboardObserver; " `; -exports[`public API should not change unintentionally Libraries/Components/PopupMenuAndroid/PopupMenuAndroid.android.js 1`] = ` -"export type PopupMenuAndroidInstance = { - +show: () => void, -}; -type Props = { - menuItems: $ReadOnlyArray, - onSelectionChange: (number) => void, - children: React.Node, - instanceRef: RefObject, -}; -declare export default function PopupMenuAndroid(Props): React.Node; -" -`; - -exports[`public API should not change unintentionally Libraries/Components/PopupMenuAndroid/PopupMenuAndroid.js 1`] = ` -"export type PopupMenuAndroidInstance = { - +show: () => void, -}; -type Props = { - menuItems: $ReadOnlyArray, - onSelectionChange: (number) => void, - children: Node, - instanceRef: RefObject, -}; -declare function PopupMenuAndroid(props: Props): Node; -declare export default typeof PopupMenuAndroid; -" -`; - -exports[`public API should not change unintentionally Libraries/Components/PopupMenuAndroid/PopupMenuAndroidNativeComponent.js 1`] = ` -"export * from \\"../../../src/private/specs/components/PopupMenuAndroidNativeComponent\\"; -declare export default typeof PopupMenuAndroidNativeComponent; -" -`; - exports[`public API should not change unintentionally Libraries/Components/Pressable/Pressable.js 1`] = ` "type ViewStyleProp = $ElementType, \\"style\\">; export type StateCallbackType = $ReadOnly<{| @@ -9026,7 +8991,6 @@ declare module.exports: { get ImageBackground(): ImageBackground, get InputAccessoryView(): InputAccessoryView, get KeyboardAvoidingView(): KeyboardAvoidingView, - get PopupMenuAndroid(): PopupMenuAndroid, get Modal(): Modal, get Pressable(): Pressable, get ProgressBarAndroid(): ProgressBarAndroid, diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 91f7ca364cafc7..c945b6b853fb87 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -5657,17 +5657,6 @@ public abstract interface class com/facebook/react/viewmanagers/AndroidHorizonta public abstract fun setRemoveClippedSubviews (Landroid/view/View;Z)V } -public class com/facebook/react/viewmanagers/AndroidPopupMenuManagerDelegate : com/facebook/react/uimanager/BaseViewManagerDelegate { - public fun (Lcom/facebook/react/uimanager/BaseViewManagerInterface;)V - public fun receiveCommand (Landroid/view/View;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V - public fun setProperty (Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V -} - -public abstract interface class com/facebook/react/viewmanagers/AndroidPopupMenuManagerInterface { - public abstract fun setMenuItems (Landroid/view/View;Lcom/facebook/react/bridge/ReadableArray;)V - public abstract fun show (Landroid/view/View;)V -} - public class com/facebook/react/viewmanagers/AndroidProgressBarManagerDelegate : com/facebook/react/uimanager/BaseViewManagerDelegate { public fun (Lcom/facebook/react/uimanager/BaseViewManagerInterface;)V public fun setProperty (Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V @@ -6137,47 +6126,6 @@ public abstract interface class com/facebook/react/views/modal/ReactModalHostVie public abstract fun onRequestClose (Landroid/content/DialogInterface;)V } -public final class com/facebook/react/views/popupmenu/PopupMenuSelectionEvent : com/facebook/react/uimanager/events/Event { - public static final field Companion Lcom/facebook/react/views/popupmenu/PopupMenuSelectionEvent$Companion; - public static final field EVENT_NAME Ljava/lang/String; - public fun (III)V - public fun dispatch (Lcom/facebook/react/uimanager/events/RCTEventEmitter;)V - public fun getEventName ()Ljava/lang/String; -} - -public final class com/facebook/react/views/popupmenu/PopupMenuSelectionEvent$Companion { -} - -public final class com/facebook/react/views/popupmenu/ReactPopupMenuContainer : android/widget/FrameLayout { - public fun (Landroid/content/Context;)V - public final fun setMenuItems (Lcom/facebook/react/bridge/ReadableArray;)V - public final fun showPopupMenu ()V -} - -public final class com/facebook/react/views/popupmenu/ReactPopupMenuManager : com/facebook/react/uimanager/ViewGroupManager, com/facebook/react/viewmanagers/AndroidPopupMenuManagerInterface { - public static final field Companion Lcom/facebook/react/views/popupmenu/ReactPopupMenuManager$Companion; - public static final field REACT_CLASS Ljava/lang/String; - public fun ()V - public synthetic fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View; - public fun getName ()Ljava/lang/String; - public synthetic fun receiveCommand (Landroid/view/View;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V - public fun receiveCommand (Lcom/facebook/react/views/popupmenu/ReactPopupMenuContainer;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V - public synthetic fun setMenuItems (Landroid/view/View;Lcom/facebook/react/bridge/ReadableArray;)V - public fun setMenuItems (Lcom/facebook/react/views/popupmenu/ReactPopupMenuContainer;Lcom/facebook/react/bridge/ReadableArray;)V - public synthetic fun show (Landroid/view/View;)V - public fun show (Lcom/facebook/react/views/popupmenu/ReactPopupMenuContainer;)V -} - -public class com/facebook/react/views/popupmenu/ReactPopupMenuManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/popupmenu/ReactPopupMenuManager;Lcom/facebook/react/views/popupmenu/ReactPopupMenuContainer;Ljava/lang/String;Ljava/lang/Object;)V -} - -public final class com/facebook/react/views/popupmenu/ReactPopupMenuManager$Companion { -} - public class com/facebook/react/views/progressbar/ProgressBarShadowNode : com/facebook/react/uimanager/LayoutShadowNode, com/facebook/yoga/YogaMeasureFunction { public fun ()V public fun getStyle ()Ljava/lang/String; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java index b06dcc7d745983..dac68508acaa0f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java @@ -47,7 +47,6 @@ import com.facebook.react.views.drawer.ReactDrawerLayoutManager; import com.facebook.react.views.image.ReactImageManager; import com.facebook.react.views.modal.ReactModalHostManager; -import com.facebook.react.views.popupmenu.ReactPopupMenuManager; import com.facebook.react.views.progressbar.ReactProgressBarViewManager; import com.facebook.react.views.scroll.ReactHorizontalScrollContainerViewManager; import com.facebook.react.views.scroll.ReactHorizontalScrollViewManager; @@ -171,7 +170,6 @@ public List createViewManagers(ReactApplicationContext reactContext viewManagers.add(new ReactScrollViewManager()); viewManagers.add(new ReactSwitchManager()); viewManagers.add(new SwipeRefreshLayoutManager()); - viewManagers.add(new ReactPopupMenuManager()); // Native equivalents viewManagers.add(new FrescoBasedReactTextInlineImageViewManager()); @@ -213,7 +211,6 @@ public Map getViewManagersMap() { appendMap(viewManagers, ReactSwitchManager.REACT_CLASS, ReactSwitchManager::new); appendMap( viewManagers, SwipeRefreshLayoutManager.REACT_CLASS, SwipeRefreshLayoutManager::new); - appendMap(viewManagers, ReactPopupMenuManager.REACT_CLASS, ReactPopupMenuManager::new); appendMap( viewManagers, FrescoBasedReactTextInlineImageViewManager.REACT_CLASS, diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/CoreComponentsRegistry.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/CoreComponentsRegistry.cpp index fdb2f051621fd2..fd8e579865f73b 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/CoreComponentsRegistry.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/CoreComponentsRegistry.cpp @@ -67,8 +67,6 @@ CoreComponentsRegistry::sharedProviderRegistry() { AndroidDrawerLayoutComponentDescriptor>()); providerRegistry->add(concreteComponentDescriptorProvider< DebuggingOverlayComponentDescriptor>()); - providerRegistry->add(concreteComponentDescriptorProvider< - AndroidPopupMenuComponentDescriptor>()); return providerRegistry; }(); diff --git a/packages/react-native/index.js b/packages/react-native/index.js index 2dfeafbb64efd7..f087b702545fcd 100644 --- a/packages/react-native/index.js +++ b/packages/react-native/index.js @@ -27,7 +27,6 @@ import typeof Clipboard from './Libraries/Components/Clipboard/Clipboard'; import typeof DrawerLayoutAndroid from './Libraries/Components/DrawerAndroid/DrawerLayoutAndroid'; import typeof Keyboard from './Libraries/Components/Keyboard/Keyboard'; import typeof KeyboardAvoidingView from './Libraries/Components/Keyboard/KeyboardAvoidingView'; -import typeof PopupMenuAndroid from './Libraries/Components/PopupMenuAndroid/PopupMenuAndroid'; import typeof Pressable from './Libraries/Components/Pressable/Pressable'; import typeof ProgressBarAndroid from './Libraries/Components/ProgressBarAndroid/ProgressBarAndroid'; import typeof RefreshControl from './Libraries/Components/RefreshControl/RefreshControl'; @@ -135,10 +134,6 @@ module.exports = { return require('./Libraries/Components/Keyboard/KeyboardAvoidingView') .default; }, - get PopupMenuAndroid(): PopupMenuAndroid { - return require('./Libraries/Components/PopupMenuAndroid/PopupMenuAndroid') - .default; - }, get Modal(): Modal { return require('./Libraries/Modal/Modal'); }, diff --git a/packages/rn-tester/android/app/build.gradle.kts b/packages/rn-tester/android/app/build.gradle.kts index 5ad05a044325fd..e2c69a64985e34 100644 --- a/packages/rn-tester/android/app/build.gradle.kts +++ b/packages/rn-tester/android/app/build.gradle.kts @@ -151,6 +151,7 @@ android { dependencies { // Build React Native from source implementation(project(":packages:react-native:ReactAndroid")) + implementation(project(":packages:react-native-popup-menu-android: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 33b2373fd46c27..01756aea982108 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 @@ -25,6 +25,7 @@ import com.facebook.react.defaults.DefaultReactHost import com.facebook.react.defaults.DefaultReactNativeHost import com.facebook.react.module.model.ReactModuleInfo import com.facebook.react.module.model.ReactModuleInfoProvider +import com.facebook.react.popupmenu.PopupMenuPackage import com.facebook.react.shell.MainReactPackage import com.facebook.react.uiapp.component.MyLegacyViewManager import com.facebook.react.uiapp.component.MyNativeViewManager @@ -44,6 +45,7 @@ class RNTesterApplication : Application(), ReactApplication { public override fun getPackages(): List { return listOf( MainReactPackage(), + PopupMenuPackage(), object : TurboReactPackage() { override fun getModule( name: String, diff --git a/packages/rn-tester/js/examples/PopupMenuAndroid/PopupMenuAndroidExample.js b/packages/rn-tester/js/examples/PopupMenuAndroid/PopupMenuAndroidExample.js index 2b35119e662ed8..3934c0f4f08307 100644 --- a/packages/rn-tester/js/examples/PopupMenuAndroid/PopupMenuAndroidExample.js +++ b/packages/rn-tester/js/examples/PopupMenuAndroid/PopupMenuAndroidExample.js @@ -10,11 +10,12 @@ 'use strict'; +import type {PopupMenuAndroidInstance} from '@react-native/popup-menu-android'; import type {Node} from 'react'; -import type {PopupMenuAndroidInstance} from 'react-native/Libraries/Components/PopupMenuAndroid/PopupMenuAndroid'; +import PopupMenuAndroid from '@react-native/popup-menu-android'; import * as React from 'react'; -import {Button, PopupMenuAndroid, StyleSheet, Text, View} from 'react-native'; +import {Button, StyleSheet, Text, View} from 'react-native'; type Fruit = 'Apple' | 'Pear' | 'Banana' | 'Orange' | 'Kiwi'; diff --git a/packages/rn-tester/metro.config.js b/packages/rn-tester/metro.config.js index 3c41387cc19b65..87b72ad0f6c214 100644 --- a/packages/rn-tester/metro.config.js +++ b/packages/rn-tester/metro.config.js @@ -30,6 +30,7 @@ const config = { path.resolve(__dirname, '../polyfills'), path.resolve(__dirname, '../react-native'), path.resolve(__dirname, '../virtualized-lists'), + path.resolve(__dirname, '../react-native-popup-menu-android'), ], resolver: { blockList: [/..\/react-native\/sdks\/hermes/], diff --git a/packages/rn-tester/package.json b/packages/rn-tester/package.json index d63abf26aab14e..87ed68d334c9b8 100644 --- a/packages/rn-tester/package.json +++ b/packages/rn-tester/package.json @@ -25,7 +25,8 @@ "dependencies": { "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", - "nullthrows": "^1.1.1" + "nullthrows": "^1.1.1", + "@react-native/popup-menu-android": "^0.74.0" }, "peerDependencies": { "react": "18.2.0", diff --git a/settings.gradle.kts b/settings.gradle.kts index 21064d004c9efe..0919ad1f7a74bf 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,6 +17,7 @@ include( ":packages:react-native:ReactAndroid", ":packages:react-native:ReactAndroid:hermes-engine", ":packages:react-native:ReactAndroid:external-artifacts", + ":packages:react-native-popup-menu-android:android", ":packages:rn-tester:android:app") includeBuild("packages/react-native-gradle-plugin/")