@office-iss/react-native-win32 0.0.0-canary.301 → 0.0.0-canary.303

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 (132) hide show
  1. package/.flowconfig +2 -2
  2. package/CHANGELOG.json +49 -1
  3. package/CHANGELOG.md +24 -5
  4. package/IntegrationTests/IntegrationTestsApp.js +1 -1
  5. package/IntegrationTests/LayoutEventsTest.js +3 -3
  6. package/Libraries/ActionSheetIOS/ActionSheetIOS.js +3 -3
  7. package/Libraries/Alert/RCTAlertManager.android.js +2 -2
  8. package/Libraries/Animated/AnimatedEvent.js +1 -1
  9. package/Libraries/Animated/AnimatedImplementation.js +2 -2
  10. package/Libraries/Animated/AnimatedMock.js +1 -1
  11. package/Libraries/Animated/NativeAnimatedAllowlist.js +1 -0
  12. package/Libraries/Animated/animations/Animation.js +5 -6
  13. package/Libraries/Animated/components/AnimatedScrollView.js +1 -1
  14. package/Libraries/Animated/nodes/AnimatedColor.js +9 -9
  15. package/Libraries/Animated/nodes/AnimatedInterpolation.js +4 -4
  16. package/Libraries/Animated/nodes/AnimatedProps.js +2 -2
  17. package/Libraries/Animated/nodes/AnimatedStyle.js +6 -4
  18. package/Libraries/Animated/nodes/AnimatedTransform.js +1 -1
  19. package/Libraries/AppState/AppState.js +5 -1
  20. package/Libraries/BatchedBridge/NativeModules.js +1 -1
  21. package/Libraries/Blob/BlobManager.js +1 -1
  22. package/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js +1 -1
  23. package/Libraries/Components/AccessibilityInfo/AccessibilityInfo.win32.js +1 -1
  24. package/Libraries/Components/Button.js +1 -1
  25. package/Libraries/Components/Button.win32.js +1 -1
  26. package/Libraries/Components/Pressable/useAndroidRippleForView.js +2 -2
  27. package/Libraries/Components/ScrollView/ScrollView.js +3 -2
  28. package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +1 -1
  29. package/Libraries/Components/TextInput/TextInput.flow.js +12 -5
  30. package/Libraries/Components/TextInput/TextInput.flow.win32.js +12 -5
  31. package/Libraries/Components/TextInput/TextInput.js +9 -4
  32. package/Libraries/Components/TextInput/TextInput.win32.js +9 -6
  33. package/Libraries/Components/TextInput/Win32TextInputNativeComponent.js +2 -3
  34. package/Libraries/Components/Touchable/TouchableWithoutFeedback.js +1 -1
  35. package/Libraries/Components/View/View.win32.js +3 -1
  36. package/Libraries/Core/Devtools/loadBundleFromServer.js +1 -1
  37. package/Libraries/Core/Devtools/loadBundleFromServer.win32.js +1 -1
  38. package/Libraries/Core/ExceptionsManager.js +2 -2
  39. package/Libraries/Core/ReactFiberErrorDialog.js +3 -3
  40. package/Libraries/Core/ReactNativeVersion.js +1 -1
  41. package/Libraries/Core/Timers/JSTimers.js +1 -1
  42. package/Libraries/Core/Timers/immediateShim.js +1 -1
  43. package/Libraries/Debugging/DebuggingOverlayRegistry.js +5 -3
  44. package/Libraries/Image/Image.android.js +318 -111
  45. package/Libraries/Image/ImageSourceUtils.js +8 -2
  46. package/Libraries/Image/resolveAssetSource.js +1 -1
  47. package/Libraries/Interaction/InteractionManager.js +1 -1
  48. package/Libraries/Interaction/PanResponder.js +1 -1
  49. package/Libraries/Lists/FlatList.js +5 -6
  50. package/Libraries/LogBox/Data/LogBoxData.js +1 -1
  51. package/Libraries/LogBox/Data/parseLogBoxLog.js +1 -1
  52. package/Libraries/LogBox/UI/LogBoxInspectorSourceMapStatus.js +1 -1
  53. package/Libraries/LogBox/UI/LogBoxInspectorSourceMapStatus.win32.js +1 -1
  54. package/Libraries/Modal/Modal.js +2 -2
  55. package/Libraries/NativeComponent/NativeComponentRegistry.js +1 -1
  56. package/Libraries/NativeComponent/ViewConfig.js +1 -1
  57. package/Libraries/Network/RCTNetworking.android.js +1 -1
  58. package/Libraries/Network/RCTNetworking.ios.js +1 -1
  59. package/Libraries/Network/RCTNetworking.win32.js +1 -1
  60. package/Libraries/Network/convertRequestBody.js +1 -1
  61. package/Libraries/PermissionsAndroid/PermissionsAndroid.js +10 -9
  62. package/Libraries/Pressability/HoverState.js +2 -0
  63. package/Libraries/Pressability/HoverState.win32.js +2 -0
  64. package/Libraries/PushNotificationIOS/PushNotificationIOS.js +2 -2
  65. package/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricHostComponent.js +2 -0
  66. package/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstance.js +3 -3
  67. package/Libraries/ReactNative/RendererImplementation.js +116 -116
  68. package/Libraries/ReactNative/UIManager.js +3 -3
  69. package/Libraries/ReactPrivate/ReactNativePrivateInterface.js +1 -1
  70. package/Libraries/Renderer/shims/ReactFabric.js +1 -3
  71. package/Libraries/Renderer/shims/ReactFeatureFlags.js +1 -3
  72. package/Libraries/Renderer/shims/ReactNative.js +1 -3
  73. package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +1 -3
  74. package/Libraries/Renderer/shims/createReactNativeComponentClass.js +1 -3
  75. package/Libraries/StyleSheet/PlatformColorValueTypes.android.js +2 -2
  76. package/Libraries/StyleSheet/PlatformColorValueTypes.ios.js +2 -2
  77. package/Libraries/StyleSheet/PlatformColorValueTypes.win32.js +4 -0
  78. package/Libraries/StyleSheet/flattenStyle.js +2 -2
  79. package/Libraries/StyleSheet/splitLayoutProps.js +2 -2
  80. package/Libraries/Text/Text.js +509 -235
  81. package/Libraries/Text/Text.win32.js +622 -275
  82. package/Libraries/Text/TextNativeComponent.js +2 -2
  83. package/Libraries/Text/TextNativeComponent.win32.js +2 -2
  84. package/Libraries/Utilities/HMRClient.js +0 -1
  85. package/Libraries/Utilities/Platform.android.js +3 -3
  86. package/Libraries/Utilities/Platform.d.ts +1 -0
  87. package/Libraries/Utilities/Platform.ios.js +1 -1
  88. package/Libraries/Utilities/Platform.win32.js +3 -3
  89. package/Libraries/Utilities/PlatformTypes.js +1 -1
  90. package/Libraries/Utilities/ReactNativeTestTools.js +12 -0
  91. package/Libraries/Utilities/codegenNativeCommands.js +1 -1
  92. package/Libraries/Utilities/codegenNativeComponent.js +1 -1
  93. package/Libraries/Utilities/differ/pointsDiffer.js +1 -1
  94. package/Libraries/vendor/emitter/EventEmitter.js +1 -1
  95. package/index.js +3 -0
  96. package/index.win32.js +4 -0
  97. package/jest/local-setup.js +2 -2
  98. package/jest/mock.js +1 -1
  99. package/jest/mockComponent.js +8 -8
  100. package/jest/mockNativeComponent.js +3 -2
  101. package/jest/mocks/Modal.js +1 -1
  102. package/jest/mocks/ScrollView.js +1 -1
  103. package/jest/mocks/ViewNativeComponent.js +1 -1
  104. package/jest/setup.js +12 -12
  105. package/overrides.json +16 -16
  106. package/package.json +12 -12
  107. package/src/private/animated/NativeAnimatedHelper.js +3 -3
  108. package/src/private/animated/NativeAnimatedHelper.win32.js +3 -3
  109. package/src/private/animated/createAnimatedPropsHook.js +9 -11
  110. package/src/private/animated/createAnimatedPropsMemoHook.js +6 -6
  111. package/src/private/components/virtualview/VirtualView.js +7 -4
  112. package/src/private/components/virtualview/VirtualViewNativeComponent.js +6 -0
  113. package/src/private/devsupport/devmenu/elementinspector/Inspector.js +2 -2
  114. package/src/private/featureflags/ReactNativeFeatureFlags.js +9 -8
  115. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +1 -2
  116. package/src/private/renderer/errorhandling/ErrorHandlers.js +3 -3
  117. package/src/private/types/HostInstance.js +4 -1
  118. package/src/private/webapis/dom/nodes/ReactNativeDocument.js +22 -2
  119. package/src/private/webapis/dom/nodes/ReactNativeElement.js +1 -1
  120. package/src/private/webapis/dom/nodes/ReadOnlyElement.js +5 -3
  121. package/src/private/webapis/dom/nodes/ReadOnlyNode.js +16 -13
  122. package/src/private/webapis/dom/nodes/internals/NodeInternals.js +45 -22
  123. package/src/private/webapis/dom/nodes/internals/ReactNativeDocumentInstanceHandle.js +1 -1
  124. package/src/private/webapis/dom/nodes/specs/NativeDOM.js +26 -192
  125. package/src/private/webapis/dom/oldstylecollections/HTMLCollection.js +14 -11
  126. package/src/private/webapis/dom/oldstylecollections/NodeList.js +13 -10
  127. package/src/private/webapis/geometry/DOMRectList.js +1 -1
  128. package/src/private/webapis/mutationobserver/internals/MutationObserverManager.js +1 -1
  129. package/src/private/webapis/performance/EventTiming.js +1 -1
  130. package/src/private/webapis/performance/Performance.js +12 -30
  131. package/src/private/webapis/performance/specs/NativePerformance.js +4 -4
  132. package/src/private/webapis/structuredClone/structuredClone.js +9 -9
@@ -14,6 +14,7 @@ import type {GestureResponderEvent} from '../Types/CoreEventTypes';
14
14
  import type {NativeTextProps} from './TextNativeComponent';
15
15
  import type {PressRetentionOffset, TextProps} from './TextProps';
16
16
 
17
+ import * as ReactNativeFeatureFlags from '../../src/private/featureflags/ReactNativeFeatureFlags';
17
18
  import * as PressabilityDebug from '../Pressability/PressabilityDebug';
18
19
  import usePressability from '../Pressability/usePressability';
19
20
  import flattenStyle from '../StyleSheet/flattenStyle';
@@ -35,156 +36,495 @@ type TextForwardRef = React.ElementRef<
35
36
  *
36
37
  * @see https://reactnative.dev/docs/text
37
38
  */
38
- const TextImpl: component(
39
- ref?: React.RefSetter<TextForwardRef>,
40
- ...props: TextProps
41
- ) = ({
42
- ref: forwardedRef,
43
- accessible,
44
- accessibilityLabel,
45
- accessibilityState,
46
- allowFontScaling,
47
- 'aria-busy': ariaBusy,
48
- 'aria-checked': ariaChecked,
49
- 'aria-disabled': ariaDisabled,
50
- 'aria-expanded': ariaExpanded,
51
- 'aria-label': ariaLabel,
52
- 'aria-selected': ariaSelected,
53
- children,
54
- ellipsizeMode,
55
- disabled,
56
- id,
57
- nativeID,
58
- numberOfLines,
59
- onLongPress,
60
- onPress,
61
- onPressIn,
62
- onPressOut,
63
- onResponderGrant,
64
- onResponderMove,
65
- onResponderRelease,
66
- onResponderTerminate,
67
- onResponderTerminationRequest,
68
- onStartShouldSetResponder,
69
- pressRetentionOffset,
70
- selectable,
71
- selectionColor,
72
- suppressHighlighting,
73
- style,
74
- ...restProps
75
- }: {
76
- ref?: React.RefSetter<TextForwardRef>,
77
- ...TextProps,
78
- }) => {
79
- const _accessibilityLabel = ariaLabel ?? accessibilityLabel;
80
-
81
- let _accessibilityState: ?TextProps['accessibilityState'] =
82
- accessibilityState;
83
- if (
84
- ariaBusy != null ||
85
- ariaChecked != null ||
86
- ariaDisabled != null ||
87
- ariaExpanded != null ||
88
- ariaSelected != null
89
- ) {
90
- if (_accessibilityState != null) {
91
- _accessibilityState = {
92
- busy: ariaBusy ?? _accessibilityState.busy,
93
- checked: ariaChecked ?? _accessibilityState.checked,
94
- disabled: ariaDisabled ?? _accessibilityState.disabled,
95
- expanded: ariaExpanded ?? _accessibilityState.expanded,
96
- selected: ariaSelected ?? _accessibilityState.selected,
97
- };
98
- } else {
99
- _accessibilityState = {
100
- busy: ariaBusy,
101
- checked: ariaChecked,
102
- disabled: ariaDisabled,
103
- expanded: ariaExpanded,
104
- selected: ariaSelected,
39
+ let _TextImpl;
40
+ if (ReactNativeFeatureFlags.reduceDefaultPropsInText()) {
41
+ const TextImplNoDefaultProps: component(
42
+ ref?: React.RefSetter<TextForwardRef>,
43
+ ...props: TextProps
44
+ ) = ({
45
+ ref: forwardedRef,
46
+ accessible,
47
+ accessibilityLabel,
48
+ accessibilityState,
49
+ allowFontScaling,
50
+ 'aria-busy': ariaBusy,
51
+ 'aria-checked': ariaChecked,
52
+ 'aria-disabled': ariaDisabled,
53
+ 'aria-expanded': ariaExpanded,
54
+ 'aria-label': ariaLabel,
55
+ 'aria-selected': ariaSelected,
56
+ children,
57
+ ellipsizeMode,
58
+ disabled,
59
+ id,
60
+ nativeID,
61
+ numberOfLines,
62
+ onLongPress,
63
+ onPress,
64
+ onPressIn,
65
+ onPressOut,
66
+ onResponderGrant,
67
+ onResponderMove,
68
+ onResponderRelease,
69
+ onResponderTerminate,
70
+ onResponderTerminationRequest,
71
+ onStartShouldSetResponder,
72
+ pressRetentionOffset,
73
+ selectable,
74
+ selectionColor,
75
+ suppressHighlighting,
76
+ style,
77
+ ...restProps
78
+ }: {
79
+ ref?: React.RefSetter<TextForwardRef>,
80
+ ...TextProps,
81
+ }) => {
82
+ const processedProps = restProps as {
83
+ ...NativeTextProps,
84
+ };
85
+ const _accessibilityLabel = ariaLabel ?? accessibilityLabel;
86
+ let _accessibilityState: ?TextProps['accessibilityState'] =
87
+ accessibilityState;
88
+ if (
89
+ ariaBusy != null ||
90
+ ariaChecked != null ||
91
+ ariaDisabled != null ||
92
+ ariaExpanded != null ||
93
+ ariaSelected != null
94
+ ) {
95
+ if (_accessibilityState != null) {
96
+ _accessibilityState = {
97
+ busy: ariaBusy ?? _accessibilityState.busy,
98
+ checked: ariaChecked ?? _accessibilityState.checked,
99
+ disabled: ariaDisabled ?? _accessibilityState.disabled,
100
+ expanded: ariaExpanded ?? _accessibilityState.expanded,
101
+ selected: ariaSelected ?? _accessibilityState.selected,
102
+ };
103
+ } else {
104
+ _accessibilityState = {
105
+ busy: ariaBusy,
106
+ checked: ariaChecked,
107
+ disabled: ariaDisabled,
108
+ expanded: ariaExpanded,
109
+ selected: ariaSelected,
110
+ };
111
+ }
112
+ }
113
+
114
+ const _accessibilityStateDisabled = _accessibilityState?.disabled;
115
+ const _disabled = disabled ?? _accessibilityStateDisabled;
116
+
117
+ // If the disabled prop and accessibilityState.disabled are out of sync but not both in
118
+ // falsy states we need to update the accessibilityState object to use the disabled prop.
119
+ if (
120
+ _accessibilityState != null &&
121
+ _disabled !== _accessibilityStateDisabled &&
122
+ ((_disabled != null && _disabled !== false) ||
123
+ (_accessibilityStateDisabled != null &&
124
+ _accessibilityStateDisabled !== false))
125
+ ) {
126
+ _accessibilityState.disabled = _disabled;
127
+ }
128
+
129
+ const _accessible = Platform.select({
130
+ ios: accessible !== false,
131
+ android:
132
+ accessible == null
133
+ ? onPress != null || onLongPress != null
134
+ : accessible,
135
+ default: accessible,
136
+ });
137
+
138
+ const isPressable =
139
+ (onPress != null ||
140
+ onLongPress != null ||
141
+ onStartShouldSetResponder != null) &&
142
+ _disabled !== true;
143
+
144
+ // TODO: Move this processing to the view configuration.
145
+ const _selectionColor =
146
+ selectionColor != null ? processColor(selectionColor) : undefined;
147
+
148
+ let _style = style;
149
+ if (__DEV__) {
150
+ if (PressabilityDebug.isEnabled() && onPress != null) {
151
+ _style = [style, {color: 'magenta'}];
152
+ }
153
+ }
154
+
155
+ let _numberOfLines = numberOfLines;
156
+ if (_numberOfLines != null && !(_numberOfLines >= 0)) {
157
+ if (__DEV__) {
158
+ console.error(
159
+ `'numberOfLines' in <Text> must be a non-negative number, received: ${_numberOfLines}. The value will be set to 0.`,
160
+ );
161
+ }
162
+ _numberOfLines = 0;
163
+ }
164
+
165
+ let _selectable = selectable;
166
+
167
+ let processedStyle = flattenStyle<TextStyleProp>(_style);
168
+ if (processedStyle != null) {
169
+ let overrides: ?{...TextStyleInternal} = null;
170
+ if (typeof processedStyle.fontWeight === 'number') {
171
+ overrides = overrides || ({}: {...TextStyleInternal});
172
+ overrides.fontWeight =
173
+ // $FlowFixMe[incompatible-type]
174
+ (String(processedStyle.fontWeight): TextStyleInternal['fontWeight']);
175
+ }
176
+
177
+ if (processedStyle.userSelect != null) {
178
+ _selectable = userSelectToSelectableMap[processedStyle.userSelect];
179
+ overrides = overrides || ({}: {...TextStyleInternal});
180
+ overrides.userSelect = undefined;
181
+ }
182
+
183
+ if (processedStyle.verticalAlign != null) {
184
+ overrides = overrides || ({}: {...TextStyleInternal});
185
+ overrides.textAlignVertical =
186
+ verticalAlignToTextAlignVerticalMap[processedStyle.verticalAlign];
187
+ overrides.verticalAlign = undefined;
188
+ }
189
+
190
+ if (overrides != null) {
191
+ // $FlowFixMe[incompatible-type]
192
+ _style = [_style, overrides];
193
+ }
194
+ }
195
+
196
+ const _nativeID = id ?? nativeID;
197
+
198
+ if (_accessibilityLabel !== undefined) {
199
+ processedProps.accessibilityLabel = _accessibilityLabel;
200
+ }
201
+ if (_accessibilityState !== undefined) {
202
+ processedProps.accessibilityState = _accessibilityState;
203
+ }
204
+ if (_nativeID !== undefined) {
205
+ processedProps.nativeID = _nativeID;
206
+ }
207
+ if (_numberOfLines !== undefined) {
208
+ processedProps.numberOfLines = _numberOfLines;
209
+ }
210
+ if (_selectable !== undefined) {
211
+ processedProps.selectable = _selectable;
212
+ }
213
+ if (_style !== undefined) {
214
+ processedProps.style = _style;
215
+ }
216
+ if (_selectionColor !== undefined) {
217
+ processedProps.selectionColor = _selectionColor;
218
+ }
219
+
220
+ let textPressabilityProps: ?TextPressabilityProps;
221
+ if (isPressable) {
222
+ textPressabilityProps = {
223
+ onLongPress,
224
+ onPress,
225
+ onPressIn,
226
+ onPressOut,
227
+ onResponderGrant,
228
+ onResponderMove,
229
+ onResponderRelease,
230
+ onResponderTerminate,
231
+ onResponderTerminationRequest,
232
+ onStartShouldSetResponder,
233
+ pressRetentionOffset,
234
+ suppressHighlighting,
105
235
  };
106
236
  }
107
- }
108
237
 
109
- const _accessibilityStateDisabled = _accessibilityState?.disabled;
110
- const _disabled = disabled ?? _accessibilityStateDisabled;
238
+ const hasTextAncestor = useContext(TextAncestorContext);
239
+ if (hasTextAncestor) {
240
+ processedProps.disabled = disabled;
241
+ processedProps.children = children;
242
+ if (isPressable) {
243
+ return (
244
+ <NativePressableVirtualText
245
+ ref={forwardedRef}
246
+ textProps={processedProps}
247
+ textPressabilityProps={textPressabilityProps ?? {}}
248
+ />
249
+ );
250
+ }
251
+ return <NativeVirtualText {...processedProps} ref={forwardedRef} />;
252
+ }
253
+
254
+ let nativeText = null;
111
255
 
112
- const isPressable =
113
- (onPress != null ||
114
- onLongPress != null ||
115
- onStartShouldSetResponder != null) &&
116
- _disabled !== true;
256
+ processedProps.accessible = _accessible;
257
+ processedProps.allowFontScaling = allowFontScaling !== false;
258
+ processedProps.disabled = _disabled;
259
+ processedProps.ellipsizeMode = ellipsizeMode ?? 'tail';
260
+ processedProps.children = children;
117
261
 
118
- // TODO: Move this processing to the view configuration.
119
- const _selectionColor =
120
- selectionColor != null ? processColor(selectionColor) : undefined;
262
+ if (isPressable) {
263
+ nativeText = (
264
+ <NativePressableText
265
+ ref={forwardedRef}
266
+ textProps={processedProps}
267
+ textPressabilityProps={textPressabilityProps ?? {}}
268
+ />
269
+ );
270
+ } else {
271
+ nativeText = <NativeText {...processedProps} ref={forwardedRef} />;
272
+ }
273
+
274
+ if (children == null) {
275
+ return nativeText;
276
+ }
277
+
278
+ // If the children do not contain a JSX element it would not be possible to have a
279
+ // nested `Text` component so we can skip adding the `TextAncestorContext` context wrapper
280
+ // which has a performance overhead. Since we do this for performance reasons we need
281
+ // to keep the check simple to avoid regressing overall perf. For this reason the
282
+ // `children.length` constant is set to `3`, this should be a reasonable tradeoff
283
+ // to capture the majority of `Text` uses but also not make this check too expensive.
284
+ if (Array.isArray(children) && children.length <= 3) {
285
+ let hasNonTextChild = false;
286
+ for (let child of children) {
287
+ if (child != null && typeof child === 'object') {
288
+ hasNonTextChild = true;
289
+ break;
290
+ }
291
+ }
292
+ if (!hasNonTextChild) {
293
+ return nativeText;
294
+ }
295
+ } else if (typeof children !== 'object') {
296
+ return nativeText;
297
+ }
121
298
 
122
- let _style = style;
123
- if (__DEV__) {
124
- if (PressabilityDebug.isEnabled() && onPress != null) {
125
- _style = [style, {color: 'magenta'}];
299
+ return <TextAncestorContext value={true}>{nativeText}</TextAncestorContext>;
300
+ };
301
+ _TextImpl = TextImplNoDefaultProps;
302
+ } else {
303
+ const TextImplLegacy: component(
304
+ ref?: React.RefSetter<TextForwardRef>,
305
+ ...props: TextProps
306
+ ) = ({
307
+ ref: forwardedRef,
308
+ accessible,
309
+ accessibilityLabel,
310
+ accessibilityState,
311
+ allowFontScaling,
312
+ 'aria-busy': ariaBusy,
313
+ 'aria-checked': ariaChecked,
314
+ 'aria-disabled': ariaDisabled,
315
+ 'aria-expanded': ariaExpanded,
316
+ 'aria-label': ariaLabel,
317
+ 'aria-selected': ariaSelected,
318
+ children,
319
+ ellipsizeMode,
320
+ disabled,
321
+ id,
322
+ nativeID,
323
+ numberOfLines,
324
+ onLongPress,
325
+ onPress,
326
+ onPressIn,
327
+ onPressOut,
328
+ onResponderGrant,
329
+ onResponderMove,
330
+ onResponderRelease,
331
+ onResponderTerminate,
332
+ onResponderTerminationRequest,
333
+ onStartShouldSetResponder,
334
+ pressRetentionOffset,
335
+ selectable,
336
+ selectionColor,
337
+ suppressHighlighting,
338
+ style,
339
+ ...restProps
340
+ }: {
341
+ ref?: React.RefSetter<TextForwardRef>,
342
+ ...TextProps,
343
+ }) => {
344
+ const _accessibilityLabel = ariaLabel ?? accessibilityLabel;
345
+
346
+ let _accessibilityState: ?TextProps['accessibilityState'] =
347
+ accessibilityState;
348
+ if (
349
+ ariaBusy != null ||
350
+ ariaChecked != null ||
351
+ ariaDisabled != null ||
352
+ ariaExpanded != null ||
353
+ ariaSelected != null
354
+ ) {
355
+ if (_accessibilityState != null) {
356
+ _accessibilityState = {
357
+ busy: ariaBusy ?? _accessibilityState.busy,
358
+ checked: ariaChecked ?? _accessibilityState.checked,
359
+ disabled: ariaDisabled ?? _accessibilityState.disabled,
360
+ expanded: ariaExpanded ?? _accessibilityState.expanded,
361
+ selected: ariaSelected ?? _accessibilityState.selected,
362
+ };
363
+ } else {
364
+ _accessibilityState = {
365
+ busy: ariaBusy,
366
+ checked: ariaChecked,
367
+ disabled: ariaDisabled,
368
+ expanded: ariaExpanded,
369
+ selected: ariaSelected,
370
+ };
371
+ }
126
372
  }
127
- }
128
373
 
129
- let _numberOfLines = numberOfLines;
130
- if (_numberOfLines != null && !(_numberOfLines >= 0)) {
374
+ const _accessibilityStateDisabled = _accessibilityState?.disabled;
375
+ const _disabled = disabled ?? _accessibilityStateDisabled;
376
+
377
+ const isPressable =
378
+ (onPress != null ||
379
+ onLongPress != null ||
380
+ onStartShouldSetResponder != null) &&
381
+ _disabled !== true;
382
+
383
+ // TODO: Move this processing to the view configuration.
384
+ const _selectionColor =
385
+ selectionColor != null ? processColor(selectionColor) : undefined;
386
+
387
+ let _style = style;
131
388
  if (__DEV__) {
132
- console.error(
133
- `'numberOfLines' in <Text> must be a non-negative number, received: ${_numberOfLines}. The value will be set to 0.`,
134
- );
389
+ if (PressabilityDebug.isEnabled() && onPress != null) {
390
+ _style = [style, {color: 'magenta'}];
391
+ }
135
392
  }
136
- _numberOfLines = 0;
137
- }
138
-
139
- let _selectable = selectable;
140
-
141
- let processedStyle = flattenStyle<TextStyleProp>(_style);
142
- if (processedStyle != null) {
143
- let overrides: ?{...TextStyleInternal} = null;
144
- if (typeof processedStyle.fontWeight === 'number') {
145
- overrides = overrides || ({}: {...TextStyleInternal});
146
- overrides.fontWeight =
147
- // $FlowFixMe[incompatible-cast]
148
- (processedStyle.fontWeight.toString(): TextStyleInternal['fontWeight']);
393
+
394
+ let _numberOfLines = numberOfLines;
395
+ if (_numberOfLines != null && !(_numberOfLines >= 0)) {
396
+ if (__DEV__) {
397
+ console.error(
398
+ `'numberOfLines' in <Text> must be a non-negative number, received: ${_numberOfLines}. The value will be set to 0.`,
399
+ );
400
+ }
401
+ _numberOfLines = 0;
149
402
  }
150
403
 
151
- if (processedStyle.userSelect != null) {
152
- _selectable = userSelectToSelectableMap[processedStyle.userSelect];
153
- overrides = overrides || ({}: {...TextStyleInternal});
154
- overrides.userSelect = undefined;
404
+ let _selectable = selectable;
405
+
406
+ let processedStyle = flattenStyle<TextStyleProp>(_style);
407
+ if (processedStyle != null) {
408
+ let overrides: ?{...TextStyleInternal} = null;
409
+ if (typeof processedStyle.fontWeight === 'number') {
410
+ overrides = overrides || ({}: {...TextStyleInternal});
411
+ overrides.fontWeight =
412
+ // $FlowFixMe[incompatible-type]
413
+ (processedStyle.fontWeight.toString(): TextStyleInternal['fontWeight']);
414
+ }
415
+
416
+ if (processedStyle.userSelect != null) {
417
+ _selectable = userSelectToSelectableMap[processedStyle.userSelect];
418
+ overrides = overrides || ({}: {...TextStyleInternal});
419
+ overrides.userSelect = undefined;
420
+ }
421
+
422
+ if (processedStyle.verticalAlign != null) {
423
+ overrides = overrides || ({}: {...TextStyleInternal});
424
+ overrides.textAlignVertical =
425
+ verticalAlignToTextAlignVerticalMap[processedStyle.verticalAlign];
426
+ overrides.verticalAlign = undefined;
427
+ }
428
+
429
+ if (overrides != null) {
430
+ // $FlowFixMe[incompatible-type]
431
+ _style = [_style, overrides];
432
+ }
155
433
  }
156
434
 
157
- if (processedStyle.verticalAlign != null) {
158
- overrides = overrides || ({}: {...TextStyleInternal});
159
- overrides.textAlignVertical =
160
- verticalAlignToTextAlignVerticalMap[processedStyle.verticalAlign];
161
- overrides.verticalAlign = undefined;
435
+ const _nativeID = id ?? nativeID;
436
+
437
+ const hasTextAncestor = useContext(TextAncestorContext);
438
+ if (hasTextAncestor) {
439
+ if (isPressable) {
440
+ return (
441
+ <NativePressableVirtualText
442
+ ref={forwardedRef}
443
+ textProps={{
444
+ ...restProps,
445
+ accessibilityLabel: _accessibilityLabel,
446
+ accessibilityState: _accessibilityState,
447
+ nativeID: _nativeID,
448
+ numberOfLines: _numberOfLines,
449
+ selectable: _selectable,
450
+ selectionColor: _selectionColor,
451
+ style: _style,
452
+ disabled: disabled,
453
+ children,
454
+ }}
455
+ textPressabilityProps={{
456
+ onLongPress,
457
+ onPress,
458
+ onPressIn,
459
+ onPressOut,
460
+ onResponderGrant,
461
+ onResponderMove,
462
+ onResponderRelease,
463
+ onResponderTerminate,
464
+ onResponderTerminationRequest,
465
+ onStartShouldSetResponder,
466
+ pressRetentionOffset,
467
+ suppressHighlighting,
468
+ }}
469
+ />
470
+ );
471
+ }
472
+
473
+ return (
474
+ <NativeVirtualText
475
+ {...restProps}
476
+ accessibilityLabel={_accessibilityLabel}
477
+ accessibilityState={_accessibilityState}
478
+ nativeID={_nativeID}
479
+ numberOfLines={_numberOfLines}
480
+ ref={forwardedRef}
481
+ selectable={_selectable}
482
+ selectionColor={_selectionColor}
483
+ style={_style}
484
+ disabled={disabled}>
485
+ {children}
486
+ </NativeVirtualText>
487
+ );
162
488
  }
163
489
 
164
- if (overrides != null) {
165
- // $FlowFixMe[incompatible-type]
166
- _style = [_style, overrides];
490
+ // If the disabled prop and accessibilityState.disabled are out of sync but not both in
491
+ // falsy states we need to update the accessibilityState object to use the disabled prop.
492
+ if (
493
+ _disabled !== _accessibilityStateDisabled &&
494
+ ((_disabled != null && _disabled !== false) ||
495
+ (_accessibilityStateDisabled != null &&
496
+ _accessibilityStateDisabled !== false))
497
+ ) {
498
+ _accessibilityState = {..._accessibilityState, disabled: _disabled};
167
499
  }
168
- }
169
500
 
170
- const _nativeID = id ?? nativeID;
501
+ const _accessible = Platform.select({
502
+ ios: accessible !== false,
503
+ android:
504
+ accessible == null
505
+ ? onPress != null || onLongPress != null
506
+ : accessible,
507
+ default: accessible,
508
+ });
171
509
 
172
- const hasTextAncestor = useContext(TextAncestorContext);
173
- if (hasTextAncestor) {
510
+ let nativeText = null;
174
511
  if (isPressable) {
175
- return (
176
- <NativePressableVirtualText
512
+ nativeText = (
513
+ <NativePressableText
177
514
  ref={forwardedRef}
178
515
  textProps={{
179
516
  ...restProps,
180
517
  accessibilityLabel: _accessibilityLabel,
181
518
  accessibilityState: _accessibilityState,
519
+ accessible: _accessible,
520
+ allowFontScaling: allowFontScaling !== false,
521
+ disabled: _disabled,
522
+ ellipsizeMode: ellipsizeMode ?? 'tail',
182
523
  nativeID: _nativeID,
183
524
  numberOfLines: _numberOfLines,
184
525
  selectable: _selectable,
185
526
  selectionColor: _selectionColor,
186
527
  style: _style,
187
- disabled: disabled,
188
528
  children,
189
529
  }}
190
530
  textPressabilityProps={{
@@ -203,127 +543,61 @@ const TextImpl: component(
203
543
  }}
204
544
  />
205
545
  );
546
+ } else {
547
+ nativeText = (
548
+ <NativeText
549
+ {...restProps}
550
+ accessibilityLabel={_accessibilityLabel}
551
+ accessibilityState={_accessibilityState}
552
+ accessible={_accessible}
553
+ allowFontScaling={allowFontScaling !== false}
554
+ disabled={_disabled}
555
+ ellipsizeMode={ellipsizeMode ?? 'tail'}
556
+ nativeID={_nativeID}
557
+ numberOfLines={_numberOfLines}
558
+ ref={forwardedRef}
559
+ selectable={_selectable}
560
+ selectionColor={_selectionColor}
561
+ style={_style}>
562
+ {children}
563
+ </NativeText>
564
+ );
206
565
  }
207
566
 
208
- return (
209
- <NativeVirtualText
210
- {...restProps}
211
- accessibilityLabel={_accessibilityLabel}
212
- accessibilityState={_accessibilityState}
213
- nativeID={_nativeID}
214
- numberOfLines={_numberOfLines}
215
- ref={forwardedRef}
216
- selectable={_selectable}
217
- selectionColor={_selectionColor}
218
- style={_style}
219
- disabled={disabled}>
220
- {children}
221
- </NativeVirtualText>
222
- );
223
- }
224
-
225
- // If the disabled prop and accessibilityState.disabled are out of sync but not both in
226
- // falsy states we need to update the accessibilityState object to use the disabled prop.
227
- if (
228
- _disabled !== _accessibilityStateDisabled &&
229
- ((_disabled != null && _disabled !== false) ||
230
- (_accessibilityStateDisabled != null &&
231
- _accessibilityStateDisabled !== false))
232
- ) {
233
- _accessibilityState = {..._accessibilityState, disabled: _disabled};
234
- }
235
-
236
- const _accessible = Platform.select({
237
- ios: accessible !== false,
238
- android:
239
- accessible == null ? onPress != null || onLongPress != null : accessible,
240
- default: accessible,
241
- });
242
-
243
- let nativeText = null;
244
- if (isPressable) {
245
- nativeText = (
246
- <NativePressableText
247
- ref={forwardedRef}
248
- textProps={{
249
- ...restProps,
250
- accessibilityLabel: _accessibilityLabel,
251
- accessibilityState: _accessibilityState,
252
- accessible: _accessible,
253
- allowFontScaling: allowFontScaling !== false,
254
- disabled: _disabled,
255
- ellipsizeMode: ellipsizeMode ?? 'tail',
256
- nativeID: _nativeID,
257
- numberOfLines: _numberOfLines,
258
- selectable: _selectable,
259
- selectionColor: _selectionColor,
260
- style: _style,
261
- children,
262
- }}
263
- textPressabilityProps={{
264
- onLongPress,
265
- onPress,
266
- onPressIn,
267
- onPressOut,
268
- onResponderGrant,
269
- onResponderMove,
270
- onResponderRelease,
271
- onResponderTerminate,
272
- onResponderTerminationRequest,
273
- onStartShouldSetResponder,
274
- pressRetentionOffset,
275
- suppressHighlighting,
276
- }}
277
- />
278
- );
279
- } else {
280
- nativeText = (
281
- <NativeText
282
- {...restProps}
283
- accessibilityLabel={_accessibilityLabel}
284
- accessibilityState={_accessibilityState}
285
- accessible={_accessible}
286
- allowFontScaling={allowFontScaling !== false}
287
- disabled={_disabled}
288
- ellipsizeMode={ellipsizeMode ?? 'tail'}
289
- nativeID={_nativeID}
290
- numberOfLines={_numberOfLines}
291
- ref={forwardedRef}
292
- selectable={_selectable}
293
- selectionColor={_selectionColor}
294
- style={_style}>
295
- {children}
296
- </NativeText>
297
- );
298
- }
299
-
300
- if (children == null) {
301
- return nativeText;
302
- }
303
-
304
- // If the children do not contain a JSX element it would not be possible to have a
305
- // nested `Text` component so we can skip adding the `TextAncestorContext` context wrapper
306
- // which has a performance overhead. Since we do this for performance reasons we need
307
- // to keep the check simple to avoid regressing overall perf. For this reason the
308
- // `children.length` constant is set to `3`, this should be a reasonable tradeoff
309
- // to capture the majority of `Text` uses but also not make this check too expensive.
310
- if (Array.isArray(children) && children.length <= 3) {
311
- let hasNonTextChild = false;
312
- for (let child of children) {
313
- if (child != null && typeof child === 'object') {
314
- hasNonTextChild = true;
315
- break;
316
- }
567
+ if (children == null) {
568
+ return nativeText;
317
569
  }
318
- if (!hasNonTextChild) {
570
+
571
+ // If the children do not contain a JSX element it would not be possible to have a
572
+ // nested `Text` component so we can skip adding the `TextAncestorContext` context wrapper
573
+ // which has a performance overhead. Since we do this for performance reasons we need
574
+ // to keep the check simple to avoid regressing overall perf. For this reason the
575
+ // `children.length` constant is set to `3`, this should be a reasonable tradeoff
576
+ // to capture the majority of `Text` uses but also not make this check too expensive.
577
+ if (Array.isArray(children) && children.length <= 3) {
578
+ let hasNonTextChild = false;
579
+ for (let child of children) {
580
+ if (child != null && typeof child === 'object') {
581
+ hasNonTextChild = true;
582
+ break;
583
+ }
584
+ }
585
+ if (!hasNonTextChild) {
586
+ return nativeText;
587
+ }
588
+ } else if (typeof children !== 'object') {
319
589
  return nativeText;
320
590
  }
321
- } else if (typeof children !== 'object') {
322
- return nativeText;
323
- }
324
591
 
325
- return <TextAncestorContext value={true}>{nativeText}</TextAncestorContext>;
326
- };
592
+ return <TextAncestorContext value={true}>{nativeText}</TextAncestorContext>;
593
+ };
594
+ _TextImpl = TextImplLegacy;
595
+ }
596
+
597
+ const TextImpl: component(
598
+ ref?: React.RefSetter<TextForwardRef>,
599
+ ...props: TextProps
600
+ ) = _TextImpl;
327
601
 
328
602
  TextImpl.displayName = 'Text';
329
603