@office-iss/react-native-win32 0.0.0-canary.257 → 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 +40 -1
- package/CHANGELOG.md +20 -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/LogBox/UI/LogBoxInspectorHeader.js +20 -8
- package/Libraries/LogBox/UI/LogBoxInspectorHeader.win32.js +20 -8
- 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/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 +17 -2
- package/Libraries/Text/Text.win32.js +17 -2
- package/index.js +1 -0
- package/index.win32.js +1 -0
- package/jest/mockComponent.js +4 -1
- package/overrides.json +5 -5
- package/package.json +22 -22
- 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/NativeSampleTurboModule.js +14 -1
|
@@ -36,7 +36,7 @@ const checkVersions = function checkVersions(): void {
|
|
|
36
36
|
`Native version: ${_formatVersion(nativeVersion)}\n\n` +
|
|
37
37
|
'Make sure that you have rebuilt the native code. If the problem ' +
|
|
38
38
|
'persists try clearing the Watchman and packager caches with ' +
|
|
39
|
-
'`watchman watch-del-all && npx react-native start --reset-cache`.',
|
|
39
|
+
'`watchman watch-del-all && npx @react-native-community/cli start --reset-cache`.',
|
|
40
40
|
);
|
|
41
41
|
}
|
|
42
42
|
};
|
|
@@ -8,9 +8,10 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import type {ViewProps} from '../../Components/View/ViewPropTypes';
|
|
11
12
|
import type {LogLevel} from '../Data/LogBoxLog';
|
|
12
13
|
|
|
13
|
-
import
|
|
14
|
+
import SafeAreaView from '../../Components/SafeAreaView/SafeAreaView';
|
|
14
15
|
import View from '../../Components/View/View';
|
|
15
16
|
import StyleSheet from '../../StyleSheet/StyleSheet';
|
|
16
17
|
import Text from '../../Text/Text';
|
|
@@ -26,16 +27,30 @@ type Props = $ReadOnly<{
|
|
|
26
27
|
level: LogLevel,
|
|
27
28
|
}>;
|
|
28
29
|
|
|
30
|
+
const LogBoxInspectorHeaderSafeArea: React.AbstractComponent<ViewProps> =
|
|
31
|
+
Platform.OS === 'android'
|
|
32
|
+
? function LogBoxInspectorHeaderSafeArea(props) {
|
|
33
|
+
// NOTE: Inline the import of `StatusBar` so that initializing this module
|
|
34
|
+
// does not require initializing a TurboModule (and main thread one, too).
|
|
35
|
+
const {currentHeight} = require('../../Components/StatusBar/StatusBar');
|
|
36
|
+
const style = StyleSheet.compose(
|
|
37
|
+
{paddingTop: currentHeight},
|
|
38
|
+
props.style,
|
|
39
|
+
);
|
|
40
|
+
return <View {...props} style={style} />;
|
|
41
|
+
}
|
|
42
|
+
: SafeAreaView;
|
|
43
|
+
|
|
29
44
|
export default function LogBoxInspectorHeader(props: Props): React.Node {
|
|
30
45
|
if (props.level === 'syntax') {
|
|
31
46
|
return (
|
|
32
|
-
<
|
|
47
|
+
<LogBoxInspectorHeaderSafeArea style={styles[props.level]}>
|
|
33
48
|
<View style={styles.header}>
|
|
34
49
|
<View style={styles.title}>
|
|
35
50
|
<Text style={styles.titleText}>Failed to compile</Text>
|
|
36
51
|
</View>
|
|
37
52
|
</View>
|
|
38
|
-
</
|
|
53
|
+
</LogBoxInspectorHeaderSafeArea>
|
|
39
54
|
);
|
|
40
55
|
}
|
|
41
56
|
|
|
@@ -47,7 +62,7 @@ export default function LogBoxInspectorHeader(props: Props): React.Node {
|
|
|
47
62
|
const titleText = `Log ${props.selectedIndex + 1} of ${props.total}`;
|
|
48
63
|
|
|
49
64
|
return (
|
|
50
|
-
<
|
|
65
|
+
<LogBoxInspectorHeaderSafeArea style={styles[props.level]}>
|
|
51
66
|
<View style={styles.header}>
|
|
52
67
|
<LogBoxInspectorHeaderButton
|
|
53
68
|
disabled={props.total <= 1}
|
|
@@ -65,7 +80,7 @@ export default function LogBoxInspectorHeader(props: Props): React.Node {
|
|
|
65
80
|
onPress={() => props.onSelectIndex(nextIndex)}
|
|
66
81
|
/>
|
|
67
82
|
</View>
|
|
68
|
-
</
|
|
83
|
+
</LogBoxInspectorHeaderSafeArea>
|
|
69
84
|
);
|
|
70
85
|
}
|
|
71
86
|
|
|
@@ -101,7 +116,4 @@ const styles = StyleSheet.create({
|
|
|
101
116
|
includeFontPadding: false,
|
|
102
117
|
lineHeight: 20,
|
|
103
118
|
},
|
|
104
|
-
safeArea: {
|
|
105
|
-
paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 40,
|
|
106
|
-
},
|
|
107
119
|
});
|
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
|
+
import type {ViewProps} from '../../Components/View/ViewPropTypes';
|
|
13
14
|
import type {LogLevel} from '../Data/LogBoxLog';
|
|
14
15
|
|
|
15
|
-
import
|
|
16
|
+
import SafeAreaView from '../../Components/SafeAreaView/SafeAreaView';
|
|
16
17
|
import View from '../../Components/View/View';
|
|
17
18
|
import StyleSheet from '../../StyleSheet/StyleSheet';
|
|
18
19
|
import Text from '../../Text/Text';
|
|
@@ -28,16 +29,30 @@ type Props = $ReadOnly<{
|
|
|
28
29
|
level: LogLevel,
|
|
29
30
|
}>;
|
|
30
31
|
|
|
32
|
+
const LogBoxInspectorHeaderSafeArea: React.AbstractComponent<ViewProps> =
|
|
33
|
+
Platform.OS === 'android'
|
|
34
|
+
? function LogBoxInspectorHeaderSafeArea(props) {
|
|
35
|
+
// NOTE: Inline the import of `StatusBar` so that initializing this module
|
|
36
|
+
// does not require initializing a TurboModule (and main thread one, too).
|
|
37
|
+
const {currentHeight} = require('../../Components/StatusBar/StatusBar');
|
|
38
|
+
const style = StyleSheet.compose(
|
|
39
|
+
{paddingTop: currentHeight},
|
|
40
|
+
props.style,
|
|
41
|
+
);
|
|
42
|
+
return <View {...props} style={style} />;
|
|
43
|
+
}
|
|
44
|
+
: SafeAreaView;
|
|
45
|
+
|
|
31
46
|
export default function LogBoxInspectorHeader(props: Props): React.Node {
|
|
32
47
|
if (props.level === 'syntax') {
|
|
33
48
|
return (
|
|
34
|
-
<
|
|
49
|
+
<LogBoxInspectorHeaderSafeArea style={styles[props.level]}>
|
|
35
50
|
<View style={styles.header}>
|
|
36
51
|
<View style={styles.title}>
|
|
37
52
|
<Text style={styles.titleText}>Failed to compile</Text>
|
|
38
53
|
</View>
|
|
39
54
|
</View>
|
|
40
|
-
</
|
|
55
|
+
</LogBoxInspectorHeaderSafeArea>
|
|
41
56
|
);
|
|
42
57
|
}
|
|
43
58
|
|
|
@@ -49,7 +64,7 @@ export default function LogBoxInspectorHeader(props: Props): React.Node {
|
|
|
49
64
|
const titleText = `Log ${props.selectedIndex + 1} of ${props.total}`;
|
|
50
65
|
|
|
51
66
|
return (
|
|
52
|
-
<
|
|
67
|
+
<LogBoxInspectorHeaderSafeArea style={styles[props.level]}>
|
|
53
68
|
<View style={styles.header}>
|
|
54
69
|
<LogBoxInspectorHeaderButton
|
|
55
70
|
disabled={props.total <= 1}
|
|
@@ -67,7 +82,7 @@ export default function LogBoxInspectorHeader(props: Props): React.Node {
|
|
|
67
82
|
onPress={() => props.onSelectIndex(nextIndex)}
|
|
68
83
|
/>
|
|
69
84
|
</View>
|
|
70
|
-
</
|
|
85
|
+
</LogBoxInspectorHeaderSafeArea>
|
|
71
86
|
);
|
|
72
87
|
}
|
|
73
88
|
|
|
@@ -106,7 +121,4 @@ const styles = StyleSheet.create({
|
|
|
106
121
|
includeFontPadding: false,
|
|
107
122
|
lineHeight: 20,
|
|
108
123
|
},
|
|
109
|
-
safeArea: {
|
|
110
|
-
paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 40,
|
|
111
|
-
},
|
|
112
124
|
});
|
|
@@ -90,7 +90,6 @@ const AppContainer = ({
|
|
|
90
90
|
internal_excludeInspector = false,
|
|
91
91
|
internal_excludeLogBox = false,
|
|
92
92
|
rootTag,
|
|
93
|
-
showArchitectureIndicator,
|
|
94
93
|
WrapperComponent,
|
|
95
94
|
rootViewStyle,
|
|
96
95
|
}: Props): React.Node => {
|
|
@@ -150,10 +149,7 @@ const AppContainer = ({
|
|
|
150
149
|
|
|
151
150
|
if (WrapperComponent != null) {
|
|
152
151
|
innerView = (
|
|
153
|
-
<WrapperComponent
|
|
154
|
-
initialProps={initialProps}
|
|
155
|
-
fabric={fabric === true}
|
|
156
|
-
showArchitectureIndicator={showArchitectureIndicator === true}>
|
|
152
|
+
<WrapperComponent initialProps={initialProps} fabric={fabric === true}>
|
|
157
153
|
{innerView}
|
|
158
154
|
</WrapperComponent>
|
|
159
155
|
);
|
|
@@ -21,7 +21,6 @@ const AppContainer = ({
|
|
|
21
21
|
fabric,
|
|
22
22
|
initialProps,
|
|
23
23
|
rootTag,
|
|
24
|
-
showArchitectureIndicator,
|
|
25
24
|
WrapperComponent,
|
|
26
25
|
rootViewStyle,
|
|
27
26
|
}: Props): React.Node => {
|
|
@@ -29,10 +28,7 @@ const AppContainer = ({
|
|
|
29
28
|
|
|
30
29
|
if (WrapperComponent != null) {
|
|
31
30
|
innerView = (
|
|
32
|
-
<WrapperComponent
|
|
33
|
-
initialProps={initialProps}
|
|
34
|
-
fabric={fabric === true}
|
|
35
|
-
showArchitectureIndicator={showArchitectureIndicator === true}>
|
|
31
|
+
<WrapperComponent initialProps={initialProps} fabric={fabric === true}>
|
|
36
32
|
{innerView}
|
|
37
33
|
</WrapperComponent>
|
|
38
34
|
);
|
|
@@ -18,7 +18,6 @@ export type Props = $ReadOnly<{|
|
|
|
18
18
|
fabric?: boolean,
|
|
19
19
|
rootTag: number | RootTag,
|
|
20
20
|
initialProps?: {...},
|
|
21
|
-
showArchitectureIndicator?: boolean,
|
|
22
21
|
WrapperComponent?: ?React.ComponentType<any>,
|
|
23
22
|
rootViewStyle?: ?ViewStyleProp,
|
|
24
23
|
internal_excludeLogBox?: boolean,
|
|
@@ -73,7 +73,6 @@ let componentProviderInstrumentationHook: ComponentProviderInstrumentationHook =
|
|
|
73
73
|
|
|
74
74
|
let wrapperComponentProvider: ?WrapperComponentProvider;
|
|
75
75
|
let rootViewStyleProvider: ?RootViewStyleProvider;
|
|
76
|
-
let showArchitectureIndicator = false;
|
|
77
76
|
|
|
78
77
|
/**
|
|
79
78
|
* `AppRegistry` is the JavaScript entry point to running all React Native apps.
|
|
@@ -89,10 +88,6 @@ const AppRegistry = {
|
|
|
89
88
|
rootViewStyleProvider = provider;
|
|
90
89
|
},
|
|
91
90
|
|
|
92
|
-
enableArchitectureIndicator(enabled: boolean): void {
|
|
93
|
-
showArchitectureIndicator = enabled;
|
|
94
|
-
},
|
|
95
|
-
|
|
96
91
|
registerConfig(config: Array<AppConfig>): void {
|
|
97
92
|
config.forEach(appConfig => {
|
|
98
93
|
if (appConfig.run) {
|
|
@@ -139,7 +134,6 @@ const AppRegistry = {
|
|
|
139
134
|
wrapperComponentProvider && wrapperComponentProvider(appParameters),
|
|
140
135
|
rootViewStyleProvider && rootViewStyleProvider(appParameters),
|
|
141
136
|
appParameters.fabric,
|
|
142
|
-
showArchitectureIndicator,
|
|
143
137
|
scopedPerformanceLogger,
|
|
144
138
|
appKey === 'LogBox', // is logbox
|
|
145
139
|
appKey,
|
|
@@ -35,7 +35,6 @@ export default function renderApplication<Props: Object>(
|
|
|
35
35
|
WrapperComponent?: ?React.ComponentType<any>,
|
|
36
36
|
rootViewStyle?: ?ViewStyleProp,
|
|
37
37
|
fabric?: boolean,
|
|
38
|
-
showArchitectureIndicator?: boolean,
|
|
39
38
|
scopedPerformanceLogger?: IPerformanceLogger,
|
|
40
39
|
isLogBox?: boolean,
|
|
41
40
|
debugName?: string,
|
|
@@ -52,7 +51,6 @@ export default function renderApplication<Props: Object>(
|
|
|
52
51
|
<AppContainer
|
|
53
52
|
rootTag={rootTag}
|
|
54
53
|
fabric={fabric}
|
|
55
|
-
showArchitectureIndicator={showArchitectureIndicator}
|
|
56
54
|
WrapperComponent={WrapperComponent}
|
|
57
55
|
rootViewStyle={rootViewStyle}
|
|
58
56
|
initialProps={initialProps ?? Object.freeze({})}
|
|
@@ -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) => {
|
|
@@ -307,7 +309,7 @@ const Text: React.AbstractComponent<
|
|
|
307
309
|
);
|
|
308
310
|
});
|
|
309
311
|
|
|
310
|
-
|
|
312
|
+
TextLegacy.displayName = 'TextLegacy';
|
|
311
313
|
|
|
312
314
|
/**
|
|
313
315
|
* Returns false until the first time `newValue` is true, after which this will
|
|
@@ -337,4 +339,17 @@ const verticalAlignToTextAlignVerticalMap = {
|
|
|
337
339
|
middle: 'center',
|
|
338
340
|
};
|
|
339
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
|
+
|
|
340
355
|
module.exports = Text;
|