@momo-kits/foundation 0.167.1-beta.7 → 0.167.1-duo.2
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 +4 -4
- package/Application/BottomTab/BottomTabBar.tsx +6 -3
- package/Application/BottomTab/index.tsx +10 -11
- package/Application/Components/HeaderExtendHeader.tsx +40 -27
- package/Application/Components/HeaderLeft.tsx +17 -0
- package/Application/Components/HeaderRight.tsx +59 -9
- package/Application/Components/HeaderTitle.tsx +47 -21
- package/Application/Components/SearchHeader.tsx +15 -14
- package/Application/Components/SideBarButton.tsx +128 -0
- package/Application/ModalScreen.tsx +2 -2
- package/Application/NavigationContainer.tsx +22 -37
- package/Application/Navigator.ts +1 -3
- package/Application/StackScreen.tsx +2 -5
- package/Application/WidgetContainer.tsx +9 -15
- package/Application/types.ts +5 -1
- package/Application/utils.tsx +10 -3
- package/Consts/index.ts +0 -1
- package/Consts/theme.ts +3 -4
- package/Input/Input.tsx +3 -4
- package/Input/InputMoney.tsx +31 -51
- package/Input/InputPhoneNumber.tsx +3 -4
- package/Input/InputSearch.tsx +3 -4
- package/Input/InputTextArea.tsx +3 -4
- package/Layout/Card.tsx +8 -26
- package/Layout/FloatingButton.tsx +3 -3
- package/Layout/Item.tsx +1 -10
- package/Layout/Screen.tsx +39 -12
- package/Layout/Section.tsx +5 -18
- package/Layout/index.ts +4 -4
- package/Layout/utils.ts +280 -5
- package/Popup/PopupNotify.tsx +2 -2
- package/Text/index.tsx +5 -15
- package/Text/utils.ts +1 -2
- package/package.json +3 -2
- package/Consts/designSystemFont.ts +0 -25
- package/Layout/GridSystem.tsx +0 -137
|
@@ -22,12 +22,12 @@ import Animated, {
|
|
|
22
22
|
Easing,
|
|
23
23
|
Extrapolation,
|
|
24
24
|
interpolate,
|
|
25
|
-
runOnJS,
|
|
26
25
|
useAnimatedStyle,
|
|
27
26
|
useSharedValue,
|
|
28
27
|
withSpring,
|
|
29
28
|
withTiming,
|
|
30
29
|
} from 'react-native-reanimated';
|
|
30
|
+
import { scheduleOnRN } from 'react-native-worklets';
|
|
31
31
|
import layoutStyles from '../Layout/styles';
|
|
32
32
|
|
|
33
33
|
const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
@@ -74,7 +74,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
74
74
|
duration: 200,
|
|
75
75
|
easing: Easing.bezier(0.3, 0.0, 0.8, 0.15),
|
|
76
76
|
},
|
|
77
|
-
() =>
|
|
77
|
+
() => scheduleOnRN(callback),
|
|
78
78
|
);
|
|
79
79
|
},
|
|
80
80
|
[heightDevice, translateY],
|
|
@@ -137,9 +137,9 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
137
137
|
}
|
|
138
138
|
closeAnimation(() => {
|
|
139
139
|
navigator?.pop();
|
|
140
|
-
|
|
140
|
+
scheduleOnRN(() => {
|
|
141
141
|
callback?.();
|
|
142
|
-
})
|
|
142
|
+
});
|
|
143
143
|
});
|
|
144
144
|
},
|
|
145
145
|
[barrierDismissible, closeAnimation, navigator],
|
|
@@ -58,11 +58,13 @@ export default function BottomTabBar({
|
|
|
58
58
|
const { theme } = useContext(ApplicationContext);
|
|
59
59
|
const { routes } = state;
|
|
60
60
|
const widthDevice = useWindowDimensions()?.width;
|
|
61
|
+
const insets = useSafeAreaInsets();
|
|
61
62
|
const useFloating = floatingButton && state.routes.length % 2 === 0;
|
|
62
|
-
const itemWidth =
|
|
63
|
+
const itemWidth =
|
|
64
|
+
(widthDevice - insets.left - insets.right) /
|
|
65
|
+
(state.routes.length + (useFloating ? 1 : 0));
|
|
63
66
|
// const buildLink = useLinkBuilder();
|
|
64
67
|
const indicatorAnimated = useSharedValue(0);
|
|
65
|
-
const insets = useSafeAreaInsets();
|
|
66
68
|
|
|
67
69
|
const indicatorStyle = useAnimatedStyle(() => ({
|
|
68
70
|
width: itemWidth,
|
|
@@ -246,7 +248,8 @@ export default function BottomTabBar({
|
|
|
246
248
|
},
|
|
247
249
|
{
|
|
248
250
|
paddingBottom: paddingBottom,
|
|
249
|
-
|
|
251
|
+
paddingLeft: insets.left,
|
|
252
|
+
paddingRight: insets.right,
|
|
250
253
|
},
|
|
251
254
|
style,
|
|
252
255
|
]}
|
|
@@ -28,6 +28,7 @@ import { BottomTabProps } from '../types';
|
|
|
28
28
|
import { getOptions, getStackOptions, useAppState } from '../utils';
|
|
29
29
|
import BottomTabBar from './BottomTabBar';
|
|
30
30
|
import { ApplicationContext, MiniAppContext } from '../../Context';
|
|
31
|
+
import { useScreenLayout } from '../../Layout';
|
|
31
32
|
|
|
32
33
|
const Tab = createBottomTabNavigator();
|
|
33
34
|
const Stack = createStackNavigator();
|
|
@@ -36,7 +37,13 @@ const TabScreen: React.FC<any> = ({ route, navigation }) => {
|
|
|
36
37
|
const { navigator } = useContext(ApplicationContext);
|
|
37
38
|
const context = useContext<any>(MiniAppContext);
|
|
38
39
|
const { nested, options, screen, initialParams } = route?.params;
|
|
39
|
-
const
|
|
40
|
+
const { headerHeight, headerStatusBarHeight } = useScreenLayout();
|
|
41
|
+
const headerStyleOptions = {
|
|
42
|
+
headerStyle: {
|
|
43
|
+
height: headerHeight,
|
|
44
|
+
},
|
|
45
|
+
headerStatusBarHeight,
|
|
46
|
+
};
|
|
40
47
|
|
|
41
48
|
const opacityValue = 0.3;
|
|
42
49
|
const scaleValue = 0.97;
|
|
@@ -139,11 +146,7 @@ const TabScreen: React.FC<any> = ({ route, navigation }) => {
|
|
|
139
146
|
return (
|
|
140
147
|
<Animated.View style={[styles.container, tabAnimatedStyle]}>
|
|
141
148
|
<Stack.Navigator
|
|
142
|
-
screenOptions={
|
|
143
|
-
headerStyle: {
|
|
144
|
-
height: 52 + insets.top,
|
|
145
|
-
},
|
|
146
|
-
}}
|
|
149
|
+
screenOptions={headerStyleOptions}
|
|
147
150
|
>
|
|
148
151
|
<Stack.Screen
|
|
149
152
|
name="Stack"
|
|
@@ -174,11 +177,7 @@ const TabScreen: React.FC<any> = ({ route, navigation }) => {
|
|
|
174
177
|
<NavigationIndependentTree>
|
|
175
178
|
<NavigationContainer>
|
|
176
179
|
<Stack.Navigator
|
|
177
|
-
screenOptions={
|
|
178
|
-
headerStyle: {
|
|
179
|
-
height: 52 + insets.top,
|
|
180
|
-
},
|
|
181
|
-
}}
|
|
180
|
+
screenOptions={headerStyleOptions}
|
|
182
181
|
>
|
|
183
182
|
<Stack.Screen
|
|
184
183
|
name="Stack"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { Ref, useContext } from 'react';
|
|
2
2
|
import LinearGradient from 'react-native-linear-gradient';
|
|
3
|
-
import {
|
|
3
|
+
import { Platform, StyleSheet, View } from 'react-native';
|
|
4
4
|
import Animated, {
|
|
5
5
|
Extrapolation,
|
|
6
6
|
interpolate,
|
|
@@ -14,21 +14,18 @@ import { Colors, Radius, Spacing } from '../../Consts';
|
|
|
14
14
|
import { Image } from '../../Image';
|
|
15
15
|
import { SearchHeaderProps } from '../types';
|
|
16
16
|
import BackgroundImageView from './BackgroundImageView';
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
useNormalizedSharedValue,
|
|
20
|
-
} from '../utils';
|
|
17
|
+
import { AnimatedCompatValue, useNormalizedSharedValue } from '../utils';
|
|
18
|
+
import { useScreenLayout } from '../../Layout';
|
|
21
19
|
|
|
22
20
|
const SCREEN_PADDING = 12;
|
|
23
21
|
const BACK_WIDTH = 28;
|
|
24
|
-
|
|
25
|
-
const { width: screenWidth } = Dimensions.get('window');
|
|
22
|
+
const TOOLKIT_WIDTH = 73;
|
|
26
23
|
|
|
27
24
|
const HeaderExtendHeader: React.FC<{
|
|
28
25
|
headerType?: HeaderType;
|
|
29
26
|
animatedValue: AnimatedCompatValue;
|
|
30
27
|
heightHeader: number;
|
|
31
|
-
headerRightWidth
|
|
28
|
+
headerRightWidth?: number;
|
|
32
29
|
inputSearchProps?: SearchHeaderProps;
|
|
33
30
|
inputSearchRef?: Ref<InputRef>;
|
|
34
31
|
navigation?: Navigation;
|
|
@@ -39,7 +36,7 @@ const HeaderExtendHeader: React.FC<{
|
|
|
39
36
|
headerType = 'default',
|
|
40
37
|
animatedValue,
|
|
41
38
|
heightHeader,
|
|
42
|
-
headerRightWidth
|
|
39
|
+
headerRightWidth: customHeaderRightWidth,
|
|
43
40
|
inputSearchProps,
|
|
44
41
|
inputSearchRef,
|
|
45
42
|
useShadowHeader: useShadowHeaderProp = true,
|
|
@@ -51,7 +48,19 @@ const HeaderExtendHeader: React.FC<{
|
|
|
51
48
|
const sharedValue = useNormalizedSharedValue(animatedValue);
|
|
52
49
|
const gradientColor = customGradientColor ?? theme.colors.gradient;
|
|
53
50
|
const headerBackground = customBackground ?? theme.assets?.headerBackground;
|
|
54
|
-
const
|
|
51
|
+
const layout = useScreenLayout();
|
|
52
|
+
|
|
53
|
+
const leftPosition =
|
|
54
|
+
inputSearchProps?.leftPosition ||
|
|
55
|
+
(layout.sideBar ? SCREEN_PADDING : BACK_WIDTH + 20);
|
|
56
|
+
const headerRightWidth =
|
|
57
|
+
customHeaderRightWidth ?? (layout.sideBar ? 0 : TOOLKIT_WIDTH);
|
|
58
|
+
const contentLeft = layout.insetLeft + SCREEN_PADDING;
|
|
59
|
+
const contentRight = layout.insetLeft + layout.contentWidth;
|
|
60
|
+
const collapsedLeft = layout.insetLeft + leftPosition;
|
|
61
|
+
const searchWidth = layout.contentWidth - SCREEN_PADDING * 2;
|
|
62
|
+
const collapsedSearchWidth =
|
|
63
|
+
contentRight - collapsedLeft - SCREEN_PADDING - headerRightWidth;
|
|
55
64
|
|
|
56
65
|
let useShadowHeader = useShadowHeaderProp;
|
|
57
66
|
if (inputSearchProps && Platform.OS === 'android') {
|
|
@@ -70,7 +79,12 @@ const HeaderExtendHeader: React.FC<{
|
|
|
70
79
|
}));
|
|
71
80
|
|
|
72
81
|
const gradientOpacityStyle = useAnimatedStyle(() => ({
|
|
73
|
-
opacity: interpolate(
|
|
82
|
+
opacity: interpolate(
|
|
83
|
+
sharedValue.value,
|
|
84
|
+
[0, 52],
|
|
85
|
+
[1, 0],
|
|
86
|
+
Extrapolation.CLAMP,
|
|
87
|
+
),
|
|
74
88
|
}));
|
|
75
89
|
|
|
76
90
|
const searchTranslateStyle = useAnimatedStyle(() => ({
|
|
@@ -79,7 +93,7 @@ const HeaderExtendHeader: React.FC<{
|
|
|
79
93
|
translateX: interpolate(
|
|
80
94
|
sharedValue.value,
|
|
81
95
|
[0, 100],
|
|
82
|
-
[
|
|
96
|
+
[contentLeft, collapsedLeft],
|
|
83
97
|
Extrapolation.CLAMP,
|
|
84
98
|
),
|
|
85
99
|
},
|
|
@@ -87,19 +101,19 @@ const HeaderExtendHeader: React.FC<{
|
|
|
87
101
|
width: interpolate(
|
|
88
102
|
sharedValue.value,
|
|
89
103
|
[0, 100],
|
|
90
|
-
[
|
|
91
|
-
screenWidth - SCREEN_PADDING * 2,
|
|
92
|
-
screenWidth - leftPosition - 12 - headerRightWidth,
|
|
93
|
-
],
|
|
104
|
+
[searchWidth, collapsedSearchWidth],
|
|
94
105
|
Extrapolation.CLAMP,
|
|
95
106
|
),
|
|
96
107
|
}));
|
|
97
108
|
|
|
98
109
|
const searchBackgroundStyle = useAnimatedStyle(() => {
|
|
99
110
|
const t = Math.min(Math.max(sharedValue.value / 100, 0), 1);
|
|
100
|
-
return {
|
|
101
|
-
|
|
102
|
-
|
|
111
|
+
return {
|
|
112
|
+
backgroundColor:
|
|
113
|
+
t === 0
|
|
114
|
+
? theme.colors.background.surface
|
|
115
|
+
: theme.colors.background.default,
|
|
116
|
+
};
|
|
103
117
|
});
|
|
104
118
|
|
|
105
119
|
const extendedHeightStyle = useAnimatedStyle(() => ({
|
|
@@ -124,9 +138,7 @@ const HeaderExtendHeader: React.FC<{
|
|
|
124
138
|
<Animated.View
|
|
125
139
|
style={[
|
|
126
140
|
styles.headerBox,
|
|
127
|
-
headerType === 'extended'
|
|
128
|
-
? heightStyle
|
|
129
|
-
: { height: heightHeader },
|
|
141
|
+
headerType === 'extended' ? heightStyle : { height: heightHeader },
|
|
130
142
|
]}
|
|
131
143
|
>
|
|
132
144
|
{!!gradientColor && (
|
|
@@ -162,10 +174,7 @@ const HeaderExtendHeader: React.FC<{
|
|
|
162
174
|
style={[{ marginVertical: Spacing.S }, searchTranslateStyle]}
|
|
163
175
|
>
|
|
164
176
|
<Animated.View
|
|
165
|
-
style={[
|
|
166
|
-
{ borderRadius: Radius.XL },
|
|
167
|
-
searchBackgroundStyle,
|
|
168
|
-
]}
|
|
177
|
+
style={[{ borderRadius: Radius.XL }, searchBackgroundStyle]}
|
|
169
178
|
>
|
|
170
179
|
<InputSearch
|
|
171
180
|
{...inputSearchProps}
|
|
@@ -191,7 +200,11 @@ const HeaderExtendHeader: React.FC<{
|
|
|
191
200
|
/>
|
|
192
201
|
{!!gradientColor && (
|
|
193
202
|
<Animated.View
|
|
194
|
-
style={[
|
|
203
|
+
style={[
|
|
204
|
+
styles.extendedHeader,
|
|
205
|
+
gradientOpacityStyle,
|
|
206
|
+
extendedHeightStyle,
|
|
207
|
+
]}
|
|
195
208
|
>
|
|
196
209
|
<LinearGradient
|
|
197
210
|
colors={[gradientColor, gradientColor + '00']}
|
|
@@ -4,6 +4,8 @@ import React, { useCallback, useContext, useEffect } from 'react';
|
|
|
4
4
|
import { ApplicationContext, MiniAppContext } from '../../Context';
|
|
5
5
|
import { PopupNotify } from '../../Popup';
|
|
6
6
|
import { NavigationButton } from './NavigationButton';
|
|
7
|
+
import { SideBarButton } from './SideBarButton';
|
|
8
|
+
import { useSideBarItemStyle } from '../../Layout/utils';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* default header left used for nav
|
|
@@ -13,9 +15,11 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
13
15
|
preventBack,
|
|
14
16
|
onPressLeftHeader,
|
|
15
17
|
onBackHandler,
|
|
18
|
+
floating = false,
|
|
16
19
|
}) => {
|
|
17
20
|
const context = useContext<any>(MiniAppContext);
|
|
18
21
|
const { navigator } = useContext(ApplicationContext);
|
|
22
|
+
const sideBarStyle = useSideBarItemStyle('left', 0);
|
|
19
23
|
|
|
20
24
|
const goBack = useCallback(() => {
|
|
21
25
|
const canGoBack = navigator?.ref?.current?.canGoBack?.();
|
|
@@ -72,6 +76,19 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
72
76
|
return () => backHandler.remove();
|
|
73
77
|
}, [goBackSafe]);
|
|
74
78
|
|
|
79
|
+
if (floating && sideBarStyle) {
|
|
80
|
+
return (
|
|
81
|
+
<View style={sideBarStyle} pointerEvents={'box-none'}>
|
|
82
|
+
<SideBarButton
|
|
83
|
+
accessibilityLabel="btn_navigation_back"
|
|
84
|
+
icon="arrow-back"
|
|
85
|
+
tintColor={tintColor}
|
|
86
|
+
onPress={goBackSafe}
|
|
87
|
+
/>
|
|
88
|
+
</View>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
75
92
|
return (
|
|
76
93
|
<View style={styles.headerLeft}>
|
|
77
94
|
<NavigationButton
|
|
@@ -13,6 +13,8 @@ import { PopupNotify } from '../../Popup';
|
|
|
13
13
|
import { Tool, ToolGroup } from '../types';
|
|
14
14
|
import { Icon } from '../../Icon';
|
|
15
15
|
import { Text } from '../../Text';
|
|
16
|
+
import { useSideBarItemStyle } from '../../Layout/utils';
|
|
17
|
+
import { SideBarButton, SideBarGroup, SideBarGroupItem } from './SideBarButton';
|
|
16
18
|
|
|
17
19
|
const DID_SYNC_NEW_HOME = 'did_sync_new_home';
|
|
18
20
|
|
|
@@ -21,8 +23,9 @@ const DID_SYNC_NEW_HOME = 'did_sync_new_home';
|
|
|
21
23
|
*/
|
|
22
24
|
const HeaderRight: React.FC<any> = props => {
|
|
23
25
|
const { translate } = useContext(ApplicationContext);
|
|
24
|
-
const { headerRight = {} } = props;
|
|
26
|
+
const { headerRight = {}, floating = false } = props;
|
|
25
27
|
const { useOnBoarding = false, buttonOnBoarding, onPress } = headerRight;
|
|
28
|
+
const sideBarStyle = useSideBarItemStyle('right', 1);
|
|
26
29
|
|
|
27
30
|
if (typeof props.headerRight === 'function') {
|
|
28
31
|
return props.headerRight(props);
|
|
@@ -38,6 +41,18 @@ const HeaderRight: React.FC<any> = props => {
|
|
|
38
41
|
);
|
|
39
42
|
}
|
|
40
43
|
|
|
44
|
+
if (floating && sideBarStyle) {
|
|
45
|
+
return (
|
|
46
|
+
<View style={sideBarStyle} pointerEvents={'box-none'}>
|
|
47
|
+
<HeaderToolkitAction
|
|
48
|
+
{...props.headerRight}
|
|
49
|
+
tintColor={props.tintColor}
|
|
50
|
+
vertical
|
|
51
|
+
/>
|
|
52
|
+
</View>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
41
56
|
return (
|
|
42
57
|
<View style={styles.headerRightButton}>
|
|
43
58
|
<HeaderToolkitAction {...props.headerRight} tintColor={props.tintColor} />
|
|
@@ -56,6 +71,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
56
71
|
useMore = false,
|
|
57
72
|
tools = [],
|
|
58
73
|
useCloseIcon = false,
|
|
74
|
+
vertical = false,
|
|
59
75
|
}) => {
|
|
60
76
|
const { navigator } = useContext(ApplicationContext);
|
|
61
77
|
const context = useContext<any>(MiniAppContext);
|
|
@@ -260,6 +276,43 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
260
276
|
group?.items?.some?.(tool => tool?.showBadge),
|
|
261
277
|
);
|
|
262
278
|
|
|
279
|
+
const useHelpCenter = context.appId !== 'vn.momo.helpcenter';
|
|
280
|
+
const closeIcon = useCloseIcon
|
|
281
|
+
? '16_navigation_close_circle'
|
|
282
|
+
: '16_basic_home';
|
|
283
|
+
|
|
284
|
+
if (vertical) {
|
|
285
|
+
return (
|
|
286
|
+
<View style={styles.sideBarColumn}>
|
|
287
|
+
{useShortcut && (
|
|
288
|
+
<SideBarButton
|
|
289
|
+
disabled={isLoading}
|
|
290
|
+
icon={iconShortcut}
|
|
291
|
+
onPress={shortcutOnPress}
|
|
292
|
+
tintColor={tintColor}
|
|
293
|
+
showBadge={showBadge}
|
|
294
|
+
/>
|
|
295
|
+
)}
|
|
296
|
+
<SideBarGroup tintColor={tintColor}>
|
|
297
|
+
{useHelpCenter && (
|
|
298
|
+
<SideBarGroupItem
|
|
299
|
+
accessibilityLabel={'btn_navigation_help_center'}
|
|
300
|
+
icon={'help_center'}
|
|
301
|
+
tintColor={tintColor}
|
|
302
|
+
onPress={onPressHelpCenter}
|
|
303
|
+
/>
|
|
304
|
+
)}
|
|
305
|
+
<SideBarGroupItem
|
|
306
|
+
accessibilityLabel={'btn_navigation_close'}
|
|
307
|
+
icon={closeIcon}
|
|
308
|
+
tintColor={tintColor}
|
|
309
|
+
onPress={onClose}
|
|
310
|
+
/>
|
|
311
|
+
</SideBarGroup>
|
|
312
|
+
</View>
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
|
|
263
316
|
return (
|
|
264
317
|
<View style={Styles.row}>
|
|
265
318
|
{useShortcut && (
|
|
@@ -280,7 +333,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
280
333
|
},
|
|
281
334
|
]}
|
|
282
335
|
>
|
|
283
|
-
{
|
|
336
|
+
{useHelpCenter && (
|
|
284
337
|
<>
|
|
285
338
|
<TouchableOpacity
|
|
286
339
|
accessibilityLabel={'btn_navigation_help_center'}
|
|
@@ -299,13 +352,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
299
352
|
style={styles.toolkitButton}
|
|
300
353
|
hitSlop={{ top: 7, bottom: 7, left: 0, right: 7 }}
|
|
301
354
|
>
|
|
302
|
-
<Icon
|
|
303
|
-
color={tintColor}
|
|
304
|
-
source={
|
|
305
|
-
useCloseIcon ? '16_navigation_close_circle' : '16_basic_home'
|
|
306
|
-
}
|
|
307
|
-
size={20}
|
|
308
|
-
/>
|
|
355
|
+
<Icon color={tintColor} source={closeIcon} size={20} />
|
|
309
356
|
</TouchableOpacity>
|
|
310
357
|
</View>
|
|
311
358
|
</View>
|
|
@@ -376,6 +423,9 @@ const styles = StyleSheet.create({
|
|
|
376
423
|
width: 0.5,
|
|
377
424
|
height: 12,
|
|
378
425
|
},
|
|
426
|
+
sideBarColumn: {
|
|
427
|
+
gap: Spacing.M,
|
|
428
|
+
},
|
|
379
429
|
headerLeft: {
|
|
380
430
|
marginLeft: 12,
|
|
381
431
|
},
|
|
@@ -7,13 +7,7 @@ import Animated, {
|
|
|
7
7
|
} from 'react-native-reanimated';
|
|
8
8
|
import { ApplicationContext, MiniAppContext } from '../../Context';
|
|
9
9
|
import { exportFontFamily, Text, useScaleSize } from '../../Text';
|
|
10
|
-
import {
|
|
11
|
-
Colors,
|
|
12
|
-
Radius,
|
|
13
|
-
Spacing,
|
|
14
|
-
Styles,
|
|
15
|
-
useHeaderFontFamily,
|
|
16
|
-
} from '../../Consts';
|
|
10
|
+
import { Colors, Radius, Spacing, Styles } from '../../Consts';
|
|
17
11
|
import {
|
|
18
12
|
TitleJourneyProps,
|
|
19
13
|
TitleLocationProps,
|
|
@@ -22,7 +16,33 @@ import {
|
|
|
22
16
|
import { Image } from '../../Image';
|
|
23
17
|
import { Icon } from '../../Icon';
|
|
24
18
|
import { Skeleton } from '../../Skeleton';
|
|
25
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
AnimatedCompatValue,
|
|
21
|
+
isWhiteListDesignSystem,
|
|
22
|
+
useNormalizedSharedValue,
|
|
23
|
+
} from '../utils';
|
|
24
|
+
import { useScreenLayout } from '../../Layout';
|
|
25
|
+
|
|
26
|
+
const useHeaderFontFamily = (): string => {
|
|
27
|
+
const context = useContext<any>(MiniAppContext);
|
|
28
|
+
return isWhiteListDesignSystem(context) ? 'MoMoTrustDisplay' : 'SFProText';
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* back button and toolkit sharing the navigation bar with the title
|
|
33
|
+
*/
|
|
34
|
+
const HEADER_ACTIONS_WIDTH = 172;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* max title width, the iPhone Duo side bar takes back and toolkit out of the bar
|
|
38
|
+
*/
|
|
39
|
+
const useTitleMaxWidth = () => {
|
|
40
|
+
const { width, contentWidth, sideBar } = useScreenLayout();
|
|
41
|
+
if (sideBar) {
|
|
42
|
+
return contentWidth - Spacing.M * 2;
|
|
43
|
+
}
|
|
44
|
+
return width - HEADER_ACTIONS_WIDTH;
|
|
45
|
+
};
|
|
26
46
|
|
|
27
47
|
type HeaderTitleInterpolate = {
|
|
28
48
|
inputRange: number[];
|
|
@@ -44,6 +64,7 @@ const HeaderTitle: React.FC<
|
|
|
44
64
|
> = props => {
|
|
45
65
|
const context = useContext<any>(MiniAppContext);
|
|
46
66
|
const headerFontFamily = useHeaderFontFamily();
|
|
67
|
+
const maxWidth = useTitleMaxWidth();
|
|
47
68
|
|
|
48
69
|
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
49
70
|
|
|
@@ -74,7 +95,7 @@ const HeaderTitle: React.FC<
|
|
|
74
95
|
style={[
|
|
75
96
|
{
|
|
76
97
|
justifyContent: 'center',
|
|
77
|
-
maxWidth
|
|
98
|
+
maxWidth,
|
|
78
99
|
},
|
|
79
100
|
showBaseLineDebug && styles.debugBaseLine,
|
|
80
101
|
]}
|
|
@@ -138,7 +159,7 @@ const TitleUser: React.FC<TitleUserProps> = ({
|
|
|
138
159
|
}) => {
|
|
139
160
|
const { theme } = useContext(ApplicationContext);
|
|
140
161
|
const headerFontFamily = useHeaderFontFamily();
|
|
141
|
-
const maxWidth =
|
|
162
|
+
const maxWidth = useTitleMaxWidth();
|
|
142
163
|
const getShortName = (name: string) => {
|
|
143
164
|
const words = name.split(' ');
|
|
144
165
|
const lastTwoWords = words.slice(-2);
|
|
@@ -421,7 +442,7 @@ const TitleLocation: React.FC<TitleLocationProps> = ({
|
|
|
421
442
|
isLoading,
|
|
422
443
|
}) => {
|
|
423
444
|
const headerFontFamily = useHeaderFontFamily();
|
|
424
|
-
const maxWidth =
|
|
445
|
+
const maxWidth = useTitleMaxWidth();
|
|
425
446
|
const renderShimmer = () => {
|
|
426
447
|
return (
|
|
427
448
|
<View style={Styles.flex}>
|
|
@@ -457,9 +478,12 @@ const TitleLocation: React.FC<TitleLocationProps> = ({
|
|
|
457
478
|
</Text>
|
|
458
479
|
)}
|
|
459
480
|
<View style={Styles.row}>
|
|
460
|
-
<Text
|
|
481
|
+
<Text
|
|
482
|
+
typography="action_xs_bold"
|
|
461
483
|
fontFamily={headerFontFamily}
|
|
462
|
-
|
|
484
|
+
color={tintColor}
|
|
485
|
+
numberOfLines={1}
|
|
486
|
+
>
|
|
463
487
|
{location}
|
|
464
488
|
</Text>
|
|
465
489
|
<Icon
|
|
@@ -487,10 +511,14 @@ const TitleJourney: React.FC<TitleJourneyProps> = ({
|
|
|
487
511
|
isLoading,
|
|
488
512
|
}) => {
|
|
489
513
|
const headerFontFamily = useHeaderFontFamily();
|
|
490
|
-
const
|
|
491
|
-
const
|
|
492
|
-
|
|
493
|
-
const
|
|
514
|
+
const maxWidth = useTitleMaxWidth();
|
|
515
|
+
const { sideBar } = useScreenLayout();
|
|
516
|
+
// journey split is tuned against the whole bar width
|
|
517
|
+
const barWidth = sideBar
|
|
518
|
+
? maxWidth + HEADER_ACTIONS_WIDTH
|
|
519
|
+
: Dimensions.get('screen').width;
|
|
520
|
+
const startWidth = barWidth * 0.25;
|
|
521
|
+
const endWidth = barWidth * 0.75 - 212;
|
|
494
522
|
const renderShimmer = () => {
|
|
495
523
|
return (
|
|
496
524
|
<View style={Styles.flex}>
|
|
@@ -522,8 +550,7 @@ const TitleJourney: React.FC<TitleJourneyProps> = ({
|
|
|
522
550
|
style={{ maxWidth: startWidth }}
|
|
523
551
|
color={tintColor}
|
|
524
552
|
numberOfLines={1}
|
|
525
|
-
|
|
526
|
-
|
|
553
|
+
fontFamily={headerFontFamily}
|
|
527
554
|
>
|
|
528
555
|
{start}
|
|
529
556
|
</Text>
|
|
@@ -539,8 +566,7 @@ const TitleJourney: React.FC<TitleJourneyProps> = ({
|
|
|
539
566
|
typography="action_xs_bold"
|
|
540
567
|
color={tintColor}
|
|
541
568
|
numberOfLines={1}
|
|
542
|
-
|
|
543
|
-
|
|
569
|
+
fontFamily={headerFontFamily}
|
|
544
570
|
>
|
|
545
571
|
{end}
|
|
546
572
|
</Text>
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import { Colors, Radius, Spacing, Styles } from '../../Consts';
|
|
2
2
|
import { InputRef, InputSearch } from '../../Input';
|
|
3
|
-
import {
|
|
4
|
-
Dimensions,
|
|
5
|
-
StyleSheet,
|
|
6
|
-
TouchableOpacity,
|
|
7
|
-
View,
|
|
8
|
-
} from 'react-native';
|
|
3
|
+
import { StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
9
4
|
import Animated, { useAnimatedStyle } from 'react-native-reanimated';
|
|
10
5
|
import React, { useContext } from 'react';
|
|
11
6
|
import { SearchHeaderProps } from '../types';
|
|
12
7
|
import { ApplicationContext, MiniAppContext } from '../../Context';
|
|
13
8
|
import { Text } from '../../Text';
|
|
14
9
|
import { useNormalizedSharedValue } from '../utils';
|
|
10
|
+
import { useScreenLayout } from '../../Layout';
|
|
15
11
|
|
|
16
12
|
const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
|
|
17
13
|
(
|
|
@@ -27,18 +23,25 @@ const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
|
|
|
27
23
|
const { theme, navigator } = useContext(ApplicationContext);
|
|
28
24
|
const context = useContext<any>(MiniAppContext);
|
|
29
25
|
const BACK_WIDTH = 28;
|
|
30
|
-
const
|
|
26
|
+
const layout = useScreenLayout();
|
|
31
27
|
|
|
32
28
|
const sharedValue = useNormalizedSharedValue(animatedValue);
|
|
33
29
|
const leftPosition = props?.leftPosition ?? BACK_WIDTH + 20;
|
|
34
30
|
const headerRightWidth = props?.headerRightWidth ?? 73;
|
|
35
31
|
|
|
32
|
+
// iPhone Duo side bar holds back: the search shares the content width with the buttons only
|
|
33
|
+
let searchMaxWidth = layout.width - leftPosition - 12 - headerRightWidth;
|
|
34
|
+
if (layout.sideBar) {
|
|
35
|
+
searchMaxWidth = layout.contentWidth - Spacing.M * 2 - headerRightWidth;
|
|
36
|
+
}
|
|
37
|
+
|
|
36
38
|
const backgroundStyle = useAnimatedStyle(() => {
|
|
37
39
|
const t = Math.min(Math.max(sharedValue.value / 100, 0), 1);
|
|
38
40
|
return {
|
|
39
|
-
backgroundColor:
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
backgroundColor:
|
|
42
|
+
t === 0
|
|
43
|
+
? theme.colors.background.surface
|
|
44
|
+
: theme.colors.background.default,
|
|
42
45
|
};
|
|
43
46
|
});
|
|
44
47
|
|
|
@@ -77,13 +80,11 @@ const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
|
|
|
77
80
|
style={[
|
|
78
81
|
Styles.flex,
|
|
79
82
|
renderButtons && {
|
|
80
|
-
maxWidth:
|
|
83
|
+
maxWidth: searchMaxWidth,
|
|
81
84
|
},
|
|
82
85
|
]}
|
|
83
86
|
>
|
|
84
|
-
<Animated.View
|
|
85
|
-
style={[{ borderRadius: Radius.XL }, backgroundStyle]}
|
|
86
|
-
>
|
|
87
|
+
<Animated.View style={[{ borderRadius: Radius.XL }, backgroundStyle]}>
|
|
87
88
|
<InputSearch
|
|
88
89
|
ref={ref}
|
|
89
90
|
{...props}
|