react-native-windows 0.74.25 → 0.74.27
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.
- package/Libraries/Modal/Modal.windows.js +352 -0
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +26 -46
- package/Microsoft.ReactNative/Fabric/ComponentView.h +6 -19
- package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.cpp +5 -0
- package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.h +4 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +164 -3
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +7 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +205 -101
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +21 -13
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +9 -2
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +2 -1
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +59 -9
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +2 -0
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +78 -30
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +21 -1
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +10 -0
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +3 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +14 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +4 -0
- package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp +1 -1
- package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +25 -0
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/codegen/NativeAccessibilityInfoSpec.g.h +1 -0
- package/codegen/NativeAccessibilityManagerSpec.g.h +1 -0
- package/codegen/NativeActionSheetManagerSpec.g.h +1 -0
- package/codegen/NativeAlertManagerSpec.g.h +1 -0
- package/codegen/NativeAnimatedModuleSpec.g.h +1 -0
- package/codegen/NativeAnimatedTurboModuleSpec.g.h +1 -0
- package/codegen/NativeAnimationsDebugModuleSpec.g.h +1 -0
- package/codegen/NativeAppStateSpec.g.h +1 -0
- package/codegen/NativeAppThemeSpec.g.h +1 -0
- package/codegen/NativeAppearanceSpec.g.h +1 -0
- package/codegen/NativeBlobModuleSpec.g.h +1 -0
- package/codegen/NativeBugReportingSpec.g.h +1 -0
- package/codegen/NativeClipboardSpec.g.h +1 -0
- package/codegen/NativeDevLoadingViewSpec.g.h +1 -0
- package/codegen/NativeDevMenuSpec.g.h +1 -0
- package/codegen/NativeDevSettingsSpec.g.h +1 -0
- package/codegen/NativeDevToolsSettingsManagerSpec.g.h +1 -0
- package/codegen/NativeDeviceEventManagerSpec.g.h +1 -0
- package/codegen/NativeDeviceInfoSpec.g.h +1 -0
- package/codegen/NativeDialogManagerAndroidSpec.g.h +1 -0
- package/codegen/NativeDialogManagerWindowsSpec.g.h +1 -0
- package/codegen/NativeExceptionsManagerSpec.g.h +1 -0
- package/codegen/NativeFileReaderModuleSpec.g.h +1 -0
- package/codegen/NativeFrameRateLoggerSpec.g.h +1 -0
- package/codegen/NativeHeadlessJsTaskSupportSpec.g.h +1 -0
- package/codegen/NativeI18nManagerSpec.g.h +1 -0
- package/codegen/NativeImageEditorSpec.g.h +1 -0
- package/codegen/NativeImageLoaderAndroidSpec.g.h +1 -0
- package/codegen/NativeImageLoaderIOSSpec.g.h +1 -0
- package/codegen/NativeImageStoreAndroidSpec.g.h +1 -0
- package/codegen/NativeImageStoreIOSSpec.g.h +1 -0
- package/codegen/NativeIntentAndroidSpec.g.h +1 -0
- package/codegen/NativeIntersectionObserverSpec.g.h +1 -0
- package/codegen/NativeJSCHeapCaptureSpec.g.h +1 -0
- package/codegen/NativeJSCSamplingProfilerSpec.g.h +1 -0
- package/codegen/NativeKeyboardObserverSpec.g.h +1 -0
- package/codegen/NativeLinkingManagerSpec.g.h +1 -0
- package/codegen/NativeLogBoxSpec.g.h +1 -0
- package/codegen/NativeModalManagerSpec.g.h +1 -0
- package/codegen/NativeMutationObserverSpec.g.h +1 -0
- package/codegen/NativeNetworkingAndroidSpec.g.h +1 -0
- package/codegen/NativeNetworkingIOSSpec.g.h +1 -0
- package/codegen/NativePerformanceObserverSpec.g.h +1 -0
- package/codegen/NativePerformanceSpec.g.h +1 -0
- package/codegen/NativePermissionsAndroidSpec.g.h +1 -0
- package/codegen/NativePlatformConstantsAndroidSpec.g.h +1 -0
- package/codegen/NativePlatformConstantsIOSSpec.g.h +1 -0
- package/codegen/NativePlatformConstantsWinSpec.g.h +1 -0
- package/codegen/NativePushNotificationManagerIOSSpec.g.h +1 -0
- package/codegen/NativeReactNativeFeatureFlagsSpec.g.h +1 -0
- package/codegen/NativeRedBoxSpec.g.h +1 -0
- package/codegen/NativeSampleTurboModuleSpec.g.h +1 -0
- package/codegen/NativeSegmentFetcherSpec.g.h +1 -0
- package/codegen/NativeSettingsManagerSpec.g.h +1 -0
- package/codegen/NativeShareModuleSpec.g.h +1 -0
- package/codegen/NativeSoundManagerSpec.g.h +1 -0
- package/codegen/NativeSourceCodeSpec.g.h +1 -0
- package/codegen/NativeStatusBarManagerAndroidSpec.g.h +1 -0
- package/codegen/NativeStatusBarManagerIOSSpec.g.h +1 -0
- package/codegen/NativeTimingSpec.g.h +1 -0
- package/codegen/NativeToastAndroidSpec.g.h +1 -0
- package/codegen/NativeUIManagerSpec.g.h +1 -0
- package/codegen/NativeVibrationSpec.g.h +1 -0
- package/codegen/NativeWebSocketModuleSpec.g.h +1 -0
- package/package.json +3 -3
|
@@ -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,11 +22,12 @@ struct RootComponentView;
|
|
|
22
22
|
|
|
23
23
|
namespace winrt::Microsoft::ReactNative::implementation {
|
|
24
24
|
|
|
25
|
-
ComponentView::ComponentView(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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 (
|
|
56
|
-
|
|
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;
|
|
@@ -89,16 +87,14 @@ void ComponentView::Mounted(winrt::event_token const &token) noexcept {
|
|
|
89
87
|
void ComponentView::UnmountChildComponentView(
|
|
90
88
|
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
|
|
91
89
|
uint32_t index) noexcept {
|
|
92
|
-
if (
|
|
93
|
-
|
|
90
|
+
if (m_builder && m_builder->UnmountChildComponentViewHandler()) {
|
|
91
|
+
m_builder->UnmountChildComponentViewHandler()(
|
|
92
|
+
*this, winrt::make<UnmountChildComponentViewArgs>(childComponentView, index));
|
|
94
93
|
}
|
|
95
94
|
m_children.RemoveAt(index);
|
|
96
95
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(childComponentView)->parent(nullptr);
|
|
97
96
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(childComponentView)->onUnmounted();
|
|
98
97
|
}
|
|
99
|
-
void ComponentView::UnmountChildComponentViewHandler(const UnmountChildComponentViewDelegate &handler) noexcept {
|
|
100
|
-
m_unmountChildComponentViewHandler = handler;
|
|
101
|
-
}
|
|
102
98
|
|
|
103
99
|
void ComponentView::onUnmounted() noexcept {
|
|
104
100
|
if (!m_mounted)
|
|
@@ -148,15 +144,11 @@ uint32_t UnmountChildComponentViewArgs::Index() const noexcept {
|
|
|
148
144
|
void ComponentView::updateProps(
|
|
149
145
|
facebook::react::Props::Shared const &props,
|
|
150
146
|
facebook::react::Props::Shared const &oldProps) noexcept {
|
|
151
|
-
if (
|
|
152
|
-
|
|
147
|
+
if (m_builder && m_builder->UpdatePropsHandler()) {
|
|
148
|
+
m_builder->UpdatePropsHandler()(*this, userProps(props), oldProps ? userProps(oldProps) : nullptr);
|
|
153
149
|
}
|
|
154
150
|
}
|
|
155
151
|
|
|
156
|
-
void ComponentView::UpdatePropsHandler(const UpdatePropsDelegate &handler) noexcept {
|
|
157
|
-
m_updatePropsDelegate = handler;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
152
|
const winrt::Microsoft::ReactNative::IComponentProps ComponentView::userProps(
|
|
161
153
|
facebook::react::Props::Shared const &props) noexcept {
|
|
162
154
|
const auto &abiProps =
|
|
@@ -165,28 +157,20 @@ const winrt::Microsoft::ReactNative::IComponentProps ComponentView::userProps(
|
|
|
165
157
|
}
|
|
166
158
|
|
|
167
159
|
void ComponentView::updateEventEmitter(facebook::react::EventEmitter::Shared const &eventEmitter) noexcept {
|
|
168
|
-
if (
|
|
169
|
-
|
|
160
|
+
if (m_builder && m_builder->UpdateEventEmitterHandler()) {
|
|
161
|
+
m_builder->UpdateEventEmitterHandler()(*this, winrt::make<EventEmitter>(eventEmitter));
|
|
170
162
|
}
|
|
171
163
|
}
|
|
172
164
|
|
|
173
|
-
void ComponentView::UpdateEventEmitterHandler(const UpdateEventEmitterDelegate &handler) noexcept {
|
|
174
|
-
m_updateEventEmitterHandler = handler;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
165
|
void ComponentView::updateState(
|
|
178
166
|
facebook::react::State::Shared const &state,
|
|
179
167
|
facebook::react::State::Shared const &oldState) noexcept {
|
|
180
168
|
// Avoid new-ing up a new AbiComponentState on every state change if we are not a custom component
|
|
181
|
-
if (
|
|
182
|
-
|
|
169
|
+
if (m_builder && m_builder->UpdateStateHandler()) {
|
|
170
|
+
m_builder->UpdateStateHandler()(*this, winrt::make<::Microsoft::ReactNative::AbiComponentState>(state));
|
|
183
171
|
}
|
|
184
172
|
}
|
|
185
173
|
|
|
186
|
-
void ComponentView::UpdateStateHandler(const UpdateStateDelegate &handler) noexcept {
|
|
187
|
-
m_updateStateDelegate = handler;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
174
|
LayoutMetricsChangedArgs::LayoutMetricsChangedArgs(
|
|
191
175
|
const winrt::Microsoft::ReactNative::LayoutMetrics &newLayoutMetrics,
|
|
192
176
|
const winrt::Microsoft::ReactNative::LayoutMetrics &oldLayoutMetrics)
|
|
@@ -216,6 +200,10 @@ void ComponentView::updateLayoutMetrics(
|
|
|
216
200
|
layoutMetrics.frame.size.height},
|
|
217
201
|
layoutMetrics.pointScaleFactor};
|
|
218
202
|
|
|
203
|
+
if (m_builder && m_builder->UpdateLayoutMetricsHandler()) {
|
|
204
|
+
m_builder->UpdateLayoutMetricsHandler()(*this, newMetrics, oldMetrics);
|
|
205
|
+
}
|
|
206
|
+
|
|
219
207
|
m_layoutMetrics = layoutMetrics;
|
|
220
208
|
|
|
221
209
|
m_layoutMetricsChangedEvent(*this, winrt::make<LayoutMetricsChangedArgs>(newMetrics, oldMetrics));
|
|
@@ -240,13 +228,9 @@ void ComponentView::LayoutMetricsChanged(winrt::event_token const &token) noexce
|
|
|
240
228
|
m_layoutMetricsChangedEvent.remove(token);
|
|
241
229
|
}
|
|
242
230
|
|
|
243
|
-
void ComponentView::FinalizeUpdateHandler(const UpdateFinalizerDelegate &handler) noexcept {
|
|
244
|
-
m_finalizeUpdateHandler = handler;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
231
|
void ComponentView::FinalizeUpdates(winrt::Microsoft::ReactNative::ComponentViewUpdateMask updateMask) noexcept {
|
|
248
|
-
if (
|
|
249
|
-
|
|
232
|
+
if (m_builder && m_builder->FinalizeUpdateHandler()) {
|
|
233
|
+
m_builder->FinalizeUpdateHandler()(*this, updateMask);
|
|
250
234
|
}
|
|
251
235
|
}
|
|
252
236
|
|
|
@@ -257,13 +241,9 @@ facebook::react::Props::Shared ComponentView::props() noexcept {
|
|
|
257
241
|
return {};
|
|
258
242
|
}
|
|
259
243
|
|
|
260
|
-
void ComponentView::CustomCommandHandler(const HandleCommandDelegate &handler) noexcept {
|
|
261
|
-
m_customCommandHandler = handler;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
244
|
void ComponentView::HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept {
|
|
265
|
-
if (
|
|
266
|
-
|
|
245
|
+
if (m_builder && m_builder->CustomCommandHandler()) {
|
|
246
|
+
m_builder->CustomCommandHandler()(*this, args);
|
|
267
247
|
}
|
|
268
248
|
}
|
|
269
249
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
#include <react/renderer/core/LayoutMetrics.h>
|
|
13
13
|
|
|
14
14
|
#include <ComponentView.Experimental.interop.h>
|
|
15
|
+
#include <Fabric/Composition/ReactCompositionViewComponentBuilder.h>
|
|
15
16
|
#include <Fabric/Composition/Theme.h>
|
|
16
17
|
#include <uiautomationcore.h>
|
|
17
18
|
#include <winrt/Microsoft.ReactNative.Composition.Input.h>
|
|
@@ -80,7 +81,10 @@ struct UnmountChildComponentViewArgs : public UnmountChildComponentViewArgsT<Unm
|
|
|
80
81
|
|
|
81
82
|
struct ComponentView
|
|
82
83
|
: public ComponentViewT<ComponentView, ::Microsoft::ReactNative::Composition::Experimental::IComponentViewInterop> {
|
|
83
|
-
ComponentView(
|
|
84
|
+
ComponentView(
|
|
85
|
+
facebook::react::Tag tag,
|
|
86
|
+
winrt::Microsoft::ReactNative::ReactContext const &reactContext,
|
|
87
|
+
winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder *builder);
|
|
84
88
|
|
|
85
89
|
virtual std::vector<facebook::react::ComponentDescriptorProvider> supplementalComponentDescriptorProviders() noexcept;
|
|
86
90
|
virtual void updateProps(
|
|
@@ -115,7 +119,6 @@ struct ComponentView
|
|
|
115
119
|
virtual void onGettingFocus(const winrt::Microsoft::ReactNative::GettingFocusEventArgs &args) noexcept;
|
|
116
120
|
virtual void onLostFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept;
|
|
117
121
|
virtual void onGotFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept;
|
|
118
|
-
void MarkAsCustomComponent() noexcept;
|
|
119
122
|
virtual void onMounted() noexcept;
|
|
120
123
|
bool isMounted() noexcept;
|
|
121
124
|
virtual void onUnmounted() noexcept;
|
|
@@ -223,14 +226,6 @@ struct ComponentView
|
|
|
223
226
|
void UserData(const winrt::IInspectable &userData) noexcept;
|
|
224
227
|
winrt::IInspectable UserData() const noexcept;
|
|
225
228
|
|
|
226
|
-
void CustomCommandHandler(const HandleCommandDelegate &handler) noexcept;
|
|
227
|
-
void UpdatePropsHandler(const UpdatePropsDelegate &handler) noexcept;
|
|
228
|
-
void UpdateStateHandler(const UpdateStateDelegate &handler) noexcept;
|
|
229
|
-
void UpdateEventEmitterHandler(const UpdateEventEmitterDelegate &handler) noexcept;
|
|
230
|
-
void MountChildComponentViewHandler(const MountChildComponentViewDelegate &handler) noexcept;
|
|
231
|
-
void UnmountChildComponentViewHandler(const UnmountChildComponentViewDelegate &handler) noexcept;
|
|
232
|
-
void FinalizeUpdateHandler(const UpdateFinalizerDelegate &handler) noexcept;
|
|
233
|
-
|
|
234
229
|
virtual void MountChildComponentView(
|
|
235
230
|
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
|
|
236
231
|
uint32_t index) noexcept;
|
|
@@ -258,7 +253,7 @@ struct ComponentView
|
|
|
258
253
|
const winrt::Microsoft::ReactNative::Composition::Input::CharacterReceivedRoutedEventArgs &args) noexcept;
|
|
259
254
|
|
|
260
255
|
protected:
|
|
261
|
-
|
|
256
|
+
winrt::com_ptr<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder> m_builder;
|
|
262
257
|
bool m_mounted : 1 {false};
|
|
263
258
|
const facebook::react::Tag m_tag;
|
|
264
259
|
winrt::IInspectable m_userData;
|
|
@@ -270,14 +265,6 @@ struct ComponentView
|
|
|
270
265
|
winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::ReactNative::ComponentView> m_children{
|
|
271
266
|
winrt::single_threaded_vector<winrt::Microsoft::ReactNative::ComponentView>()};
|
|
272
267
|
|
|
273
|
-
UpdatePropsDelegate m_updatePropsDelegate{nullptr};
|
|
274
|
-
UpdateStateDelegate m_updateStateDelegate{nullptr};
|
|
275
|
-
HandleCommandDelegate m_customCommandHandler{nullptr};
|
|
276
|
-
UpdateFinalizerDelegate m_finalizeUpdateHandler{nullptr};
|
|
277
|
-
MountChildComponentViewDelegate m_mountChildComponentViewHandler{nullptr};
|
|
278
|
-
UnmountChildComponentViewDelegate m_unmountChildComponentViewHandler{nullptr};
|
|
279
|
-
UpdateEventEmitterDelegate m_updateEventEmitterHandler{nullptr};
|
|
280
|
-
|
|
281
268
|
winrt::event<
|
|
282
269
|
winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs>>
|
|
283
270
|
m_keyDownEvent;
|
|
@@ -818,6 +818,11 @@ uint8_t BorderPrimitive::numberOfVisuals() const noexcept {
|
|
|
818
818
|
return m_numBorderVisuals;
|
|
819
819
|
}
|
|
820
820
|
|
|
821
|
+
void BorderPrimitive::setOuter(
|
|
822
|
+
winrt::Microsoft::ReactNative::Composition::implementation::ComponentView *outer) noexcept {
|
|
823
|
+
m_outer = outer;
|
|
824
|
+
}
|
|
825
|
+
|
|
821
826
|
bool BorderPrimitive::TryUpdateSpecialBorderLayers(
|
|
822
827
|
winrt::Microsoft::ReactNative::Composition::implementation::Theme *theme,
|
|
823
828
|
std::array<winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual, SpecialBorderLayerCount>
|
|
@@ -29,6 +29,10 @@ struct BorderPrimitive {
|
|
|
29
29
|
|
|
30
30
|
void markNeedsUpdate() noexcept;
|
|
31
31
|
|
|
32
|
+
// We hoist focus visuals up the tree to allow them to be higher in the z-order.
|
|
33
|
+
// This means a single BorderPrimitive may change the owning ComponentView as focus moves around
|
|
34
|
+
void setOuter(winrt::Microsoft::ReactNative::Composition::implementation::ComponentView *outer) noexcept;
|
|
35
|
+
|
|
32
36
|
void updateProps(
|
|
33
37
|
const facebook::react::ViewProps &oldViewProps,
|
|
34
38
|
const facebook::react::ViewProps &newViewProps) noexcept;
|