react-native-windows 0.75.9 → 0.75.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/Libraries/Modal/Modal.windows.js +352 -0
  2. package/Microsoft.ReactNative/CompositionComponentView.idl +2 -1
  3. package/Microsoft.ReactNative/Fabric/AbiComponentDescriptor.cpp +4 -1
  4. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp +1 -1
  5. package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +7 -0
  6. package/Microsoft.ReactNative/Fabric/AbiViewProps.h +2 -0
  7. package/Microsoft.ReactNative/Fabric/ComponentView.cpp +45 -50
  8. package/Microsoft.ReactNative/Fabric/ComponentView.h +14 -22
  9. package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.cpp +931 -0
  10. package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.h +80 -0
  11. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +31 -13
  12. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +187 -6
  13. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +10 -1
  14. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +8 -32
  15. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +316 -911
  16. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +32 -29
  17. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +9 -2
  18. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +2 -1
  19. package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +1 -1
  20. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +181 -123
  21. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +16 -8
  22. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +99 -37
  23. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +25 -3
  24. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +63 -2
  25. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +12 -0
  26. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +51 -3
  27. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +3 -0
  28. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +18 -8
  29. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +3 -0
  30. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +54 -5
  31. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +8 -0
  32. package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +9 -3
  33. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +11 -0
  34. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +2 -0
  35. package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp +1 -1
  36. package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +26 -0
  37. package/Microsoft.ReactNative/IReactViewComponentBuilder.idl +1 -1
  38. package/Microsoft.ReactNative/ReactNativeAppBuilder.cpp +25 -129
  39. package/Microsoft.ReactNative/ReactNativeAppBuilder.h +5 -13
  40. package/Microsoft.ReactNative/ReactNativeAppBuilder.idl +13 -34
  41. package/Microsoft.ReactNative/ReactNativeIsland.idl +3 -2
  42. package/Microsoft.ReactNative/ReactNativeWin32App.cpp +129 -18
  43. package/Microsoft.ReactNative/ReactNativeWin32App.h +14 -5
  44. package/Microsoft.ReactNative/ViewProps.idl +2 -0
  45. package/Microsoft.ReactNative.Cxx/ComponentView.Experimental.interop.h +14 -0
  46. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  47. package/Shared/Shared.vcxitems +3 -10
  48. package/Shared/Shared.vcxitems.filters +1 -0
  49. package/codegen/NativeAccessibilityInfoSpec.g.h +1 -0
  50. package/codegen/NativeAccessibilityManagerSpec.g.h +1 -0
  51. package/codegen/NativeActionSheetManagerSpec.g.h +1 -0
  52. package/codegen/NativeAlertManagerSpec.g.h +1 -0
  53. package/codegen/NativeAnimatedModuleSpec.g.h +1 -0
  54. package/codegen/NativeAnimatedTurboModuleSpec.g.h +1 -0
  55. package/codegen/NativeAppStateSpec.g.h +1 -0
  56. package/codegen/NativeAppThemeSpec.g.h +1 -0
  57. package/codegen/NativeAppearanceSpec.g.h +1 -0
  58. package/codegen/NativeBlobModuleSpec.g.h +1 -0
  59. package/codegen/NativeBugReportingSpec.g.h +1 -0
  60. package/codegen/NativeClipboardSpec.g.h +1 -0
  61. package/codegen/NativeDOMSpec.g.h +1 -0
  62. package/codegen/NativeDevLoadingViewSpec.g.h +1 -0
  63. package/codegen/NativeDevMenuSpec.g.h +1 -0
  64. package/codegen/NativeDevSettingsSpec.g.h +1 -0
  65. package/codegen/NativeDevToolsSettingsManagerSpec.g.h +1 -0
  66. package/codegen/NativeDeviceEventManagerSpec.g.h +1 -0
  67. package/codegen/NativeDeviceInfoSpec.g.h +1 -0
  68. package/codegen/NativeDialogManagerAndroidSpec.g.h +1 -0
  69. package/codegen/NativeDialogManagerWindowsSpec.g.h +1 -0
  70. package/codegen/NativeExceptionsManagerSpec.g.h +1 -0
  71. package/codegen/NativeFileReaderModuleSpec.g.h +1 -0
  72. package/codegen/NativeFrameRateLoggerSpec.g.h +1 -0
  73. package/codegen/NativeHeadlessJsTaskSupportSpec.g.h +1 -0
  74. package/codegen/NativeI18nManagerSpec.g.h +1 -0
  75. package/codegen/NativeIdleCallbacksSpec.g.h +1 -0
  76. package/codegen/NativeImageEditorSpec.g.h +1 -0
  77. package/codegen/NativeImageLoaderAndroidSpec.g.h +1 -0
  78. package/codegen/NativeImageLoaderIOSSpec.g.h +1 -0
  79. package/codegen/NativeImageStoreAndroidSpec.g.h +1 -0
  80. package/codegen/NativeImageStoreIOSSpec.g.h +1 -0
  81. package/codegen/NativeIntentAndroidSpec.g.h +1 -0
  82. package/codegen/NativeIntersectionObserverSpec.g.h +1 -0
  83. package/codegen/NativeJSCHeapCaptureSpec.g.h +1 -0
  84. package/codegen/NativeJSCSamplingProfilerSpec.g.h +1 -0
  85. package/codegen/NativeKeyboardObserverSpec.g.h +1 -0
  86. package/codegen/NativeLinkingManagerSpec.g.h +1 -0
  87. package/codegen/NativeLogBoxSpec.g.h +1 -0
  88. package/codegen/NativeMicrotasksSpec.g.h +1 -0
  89. package/codegen/NativeModalManagerSpec.g.h +1 -0
  90. package/codegen/NativeMutationObserverSpec.g.h +1 -0
  91. package/codegen/NativeNetworkingAndroidSpec.g.h +1 -0
  92. package/codegen/NativeNetworkingIOSSpec.g.h +1 -0
  93. package/codegen/NativePerformanceObserverSpec.g.h +1 -0
  94. package/codegen/NativePerformanceSpec.g.h +1 -0
  95. package/codegen/NativePermissionsAndroidSpec.g.h +1 -0
  96. package/codegen/NativePlatformConstantsAndroidSpec.g.h +1 -0
  97. package/codegen/NativePlatformConstantsIOSSpec.g.h +1 -0
  98. package/codegen/NativePlatformConstantsWindowsSpec.g.h +1 -0
  99. package/codegen/NativePushNotificationManagerIOSSpec.g.h +1 -0
  100. package/codegen/NativeReactNativeFeatureFlagsSpec.g.h +1 -0
  101. package/codegen/NativeRedBoxSpec.g.h +1 -0
  102. package/codegen/NativeSampleTurboModuleSpec.g.h +1 -0
  103. package/codegen/NativeSegmentFetcherSpec.g.h +1 -0
  104. package/codegen/NativeSettingsManagerSpec.g.h +1 -0
  105. package/codegen/NativeShareModuleSpec.g.h +1 -0
  106. package/codegen/NativeSoundManagerSpec.g.h +1 -0
  107. package/codegen/NativeSourceCodeSpec.g.h +1 -0
  108. package/codegen/NativeStatusBarManagerAndroidSpec.g.h +1 -0
  109. package/codegen/NativeStatusBarManagerIOSSpec.g.h +1 -0
  110. package/codegen/NativeTimingSpec.g.h +1 -0
  111. package/codegen/NativeToastAndroidSpec.g.h +1 -0
  112. package/codegen/NativeUIManagerSpec.g.h +1 -0
  113. package/codegen/NativeVibrationSpec.g.h +1 -0
  114. package/codegen/NativeWebSocketModuleSpec.g.h +1 -0
  115. package/package.json +3 -3
  116. package/templates/cpp-app/windows/MyApp/MyApp.cpp +46 -130
  117. package/Microsoft.ReactNative/ReactInstanceSettingsBuilder.cpp +0 -59
  118. package/Microsoft.ReactNative/ReactInstanceSettingsBuilder.h +0 -23
@@ -0,0 +1,352 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @flow strict-local
9
+ */
10
+
11
+ import type {ViewProps} from '../Components/View/ViewPropTypes';
12
+ import type {RootTag} from '../ReactNative/RootTag';
13
+ import type {DirectEventHandler} from '../Types/CodegenTypes';
14
+
15
+ import NativeEventEmitter from '../EventEmitter/NativeEventEmitter';
16
+ import {type EventSubscription} from '../vendor/emitter/EventEmitter';
17
+ import ModalInjection from './ModalInjection';
18
+ import NativeModalManager from './NativeModalManager';
19
+ import RCTModalHostView from './RCTModalHostViewNativeComponent';
20
+ import {VirtualizedListContextResetter} from '@react-native/virtualized-lists';
21
+
22
+ const ScrollView = require('../Components/ScrollView/ScrollView');
23
+ const View = require('../Components/View/View');
24
+ const AppContainer = require('../ReactNative/AppContainer');
25
+ const I18nManager = require('../ReactNative/I18nManager');
26
+ const {RootTagContext} = require('../ReactNative/RootTag');
27
+ const StyleSheet = require('../StyleSheet/StyleSheet');
28
+ const Platform = require('../Utilities/Platform');
29
+ const React = require('react');
30
+
31
+ type ModalEventDefinitions = {
32
+ modalDismissed: [{modalID: number}],
33
+ };
34
+
35
+ const ModalEventEmitter =
36
+ (Platform.OS === 'ios' || Platform.OS === 'windows') && // [Windows]
37
+ NativeModalManager != null
38
+ ? new NativeEventEmitter<ModalEventDefinitions>(
39
+ // T88715063: NativeEventEmitter only used this parameter on iOS. Now it uses it on all platforms, so this code was modified automatically to preserve its behavior
40
+ // If you want to use the native module on other platforms, please remove this condition and test its behavior
41
+ Platform.OS !== 'ios' && Platform.OS !== 'windows' // [Windows]
42
+ ? null
43
+ : NativeModalManager,
44
+ )
45
+ : null;
46
+
47
+ /**
48
+ * The Modal component is a simple way to present content above an enclosing view.
49
+ *
50
+ * See https://reactnative.dev/docs/modal
51
+ */
52
+
53
+ // In order to route onDismiss callbacks, we need to uniquely identifier each
54
+ // <Modal> on screen. There can be different ones, either nested or as siblings.
55
+ // We cannot pass the onDismiss callback to native as the view will be
56
+ // destroyed before the callback is fired.
57
+ let uniqueModalIdentifier = 0;
58
+
59
+ type OrientationChangeEvent = $ReadOnly<{|
60
+ orientation: 'portrait' | 'landscape',
61
+ |}>;
62
+
63
+ export type Props = $ReadOnly<{|
64
+ ...ViewProps,
65
+
66
+ /**
67
+ * The `animationType` prop controls how the modal animates.
68
+ *
69
+ * See https://reactnative.dev/docs/modal#animationtype
70
+ */
71
+ animationType?: ?('none' | 'slide' | 'fade'),
72
+
73
+ /**
74
+ * The `presentationStyle` prop controls how the modal appears.
75
+ *
76
+ * See https://reactnative.dev/docs/modal#presentationstyle
77
+ */
78
+ presentationStyle?: ?(
79
+ | 'fullScreen'
80
+ | 'pageSheet'
81
+ | 'formSheet'
82
+ | 'overFullScreen'
83
+ ),
84
+
85
+ /**
86
+ * The `transparent` prop determines whether your modal will fill the
87
+ * entire view.
88
+ *
89
+ * See https://reactnative.dev/docs/modal#transparent
90
+ */
91
+ transparent?: ?boolean,
92
+
93
+ /**
94
+ * The `statusBarTranslucent` prop determines whether your modal should go under
95
+ * the system statusbar.
96
+ *
97
+ * See https://reactnative.dev/docs/modal.html#statusbartranslucent-android
98
+ */
99
+ statusBarTranslucent?: ?boolean,
100
+
101
+ /**
102
+ * The `hardwareAccelerated` prop controls whether to force hardware
103
+ * acceleration for the underlying window.
104
+ *
105
+ * This prop works only on Android.
106
+ *
107
+ * See https://reactnative.dev/docs/modal#hardwareaccelerated
108
+ */
109
+ hardwareAccelerated?: ?boolean,
110
+
111
+ /**
112
+ * The `visible` prop determines whether your modal is visible.
113
+ *
114
+ * See https://reactnative.dev/docs/modal#visible
115
+ */
116
+ visible?: ?boolean,
117
+
118
+ /**
119
+ * The `onRequestClose` callback is called when the user taps the hardware
120
+ * back button on Android or the menu button on Apple TV.
121
+ *
122
+ * This is required on Apple TV and Android.
123
+ *
124
+ * See https://reactnative.dev/docs/modal#onrequestclose
125
+ */
126
+ onRequestClose?: ?DirectEventHandler<null>,
127
+
128
+ /**
129
+ * The `onShow` prop allows passing a function that will be called once the
130
+ * modal has been shown.
131
+ *
132
+ * See https://reactnative.dev/docs/modal#onshow
133
+ */
134
+ onShow?: ?DirectEventHandler<null>,
135
+
136
+ /**
137
+ * The `onDismiss` prop allows passing a function that will be called once
138
+ * the modal has been dismissed.
139
+ *
140
+ * See https://reactnative.dev/docs/modal#ondismiss
141
+ */
142
+ onDismiss?: ?() => mixed,
143
+
144
+ /**
145
+ * The `supportedOrientations` prop allows the modal to be rotated to any of the specified orientations.
146
+ *
147
+ * See https://reactnative.dev/docs/modal#supportedorientations
148
+ */
149
+ supportedOrientations?: ?$ReadOnlyArray<
150
+ | 'portrait'
151
+ | 'portrait-upside-down'
152
+ | 'landscape'
153
+ | 'landscape-left'
154
+ | 'landscape-right',
155
+ >,
156
+
157
+ /**
158
+ * The `onOrientationChange` callback is called when the orientation changes while the modal is being displayed.
159
+ *
160
+ * See https://reactnative.dev/docs/modal#onorientationchange
161
+ */
162
+ onOrientationChange?: ?DirectEventHandler<OrientationChangeEvent>,
163
+
164
+ /**
165
+ * The `backdropColor` props sets the background color of the modal's container.
166
+ * Defaults to `white` if not provided and transparent is `false`. Ignored if `transparent` is `true`.
167
+ */
168
+ backdropColor?: ?string,
169
+ |}>;
170
+
171
+ function confirmProps(props: Props) {
172
+ if (__DEV__) {
173
+ if (
174
+ props.presentationStyle &&
175
+ props.presentationStyle !== 'overFullScreen' &&
176
+ props.transparent === true
177
+ ) {
178
+ console.warn(
179
+ `Modal with '${props.presentationStyle}' presentation style and 'transparent' value is not supported.`,
180
+ );
181
+ }
182
+ }
183
+ }
184
+
185
+ // Create a state to track whether the Modal is rendering or not.
186
+ // This is the only prop that controls whether the modal is rendered or not.
187
+ type State = {
188
+ isRendered: boolean,
189
+ };
190
+
191
+ class Modal extends React.Component<Props, State> {
192
+ static defaultProps: {|hardwareAccelerated: boolean, visible: boolean|} = {
193
+ visible: true,
194
+ hardwareAccelerated: false,
195
+ };
196
+
197
+ static contextType: React.Context<RootTag> = RootTagContext;
198
+
199
+ _identifier: number;
200
+ _eventSubscription: ?EventSubscription;
201
+
202
+ constructor(props: Props) {
203
+ super(props);
204
+ if (__DEV__) {
205
+ confirmProps(props);
206
+ }
207
+ this._identifier = uniqueModalIdentifier++;
208
+ this.state = {
209
+ isRendered: props.visible === true,
210
+ };
211
+ }
212
+
213
+ componentDidMount() {
214
+ // 'modalDismissed' is for the old renderer in iOS only
215
+ if (ModalEventEmitter) {
216
+ this._eventSubscription = ModalEventEmitter.addListener(
217
+ 'modalDismissed',
218
+ event => {
219
+ this.setState({isRendered: false}, () => {
220
+ if (event.modalID === this._identifier && this.props.onDismiss) {
221
+ this.props.onDismiss();
222
+ }
223
+ });
224
+ },
225
+ );
226
+ }
227
+ }
228
+
229
+ componentWillUnmount() {
230
+ if (this._eventSubscription) {
231
+ this._eventSubscription.remove();
232
+ }
233
+ }
234
+
235
+ componentDidUpdate(prevProps: Props) {
236
+ if (prevProps.visible === false && this.props.visible === true) {
237
+ this.setState({isRendered: true});
238
+ }
239
+
240
+ if (__DEV__) {
241
+ confirmProps(this.props);
242
+ }
243
+ }
244
+
245
+ // Helper function to encapsulate platform specific logic to show or not the Modal.
246
+ _shouldShowModal(): boolean {
247
+ if (Platform.OS === 'ios' || Platform.OS === 'windows') {
248
+ // [Windows]
249
+ return this.props.visible === true || this.state.isRendered === true;
250
+ }
251
+
252
+ return this.props.visible === true;
253
+ }
254
+
255
+ render(): React.Node {
256
+ if (!this._shouldShowModal()) {
257
+ return null;
258
+ }
259
+
260
+ const containerStyles = {
261
+ backgroundColor:
262
+ this.props.transparent === true
263
+ ? 'transparent'
264
+ : this.props.backdropColor ?? 'white',
265
+ };
266
+
267
+ let animationType = this.props.animationType || 'none';
268
+
269
+ let presentationStyle = this.props.presentationStyle;
270
+ if (!presentationStyle) {
271
+ presentationStyle = 'fullScreen';
272
+ if (this.props.transparent === true) {
273
+ presentationStyle = 'overFullScreen';
274
+ }
275
+ }
276
+
277
+ const innerChildren = __DEV__ ? (
278
+ <AppContainer rootTag={this.context}>{this.props.children}</AppContainer>
279
+ ) : (
280
+ this.props.children
281
+ );
282
+
283
+ const onDismiss = () => {
284
+ // OnDismiss is implemented on iOS/Windows only. // [Windows]
285
+ if (Platform.OS === 'ios' || Platform.OS === 'windows') {
286
+ // [Windows]
287
+ this.setState({isRendered: false}, () => {
288
+ if (this.props.onDismiss) {
289
+ this.props.onDismiss();
290
+ }
291
+ });
292
+ }
293
+ };
294
+
295
+ return (
296
+ <RCTModalHostView
297
+ animationType={animationType}
298
+ presentationStyle={presentationStyle}
299
+ transparent={this.props.transparent}
300
+ hardwareAccelerated={this.props.hardwareAccelerated}
301
+ onRequestClose={this.props.onRequestClose}
302
+ onShow={this.props.onShow}
303
+ onDismiss={onDismiss}
304
+ visible={this.props.visible}
305
+ statusBarTranslucent={this.props.statusBarTranslucent}
306
+ identifier={this._identifier}
307
+ style={styles.modal}
308
+ // $FlowFixMe[method-unbinding] added when improving typing for this parameters
309
+ onStartShouldSetResponder={this._shouldSetResponder}
310
+ supportedOrientations={this.props.supportedOrientations}
311
+ onOrientationChange={this.props.onOrientationChange}
312
+ testID={this.props.testID}>
313
+ <VirtualizedListContextResetter>
314
+ <ScrollView.Context.Provider value={null}>
315
+ <View
316
+ style={[styles.container, containerStyles]}
317
+ collapsable={false}>
318
+ {innerChildren}
319
+ </View>
320
+ </ScrollView.Context.Provider>
321
+ </VirtualizedListContextResetter>
322
+ </RCTModalHostView>
323
+ );
324
+ }
325
+
326
+ // We don't want any responder events bubbling out of the modal.
327
+ _shouldSetResponder(): boolean {
328
+ return true;
329
+ }
330
+ }
331
+
332
+ const side = I18nManager.getConstants().isRTL ? 'right' : 'left';
333
+ const styles = StyleSheet.create({
334
+ modal: {
335
+ position: 'absolute',
336
+ },
337
+ container: {
338
+ /* $FlowFixMe[invalid-computed-prop] (>=0.111.0 site=react_native_fb) This
339
+ * comment suppresses an error found when Flow v0.111 was deployed. To see
340
+ * the error, delete this comment and run Flow. */
341
+ [side]: 0,
342
+ top: 0,
343
+ flex: 1,
344
+ },
345
+ });
346
+
347
+ const ExportedModal: React.AbstractComponent<
348
+ React.ElementConfig<typeof Modal>,
349
+ // $FlowFixMe[incompatible-type-arg]
350
+ > = ModalInjection.unstable_Modal ?? Modal;
351
+
352
+ module.exports = ExportedModal;
@@ -22,8 +22,9 @@ namespace Microsoft.ReactNative.Composition
22
22
  NativeBorder = 0x00000001,
23
23
  ShadowProps = 0x00000002,
24
24
  Background = 0x00000004,
25
+ FocusVisual = 0x00000008,
25
26
 
26
- Default = 0x00000007, // ShadowProps | NativeBorder | Background
27
+ Default = 0x0000000F, // ShadowProps | NativeBorder | Background | FocusVisual
27
28
  };
28
29
 
29
30
  namespace Experimental {
@@ -106,7 +106,10 @@ facebook::react::Props::Shared AbiComponentDescriptor::cloneProps(
106
106
  rawProps);
107
107
  auto userProps =
108
108
  winrt::get_self<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder>(m_builder)
109
- ->CreateProps(nullptr);
109
+ ->CreateProps(
110
+ nullptr,
111
+ props ? static_cast<winrt::Microsoft::ReactNative::implementation::AbiProps const &>(*props).UserProps()
112
+ : nullptr);
110
113
  shadowNodeProps->SetUserProps(userProps);
111
114
 
112
115
  rawProps.iterateOverValues(
@@ -103,7 +103,7 @@ facebook::react::Props::Shared AbiViewComponentDescriptor::cloneProps(
103
103
  winrt::make<winrt::Microsoft::ReactNative::implementation::ViewProps>(shadowNodeProps, false /*holdRef*/);
104
104
  auto userProps =
105
105
  winrt::get_self<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder>(m_builder)
106
- ->CreateProps(viewProps);
106
+ ->CreateProps(viewProps, props ? static_cast<AbiViewProps const &>(*props).UserProps() : nullptr);
107
107
  shadowNodeProps->SetUserProps(userProps, viewProps);
108
108
 
109
109
  rawProps.iterateOverValues(
@@ -65,6 +65,13 @@ winrt::Microsoft::ReactNative::Composition::Experimental::IBrush Color::AsIntern
65
65
  return winrt::get_self<winrt::Microsoft::ReactNative::Composition::implementation::Theme>(theme)->Brush(*m_color);
66
66
  }
67
67
 
68
+ bool Color::Equals(const winrt::Microsoft::ReactNative::Color &color) const noexcept {
69
+ if (!color) {
70
+ return false;
71
+ }
72
+ return m_color == winrt::get_self<Color>(color)->m_color;
73
+ }
74
+
68
75
  winrt::Microsoft::ReactNative::Color Color::ReadValue(
69
76
  const winrt::Microsoft::ReactNative::IJSValueReader &reader) noexcept {
70
77
  switch (reader.ValueType()) {
@@ -50,6 +50,8 @@ struct Color : ColorT<Color, Composition::Experimental::IInternalColor> {
50
50
  winrt::Microsoft::ReactNative::Composition::Experimental::IBrush AsInternalBrush(
51
51
  const winrt::Microsoft::ReactNative::Composition::Theme theme) noexcept;
52
52
 
53
+ bool Equals(const winrt::Microsoft::ReactNative::Color &color) const noexcept;
54
+
53
55
  static winrt::Microsoft::ReactNative::Color ReadValue(
54
56
  const winrt::Microsoft::ReactNative::IJSValueReader &reader) noexcept;
55
57
  static void WriteValue(
@@ -22,11 +22,12 @@ struct RootComponentView;
22
22
 
23
23
  namespace winrt::Microsoft::ReactNative::implementation {
24
24
 
25
- ComponentView::ComponentView(facebook::react::Tag tag, winrt::Microsoft::ReactNative::ReactContext const &reactContext)
26
- : m_tag(tag), m_reactContext(reactContext) {}
27
-
28
- void ComponentView::MarkAsCustomComponent() noexcept {
29
- m_customComponent = true;
25
+ ComponentView::ComponentView(
26
+ facebook::react::Tag tag,
27
+ winrt::Microsoft::ReactNative::ReactContext const &reactContext,
28
+ winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder *builder)
29
+ : m_tag(tag), m_reactContext(reactContext) {
30
+ m_builder.copy_from(builder);
30
31
  }
31
32
 
32
33
  std::vector<facebook::react::ComponentDescriptorProvider>
@@ -52,18 +53,15 @@ void ComponentView::MountChildComponentView(
52
53
  uint32_t index) noexcept {
53
54
  m_children.InsertAt(index, childComponentView);
54
55
  winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(childComponentView)->parent(*this);
55
- if (m_mountChildComponentViewHandler) {
56
- m_mountChildComponentViewHandler(*this, winrt::make<MountChildComponentViewArgs>(childComponentView, index));
56
+ if (m_builder && m_builder->MountChildComponentViewHandler()) {
57
+ m_builder->MountChildComponentViewHandler()(
58
+ *this, winrt::make<MountChildComponentViewArgs>(childComponentView, index));
57
59
  }
58
60
  if (m_mounted) {
59
61
  winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(childComponentView)->onMounted();
60
62
  }
61
63
  }
62
64
 
63
- void ComponentView::MountChildComponentViewHandler(const MountChildComponentViewDelegate &handler) noexcept {
64
- m_mountChildComponentViewHandler = handler;
65
- }
66
-
67
65
  void ComponentView::onMounted() noexcept {
68
66
  assert(!m_mounted);
69
67
  m_mounted = true;
@@ -73,6 +71,10 @@ void ComponentView::onMounted() noexcept {
73
71
  m_mountedEvent(*this, *this);
74
72
  }
75
73
 
74
+ bool ComponentView::isMounted() noexcept {
75
+ return m_mounted;
76
+ }
77
+
76
78
  winrt::event_token ComponentView::Mounted(
77
79
  winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::ComponentView> const &handler) noexcept {
78
80
  return m_mountedEvent.add(handler);
@@ -85,16 +87,14 @@ void ComponentView::Mounted(winrt::event_token const &token) noexcept {
85
87
  void ComponentView::UnmountChildComponentView(
86
88
  const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
87
89
  uint32_t index) noexcept {
88
- if (m_mountChildComponentViewHandler) {
89
- m_mountChildComponentViewHandler(*this, winrt::make<MountChildComponentViewArgs>(childComponentView, index));
90
+ if (m_builder && m_builder->UnmountChildComponentViewHandler()) {
91
+ m_builder->UnmountChildComponentViewHandler()(
92
+ *this, winrt::make<UnmountChildComponentViewArgs>(childComponentView, index));
90
93
  }
91
94
  m_children.RemoveAt(index);
92
95
  winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(childComponentView)->parent(nullptr);
93
96
  winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(childComponentView)->onUnmounted();
94
97
  }
95
- void ComponentView::UnmountChildComponentViewHandler(const UnmountChildComponentViewDelegate &handler) noexcept {
96
- m_unmountChildComponentViewHandler = handler;
97
- }
98
98
 
99
99
  void ComponentView::onUnmounted() noexcept {
100
100
  if (!m_mounted)
@@ -144,15 +144,11 @@ uint32_t UnmountChildComponentViewArgs::Index() const noexcept {
144
144
  void ComponentView::updateProps(
145
145
  facebook::react::Props::Shared const &props,
146
146
  facebook::react::Props::Shared const &oldProps) noexcept {
147
- if (m_updatePropsDelegate) {
148
- m_updatePropsDelegate(*this, userProps(props), oldProps ? userProps(oldProps) : nullptr);
147
+ if (m_builder && m_builder->UpdatePropsHandler()) {
148
+ m_builder->UpdatePropsHandler()(*this, userProps(props), oldProps ? userProps(oldProps) : nullptr);
149
149
  }
150
150
  }
151
151
 
152
- void ComponentView::UpdatePropsHandler(const UpdatePropsDelegate &handler) noexcept {
153
- m_updatePropsDelegate = handler;
154
- }
155
-
156
152
  const winrt::Microsoft::ReactNative::IComponentProps ComponentView::userProps(
157
153
  facebook::react::Props::Shared const &props) noexcept {
158
154
  const auto &abiProps =
@@ -161,28 +157,20 @@ const winrt::Microsoft::ReactNative::IComponentProps ComponentView::userProps(
161
157
  }
162
158
 
163
159
  void ComponentView::updateEventEmitter(facebook::react::EventEmitter::Shared const &eventEmitter) noexcept {
164
- if (m_updateEventEmitterHandler) {
165
- m_updateEventEmitterHandler(*this, winrt::make<EventEmitter>(eventEmitter));
160
+ if (m_builder && m_builder->UpdateEventEmitterHandler()) {
161
+ m_builder->UpdateEventEmitterHandler()(*this, winrt::make<EventEmitter>(eventEmitter));
166
162
  }
167
163
  }
168
164
 
169
- void ComponentView::UpdateEventEmitterHandler(const UpdateEventEmitterDelegate &handler) noexcept {
170
- m_updateEventEmitterHandler = handler;
171
- }
172
-
173
165
  void ComponentView::updateState(
174
166
  facebook::react::State::Shared const &state,
175
167
  facebook::react::State::Shared const &oldState) noexcept {
176
168
  // Avoid new-ing up a new AbiComponentState on every state change if we are not a custom component
177
- if (m_updateStateDelegate) {
178
- m_updateStateDelegate(*this, winrt::make<::Microsoft::ReactNative::AbiComponentState>(state));
169
+ if (m_builder && m_builder->UpdateStateHandler()) {
170
+ m_builder->UpdateStateHandler()(*this, winrt::make<::Microsoft::ReactNative::AbiComponentState>(state));
179
171
  }
180
172
  }
181
173
 
182
- void ComponentView::UpdateStateHandler(const UpdateStateDelegate &handler) noexcept {
183
- m_updateStateDelegate = handler;
184
- }
185
-
186
174
  LayoutMetricsChangedArgs::LayoutMetricsChangedArgs(
187
175
  const winrt::Microsoft::ReactNative::LayoutMetrics &newLayoutMetrics,
188
176
  const winrt::Microsoft::ReactNative::LayoutMetrics &oldLayoutMetrics)
@@ -212,6 +200,10 @@ void ComponentView::updateLayoutMetrics(
212
200
  layoutMetrics.frame.size.height},
213
201
  layoutMetrics.pointScaleFactor};
214
202
 
203
+ if (m_builder && m_builder->UpdateLayoutMetricsHandler()) {
204
+ m_builder->UpdateLayoutMetricsHandler()(*this, newMetrics, oldMetrics);
205
+ }
206
+
215
207
  m_layoutMetrics = layoutMetrics;
216
208
 
217
209
  m_layoutMetricsChangedEvent(*this, winrt::make<LayoutMetricsChangedArgs>(newMetrics, oldMetrics));
@@ -236,13 +228,9 @@ void ComponentView::LayoutMetricsChanged(winrt::event_token const &token) noexce
236
228
  m_layoutMetricsChangedEvent.remove(token);
237
229
  }
238
230
 
239
- void ComponentView::FinalizeUpdateHandler(const UpdateFinalizerDelegate &handler) noexcept {
240
- m_finalizeUpdateHandler = handler;
241
- }
242
-
243
231
  void ComponentView::FinalizeUpdates(winrt::Microsoft::ReactNative::ComponentViewUpdateMask updateMask) noexcept {
244
- if (m_finalizeUpdateHandler) {
245
- m_finalizeUpdateHandler(*this, updateMask);
232
+ if (m_builder && m_builder->FinalizeUpdateHandler()) {
233
+ m_builder->FinalizeUpdateHandler()(*this, updateMask);
246
234
  }
247
235
  }
248
236
 
@@ -253,13 +241,9 @@ facebook::react::Props::Shared ComponentView::props() noexcept {
253
241
  return {};
254
242
  }
255
243
 
256
- void ComponentView::CustomCommandHandler(const HandleCommandDelegate &handler) noexcept {
257
- m_customCommandHandler = handler;
258
- }
259
-
260
244
  void ComponentView::HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept {
261
- if (m_customCommandHandler) {
262
- m_customCommandHandler(*this, args);
245
+ if (m_builder && m_builder->CustomCommandHandler()) {
246
+ m_builder->CustomCommandHandler()(*this, args);
263
247
  }
264
248
  }
265
249
 
@@ -342,10 +326,13 @@ bool ComponentView::runOnChildren(
342
326
  return true;
343
327
  }
344
328
  } else {
345
- // TODO is this conversion from rend correct?
346
- for (auto it = m_children.end(); it != m_children.begin(); --it) {
347
- if (fn(*winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(*it)))
348
- return true;
329
+ if (m_children.Size()) {
330
+ auto it = m_children.end();
331
+ do {
332
+ it--;
333
+ if (fn(*winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(*it)))
334
+ return true;
335
+ } while (it != m_children.begin());
349
336
  }
350
337
  }
351
338
  return false;
@@ -356,6 +343,14 @@ RECT ComponentView::getClientRect() const noexcept {
356
343
  return {};
357
344
  }
358
345
 
346
+ winrt::Windows::Foundation::Point ComponentView::ScreenToLocal(winrt::Windows::Foundation::Point pt) noexcept {
347
+ return rootComponentView()->ConvertScreenToLocal(pt);
348
+ }
349
+
350
+ winrt::Windows::Foundation::Point ComponentView::LocalToScreen(winrt::Windows::Foundation::Point pt) noexcept {
351
+ return rootComponentView()->ConvertLocalToScreen(pt);
352
+ }
353
+
359
354
  // The offset from this elements parent to its children (accounts for things like scroll position)
360
355
  facebook::react::Point ComponentView::getClientOffset() const noexcept {
361
356
  assert(false);