@office-iss/react-native-win32 0.0.0-canary.264 → 0.0.0-canary.266
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/.flowconfig +1 -1
- package/CHANGELOG.json +61 -7
- package/CHANGELOG.md +28 -8
- package/Libraries/Animated/AnimatedImplementation.js +2 -2
- package/Libraries/Animated/NativeAnimatedAllowlist.js +20 -9
- package/Libraries/Animated/animations/Animation.js +1 -4
- package/Libraries/Animated/createAnimatedComponent.js +13 -0
- package/Libraries/Animated/nodes/AnimatedNode.js +39 -45
- package/Libraries/Animated/nodes/AnimatedObject.js +13 -3
- package/Libraries/Animated/nodes/AnimatedProps.js +81 -37
- package/Libraries/Animated/nodes/AnimatedStyle.js +104 -39
- package/Libraries/Animated/nodes/AnimatedTransform.js +55 -22
- package/Libraries/Animated/nodes/AnimatedWithChildren.js +1 -3
- package/Libraries/Animated/useAnimatedProps.js +38 -20
- package/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js +3 -1
- package/Libraries/Components/ScrollView/ScrollView.js +12 -9
- package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +3 -0
- package/Libraries/Components/TextInput/RCTTextInputViewConfig.js +10 -0
- package/Libraries/Components/TextInput/TextInput.d.ts +19 -0
- package/Libraries/Components/TextInput/TextInput.flow.js +17 -1
- package/Libraries/Components/TextInput/TextInput.js +17 -1
- package/Libraries/Components/TextInput/TextInput.win32.js +17 -1
- package/Libraries/Components/Touchable/TouchableBounce.js +1 -1
- package/Libraries/Components/Touchable/TouchableHighlight.js +2 -2
- package/Libraries/Components/Touchable/TouchableOpacity.js +1 -1
- package/Libraries/Components/View/ReactNativeStyleAttributes.js +6 -2
- package/Libraries/Core/ReactNativeVersion.js +2 -2
- package/Libraries/Image/AssetSourceResolver.js +12 -1
- package/Libraries/Modal/Modal.d.ts +7 -0
- package/Libraries/Modal/Modal.js +9 -1
- package/Libraries/NativeComponent/BaseViewConfig.android.js +7 -2
- package/Libraries/NativeComponent/BaseViewConfig.ios.js +11 -2
- package/Libraries/NativeComponent/BaseViewConfig.win32.js +1 -1
- package/Libraries/NativeComponent/StaticViewConfigValidator.js +0 -1
- package/Libraries/ReactNative/AppRegistry.js +2 -6
- package/Libraries/ReactNative/getNativeComponentAttributes.js +4 -0
- package/Libraries/Renderer/shims/ReactNativeTypes.js +3 -3
- package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +5 -6
- package/Libraries/StyleSheet/StyleSheetTypes.d.ts +102 -5
- package/Libraries/StyleSheet/StyleSheetTypes.js +9 -5
- package/Libraries/StyleSheet/processBoxShadow.js +5 -7
- package/Libraries/StyleSheet/processFilter.js +4 -4
- package/Libraries/Text/TextNativeComponent.js +0 -1
- package/Libraries/Utilities/HMRClient.js +5 -5
- package/overrides.json +6 -6
- package/package.json +21 -19
- package/src/private/animated/NativeAnimatedHelper.js +12 -8
- package/src/private/animated/NativeAnimatedHelper.win32.js +12 -8
- package/src/private/animated/useAnimatedPropsMemo.js +349 -0
- package/src/private/components/HScrollViewNativeComponents.js +9 -8
- package/src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE.js +13 -9
- package/src/private/components/VScrollViewNativeComponents.js +9 -8
- package/src/private/featureflags/ReactNativeFeatureFlags.js +50 -22
- package/src/private/featureflags/ReactNativeFeatureFlagsBase.js +8 -2
- package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +7 -4
- package/src/private/webapis/dom/geometry/DOMRect.js +2 -2
- package/src/private/webapis/dom/geometry/DOMRectReadOnly.js +2 -2
- package/types/experimental.d.ts +0 -105
- package/types/modules/Codegen.d.ts +6 -0
|
@@ -0,0 +1,349 @@
|
|
|
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 AnimatedProps from '../../../Libraries/Animated/nodes/AnimatedProps';
|
|
13
|
+
import type {AnimatedPropsAllowlist} from '../../../Libraries/Animated/nodes/AnimatedProps';
|
|
14
|
+
import type {AnimatedStyleAllowlist} from '../../../Libraries/Animated/nodes/AnimatedStyle';
|
|
15
|
+
|
|
16
|
+
import {AnimatedEvent} from '../../../Libraries/Animated/AnimatedEvent';
|
|
17
|
+
import AnimatedNode from '../../../Libraries/Animated/nodes/AnimatedNode';
|
|
18
|
+
import {isPlainObject} from '../../../Libraries/Animated/nodes/AnimatedObject';
|
|
19
|
+
import flattenStyle from '../../../Libraries/StyleSheet/flattenStyle';
|
|
20
|
+
|
|
21
|
+
import nullthrows from 'nullthrows';
|
|
22
|
+
import {useMemo, useState} from 'react';
|
|
23
|
+
|
|
24
|
+
type CompositeKey = {
|
|
25
|
+
style?: {[string]: CompositeKeyComponent},
|
|
26
|
+
[string]:
|
|
27
|
+
| CompositeKeyComponent
|
|
28
|
+
| AnimatedEvent
|
|
29
|
+
| $ReadOnlyArray<mixed>
|
|
30
|
+
| $ReadOnly<{[string]: mixed}>,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type CompositeKeyComponent =
|
|
34
|
+
| AnimatedNode
|
|
35
|
+
| Array<CompositeKeyComponent | null>
|
|
36
|
+
| {[string]: CompositeKeyComponent};
|
|
37
|
+
|
|
38
|
+
type $ReadOnlyCompositeKey = $ReadOnly<{
|
|
39
|
+
style?: $ReadOnly<{[string]: CompositeKeyComponent}>,
|
|
40
|
+
[string]:
|
|
41
|
+
| $ReadOnlyCompositeKeyComponent
|
|
42
|
+
| AnimatedEvent
|
|
43
|
+
| $ReadOnlyArray<mixed>
|
|
44
|
+
| $ReadOnly<{[string]: mixed}>,
|
|
45
|
+
}>;
|
|
46
|
+
|
|
47
|
+
type $ReadOnlyCompositeKeyComponent =
|
|
48
|
+
| AnimatedNode
|
|
49
|
+
| $ReadOnlyArray<$ReadOnlyCompositeKeyComponent | null>
|
|
50
|
+
| $ReadOnly<{[string]: $ReadOnlyCompositeKeyComponent}>;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* A hook that returns an `AnimatedProps` object that is memoized based on the
|
|
54
|
+
* subset of `props` that are instances of `AnimatedNode` or `AnimatedEvent`.
|
|
55
|
+
*/
|
|
56
|
+
export function useAnimatedPropsMemo(
|
|
57
|
+
create: () => AnimatedProps,
|
|
58
|
+
// TODO: Make this two separate arguments after the experiment is over. This
|
|
59
|
+
// is only an array-like structure to make it easier to experiment with this
|
|
60
|
+
// and `useMemo`.
|
|
61
|
+
[allowlist, props]: [?AnimatedPropsAllowlist, {[string]: mixed}],
|
|
62
|
+
): AnimatedProps {
|
|
63
|
+
const compositeKey = useMemo(
|
|
64
|
+
() => createCompositeKeyForProps(props, allowlist),
|
|
65
|
+
[allowlist, props],
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const [state, setState] = useState<{
|
|
69
|
+
allowlist: ?AnimatedPropsAllowlist,
|
|
70
|
+
compositeKey: $ReadOnlyCompositeKey | null,
|
|
71
|
+
value: AnimatedProps,
|
|
72
|
+
}>(() => ({
|
|
73
|
+
allowlist,
|
|
74
|
+
compositeKey,
|
|
75
|
+
value: create(),
|
|
76
|
+
}));
|
|
77
|
+
|
|
78
|
+
if (
|
|
79
|
+
state.allowlist !== allowlist ||
|
|
80
|
+
!areCompositeKeysEqual(state.compositeKey, compositeKey)
|
|
81
|
+
) {
|
|
82
|
+
setState({
|
|
83
|
+
allowlist,
|
|
84
|
+
compositeKey,
|
|
85
|
+
value: create(),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return state.value;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Creates a new composite key for a `props` object that can be used to detect
|
|
93
|
+
* whether a new `AnimatedProps` instance must be created.
|
|
94
|
+
*
|
|
95
|
+
* - With an allowlist, those props are searched for `AnimatedNode` instances.
|
|
96
|
+
* - Without an allowlist, `style` is searched for `AnimatedNode` instances,
|
|
97
|
+
* but all other objects and arrays are included (not searched). We do not
|
|
98
|
+
* search objects and arrays without an allowlist in case they are very large
|
|
99
|
+
* data structures. We safely traverse `style` becuase it is bounded.
|
|
100
|
+
*
|
|
101
|
+
* Any `AnimatedEvent` instances at the first depth are always included.
|
|
102
|
+
*
|
|
103
|
+
* If `props` contains no `AnimatedNode` or `AnimatedEvent` instances, this
|
|
104
|
+
* returns null.
|
|
105
|
+
*/
|
|
106
|
+
export function createCompositeKeyForProps(
|
|
107
|
+
props: $ReadOnly<{[string]: mixed}>,
|
|
108
|
+
allowlist: ?AnimatedPropsAllowlist,
|
|
109
|
+
): $ReadOnlyCompositeKey | null {
|
|
110
|
+
let compositeKey: CompositeKey | null = null;
|
|
111
|
+
|
|
112
|
+
const keys = Object.keys(props);
|
|
113
|
+
for (let ii = 0, length = keys.length; ii < length; ii++) {
|
|
114
|
+
const key = keys[ii];
|
|
115
|
+
const value = props[key];
|
|
116
|
+
|
|
117
|
+
if (allowlist == null || Object.hasOwn(allowlist, key)) {
|
|
118
|
+
let compositeKeyComponent;
|
|
119
|
+
if (key === 'style') {
|
|
120
|
+
// $FlowFixMe[incompatible-call] - `style` is a valid argument.
|
|
121
|
+
// $FlowFixMe[incompatible-type] - `flattenStyle` returns an object.
|
|
122
|
+
const flatStyle: ?{[string]: mixed} = flattenStyle(value);
|
|
123
|
+
if (flatStyle != null) {
|
|
124
|
+
compositeKeyComponent = createCompositeKeyForObject(
|
|
125
|
+
flatStyle,
|
|
126
|
+
allowlist?.style,
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
} else if (
|
|
130
|
+
value instanceof AnimatedNode ||
|
|
131
|
+
value instanceof AnimatedEvent
|
|
132
|
+
) {
|
|
133
|
+
compositeKeyComponent = value;
|
|
134
|
+
} else if (Array.isArray(value)) {
|
|
135
|
+
compositeKeyComponent =
|
|
136
|
+
allowlist == null ? value : createCompositeKeyForArray(value);
|
|
137
|
+
} else if (isPlainObject(value)) {
|
|
138
|
+
compositeKeyComponent =
|
|
139
|
+
allowlist == null ? value : createCompositeKeyForObject(value);
|
|
140
|
+
}
|
|
141
|
+
if (compositeKeyComponent != null) {
|
|
142
|
+
if (compositeKey == null) {
|
|
143
|
+
compositeKey = {} as CompositeKey;
|
|
144
|
+
}
|
|
145
|
+
compositeKey[key] = compositeKeyComponent;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return compositeKey;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Creates a new composite key for an array that retains all values that are or
|
|
155
|
+
* contain `AnimatedNode` instances, and `null` for the rest.
|
|
156
|
+
*
|
|
157
|
+
* If `array` contains no `AnimatedNode` instances, this returns null.
|
|
158
|
+
*/
|
|
159
|
+
function createCompositeKeyForArray(
|
|
160
|
+
array: $ReadOnlyArray<mixed>,
|
|
161
|
+
): $ReadOnlyArray<$ReadOnlyCompositeKeyComponent | null> | null {
|
|
162
|
+
let compositeKey: Array<$ReadOnlyCompositeKeyComponent | null> | null = null;
|
|
163
|
+
|
|
164
|
+
for (let ii = 0, length = array.length; ii < length; ii++) {
|
|
165
|
+
const value = array[ii];
|
|
166
|
+
|
|
167
|
+
let compositeKeyComponent;
|
|
168
|
+
if (value instanceof AnimatedNode) {
|
|
169
|
+
compositeKeyComponent = value;
|
|
170
|
+
} else if (Array.isArray(value)) {
|
|
171
|
+
compositeKeyComponent = createCompositeKeyForArray(value);
|
|
172
|
+
} else if (isPlainObject(value)) {
|
|
173
|
+
compositeKeyComponent = createCompositeKeyForObject(value);
|
|
174
|
+
}
|
|
175
|
+
if (compositeKeyComponent != null) {
|
|
176
|
+
if (compositeKey == null) {
|
|
177
|
+
compositeKey = new Array<$ReadOnlyCompositeKeyComponent | null>(
|
|
178
|
+
array.length,
|
|
179
|
+
).fill(null);
|
|
180
|
+
}
|
|
181
|
+
compositeKey[ii] = compositeKeyComponent;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return compositeKey;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Creates a new composite key for an object that retains only properties that
|
|
190
|
+
* are or contain `AnimatedNode` instances.
|
|
191
|
+
*
|
|
192
|
+
* When used to create composite keys for `style` props:
|
|
193
|
+
*
|
|
194
|
+
* - With an allowlist, those properties are searched.
|
|
195
|
+
* - Without an allowlist, every property is searched.
|
|
196
|
+
*
|
|
197
|
+
* If `object` contains no `AnimatedNode` instances, this returns null.
|
|
198
|
+
*/
|
|
199
|
+
function createCompositeKeyForObject(
|
|
200
|
+
object: $ReadOnly<{[string]: mixed}>,
|
|
201
|
+
allowlist?: ?AnimatedStyleAllowlist,
|
|
202
|
+
): $ReadOnly<{[string]: $ReadOnlyCompositeKeyComponent}> | null {
|
|
203
|
+
let compositeKey: {[string]: $ReadOnlyCompositeKeyComponent} | null = null;
|
|
204
|
+
|
|
205
|
+
const keys = Object.keys(object);
|
|
206
|
+
for (let ii = 0, length = keys.length; ii < length; ii++) {
|
|
207
|
+
const key = keys[ii];
|
|
208
|
+
|
|
209
|
+
if (allowlist == null || Object.hasOwn(allowlist, key)) {
|
|
210
|
+
const value = object[key];
|
|
211
|
+
|
|
212
|
+
let compositeKeyComponent;
|
|
213
|
+
if (value instanceof AnimatedNode) {
|
|
214
|
+
compositeKeyComponent = value;
|
|
215
|
+
} else if (Array.isArray(value)) {
|
|
216
|
+
compositeKeyComponent = createCompositeKeyForArray(value);
|
|
217
|
+
} else if (isPlainObject(value)) {
|
|
218
|
+
compositeKeyComponent = createCompositeKeyForObject(value);
|
|
219
|
+
}
|
|
220
|
+
if (compositeKeyComponent != null) {
|
|
221
|
+
if (compositeKey == null) {
|
|
222
|
+
compositeKey = {} as {[string]: $ReadOnlyCompositeKeyComponent};
|
|
223
|
+
}
|
|
224
|
+
compositeKey[key] = compositeKeyComponent;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return compositeKey;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export function areCompositeKeysEqual(
|
|
233
|
+
maybePrev: $ReadOnlyCompositeKey | null,
|
|
234
|
+
maybeNext: $ReadOnlyCompositeKey | null,
|
|
235
|
+
allowlist: ?AnimatedPropsAllowlist,
|
|
236
|
+
): boolean {
|
|
237
|
+
if (maybePrev === maybeNext) {
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
if (maybePrev === null || maybeNext === null) {
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
// Help Flow retain the type refinements of these.
|
|
244
|
+
const prev = maybePrev;
|
|
245
|
+
const next = maybeNext;
|
|
246
|
+
|
|
247
|
+
const keys = Object.keys(prev);
|
|
248
|
+
const length = keys.length;
|
|
249
|
+
if (length !== Object.keys(next).length) {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
for (let ii = 0; ii < length; ii++) {
|
|
253
|
+
const key = keys[ii];
|
|
254
|
+
if (!Object.hasOwn(next, key)) {
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
const prevComponent = prev[key];
|
|
258
|
+
const nextComponent = next[key];
|
|
259
|
+
|
|
260
|
+
if (key === 'style') {
|
|
261
|
+
// We know style components are objects with non-mixed values.
|
|
262
|
+
if (
|
|
263
|
+
!areCompositeKeyComponentsEqual(
|
|
264
|
+
// $FlowIgnore[incompatible-cast]
|
|
265
|
+
prevComponent as $ReadOnlyCompositeKeyComponent,
|
|
266
|
+
// $FlowIgnore[incompatible-cast]
|
|
267
|
+
nextComponent as $ReadOnlyCompositeKeyComponent,
|
|
268
|
+
)
|
|
269
|
+
) {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
} else if (
|
|
273
|
+
prevComponent instanceof AnimatedNode ||
|
|
274
|
+
prevComponent instanceof AnimatedEvent
|
|
275
|
+
) {
|
|
276
|
+
if (prevComponent !== nextComponent) {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
} else {
|
|
280
|
+
// When `allowlist` is null, the components must be the same. Otherwise,
|
|
281
|
+
// we created the components using deep traversal, so deep compare them.
|
|
282
|
+
if (allowlist == null) {
|
|
283
|
+
if (prevComponent !== nextComponent) {
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
} else {
|
|
287
|
+
if (
|
|
288
|
+
!areCompositeKeyComponentsEqual(
|
|
289
|
+
// $FlowIgnore[incompatible-cast]
|
|
290
|
+
prevComponent as $ReadOnlyCompositeKeyComponent,
|
|
291
|
+
// $FlowIgnore[incompatible-cast]
|
|
292
|
+
nextComponent as $ReadOnlyCompositeKeyComponent,
|
|
293
|
+
)
|
|
294
|
+
) {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return true;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function areCompositeKeyComponentsEqual(
|
|
304
|
+
prev: $ReadOnlyCompositeKeyComponent | null,
|
|
305
|
+
next: $ReadOnlyCompositeKeyComponent | null,
|
|
306
|
+
): boolean {
|
|
307
|
+
if (prev === next) {
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
if (prev instanceof AnimatedNode) {
|
|
311
|
+
return prev === next;
|
|
312
|
+
}
|
|
313
|
+
if (Array.isArray(prev)) {
|
|
314
|
+
if (!Array.isArray(next)) {
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
const length = prev.length;
|
|
318
|
+
if (length !== next.length) {
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
for (let ii = 0; ii < length; ii++) {
|
|
322
|
+
if (!areCompositeKeyComponentsEqual(prev[ii], next[ii])) {
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return true;
|
|
327
|
+
}
|
|
328
|
+
if (isPlainObject(prev)) {
|
|
329
|
+
if (!isPlainObject(next)) {
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
const keys = Object.keys(prev);
|
|
333
|
+
const length = keys.length;
|
|
334
|
+
if (length !== Object.keys(next).length) {
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
for (let ii = 0; ii < length; ii++) {
|
|
338
|
+
const key = keys[ii];
|
|
339
|
+
if (
|
|
340
|
+
!Object.hasOwn(nullthrows(next), key) ||
|
|
341
|
+
!areCompositeKeyComponentsEqual(prev[key], next[key])
|
|
342
|
+
) {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
@@ -21,33 +21,34 @@ import Platform from '../../../Libraries/Utilities/Platform';
|
|
|
21
21
|
import AndroidHorizontalScrollContentViewNativeComponent from '../specs/components/AndroidHorizontalScrollContentViewNativeComponent';
|
|
22
22
|
import useSyncOnScroll from './useSyncOnScroll';
|
|
23
23
|
import * as React from 'react';
|
|
24
|
+
import {forwardRef} from 'react';
|
|
24
25
|
|
|
25
26
|
const HScrollViewNativeComponentForPlatform =
|
|
26
27
|
Platform.OS === 'android'
|
|
27
28
|
? AndroidHorizontalScrollViewNativeComponent
|
|
28
29
|
: ScrollViewNativeComponent;
|
|
29
30
|
|
|
31
|
+
// TODO: After upgrading to React 19, remove `forwardRef` from this component.
|
|
30
32
|
export const HScrollViewNativeComponent: React.AbstractComponent<
|
|
31
33
|
ScrollViewNativeProps,
|
|
32
34
|
TScrollViewNativeImperativeHandle,
|
|
33
35
|
// $FlowExpectedError[incompatible-type] - Flow cannot model imperative handles, yet.
|
|
34
|
-
> = function HScrollViewNativeComponent(
|
|
35
|
-
|
|
36
|
-
ref
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const [ref, enableSyncOnScroll] = useSyncOnScroll(props.ref);
|
|
36
|
+
> = forwardRef(function HScrollViewNativeComponent(
|
|
37
|
+
props: ScrollViewNativeProps,
|
|
38
|
+
ref: ?React.RefSetter<TScrollViewNativeImperativeHandle | null>,
|
|
39
|
+
): React.Node {
|
|
40
|
+
const [componentRef, enableSyncOnScroll] = useSyncOnScroll(ref);
|
|
40
41
|
// NOTE: When `useSyncOnScroll` triggers an update, `props` will not have
|
|
41
42
|
// changed. Notably, `props.children` will be the same, allowing React to
|
|
42
43
|
// bail out during reconciliation.
|
|
43
44
|
return (
|
|
44
45
|
<HScrollViewNativeComponentForPlatform
|
|
45
46
|
{...props}
|
|
46
|
-
ref={
|
|
47
|
+
ref={componentRef}
|
|
47
48
|
enableSyncOnScroll={enableSyncOnScroll}
|
|
48
49
|
/>
|
|
49
50
|
);
|
|
50
|
-
};
|
|
51
|
+
});
|
|
51
52
|
|
|
52
53
|
export const HScrollContentViewNativeComponent: HostComponent<ViewProps> =
|
|
53
54
|
Platform.OS === 'android'
|
|
@@ -12,16 +12,20 @@
|
|
|
12
12
|
import type {ViewProps} from '../../../Libraries/Components/View/ViewPropTypes';
|
|
13
13
|
import Platform from '../../../Libraries/Utilities/Platform';
|
|
14
14
|
import View from '../../../Libraries/Components/View/View';
|
|
15
|
+
import UIManager from '../../../Libraries/ReactNative/UIManager';
|
|
15
16
|
import * as React from 'react';
|
|
16
|
-
export * from '../../../src/private/specs/components/RCTSafeAreaViewNativeComponent';
|
|
17
|
-
import RCTSafeAreaViewNativeComponent from '../../../src/private/specs/components/RCTSafeAreaViewNativeComponent';
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
const exported: React.AbstractComponent<
|
|
19
|
+
ViewProps,
|
|
20
|
+
React.ElementRef<typeof View>,
|
|
21
|
+
> = Platform.select({
|
|
22
|
+
ios: require('../../../src/private/specs/components/RCTSafeAreaViewNativeComponent')
|
|
23
|
+
.default,
|
|
24
|
+
android: UIManager.hasViewManagerConfig('RCTSafeAreaView')
|
|
25
|
+
? require('../../../src/private/specs/components/RCTSafeAreaViewNativeComponent')
|
|
26
|
+
.default
|
|
27
|
+
: View,
|
|
28
|
+
default: View,
|
|
29
|
+
});
|
|
26
30
|
|
|
27
31
|
export default exported;
|
|
@@ -20,28 +20,29 @@ import View from '../../../Libraries/Components/View/View';
|
|
|
20
20
|
import Platform from '../../../Libraries/Utilities/Platform';
|
|
21
21
|
import useSyncOnScroll from './useSyncOnScroll';
|
|
22
22
|
import * as React from 'react';
|
|
23
|
+
import {forwardRef} from 'react';
|
|
23
24
|
|
|
25
|
+
// TODO: After upgrading to React 19, remove `forwardRef` from this component.
|
|
24
26
|
export const VScrollViewNativeComponent: React.AbstractComponent<
|
|
25
27
|
ScrollViewNativeProps,
|
|
26
28
|
TScrollViewNativeImperativeHandle,
|
|
27
29
|
// $FlowExpectedError[incompatible-type] - Flow cannot model imperative handles, yet.
|
|
28
|
-
> = function VScrollViewNativeComponent(
|
|
29
|
-
|
|
30
|
-
ref
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const [ref, enableSyncOnScroll] = useSyncOnScroll(props.ref);
|
|
30
|
+
> = forwardRef(function VScrollViewNativeComponent(
|
|
31
|
+
props: ScrollViewNativeProps,
|
|
32
|
+
ref: ?React.RefSetter<TScrollViewNativeImperativeHandle | null>,
|
|
33
|
+
): React.Node {
|
|
34
|
+
const [componentRef, enableSyncOnScroll] = useSyncOnScroll(ref);
|
|
34
35
|
// NOTE: When `useSyncOnScroll` triggers an update, `props` will not have
|
|
35
36
|
// changed. Notably, `props.children` will be the same, allowing React to
|
|
36
37
|
// bail out during reconciliation.
|
|
37
38
|
return (
|
|
38
39
|
<ScrollViewNativeComponent
|
|
39
40
|
{...props}
|
|
40
|
-
ref={
|
|
41
|
+
ref={componentRef}
|
|
41
42
|
enableSyncOnScroll={enableSyncOnScroll}
|
|
42
43
|
/>
|
|
43
44
|
);
|
|
44
|
-
};
|
|
45
|
+
});
|
|
45
46
|
|
|
46
47
|
export const VScrollContentViewNativeComponent: HostComponent<ViewProps> =
|
|
47
48
|
Platform.OS === 'android' ? View : ScrollContentViewNativeComponent;
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @generated SignedSource<<
|
|
8
|
-
* @flow strict
|
|
7
|
+
* @generated SignedSource<<79bdedd5a09ba284cdaa2e4f40ffd2fd>>
|
|
8
|
+
* @flow strict
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
import {
|
|
22
22
|
type Getter,
|
|
23
|
+
type OverridesFor,
|
|
23
24
|
createJavaScriptFlagGetter,
|
|
24
25
|
createNativeFlagGetter,
|
|
25
26
|
setOverrides,
|
|
@@ -30,18 +31,20 @@ export type ReactNativeFeatureFlagsJsOnly = {
|
|
|
30
31
|
animatedShouldDebounceQueueFlush: Getter<boolean>,
|
|
31
32
|
animatedShouldUseSingleOp: Getter<boolean>,
|
|
32
33
|
enableAccessToHostTreeInFabric: Getter<boolean>,
|
|
34
|
+
enableAnimatedAllowlist: Getter<boolean>,
|
|
35
|
+
enableAnimatedClearImmediateFix: Getter<boolean>,
|
|
36
|
+
enableAnimatedPropsMemo: Getter<boolean>,
|
|
33
37
|
enableOptimisedVirtualizedCells: Getter<boolean>,
|
|
34
38
|
isLayoutAnimationEnabled: Getter<boolean>,
|
|
35
|
-
shouldSkipStateUpdatesForLoopingAnimations: Getter<boolean>,
|
|
36
39
|
shouldUseAnimatedObjectForTransform: Getter<boolean>,
|
|
37
40
|
shouldUseRemoveClippedSubviewsAsDefaultOnIOS: Getter<boolean>,
|
|
38
41
|
shouldUseSetNativePropsInFabric: Getter<boolean>,
|
|
39
42
|
shouldUseSetNativePropsInNativeAnimationsInFabric: Getter<boolean>,
|
|
40
|
-
|
|
43
|
+
useInsertionEffectsForAnimations: Getter<boolean>,
|
|
41
44
|
useRefsForTextInputState: Getter<boolean>,
|
|
42
45
|
};
|
|
43
46
|
|
|
44
|
-
export type ReactNativeFeatureFlagsJsOnlyOverrides =
|
|
47
|
+
export type ReactNativeFeatureFlagsJsOnlyOverrides = OverridesFor<ReactNativeFeatureFlagsJsOnly>;
|
|
45
48
|
|
|
46
49
|
export type ReactNativeFeatureFlags = {
|
|
47
50
|
...ReactNativeFeatureFlagsJsOnly,
|
|
@@ -51,9 +54,11 @@ export type ReactNativeFeatureFlags = {
|
|
|
51
54
|
completeReactInstanceCreationOnBgThreadOnAndroid: Getter<boolean>,
|
|
52
55
|
destroyFabricSurfacesInReactInstanceManager: Getter<boolean>,
|
|
53
56
|
enableAlignItemsBaselineOnFabricIOS: Getter<boolean>,
|
|
57
|
+
enableAndroidLineHeightCentering: Getter<boolean>,
|
|
54
58
|
enableAndroidMixBlendModeProp: Getter<boolean>,
|
|
55
59
|
enableBackgroundStyleApplicator: Getter<boolean>,
|
|
56
60
|
enableCleanTextInputYogaNode: Getter<boolean>,
|
|
61
|
+
enableDeletionOfUnmountedViews: Getter<boolean>,
|
|
57
62
|
enableEagerRootViewAttachment: Getter<boolean>,
|
|
58
63
|
enableEventEmitterRetentionDuringGesturesOnAndroid: Getter<boolean>,
|
|
59
64
|
enableFabricLogs: Getter<boolean>,
|
|
@@ -63,16 +68,16 @@ export type ReactNativeFeatureFlags = {
|
|
|
63
68
|
enableLayoutAnimationsOnIOS: Getter<boolean>,
|
|
64
69
|
enableLongTaskAPI: Getter<boolean>,
|
|
65
70
|
enableMicrotasks: Getter<boolean>,
|
|
71
|
+
enablePreciseSchedulingForPremountItemsOnAndroid: Getter<boolean>,
|
|
66
72
|
enablePropsUpdateReconciliationAndroid: Getter<boolean>,
|
|
67
73
|
enableReportEventPaintTime: Getter<boolean>,
|
|
68
74
|
enableSynchronousStateUpdates: Getter<boolean>,
|
|
75
|
+
enableTextPreallocationOptimisation: Getter<boolean>,
|
|
69
76
|
enableUIConsistency: Getter<boolean>,
|
|
70
77
|
enableViewRecycling: Getter<boolean>,
|
|
71
78
|
excludeYogaFromRawProps: Getter<boolean>,
|
|
72
79
|
fetchImagesInViewPreallocation: Getter<boolean>,
|
|
73
|
-
fixIncorrectScrollViewStateUpdateOnAndroid: Getter<boolean>,
|
|
74
80
|
fixMappingOfEventPrioritiesBetweenFabricAndReact: Getter<boolean>,
|
|
75
|
-
fixMissedFabricStateUpdatesOnAndroid: Getter<boolean>,
|
|
76
81
|
fixMountingCoordinatorReportedPendingTransactionsOnAndroid: Getter<boolean>,
|
|
77
82
|
forceBatchingMountItemsOnAndroid: Getter<boolean>,
|
|
78
83
|
fuseboxEnabledDebug: Getter<boolean>,
|
|
@@ -80,6 +85,7 @@ export type ReactNativeFeatureFlags = {
|
|
|
80
85
|
initEagerTurboModulesOnNativeModulesQueueAndroid: Getter<boolean>,
|
|
81
86
|
lazyAnimationCallbacks: Getter<boolean>,
|
|
82
87
|
loadVectorDrawablesOnImages: Getter<boolean>,
|
|
88
|
+
removeNestedCallsToDispatchMountItemsOnAndroid: Getter<boolean>,
|
|
83
89
|
setAndroidLayoutDirection: Getter<boolean>,
|
|
84
90
|
traceTurboModulePromiseRejectionsOnAndroid: Getter<boolean>,
|
|
85
91
|
useFabricInterop: Getter<boolean>,
|
|
@@ -115,6 +121,21 @@ export const animatedShouldUseSingleOp: Getter<boolean> = createJavaScriptFlagGe
|
|
|
115
121
|
*/
|
|
116
122
|
export const enableAccessToHostTreeInFabric: Getter<boolean> = createJavaScriptFlagGetter('enableAccessToHostTreeInFabric', false);
|
|
117
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Enables Animated to skip non-allowlisted props and styles.
|
|
126
|
+
*/
|
|
127
|
+
export const enableAnimatedAllowlist: Getter<boolean> = createJavaScriptFlagGetter('enableAnimatedAllowlist', false);
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Enables an experimental to use the proper clearIntermediate instead of calling the wrong clearTimeout and canceling another timer.
|
|
131
|
+
*/
|
|
132
|
+
export const enableAnimatedClearImmediateFix: Getter<boolean> = createJavaScriptFlagGetter('enableAnimatedClearImmediateFix', true);
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Enables Animated to analyze props to minimize invalidating `AnimatedProps`.
|
|
136
|
+
*/
|
|
137
|
+
export const enableAnimatedPropsMemo: Getter<boolean> = createJavaScriptFlagGetter('enableAnimatedPropsMemo', false);
|
|
138
|
+
|
|
118
139
|
/**
|
|
119
140
|
* Removing unnecessary rerenders Virtualized cells after any rerenders of Virualized list. Works with strict=true option
|
|
120
141
|
*/
|
|
@@ -125,11 +146,6 @@ export const enableOptimisedVirtualizedCells: Getter<boolean> = createJavaScript
|
|
|
125
146
|
*/
|
|
126
147
|
export const isLayoutAnimationEnabled: Getter<boolean> = createJavaScriptFlagGetter('isLayoutAnimationEnabled', true);
|
|
127
148
|
|
|
128
|
-
/**
|
|
129
|
-
* If the animation is within Animated.loop, we do not send state updates to React.
|
|
130
|
-
*/
|
|
131
|
-
export const shouldSkipStateUpdatesForLoopingAnimations: Getter<boolean> = createJavaScriptFlagGetter('shouldSkipStateUpdatesForLoopingAnimations', false);
|
|
132
|
-
|
|
133
149
|
/**
|
|
134
150
|
* Enables use of AnimatedObject for animating transform values.
|
|
135
151
|
*/
|
|
@@ -151,9 +167,9 @@ export const shouldUseSetNativePropsInFabric: Getter<boolean> = createJavaScript
|
|
|
151
167
|
export const shouldUseSetNativePropsInNativeAnimationsInFabric: Getter<boolean> = createJavaScriptFlagGetter('shouldUseSetNativePropsInNativeAnimationsInFabric', false);
|
|
152
168
|
|
|
153
169
|
/**
|
|
154
|
-
*
|
|
170
|
+
* Changes construction of the animation graph to `useInsertionEffect` instead of `useLayoutEffect`.
|
|
155
171
|
*/
|
|
156
|
-
export const
|
|
172
|
+
export const useInsertionEffectsForAnimations: Getter<boolean> = createJavaScriptFlagGetter('useInsertionEffectsForAnimations', false);
|
|
157
173
|
|
|
158
174
|
/**
|
|
159
175
|
* Enable a variant of TextInput that moves some state to refs to avoid unnecessary re-renders
|
|
@@ -184,6 +200,10 @@ export const destroyFabricSurfacesInReactInstanceManager: Getter<boolean> = crea
|
|
|
184
200
|
* Kill-switch to turn off support for aling-items:baseline on Fabric iOS.
|
|
185
201
|
*/
|
|
186
202
|
export const enableAlignItemsBaselineOnFabricIOS: Getter<boolean> = createNativeFlagGetter('enableAlignItemsBaselineOnFabricIOS', true);
|
|
203
|
+
/**
|
|
204
|
+
* When enabled, custom line height calculation will be centered from top to bottom.
|
|
205
|
+
*/
|
|
206
|
+
export const enableAndroidLineHeightCentering: Getter<boolean> = createNativeFlagGetter('enableAndroidLineHeightCentering', false);
|
|
187
207
|
/**
|
|
188
208
|
* Enables mix-blend-mode prop on Android.
|
|
189
209
|
*/
|
|
@@ -196,6 +216,10 @@ export const enableBackgroundStyleApplicator: Getter<boolean> = createNativeFlag
|
|
|
196
216
|
* Clean yoga node when <TextInput /> does not change.
|
|
197
217
|
*/
|
|
198
218
|
export const enableCleanTextInputYogaNode: Getter<boolean> = createNativeFlagGetter('enableCleanTextInputYogaNode', false);
|
|
219
|
+
/**
|
|
220
|
+
* Deletes views that were pre-allocated but never mounted on the screen.
|
|
221
|
+
*/
|
|
222
|
+
export const enableDeletionOfUnmountedViews: Getter<boolean> = createNativeFlagGetter('enableDeletionOfUnmountedViews', false);
|
|
199
223
|
/**
|
|
200
224
|
* Feature flag to configure eager attachment of the root view/initialisation of the JS code.
|
|
201
225
|
*/
|
|
@@ -232,6 +256,10 @@ export const enableLongTaskAPI: Getter<boolean> = createNativeFlagGetter('enable
|
|
|
232
256
|
* Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution).
|
|
233
257
|
*/
|
|
234
258
|
export const enableMicrotasks: Getter<boolean> = createNativeFlagGetter('enableMicrotasks', false);
|
|
259
|
+
/**
|
|
260
|
+
* Moves execution of pre-mount items to outside the choregrapher in the main thread, so we can estimate idle time more precisely (Android only).
|
|
261
|
+
*/
|
|
262
|
+
export const enablePreciseSchedulingForPremountItemsOnAndroid: Getter<boolean> = createNativeFlagGetter('enablePreciseSchedulingForPremountItemsOnAndroid', false);
|
|
235
263
|
/**
|
|
236
264
|
* When enabled, Android will receive prop updates based on the differences between the last rendered shadow node and the last committed shadow node.
|
|
237
265
|
*/
|
|
@@ -244,6 +272,10 @@ export const enableReportEventPaintTime: Getter<boolean> = createNativeFlagGette
|
|
|
244
272
|
* Dispatches state updates synchronously in Fabric (e.g.: updates the scroll position in the shadow tree synchronously from the main thread).
|
|
245
273
|
*/
|
|
246
274
|
export const enableSynchronousStateUpdates: Getter<boolean> = createNativeFlagGetter('enableSynchronousStateUpdates', false);
|
|
275
|
+
/**
|
|
276
|
+
* Text preallocation optimisation where unnecessary work is removed.
|
|
277
|
+
*/
|
|
278
|
+
export const enableTextPreallocationOptimisation: Getter<boolean> = createNativeFlagGetter('enableTextPreallocationOptimisation', false);
|
|
247
279
|
/**
|
|
248
280
|
* Ensures that JavaScript always has a consistent view of the state of the UI (e.g.: commits done in other threads are not immediately propagated to JS during its execution).
|
|
249
281
|
*/
|
|
@@ -260,18 +292,10 @@ export const excludeYogaFromRawProps: Getter<boolean> = createNativeFlagGetter('
|
|
|
260
292
|
* Start image fetching during view preallocation instead of waiting for layout pass
|
|
261
293
|
*/
|
|
262
294
|
export const fetchImagesInViewPreallocation: Getter<boolean> = createNativeFlagGetter('fetchImagesInViewPreallocation', false);
|
|
263
|
-
/**
|
|
264
|
-
* When doing a smooth scroll animation, it stops setting the state with the final scroll position in Fabric before the animation starts.
|
|
265
|
-
*/
|
|
266
|
-
export const fixIncorrectScrollViewStateUpdateOnAndroid: Getter<boolean> = createNativeFlagGetter('fixIncorrectScrollViewStateUpdateOnAndroid', false);
|
|
267
295
|
/**
|
|
268
296
|
* Uses the default event priority instead of the discreet event priority by default when dispatching events from Fabric to React.
|
|
269
297
|
*/
|
|
270
298
|
export const fixMappingOfEventPrioritiesBetweenFabricAndReact: Getter<boolean> = createNativeFlagGetter('fixMappingOfEventPrioritiesBetweenFabricAndReact', false);
|
|
271
|
-
/**
|
|
272
|
-
* Enables a fix to prevent the possibility of state updates in Fabric being missed due to race conditions with previous state updates.
|
|
273
|
-
*/
|
|
274
|
-
export const fixMissedFabricStateUpdatesOnAndroid: Getter<boolean> = createNativeFlagGetter('fixMissedFabricStateUpdatesOnAndroid', false);
|
|
275
299
|
/**
|
|
276
300
|
* Fixes a limitation on Android where the mounting coordinator would report there are no pending transactions but some of them were actually not processed due to the use of the push model.
|
|
277
301
|
*/
|
|
@@ -300,6 +324,10 @@ export const lazyAnimationCallbacks: Getter<boolean> = createNativeFlagGetter('l
|
|
|
300
324
|
* Adds support for loading vector drawable assets in the Image component (only on Android)
|
|
301
325
|
*/
|
|
302
326
|
export const loadVectorDrawablesOnImages: Getter<boolean> = createNativeFlagGetter('loadVectorDrawablesOnImages', false);
|
|
327
|
+
/**
|
|
328
|
+
* Removes nested calls to MountItemDispatcher.dispatchMountItems on Android, so we do less work per frame on the UI thread.
|
|
329
|
+
*/
|
|
330
|
+
export const removeNestedCallsToDispatchMountItemsOnAndroid: Getter<boolean> = createNativeFlagGetter('removeNestedCallsToDispatchMountItemsOnAndroid', false);
|
|
303
331
|
/**
|
|
304
332
|
* Propagate layout direction to Android views.
|
|
305
333
|
*/
|