@momo-kits/foundation 0.167.1-duo.2 → 0.167.1-duo.4
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/Application/BottomSheet.tsx +111 -10
- package/Application/BottomTab/DuoBarCompression.tsx +135 -0
- package/Application/BottomTab/DuoTabBar.tsx +462 -0
- package/Application/BottomTab/index.tsx +145 -123
- package/Application/Components/DuoGlassBackground.tsx +179 -0
- package/Application/Components/DuoQuickReturnHeader.tsx +42 -0
- package/Application/Components/HeaderLeft.tsx +8 -2
- package/Application/Components/HeaderRight.tsx +47 -2
- package/Application/Components/OptionalGlassView.ts +11 -0
- package/Application/ModalScreen.tsx +14 -0
- package/Application/NavigationContainer.tsx +14 -11
- package/Application/device.ts +29 -0
- package/Application/types.ts +5 -0
- package/Layout/ReservedRegions.tsx +47 -0
- package/Layout/Screen.tsx +187 -32
- package/Layout/utils.ts +76 -8
- package/Popup/PopupNotify.tsx +31 -20
- package/Popup/PopupPromotion.tsx +20 -8
- package/Popup/utils.ts +32 -0
- package/package.json +1 -1
package/Popup/PopupNotify.tsx
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import React, { useContext, useRef, useState } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
Dimensions,
|
|
4
|
-
ScrollView,
|
|
5
|
-
StyleSheet,
|
|
6
|
-
TouchableOpacity,
|
|
7
|
-
View,
|
|
8
|
-
} from 'react-native';
|
|
2
|
+
import { ScrollView, StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
9
3
|
import { ApplicationContext, MiniAppContext } from '../Context';
|
|
10
4
|
import { Button } from '../Button';
|
|
11
5
|
import { Colors, Radius, Spacing, Styles } from '../Consts';
|
|
@@ -14,6 +8,7 @@ import { Image } from '../Image';
|
|
|
14
8
|
import { Text, useScaleSize } from '../Text';
|
|
15
9
|
import { PopupNotifyProps } from './types';
|
|
16
10
|
import { scheduleOnRN } from 'react-native-worklets';
|
|
11
|
+
import { usePopupMaxHeight, usePopupWidth } from './utils';
|
|
17
12
|
|
|
18
13
|
const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
19
14
|
image,
|
|
@@ -29,7 +24,8 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
29
24
|
const context = useContext<any>(MiniAppContext);
|
|
30
25
|
const { theme, navigator, translate } = useContext(ApplicationContext);
|
|
31
26
|
const [scrollContent, setScrollContent] = useState(false);
|
|
32
|
-
const
|
|
27
|
+
const popupWidth = usePopupWidth();
|
|
28
|
+
const maxHeight = usePopupMaxHeight();
|
|
33
29
|
const scaledMaxHeight = useScaleSize(172);
|
|
34
30
|
|
|
35
31
|
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
@@ -172,18 +168,8 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
172
168
|
}
|
|
173
169
|
};
|
|
174
170
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
accessibilityLabel={'popup_notify'}
|
|
178
|
-
style={[
|
|
179
|
-
styles.container,
|
|
180
|
-
{
|
|
181
|
-
backgroundColor: theme.colors.background.surface,
|
|
182
|
-
width: widthDevice - Spacing.XL * 2,
|
|
183
|
-
},
|
|
184
|
-
showBaseLineDebug && styles.debugBaseLine,
|
|
185
|
-
]}
|
|
186
|
-
>
|
|
171
|
+
const body = (
|
|
172
|
+
<>
|
|
187
173
|
{!!image && <Image source={{ uri: image }} style={styles.image} />}
|
|
188
174
|
<View style={styles.content}>
|
|
189
175
|
<Text
|
|
@@ -225,6 +211,30 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
225
211
|
</View>
|
|
226
212
|
)}
|
|
227
213
|
</View>
|
|
214
|
+
</>
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
return (
|
|
218
|
+
<View
|
|
219
|
+
accessibilityLabel={'popup_notify'}
|
|
220
|
+
style={[
|
|
221
|
+
styles.container,
|
|
222
|
+
{
|
|
223
|
+
backgroundColor: theme.colors.background.surface,
|
|
224
|
+
width: popupWidth,
|
|
225
|
+
maxHeight,
|
|
226
|
+
},
|
|
227
|
+
showBaseLineDebug && styles.debugBaseLine,
|
|
228
|
+
]}
|
|
229
|
+
>
|
|
230
|
+
{maxHeight === undefined ? (
|
|
231
|
+
body
|
|
232
|
+
) : (
|
|
233
|
+
// scrolls when iPhone Duo landscape is too short; actions stay visible
|
|
234
|
+
<ScrollView style={styles.body} bounces={false}>
|
|
235
|
+
{body}
|
|
236
|
+
</ScrollView>
|
|
237
|
+
)}
|
|
228
238
|
<View style={styles.contentAction}>{buildAction()}</View>
|
|
229
239
|
{buildCloseIcon()}
|
|
230
240
|
</View>
|
|
@@ -242,6 +252,7 @@ const styles = StyleSheet.create({
|
|
|
242
252
|
aspectRatio: 1.7777,
|
|
243
253
|
overflow: 'hidden',
|
|
244
254
|
},
|
|
255
|
+
body: { flexShrink: 1 },
|
|
245
256
|
content: { padding: Spacing.XL },
|
|
246
257
|
description: {
|
|
247
258
|
marginTop: Spacing.S,
|
package/Popup/PopupPromotion.tsx
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import React, { useContext, useRef } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
3
3
|
import { PopupPromotionProps } from './types';
|
|
4
4
|
import { ApplicationContext, MiniAppContext } from '../Context';
|
|
5
5
|
import { Image } from '../Image';
|
|
6
6
|
import { Colors, Radius, Spacing } from '../Consts';
|
|
7
7
|
import { Icon } from '../Icon';
|
|
8
|
+
import { usePopupMaxHeight, usePopupWidth } from './utils';
|
|
9
|
+
|
|
10
|
+
const ASPECT_RATIO = 0.72;
|
|
11
|
+
const ICON_CLOSE_SIZE = 20;
|
|
12
|
+
// close button row under the image: marginTop + vertical padding + icon
|
|
13
|
+
const CLOSE_ROW_HEIGHT = Spacing.S * 3 + ICON_CLOSE_SIZE;
|
|
8
14
|
|
|
9
15
|
const PopupPromotion: React.FC<PopupPromotionProps> = ({
|
|
10
16
|
image,
|
|
@@ -14,7 +20,13 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
|
|
|
14
20
|
}) => {
|
|
15
21
|
const context = useContext<any>(MiniAppContext);
|
|
16
22
|
const { theme, navigator } = useContext(ApplicationContext);
|
|
17
|
-
const
|
|
23
|
+
const popupWidth = usePopupWidth();
|
|
24
|
+
const maxHeight = usePopupMaxHeight();
|
|
25
|
+
// fit the portrait image by height when iPhone Duo leaves too little room
|
|
26
|
+
const imageWidth =
|
|
27
|
+
maxHeight === undefined
|
|
28
|
+
? popupWidth
|
|
29
|
+
: Math.min(popupWidth, (maxHeight - CLOSE_ROW_HEIGHT) * ASPECT_RATIO);
|
|
18
30
|
const closeAction = useRef('touch_outside');
|
|
19
31
|
|
|
20
32
|
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
@@ -69,7 +81,7 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
|
|
|
69
81
|
return (
|
|
70
82
|
<View
|
|
71
83
|
accessibilityLabel={'popup_promotion'}
|
|
72
|
-
style={showBaseLineDebug && styles.debugBaseLine}
|
|
84
|
+
style={[{ width: imageWidth }, showBaseLineDebug && styles.debugBaseLine]}
|
|
73
85
|
>
|
|
74
86
|
<TouchableOpacity onPress={() => onAction(onActionClick)}>
|
|
75
87
|
<Image
|
|
@@ -80,7 +92,7 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
|
|
|
80
92
|
style={[
|
|
81
93
|
styles.container,
|
|
82
94
|
{
|
|
83
|
-
width:
|
|
95
|
+
width: imageWidth,
|
|
84
96
|
},
|
|
85
97
|
]}
|
|
86
98
|
/>
|
|
@@ -92,7 +104,7 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
|
|
|
92
104
|
|
|
93
105
|
const styles = StyleSheet.create({
|
|
94
106
|
container: {
|
|
95
|
-
aspectRatio:
|
|
107
|
+
aspectRatio: ASPECT_RATIO,
|
|
96
108
|
width: '100%',
|
|
97
109
|
},
|
|
98
110
|
debugBaseLine: { borderWidth: 1, borderColor: Colors.green_06 },
|
|
@@ -103,11 +115,11 @@ const styles = StyleSheet.create({
|
|
|
103
115
|
marginTop: Spacing.S,
|
|
104
116
|
},
|
|
105
117
|
iconButton: {
|
|
106
|
-
padding:
|
|
118
|
+
padding: Spacing.S,
|
|
107
119
|
},
|
|
108
120
|
iconClose: {
|
|
109
|
-
width:
|
|
110
|
-
height:
|
|
121
|
+
width: ICON_CLOSE_SIZE,
|
|
122
|
+
height: ICON_CLOSE_SIZE,
|
|
111
123
|
alignItems: 'center',
|
|
112
124
|
justifyContent: 'center',
|
|
113
125
|
borderRadius: Radius.M,
|
package/Popup/utils.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Dimensions, useWindowDimensions } from 'react-native';
|
|
2
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
3
|
+
import { Spacing } from '../Consts';
|
|
4
|
+
import { getDuoTopInset, isIPhoneDuo } from '../Application/device';
|
|
5
|
+
|
|
6
|
+
// width of a system alert on the iPhone Duo inner display, in both orientations
|
|
7
|
+
const DUO_POPUP_MAX_WIDTH = 440;
|
|
8
|
+
|
|
9
|
+
const usePopupWidth = () => {
|
|
10
|
+
const windowSize = useWindowDimensions();
|
|
11
|
+
if (!isIPhoneDuo()) {
|
|
12
|
+
return Dimensions.get('window').width - Spacing.XL * 2;
|
|
13
|
+
}
|
|
14
|
+
return Math.min(windowSize.width - Spacing.XL * 2, DUO_POPUP_MAX_WIDTH);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// room left for a popup on iPhone Duo, where landscape is too short for it
|
|
18
|
+
const usePopupMaxHeight = () => {
|
|
19
|
+
const insets = useSafeAreaInsets();
|
|
20
|
+
const { width, height } = useWindowDimensions();
|
|
21
|
+
if (!isIPhoneDuo()) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
return (
|
|
25
|
+
height -
|
|
26
|
+
getDuoTopInset(insets, width, height) -
|
|
27
|
+
insets.bottom -
|
|
28
|
+
Spacing.XL * 2
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export { usePopupWidth, usePopupMaxHeight };
|