@office-iss/react-native-win32 0.75.2 → 0.76.0-preview.1

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 (174) hide show
  1. package/.eslintrc.js +11 -0
  2. package/.flowconfig +5 -4
  3. package/CHANGELOG.json +164 -47
  4. package/CHANGELOG.md +53 -28
  5. package/Libraries/Alert/Alert.js +3 -0
  6. package/Libraries/Animated/AnimatedEvent.js +1 -1
  7. package/Libraries/Animated/AnimatedImplementation.js +7 -7
  8. package/Libraries/Animated/NativeAnimatedAllowlist.js +111 -0
  9. package/Libraries/Animated/animations/Animation.js +11 -1
  10. package/Libraries/Animated/animations/DecayAnimation.js +1 -1
  11. package/Libraries/Animated/animations/SpringAnimation.js +1 -1
  12. package/Libraries/Animated/animations/TimingAnimation.js +2 -1
  13. package/Libraries/Animated/components/AnimatedScrollView.js +3 -2
  14. package/Libraries/Animated/createAnimatedComponent.js +10 -9
  15. package/Libraries/Animated/nodes/AnimatedColor.js +1 -1
  16. package/Libraries/Animated/nodes/AnimatedInterpolation.js +3 -2
  17. package/Libraries/Animated/nodes/AnimatedNode.js +42 -33
  18. package/Libraries/Animated/nodes/AnimatedObject.js +56 -50
  19. package/Libraries/Animated/nodes/AnimatedProps.js +77 -40
  20. package/Libraries/Animated/nodes/AnimatedStyle.js +103 -59
  21. package/Libraries/Animated/nodes/AnimatedTracking.js +1 -1
  22. package/Libraries/Animated/nodes/AnimatedTransform.js +102 -67
  23. package/Libraries/Animated/nodes/AnimatedValue.js +2 -1
  24. package/Libraries/Animated/nodes/AnimatedWithChildren.js +21 -22
  25. package/Libraries/Animated/useAnimatedProps.js +142 -7
  26. package/Libraries/BatchedBridge/NativeModules.js +2 -0
  27. package/Libraries/Blob/FileReader.js +1 -1
  28. package/Libraries/Blob/URL.js +2 -62
  29. package/Libraries/Blob/URLSearchParams.js +71 -0
  30. package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js +1 -1
  31. package/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js +1 -1
  32. package/Libraries/Components/ScrollView/ScrollView.js +131 -169
  33. package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +1 -1
  34. package/Libraries/Components/StatusBar/StatusBar.js +3 -1
  35. package/Libraries/Components/TextInput/TextInput.d.ts +32 -2
  36. package/Libraries/Components/TextInput/TextInput.js +230 -94
  37. package/Libraries/Components/TextInput/TextInput.win32.js +230 -100
  38. package/Libraries/Components/View/ReactNativeStyleAttributes.js +22 -0
  39. package/Libraries/Components/View/ReactNativeViewAttributes.js +2 -0
  40. package/Libraries/Components/View/ReactNativeViewAttributes.win32.js +2 -0
  41. package/Libraries/Components/View/ViewAccessibility.d.ts +15 -0
  42. package/Libraries/Components/View/ViewNativeComponent.js +0 -1
  43. package/Libraries/Components/View/ViewPropTypes.js +14 -0
  44. package/Libraries/Components/View/ViewPropTypes.win32.js +14 -0
  45. package/Libraries/Core/ExceptionsManager.js +2 -0
  46. package/Libraries/Core/InitializeCore.js +3 -1
  47. package/Libraries/Core/ReactFiberErrorDialog.js +3 -0
  48. package/Libraries/Core/ReactNativeVersion.js +4 -4
  49. package/Libraries/Core/ReactNativeVersionCheck.win32.js +1 -1
  50. package/Libraries/Core/setUpErrorHandling.js +7 -1
  51. package/Libraries/Core/setUpGlobals.js +1 -0
  52. package/Libraries/Core/setUpReactRefresh.js +0 -4
  53. package/Libraries/Image/AssetSourceResolver.js +28 -1
  54. package/Libraries/Image/Image.android.js +9 -14
  55. package/Libraries/Image/Image.ios.js +11 -22
  56. package/Libraries/Image/Image.win32.js +11 -24
  57. package/Libraries/Image/ImageBackground.js +1 -8
  58. package/Libraries/Image/ImageUtils.js +9 -9
  59. package/Libraries/Image/ImageViewNativeComponent.js +1 -0
  60. package/Libraries/Inspector/Inspector.js +3 -2
  61. package/Libraries/Inspector/Inspector.win32.js +3 -2
  62. package/Libraries/Inspector/InspectorPanel.js +16 -10
  63. package/Libraries/Inspector/NetworkOverlay.js +1 -1
  64. package/Libraries/Interaction/TaskQueue.js +1 -0
  65. package/Libraries/Lists/FlatList.js +1 -1
  66. package/Libraries/Lists/SectionList.js +2 -2
  67. package/Libraries/Lists/SectionListModern.js +3 -3
  68. package/Libraries/LogBox/Data/LogBoxData.js +24 -3
  69. package/Libraries/LogBox/LogBoxNotificationContainer.js +3 -2
  70. package/Libraries/LogBox/UI/LogBoxInspectorHeader.js +9 -8
  71. package/Libraries/LogBox/UI/LogBoxInspectorHeader.win32.js +9 -29
  72. package/Libraries/Modal/Modal.js +0 -1
  73. package/Libraries/NativeComponent/BaseViewConfig.android.js +8 -0
  74. package/Libraries/NativeComponent/BaseViewConfig.ios.js +7 -0
  75. package/Libraries/NativeComponent/BaseViewConfig.win32.js +7 -0
  76. package/Libraries/NativeComponent/NativeComponentRegistry.js +22 -22
  77. package/Libraries/NativeComponent/StaticViewConfigValidator.js +0 -21
  78. package/Libraries/Network/XMLHttpRequest.js +4 -2
  79. package/Libraries/ReactNative/AppContainer-dev.js +1 -5
  80. package/Libraries/ReactNative/AppContainer-prod.js +1 -5
  81. package/Libraries/ReactNative/AppContainer.js +0 -1
  82. package/Libraries/ReactNative/AppRegistry.js +0 -6
  83. package/Libraries/ReactNative/BridgelessUIManager.js +1 -0
  84. package/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricHostComponent.js +1 -1
  85. package/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstance.js +5 -5
  86. package/Libraries/ReactNative/RendererImplementation.js +26 -4
  87. package/Libraries/ReactNative/getNativeComponentAttributes.js +8 -0
  88. package/Libraries/ReactNative/renderApplication.js +0 -2
  89. package/Libraries/Renderer/shims/ReactNativeTypes.js +11 -4
  90. package/Libraries/StyleSheet/StyleSheet.js +1 -1
  91. package/Libraries/StyleSheet/StyleSheet.win32.js +1 -1
  92. package/Libraries/StyleSheet/StyleSheetTypes.d.ts +57 -0
  93. package/Libraries/StyleSheet/StyleSheetTypes.js +60 -5
  94. package/Libraries/StyleSheet/processBackgroundImage.js +384 -0
  95. package/Libraries/StyleSheet/processBoxShadow.js +211 -0
  96. package/Libraries/StyleSheet/processFilter.js +231 -42
  97. package/Libraries/Text/Text.js +394 -196
  98. package/Libraries/Text/Text.win32.js +442 -229
  99. package/Libraries/Text/TextNativeComponent.js +2 -1
  100. package/Libraries/Text/TextNativeComponent.win32.js +1 -1
  101. package/Libraries/TurboModule/TurboModuleRegistry.js +13 -50
  102. package/Libraries/Types/CodegenTypes.js +3 -1
  103. package/Libraries/Utilities/Appearance.js +108 -84
  104. package/Libraries/Utilities/DevLoadingView.js +2 -4
  105. package/Libraries/Utilities/HMRClient.js +2 -1
  106. package/Libraries/Utilities/ReactNativeTestTools.js +1 -1
  107. package/Libraries/Utilities/createPerformanceLogger.js +0 -9
  108. package/Libraries/Utilities/stringifyViewConfig.js +22 -0
  109. package/Libraries/Utilities/useColorScheme.js +3 -3
  110. package/Libraries/WebSocket/WebSocket.js +1 -1
  111. package/Libraries/promiseRejectionTrackingOptions.js +1 -1
  112. package/Libraries/vendor/emitter/EventEmitter.js +6 -5
  113. package/flow/jest.js +2 -2
  114. package/index.js +3 -1
  115. package/index.win32.js +3 -1
  116. package/jest/mockComponent.js +4 -1
  117. package/jest/mockModal.js +1 -3
  118. package/jest/mockScrollView.js +1 -1
  119. package/jest/renderer.js +2 -2
  120. package/jest/setup.js +16 -13
  121. package/jest.config.js +1 -2
  122. package/overrides.json +22 -22
  123. package/package.json +30 -30
  124. package/src/private/animated/NativeAnimatedHelper.js +438 -0
  125. package/src/private/animated/NativeAnimatedHelper.win32.js +440 -0
  126. package/src/private/animated/NativeAnimatedValidation.js +64 -0
  127. package/src/private/components/HScrollViewNativeComponents.js +56 -0
  128. package/src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE.js +27 -0
  129. package/src/private/components/VScrollViewNativeComponents.js +48 -0
  130. package/src/private/components/useSyncOnScroll.js +48 -0
  131. package/src/private/featureflags/ReactNativeFeatureFlags.js +166 -16
  132. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +29 -5
  133. package/src/private/fusebox/FuseboxSessionObserver.js +42 -0
  134. package/{Libraries/Core → src/private/renderer/errorhandling}/ErrorHandlers.js +14 -4
  135. package/src/private/setup/setUpDOM.js +28 -0
  136. package/src/private/setup/setUpIntersectionObserver.js +27 -0
  137. package/src/private/setup/setUpMutationObserver.js +26 -0
  138. package/src/private/setup/setUpPerformanceObserver.js +64 -0
  139. package/src/private/specs/modules/NativeAppearance.js +3 -3
  140. package/src/private/specs/modules/NativeLinkingManager.js +1 -1
  141. package/src/private/specs/modules/NativePlatformConstantsWin.js +7 -0
  142. package/src/private/specs/modules/NativeSampleTurboModule.js +14 -1
  143. package/src/private/webapis/dom/nodes/ReadOnlyNode.js +6 -4
  144. package/{Libraries/IntersectionObserver → src/private/webapis/intersectionobserver}/IntersectionObserver.js +5 -3
  145. package/{Libraries/IntersectionObserver → src/private/webapis/intersectionobserver}/IntersectionObserverEntry.js +3 -3
  146. package/{Libraries/IntersectionObserver → src/private/webapis/intersectionobserver}/IntersectionObserverManager.js +14 -17
  147. package/src/private/{specs/modules → webapis/intersectionobserver/specs}/NativeIntersectionObserver.js +2 -2
  148. package/{Libraries/IntersectionObserver → src/private/webapis/intersectionobserver/specs}/__mocks__/NativeIntersectionObserver.js +4 -4
  149. package/{Libraries/MutationObserver → src/private/webapis/mutationobserver}/MutationObserver.js +5 -3
  150. package/{Libraries/MutationObserver → src/private/webapis/mutationobserver}/MutationObserverManager.js +24 -15
  151. package/{Libraries/MutationObserver → src/private/webapis/mutationobserver}/MutationRecord.js +4 -6
  152. package/src/private/{specs/modules → webapis/mutationobserver/specs}/NativeMutationObserver.js +2 -2
  153. package/{Libraries/MutationObserver → src/private/webapis/mutationobserver/specs}/__mocks__/NativeMutationObserver.js +5 -5
  154. package/src/private/webapis/performance/{EventCounts.js → EventTiming.js} +65 -3
  155. package/src/private/webapis/performance/LongTasks.js +39 -0
  156. package/src/private/webapis/performance/Performance.js +22 -9
  157. package/src/private/webapis/performance/PerformanceEntry.js +36 -18
  158. package/src/private/webapis/performance/PerformanceObserver.js +29 -43
  159. package/src/private/webapis/performance/RawPerformanceEntry.js +24 -1
  160. package/src/private/webapis/performance/UserTiming.js +17 -12
  161. package/src/private/webapis/performance/specs/NativePerformanceObserver.js +1 -1
  162. package/src-win/Libraries/Components/View/ViewAccessibility.d.ts +15 -0
  163. package/types/experimental.d.ts +20 -1
  164. package/Libraries/Animated/NativeAnimatedHelper.js +0 -615
  165. package/Libraries/Animated/NativeAnimatedHelper.win32.js +0 -617
  166. package/Libraries/Core/setUpIntersectionObserver.js +0 -16
  167. package/Libraries/Core/setUpMutationObserver.js +0 -16
  168. package/Libraries/Core/setUpPerformanceObserver.js +0 -18
  169. package/Libraries/IntersectionObserver/NativeIntersectionObserver.js +0 -13
  170. package/Libraries/MutationObserver/NativeMutationObserver.js +0 -13
  171. package/Libraries/Utilities/verifyComponentAttributeEquivalence.js +0 -135
  172. package/src/private/core/setUpDOM.js +0 -18
  173. package/src/private/webapis/performance/PerformanceEventTiming.js +0 -55
  174. /package/src/private/{core → styles}/composeStyles.js +0 -0
@@ -0,0 +1,440 @@
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
+ * @flow strict-local
8
+ * @format
9
+ */
10
+
11
+ import type {EventSubscription} from '../../../Libraries/vendor/emitter/EventEmitter';
12
+ import type {EventConfig} from '../../../Libraries/Animated/AnimatedEvent';
13
+ import type {
14
+ AnimationConfig,
15
+ EndCallback,
16
+ } from '../../../Libraries/Animated/animations/Animation';
17
+ import type {
18
+ AnimatedNodeConfig,
19
+ EventMapping,
20
+ } from '../../../Libraries/Animated/NativeAnimatedModule';
21
+
22
+ import * as ReactNativeFeatureFlags from '../featureflags/ReactNativeFeatureFlags';
23
+ import NativeEventEmitter from '../../../Libraries/EventEmitter/NativeEventEmitter';
24
+ import RCTDeviceEventEmitter from '../../../Libraries/EventEmitter/RCTDeviceEventEmitter';
25
+ import Platform from '../../../Libraries/Utilities/Platform';
26
+ import NativeAnimatedNonTurboModule from '../../../Libraries/Animated/NativeAnimatedModule';
27
+ import NativeAnimatedTurboModule from '../../../Libraries/Animated/NativeAnimatedTurboModule';
28
+ import invariant from 'invariant';
29
+ import nullthrows from 'nullthrows';
30
+
31
+ // TODO T69437152 @petetheheat - Delete this fork when Fabric ships to 100%.
32
+ const NativeAnimatedModule: typeof NativeAnimatedTurboModule =
33
+ NativeAnimatedNonTurboModule ?? NativeAnimatedTurboModule;
34
+
35
+ let __nativeAnimatedNodeTagCount = 1; /* used for animated nodes */
36
+ let __nativeAnimationIdCount = 1; /* used for started animations */
37
+
38
+ let nativeEventEmitter;
39
+
40
+ let waitingForQueuedOperations = new Set<string>();
41
+ let queueOperations = false;
42
+ let queue: Array<() => void> = [];
43
+ let singleOpQueue: Array<mixed> = [];
44
+
45
+ const isSingleOpBatching =
46
+ Platform.OS === 'android' &&
47
+ NativeAnimatedModule?.queueAndExecuteBatchedOperations != null &&
48
+ ReactNativeFeatureFlags.animatedShouldUseSingleOp();
49
+ let flushQueueTimeout = null;
50
+
51
+ const eventListenerGetValueCallbacks: {
52
+ [number]: (value: number) => void,
53
+ } = {};
54
+ const eventListenerAnimationFinishedCallbacks: {
55
+ [number]: EndCallback,
56
+ } = {};
57
+ let globalEventEmitterGetValueListener: ?EventSubscription = null;
58
+ let globalEventEmitterAnimationFinishedListener: ?EventSubscription = null;
59
+
60
+ function createNativeOperations(): $NonMaybeType<typeof NativeAnimatedModule> {
61
+ const methodNames = [
62
+ 'createAnimatedNode', // 1
63
+ 'updateAnimatedNodeConfig', // 2
64
+ 'getValue', // 3
65
+ 'startListeningToAnimatedNodeValue', // 4
66
+ 'stopListeningToAnimatedNodeValue', // 5
67
+ 'connectAnimatedNodes', // 6
68
+ 'disconnectAnimatedNodes', // 7
69
+ 'startAnimatingNode', // 8
70
+ 'stopAnimation', // 9
71
+ 'setAnimatedNodeValue', // 10
72
+ 'setAnimatedNodeOffset', // 11
73
+ 'flattenAnimatedNodeOffset', // 12
74
+ 'extractAnimatedNodeOffset', // 13
75
+ 'connectAnimatedNodeToView', // 14
76
+ 'disconnectAnimatedNodeFromView', // 15
77
+ 'restoreDefaultValues', // 16
78
+ 'dropAnimatedNode', // 17
79
+ 'addAnimatedEventToView', // 18
80
+ 'removeAnimatedEventFromView', // 19
81
+ 'addListener', // 20
82
+ 'removeListener', // 21
83
+ ];
84
+ const nativeOperations: {
85
+ [$Values<typeof methodNames>]: (...$ReadOnlyArray<mixed>) => void,
86
+ } = {};
87
+ if (isSingleOpBatching) {
88
+ for (let ii = 0, length = methodNames.length; ii < length; ii++) {
89
+ const methodName = methodNames[ii];
90
+ const operationID = ii + 1;
91
+ nativeOperations[methodName] = (...args) => {
92
+ // `singleOpQueue` is a flat array of operation IDs and arguments, which
93
+ // is possible because # arguments is fixed for each operation. For more
94
+ // details, see `NativeAnimatedModule.queueAndExecuteBatchedOperations`.
95
+ singleOpQueue.push(operationID, ...args);
96
+ };
97
+ }
98
+ } else {
99
+ for (let ii = 0, length = methodNames.length; ii < length; ii++) {
100
+ const methodName = methodNames[ii];
101
+ nativeOperations[methodName] = (...args) => {
102
+ const method = nullthrows(NativeAnimatedModule)[methodName];
103
+ // If queueing is explicitly on, *or* the queue has not yet
104
+ // been flushed, use the queue. This is to prevent operations
105
+ // from being executed out of order.
106
+ if (queueOperations || queue.length !== 0) {
107
+ // $FlowExpectedError[incompatible-call] - Dynamism.
108
+ queue.push(() => method(...args));
109
+ } else {
110
+ // $FlowExpectedError[incompatible-call] - Dynamism.
111
+ method(...args);
112
+ }
113
+ };
114
+ }
115
+ }
116
+ // $FlowExpectedError[incompatible-return] - Dynamism.
117
+ return nativeOperations;
118
+ }
119
+
120
+ const NativeOperations = createNativeOperations();
121
+
122
+ /**
123
+ * Wrappers around NativeAnimatedModule to provide flow and autocomplete support for
124
+ * the native module methods, and automatic queue management on Android
125
+ */
126
+ const API = {
127
+ getValue: (isSingleOpBatching
128
+ ? (tag, saveValueCallback) => {
129
+ if (saveValueCallback) {
130
+ eventListenerGetValueCallbacks[tag] = saveValueCallback;
131
+ }
132
+ /* $FlowExpectedError[incompatible-call] - `saveValueCallback` is handled
133
+ differently when `isSingleOpBatching` is enabled. */
134
+ NativeOperations.getValue(tag);
135
+ }
136
+ : (tag, saveValueCallback) => {
137
+ NativeOperations.getValue(tag, saveValueCallback);
138
+ }) as $NonMaybeType<typeof NativeAnimatedModule>['getValue'],
139
+
140
+ setWaitingForIdentifier(id: string): void {
141
+ waitingForQueuedOperations.add(id);
142
+ queueOperations = true;
143
+ if (
144
+ ReactNativeFeatureFlags.animatedShouldDebounceQueueFlush() &&
145
+ flushQueueTimeout
146
+ ) {
147
+ clearTimeout(flushQueueTimeout);
148
+ }
149
+ },
150
+
151
+ unsetWaitingForIdentifier(id: string): void {
152
+ waitingForQueuedOperations.delete(id);
153
+
154
+ if (waitingForQueuedOperations.size === 0) {
155
+ queueOperations = false;
156
+ API.disableQueue();
157
+ }
158
+ },
159
+
160
+ disableQueue(): void {
161
+ invariant(NativeAnimatedModule, 'Native animated module is not available');
162
+
163
+ if (ReactNativeFeatureFlags.animatedShouldDebounceQueueFlush()) {
164
+ const prevTimeout = flushQueueTimeout;
165
+ clearImmediate(prevTimeout);
166
+ flushQueueTimeout = setImmediate(API.flushQueue);
167
+ } else {
168
+ API.flushQueue();
169
+ }
170
+ },
171
+
172
+ flushQueue: (isSingleOpBatching
173
+ ? (): void => {
174
+ /* [Windows #11041
175
+ // TODO: (T136971132)
176
+ invariant(
177
+ NativeAnimatedModule || process.env.NODE_ENV === 'test',
178
+ 'Native animated module is not available',
179
+ );
180
+ Windows] */
181
+ flushQueueTimeout = null;
182
+
183
+ if (singleOpQueue.length === 0) {
184
+ return;
185
+ }
186
+
187
+ // Set up event listener for callbacks if it's not set up
188
+ ensureGlobalEventEmitterListeners();
189
+
190
+ // Single op batching doesn't use callback functions, instead we
191
+ // use RCTDeviceEventEmitter. This reduces overhead of sending lots of
192
+ // JSI functions across to native code; but also, TM infrastructure currently
193
+ // does not support packing a function into native arrays.
194
+ NativeAnimatedModule?.queueAndExecuteBatchedOperations?.(singleOpQueue);
195
+ singleOpQueue.length = 0;
196
+ }
197
+ : (): void => {
198
+ // TODO: (T136971132)
199
+ invariant(
200
+ NativeAnimatedModule || process.env.NODE_ENV === 'test',
201
+ 'Native animated module is not available',
202
+ );
203
+ flushQueueTimeout = null;
204
+
205
+ if (queue.length === 0) {
206
+ return;
207
+ }
208
+
209
+ if (Platform.OS === 'android') {
210
+ NativeAnimatedModule?.startOperationBatch?.();
211
+ }
212
+
213
+ for (let q = 0, l = queue.length; q < l; q++) {
214
+ queue[q]();
215
+ }
216
+ queue.length = 0;
217
+
218
+ if (Platform.OS === 'android') {
219
+ NativeAnimatedModule?.finishOperationBatch?.();
220
+ }
221
+ }) as () => void,
222
+
223
+ createAnimatedNode(tag: number, config: AnimatedNodeConfig): void {
224
+ NativeOperations.createAnimatedNode(tag, config);
225
+ },
226
+
227
+ updateAnimatedNodeConfig(tag: number, config: AnimatedNodeConfig): void {
228
+ NativeOperations.updateAnimatedNodeConfig?.(tag, config);
229
+ },
230
+
231
+ startListeningToAnimatedNodeValue(tag: number): void {
232
+ NativeOperations.startListeningToAnimatedNodeValue(tag);
233
+ },
234
+
235
+ stopListeningToAnimatedNodeValue(tag: number): void {
236
+ NativeOperations.stopListeningToAnimatedNodeValue(tag);
237
+ },
238
+
239
+ connectAnimatedNodes(parentTag: number, childTag: number): void {
240
+ NativeOperations.connectAnimatedNodes(parentTag, childTag);
241
+ },
242
+
243
+ disconnectAnimatedNodes(parentTag: number, childTag: number): void {
244
+ NativeOperations.disconnectAnimatedNodes(parentTag, childTag);
245
+ },
246
+
247
+ startAnimatingNode: (isSingleOpBatching
248
+ ? (animationId, nodeTag, config, endCallback) => {
249
+ if (endCallback) {
250
+ eventListenerAnimationFinishedCallbacks[animationId] = endCallback;
251
+ }
252
+ /* $FlowExpectedError[incompatible-call] - `endCallback` is handled
253
+ differently when `isSingleOpBatching` is enabled. */
254
+ NativeOperations.startAnimatingNode(animationId, nodeTag, config);
255
+ }
256
+ : (animationId, nodeTag, config, endCallback) => {
257
+ NativeOperations.startAnimatingNode(
258
+ animationId,
259
+ nodeTag,
260
+ config,
261
+ endCallback,
262
+ );
263
+ }) as $NonMaybeType<typeof NativeAnimatedModule>['startAnimatingNode'],
264
+
265
+ stopAnimation(animationId: number) {
266
+ NativeOperations.stopAnimation(animationId);
267
+ },
268
+
269
+ setAnimatedNodeValue(nodeTag: number, value: number): void {
270
+ NativeOperations.setAnimatedNodeValue(nodeTag, value);
271
+ },
272
+
273
+ setAnimatedNodeOffset(nodeTag: number, offset: number): void {
274
+ NativeOperations.setAnimatedNodeOffset(nodeTag, offset);
275
+ },
276
+
277
+ flattenAnimatedNodeOffset(nodeTag: number): void {
278
+ NativeOperations.flattenAnimatedNodeOffset(nodeTag);
279
+ },
280
+
281
+ extractAnimatedNodeOffset(nodeTag: number): void {
282
+ NativeOperations.extractAnimatedNodeOffset(nodeTag);
283
+ },
284
+
285
+ connectAnimatedNodeToView(nodeTag: number, viewTag: number): void {
286
+ NativeOperations.connectAnimatedNodeToView(nodeTag, viewTag);
287
+ },
288
+
289
+ disconnectAnimatedNodeFromView(nodeTag: number, viewTag: number): void {
290
+ NativeOperations.disconnectAnimatedNodeFromView(nodeTag, viewTag);
291
+ },
292
+
293
+ restoreDefaultValues(nodeTag: number): void {
294
+ NativeOperations.restoreDefaultValues?.(nodeTag);
295
+ },
296
+
297
+ dropAnimatedNode(tag: number): void {
298
+ NativeOperations.dropAnimatedNode(tag);
299
+ },
300
+
301
+ addAnimatedEventToView(
302
+ viewTag: number,
303
+ eventName: string,
304
+ eventMapping: EventMapping,
305
+ ) {
306
+ NativeOperations.addAnimatedEventToView(viewTag, eventName, eventMapping);
307
+ },
308
+
309
+ removeAnimatedEventFromView(
310
+ viewTag: number,
311
+ eventName: string,
312
+ animatedNodeTag: number,
313
+ ) {
314
+ NativeOperations.removeAnimatedEventFromView(
315
+ viewTag,
316
+ eventName,
317
+ animatedNodeTag,
318
+ );
319
+ },
320
+ };
321
+
322
+ function ensureGlobalEventEmitterListeners() {
323
+ if (
324
+ globalEventEmitterGetValueListener &&
325
+ globalEventEmitterAnimationFinishedListener
326
+ ) {
327
+ return;
328
+ }
329
+ globalEventEmitterGetValueListener = RCTDeviceEventEmitter.addListener(
330
+ 'onNativeAnimatedModuleGetValue',
331
+ params => {
332
+ const {tag} = params;
333
+ const callback = eventListenerGetValueCallbacks[tag];
334
+ if (!callback) {
335
+ return;
336
+ }
337
+ callback(params.value);
338
+ delete eventListenerGetValueCallbacks[tag];
339
+ },
340
+ );
341
+ globalEventEmitterAnimationFinishedListener =
342
+ RCTDeviceEventEmitter.addListener(
343
+ 'onNativeAnimatedModuleAnimationFinished',
344
+ params => {
345
+ // TODO: remove Array.isArray once native changes have propagated
346
+ const animations = Array.isArray(params) ? params : [params];
347
+ for (const animation of animations) {
348
+ const {animationId} = animation;
349
+ const callback = eventListenerAnimationFinishedCallbacks[animationId];
350
+ if (callback) {
351
+ callback(animation);
352
+ delete eventListenerAnimationFinishedCallbacks[animationId];
353
+ }
354
+ }
355
+ },
356
+ );
357
+ }
358
+
359
+ function generateNewNodeTag(): number {
360
+ return __nativeAnimatedNodeTagCount++;
361
+ }
362
+
363
+ function generateNewAnimationId(): number {
364
+ return __nativeAnimationIdCount++;
365
+ }
366
+
367
+ function assertNativeAnimatedModule(): void {
368
+ invariant(NativeAnimatedModule, 'Native animated module is not available');
369
+ }
370
+
371
+ let _warnedMissingNativeAnimated = false;
372
+
373
+ function shouldUseNativeDriver(
374
+ config: $ReadOnly<{...AnimationConfig, ...}> | EventConfig,
375
+ ): boolean {
376
+ if (config.useNativeDriver == null) {
377
+ console.warn(
378
+ 'Animated: `useNativeDriver` was not specified. This is a required ' +
379
+ 'option and must be explicitly set to `true` or `false`',
380
+ );
381
+ }
382
+
383
+ if (config.useNativeDriver === true && !NativeAnimatedModule) {
384
+ if (process.env.NODE_ENV !== 'test') {
385
+ if (!_warnedMissingNativeAnimated) {
386
+ console.warn(
387
+ 'Animated: `useNativeDriver` is not supported because the native ' +
388
+ 'animated module is missing. Falling back to JS-based animation. To ' +
389
+ 'resolve this, add `RCTAnimation` module to this app, or remove ' +
390
+ '`useNativeDriver`. ' +
391
+ 'Make sure to run `bundle exec pod install` first. Read more about autolinking: https://github.com/react-native-community/cli/blob/master/docs/autolinking.md',
392
+ );
393
+ _warnedMissingNativeAnimated = true;
394
+ }
395
+ }
396
+ return false;
397
+ }
398
+
399
+ return config.useNativeDriver || false;
400
+ }
401
+
402
+ function transformDataType(value: number | string): number | string {
403
+ // Change the string type to number type so we can reuse the same logic in
404
+ // iOS and Android platform
405
+ if (typeof value !== 'string') {
406
+ return value;
407
+ }
408
+
409
+ // Normalize degrees and radians to a number expressed in radians
410
+ if (value.endsWith('deg')) {
411
+ const degrees = parseFloat(value) || 0;
412
+ return (degrees * Math.PI) / 180.0;
413
+ } else if (value.endsWith('rad')) {
414
+ return parseFloat(value) || 0;
415
+ } else {
416
+ return value;
417
+ }
418
+ }
419
+
420
+ export default {
421
+ API,
422
+ generateNewNodeTag,
423
+ generateNewAnimationId,
424
+ assertNativeAnimatedModule,
425
+ shouldUseNativeDriver,
426
+ transformDataType,
427
+ // $FlowExpectedError[unsafe-getters-setters] - unsafe getter lint suppression
428
+ // $FlowExpectedError[missing-type-arg] - unsafe getter lint suppression
429
+ get nativeEventEmitter(): NativeEventEmitter {
430
+ if (!nativeEventEmitter) {
431
+ // $FlowFixMe[underconstrained-implicit-instantiation]
432
+ nativeEventEmitter = new NativeEventEmitter(
433
+ // 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
434
+ // If you want to use the native module on other platforms, please remove this condition and test its behavior
435
+ Platform.OS !== 'ios' ? null : NativeAnimatedModule,
436
+ );
437
+ }
438
+ return nativeEventEmitter;
439
+ },
440
+ };
@@ -0,0 +1,64 @@
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
+ * @flow strict-local
8
+ * @format
9
+ */
10
+
11
+ import type {InterpolationConfigType} from '../../../Libraries/Animated/nodes/AnimatedInterpolation';
12
+
13
+ import {
14
+ isSupportedInterpolationParam,
15
+ isSupportedStyleProp,
16
+ isSupportedTransformProp,
17
+ } from '../../../Libraries/Animated/NativeAnimatedAllowlist';
18
+
19
+ export function validateInterpolation<OutputT: number | string>(
20
+ config: InterpolationConfigType<OutputT>,
21
+ ): void {
22
+ for (const key in config) {
23
+ if (!isSupportedInterpolationParam(key)) {
24
+ console.error(
25
+ `Interpolation property '${key}' is not supported by native animated module`,
26
+ );
27
+ }
28
+ }
29
+ }
30
+
31
+ export function validateStyles(styles: {[key: string]: ?number, ...}): void {
32
+ for (const key in styles) {
33
+ if (!isSupportedStyleProp(key)) {
34
+ console.error(
35
+ `Style property '${key}' is not supported by native animated module`,
36
+ );
37
+ }
38
+ }
39
+ }
40
+
41
+ export function validateTransform(
42
+ configs: Array<
43
+ | {
44
+ type: 'animated',
45
+ property: string,
46
+ nodeTag: ?number,
47
+ ...
48
+ }
49
+ | {
50
+ type: 'static',
51
+ property: string,
52
+ value: number | string,
53
+ ...
54
+ },
55
+ >,
56
+ ): void {
57
+ configs.forEach(config => {
58
+ if (!isSupportedTransformProp(config.property)) {
59
+ console.error(
60
+ `Property '${config.property}' is not supported by native animated module`,
61
+ );
62
+ }
63
+ });
64
+ }
@@ -0,0 +1,56 @@
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
+ * @flow strict-local
8
+ * @format
9
+ * @oncall react_native
10
+ */
11
+
12
+ import type {ScrollViewNativeProps} from '../../../Libraries/Components/ScrollView/ScrollViewNativeComponentType';
13
+ import type {ViewProps} from '../../../Libraries/Components/View/ViewPropTypes';
14
+ import type {HostComponent} from '../../../Libraries/Renderer/shims/ReactNativeTypes';
15
+ import type {TScrollViewNativeImperativeHandle} from './useSyncOnScroll';
16
+
17
+ import AndroidHorizontalScrollViewNativeComponent from '../../../Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent';
18
+ import ScrollContentViewNativeComponent from '../../../Libraries/Components/ScrollView/ScrollContentViewNativeComponent';
19
+ import ScrollViewNativeComponent from '../../../Libraries/Components/ScrollView/ScrollViewNativeComponent';
20
+ import Platform from '../../../Libraries/Utilities/Platform';
21
+ import AndroidHorizontalScrollContentViewNativeComponent from '../specs/components/AndroidHorizontalScrollContentViewNativeComponent';
22
+ import useSyncOnScroll from './useSyncOnScroll';
23
+ import * as React from 'react';
24
+ import {forwardRef} from 'react';
25
+
26
+ const HScrollViewNativeComponentForPlatform =
27
+ Platform.OS === 'android'
28
+ ? AndroidHorizontalScrollViewNativeComponent
29
+ : ScrollViewNativeComponent;
30
+
31
+ // TODO: After upgrading to React 19, remove `forwardRef` from this component.
32
+ export const HScrollViewNativeComponent: React.AbstractComponent<
33
+ ScrollViewNativeProps,
34
+ TScrollViewNativeImperativeHandle,
35
+ // $FlowExpectedError[incompatible-type] - Flow cannot model imperative handles, yet.
36
+ > = forwardRef(function HScrollViewNativeComponent(
37
+ props: ScrollViewNativeProps,
38
+ ref: ?React.RefSetter<TScrollViewNativeImperativeHandle | null>,
39
+ ): React.Node {
40
+ const [componentRef, enableSyncOnScroll] = useSyncOnScroll(ref);
41
+ // NOTE: When `useSyncOnScroll` triggers an update, `props` will not have
42
+ // changed. Notably, `props.children` will be the same, allowing React to
43
+ // bail out during reconciliation.
44
+ return (
45
+ <HScrollViewNativeComponentForPlatform
46
+ {...props}
47
+ ref={componentRef}
48
+ enableSyncOnScroll={enableSyncOnScroll}
49
+ />
50
+ );
51
+ });
52
+
53
+ export const HScrollContentViewNativeComponent: HostComponent<ViewProps> =
54
+ Platform.OS === 'android'
55
+ ? AndroidHorizontalScrollContentViewNativeComponent
56
+ : ScrollContentViewNativeComponent;
@@ -0,0 +1,27 @@
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
+ * @flow strict-local
8
+ * @format
9
+ * @oncall react_native
10
+ */
11
+
12
+ import type {ViewProps} from '../../../Libraries/Components/View/ViewPropTypes';
13
+ import Platform from '../../../Libraries/Utilities/Platform';
14
+ import View from '../../../Libraries/Components/View/View';
15
+ import * as React from 'react';
16
+ export * from '../../../src/private/specs/components/RCTSafeAreaViewNativeComponent';
17
+ import RCTSafeAreaViewNativeComponent from '../../../src/private/specs/components/RCTSafeAreaViewNativeComponent';
18
+
19
+ let exported: React.AbstractComponent<ViewProps, React.ElementRef<typeof View>>;
20
+
21
+ if (Platform.OS === 'android' || Platform.OS === 'ios') {
22
+ exported = RCTSafeAreaViewNativeComponent;
23
+ } else {
24
+ exported = View;
25
+ }
26
+
27
+ export default exported;
@@ -0,0 +1,48 @@
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
+ * @flow strict-local
8
+ * @format
9
+ * @oncall react_native
10
+ */
11
+
12
+ import type {ScrollViewNativeProps} from '../../../Libraries/Components/ScrollView/ScrollViewNativeComponentType';
13
+ import type {ViewProps} from '../../../Libraries/Components/View/ViewPropTypes';
14
+ import type {HostComponent} from '../../../Libraries/Renderer/shims/ReactNativeTypes';
15
+ import type {TScrollViewNativeImperativeHandle} from './useSyncOnScroll';
16
+
17
+ import ScrollContentViewNativeComponent from '../../../Libraries/Components/ScrollView/ScrollContentViewNativeComponent';
18
+ import ScrollViewNativeComponent from '../../../Libraries/Components/ScrollView/ScrollViewNativeComponent';
19
+ import View from '../../../Libraries/Components/View/View';
20
+ import Platform from '../../../Libraries/Utilities/Platform';
21
+ import useSyncOnScroll from './useSyncOnScroll';
22
+ import * as React from 'react';
23
+ import {forwardRef} from 'react';
24
+
25
+ // TODO: After upgrading to React 19, remove `forwardRef` from this component.
26
+ export const VScrollViewNativeComponent: React.AbstractComponent<
27
+ ScrollViewNativeProps,
28
+ TScrollViewNativeImperativeHandle,
29
+ // $FlowExpectedError[incompatible-type] - Flow cannot model imperative handles, yet.
30
+ > = forwardRef(function VScrollViewNativeComponent(
31
+ props: ScrollViewNativeProps,
32
+ ref: ?React.RefSetter<TScrollViewNativeImperativeHandle | null>,
33
+ ): React.Node {
34
+ const [componentRef, enableSyncOnScroll] = useSyncOnScroll(ref);
35
+ // NOTE: When `useSyncOnScroll` triggers an update, `props` will not have
36
+ // changed. Notably, `props.children` will be the same, allowing React to
37
+ // bail out during reconciliation.
38
+ return (
39
+ <ScrollViewNativeComponent
40
+ {...props}
41
+ ref={componentRef}
42
+ enableSyncOnScroll={enableSyncOnScroll}
43
+ />
44
+ );
45
+ });
46
+
47
+ export const VScrollContentViewNativeComponent: HostComponent<ViewProps> =
48
+ Platform.OS === 'android' ? View : ScrollContentViewNativeComponent;
@@ -0,0 +1,48 @@
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
+ * @flow strict-local
8
+ * @format
9
+ * @oncall react_native
10
+ */
11
+
12
+ import type {ScrollViewNativeProps} from '../../../Libraries/Components/ScrollView/ScrollViewNativeComponentType';
13
+ import type {HostComponent} from '../../../Libraries/Renderer/shims/ReactNativeTypes';
14
+
15
+ import * as React from 'react';
16
+ import {useImperativeHandle, useRef, useState} from 'react';
17
+
18
+ export type TScrollViewNativeComponentInstance = React.ElementRef<
19
+ HostComponent<ScrollViewNativeProps>,
20
+ >;
21
+
22
+ export type TScrollViewNativeImperativeHandle = {
23
+ componentRef: React.RefObject<TScrollViewNativeComponentInstance | null>,
24
+ unstable_setEnableSyncOnScroll: (enabled: true) => void,
25
+ };
26
+
27
+ /**
28
+ * Hook used by `HScrollViewNativeComponent` and `VScrollViewNativeComponent`
29
+ * to make an implementation of `unstable_setEnableSyncOnScroll` available that
30
+ * does not require updating all `ScrollView` children.
31
+ */
32
+ export default function useSyncOnScroll(
33
+ inputRef: ?React.RefSetter<TScrollViewNativeImperativeHandle | null>,
34
+ ): [React.RefSetter<TScrollViewNativeComponentInstance | null>, true | void] {
35
+ const componentRef = useRef<TScrollViewNativeComponentInstance | null>(null);
36
+ const [enableSyncOnScroll, setEnableSyncOnScroll] = useState<true | void>();
37
+
38
+ useImperativeHandle<TScrollViewNativeImperativeHandle>(inputRef, () => {
39
+ return {
40
+ componentRef,
41
+ unstable_setEnableSyncOnScroll(enabled: true): void {
42
+ setEnableSyncOnScroll(enabled);
43
+ },
44
+ };
45
+ }, []);
46
+
47
+ return [componentRef, enableSyncOnScroll];
48
+ }