@office-iss/react-native-win32 0.0.0-canary.256 → 0.0.0-canary.258

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 (64) hide show
  1. package/.flowconfig +4 -2
  2. package/CHANGELOG.json +79 -1
  3. package/CHANGELOG.md +32 -8
  4. package/Libraries/Components/ScrollView/ScrollView.js +124 -165
  5. package/Libraries/Core/InitializeCore.js +2 -0
  6. package/Libraries/Core/ReactNativeVersion.js +3 -3
  7. package/Libraries/Core/ReactNativeVersionCheck.win32.js +1 -1
  8. package/Libraries/Core/setUpGlobals.js +1 -0
  9. package/Libraries/Core/setUpTimers.js +19 -0
  10. package/Libraries/LogBox/Data/LogBoxData.js +39 -4
  11. package/Libraries/LogBox/Data/LogBoxLog.js +5 -2
  12. package/Libraries/LogBox/Data/parseLogBoxLog.js +22 -1
  13. package/Libraries/LogBox/LogBox.js +29 -12
  14. package/Libraries/LogBox/LogBoxNotificationContainer.js +4 -0
  15. package/Libraries/LogBox/UI/LogBoxInspector.js +8 -70
  16. package/Libraries/LogBox/UI/LogBoxInspectorBody.js +87 -0
  17. package/Libraries/LogBox/UI/LogBoxInspectorFooter.js +6 -42
  18. package/Libraries/LogBox/UI/LogBoxInspectorFooterButton.js +58 -0
  19. package/Libraries/LogBox/UI/LogBoxInspectorHeader.js +25 -74
  20. package/Libraries/LogBox/UI/LogBoxInspectorHeader.win32.js +27 -80
  21. package/Libraries/LogBox/UI/LogBoxInspectorHeaderButton.js +76 -0
  22. package/Libraries/LogBox/UI/LogBoxNotification.js +13 -152
  23. package/Libraries/LogBox/UI/LogBoxNotificationCountBadge.js +63 -0
  24. package/Libraries/LogBox/UI/LogBoxNotificationDismissButton.js +67 -0
  25. package/Libraries/LogBox/UI/LogBoxNotificationMessage.js +57 -0
  26. package/Libraries/ReactNative/AppContainer-dev.js +1 -5
  27. package/Libraries/ReactNative/AppContainer-prod.js +1 -5
  28. package/Libraries/ReactNative/AppContainer.js +0 -1
  29. package/Libraries/ReactNative/AppRegistry.js +0 -6
  30. package/Libraries/ReactNative/renderApplication.js +0 -2
  31. package/Libraries/Renderer/implementations/ReactFabric-dev.js +15690 -26405
  32. package/Libraries/Renderer/implementations/ReactFabric-prod.js +2675 -1630
  33. package/Libraries/Renderer/implementations/ReactFabric-profiling.js +2945 -1682
  34. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +16141 -27018
  35. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +2723 -1666
  36. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +2984 -1737
  37. package/Libraries/Share/Share.d.ts +16 -10
  38. package/Libraries/Share/Share.js +14 -15
  39. package/Libraries/StyleSheet/StyleSheetTypes.d.ts +19 -0
  40. package/Libraries/StyleSheet/StyleSheetTypes.js +19 -1
  41. package/Libraries/StyleSheet/processFilter.js +214 -39
  42. package/Libraries/Text/Text.js +42 -22
  43. package/Libraries/Text/Text.win32.js +42 -22
  44. package/Libraries/Text/TextNativeComponent.js +1 -1
  45. package/Libraries/Text/TextNativeComponent.win32.js +1 -1
  46. package/Libraries/Text/TextOptimized.js +538 -0
  47. package/Libraries/Utilities/ReactNativeTestTools.js +7 -24
  48. package/Libraries/__tests__/ButtonWin32-test.js +7 -6
  49. package/Libraries/promiseRejectionTrackingOptions.js +1 -0
  50. package/index.js +1 -0
  51. package/index.win32.js +1 -0
  52. package/jest/mockComponent.js +4 -1
  53. package/jest/renderer.js +25 -14
  54. package/jest/setup.js +5 -0
  55. package/overrides.json +6 -6
  56. package/package.json +26 -26
  57. package/src/private/core/components/HScrollViewNativeComponents.js +55 -0
  58. package/src/private/core/components/VScrollViewNativeComponents.js +47 -0
  59. package/src/private/core/components/useSyncOnScroll.js +48 -0
  60. package/src/private/featureflags/ReactNativeFeatureFlags.js +12 -1
  61. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +2 -1
  62. package/src/private/specs/modules/NativeDevSettings.js +1 -0
  63. package/src/private/specs/modules/NativeSampleTurboModule.js +14 -1
  64. package/src/private/webapis/idlecallbacks/specs/NativeIdleCallbacks.js +34 -0
@@ -12,11 +12,13 @@ import {ColorValue} from '../StyleSheet/StyleSheet';
12
12
  export type ShareContent =
13
13
  | {
14
14
  title?: string | undefined;
15
- message: string;
15
+ url: string;
16
+ message?: string | undefined;
16
17
  }
17
18
  | {
18
19
  title?: string | undefined;
19
- url: string;
20
+ url?: string | undefined;
21
+ message: string;
20
22
  };
21
23
 
22
24
  export type ShareOptions = {
@@ -40,29 +42,33 @@ export interface ShareStatic {
40
42
  * If the user dismissed the dialog, the Promise will still be resolved with action being `Share.dismissedAction`
41
43
  * and all the other keys being undefined.
42
44
  *
43
- * In Android, Returns a Promise which always be resolved with action being `Share.sharedAction`.
45
+ * In Android, Returns a Promise which always resolves with action being `Share.sharedAction`.
44
46
  *
45
47
  * ### Content
46
48
  *
49
+ * #### iOS
50
+ *
51
+ * - `url` - a URL to share
47
52
  * - `message` - a message to share
48
- * - `title` - title of the message
49
53
  *
50
- * #### iOS
54
+ * At least one of `URL` or `message` is required.
51
55
  *
52
- * - `url` - an URL to share
56
+ * #### Android
53
57
  *
54
- * At least one of URL and message is required.
58
+ * - `title` - title of the message (optional)
59
+ * - `message` - a message to share (often will include a URL).
55
60
  *
56
61
  * ### Options
57
62
  *
58
63
  * #### iOS
59
64
  *
60
- * - `excludedActivityTypes`
61
- * - `tintColor`
65
+ * - `subject` - a subject to share via email
66
+ * - `excludedActivityTypes`
67
+ * - `tintColor`
62
68
  *
63
69
  * #### Android
64
70
  *
65
- * - `dialogTitle`
71
+ * - `dialogTitle`
66
72
  *
67
73
  */
68
74
  share(content: ShareContent, options?: ShareOptions): Promise<ShareAction>;
@@ -15,24 +15,23 @@ const processColor = require('../StyleSheet/processColor').default;
15
15
  const Platform = require('../Utilities/Platform');
16
16
  const invariant = require('invariant');
17
17
 
18
- type Content =
18
+ export type ShareContent =
19
19
  | {
20
20
  title?: string,
21
- message: string,
22
- ...
21
+ url: string,
22
+ message?: string,
23
23
  }
24
24
  | {
25
25
  title?: string,
26
- url: string,
27
- ...
26
+ url?: string,
27
+ message: string,
28
28
  };
29
- type Options = {
29
+ export type ShareOptions = {
30
30
  dialogTitle?: string,
31
31
  excludedActivityTypes?: Array<string>,
32
32
  tintColor?: string,
33
33
  subject?: string,
34
34
  anchor?: number,
35
- ...
36
35
  };
37
36
 
38
37
  class Share {
@@ -43,21 +42,21 @@ class Share {
43
42
  * If the user dismissed the dialog, the Promise will still be resolved with action being `Share.dismissedAction`
44
43
  * and all the other keys being undefined.
45
44
  *
46
- * In Android, Returns a Promise which always be resolved with action being `Share.sharedAction`.
45
+ * In Android, Returns a Promise which always resolves with action being `Share.sharedAction`.
47
46
  *
48
47
  * ### Content
49
48
  *
50
- * - `message` - a message to share
51
- *
52
49
  * #### iOS
53
50
  *
54
51
  * - `url` - a URL to share
52
+ * - `message` - a message to share
55
53
  *
56
- * At least one of URL and message is required.
54
+ * At least one of `URL` or `message` is required.
57
55
  *
58
56
  * #### Android
59
57
  *
60
- * - `title` - title of the message
58
+ * - `title` - title of the message (optional)
59
+ * - `message` - a message to share (often will include a URL).
61
60
  *
62
61
  * ### Options
63
62
  *
@@ -73,8 +72,8 @@ class Share {
73
72
  *
74
73
  */
75
74
  static share(
76
- content: Content,
77
- options: Options = {},
75
+ content: ShareContent,
76
+ options: ShareOptions = {},
78
77
  ): Promise<{action: string, activityType: ?string}> {
79
78
  invariant(
80
79
  typeof content === 'object' && content !== null,
@@ -82,7 +81,7 @@ class Share {
82
81
  );
83
82
  invariant(
84
83
  typeof content.url === 'string' || typeof content.message === 'string',
85
- 'At least one of URL and message is required',
84
+ 'At least one of URL or message is required',
86
85
  );
87
86
  invariant(
88
87
  typeof options === 'object' && options !== null,
@@ -11,6 +11,25 @@ import {Animated} from '../Animated/Animated';
11
11
  import {ImageResizeMode} from '../Image/ImageResizeMode';
12
12
  import {ColorValue} from './StyleSheet';
13
13
 
14
+ export type FilterPrimitive =
15
+ | {brightness: number | string}
16
+ | {blur: number | string}
17
+ | {contrast: number | string}
18
+ | {grayscale: number | string}
19
+ | {'hue-rotate': number | string}
20
+ | {invert: number | string}
21
+ | {opacity: number | string}
22
+ | {saturate: number | string}
23
+ | {sepia: number | string}
24
+ | {'drop-shadow': DropShadowPrimitive | string};
25
+
26
+ export type DropShadowPrimitive = {
27
+ offsetX: number | string;
28
+ offsetY: number | string;
29
+ standardDeviation?: number | string | undefined;
30
+ color?: ColorValue | number | undefined;
31
+ };
32
+
14
33
  type FlexAlignType =
15
34
  | 'flex-start'
16
35
  | 'flex-end'
@@ -11,7 +11,6 @@
11
11
  'use strict';
12
12
 
13
13
  import type AnimatedNode from '../Animated/nodes/AnimatedNode';
14
- import type {FilterPrimitive} from '../StyleSheet/processFilter';
15
14
  import type {
16
15
  ____DangerouslyImpreciseStyle_InternalOverrides,
17
16
  ____ImageStyle_InternalOverrides,
@@ -35,6 +34,25 @@ export type EdgeInsetsValue = {
35
34
  bottom: number,
36
35
  };
37
36
 
37
+ export type FilterPrimitive =
38
+ | {brightness: number | string}
39
+ | {blur: number | string}
40
+ | {contrast: number | string}
41
+ | {grayscale: number | string}
42
+ | {'hue-rotate': number | string}
43
+ | {invert: number | string}
44
+ | {opacity: number | string}
45
+ | {saturate: number | string}
46
+ | {sepia: number | string}
47
+ | {'drop-shadow': DropShadowPrimitive | string};
48
+
49
+ export type DropShadowPrimitive = {
50
+ offsetX: number | string,
51
+ offsetY: number | string,
52
+ standardDeviation?: number | string,
53
+ color?: ____ColorValue_Internal | number,
54
+ };
55
+
38
56
  export type DimensionValue = number | string | 'auto' | AnimatedNode | null;
39
57
  export type AnimatableNumericValue = number | AnimatedNode;
40
58
 
@@ -4,64 +4,97 @@
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
- * @format
7
+ * @format strict-local
8
8
  * @flow
9
+ * @oncall react-native
9
10
  */
10
11
 
11
12
  'use strict';
12
13
 
13
- export type FilterPrimitive =
14
- | {brightness: number | string}
15
- | {blur: number | string}
16
- | {contrast: number | string}
17
- | {grayscale: number | string}
18
- | {hueRotate: number | string}
19
- | {invert: number | string}
20
- | {opacity: number | string}
21
- | {saturate: number | string}
22
- | {sepia: number | string};
14
+ import type {ColorValue} from './StyleSheet';
15
+ import type {DropShadowPrimitive, FilterPrimitive} from './StyleSheetTypes';
16
+
17
+ import processColor from './processColor';
18
+
19
+ type ParsedFilter =
20
+ | {brightness: number}
21
+ | {blur: number}
22
+ | {contrast: number}
23
+ | {grayscale: number}
24
+ | {'hue-rotate': number}
25
+ | {invert: number}
26
+ | {opacity: number}
27
+ | {saturate: number}
28
+ | {sepia: number}
29
+ | {'drop-shadow': ParsedDropShadow};
30
+
31
+ type ParsedDropShadow = {
32
+ offsetX: number,
33
+ offsetY: number,
34
+ standardDeviation?: number,
35
+ color?: ColorValue,
36
+ };
23
37
 
24
38
  export default function processFilter(
25
39
  filter: $ReadOnlyArray<FilterPrimitive> | string,
26
- ): $ReadOnlyArray<FilterPrimitive> {
27
- let result: Array<FilterPrimitive> = [];
40
+ ): $ReadOnlyArray<ParsedFilter> {
41
+ let result: Array<ParsedFilter> = [];
28
42
  if (typeof filter === 'string') {
29
- // matches on functions with args like "brightness(1.5)"
30
- const regex = new RegExp(/(\w+)\(([^)]+)\)/g);
43
+ // matches on functions with args like "drop-shadow(1.5)"
44
+ const regex = /([\w-]+)\(([^)]+)\)/g;
31
45
  let matches;
32
46
 
33
47
  while ((matches = regex.exec(filter))) {
34
- const amount = _getFilterAmount(matches[1], matches[2]);
35
-
36
- if (amount != null) {
37
- const filterPrimitive = {};
38
- // $FlowFixMe The key will be the correct one but flow can't see that.
39
- filterPrimitive[matches[1]] = amount;
40
- // $FlowFixMe The key will be the correct one but flow can't see that.
41
- result.push(filterPrimitive);
48
+ let filterName = matches[1].toLowerCase();
49
+ if (filterName === 'drop-shadow') {
50
+ const dropShadow = parseDropShadow(matches[2]);
51
+ if (dropShadow != null) {
52
+ result.push({'drop-shadow': dropShadow});
53
+ } else {
54
+ return [];
55
+ }
42
56
  } else {
43
- // If any primitive is invalid then apply none of the filters. This is how
44
- // web works and makes it clear that something is wrong becuase no
45
- // graphical effects are happening.
46
- return [];
57
+ const amount = _getFilterAmount(filterName, matches[2]);
58
+
59
+ if (amount != null) {
60
+ const filterPrimitive = {};
61
+ // $FlowFixMe The key will be the correct one but flow can't see that.
62
+ filterPrimitive[filterName] = amount;
63
+ // $FlowFixMe The key will be the correct one but flow can't see that.
64
+ result.push(filterPrimitive);
65
+ } else {
66
+ // If any primitive is invalid then apply none of the filters. This is how
67
+ // web works and makes it clear that something is wrong becuase no
68
+ // graphical effects are happening.
69
+ return [];
70
+ }
47
71
  }
48
72
  }
49
73
  } else {
50
74
  for (const filterPrimitive of filter) {
51
75
  const [filterName, filterValue] = Object.entries(filterPrimitive)[0];
52
- const amount = _getFilterAmount(filterName, filterValue);
53
-
54
- if (amount != null) {
55
- const resultObject = {};
76
+ if (filterName === 'drop-shadow') {
56
77
  // $FlowFixMe
57
- resultObject[filterName] = amount;
58
- // $FlowFixMe
59
- result.push(resultObject);
78
+ const dropShadow = parseDropShadow(filterValue);
79
+ if (dropShadow == null) {
80
+ return [];
81
+ }
82
+ result.push({'drop-shadow': dropShadow});
60
83
  } else {
61
- // If any primitive is invalid then apply none of the filters. This is how
62
- // web works and makes it clear that something is wrong becuase no
63
- // graphical effects are happening.
64
- return [];
84
+ const amount = _getFilterAmount(filterName, filterValue);
85
+
86
+ if (amount != null) {
87
+ const resultObject = {};
88
+ // $FlowFixMe
89
+ resultObject[filterName] = amount;
90
+ // $FlowFixMe
91
+ result.push(resultObject);
92
+ } else {
93
+ // If any primitive is invalid then apply none of the filters. This is how
94
+ // web works and makes it clear that something is wrong becuase no
95
+ // graphical effects are happening.
96
+ return [];
97
+ }
65
98
  }
66
99
  }
67
100
  }
@@ -92,7 +125,7 @@ function _getFilterAmount(filterName: string, filterArgs: mixed): ?number {
92
125
  switch (filterName) {
93
126
  // Hue rotate takes some angle that can have a unit and can be
94
127
  // negative. Additionally, 0 with no unit is allowed.
95
- case 'hueRotate':
128
+ case 'hue-rotate':
96
129
  if (filterArgAsNumber === 0) {
97
130
  return 0;
98
131
  }
@@ -130,3 +163,145 @@ function _getFilterAmount(filterName: string, filterArgs: mixed): ?number {
130
163
  return undefined;
131
164
  }
132
165
  }
166
+
167
+ function parseDropShadow(
168
+ rawDropShadow: string | DropShadowPrimitive,
169
+ ): ?ParsedDropShadow {
170
+ const dropShadow =
171
+ typeof rawDropShadow === 'string'
172
+ ? parseDropShadowString(rawDropShadow)
173
+ : rawDropShadow;
174
+
175
+ const parsedDropShadow: ParsedDropShadow = {
176
+ offsetX: 0,
177
+ offsetY: 0,
178
+ };
179
+ let offsetX: number;
180
+ let offsetY: number;
181
+
182
+ for (const arg in dropShadow) {
183
+ let value;
184
+ switch (arg) {
185
+ case 'offsetX':
186
+ value =
187
+ typeof dropShadow.offsetX === 'string'
188
+ ? parseLength(dropShadow.offsetX)
189
+ : dropShadow.offsetX;
190
+ if (value == null) {
191
+ return null;
192
+ }
193
+ offsetX = value;
194
+ break;
195
+ case 'offsetY':
196
+ value =
197
+ typeof dropShadow.offsetY === 'string'
198
+ ? parseLength(dropShadow.offsetY)
199
+ : dropShadow.offsetY;
200
+ if (value == null) {
201
+ return null;
202
+ }
203
+ offsetY = value;
204
+ break;
205
+ case 'standardDeviation':
206
+ value =
207
+ typeof dropShadow.standardDeviation === 'string'
208
+ ? parseLength(dropShadow.standardDeviation)
209
+ : dropShadow.standardDeviation;
210
+ if (value == null || value < 0) {
211
+ return null;
212
+ }
213
+ parsedDropShadow.standardDeviation = value;
214
+ break;
215
+ case 'color':
216
+ const color = processColor(dropShadow.color);
217
+ if (color == null) {
218
+ return null;
219
+ }
220
+ parsedDropShadow.color = color;
221
+ break;
222
+ default:
223
+ return null;
224
+ }
225
+ }
226
+
227
+ if (offsetX == null || offsetY == null) {
228
+ return null;
229
+ }
230
+
231
+ parsedDropShadow.offsetX = offsetX;
232
+ parsedDropShadow.offsetY = offsetY;
233
+
234
+ return parsedDropShadow;
235
+ }
236
+
237
+ function parseDropShadowString(rawDropShadow: string): ?DropShadowPrimitive {
238
+ const dropShadow: DropShadowPrimitive = {
239
+ offsetX: 0,
240
+ offsetY: 0,
241
+ };
242
+ let offsetX: string;
243
+ let offsetY: string;
244
+ let lengthCount = 0;
245
+ let keywordDetectedAfterLength = false;
246
+
247
+ // split on all whitespaces
248
+ for (const arg of rawDropShadow.split(/\s+/)) {
249
+ const processedColor = processColor(arg);
250
+ if (processedColor != null) {
251
+ if (dropShadow.color != null) {
252
+ return null;
253
+ }
254
+ if (offsetX != null) {
255
+ keywordDetectedAfterLength = true;
256
+ }
257
+ dropShadow.color = arg;
258
+ continue;
259
+ }
260
+
261
+ switch (lengthCount) {
262
+ case 0:
263
+ offsetX = arg;
264
+ lengthCount++;
265
+ break;
266
+ case 1:
267
+ if (keywordDetectedAfterLength) {
268
+ return null;
269
+ }
270
+ offsetY = arg;
271
+ lengthCount++;
272
+ break;
273
+ case 2:
274
+ if (keywordDetectedAfterLength) {
275
+ return null;
276
+ }
277
+ dropShadow.standardDeviation = arg;
278
+ lengthCount++;
279
+ break;
280
+ default:
281
+ return null;
282
+ }
283
+ }
284
+ if (offsetX == null || offsetY == null) {
285
+ return null;
286
+ }
287
+
288
+ dropShadow.offsetX = offsetX;
289
+ dropShadow.offsetY = offsetY;
290
+ return dropShadow;
291
+ }
292
+
293
+ function parseLength(length: string): ?number {
294
+ // matches on args with units like "1.5 5% -80deg"
295
+ const argsWithUnitsRegex = /([+-]?\d*(\.\d+)?)([\w\W]+)?/g;
296
+ const match = argsWithUnitsRegex.exec(length);
297
+
298
+ if (!match || Number.isNaN(match[1])) {
299
+ return null;
300
+ }
301
+
302
+ if (match[3] != null && match[3] !== 'px') {
303
+ return null;
304
+ }
305
+
306
+ return Number(match[1]);
307
+ }
@@ -11,6 +11,7 @@
11
11
  import type {PressEvent} from '../Types/CoreEventTypes';
12
12
  import type {TextProps} from './TextProps';
13
13
 
14
+ import * as ReactNativeFeatureFlags from '../../src/private/featureflags/ReactNativeFeatureFlags';
14
15
  import * as PressabilityDebug from '../Pressability/PressabilityDebug';
15
16
  import usePressability from '../Pressability/usePressability';
16
17
  import flattenStyle from '../StyleSheet/flattenStyle';
@@ -18,6 +19,7 @@ import processColor from '../StyleSheet/processColor';
18
19
  import Platform from '../Utilities/Platform';
19
20
  import TextAncestor from './TextAncestor';
20
21
  import {NativeText, NativeVirtualText} from './TextNativeComponent';
22
+ import TextOptimized from './TextOptimized';
21
23
  import * as React from 'react';
22
24
  import {useContext, useMemo, useState} from 'react';
23
25
 
@@ -26,7 +28,7 @@ import {useContext, useMemo, useState} from 'react';
26
28
  *
27
29
  * @see https://reactnative.dev/docs/text
28
30
  */
29
- const Text: React.AbstractComponent<
31
+ const TextLegacy: React.AbstractComponent<
30
32
  TextProps,
31
33
  React.ElementRef<typeof NativeText | typeof NativeVirtualText>,
32
34
  > = React.forwardRef((props: TextProps, forwardedRef) => {
@@ -42,8 +44,10 @@ const Text: React.AbstractComponent<
42
44
  'aria-label': ariaLabel,
43
45
  'aria-selected': ariaSelected,
44
46
  ellipsizeMode,
47
+ disabled,
45
48
  id,
46
49
  nativeID,
50
+ numberOfLines,
47
51
  onLongPress,
48
52
  onPress,
49
53
  onPressIn,
@@ -55,7 +59,10 @@ const Text: React.AbstractComponent<
55
59
  onResponderTerminationRequest,
56
60
  onStartShouldSetResponder,
57
61
  pressRetentionOffset,
62
+ selectable,
63
+ selectionColor,
58
64
  suppressHighlighting,
65
+ style,
59
66
  ...restProps
60
67
  } = props;
61
68
 
@@ -92,7 +99,7 @@ const Text: React.AbstractComponent<
92
99
  }
93
100
 
94
101
  const _accessibilityStateDisabled = _accessibilityState?.disabled;
95
- const _disabled = restProps.disabled ?? _accessibilityStateDisabled;
102
+ const _disabled = disabled ?? _accessibilityStateDisabled;
96
103
 
97
104
  const isPressable =
98
105
  (onPress != null ||
@@ -195,29 +202,28 @@ const Text: React.AbstractComponent<
195
202
  );
196
203
 
197
204
  // TODO: Move this processing to the view configuration.
198
- const selectionColor =
199
- restProps.selectionColor == null
200
- ? null
201
- : processColor(restProps.selectionColor);
205
+ const _selectionColor =
206
+ selectionColor == null ? null : processColor(selectionColor);
202
207
 
203
- let style = restProps.style;
208
+ let _style = style;
204
209
  if (__DEV__) {
205
210
  if (PressabilityDebug.isEnabled() && onPress != null) {
206
- style = [restProps.style, {color: 'magenta'}];
211
+ _style = [style, {color: 'magenta'}];
207
212
  }
208
213
  }
209
214
 
210
- let numberOfLines = restProps.numberOfLines;
211
- if (numberOfLines != null && !(numberOfLines >= 0)) {
212
- console.error(
213
- `'numberOfLines' in <Text> must be a non-negative number, received: ${numberOfLines}. The value will be set to 0.`,
214
- );
215
- numberOfLines = 0;
215
+ let _numberOfLines = numberOfLines;
216
+ if (_numberOfLines != null && !(_numberOfLines >= 0)) {
217
+ if (__DEV__) {
218
+ console.error(
219
+ `'numberOfLines' in <Text> must be a non-negative number, received: ${_numberOfLines}. The value will be set to 0.`,
220
+ );
221
+ }
222
+ _numberOfLines = 0;
216
223
  }
217
224
 
218
- let _selectable = restProps.selectable;
219
-
220
- const processedStyle = flattenStyle(style);
225
+ let _selectable = selectable;
226
+ const processedStyle = flattenStyle(_style);
221
227
  if (processedStyle != null) {
222
228
  if (typeof processedStyle.fontWeight === 'number') {
223
229
  // $FlowFixMe[cannot-write]
@@ -252,11 +258,12 @@ const Text: React.AbstractComponent<
252
258
  isHighlighted={isHighlighted}
253
259
  isPressable={isPressable}
254
260
  nativeID={_nativeID}
255
- numberOfLines={numberOfLines}
261
+ numberOfLines={_numberOfLines}
256
262
  ref={forwardedRef}
257
263
  selectable={_selectable}
258
- selectionColor={selectionColor}
264
+ selectionColor={_selectionColor}
259
265
  style={processedStyle}
266
+ disabled={disabled}
260
267
  />
261
268
  );
262
269
  }
@@ -292,17 +299,17 @@ const Text: React.AbstractComponent<
292
299
  ellipsizeMode={ellipsizeMode ?? 'tail'}
293
300
  isHighlighted={isHighlighted}
294
301
  nativeID={_nativeID}
295
- numberOfLines={numberOfLines}
302
+ numberOfLines={_numberOfLines}
296
303
  ref={forwardedRef}
297
304
  selectable={_selectable}
298
- selectionColor={selectionColor}
305
+ selectionColor={_selectionColor}
299
306
  style={processedStyle}
300
307
  />
301
308
  </TextAncestor.Provider>
302
309
  );
303
310
  });
304
311
 
305
- Text.displayName = 'Text';
312
+ TextLegacy.displayName = 'TextLegacy';
306
313
 
307
314
  /**
308
315
  * Returns false until the first time `newValue` is true, after which this will
@@ -332,4 +339,17 @@ const verticalAlignToTextAlignVerticalMap = {
332
339
  middle: 'center',
333
340
  };
334
341
 
342
+ const Text: React.AbstractComponent<
343
+ TextProps,
344
+ React.ElementRef<typeof NativeText | typeof NativeVirtualText>,
345
+ > = React.forwardRef((props: TextProps, forwardedRef) => {
346
+ if (ReactNativeFeatureFlags.shouldUseOptimizedText()) {
347
+ return <TextOptimized {...props} ref={forwardedRef} />;
348
+ } else {
349
+ return <TextLegacy {...props} ref={forwardedRef} />;
350
+ }
351
+ });
352
+
353
+ Text.displayName = 'Text';
354
+
335
355
  module.exports = Text;