@office-iss/react-native-win32 0.74.3 → 0.75.0-preview.1
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 +9 -4
- package/CHANGELOG.json +563 -45
- package/CHANGELOG.md +169 -26
- package/Libraries/Animated/AnimatedImplementation.js +2 -0
- package/Libraries/Animated/NativeAnimatedHelper.js +4 -0
- package/Libraries/Animated/NativeAnimatedHelper.win32.js +4 -0
- package/Libraries/Animated/createAnimatedComponent.js +10 -4
- package/Libraries/Animated/useAnimatedProps.js +56 -28
- package/Libraries/BatchedBridge/MessageQueue.js +1 -0
- package/Libraries/Components/Button.js +10 -5
- package/Libraries/Components/Button.win32.js +1 -0
- package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js +11 -2
- package/Libraries/Components/Pressable/Pressable.js +13 -6
- package/Libraries/Components/Pressable/Pressable.win32.js +13 -6
- package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +4 -0
- package/Libraries/Components/ScrollView/ScrollView.js +109 -29
- package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +6 -0
- package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +13 -1
- package/Libraries/Components/StatusBar/StatusBar.js +1 -21
- package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +0 -15
- package/Libraries/Components/TextInput/InputAccessoryView.js +10 -1
- package/Libraries/Components/TextInput/RCTTextInputViewConfig.js +0 -12
- package/Libraries/Components/TextInput/TextInput.d.ts +0 -19
- package/Libraries/Components/TextInput/TextInput.js +20 -73
- package/Libraries/Components/TextInput/TextInput.win32.js +21 -75
- package/Libraries/Components/Touchable/Touchable.js +2 -2
- package/Libraries/Components/Touchable/TouchableHighlight.d.ts +4 -10
- package/Libraries/Components/Touchable/TouchableHighlight.js +3 -1
- package/Libraries/Components/Touchable/TouchableOpacity.d.ts +4 -32
- package/Libraries/Components/Touchable/TouchableOpacity.js +3 -1
- package/Libraries/Components/Touchable/TouchableWithoutFeedback.d.ts +8 -0
- package/Libraries/Components/Touchable/TouchableWithoutFeedback.js +117 -111
- package/Libraries/Components/View/ReactNativeStyleAttributes.js +6 -0
- package/Libraries/Components/View/ReactNativeViewAttributes.js +1 -0
- package/Libraries/Components/View/ReactNativeViewAttributes.win32.js +1 -0
- package/Libraries/Components/View/View.js +0 -11
- package/Libraries/Components/View/View.win32.js +0 -11
- package/Libraries/Components/View/ViewAccessibility.js +4 -4
- package/Libraries/Components/View/ViewAccessibility.win32.js +6 -6
- package/Libraries/Components/View/ViewPropTypes.d.ts +7 -49
- package/Libraries/Components/View/ViewPropTypes.js +7 -0
- package/Libraries/Components/View/ViewPropTypes.win32.js +7 -0
- package/Libraries/Core/Devtools/loadBundleFromServer.js +3 -3
- package/Libraries/Core/Devtools/loadBundleFromServer.win32.js +153 -0
- package/Libraries/Core/Devtools/parseErrorStack.js +5 -5
- package/Libraries/Core/Devtools/parseHermesStack.js +22 -16
- package/Libraries/Core/ErrorHandlers.js +116 -0
- package/Libraries/Core/ExceptionsManager.js +2 -2
- package/Libraries/Core/ReactNativeVersion.js +3 -3
- package/Libraries/Core/setUpDeveloperTools.js +3 -1
- package/Libraries/Core/setUpPerformance.js +6 -4
- package/Libraries/Core/setUpReactDevTools.js +70 -10
- package/Libraries/Core/setUpTimers.js +50 -31
- package/Libraries/Debugging/DebuggingOverlayRegistry.js +1 -1
- package/Libraries/Image/Image.android.js +23 -13
- package/Libraries/Image/Image.d.ts +14 -15
- package/Libraries/Image/Image.ios.js +21 -11
- package/Libraries/Image/Image.win32.js +5 -3
- package/Libraries/Image/ImageProps.js +16 -5
- package/Libraries/Image/ImageTypes.flow.js +7 -2
- package/Libraries/Image/ImageUtils.js +1 -0
- package/Libraries/Image/ImageViewNativeComponent.js +2 -1
- package/Libraries/Inspector/ElementBox.js +6 -3
- package/Libraries/Inspector/ElementProperties.js +1 -1
- package/Libraries/Interaction/TouchHistoryMath.js +4 -4
- package/Libraries/IntersectionObserver/IntersectionObserverManager.js +6 -26
- package/Libraries/JSInspector/NetworkAgent.js +1 -1
- package/Libraries/LogBox/Data/LogBoxData.js +39 -29
- package/Libraries/LogBox/Data/LogBoxLog.js +114 -2
- package/Libraries/LogBox/Data/parseLogBoxLog.js +168 -53
- 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 +5 -66
- package/Libraries/LogBox/UI/LogBoxInspectorHeader.win32.js +8 -52
- package/Libraries/LogBox/UI/LogBoxInspectorHeaderButton.js +76 -0
- package/Libraries/LogBox/UI/LogBoxInspectorReactFrames.js +8 -5
- package/Libraries/LogBox/UI/LogBoxInspectorReactFrames.win32.js +8 -5
- 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/NativeComponent/BaseViewConfig.android.js +5 -0
- package/Libraries/NativeComponent/BaseViewConfig.ios.js +5 -0
- package/Libraries/NativeComponent/BaseViewConfig.win32.js +5 -0
- package/Libraries/NativeComponent/NativeComponentRegistry.js +12 -5
- package/Libraries/NativeComponent/StaticViewConfigValidator.js +3 -0
- package/Libraries/Network/XMLHttpRequest.js +5 -1
- package/Libraries/NewAppScreen/components/LearnMoreLinks.js +3 -3
- package/Libraries/Pressability/Pressability.js +3 -51
- package/Libraries/Pressability/Pressability.win32.js +3 -51
- package/Libraries/ReactNative/AppContainer-dev.js +3 -2
- package/Libraries/ReactNative/AppContainer-prod.js +2 -1
- package/Libraries/ReactNative/AppContainer.js +2 -0
- package/Libraries/ReactNative/AppRegistry.d.ts +7 -0
- package/Libraries/ReactNative/AppRegistry.js +10 -4
- package/Libraries/ReactNative/BridgelessUIManager.js +1 -21
- package/Libraries/ReactNative/FabricUIManager.js +0 -51
- package/Libraries/ReactNative/ReactFabricPublicInstance/warnForStyleProps.js +1 -0
- package/Libraries/ReactNative/RendererImplementation.js +20 -2
- package/Libraries/ReactNative/UIManager.d.ts +0 -21
- package/Libraries/ReactNative/UIManagerProperties.js +0 -3
- package/Libraries/ReactNative/__mocks__/FabricUIManager.js +5 -341
- package/Libraries/ReactNative/getNativeComponentAttributes.js +8 -8
- package/Libraries/ReactNative/renderApplication.js +3 -0
- package/Libraries/Renderer/implementations/ReactFabric-dev.js +15682 -27088
- package/Libraries/Renderer/implementations/ReactFabric-prod.js +5082 -4381
- package/Libraries/Renderer/implementations/ReactFabric-profiling.js +3480 -2571
- package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +15943 -27543
- package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +5303 -4606
- package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +3450 -2572
- package/Libraries/Renderer/shims/ReactFabric.js +2 -2
- package/Libraries/Renderer/shims/ReactFeatureFlags.js +2 -2
- package/Libraries/Renderer/shims/ReactNative.js +2 -3
- package/Libraries/Renderer/shims/ReactNativeTypes.js +24 -3
- package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +2 -2
- package/Libraries/Renderer/shims/createReactNativeComponentClass.js +2 -2
- package/Libraries/Share/Share.d.ts +16 -10
- package/Libraries/Share/Share.js +14 -15
- package/Libraries/StyleSheet/StyleSheet.d.ts +1 -1
- package/Libraries/StyleSheet/StyleSheet.js +3 -10
- package/Libraries/StyleSheet/StyleSheet.win32.js +3 -10
- package/Libraries/StyleSheet/StyleSheetTypes.d.ts +21 -21
- package/Libraries/StyleSheet/StyleSheetTypes.js +24 -18
- package/Libraries/StyleSheet/flattenStyle.js +1 -0
- package/Libraries/StyleSheet/processFilter.js +132 -0
- package/Libraries/StyleSheet/processTransform.js +18 -3
- package/Libraries/Text/Text.js +151 -128
- package/Libraries/Text/Text.win32.js +163 -138
- package/Libraries/Text/TextNativeComponent.js +5 -4
- package/Libraries/Text/TextNativeComponent.win32.js +5 -4
- package/Libraries/Text/TextProps.js +6 -6
- package/Libraries/Text/TextProps.win32.js +6 -6
- package/Libraries/TurboModule/TurboModuleRegistry.js +2 -1
- package/Libraries/Types/CodegenTypes.js +3 -0
- package/Libraries/Utilities/{LoadingView.android.js → DevLoadingView.js} +33 -11
- package/Libraries/Utilities/Dimensions.js +1 -0
- package/Libraries/Utilities/Dimensions.win32.js +1 -0
- package/Libraries/Utilities/HMRClient.js +36 -8
- package/Libraries/Utilities/HMRClientProdShim.js +1 -0
- package/Libraries/Utilities/Platform.android.js +4 -4
- package/Libraries/Utilities/RCTLog.js +1 -0
- package/Libraries/Utilities/ReactNativeTestTools.js +12 -24
- package/Libraries/Utilities/verifyComponentAttributeEquivalence.js +11 -6
- package/Libraries/__tests__/ButtonWin32-test.js +7 -6
- package/Libraries/promiseRejectionTrackingOptions.js +1 -0
- package/jest/mockComponent.js +7 -0
- package/jest/renderer.js +25 -14
- package/jest/setup.js +19 -13
- package/jest.config.js +2 -1
- package/overrides.json +30 -29
- package/package.json +27 -25
- package/rn-get-polyfills.js +1 -0
- package/src/private/core/composeStyles.js +27 -0
- package/src/private/featureflags/ReactNativeFeatureFlags.js +93 -33
- package/src/private/featureflags/ReactNativeFeatureFlagsBase.js +23 -4
- package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +56 -0
- package/src/private/fusebox/setUpFuseboxReactDevToolsDispatcher.js +108 -0
- package/src/private/specs/modules/NativeBlobModule.js +4 -2
- package/src/private/specs/modules/NativeDevSettings.js +1 -0
- package/src/private/specs/modules/NativePushNotificationManagerIOS.js +0 -4
- package/src/private/specs/modules/NativeUIManager.js +0 -7
- package/src/private/webapis/dom/geometry/DOMRectReadOnly.js +24 -24
- package/src/private/webapis/dom/nodes/ReactNativeElement.js +11 -14
- package/src/private/webapis/dom/nodes/ReadOnlyCharacterData.js +2 -3
- package/src/private/webapis/dom/nodes/ReadOnlyElement.js +24 -54
- package/src/private/webapis/dom/nodes/ReadOnlyNode.js +5 -13
- package/src/private/webapis/dom/nodes/specs/NativeDOM.js +468 -0
- package/src/private/webapis/dom/nodes/specs/__mocks__/NativeDOMMock.js +413 -0
- package/src/private/webapis/dom/oldstylecollections/DOMRectList.js +4 -4
- package/src/private/webapis/dom/oldstylecollections/HTMLCollection.js +4 -4
- package/src/private/webapis/dom/oldstylecollections/NodeList.js +5 -5
- package/src/private/webapis/idlecallbacks/specs/NativeIdleCallbacks.js +34 -0
- package/src/private/webapis/microtasks/specs/NativeMicrotasks.js +21 -0
- package/src/private/webapis/performance/EventCounts.js +1 -1
- package/src/private/webapis/performance/MemoryInfo.js +9 -9
- package/src/private/webapis/performance/Performance.js +10 -56
- package/src/private/webapis/performance/PerformanceObserver.js +30 -22
- package/src/private/webapis/performance/RawPerformanceEntry.js +2 -7
- package/src/private/webapis/performance/ReactNativeStartupTiming.js +18 -18
- package/src/private/webapis/performance/UserTiming.js +63 -0
- package/src/private/webapis/performance/{NativePerformance.js → specs/NativePerformance.js} +3 -2
- package/src/private/webapis/performance/{NativePerformanceObserver.js → specs/NativePerformanceObserver.js} +2 -2
- package/src/private/webapis/performance/{__mocks__ → specs/__mocks__}/NativePerformance.js +1 -1
- package/src/private/webapis/performance/{__mocks__ → specs/__mocks__}/NativePerformanceObserver.js +3 -4
- package/src-win/Libraries/Components/View/ViewPropTypes.d.ts +7 -49
- package/types/modules/globals.d.ts +4 -0
- package/Libraries/Components/ScrollView/ScrollView.win32.js +0 -1915
- package/Libraries/NativeModules/specs/NativeAnimationsDebugModule.js +0 -13
- package/Libraries/Utilities/LoadingView.ios.js +0 -50
- package/Libraries/Utilities/LoadingView.js +0 -16
- package/jest/ReactNativeInternalFeatureFlagsMock.js +0 -13
- package/src/private/featureflags/NativeReactNativeFeatureFlags.js +0 -44
- package/src/private/featureflags/__tests__/ReactNativeFeatureFlags-test.js +0 -92
- package/src/private/specs/modules/NativeAnimationsDebugModule.js +0 -20
- package/src/private/webapis/dom/oldstylecollections/__tests__/DOMRectList-test.js +0 -85
- package/src/private/webapis/dom/oldstylecollections/__tests__/HTMLCollection-test.js +0 -80
- package/src/private/webapis/dom/oldstylecollections/__tests__/NodeList-test.js +0 -161
- package/src/private/webapis/performance/__tests__/EventCounts-test.js +0 -116
- package/src/private/webapis/performance/__tests__/NativePerformanceMock-test.js +0 -82
- package/src/private/webapis/performance/__tests__/NativePerformanceObserverMock-test.js +0 -108
- package/src/private/webapis/performance/__tests__/Performance-test.js +0 -117
- package/src/private/webapis/performance/__tests__/PerformanceObserver-test.js +0 -208
|
@@ -0,0 +1,76 @@
|
|
|
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
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type {ImageSource} from '../../Image/ImageSource';
|
|
12
|
+
import type {LogLevel} from '../Data/LogBoxLog';
|
|
13
|
+
|
|
14
|
+
import Image from '../../Image/Image';
|
|
15
|
+
import StyleSheet from '../../StyleSheet/StyleSheet';
|
|
16
|
+
import LogBoxButton from './LogBoxButton';
|
|
17
|
+
import * as LogBoxStyle from './LogBoxStyle';
|
|
18
|
+
import * as React from 'react';
|
|
19
|
+
|
|
20
|
+
const backgroundForLevel = (level: LogLevel) =>
|
|
21
|
+
({
|
|
22
|
+
warn: {
|
|
23
|
+
default: 'transparent',
|
|
24
|
+
pressed: LogBoxStyle.getWarningDarkColor(),
|
|
25
|
+
},
|
|
26
|
+
error: {
|
|
27
|
+
default: 'transparent',
|
|
28
|
+
pressed: LogBoxStyle.getErrorDarkColor(),
|
|
29
|
+
},
|
|
30
|
+
fatal: {
|
|
31
|
+
default: 'transparent',
|
|
32
|
+
pressed: LogBoxStyle.getFatalDarkColor(),
|
|
33
|
+
},
|
|
34
|
+
syntax: {
|
|
35
|
+
default: 'transparent',
|
|
36
|
+
pressed: LogBoxStyle.getFatalDarkColor(),
|
|
37
|
+
},
|
|
38
|
+
})[level];
|
|
39
|
+
|
|
40
|
+
export default function LogBoxInspectorHeaderButton(
|
|
41
|
+
props: $ReadOnly<{
|
|
42
|
+
disabled: boolean,
|
|
43
|
+
image: ImageSource,
|
|
44
|
+
level: LogLevel,
|
|
45
|
+
onPress?: ?() => void,
|
|
46
|
+
}>,
|
|
47
|
+
): React.Node {
|
|
48
|
+
return (
|
|
49
|
+
<LogBoxButton
|
|
50
|
+
backgroundColor={backgroundForLevel(props.level)}
|
|
51
|
+
onPress={props.disabled ? null : props.onPress}
|
|
52
|
+
style={styles.button}>
|
|
53
|
+
{props.disabled ? null : (
|
|
54
|
+
<Image source={props.image} style={styles.buttonImage} />
|
|
55
|
+
)}
|
|
56
|
+
</LogBoxButton>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const styles = StyleSheet.create({
|
|
61
|
+
button: {
|
|
62
|
+
alignItems: 'center',
|
|
63
|
+
aspectRatio: 1,
|
|
64
|
+
justifyContent: 'center',
|
|
65
|
+
marginTop: 5,
|
|
66
|
+
marginRight: 6,
|
|
67
|
+
marginLeft: 6,
|
|
68
|
+
marginBottom: -8,
|
|
69
|
+
borderRadius: 3,
|
|
70
|
+
},
|
|
71
|
+
buttonImage: {
|
|
72
|
+
height: 14,
|
|
73
|
+
width: 8,
|
|
74
|
+
tintColor: LogBoxStyle.getTextColor(),
|
|
75
|
+
},
|
|
76
|
+
});
|
|
@@ -50,24 +50,27 @@ function getPrettyFileName(path: string) {
|
|
|
50
50
|
}
|
|
51
51
|
function LogBoxInspectorReactFrames(props: Props): React.Node {
|
|
52
52
|
const [collapsed, setCollapsed] = React.useState(true);
|
|
53
|
-
if (
|
|
53
|
+
if (
|
|
54
|
+
props.log.getAvailableComponentStack() == null ||
|
|
55
|
+
props.log.getAvailableComponentStack().length < 1
|
|
56
|
+
) {
|
|
54
57
|
return null;
|
|
55
58
|
}
|
|
56
59
|
|
|
57
60
|
function getStackList() {
|
|
58
61
|
if (collapsed) {
|
|
59
|
-
return props.log.
|
|
62
|
+
return props.log.getAvailableComponentStack().slice(0, 3);
|
|
60
63
|
} else {
|
|
61
|
-
return props.log.
|
|
64
|
+
return props.log.getAvailableComponentStack();
|
|
62
65
|
}
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
function getCollapseMessage() {
|
|
66
|
-
if (props.log.
|
|
69
|
+
if (props.log.getAvailableComponentStack().length <= 3) {
|
|
67
70
|
return;
|
|
68
71
|
}
|
|
69
72
|
|
|
70
|
-
const count = props.log.
|
|
73
|
+
const count = props.log.getAvailableComponentStack().length - 3;
|
|
71
74
|
if (collapsed) {
|
|
72
75
|
return `See ${count} more components`;
|
|
73
76
|
} else {
|
|
@@ -50,24 +50,27 @@ function getPrettyFileName(path: string) {
|
|
|
50
50
|
}
|
|
51
51
|
function LogBoxInspectorReactFrames(props: Props): React.Node {
|
|
52
52
|
const [collapsed, setCollapsed] = React.useState(true);
|
|
53
|
-
if (
|
|
53
|
+
if (
|
|
54
|
+
props.log.getAvailableComponentStack() == null ||
|
|
55
|
+
props.log.getAvailableComponentStack().length < 1
|
|
56
|
+
) {
|
|
54
57
|
return null;
|
|
55
58
|
}
|
|
56
59
|
|
|
57
60
|
function getStackList() {
|
|
58
61
|
if (collapsed) {
|
|
59
|
-
return props.log.
|
|
62
|
+
return props.log.getAvailableComponentStack().slice(0, 3);
|
|
60
63
|
} else {
|
|
61
|
-
return props.log.
|
|
64
|
+
return props.log.getAvailableComponentStack();
|
|
62
65
|
}
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
function getCollapseMessage() {
|
|
66
|
-
if (props.log.
|
|
69
|
+
if (props.log.getAvailableComponentStack().length <= 3) {
|
|
67
70
|
return;
|
|
68
71
|
}
|
|
69
72
|
|
|
70
|
-
const count = props.log.
|
|
73
|
+
const count = props.log.getAvailableComponentStack().length - 3;
|
|
71
74
|
if (collapsed) {
|
|
72
75
|
return `See ${count} more components`;
|
|
73
76
|
} else {
|
|
@@ -8,18 +8,17 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type {Message as MessageType} from '../Data/parseLogBoxLog';
|
|
12
|
-
|
|
13
11
|
import View from '../../Components/View/View';
|
|
14
|
-
import Image from '../../Image/Image';
|
|
15
12
|
import StyleSheet from '../../StyleSheet/StyleSheet';
|
|
16
|
-
import Text from '../../Text/Text';
|
|
17
13
|
import * as LogBoxData from '../Data/LogBoxData';
|
|
18
14
|
import LogBoxLog from '../Data/LogBoxLog';
|
|
19
15
|
import LogBoxButton from './LogBoxButton';
|
|
20
|
-
import
|
|
16
|
+
import LogBoxNotificationCountBadge from './LogBoxNotificationCountBadge';
|
|
17
|
+
import LogBoxNotificationDismissButton from './LogBoxNotificationDismissButton';
|
|
18
|
+
import LogBoxNotificationMessage from './LogBoxNotificationMessage';
|
|
21
19
|
import * as LogBoxStyle from './LogBoxStyle';
|
|
22
20
|
import * as React from 'react';
|
|
21
|
+
import {useEffect} from 'react';
|
|
23
22
|
|
|
24
23
|
type Props = $ReadOnly<{
|
|
25
24
|
log: LogBoxLog,
|
|
@@ -29,170 +28,34 @@ type Props = $ReadOnly<{
|
|
|
29
28
|
onPressDismiss: () => void,
|
|
30
29
|
}>;
|
|
31
30
|
|
|
32
|
-
function
|
|
31
|
+
export default function LogBoxNotification(props: Props): React.Node {
|
|
33
32
|
const {totalLogCount, level, log} = props;
|
|
34
33
|
|
|
35
34
|
// Eagerly symbolicate so the stack is available when pressing to inspect.
|
|
36
|
-
|
|
35
|
+
useEffect(() => {
|
|
37
36
|
LogBoxData.symbolicateLogLazy(log);
|
|
38
37
|
}, [log]);
|
|
39
38
|
|
|
40
39
|
return (
|
|
41
|
-
<View style={
|
|
40
|
+
<View style={styles.container}>
|
|
42
41
|
<LogBoxButton
|
|
43
42
|
onPress={props.onPressOpen}
|
|
44
|
-
style={
|
|
43
|
+
style={styles.press}
|
|
45
44
|
backgroundColor={{
|
|
46
45
|
default: LogBoxStyle.getBackgroundColor(1),
|
|
47
46
|
pressed: LogBoxStyle.getBackgroundColor(0.9),
|
|
48
47
|
}}>
|
|
49
|
-
<View style={
|
|
50
|
-
<
|
|
51
|
-
<
|
|
52
|
-
<
|
|
48
|
+
<View style={styles.content}>
|
|
49
|
+
<LogBoxNotificationCountBadge count={totalLogCount} level={level} />
|
|
50
|
+
<LogBoxNotificationMessage message={log.message} />
|
|
51
|
+
<LogBoxNotificationDismissButton onPress={props.onPressDismiss} />
|
|
53
52
|
</View>
|
|
54
53
|
</LogBoxButton>
|
|
55
54
|
</View>
|
|
56
55
|
);
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<View style={countStyles.outside}>
|
|
62
|
-
{/* $FlowFixMe[incompatible-type] (>=0.114.0) This suppression was added
|
|
63
|
-
* when fixing the type of `StyleSheet.create`. Remove this comment to
|
|
64
|
-
* see the error. */}
|
|
65
|
-
<View style={[countStyles.inside, countStyles[props.level]]}>
|
|
66
|
-
<Text style={countStyles.text}>
|
|
67
|
-
{props.count <= 1 ? '!' : props.count}
|
|
68
|
-
</Text>
|
|
69
|
-
</View>
|
|
70
|
-
</View>
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function Message(props: {message: MessageType}) {
|
|
75
|
-
return (
|
|
76
|
-
<View style={messageStyles.container}>
|
|
77
|
-
<Text numberOfLines={1} style={messageStyles.text}>
|
|
78
|
-
{props.message && (
|
|
79
|
-
<LogBoxMessage
|
|
80
|
-
plaintext
|
|
81
|
-
message={props.message}
|
|
82
|
-
style={messageStyles.substitutionText}
|
|
83
|
-
/>
|
|
84
|
-
)}
|
|
85
|
-
</Text>
|
|
86
|
-
</View>
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function DismissButton(props: {onPress: () => void}) {
|
|
91
|
-
return (
|
|
92
|
-
<View style={dismissStyles.container}>
|
|
93
|
-
<LogBoxButton
|
|
94
|
-
backgroundColor={{
|
|
95
|
-
default: LogBoxStyle.getTextColor(0.3),
|
|
96
|
-
pressed: LogBoxStyle.getTextColor(0.5),
|
|
97
|
-
}}
|
|
98
|
-
hitSlop={{
|
|
99
|
-
top: 12,
|
|
100
|
-
right: 10,
|
|
101
|
-
bottom: 12,
|
|
102
|
-
left: 10,
|
|
103
|
-
}}
|
|
104
|
-
onPress={props.onPress}
|
|
105
|
-
style={dismissStyles.press}>
|
|
106
|
-
<Image
|
|
107
|
-
source={require('./LogBoxImages/close.png')}
|
|
108
|
-
style={dismissStyles.image}
|
|
109
|
-
/>
|
|
110
|
-
</LogBoxButton>
|
|
111
|
-
</View>
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const countStyles = StyleSheet.create({
|
|
116
|
-
warn: {
|
|
117
|
-
backgroundColor: LogBoxStyle.getWarningColor(1),
|
|
118
|
-
},
|
|
119
|
-
error: {
|
|
120
|
-
backgroundColor: LogBoxStyle.getErrorColor(1),
|
|
121
|
-
},
|
|
122
|
-
log: {
|
|
123
|
-
backgroundColor: LogBoxStyle.getLogColor(1),
|
|
124
|
-
},
|
|
125
|
-
outside: {
|
|
126
|
-
padding: 2,
|
|
127
|
-
borderRadius: 25,
|
|
128
|
-
backgroundColor: '#fff',
|
|
129
|
-
marginRight: 8,
|
|
130
|
-
},
|
|
131
|
-
inside: {
|
|
132
|
-
minWidth: 18,
|
|
133
|
-
paddingLeft: 4,
|
|
134
|
-
paddingRight: 4,
|
|
135
|
-
borderRadius: 25,
|
|
136
|
-
fontWeight: '600',
|
|
137
|
-
},
|
|
138
|
-
text: {
|
|
139
|
-
color: LogBoxStyle.getTextColor(1),
|
|
140
|
-
fontSize: 14,
|
|
141
|
-
lineHeight: 18,
|
|
142
|
-
textAlign: 'center',
|
|
143
|
-
fontWeight: '600',
|
|
144
|
-
textShadowColor: LogBoxStyle.getBackgroundColor(0.4),
|
|
145
|
-
textShadowOffset: {width: 0, height: 0},
|
|
146
|
-
textShadowRadius: 3,
|
|
147
|
-
},
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
const messageStyles = StyleSheet.create({
|
|
151
|
-
container: {
|
|
152
|
-
alignSelf: 'stretch',
|
|
153
|
-
flexGrow: 1,
|
|
154
|
-
flexShrink: 1,
|
|
155
|
-
flexBasis: 'auto',
|
|
156
|
-
borderLeftColor: LogBoxStyle.getTextColor(0.2),
|
|
157
|
-
borderLeftWidth: 1,
|
|
158
|
-
paddingLeft: 8,
|
|
159
|
-
},
|
|
160
|
-
text: {
|
|
161
|
-
color: LogBoxStyle.getTextColor(1),
|
|
162
|
-
flex: 1,
|
|
163
|
-
fontSize: 14,
|
|
164
|
-
lineHeight: 22,
|
|
165
|
-
},
|
|
166
|
-
substitutionText: {
|
|
167
|
-
color: LogBoxStyle.getTextColor(0.6),
|
|
168
|
-
},
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
const dismissStyles = StyleSheet.create({
|
|
172
|
-
container: {
|
|
173
|
-
alignSelf: 'center',
|
|
174
|
-
flexDirection: 'row',
|
|
175
|
-
flexGrow: 0,
|
|
176
|
-
flexShrink: 0,
|
|
177
|
-
flexBasis: 'auto',
|
|
178
|
-
marginLeft: 5,
|
|
179
|
-
},
|
|
180
|
-
press: {
|
|
181
|
-
height: 20,
|
|
182
|
-
width: 20,
|
|
183
|
-
borderRadius: 25,
|
|
184
|
-
alignSelf: 'flex-end',
|
|
185
|
-
alignItems: 'center',
|
|
186
|
-
justifyContent: 'center',
|
|
187
|
-
},
|
|
188
|
-
image: {
|
|
189
|
-
height: 8,
|
|
190
|
-
width: 8,
|
|
191
|
-
tintColor: LogBoxStyle.getBackgroundColor(1),
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
const toastStyles = StyleSheet.create({
|
|
58
|
+
const styles = StyleSheet.create({
|
|
196
59
|
container: {
|
|
197
60
|
height: 48,
|
|
198
61
|
position: 'relative',
|
|
@@ -218,5 +81,3 @@ const toastStyles = StyleSheet.create({
|
|
|
218
81
|
flexBasis: 'auto',
|
|
219
82
|
},
|
|
220
83
|
});
|
|
221
|
-
|
|
222
|
-
export default LogBoxLogNotification;
|
|
@@ -0,0 +1,63 @@
|
|
|
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
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import View from '../../Components/View/View';
|
|
12
|
+
import StyleSheet from '../../StyleSheet/StyleSheet';
|
|
13
|
+
import Text from '../../Text/Text';
|
|
14
|
+
import * as LogBoxStyle from './LogBoxStyle';
|
|
15
|
+
import * as React from 'react';
|
|
16
|
+
|
|
17
|
+
export default function LogBoxNotificationCountBadge(props: {
|
|
18
|
+
count: number,
|
|
19
|
+
level: 'error' | 'warn',
|
|
20
|
+
}): React.Node {
|
|
21
|
+
return (
|
|
22
|
+
<View style={styles.outside}>
|
|
23
|
+
{/* $FlowFixMe[incompatible-type] (>=0.114.0) This suppression was added
|
|
24
|
+
* when fixing the type of `StyleSheet.create`. Remove this comment to
|
|
25
|
+
* see the error. */}
|
|
26
|
+
<View style={[styles.inside, styles[props.level]]}>
|
|
27
|
+
<Text style={styles.text}>{props.count <= 1 ? '!' : props.count}</Text>
|
|
28
|
+
</View>
|
|
29
|
+
</View>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const styles = StyleSheet.create({
|
|
34
|
+
warn: {
|
|
35
|
+
backgroundColor: LogBoxStyle.getWarningColor(1),
|
|
36
|
+
},
|
|
37
|
+
error: {
|
|
38
|
+
backgroundColor: LogBoxStyle.getErrorColor(1),
|
|
39
|
+
},
|
|
40
|
+
outside: {
|
|
41
|
+
padding: 2,
|
|
42
|
+
borderRadius: 25,
|
|
43
|
+
backgroundColor: '#fff',
|
|
44
|
+
marginRight: 8,
|
|
45
|
+
},
|
|
46
|
+
inside: {
|
|
47
|
+
minWidth: 18,
|
|
48
|
+
paddingLeft: 4,
|
|
49
|
+
paddingRight: 4,
|
|
50
|
+
borderRadius: 25,
|
|
51
|
+
fontWeight: '600',
|
|
52
|
+
},
|
|
53
|
+
text: {
|
|
54
|
+
color: LogBoxStyle.getTextColor(1),
|
|
55
|
+
fontSize: 14,
|
|
56
|
+
lineHeight: 18,
|
|
57
|
+
textAlign: 'center',
|
|
58
|
+
fontWeight: '600',
|
|
59
|
+
textShadowColor: LogBoxStyle.getBackgroundColor(0.4),
|
|
60
|
+
textShadowOffset: {width: 0, height: 0},
|
|
61
|
+
textShadowRadius: 3,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
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
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import View from '../../Components/View/View';
|
|
12
|
+
import Image from '../../Image/Image';
|
|
13
|
+
import StyleSheet from '../../StyleSheet/StyleSheet';
|
|
14
|
+
import LogBoxButton from './LogBoxButton';
|
|
15
|
+
import * as LogBoxStyle from './LogBoxStyle';
|
|
16
|
+
import * as React from 'react';
|
|
17
|
+
|
|
18
|
+
export default function LogBoxNotificationDismissButton(props: {
|
|
19
|
+
onPress: () => void,
|
|
20
|
+
}): React.Node {
|
|
21
|
+
return (
|
|
22
|
+
<View style={styles.container}>
|
|
23
|
+
<LogBoxButton
|
|
24
|
+
backgroundColor={{
|
|
25
|
+
default: LogBoxStyle.getTextColor(0.3),
|
|
26
|
+
pressed: LogBoxStyle.getTextColor(0.5),
|
|
27
|
+
}}
|
|
28
|
+
hitSlop={{
|
|
29
|
+
top: 12,
|
|
30
|
+
right: 10,
|
|
31
|
+
bottom: 12,
|
|
32
|
+
left: 10,
|
|
33
|
+
}}
|
|
34
|
+
onPress={props.onPress}
|
|
35
|
+
style={styles.press}>
|
|
36
|
+
<Image
|
|
37
|
+
source={require('./LogBoxImages/close.png')}
|
|
38
|
+
style={styles.image}
|
|
39
|
+
/>
|
|
40
|
+
</LogBoxButton>
|
|
41
|
+
</View>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const styles = StyleSheet.create({
|
|
46
|
+
container: {
|
|
47
|
+
alignSelf: 'center',
|
|
48
|
+
flexDirection: 'row',
|
|
49
|
+
flexGrow: 0,
|
|
50
|
+
flexShrink: 0,
|
|
51
|
+
flexBasis: 'auto',
|
|
52
|
+
marginLeft: 5,
|
|
53
|
+
},
|
|
54
|
+
press: {
|
|
55
|
+
height: 20,
|
|
56
|
+
width: 20,
|
|
57
|
+
borderRadius: 25,
|
|
58
|
+
alignSelf: 'flex-end',
|
|
59
|
+
alignItems: 'center',
|
|
60
|
+
justifyContent: 'center',
|
|
61
|
+
},
|
|
62
|
+
image: {
|
|
63
|
+
height: 8,
|
|
64
|
+
width: 8,
|
|
65
|
+
tintColor: LogBoxStyle.getBackgroundColor(1),
|
|
66
|
+
},
|
|
67
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
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
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type {Message as MessageType} from '../Data/parseLogBoxLog';
|
|
12
|
+
|
|
13
|
+
import View from '../../Components/View/View';
|
|
14
|
+
import StyleSheet from '../../StyleSheet/StyleSheet';
|
|
15
|
+
import Text from '../../Text/Text';
|
|
16
|
+
import LogBoxMessage from './LogBoxMessage';
|
|
17
|
+
import * as LogBoxStyle from './LogBoxStyle';
|
|
18
|
+
import * as React from 'react';
|
|
19
|
+
|
|
20
|
+
export default function LogBoxNotificationMessage(props: {
|
|
21
|
+
message: MessageType,
|
|
22
|
+
}): React.Node {
|
|
23
|
+
return (
|
|
24
|
+
<View style={styles.container}>
|
|
25
|
+
<Text numberOfLines={1} style={styles.text}>
|
|
26
|
+
{props.message && (
|
|
27
|
+
<LogBoxMessage
|
|
28
|
+
plaintext
|
|
29
|
+
message={props.message}
|
|
30
|
+
style={styles.substitutionText}
|
|
31
|
+
/>
|
|
32
|
+
)}
|
|
33
|
+
</Text>
|
|
34
|
+
</View>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const styles = StyleSheet.create({
|
|
39
|
+
container: {
|
|
40
|
+
alignSelf: 'stretch',
|
|
41
|
+
flexGrow: 1,
|
|
42
|
+
flexShrink: 1,
|
|
43
|
+
flexBasis: 'auto',
|
|
44
|
+
borderLeftColor: LogBoxStyle.getTextColor(0.2),
|
|
45
|
+
borderLeftWidth: 1,
|
|
46
|
+
paddingLeft: 8,
|
|
47
|
+
},
|
|
48
|
+
text: {
|
|
49
|
+
color: LogBoxStyle.getTextColor(1),
|
|
50
|
+
flex: 1,
|
|
51
|
+
fontSize: 14,
|
|
52
|
+
lineHeight: 22,
|
|
53
|
+
},
|
|
54
|
+
substitutionText: {
|
|
55
|
+
color: LogBoxStyle.getTextColor(0.6),
|
|
56
|
+
},
|
|
57
|
+
});
|
|
@@ -166,6 +166,9 @@ const validAttributesForNonEventProps = {
|
|
|
166
166
|
backgroundColor: {process: require('../StyleSheet/processColor').default},
|
|
167
167
|
transform: true,
|
|
168
168
|
transformOrigin: true,
|
|
169
|
+
experimental_filter: {
|
|
170
|
+
process: require('../StyleSheet/processFilter').default,
|
|
171
|
+
},
|
|
169
172
|
opacity: true,
|
|
170
173
|
elevation: true,
|
|
171
174
|
shadowColor: {process: require('../StyleSheet/processColor').default},
|
|
@@ -195,6 +198,7 @@ const validAttributesForNonEventProps = {
|
|
|
195
198
|
width: true,
|
|
196
199
|
minWidth: true,
|
|
197
200
|
collapsable: true,
|
|
201
|
+
collapsableChildren: true,
|
|
198
202
|
maxWidth: true,
|
|
199
203
|
height: true,
|
|
200
204
|
minHeight: true,
|
|
@@ -305,6 +309,7 @@ const validAttributesForEventProps = {
|
|
|
305
309
|
|
|
306
310
|
// Pointer events
|
|
307
311
|
onClick: true,
|
|
312
|
+
onClickCapture: true,
|
|
308
313
|
onPointerEnter: true,
|
|
309
314
|
onPointerEnterCapture: true,
|
|
310
315
|
onPointerLeave: true,
|
|
@@ -219,6 +219,10 @@ const validAttributesForNonEventProps = {
|
|
|
219
219
|
borderStyle: true,
|
|
220
220
|
hitSlop: {diff: require('../Utilities/differ/insetsDiffer')},
|
|
221
221
|
collapsable: true,
|
|
222
|
+
collapsableChildren: true,
|
|
223
|
+
experimental_filter: {
|
|
224
|
+
process: require('../StyleSheet/processFilter').default,
|
|
225
|
+
},
|
|
222
226
|
|
|
223
227
|
borderTopWidth: true,
|
|
224
228
|
borderTopColor: {process: require('../StyleSheet/processColor').default},
|
|
@@ -373,6 +377,7 @@ const validAttributesForEventProps = ConditionallyIgnoredEventHandlers({
|
|
|
373
377
|
|
|
374
378
|
// Pointer events
|
|
375
379
|
onClick: true,
|
|
380
|
+
onClickCapture: true,
|
|
376
381
|
onPointerUp: true,
|
|
377
382
|
onPointerDown: true,
|
|
378
383
|
onPointerCancel: true,
|
|
@@ -219,6 +219,10 @@ const validAttributesForNonEventProps = {
|
|
|
219
219
|
borderStyle: true,
|
|
220
220
|
hitSlop: {diff: require('../Utilities/differ/insetsDiffer')},
|
|
221
221
|
collapsable: true,
|
|
222
|
+
collapsableChildren: true,
|
|
223
|
+
experimental_filter: {
|
|
224
|
+
process: require('../StyleSheet/processFilter').default,
|
|
225
|
+
},
|
|
222
226
|
|
|
223
227
|
borderTopWidth: true,
|
|
224
228
|
borderTopColor: {process: require('../StyleSheet/processColor').default},
|
|
@@ -373,6 +377,7 @@ const validAttributesForEventProps = ConditionallyIgnoredEventHandlers({
|
|
|
373
377
|
|
|
374
378
|
// Pointer events
|
|
375
379
|
onClick: true,
|
|
380
|
+
onClickCapture: true,
|
|
376
381
|
onPointerUp: true,
|
|
377
382
|
onPointerDown: true,
|
|
378
383
|
onPointerCancel: true,
|
|
@@ -62,14 +62,21 @@ export function get<Config>(
|
|
|
62
62
|
|
|
63
63
|
let viewConfig;
|
|
64
64
|
if (native) {
|
|
65
|
-
viewConfig =
|
|
65
|
+
viewConfig =
|
|
66
|
+
getNativeComponentAttributes(name) ??
|
|
67
|
+
createViewConfig(viewConfigProvider());
|
|
66
68
|
} else {
|
|
67
|
-
viewConfig =
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
69
|
+
viewConfig =
|
|
70
|
+
createViewConfig(viewConfigProvider()) ??
|
|
71
|
+
getNativeComponentAttributes(name);
|
|
71
72
|
}
|
|
72
73
|
|
|
74
|
+
invariant(
|
|
75
|
+
viewConfig != null,
|
|
76
|
+
'NativeComponentRegistry.get: both static and native view config are missing for native component "%s".',
|
|
77
|
+
name,
|
|
78
|
+
);
|
|
79
|
+
|
|
73
80
|
if (verify) {
|
|
74
81
|
const nativeViewConfig = native
|
|
75
82
|
? viewConfig
|
|
@@ -105,6 +105,7 @@ function accumulateDifferences(
|
|
|
105
105
|
staticObject: {...},
|
|
106
106
|
): void {
|
|
107
107
|
for (const nativeKey in nativeObject) {
|
|
108
|
+
// $FlowFixMe[invalid-computed-prop]
|
|
108
109
|
const nativeValue = nativeObject[nativeKey];
|
|
109
110
|
|
|
110
111
|
if (!staticObject.hasOwnProperty(nativeKey)) {
|
|
@@ -116,6 +117,7 @@ function accumulateDifferences(
|
|
|
116
117
|
continue;
|
|
117
118
|
}
|
|
118
119
|
|
|
120
|
+
// $FlowFixMe[invalid-computed-prop]
|
|
119
121
|
const staticValue = staticObject[nativeKey];
|
|
120
122
|
|
|
121
123
|
const nativeValueIfObject = ifObject(nativeValue);
|
|
@@ -147,6 +149,7 @@ function accumulateDifferences(
|
|
|
147
149
|
for (const staticKey in staticObject) {
|
|
148
150
|
if (
|
|
149
151
|
!nativeObject.hasOwnProperty(staticKey) &&
|
|
152
|
+
// $FlowFixMe[invalid-computed-prop]
|
|
150
153
|
!isIgnored(staticObject[staticKey])
|
|
151
154
|
) {
|
|
152
155
|
differences.push({
|
|
@@ -248,7 +248,10 @@ class XMLHttpRequest extends (EventTarget(...XHR_EVENTS): any) {
|
|
|
248
248
|
} else if (this._response === '') {
|
|
249
249
|
this._cachedResponse = BlobManager.createFromParts([]);
|
|
250
250
|
} else {
|
|
251
|
-
throw new Error(
|
|
251
|
+
throw new Error(
|
|
252
|
+
'Invalid response for blob - expecting object, was ' +
|
|
253
|
+
`${typeof this._response}: ${this._response.trim()}`,
|
|
254
|
+
);
|
|
252
255
|
}
|
|
253
256
|
break;
|
|
254
257
|
|
|
@@ -627,6 +630,7 @@ class XMLHttpRequest extends (EventTarget(...XHR_EVENTS): any) {
|
|
|
627
630
|
this._lowerCaseResponseHeaders = Object.keys(headers).reduce<{
|
|
628
631
|
[string]: any,
|
|
629
632
|
}>((lcaseHeaders, headerName) => {
|
|
633
|
+
// $FlowFixMe[invalid-computed-prop]
|
|
630
634
|
lcaseHeaders[headerName.toLowerCase()] = headers[headerName];
|
|
631
635
|
return lcaseHeaders;
|
|
632
636
|
}, {});
|
|
@@ -74,10 +74,10 @@ const links = [
|
|
|
74
74
|
},
|
|
75
75
|
{
|
|
76
76
|
id: 9,
|
|
77
|
-
title: 'Follow us
|
|
78
|
-
link: 'https://
|
|
77
|
+
title: 'Follow us',
|
|
78
|
+
link: 'https://x.com/reactnative',
|
|
79
79
|
description:
|
|
80
|
-
'Stay in touch with the community, join in on Q&As and more by following React Native on
|
|
80
|
+
'Stay in touch with the community, join in on Q&As and more by following React Native on X.',
|
|
81
81
|
},
|
|
82
82
|
];
|
|
83
83
|
|