From 21155051f37770397f1f8ecf3ca3d553a51858c3 Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Tue, 10 Feb 2026 13:33:16 -0800 Subject: [PATCH 1/4] Codegen: Fix issues with more complex props and event types (#15647) * Fix issues with more complex props and event types * Change files * lint * fix --- ...-1a60d2fe-5491-4857-95e8-f2db0f4ae9c8.json | 7 + .../generators/GenerateComponentWindows.ts | 40 ++-- .../src/MovingLightNativeComponent.ts | 11 +- .../SampleCustomComponent/CalendarView.cpp | 2 +- .../SampleCustomComponent/CalendarView.g.h | 8 +- .../SampleCustomComponent/MovingLight.g.h | 192 +++++++++++++++++- 6 files changed, 236 insertions(+), 24 deletions(-) create mode 100644 change/@react-native-windows-codegen-1a60d2fe-5491-4857-95e8-f2db0f4ae9c8.json diff --git a/change/@react-native-windows-codegen-1a60d2fe-5491-4857-95e8-f2db0f4ae9c8.json b/change/@react-native-windows-codegen-1a60d2fe-5491-4857-95e8-f2db0f4ae9c8.json new file mode 100644 index 00000000000..fb230d2c766 --- /dev/null +++ b/change/@react-native-windows-codegen-1a60d2fe-5491-4857-95e8-f2db0f4ae9c8.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Fix issues with more complex props and event types", + "packageName": "@react-native-windows/codegen", + "email": "30809111+acoates-ms@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/packages/@react-native-windows/codegen/src/generators/GenerateComponentWindows.ts b/packages/@react-native-windows/codegen/src/generators/GenerateComponentWindows.ts index b08d0e51f16..1d000e27630 100644 --- a/packages/@react-native-windows/codegen/src/generators/GenerateComponentWindows.ts +++ b/packages/@react-native-windows/codegen/src/generators/GenerateComponentWindows.ts @@ -70,7 +70,7 @@ struct ::_OBJECT_NAME_:: { `; const eventEmitterMethodTemplate = ` void ::_EVENT_NAME_::(::_EVENT_OBJECT_TYPE_:: &value) const { - m_eventEmitter.DispatchEvent(L"::_EVENT_NAME_NO_ON_::", [value](const winrt::Microsoft::ReactNative::IJSValueWriter writer) { + m_eventEmitter.DispatchEvent(L"::_EVENT_NAME_NO_ON_::", [&value](const winrt::Microsoft::ReactNative::IJSValueWriter writer) { winrt::Microsoft::ReactNative::WriteValue(writer, value); }); }`; @@ -344,7 +344,9 @@ export function createComponentGenerator({ const propInitializers = componentShape.props .map(prop => { - return ` ${prop.name} = cloneFromProps->${prop.name};`; + if (prop.typeAnnotation.type === 'MixedTypeAnnotation') + return ` ${prop.name} = cloneFromProps->${prop.name}.Copy();`; + else return ` ${prop.name} = cloneFromProps->${prop.name};`; }) .join('\n'); @@ -414,7 +416,30 @@ export function createComponentGenerator({ }) .join('\n\n'); + const eventObjectUsings = eventObjectAliases.jobs + .map(eventObjectTypeName => { + return ` using ${eventObjectTypeName.replace('on', 'On')} = ${ + getAliasCppName(eventObjectTypeName) /*.replace('_on', '_On')*/ + };`; + }) + .join('\n'); + + // Collect all the alias types for the event objects so that we can generate the unnamed types within objects + eventObjectAliases.jobs.forEach(eventObjectTypeName => { + const eventObjectType = + eventObjectAliases.types[eventObjectTypeName]!; + eventObjectType.properties.forEach(property => { + translateComponentEventType( + property.typeAnnotation, + eventObjectAliases, + eventObjectTypeName, + cppCodegenOptions, + ); + }); + }); + const eventObjects = eventObjectAliases.jobs + .reverse() .map(eventObjectTypeName => { const eventObjectType = eventObjectAliases.types[eventObjectTypeName]!; @@ -437,21 +462,12 @@ export function createComponentGenerator({ return eventsObjectTemplate .replace( /::_OBJECT_NAME_::/g, - `${componentName}_${eventObjectTypeName.replace('on', 'On')}`, + getAliasCppName(eventObjectTypeName) /*.replace('_on', '_On')*/, ) .replace(/::_OBJECT_FIELDS_::/g, eventObjectFields); }) .join('\n'); - const eventObjectUsings = eventObjectAliases.jobs - .map(eventObjectTypeName => { - return ` using ${eventObjectTypeName.replace( - 'on', - 'On', - )} = ${componentName}_${eventObjectTypeName.replace('on', 'On')};`; - }) - .join('\n'); - const eventEmitter = eventEmitterTemplate .replace(/::_COMPONENT_EVENT_OBJECT_TYPES_::/g, eventObjects) .replace(/::_EVENT_EMITTER_METHODS_::/g, eventEmitterMethods) diff --git a/packages/sample-custom-component/src/MovingLightNativeComponent.ts b/packages/sample-custom-component/src/MovingLightNativeComponent.ts index e452632a2a8..18641f63c4b 100644 --- a/packages/sample-custom-component/src/MovingLightNativeComponent.ts +++ b/packages/sample-custom-component/src/MovingLightNativeComponent.ts @@ -1,4 +1,4 @@ -import {codegenNativeComponent, codegenNativeCommands} from 'react-native'; +import { codegenNativeComponent, codegenNativeCommands } from 'react-native'; import type { ColorValue, HostComponent, ViewProps } from 'react-native'; import type { @@ -7,6 +7,7 @@ import type { Double, Int32, WithDefault, + UnsafeMixed, } from 'react-native/Libraries/Types/CodegenTypes'; export type SomethingEvent = { @@ -17,12 +18,16 @@ export type SomethingEvent = { export interface MovingLightProps extends ViewProps { // Props size?: WithDefault; - color?: ColorValue + color?: ColorValue; + testMixed?: UnsafeMixed; eventParam?: string; - objectProp?: { number: Double, string: string}; + objectProp?: { number: Double, string: string }; // Events onSomething?: DirectEventHandler, + onTestObjectEvent?: DirectEventHandler<{ target: Int32; testObject: UnsafeMixed }>; + onEventWithInlineTypes?: DirectEventHandler<{ target: Int32; contentInset: { top: Double; bottom: Double; left: Double; right: Double }; contentOffset: { x: Double; y: Double }; contentSize: { width: Double; height: Double }; layoutMeasurement: { width: Double; height: Double }; velocity: { x: Double; y: Double }; isUserTriggered: boolean }>; + onEventWithMultipleAliasTypes?: DirectEventHandler<{ target: Int32; contentInset: { top: Double; bottom: Double; left: Double; right: Double }; contentOffset: { x: Double; y: Double }; contentSize: { width: Double; height: Double }; layoutMeasurement: { width: Double; height: Double }; velocity: { x: Double; y: Double }; isUserTriggered: boolean }>; } diff --git a/packages/sample-custom-component/windows/SampleCustomComponent/CalendarView.cpp b/packages/sample-custom-component/windows/SampleCustomComponent/CalendarView.cpp index 4557d956634..0927016080c 100644 --- a/packages/sample-custom-component/windows/SampleCustomComponent/CalendarView.cpp +++ b/packages/sample-custom-component/windows/SampleCustomComponent/CalendarView.cpp @@ -28,7 +28,7 @@ struct CalendarViewComponentView : public winrt::implements(); size = cloneFromProps->size; color = cloneFromProps->color; + testMixed = cloneFromProps->testMixed.Copy(); eventParam = cloneFromProps->eventParam; objectProp = cloneFromProps->objectProp; } @@ -51,6 +52,9 @@ struct MovingLightProps : winrt::implements eventParam; @@ -60,8 +64,167 @@ struct MovingLightProps : winrt::implements Date: Tue, 10 Feb 2026 13:34:45 -0800 Subject: [PATCH 2/4] update change file --- ...-windows-codegen-1a60d2fe-5491-4857-95e8-f2db0f4ae9c8.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/change/@react-native-windows-codegen-1a60d2fe-5491-4857-95e8-f2db0f4ae9c8.json b/change/@react-native-windows-codegen-1a60d2fe-5491-4857-95e8-f2db0f4ae9c8.json index fb230d2c766..62ddd65de22 100644 --- a/change/@react-native-windows-codegen-1a60d2fe-5491-4857-95e8-f2db0f4ae9c8.json +++ b/change/@react-native-windows-codegen-1a60d2fe-5491-4857-95e8-f2db0f4ae9c8.json @@ -1,7 +1,7 @@ { - "type": "prerelease", + "type": "patch", "comment": "Fix issues with more complex props and event types", "packageName": "@react-native-windows/codegen", "email": "30809111+acoates-ms@users.noreply.github.com", "dependentChangeType": "patch" -} +} \ No newline at end of file From 493e04cf93052e614641e393e9d7550b992986dd Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:54:43 -0800 Subject: [PATCH 3/4] update codegen'd files --- .../rnwcore/AndroidDrawerLayout.g.h | 40 +++++++++---------- .../rnwcore/AndroidSwipeRefreshLayout.g.h | 8 ++-- .../components/rnwcore/AndroidSwitch.g.h | 8 ++-- .../components/rnwcore/ModalHostView.g.h | 36 ++++++++--------- .../components/rnwcore/PullToRefreshView.g.h | 8 ++-- .../react/components/rnwcore/Switch.g.h | 8 ++-- .../react/components/rnwcore/VirtualView.g.h | 40 ++++++++++++++++--- 7 files changed, 88 insertions(+), 60 deletions(-) diff --git a/vnext/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h b/vnext/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h index f026661ef9e..c7f0c7147a7 100644 --- a/vnext/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +++ b/vnext/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h @@ -59,55 +59,55 @@ struct AndroidDrawerLayoutProps : winrt::implements Date: Tue, 10 Feb 2026 15:59:04 -0800 Subject: [PATCH 4/4] Change files --- ...ative-windows-5a525e83-cbc3-442c-ac76-fc2d077da5a4.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/react-native-windows-5a525e83-cbc3-442c-ac76-fc2d077da5a4.json diff --git a/change/react-native-windows-5a525e83-cbc3-442c-ac76-fc2d077da5a4.json b/change/react-native-windows-5a525e83-cbc3-442c-ac76-fc2d077da5a4.json new file mode 100644 index 00000000000..4656ed1a924 --- /dev/null +++ b/change/react-native-windows-5a525e83-cbc3-442c-ac76-fc2d077da5a4.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "update codegen'd files", + "packageName": "react-native-windows", + "email": "30809111+acoates-ms@users.noreply.github.com", + "dependentChangeType": "patch" +}