@office-iss/react-native-win32 0.0.0-canary.259 → 0.0.0-canary.260
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.flowconfig +1 -1
- package/CHANGELOG.json +16 -1
- package/CHANGELOG.md +12 -4
- package/Libraries/Animated/AnimatedImplementation.js +7 -7
- package/Libraries/Animated/animations/Animation.js +10 -0
- package/Libraries/Animated/animations/TimingAnimation.js +1 -0
- package/Libraries/Animated/components/AnimatedScrollView.js +2 -2
- package/Libraries/Animated/createAnimatedComponent.js +1 -1
- package/Libraries/Animated/useAnimatedProps.js +71 -4
- package/Libraries/Blob/FileReader.js +1 -1
- package/Libraries/Blob/URL.js +2 -62
- package/Libraries/Blob/URLSearchParams.js +71 -0
- package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js +1 -1
- package/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js +1 -1
- package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +3 -0
- package/Libraries/Components/ScrollView/ScrollView.js +5 -5
- package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +3 -3
- package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +1 -1
- package/Libraries/Components/StatusBar/StatusBar.js +3 -1
- package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +3 -0
- package/Libraries/Components/TextInput/TextInput.d.ts +32 -2
- package/Libraries/Components/TextInput/TextInput.js +19 -10
- package/Libraries/Components/TextInput/TextInput.win32.js +19 -10
- package/Libraries/Components/View/ReactNativeStyleAttributes.js +11 -0
- package/Libraries/Components/View/ReactNativeViewAttributes.js +2 -0
- package/Libraries/Components/View/ReactNativeViewAttributes.win32.js +2 -0
- package/Libraries/Components/View/ViewAccessibility.d.ts +15 -0
- package/Libraries/Components/View/ViewNativeComponent.js +6 -0
- package/Libraries/Components/View/ViewPropTypes.js +14 -0
- package/Libraries/Components/View/ViewPropTypes.win32.js +14 -0
- package/Libraries/Core/InitializeCore.js +1 -1
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Core/setUpErrorHandling.js +7 -1
- package/Libraries/Image/AssetSourceResolver.js +28 -1
- package/Libraries/Image/Image.android.js +9 -14
- package/Libraries/Image/Image.ios.js +11 -22
- package/Libraries/Image/Image.win32.js +10 -21
- package/Libraries/Image/ImageBackground.js +1 -8
- package/Libraries/Image/ImageUtils.js +9 -9
- package/Libraries/Image/ImageViewNativeComponent.js +3 -0
- package/Libraries/Inspector/NetworkOverlay.js +1 -1
- package/Libraries/Lists/FlatList.js +1 -1
- package/Libraries/Lists/SectionList.js +1 -1
- package/Libraries/Lists/SectionListModern.js +1 -1
- package/Libraries/LogBox/Data/LogBoxData.js +30 -4
- package/Libraries/NativeComponent/BaseViewConfig.android.js +1 -0
- package/Libraries/NativeComponent/BaseViewConfig.ios.js +4 -0
- package/Libraries/NativeComponent/BaseViewConfig.win32.js +4 -0
- package/Libraries/Network/XMLHttpRequest.js +4 -2
- package/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricHostComponent.js +1 -1
- package/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstance.js +5 -5
- package/Libraries/ReactNative/RendererImplementation.js +24 -2
- package/Libraries/ReactNative/getNativeComponentAttributes.js +8 -0
- package/Libraries/StyleSheet/StyleSheet.js +1 -1
- package/Libraries/StyleSheet/StyleSheet.win32.js +1 -1
- package/Libraries/StyleSheet/StyleSheetTypes.d.ts +11 -0
- package/Libraries/StyleSheet/StyleSheetTypes.js +14 -2
- package/Libraries/StyleSheet/processBackgroundImage.js +286 -0
- package/Libraries/Text/Text.js +7 -6
- package/Libraries/Text/Text.win32.js +7 -6
- package/Libraries/Text/TextNativeComponent.js +7 -0
- package/Libraries/Text/TextNativeComponent.win32.js +7 -0
- package/Libraries/Utilities/ReactNativeTestTools.js +1 -1
- package/Libraries/WebSocket/WebSocket.js +1 -1
- package/flow/jest.js +2 -2
- package/index.js +1 -0
- package/index.win32.js +1 -0
- package/jest/mockModal.js +1 -3
- package/jest/mockScrollView.js +1 -1
- package/jest/renderer.js +2 -2
- package/jest/setup.js +8 -8
- package/overrides.json +12 -12
- package/package.json +13 -13
- package/src/private/{core/components → components}/HScrollViewNativeComponents.js +8 -8
- package/src/private/{core/components → components}/VScrollViewNativeComponents.js +7 -7
- package/src/private/{core/components → components}/useSyncOnScroll.js +2 -2
- package/src/private/featureflags/ReactNativeFeatureFlags.js +84 -7
- package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +15 -2
- package/src/private/hooks/DebouncedEffectImplementation.js +148 -0
- package/src/private/hooks/useDebouncedEffect.js +23 -0
- package/{Libraries/Core → src/private/renderer/errorhandling}/ErrorHandlers.js +5 -4
- package/src/private/setup/setUpDOM.js +28 -0
- package/src/private/setup/setUpIntersectionObserver.js +27 -0
- package/src/private/setup/setUpMutationObserver.js +26 -0
- package/src/private/setup/setUpPerformanceObserver.js +64 -0
- package/src/private/specs/modules/NativeDebuggerSessionObserver.js +23 -0
- package/src/private/webapis/dom/nodes/ReadOnlyNode.js +6 -4
- package/{Libraries/IntersectionObserver → src/private/webapis/intersectionobserver}/IntersectionObserver.js +1 -1
- package/{Libraries/IntersectionObserver → src/private/webapis/intersectionobserver}/IntersectionObserverEntry.js +3 -3
- package/{Libraries/IntersectionObserver → src/private/webapis/intersectionobserver}/IntersectionObserverManager.js +5 -8
- package/src/private/{specs/modules → webapis/intersectionobserver/specs}/NativeIntersectionObserver.js +2 -2
- package/{Libraries/IntersectionObserver → src/private/webapis/intersectionobserver/specs}/__mocks__/NativeIntersectionObserver.js +4 -4
- package/{Libraries/MutationObserver → src/private/webapis/mutationobserver}/MutationObserver.js +1 -1
- package/{Libraries/MutationObserver → src/private/webapis/mutationobserver}/MutationObserverManager.js +5 -5
- package/{Libraries/MutationObserver → src/private/webapis/mutationobserver}/MutationRecord.js +4 -6
- package/src/private/{specs/modules → webapis/mutationobserver/specs}/NativeMutationObserver.js +2 -2
- package/{Libraries/MutationObserver → src/private/webapis/mutationobserver/specs}/__mocks__/NativeMutationObserver.js +5 -5
- package/src/private/webapis/performance/{EventCounts.js → EventTiming.js} +65 -3
- package/src/private/webapis/performance/LongTasks.js +39 -0
- package/src/private/webapis/performance/Performance.js +22 -9
- package/src/private/webapis/performance/PerformanceEntry.js +35 -17
- package/src/private/webapis/performance/PerformanceObserver.js +29 -43
- package/src/private/webapis/performance/RawPerformanceEntry.js +19 -1
- package/src/private/webapis/performance/UserTiming.js +17 -12
- package/src/private/webapis/performance/specs/NativePerformanceObserver.js +1 -1
- package/src-win/Libraries/Components/View/ViewAccessibility.d.ts +15 -0
- package/types/experimental.d.ts +10 -2
- package/Libraries/Core/setUpIntersectionObserver.js +0 -16
- package/Libraries/Core/setUpMutationObserver.js +0 -16
- package/Libraries/Core/setUpPerformanceObserver.js +0 -18
- package/Libraries/IntersectionObserver/NativeIntersectionObserver.js +0 -13
- package/Libraries/MutationObserver/NativeMutationObserver.js +0 -13
- package/src/private/core/setUpDOM.js +0 -18
- package/src/private/webapis/performance/PerformanceEventTiming.js +0 -55
- /package/src/private/{core → styles}/composeStyles.js +0 -0
|
@@ -193,6 +193,8 @@ const validAttributesForNonEventProps = {
|
|
|
193
193
|
accessibilityViewIsModal: true,
|
|
194
194
|
accessibilityElementsHidden: true,
|
|
195
195
|
accessibilityIgnoresInvertColors: true,
|
|
196
|
+
accessibilityShowsLargeContentViewer: true,
|
|
197
|
+
accessibilityLargeContentTitle: true,
|
|
196
198
|
testID: true,
|
|
197
199
|
backgroundColor: {process: require('../StyleSheet/processColor').default},
|
|
198
200
|
backfaceVisibility: true,
|
|
@@ -226,6 +228,8 @@ const validAttributesForNonEventProps = {
|
|
|
226
228
|
experimental_boxShadow: {
|
|
227
229
|
process: require('../StyleSheet/processBoxShadow').default,
|
|
228
230
|
},
|
|
231
|
+
experimental_mixBlendMode: true,
|
|
232
|
+
isolation: true,
|
|
229
233
|
|
|
230
234
|
borderTopWidth: true,
|
|
231
235
|
borderTopColor: {process: require('../StyleSheet/processColor').default},
|
|
@@ -193,6 +193,8 @@ const validAttributesForNonEventProps = {
|
|
|
193
193
|
accessibilityViewIsModal: true,
|
|
194
194
|
accessibilityElementsHidden: true,
|
|
195
195
|
accessibilityIgnoresInvertColors: true,
|
|
196
|
+
accessibilityShowsLargeContentViewer: true,
|
|
197
|
+
accessibilityLargeContentTitle: true,
|
|
196
198
|
testID: true,
|
|
197
199
|
backgroundColor: {process: require('../StyleSheet/processColor').default},
|
|
198
200
|
backfaceVisibility: true,
|
|
@@ -226,6 +228,8 @@ const validAttributesForNonEventProps = {
|
|
|
226
228
|
experimental_boxShadow: {
|
|
227
229
|
process: require('../StyleSheet/processBoxShadow').default,
|
|
228
230
|
},
|
|
231
|
+
experimental_mixBlendMode: true,
|
|
232
|
+
isolation: true,
|
|
229
233
|
|
|
230
234
|
borderTopWidth: true,
|
|
231
235
|
borderTopColor: {process: require('../StyleSheet/processColor').default},
|
|
@@ -78,7 +78,9 @@ const REQUEST_EVENTS = [
|
|
|
78
78
|
|
|
79
79
|
const XHR_EVENTS = REQUEST_EVENTS.concat('readystatechange');
|
|
80
80
|
|
|
81
|
-
class XMLHttpRequestEventTarget extends (EventTarget(
|
|
81
|
+
class XMLHttpRequestEventTarget extends (EventTarget(
|
|
82
|
+
...REQUEST_EVENTS,
|
|
83
|
+
): typeof EventTarget) {
|
|
82
84
|
onload: ?Function;
|
|
83
85
|
onloadstart: ?Function;
|
|
84
86
|
onprogress: ?Function;
|
|
@@ -91,7 +93,7 @@ class XMLHttpRequestEventTarget extends (EventTarget(...REQUEST_EVENTS): any) {
|
|
|
91
93
|
/**
|
|
92
94
|
* Shared base for platform-specific XMLHttpRequest implementations.
|
|
93
95
|
*/
|
|
94
|
-
class XMLHttpRequest extends (EventTarget(...XHR_EVENTS):
|
|
96
|
+
class XMLHttpRequest extends (EventTarget(...XHR_EVENTS): typeof EventTarget) {
|
|
95
97
|
static UNSENT: number = UNSENT;
|
|
96
98
|
static OPENED: number = OPENED;
|
|
97
99
|
static HEADERS_RECEIVED: number = HEADERS_RECEIVED;
|
|
@@ -20,7 +20,7 @@ import type {
|
|
|
20
20
|
import type {ElementRef} from 'react';
|
|
21
21
|
|
|
22
22
|
import TextInputState from '../../Components/TextInput/TextInputState';
|
|
23
|
-
import {getNodeFromInternalInstanceHandle} from '../../
|
|
23
|
+
import {getNodeFromInternalInstanceHandle} from '../../ReactNative/RendererProxy';
|
|
24
24
|
import {getFabricUIManager} from '../FabricUIManager';
|
|
25
25
|
import {create} from './ReactNativeAttributePayload';
|
|
26
26
|
import warnForStyleProps from './warnForStyleProps';
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
import type ReactNativeElement from '../../../src/private/webapis/dom/nodes/ReactNativeElement';
|
|
17
17
|
import type ReadOnlyText from '../../../src/private/webapis/dom/nodes/ReadOnlyText';
|
|
18
|
-
import typeof
|
|
18
|
+
import typeof * as RendererProxyT from '../../ReactNative/RendererProxy';
|
|
19
19
|
import type {
|
|
20
20
|
InternalInstanceHandle,
|
|
21
21
|
Node,
|
|
@@ -32,7 +32,7 @@ let PublicInstanceClass:
|
|
|
32
32
|
let ReadOnlyTextClass: Class<ReadOnlyText>;
|
|
33
33
|
|
|
34
34
|
// Lazy loaded to avoid evaluating the module when using the legacy renderer.
|
|
35
|
-
let
|
|
35
|
+
let RendererProxy: RendererProxyT;
|
|
36
36
|
|
|
37
37
|
export function createPublicInstance(
|
|
38
38
|
tag: number,
|
|
@@ -78,10 +78,10 @@ export function getNodeFromPublicInstance(
|
|
|
78
78
|
return null;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
if (
|
|
82
|
-
|
|
81
|
+
if (RendererProxy == null) {
|
|
82
|
+
RendererProxy = require('../../ReactNative/RendererProxy');
|
|
83
83
|
}
|
|
84
|
-
return
|
|
84
|
+
return RendererProxy.getNodeFromInternalInstanceHandle(
|
|
85
85
|
publicInstance.__internalInstanceHandle,
|
|
86
86
|
);
|
|
87
87
|
}
|
|
@@ -8,7 +8,11 @@
|
|
|
8
8
|
* @flow strict-local
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type {
|
|
11
|
+
import type {
|
|
12
|
+
HostComponent,
|
|
13
|
+
InternalInstanceHandle,
|
|
14
|
+
Node,
|
|
15
|
+
} from '../Renderer/shims/ReactNativeTypes';
|
|
12
16
|
import type ReactFabricHostComponent from './ReactFabricPublicInstance/ReactFabricHostComponent';
|
|
13
17
|
import type {Element, ElementRef, ElementType} from 'react';
|
|
14
18
|
|
|
@@ -16,7 +20,7 @@ import {
|
|
|
16
20
|
onCaughtError,
|
|
17
21
|
onRecoverableError,
|
|
18
22
|
onUncaughtError,
|
|
19
|
-
} from '
|
|
23
|
+
} from '../../src/private/renderer/errorhandling/ErrorHandlers';
|
|
20
24
|
import {type RootTag} from './RootTag';
|
|
21
25
|
export function renderElement({
|
|
22
26
|
element,
|
|
@@ -139,3 +143,21 @@ export function isChildPublicInstance(
|
|
|
139
143
|
childInstance,
|
|
140
144
|
);
|
|
141
145
|
}
|
|
146
|
+
|
|
147
|
+
export function getNodeFromInternalInstanceHandle(
|
|
148
|
+
internalInstanceHandle: InternalInstanceHandle,
|
|
149
|
+
): ?Node {
|
|
150
|
+
// This is only available in Fabric
|
|
151
|
+
return require('../Renderer/shims/ReactFabric').getNodeFromInternalInstanceHandle(
|
|
152
|
+
internalInstanceHandle,
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function getPublicInstanceFromInternalInstanceHandle(
|
|
157
|
+
internalInstanceHandle: InternalInstanceHandle,
|
|
158
|
+
): mixed /*PublicInstance | PublicTextInstance | null*/ {
|
|
159
|
+
// This is only available in Fabric
|
|
160
|
+
return require('../Renderer/shims/ReactFabric').getPublicInstanceFromInternalInstanceHandle(
|
|
161
|
+
internalInstanceHandle,
|
|
162
|
+
);
|
|
163
|
+
}
|
|
@@ -10,8 +10,12 @@
|
|
|
10
10
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
|
+
import processBoxShadow from '../StyleSheet/processBoxShadow';
|
|
14
|
+
|
|
13
15
|
const ReactNativeStyleAttributes = require('../Components/View/ReactNativeStyleAttributes');
|
|
14
16
|
const resolveAssetSource = require('../Image/resolveAssetSource');
|
|
17
|
+
const processBackgroundImage =
|
|
18
|
+
require('../StyleSheet/processBackgroundImage').default;
|
|
15
19
|
const processColor = require('../StyleSheet/processColor').default;
|
|
16
20
|
const processColorArray = require('../StyleSheet/processColorArray');
|
|
17
21
|
const processFilter = require('../StyleSheet/processFilter').default;
|
|
@@ -191,8 +195,12 @@ function getProcessorForType(typeName: string): ?(nextProp: any) => any {
|
|
|
191
195
|
return processColorArray;
|
|
192
196
|
case 'Filter':
|
|
193
197
|
return processFilter;
|
|
198
|
+
case 'BackgroundImage':
|
|
199
|
+
return processBackgroundImage;
|
|
194
200
|
case 'ImageSource':
|
|
195
201
|
return resolveAssetSource;
|
|
202
|
+
case 'BoxShadow':
|
|
203
|
+
return processBoxShadow;
|
|
196
204
|
}
|
|
197
205
|
return null;
|
|
198
206
|
}
|
|
@@ -23,7 +23,7 @@ import type {
|
|
|
23
23
|
____ViewStyleProp_Internal,
|
|
24
24
|
} from './StyleSheetTypes';
|
|
25
25
|
|
|
26
|
-
import composeStyles from '../../src/private/
|
|
26
|
+
import composeStyles from '../../src/private/styles/composeStyles';
|
|
27
27
|
|
|
28
28
|
const ReactNativeStyleAttributes = require('../Components/View/ReactNativeStyleAttributes');
|
|
29
29
|
const PixelRatio = require('../Utilities/PixelRatio').default;
|
|
@@ -23,7 +23,7 @@ import type {
|
|
|
23
23
|
____ViewStyleProp_Internal,
|
|
24
24
|
} from './StyleSheetTypes';
|
|
25
25
|
|
|
26
|
-
import composeStyles from '../../src/private/
|
|
26
|
+
import composeStyles from '../../src/private/styles/composeStyles';
|
|
27
27
|
|
|
28
28
|
const ReactNativeStyleAttributes = require('../Components/View/ReactNativeStyleAttributes');
|
|
29
29
|
const PixelRatio = require('../Utilities/PixelRatio').default;
|
|
@@ -273,6 +273,16 @@ export type BlendMode =
|
|
|
273
273
|
| 'color'
|
|
274
274
|
| 'luminosity';
|
|
275
275
|
|
|
276
|
+
export type GradientValue = {
|
|
277
|
+
type: 'linearGradient';
|
|
278
|
+
// Angle or direction enums
|
|
279
|
+
direction: string | undefined;
|
|
280
|
+
colorStops: Array<{
|
|
281
|
+
color: ColorValue;
|
|
282
|
+
position: number | undefined;
|
|
283
|
+
}>;
|
|
284
|
+
};
|
|
285
|
+
|
|
276
286
|
/**
|
|
277
287
|
* @see https://reactnative.dev/docs/view#style
|
|
278
288
|
*/
|
|
@@ -322,6 +332,7 @@ export interface ViewStyle extends FlexStyle, ShadowStyleIOS, TransformsStyle {
|
|
|
322
332
|
* Controls whether the View can be the target of touch events.
|
|
323
333
|
*/
|
|
324
334
|
pointerEvents?: 'box-none' | 'none' | 'box-only' | 'auto' | undefined;
|
|
335
|
+
isolation?: 'auto' | 'isolate' | undefined;
|
|
325
336
|
cursor?: CursorValue | undefined;
|
|
326
337
|
}
|
|
327
338
|
|
|
@@ -709,6 +709,16 @@ export type DropShadowPrimitive = {
|
|
|
709
709
|
color?: ____ColorValue_Internal,
|
|
710
710
|
};
|
|
711
711
|
|
|
712
|
+
export type GradientValue = {
|
|
713
|
+
type: 'linearGradient',
|
|
714
|
+
// Angle or direction enums
|
|
715
|
+
direction?: string,
|
|
716
|
+
colorStops: $ReadOnlyArray<{
|
|
717
|
+
color: ____ColorValue_Internal,
|
|
718
|
+
position?: string,
|
|
719
|
+
}>,
|
|
720
|
+
};
|
|
721
|
+
|
|
712
722
|
export type BoxShadowPrimitive = {
|
|
713
723
|
offsetX: number | string,
|
|
714
724
|
offsetY: number | string,
|
|
@@ -778,9 +788,11 @@ export type ____ViewStyle_InternalCore = $ReadOnly<{
|
|
|
778
788
|
elevation?: number,
|
|
779
789
|
pointerEvents?: 'auto' | 'none' | 'box-none' | 'box-only',
|
|
780
790
|
cursor?: CursorValue,
|
|
781
|
-
experimental_boxShadow?: $ReadOnlyArray<BoxShadowPrimitive
|
|
782
|
-
experimental_filter?: $ReadOnlyArray<FilterFunction
|
|
791
|
+
experimental_boxShadow?: $ReadOnlyArray<BoxShadowPrimitive> | string,
|
|
792
|
+
experimental_filter?: $ReadOnlyArray<FilterFunction> | string,
|
|
783
793
|
experimental_mixBlendMode?: ____BlendMode_Internal,
|
|
794
|
+
experimental_backgroundImage?: $ReadOnlyArray<GradientValue> | string,
|
|
795
|
+
isolation?: 'auto' | 'isolate',
|
|
784
796
|
}>;
|
|
785
797
|
|
|
786
798
|
export type ____ViewStyle_Internal = $ReadOnly<{
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @flow strict-local
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
import type {ProcessedColorValue} from './processColor';
|
|
14
|
+
import type {GradientValue} from './StyleSheetTypes';
|
|
15
|
+
|
|
16
|
+
const processColor = require('./processColor').default;
|
|
17
|
+
const DIRECTION_REGEX =
|
|
18
|
+
/^to\s+(?:top|bottom|left|right)(?:\s+(?:top|bottom|left|right))?/;
|
|
19
|
+
const ANGLE_UNIT_REGEX = /^([+-]?\d*\.?\d+)(deg|grad|rad|turn)$/i;
|
|
20
|
+
|
|
21
|
+
const TO_BOTTOM_START_END_POINTS = {
|
|
22
|
+
start: {x: 0.5, y: 0},
|
|
23
|
+
end: {x: 0.5, y: 1},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
type ParsedGradientValue = {
|
|
27
|
+
type: 'linearGradient',
|
|
28
|
+
start: {x: number, y: number},
|
|
29
|
+
end: {x: number, y: number},
|
|
30
|
+
colorStops: $ReadOnlyArray<{
|
|
31
|
+
color: ProcessedColorValue,
|
|
32
|
+
position: number,
|
|
33
|
+
}>,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default function processBackgroundImage(
|
|
37
|
+
backgroundImage: ?($ReadOnlyArray<GradientValue> | string),
|
|
38
|
+
): $ReadOnlyArray<ParsedGradientValue> {
|
|
39
|
+
let result: $ReadOnlyArray<ParsedGradientValue> = [];
|
|
40
|
+
if (backgroundImage == null) {
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (typeof backgroundImage === 'string') {
|
|
45
|
+
result = parseCSSLinearGradient(backgroundImage);
|
|
46
|
+
} else if (Array.isArray(backgroundImage)) {
|
|
47
|
+
for (const bgImage of backgroundImage) {
|
|
48
|
+
const processedColorStops = [];
|
|
49
|
+
for (let index = 0; index < bgImage.colorStops.length; index++) {
|
|
50
|
+
const stop = bgImage.colorStops[index];
|
|
51
|
+
const processedColor = processColor(stop.color);
|
|
52
|
+
let processedPosition: number | null = null;
|
|
53
|
+
|
|
54
|
+
// Currently we only support percentage and undefined value for color stop position.
|
|
55
|
+
if (typeof stop.position === 'undefined') {
|
|
56
|
+
processedPosition =
|
|
57
|
+
bgImage.colorStops.length === 1
|
|
58
|
+
? 1
|
|
59
|
+
: index / (bgImage.colorStops.length - 1);
|
|
60
|
+
} else if (stop.position.endsWith('%')) {
|
|
61
|
+
processedPosition = parseFloat(stop.position) / 100;
|
|
62
|
+
} else {
|
|
63
|
+
// If a color stop position is invalid, return an empty array and do not apply gradient. Same as web.
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (processedColor != null) {
|
|
68
|
+
processedColorStops.push({
|
|
69
|
+
color: processedColor,
|
|
70
|
+
position: processedPosition,
|
|
71
|
+
});
|
|
72
|
+
} else {
|
|
73
|
+
// If a color is invalid, return an empty array and do not apply gradient. Same as web.
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let points: {
|
|
79
|
+
start: ParsedGradientValue['start'],
|
|
80
|
+
end: ParsedGradientValue['end'],
|
|
81
|
+
} | null = null;
|
|
82
|
+
|
|
83
|
+
if (typeof bgImage.direction === 'undefined') {
|
|
84
|
+
points = TO_BOTTOM_START_END_POINTS;
|
|
85
|
+
} else if (ANGLE_UNIT_REGEX.test(bgImage.direction)) {
|
|
86
|
+
const angle = parseAngle(bgImage.direction);
|
|
87
|
+
if (angle != null) {
|
|
88
|
+
points = calculateStartEndPointsFromAngle(angle);
|
|
89
|
+
}
|
|
90
|
+
} else if (DIRECTION_REGEX.test(bgImage.direction)) {
|
|
91
|
+
const processedPoints = calculateStartEndPointsFromDirection(
|
|
92
|
+
bgImage.direction,
|
|
93
|
+
);
|
|
94
|
+
if (processedPoints != null) {
|
|
95
|
+
points = processedPoints;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (points != null) {
|
|
100
|
+
result = result.concat({
|
|
101
|
+
type: 'linearGradient',
|
|
102
|
+
start: points.start,
|
|
103
|
+
end: points.end,
|
|
104
|
+
colorStops: processedColorStops,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function parseCSSLinearGradient(
|
|
114
|
+
cssString: string,
|
|
115
|
+
): $ReadOnlyArray<ParsedGradientValue> {
|
|
116
|
+
const gradients = [];
|
|
117
|
+
let match;
|
|
118
|
+
const linearGradientRegex = /linear-gradient\s*\(((?:\([^)]*\)|[^())])*)\)/gi;
|
|
119
|
+
|
|
120
|
+
while ((match = linearGradientRegex.exec(cssString))) {
|
|
121
|
+
const gradientContent = match[1];
|
|
122
|
+
const parts = gradientContent.split(',');
|
|
123
|
+
let points = TO_BOTTOM_START_END_POINTS;
|
|
124
|
+
const trimmedDirection = parts[0].trim().toLowerCase();
|
|
125
|
+
const colorStopRegex =
|
|
126
|
+
/\s*((?:(?:rgba?|hsla?)\s*\([^)]+\))|#[0-9a-fA-F]+|[a-zA-Z]+)(?:\s+([0-9.]+%?))?\s*/gi;
|
|
127
|
+
|
|
128
|
+
if (ANGLE_UNIT_REGEX.test(trimmedDirection)) {
|
|
129
|
+
const angle = parseAngle(trimmedDirection);
|
|
130
|
+
if (angle != null) {
|
|
131
|
+
points = calculateStartEndPointsFromAngle(angle);
|
|
132
|
+
parts.shift();
|
|
133
|
+
} else {
|
|
134
|
+
// If an angle is invalid, return an empty array and do not apply any gradient. Same as web.
|
|
135
|
+
return [];
|
|
136
|
+
}
|
|
137
|
+
} else if (DIRECTION_REGEX.test(trimmedDirection)) {
|
|
138
|
+
const parsedPoints =
|
|
139
|
+
calculateStartEndPointsFromDirection(trimmedDirection);
|
|
140
|
+
if (parsedPoints != null) {
|
|
141
|
+
points = parsedPoints;
|
|
142
|
+
parts.shift();
|
|
143
|
+
} else {
|
|
144
|
+
// If a direction is invalid, return an empty array and do not apply any gradient. Same as web.
|
|
145
|
+
return [];
|
|
146
|
+
}
|
|
147
|
+
} else if (!colorStopRegex.test(trimmedDirection)) {
|
|
148
|
+
// If first part is not an angle/direction or a color stop, return an empty array and do not apply any gradient. Same as web.
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
colorStopRegex.lastIndex = 0;
|
|
152
|
+
|
|
153
|
+
const colorStops = [];
|
|
154
|
+
const fullColorStopsStr = parts.join(',');
|
|
155
|
+
let colorStopMatch;
|
|
156
|
+
while ((colorStopMatch = colorStopRegex.exec(fullColorStopsStr))) {
|
|
157
|
+
const [, color, position] = colorStopMatch;
|
|
158
|
+
const processedColor = processColor(color.trim().toLowerCase());
|
|
159
|
+
if (
|
|
160
|
+
processedColor != null &&
|
|
161
|
+
(typeof position === 'undefined' || position.endsWith('%'))
|
|
162
|
+
) {
|
|
163
|
+
colorStops.push({
|
|
164
|
+
color: processedColor,
|
|
165
|
+
position: position ? parseFloat(position) / 100 : null,
|
|
166
|
+
});
|
|
167
|
+
} else {
|
|
168
|
+
// If a color or position is invalid, return an empty array and do not apply any gradient. Same as web.
|
|
169
|
+
return [];
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
gradients.push({
|
|
174
|
+
type: 'linearGradient',
|
|
175
|
+
start: points.start,
|
|
176
|
+
end: points.end,
|
|
177
|
+
colorStops: colorStops.map((stop, index, array) => ({
|
|
178
|
+
color: stop.color,
|
|
179
|
+
position:
|
|
180
|
+
stop.position ??
|
|
181
|
+
(array.length === 1 ? 1 : index / (array.length - 1)),
|
|
182
|
+
})),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return gradients;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function calculateStartEndPointsFromDirection(direction: string): ?{
|
|
190
|
+
start: {x: number, y: number},
|
|
191
|
+
end: {x: number, y: number},
|
|
192
|
+
} {
|
|
193
|
+
// Remove extra whitespace
|
|
194
|
+
const normalizedDirection = direction.replace(/\s+/g, ' ');
|
|
195
|
+
|
|
196
|
+
switch (normalizedDirection) {
|
|
197
|
+
case 'to right':
|
|
198
|
+
return {
|
|
199
|
+
start: {x: 0, y: 0.5},
|
|
200
|
+
end: {x: 1, y: 0.5},
|
|
201
|
+
};
|
|
202
|
+
case 'to left':
|
|
203
|
+
return {
|
|
204
|
+
start: {x: 1, y: 0.5},
|
|
205
|
+
end: {x: 0, y: 0.5},
|
|
206
|
+
};
|
|
207
|
+
case 'to bottom':
|
|
208
|
+
return TO_BOTTOM_START_END_POINTS;
|
|
209
|
+
case 'to top':
|
|
210
|
+
return {
|
|
211
|
+
start: {x: 0.5, y: 1},
|
|
212
|
+
end: {x: 0.5, y: 0},
|
|
213
|
+
};
|
|
214
|
+
case 'to bottom right':
|
|
215
|
+
case 'to right bottom':
|
|
216
|
+
return {
|
|
217
|
+
start: {x: 0, y: 0},
|
|
218
|
+
end: {x: 1, y: 1},
|
|
219
|
+
};
|
|
220
|
+
case 'to top left':
|
|
221
|
+
case 'to left top':
|
|
222
|
+
return {
|
|
223
|
+
start: {x: 1, y: 1},
|
|
224
|
+
end: {x: 0, y: 0},
|
|
225
|
+
};
|
|
226
|
+
case 'to bottom left':
|
|
227
|
+
case 'to left bottom':
|
|
228
|
+
return {
|
|
229
|
+
start: {x: 1, y: 0},
|
|
230
|
+
end: {x: 0, y: 1},
|
|
231
|
+
};
|
|
232
|
+
case 'to top right':
|
|
233
|
+
case 'to right top':
|
|
234
|
+
return {
|
|
235
|
+
start: {x: 0, y: 1},
|
|
236
|
+
end: {x: 1, y: 0},
|
|
237
|
+
};
|
|
238
|
+
default:
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function calculateStartEndPointsFromAngle(angleRadians: number): {
|
|
244
|
+
start: {x: number, y: number},
|
|
245
|
+
end: {x: number, y: number},
|
|
246
|
+
} {
|
|
247
|
+
// Normalize angle to be between 0 and 2π
|
|
248
|
+
let angleRadiansNormalized = angleRadians % (2 * Math.PI);
|
|
249
|
+
if (angleRadiansNormalized < 0) {
|
|
250
|
+
angleRadiansNormalized += 2 * Math.PI;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const endX = 0.5 + 0.5 * Math.sin(angleRadiansNormalized);
|
|
254
|
+
const endY = 0.5 - 0.5 * Math.cos(angleRadiansNormalized);
|
|
255
|
+
|
|
256
|
+
const startX = 1 - endX;
|
|
257
|
+
const startY = 1 - endY;
|
|
258
|
+
|
|
259
|
+
return {
|
|
260
|
+
start: {x: startX, y: startY},
|
|
261
|
+
end: {x: endX, y: endY},
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function parseAngle(angle: string): ?number {
|
|
266
|
+
const match = angle.match(ANGLE_UNIT_REGEX);
|
|
267
|
+
if (!match) {
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const [, value, unit] = match;
|
|
272
|
+
|
|
273
|
+
const numericValue = parseFloat(value);
|
|
274
|
+
switch (unit) {
|
|
275
|
+
case 'deg':
|
|
276
|
+
return (numericValue * Math.PI) / 180;
|
|
277
|
+
case 'grad':
|
|
278
|
+
return (numericValue * Math.PI) / 200;
|
|
279
|
+
case 'rad':
|
|
280
|
+
return numericValue;
|
|
281
|
+
case 'turn':
|
|
282
|
+
return numericValue * 2 * Math.PI;
|
|
283
|
+
default:
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
}
|
package/Libraries/Text/Text.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import type {TextStyleProp} from '../StyleSheet/StyleSheet';
|
|
11
12
|
import type {____TextStyle_Internal as TextStyleInternal} from '../StyleSheet/StyleSheetTypes';
|
|
12
13
|
import type {PressEvent} from '../Types/CoreEventTypes';
|
|
13
14
|
import type {NativeTextProps} from './TextNativeComponent';
|
|
@@ -133,7 +134,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
|
|
|
133
134
|
|
|
134
135
|
let _selectable = selectable;
|
|
135
136
|
|
|
136
|
-
let processedStyle
|
|
137
|
+
let processedStyle = flattenStyle<TextStyleProp>(_style);
|
|
137
138
|
if (processedStyle != null) {
|
|
138
139
|
let overrides: ?{...TextStyleInternal} = null;
|
|
139
140
|
if (typeof processedStyle.fontWeight === 'number') {
|
|
@@ -158,7 +159,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
|
|
|
158
159
|
|
|
159
160
|
if (overrides != null) {
|
|
160
161
|
// $FlowFixMe[incompatible-type]
|
|
161
|
-
|
|
162
|
+
_style = [_style, overrides];
|
|
162
163
|
}
|
|
163
164
|
}
|
|
164
165
|
|
|
@@ -178,7 +179,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
|
|
|
178
179
|
numberOfLines: _numberOfLines,
|
|
179
180
|
selectable: _selectable,
|
|
180
181
|
selectionColor: _selectionColor,
|
|
181
|
-
style:
|
|
182
|
+
style: _style,
|
|
182
183
|
disabled: disabled,
|
|
183
184
|
children,
|
|
184
185
|
}}
|
|
@@ -212,7 +213,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
|
|
|
212
213
|
ref={forwardedRef}
|
|
213
214
|
selectable={_selectable}
|
|
214
215
|
selectionColor={_selectionColor}
|
|
215
|
-
style={
|
|
216
|
+
style={_style}
|
|
216
217
|
disabled={disabled}>
|
|
217
218
|
{children}
|
|
218
219
|
</NativeVirtualText>
|
|
@@ -256,7 +257,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
|
|
|
256
257
|
numberOfLines: _numberOfLines,
|
|
257
258
|
selectable: _selectable,
|
|
258
259
|
selectionColor: _selectionColor,
|
|
259
|
-
style:
|
|
260
|
+
style: _style,
|
|
260
261
|
children,
|
|
261
262
|
}}
|
|
262
263
|
textPressabilityProps={{
|
|
@@ -291,7 +292,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
|
|
|
291
292
|
ref={forwardedRef}
|
|
292
293
|
selectable={_selectable}
|
|
293
294
|
selectionColor={_selectionColor}
|
|
294
|
-
style={
|
|
295
|
+
style={_style}>
|
|
295
296
|
{children}
|
|
296
297
|
</NativeText>
|
|
297
298
|
);
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import type {TextStyleProp} from '../StyleSheet/StyleSheet';
|
|
11
12
|
import type {____TextStyle_Internal as TextStyleInternal} from '../StyleSheet/StyleSheetTypes';
|
|
12
13
|
import type {PressEvent} from '../Types/CoreEventTypes';
|
|
13
14
|
import type {NativeTextProps} from './TextNativeComponent';
|
|
@@ -157,7 +158,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
|
|
|
157
158
|
|
|
158
159
|
let _selectable = selectable;
|
|
159
160
|
|
|
160
|
-
let processedStyle
|
|
161
|
+
let processedStyle = flattenStyle<TextStyleProp>(_style);
|
|
161
162
|
if (processedStyle != null) {
|
|
162
163
|
let overrides: ?{...TextStyleInternal} = null;
|
|
163
164
|
if (typeof processedStyle.fontWeight === 'number') {
|
|
@@ -182,7 +183,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
|
|
|
182
183
|
|
|
183
184
|
if (overrides != null) {
|
|
184
185
|
// $FlowFixMe[incompatible-type]
|
|
185
|
-
|
|
186
|
+
_style = [_style, overrides];
|
|
186
187
|
}
|
|
187
188
|
}
|
|
188
189
|
|
|
@@ -208,7 +209,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
|
|
|
208
209
|
numberOfLines: _numberOfLines,
|
|
209
210
|
selectable: _selectable,
|
|
210
211
|
selectionColor: _selectionColor,
|
|
211
|
-
style:
|
|
212
|
+
style: _style,
|
|
212
213
|
disabled: disabled,
|
|
213
214
|
children,
|
|
214
215
|
}}
|
|
@@ -248,7 +249,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
|
|
|
248
249
|
ref={forwardedRef}
|
|
249
250
|
selectable={_selectable}
|
|
250
251
|
selectionColor={_selectionColor}
|
|
251
|
-
style={
|
|
252
|
+
style={_style}
|
|
252
253
|
disabled={disabled}>
|
|
253
254
|
{children}
|
|
254
255
|
</NativeVirtualText>
|
|
@@ -298,7 +299,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
|
|
|
298
299
|
numberOfLines: _numberOfLines,
|
|
299
300
|
selectable: _selectable,
|
|
300
301
|
selectionColor: _selectionColor,
|
|
301
|
-
style:
|
|
302
|
+
style: _style,
|
|
302
303
|
children,
|
|
303
304
|
}}
|
|
304
305
|
textPressabilityProps={{
|
|
@@ -339,7 +340,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
|
|
|
339
340
|
ref={forwardedRef}
|
|
340
341
|
selectable={_selectable}
|
|
341
342
|
selectionColor={_selectionColor}
|
|
342
|
-
style={
|
|
343
|
+
style={_style}>
|
|
343
344
|
{children}
|
|
344
345
|
</NativeText>
|
|
345
346
|
);
|
|
@@ -16,6 +16,7 @@ import type {TextProps} from './TextProps';
|
|
|
16
16
|
import {createViewConfig} from '../NativeComponent/ViewConfig';
|
|
17
17
|
import UIManager from '../ReactNative/UIManager';
|
|
18
18
|
import createReactNativeComponentClass from '../Renderer/shims/createReactNativeComponentClass';
|
|
19
|
+
import Platform from '../Utilities/Platform';
|
|
19
20
|
|
|
20
21
|
export type NativeTextProps = $ReadOnly<{
|
|
21
22
|
...TextProps,
|
|
@@ -48,6 +49,12 @@ const textViewConfig = {
|
|
|
48
49
|
dataDetectorType: true,
|
|
49
50
|
android_hyphenationFrequency: true,
|
|
50
51
|
lineBreakStrategyIOS: true,
|
|
52
|
+
// boxShadow is currently per-component on Android instead of being on BaseViewConfig yet
|
|
53
|
+
...(Platform.OS === 'android' && {
|
|
54
|
+
experimental_boxShadow: {
|
|
55
|
+
process: require('../StyleSheet/processBoxShadow').default,
|
|
56
|
+
},
|
|
57
|
+
}),
|
|
51
58
|
},
|
|
52
59
|
directEventTypes: {
|
|
53
60
|
topTextLayout: {
|