diff --git a/packages/react-native-codegen/e2e/__test_fixtures__/components/MixedPropNativeComponent.js b/packages/react-native-codegen/e2e/__test_fixtures__/components/MixedPropNativeComponent.js new file mode 100644 index 00000000000000..41169339f738c3 --- /dev/null +++ b/packages/react-native-codegen/e2e/__test_fixtures__/components/MixedPropNativeComponent.js @@ -0,0 +1,25 @@ +/** + * 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 + */ + +import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes'; +import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; +import type {HostComponent} from 'react-native/Libraries/Renderer/shims/ReactNativeTypes'; +import type {UnsafeMixed} from 'react-native/Libraries/Types/CodegenTypes'; + +type NativeProps = $ReadOnly<{| + ...ViewProps, + + // Props + mixedProp?: UnsafeMixed, +|}>; + +export default (codegenNativeComponent( + 'MixedPropNativeComponentView', +): HostComponent); diff --git a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateComponentDescriptorH-test.js.snap b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateComponentDescriptorH-test.js.snap index ea31662a596cfd..74f0e533357b01 100644 --- a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateComponentDescriptorH-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateComponentDescriptorH-test.js.snap @@ -330,6 +330,34 @@ namespace react { +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateComponentDescriptorH can generate for 'MixedPropNativeComponent.js' 1`] = ` +Object { + "ComponentDescriptors.h": " +/** + * 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 +#include + +namespace facebook { +namespace react { + +using MixedPropNativeComponentViewComponentDescriptor = ConcreteComponentDescriptor; + } // namespace react } // namespace facebook ", diff --git a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateComponentHObjCpp-test.js.snap b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateComponentHObjCpp-test.js.snap index af5f3ee0fb4d82..043dd5027e0ee7 100644 --- a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateComponentHObjCpp-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateComponentHObjCpp-test.js.snap @@ -300,6 +300,31 @@ NS_ASSUME_NONNULL_END", } `; +exports[`GenerateComponentHObjCpp can generate for 'MixedPropNativeComponent.js' 1`] = ` +Object { + "RCTComponentViewHelpers.h": "/** +* 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 RCTMixedPropNativeComponentViewViewProtocol + +@end + +NS_ASSUME_NONNULL_END", +} +`; + exports[`GenerateComponentHObjCpp can generate for 'MultiNativePropNativeComponent.js' 1`] = ` Object { "RCTComponentViewHelpers.h": "/** diff --git a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterCpp-test.js.snap b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterCpp-test.js.snap index c7a0910f721e81..398b3cf4fece32 100644 --- a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterCpp-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterCpp-test.js.snap @@ -362,6 +362,31 @@ void InterfaceOnlyNativeComponentViewEventEmitter::onChange(OnChange event) cons }); } +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateEventEmitterCpp can generate for 'MixedPropNativeComponent.js' 1`] = ` +Object { + "EventEmitters.cpp": " +/** + * 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 + +namespace facebook { +namespace react { + + + } // namespace react } // namespace facebook ", diff --git a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterH-test.js.snap b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterH-test.js.snap index 406ead6ef65c44..ee30ee4cbd70e2 100644 --- a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterH-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterH-test.js.snap @@ -461,6 +461,40 @@ class JSI_EXPORT InterfaceOnlyNativeComponentViewEventEmitter : public ViewEvent }; void onChange(OnChange value) const; +}; + +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateEventEmitterH can generate for 'MixedPropNativeComponent.js' 1`] = ` +Object { + "EventEmitters.h": " +/** + * 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 +#include + +namespace facebook { +namespace react { + +class JSI_EXPORT MixedPropNativeComponentViewEventEmitter : public ViewEventEmitter { + public: + using ViewEventEmitter::ViewEventEmitter; + + + + }; } // namespace react diff --git a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap index 1b907467748503..08c596c6cc90c6 100644 --- a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap @@ -421,6 +421,39 @@ InterfaceOnlyNativeComponentViewProps::InterfaceOnlyNativeComponentViewProps( } `; +exports[`GeneratePropsCpp can generate for 'MixedPropNativeComponent.js' 1`] = ` +Object { + "Props.cpp": " +/** + * 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 +#include +#include + +namespace facebook { +namespace react { + +MixedPropNativeComponentViewProps::MixedPropNativeComponentViewProps( + const PropsParserContext &context, + const MixedPropNativeComponentViewProps &sourceProps, + const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), + + mixedProp(convertRawProp(context, rawProps, \\"mixedProp\\", sourceProps.mixedProp, {})) + {} + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GeneratePropsCpp can generate for 'MultiNativePropNativeComponent.js' 1`] = ` Object { "Props.cpp": " diff --git a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap index 4666f4b9a34a5a..ebc4cd23016df7 100644 --- a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap @@ -625,6 +625,42 @@ class JSI_EXPORT InterfaceOnlyNativeComponentViewProps final : public ViewProps } `; +exports[`GeneratePropsH can generate for 'MixedPropNativeComponent.js' 1`] = ` +Object { + "Props.h": " +/** + * 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 { +namespace react { + +class JSI_EXPORT MixedPropNativeComponentViewProps final : public ViewProps { + public: + MixedPropNativeComponentViewProps() = default; + MixedPropNativeComponentViewProps(const PropsParserContext& context, const MixedPropNativeComponentViewProps &sourceProps, const RawProps &rawProps); + +#pragma mark - Props + + folly::dynamic mixedProp{}; +}; + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GeneratePropsH can generate for 'MultiNativePropNativeComponent.js' 1`] = ` Object { "Props.h": " diff --git a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsJavaDelegate-test.js.snap b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsJavaDelegate-test.js.snap index 23434676375b57..ebc5a9b14945e3 100644 --- a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsJavaDelegate-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsJavaDelegate-test.js.snap @@ -505,6 +505,44 @@ public class InterfaceOnlyNativeComponentViewManagerDelegate & MixedPropNativeComponentViewManagerInterface> extends BaseViewManagerDelegate { + public MixedPropNativeComponentViewManagerDelegate(U viewManager) { + super(viewManager); + } + @Override + public void setProperty(T view, String propName, @Nullable Object value) { + switch (propName) { + case \\"mixedProp\\": + mViewManager.setMixedProp(view, new DynamicFromObject(value)); + break; + default: + super.setProperty(view, propName, value); + } + } +} +", +} +`; + exports[`GeneratePropsJavaDelegate can generate for 'MultiNativePropNativeComponent.js' 1`] = ` Object { "java/com/facebook/react/viewmanagers/MultiNativePropNativeComponentViewManagerDelegate.java": "/** diff --git a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsJavaInterface-test.js.snap b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsJavaInterface-test.js.snap index 145e6d63229f23..1c3b62895ff6fa 100644 --- a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsJavaInterface-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsJavaInterface-test.js.snap @@ -296,6 +296,29 @@ public interface InterfaceOnlyNativeComponentViewManagerInterface { + void setMixedProp(T view, Dynamic value); +} +", +} +`; + exports[`GeneratePropsJavaInterface can generate for 'MultiNativePropNativeComponent.js' 1`] = ` Object { "java/com/facebook/react/viewmanagers/MultiNativePropNativeComponentViewManagerInterface.java": "/** diff --git a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateShadowNodeCpp-test.js.snap b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateShadowNodeCpp-test.js.snap index 3aa7c5a35b717c..224a02cc2ca754 100644 --- a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateShadowNodeCpp-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateShadowNodeCpp-test.js.snap @@ -294,6 +294,31 @@ namespace react { +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateShadowNodeCpp can generate for 'MixedPropNativeComponent.js' 1`] = ` +Object { + "ShadowNodes.cpp": " +/** + * 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 + +namespace facebook { +namespace react { + +extern const char MixedPropNativeComponentViewComponentName[] = \\"MixedPropNativeComponentView\\"; + } // namespace react } // namespace facebook ", diff --git a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateShadowNodeH-test.js.snap b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateShadowNodeH-test.js.snap index 53ba86ce5fc30c..d4d33cc34ad983 100644 --- a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateShadowNodeH-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateShadowNodeH-test.js.snap @@ -465,6 +465,46 @@ namespace react { +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateShadowNodeH can generate for 'MixedPropNativeComponent.js' 1`] = ` +Object { + "ShadowNodes.h": " +/** + * 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 +#include +#include +#include +#include + +namespace facebook { +namespace react { + +JSI_EXPORT extern const char MixedPropNativeComponentViewComponentName[]; + +/* + * \`ShadowNode\` for component. + */ +using MixedPropNativeComponentViewShadowNode = ConcreteViewShadowNode< + MixedPropNativeComponentViewComponentName, + MixedPropNativeComponentViewProps, + MixedPropNativeComponentViewEventEmitter, + MixedPropNativeComponentViewState>; + } // namespace react } // namespace facebook ", diff --git a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateViewConfigJs-test.js.snap b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateViewConfigJs-test.js.snap index 5630f8db49b7c7..fcfb25d973f431 100644 --- a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateViewConfigJs-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateViewConfigJs-test.js.snap @@ -509,6 +509,40 @@ export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL } `; +exports[`GenerateViewConfigJs can generate for 'MixedPropNativeComponent.js' 1`] = ` +Map { + "RNCodegenModuleFixturesNativeViewConfig.js" => " +/** + * 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. + * + * @flow + * + * @generated by codegen project: GenerateViewConfigJs.js + */ + +'use strict'; + +const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry'); + +let nativeComponentName = 'MixedPropNativeComponentView'; + + +export const __INTERNAL_VIEW_CONFIG = { + uiViewClassName: 'MixedPropNativeComponentView', + + validAttributes: { + mixedProp: true, + }, +}; + +export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL_VIEW_CONFIG); +", +} +`; + exports[`GenerateViewConfigJs can generate for 'MultiNativePropNativeComponent.js' 1`] = ` Map { "RNCodegenModuleFixturesNativeViewConfig.js" => " diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 17497531ed0803..6265482f91dbf8 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -58,6 +58,10 @@ export type ObjectTypeAnnotation<+T> = $ReadOnly<{ baseTypes?: $ReadOnlyArray, }>; +export type MixedTypeAnnotation = $ReadOnly<{ + type: 'MixedTypeAnnotation', +}>; + type FunctionTypeAnnotation<+P, +R> = $ReadOnly<{ type: 'FunctionTypeAnnotation', params: $ReadOnlyArray>, @@ -177,7 +181,8 @@ export type PropTypeAnnotation = type: 'ArrayTypeAnnotation', elementType: ObjectTypeAnnotation, }>, - }>; + }> + | MixedTypeAnnotation; export type ReservedPropTypeAnnotation = $ReadOnly<{ type: 'ReservedPropTypeAnnotation', diff --git a/packages/react-native-codegen/src/generators/components/ComponentsGeneratorUtils.js b/packages/react-native-codegen/src/generators/components/ComponentsGeneratorUtils.js index 046b9ed27919b4..c43768a1593439 100644 --- a/packages/react-native-codegen/src/generators/components/ComponentsGeneratorUtils.js +++ b/packages/react-native-codegen/src/generators/components/ComponentsGeneratorUtils.js @@ -122,6 +122,8 @@ function getNativeTypeFromAnnotation( return getEnumName(componentName, prop.name); case 'Int32EnumTypeAnnotation': return getEnumName(componentName, prop.name); + case 'MixedTypeAnnotation': + return 'folly::dynamic'; default: (typeAnnotation: empty); throw new Error( diff --git a/packages/react-native-codegen/src/generators/components/CppHelpers.js b/packages/react-native-codegen/src/generators/components/CppHelpers.js index cb3090df08cdfa..c7fbff186de863 100644 --- a/packages/react-native-codegen/src/generators/components/CppHelpers.js +++ b/packages/react-native-codegen/src/generators/components/CppHelpers.js @@ -200,6 +200,8 @@ function convertDefaultTypeToString( prop.name, typeAnnotation.default, )}`; + case 'MixedTypeAnnotation': + return ''; default: (typeAnnotation: empty); throw new Error(`Unsupported type annotation: ${typeAnnotation.type}`); diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsH.js b/packages/react-native-codegen/src/generators/components/GeneratePropsH.js index 15a7fcc425a174..684153b23b5ea5 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsH.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsH.js @@ -676,6 +676,8 @@ function generateStruct( } generateStruct(structs, componentName, nameParts.concat([name]), props); return; + case 'MixedTypeAnnotation': + return; default: (property.typeAnnotation.type: empty); throw new Error( diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js index d08dc617423ddb..68875b3b6caa6c 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js @@ -144,6 +144,8 @@ function getJavaValueForProp( return '(String) value'; case 'Int32EnumTypeAnnotation': return `value == null ? ${typeAnnotation.default} : ((Double) value).intValue()`; + case 'MixedTypeAnnotation': + return 'new DynamicFromObject(value)'; default: (typeAnnotation: empty); throw new Error('Received invalid typeAnnotation'); diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js index bc92d41b8ef8a8..a71f9b696ede6d 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js @@ -127,6 +127,8 @@ function getJavaValueForProp( case 'Int32EnumTypeAnnotation': addNullable(imports); return '@Nullable Integer value'; + case 'MixedTypeAnnotation': + return 'Dynamic value'; default: (typeAnnotation: empty); throw new Error('Received invalid typeAnnotation'); diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaPojo/PojoCollector.js b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaPojo/PojoCollector.js index eb7b1091dc7784..81829b99da8467 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaPojo/PojoCollector.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaPojo/PojoCollector.js @@ -20,6 +20,7 @@ import type { FloatTypeAnnotation, Int32TypeAnnotation, PropTypeAnnotation, + MixedTypeAnnotation, } from '../../../CodegenSchema'; const {capitalize} = require('../../Utils'); @@ -89,7 +90,8 @@ export type PojoTypeAnnotation = type: 'ArrayTypeAnnotation', elementType: PojoTypeAliasAnnotation, }>, - }>; + }> + | MixedTypeAnnotation; class PojoCollector { _pojos: Map = new Map(); diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaPojo/serializePojo.js b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaPojo/serializePojo.js index 99d009c8e2b72a..f9f7234931fee0 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaPojo/serializePojo.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaPojo/serializePojo.js @@ -24,6 +24,7 @@ function toJavaType( addImport('com.facebook.react.bridge.ReadableMap'); const importArrayList = () => addImport('java.util.ArrayList'); const importYogaValue = () => addImport('com.facebook.yoga.YogaValue'); + const importDynamic = () => addImport('com.facebook.react.bridge.Dynamic'); switch (typeAnnotation.type) { /** * Primitives @@ -222,6 +223,11 @@ function toJavaType( return `ArrayList<${elementTypeString}>`; } + case 'MixedTypeAnnotation': { + importDynamic(); + return 'Dynamic'; + } + default: { (typeAnnotation.type: empty); throw new Error( diff --git a/packages/react-native-codegen/src/generators/components/GenerateViewConfigJs.js b/packages/react-native-codegen/src/generators/components/GenerateViewConfigJs.js index 9307eb9398a88b..c8d96823129b78 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateViewConfigJs.js +++ b/packages/react-native-codegen/src/generators/components/GenerateViewConfigJs.js @@ -60,6 +60,7 @@ function getReactDiffProcessValue(typeAnnotation: PropTypeAnnotation) { case 'ObjectTypeAnnotation': case 'StringEnumTypeAnnotation': case 'Int32EnumTypeAnnotation': + case 'MixedTypeAnnotation': return j.literal(true); case 'ReservedPropTypeAnnotation': switch (typeAnnotation.name) { diff --git a/packages/react-native-codegen/src/generators/components/JavaHelpers.js b/packages/react-native-codegen/src/generators/components/JavaHelpers.js index 2d7b262cf032ae..48556d47db6636 100644 --- a/packages/react-native-codegen/src/generators/components/JavaHelpers.js +++ b/packages/react-native-codegen/src/generators/components/JavaHelpers.js @@ -117,6 +117,14 @@ function getImports( if (typeAnnotation.type === 'ObjectTypeAnnotation') { imports.add('import com.facebook.react.bridge.ReadableMap;'); } + + if (typeAnnotation.type === 'MixedTypeAnnotation') { + if (type === 'delegate') { + imports.add('import com.facebook.react.bridge.DynamicFromObject;'); + } else { + imports.add('import com.facebook.react.bridge.Dynamic;'); + } + } }); return imports; diff --git a/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js index a8277a7a67b673..57997808f52192 100644 --- a/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js @@ -1123,6 +1123,35 @@ const INT32_ENUM_PROP: SchemaType = { }, }; +const MIXED_PROP: SchemaType = { + modules: { + CustomView: { + type: 'Component', + components: { + MixedPropNativeComponent: { + extendsProps: [ + { + type: 'ReactNativeBuiltInType', + knownTypeName: 'ReactNativeCoreViewProps', + }, + ], + events: [], + props: [ + { + name: 'mixedProp', + optional: false, + typeAnnotation: { + type: 'MixedTypeAnnotation', + }, + }, + ], + commands: [], + }, + }, + }, + }, +}; + const EVENT_PROPS: SchemaType = { modules: { Switch: { @@ -1701,6 +1730,7 @@ module.exports = { MULTI_NATIVE_PROP, STRING_ENUM_PROP, INT32_ENUM_PROP, + MIXED_PROP, EVENT_PROPS, EVENTS_WITH_PAPER_NAME, EVENT_NESTED_OBJECT_PROPS, diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentDescriptorH-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentDescriptorH-test.js.snap index 21f4224e995e75..72653d4c56f282 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentDescriptorH-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentDescriptorH-test.js.snap @@ -555,6 +555,34 @@ namespace react { +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateComponentDescriptorH can generate fixture MIXED_PROP 1`] = ` +Map { + "ComponentDescriptors.h" => " +/** + * 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 +#include + +namespace facebook { +namespace react { + +using MixedPropNativeComponentComponentDescriptor = ConcreteComponentDescriptor; + } // namespace react } // namespace facebook ", diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentHObjCpp-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentHObjCpp-test.js.snap index 13a2561d102446..b232a9446ff12f 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentHObjCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentHObjCpp-test.js.snap @@ -634,6 +634,31 @@ NS_ASSUME_NONNULL_END", } `; +exports[`GenerateComponentHObjCpp can generate fixture MIXED_PROP 1`] = ` +Map { + "RCTComponentViewHelpers.h" => "/** +* 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 RCTMixedPropNativeComponentViewProtocol + +@end + +NS_ASSUME_NONNULL_END", +} +`; + exports[`GenerateComponentHObjCpp can generate fixture MULTI_NATIVE_PROP 1`] = ` Map { "RCTComponentViewHelpers.h" => "/** diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap index 54d8ff0696dc66..e2a91512639f4e 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap @@ -558,6 +558,31 @@ void InterfaceOnlyComponentEventEmitter::onChange(OnChange event) const { }); } +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateEventEmitterCpp can generate fixture MIXED_PROP 1`] = ` +Map { + "EventEmitters.cpp" => " +/** + * 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 + +namespace facebook { +namespace react { + + + } // namespace react } // namespace facebook ", diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap index 56580a3aa77b7c..62a430022e750a 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap @@ -733,6 +733,40 @@ class JSI_EXPORT InterfaceOnlyComponentEventEmitter : public ViewEventEmitter { }; void onChange(OnChange value) const; +}; + +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateEventEmitterH can generate fixture MIXED_PROP 1`] = ` +Map { + "EventEmitters.h" => " +/** + * 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 +#include + +namespace facebook { +namespace react { + +class JSI_EXPORT MixedPropNativeComponentEventEmitter : public ViewEventEmitter { + public: + using ViewEventEmitter::ViewEventEmitter; + + + + }; } // namespace react diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap index e50d587ce6109a..0853ba4c34c038 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap @@ -694,6 +694,39 @@ InterfaceOnlyComponentProps::InterfaceOnlyComponentProps( } `; +exports[`GeneratePropsCpp can generate fixture MIXED_PROP 1`] = ` +Map { + "Props.cpp" => " +/** + * 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 +#include +#include + +namespace facebook { +namespace react { + +MixedPropNativeComponentProps::MixedPropNativeComponentProps( + const PropsParserContext &context, + const MixedPropNativeComponentProps &sourceProps, + const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), + + mixedProp(convertRawProp(context, rawProps, \\"mixedProp\\", sourceProps.mixedProp, {})) + {} + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GeneratePropsCpp can generate fixture MULTI_NATIVE_PROP 1`] = ` Map { "Props.cpp" => " diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap index 2233888c128b24..7260cdda760c1b 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap @@ -999,6 +999,42 @@ class JSI_EXPORT InterfaceOnlyComponentProps final : public ViewProps { } `; +exports[`GeneratePropsH can generate fixture MIXED_PROP 1`] = ` +Map { + "Props.h" => " +/** + * 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 { +namespace react { + +class JSI_EXPORT MixedPropNativeComponentProps final : public ViewProps { + public: + MixedPropNativeComponentProps() = default; + MixedPropNativeComponentProps(const PropsParserContext& context, const MixedPropNativeComponentProps &sourceProps, const RawProps &rawProps); + +#pragma mark - Props + + folly::dynamic mixedProp{}; +}; + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GeneratePropsH can generate fixture MULTI_NATIVE_PROP 1`] = ` Map { "Props.h" => " diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaDelegate-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaDelegate-test.js.snap index 32e18daa15dee1..9bec5993102bd3 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaDelegate-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaDelegate-test.js.snap @@ -785,6 +785,44 @@ public class InterfaceOnlyComponentManagerDelegate "/** +* 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.DynamicFromObject; +import com.facebook.react.uimanager.BaseViewManagerDelegate; +import com.facebook.react.uimanager.BaseViewManagerInterface; + +public class MixedPropNativeComponentManagerDelegate & MixedPropNativeComponentManagerInterface> extends BaseViewManagerDelegate { + public MixedPropNativeComponentManagerDelegate(U viewManager) { + super(viewManager); + } + @Override + public void setProperty(T view, String propName, @Nullable Object value) { + switch (propName) { + case \\"mixedProp\\": + mViewManager.setMixedProp(view, new DynamicFromObject(value)); + break; + default: + super.setProperty(view, propName, value); + } + } +} +", +} +`; + exports[`GeneratePropsJavaDelegate can generate fixture MULTI_NATIVE_PROP 1`] = ` Map { "java/com/facebook/react/viewmanagers/ImageColorPropNativeComponentManagerDelegate.java" => "/** diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaInterface-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaInterface-test.js.snap index 350114d82c12e0..5b828b122d858f 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaInterface-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaInterface-test.js.snap @@ -458,6 +458,29 @@ public interface InterfaceOnlyComponentManagerInterface { } `; +exports[`GeneratePropsJavaInterface can generate fixture MIXED_PROP 1`] = ` +Map { + "java/com/facebook/react/viewmanagers/MixedPropNativeComponentManagerInterface.java" => "/** +* 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 com.facebook.react.bridge.Dynamic; + +public interface MixedPropNativeComponentManagerInterface { + void setMixedProp(T view, Dynamic value); +} +", +} +`; + exports[`GeneratePropsJavaInterface can generate fixture MULTI_NATIVE_PROP 1`] = ` Map { "java/com/facebook/react/viewmanagers/ImageColorPropNativeComponentManagerInterface.java" => "/** diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaPojo-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaPojo-test.js.snap index 5bd56c08bfcf85..47ce16d68f18f5 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaPojo-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaPojo-test.js.snap @@ -758,6 +758,34 @@ public class InterfaceOnlyComponentProps { } `; +exports[`GeneratePropsJavaPojo can generate fixture MIXED_PROP 1`] = ` +Map { + "java/com/facebook/react/viewmanagers/CustomView/MixedPropNativeComponentProps.java" => "/** +* 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. +* +* @generated by codegen project: GeneratePropsJavaPojo.js +*/ + +package com.facebook.react.viewmanagers.CustomView; + +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.react.bridge.Dynamic; + +@DoNotStrip +public class MixedPropNativeComponentProps { + private Dynamic mMixedProp; + @DoNotStrip + public Dynamic getMixedProp() { + return mMixedProp; + } +} +", +} +`; + exports[`GeneratePropsJavaPojo can generate fixture MULTI_NATIVE_PROP 1`] = ` Map { "java/com/facebook/react/viewmanagers/Slider/ImageColorPropNativeComponentProps.java" => "/** diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeCpp-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeCpp-test.js.snap index 7184800ffe0c01..6172d9ae625739 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeCpp-test.js.snap @@ -495,6 +495,31 @@ namespace react { +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateShadowNodeCpp can generate fixture MIXED_PROP 1`] = ` +Map { + "ShadowNodes.cpp" => " +/** + * 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 + +namespace facebook { +namespace react { + +extern const char MixedPropNativeComponentComponentName[] = \\"MixedPropNativeComponent\\"; + } // namespace react } // namespace facebook ", diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeH-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeH-test.js.snap index b8c9408db1718b..f8e76bfa9e41d2 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeH-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeH-test.js.snap @@ -787,6 +787,46 @@ namespace react { +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateShadowNodeH can generate fixture MIXED_PROP 1`] = ` +Map { + "ShadowNodes.h" => " +/** + * 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 +#include +#include +#include +#include + +namespace facebook { +namespace react { + +JSI_EXPORT extern const char MixedPropNativeComponentComponentName[]; + +/* + * \`ShadowNode\` for component. + */ +using MixedPropNativeComponentShadowNode = ConcreteViewShadowNode< + MixedPropNativeComponentComponentName, + MixedPropNativeComponentProps, + MixedPropNativeComponentEventEmitter, + MixedPropNativeComponentState>; + } // namespace react } // namespace facebook ", diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateStateCpp-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateStateCpp-test.js.snap index 736f26f9d05f14..81112bcefb78cf 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateStateCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateStateCpp-test.js.snap @@ -474,6 +474,30 @@ namespace react { +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateStateCpp can generate fixture MIXED_PROP 1`] = ` +Map { + "States.cpp" => " +/** + * 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 + +namespace facebook { +namespace react { + + + } // namespace react } // namespace facebook ", diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateStateH-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateStateH-test.js.snap index 22bd441cff30fd..c295dcfc57a1fb 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateStateH-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateStateH-test.js.snap @@ -804,6 +804,47 @@ namespace react { +} // namespace react +} // namespace facebook", +} +`; + +exports[`GenerateStateH can generate fixture MIXED_PROP 1`] = ` +Map { + "States.h" => "/** + * 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 { +namespace react { + +class MixedPropNativeComponentState { +public: + MixedPropNativeComponentState() = default; + +#ifdef ANDROID + MixedPropNativeComponentState(MixedPropNativeComponentState const &previousState, folly::dynamic data){}; + folly::dynamic getDynamic() const { + return {}; + }; + MapBuffer getMapBuffer() const { + return MapBufferBuilder::EMPTY(); + }; +#endif +}; + } // namespace react } // namespace facebook", } diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateTests-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateTests-test.js.snap index 1ff57477166f7a..8eeed7604d0d42 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateTests-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateTests-test.js.snap @@ -899,6 +899,41 @@ TEST(InterfaceOnlyComponentProps_accessibilityHint, etc) { } `; +exports[`GenerateTests can generate fixture MIXED_PROP 1`] = ` +Map { + "Tests.cpp" => "/** + * 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: GenerateTests.js + * */ + +#include +#include +#include +#include +#include +#include + +using namespace facebook::react; + +TEST(MixedPropNativeComponentProps_DoesNotDie, etc) { + auto propParser = RawPropsParser(); + propParser.prepare(); + auto const &sourceProps = MixedPropNativeComponentProps(); + auto const &rawProps = RawProps(folly::dynamic::object(\\"xx_invalid_xx\\", \\"xx_invalid_xx\\")); + + ContextContainer contextContainer{}; + PropsParserContext parserContext{-1, contextContainer}; + + rawProps.parse(propParser, parserContext); + MixedPropNativeComponentProps(parserContext, sourceProps, rawProps); +}", +} +`; + exports[`GenerateTests can generate fixture MULTI_NATIVE_PROP 1`] = ` Map { "Tests.cpp" => "/** diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateThirdPartyFabricComponentsProviderH-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateThirdPartyFabricComponentsProviderH-test.js.snap index 53593a306e6d0e..82f6247e94f4f0 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateThirdPartyFabricComponentsProviderH-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateThirdPartyFabricComponentsProviderH-test.js.snap @@ -41,6 +41,7 @@ Class ObjectPropsCls(void) __attribute__((used)); // O Class ImageColorPropNativeComponentCls(void) __attribute__((used)); // MULTI_NATIVE_PROP Class StringEnumPropsNativeComponentCls(void) __attribute__((used)); // STRING_ENUM_PROP Class Int32EnumPropsNativeComponentCls(void) __attribute__((used)); // INT32_ENUM_PROP +Class MixedPropNativeComponentCls(void) __attribute__((used)); // MIXED_PROP Class EventsNativeComponentCls(void) __attribute__((used)); // EVENT_PROPS Class InterfaceOnlyComponentCls(void) __attribute__((used)); // EVENTS_WITH_PAPER_NAME Class EventsNestedObjectNativeComponentCls(void) __attribute__((used)); // EVENT_NESTED_OBJECT_PROPS diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateThirdPartyFabricComponentsProviderObjCpp-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateThirdPartyFabricComponentsProviderObjCpp-test.js.snap index 9fbb881bc9cb2f..c766a6b679a9b5 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateThirdPartyFabricComponentsProviderObjCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateThirdPartyFabricComponentsProviderObjCpp-test.js.snap @@ -58,6 +58,8 @@ Class RCTThirdPartyFabricComponentsProvider(const char {\\"Int32EnumPropsNativeComponent\\", Int32EnumPropsNativeComponentCls}, // INT32_ENUM_PROP + {\\"MixedPropNativeComponent\\", MixedPropNativeComponentCls}, // MIXED_PROP + {\\"EventsNativeComponent\\", EventsNativeComponentCls}, // EVENT_PROPS {\\"InterfaceOnlyComponent\\", InterfaceOnlyComponentCls}, // EVENTS_WITH_PAPER_NAME diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap index 3b8b77d0d2bf2d..1826f646289b8e 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap @@ -817,6 +817,40 @@ export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL } `; +exports[`GenerateViewConfigJs can generate fixture MIXED_PROP 1`] = ` +Map { + "MIXED_PROPNativeViewConfig.js" => " +/** + * 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. + * + * @flow + * + * @generated by codegen project: GenerateViewConfigJs.js + */ + +'use strict'; + +const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry'); + +let nativeComponentName = 'MixedPropNativeComponent'; + + +export const __INTERNAL_VIEW_CONFIG = { + uiViewClassName: 'MixedPropNativeComponent', + + validAttributes: { + mixedProp: true, + }, +}; + +export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL_VIEW_CONFIG); +", +} +`; + exports[`GenerateViewConfigJs can generate fixture MULTI_NATIVE_PROP 1`] = ` Map { "MULTI_NATIVE_PROPNativeViewConfig.js" => " diff --git a/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js index e83299d3a5b0f2..3a724b3411172b 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js @@ -209,7 +209,7 @@ const ALL_PROP_TYPES_NO_EVENTS = ` const codegenNativeComponent = require('codegenNativeComponent'); -import type {Int32, Double, Float, WithDefault} from 'CodegenTypes'; +import type {Int32, Double, Float, WithDefault, UnsafeMixed} from 'CodegenTypes'; import type {ImageSource} from 'ImageSource'; import type {ColorValue, ColorArrayValue, PointValue, EdgeInsetsValue, DimensionValue} from 'StyleSheetTypes'; import type {ViewProps} from 'ViewPropTypes'; @@ -317,6 +317,10 @@ type ModuleProps = $ReadOnly<{| dimension_optional_key?: DimensionValue, dimension_optional_value: ?DimensionValue, dimension_optional_both?: ?DimensionValue, + + // Mixed props + mixed_required: UnsafeMixed, + mixed_optional_key?: UnsafeMixed, |}>; export default (codegenNativeComponent( diff --git a/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap b/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap index 21ee4a352be74d..f3ec2606cfc16c 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap @@ -571,6 +571,20 @@ exports[`RN Codegen Flow Parser can generate fixture ALL_PROP_TYPES_NO_EVENTS 1` 'type': 'ReservedPropTypeAnnotation', 'name': 'DimensionPrimitive' } + }, + { + 'name': 'mixed_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'MixedTypeAnnotation' + } + }, + { + 'name': 'mixed_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'MixedTypeAnnotation' + } } ], 'commands': [] diff --git a/packages/react-native-codegen/src/parsers/flow/components/componentsUtils.js b/packages/react-native-codegen/src/parsers/flow/components/componentsUtils.js index 03458e525ad8b1..d694fe2f795e3a 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/componentsUtils.js +++ b/packages/react-native-codegen/src/parsers/flow/components/componentsUtils.js @@ -391,6 +391,10 @@ function getTypeAnnotation<+T>( throw new Error( `Cannot use "${type}" type annotation for "${name}": must use a specific numeric type like Int32, Double, or Float`, ); + case 'UnsafeMixed': + return { + type: 'MixedTypeAnnotation', + }; default: (type: empty); throw new Error( diff --git a/packages/react-native-codegen/src/parsers/typescript/components/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/typescript/components/__test_fixtures__/fixtures.js index 8473fb54d3e21a..57aafa7b5562d4 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/__test_fixtures__/fixtures.js @@ -197,7 +197,7 @@ const ALL_PROP_TYPES_NO_EVENTS = ` const codegenNativeComponent = require('codegenNativeComponent'); -import type {Int32, Double, Float, WithDefault} from 'CodegenTypes'; +import type {Int32, Double, Float, WithDefault, UnsafeMixed} from 'CodegenTypes'; import type {ImageSource} from 'ImageSource'; import type { ColorValue, @@ -310,6 +310,10 @@ export interface ModuleProps extends ViewProps { dimension_optional_key?: DimensionValue; dimension_optional_value: DimensionValue | null | undefined; dimension_optional_both?: DimensionValue | null | undefined; + + // Mixed props + mixed_required: UnsafeMixed, + mixed_optional_key?: UnsafeMixed, } export default codegenNativeComponent( diff --git a/packages/react-native-codegen/src/parsers/typescript/components/__tests__/__snapshots__/typescript-component-parser-test.js.snap b/packages/react-native-codegen/src/parsers/typescript/components/__tests__/__snapshots__/typescript-component-parser-test.js.snap index d2f557d64cb407..4211709793e576 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/__tests__/__snapshots__/typescript-component-parser-test.js.snap +++ b/packages/react-native-codegen/src/parsers/typescript/components/__tests__/__snapshots__/typescript-component-parser-test.js.snap @@ -569,6 +569,20 @@ exports[`RN Codegen TypeScript Parser can generate fixture ALL_PROP_TYPES_NO_EVE 'type': 'ReservedPropTypeAnnotation', 'name': 'DimensionPrimitive' } + }, + { + 'name': 'mixed_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'MixedTypeAnnotation' + } + }, + { + 'name': 'mixed_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'MixedTypeAnnotation' + } } ], 'commands': [] diff --git a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js index e45bc52c53d458..8adc7e586dfcd1 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js @@ -262,6 +262,10 @@ function getCommonTypeAnnotation( return { type: 'StringTypeAnnotation', }; + case 'UnsafeMixed': + return { + type: 'MixedTypeAnnotation', + }; default: return undefined; } diff --git a/packages/react-native/Libraries/Types/CodegenTypes.js b/packages/react-native/Libraries/Types/CodegenTypes.js index ca43a6b01724dc..737e2f290b1049 100644 --- a/packages/react-native/Libraries/Types/CodegenTypes.js +++ b/packages/react-native/Libraries/Types/CodegenTypes.js @@ -29,6 +29,7 @@ export type Double = number; export type Float = number; export type Int32 = number; export type UnsafeObject = $FlowFixMe; // Object is forbidden in strict mode +export type UnsafeMixed = mixed; type DefaultTypes = number | boolean | string | $ReadOnlyArray; // Default handling, ignore the unused value