@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.
- package/.flowconfig +4 -2
- package/CHANGELOG.json +79 -1
- package/CHANGELOG.md +32 -8
- package/Libraries/Components/ScrollView/ScrollView.js +124 -165
- package/Libraries/Core/InitializeCore.js +2 -0
- package/Libraries/Core/ReactNativeVersion.js +3 -3
- package/Libraries/Core/ReactNativeVersionCheck.win32.js +1 -1
- package/Libraries/Core/setUpGlobals.js +1 -0
- package/Libraries/Core/setUpTimers.js +19 -0
- package/Libraries/LogBox/Data/LogBoxData.js +39 -4
- package/Libraries/LogBox/Data/LogBoxLog.js +5 -2
- package/Libraries/LogBox/Data/parseLogBoxLog.js +22 -1
- package/Libraries/LogBox/LogBox.js +29 -12
- package/Libraries/LogBox/LogBoxNotificationContainer.js +4 -0
- package/Libraries/LogBox/UI/LogBoxInspector.js +8 -70
- package/Libraries/LogBox/UI/LogBoxInspectorBody.js +87 -0
- package/Libraries/LogBox/UI/LogBoxInspectorFooter.js +6 -42
- package/Libraries/LogBox/UI/LogBoxInspectorFooterButton.js +58 -0
- package/Libraries/LogBox/UI/LogBoxInspectorHeader.js +25 -74
- package/Libraries/LogBox/UI/LogBoxInspectorHeader.win32.js +27 -80
- package/Libraries/LogBox/UI/LogBoxInspectorHeaderButton.js +76 -0
- package/Libraries/LogBox/UI/LogBoxNotification.js +13 -152
- package/Libraries/LogBox/UI/LogBoxNotificationCountBadge.js +63 -0
- package/Libraries/LogBox/UI/LogBoxNotificationDismissButton.js +67 -0
- package/Libraries/LogBox/UI/LogBoxNotificationMessage.js +57 -0
- package/Libraries/ReactNative/AppContainer-dev.js +1 -5
- package/Libraries/ReactNative/AppContainer-prod.js +1 -5
- package/Libraries/ReactNative/AppContainer.js +0 -1
- package/Libraries/ReactNative/AppRegistry.js +0 -6
- package/Libraries/ReactNative/renderApplication.js +0 -2
- package/Libraries/Renderer/implementations/ReactFabric-dev.js +15690 -26405
- package/Libraries/Renderer/implementations/ReactFabric-prod.js +2675 -1630
- package/Libraries/Renderer/implementations/ReactFabric-profiling.js +2945 -1682
- package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +16141 -27018
- package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +2723 -1666
- package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +2984 -1737
- package/Libraries/Share/Share.d.ts +16 -10
- package/Libraries/Share/Share.js +14 -15
- package/Libraries/StyleSheet/StyleSheetTypes.d.ts +19 -0
- package/Libraries/StyleSheet/StyleSheetTypes.js +19 -1
- package/Libraries/StyleSheet/processFilter.js +214 -39
- package/Libraries/Text/Text.js +42 -22
- package/Libraries/Text/Text.win32.js +42 -22
- package/Libraries/Text/TextNativeComponent.js +1 -1
- package/Libraries/Text/TextNativeComponent.win32.js +1 -1
- package/Libraries/Text/TextOptimized.js +538 -0
- package/Libraries/Utilities/ReactNativeTestTools.js +7 -24
- package/Libraries/__tests__/ButtonWin32-test.js +7 -6
- package/Libraries/promiseRejectionTrackingOptions.js +1 -0
- package/index.js +1 -0
- package/index.win32.js +1 -0
- package/jest/mockComponent.js +4 -1
- package/jest/renderer.js +25 -14
- package/jest/setup.js +5 -0
- package/overrides.json +6 -6
- package/package.json +26 -26
- package/src/private/core/components/HScrollViewNativeComponents.js +55 -0
- package/src/private/core/components/VScrollViewNativeComponents.js +47 -0
- package/src/private/core/components/useSyncOnScroll.js +48 -0
- package/src/private/featureflags/ReactNativeFeatureFlags.js +12 -1
- package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +2 -1
- package/src/private/specs/modules/NativeDevSettings.js +1 -0
- package/src/private/specs/modules/NativeSampleTurboModule.js +14 -1
- 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
|
-
|
|
15
|
+
url: string;
|
|
16
|
+
message?: string | undefined;
|
|
16
17
|
}
|
|
17
18
|
| {
|
|
18
19
|
title?: string | undefined;
|
|
19
|
-
url
|
|
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
|
|
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
|
-
*
|
|
54
|
+
* At least one of `URL` or `message` is required.
|
|
51
55
|
*
|
|
52
|
-
*
|
|
56
|
+
* #### Android
|
|
53
57
|
*
|
|
54
|
-
*
|
|
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
|
-
*
|
|
61
|
-
*
|
|
65
|
+
* - `subject` - a subject to share via email
|
|
66
|
+
* - `excludedActivityTypes`
|
|
67
|
+
* - `tintColor`
|
|
62
68
|
*
|
|
63
69
|
* #### Android
|
|
64
70
|
*
|
|
65
|
-
*
|
|
71
|
+
* - `dialogTitle`
|
|
66
72
|
*
|
|
67
73
|
*/
|
|
68
74
|
share(content: ShareContent, options?: ShareOptions): Promise<ShareAction>;
|
package/Libraries/Share/Share.js
CHANGED
|
@@ -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
|
|
18
|
+
export type ShareContent =
|
|
19
19
|
| {
|
|
20
20
|
title?: string,
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
url: string,
|
|
22
|
+
message?: string,
|
|
23
23
|
}
|
|
24
24
|
| {
|
|
25
25
|
title?: string,
|
|
26
|
-
url
|
|
27
|
-
|
|
26
|
+
url?: string,
|
|
27
|
+
message: string,
|
|
28
28
|
};
|
|
29
|
-
type
|
|
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
|
|
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
|
|
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:
|
|
77
|
-
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
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
| {
|
|
20
|
-
| {
|
|
21
|
-
| {
|
|
22
|
-
| {
|
|
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<
|
|
27
|
-
let result: Array<
|
|
40
|
+
): $ReadOnlyArray<ParsedFilter> {
|
|
41
|
+
let result: Array<ParsedFilter> = [];
|
|
28
42
|
if (typeof filter === 'string') {
|
|
29
|
-
// matches on functions with args like "
|
|
30
|
-
const regex =
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
if (amount != null) {
|
|
55
|
-
const resultObject = {};
|
|
76
|
+
if (filterName === 'drop-shadow') {
|
|
56
77
|
// $FlowFixMe
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
78
|
+
const dropShadow = parseDropShadow(filterValue);
|
|
79
|
+
if (dropShadow == null) {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
result.push({'drop-shadow': dropShadow});
|
|
60
83
|
} else {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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 '
|
|
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
|
+
}
|
package/Libraries/Text/Text.js
CHANGED
|
@@ -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
|
|
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 =
|
|
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
|
|
199
|
-
|
|
200
|
-
? null
|
|
201
|
-
: processColor(restProps.selectionColor);
|
|
205
|
+
const _selectionColor =
|
|
206
|
+
selectionColor == null ? null : processColor(selectionColor);
|
|
202
207
|
|
|
203
|
-
let
|
|
208
|
+
let _style = style;
|
|
204
209
|
if (__DEV__) {
|
|
205
210
|
if (PressabilityDebug.isEnabled() && onPress != null) {
|
|
206
|
-
|
|
211
|
+
_style = [style, {color: 'magenta'}];
|
|
207
212
|
}
|
|
208
213
|
}
|
|
209
214
|
|
|
210
|
-
let
|
|
211
|
-
if (
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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 =
|
|
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={
|
|
261
|
+
numberOfLines={_numberOfLines}
|
|
256
262
|
ref={forwardedRef}
|
|
257
263
|
selectable={_selectable}
|
|
258
|
-
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={
|
|
302
|
+
numberOfLines={_numberOfLines}
|
|
296
303
|
ref={forwardedRef}
|
|
297
304
|
selectable={_selectable}
|
|
298
|
-
selectionColor={
|
|
305
|
+
selectionColor={_selectionColor}
|
|
299
306
|
style={processedStyle}
|
|
300
307
|
/>
|
|
301
308
|
</TextAncestor.Provider>
|
|
302
309
|
);
|
|
303
310
|
});
|
|
304
311
|
|
|
305
|
-
|
|
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;
|