@momo-kits/foundation 0.167.1-duo.1 → 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/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 +53 -17
- 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 -32
- package/Application/Navigator.ts +1 -3
- package/Application/StackScreen.tsx +2 -5
- package/Application/WidgetContainer.tsx +9 -7
- package/Application/types.ts +5 -1
- package/Application/utils.tsx +10 -3
- package/Consts/index.ts +0 -1
- package/Consts/theme.ts +5 -6
- 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 +2 -11
- package/Text/utils.ts +1 -2
- package/package.json +4 -3
- package/Consts/designSystemFont.ts +0 -38
- 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],
|
|
@@ -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
|
},
|
|
@@ -16,7 +16,33 @@ import {
|
|
|
16
16
|
import { Image } from '../../Image';
|
|
17
17
|
import { Icon } from '../../Icon';
|
|
18
18
|
import { Skeleton } from '../../Skeleton';
|
|
19
|
-
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
|
+
};
|
|
20
46
|
|
|
21
47
|
type HeaderTitleInterpolate = {
|
|
22
48
|
inputRange: number[];
|
|
@@ -37,6 +63,8 @@ const HeaderTitle: React.FC<
|
|
|
37
63
|
HeaderTitleExtraProps & { [key: string]: any }
|
|
38
64
|
> = props => {
|
|
39
65
|
const context = useContext<any>(MiniAppContext);
|
|
66
|
+
const headerFontFamily = useHeaderFontFamily();
|
|
67
|
+
const maxWidth = useTitleMaxWidth();
|
|
40
68
|
|
|
41
69
|
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
42
70
|
|
|
@@ -67,7 +95,7 @@ const HeaderTitle: React.FC<
|
|
|
67
95
|
style={[
|
|
68
96
|
{
|
|
69
97
|
justifyContent: 'center',
|
|
70
|
-
maxWidth
|
|
98
|
+
maxWidth,
|
|
71
99
|
},
|
|
72
100
|
showBaseLineDebug && styles.debugBaseLine,
|
|
73
101
|
]}
|
|
@@ -85,7 +113,7 @@ const HeaderTitle: React.FC<
|
|
|
85
113
|
fontFamily: exportFontFamily(
|
|
86
114
|
'bold',
|
|
87
115
|
'action_xs_bold',
|
|
88
|
-
|
|
116
|
+
headerFontFamily,
|
|
89
117
|
),
|
|
90
118
|
color: props.tintColor,
|
|
91
119
|
},
|
|
@@ -130,7 +158,8 @@ const TitleUser: React.FC<TitleUserProps> = ({
|
|
|
130
158
|
isLoading,
|
|
131
159
|
}) => {
|
|
132
160
|
const { theme } = useContext(ApplicationContext);
|
|
133
|
-
const
|
|
161
|
+
const headerFontFamily = useHeaderFontFamily();
|
|
162
|
+
const maxWidth = useTitleMaxWidth();
|
|
134
163
|
const getShortName = (name: string) => {
|
|
135
164
|
const words = name.split(' ');
|
|
136
165
|
const lastTwoWords = words.slice(-2);
|
|
@@ -378,7 +407,7 @@ const TitleUser: React.FC<TitleUserProps> = ({
|
|
|
378
407
|
<View style={Styles.row}>
|
|
379
408
|
<Text
|
|
380
409
|
typography="action_xs_bold"
|
|
381
|
-
fontFamily=
|
|
410
|
+
fontFamily={headerFontFamily}
|
|
382
411
|
color={tintColor}
|
|
383
412
|
numberOfLines={1}
|
|
384
413
|
>
|
|
@@ -412,7 +441,8 @@ const TitleLocation: React.FC<TitleLocationProps> = ({
|
|
|
412
441
|
onPress,
|
|
413
442
|
isLoading,
|
|
414
443
|
}) => {
|
|
415
|
-
const
|
|
444
|
+
const headerFontFamily = useHeaderFontFamily();
|
|
445
|
+
const maxWidth = useTitleMaxWidth();
|
|
416
446
|
const renderShimmer = () => {
|
|
417
447
|
return (
|
|
418
448
|
<View style={Styles.flex}>
|
|
@@ -448,9 +478,12 @@ const TitleLocation: React.FC<TitleLocationProps> = ({
|
|
|
448
478
|
</Text>
|
|
449
479
|
)}
|
|
450
480
|
<View style={Styles.row}>
|
|
451
|
-
<Text
|
|
452
|
-
|
|
453
|
-
|
|
481
|
+
<Text
|
|
482
|
+
typography="action_xs_bold"
|
|
483
|
+
fontFamily={headerFontFamily}
|
|
484
|
+
color={tintColor}
|
|
485
|
+
numberOfLines={1}
|
|
486
|
+
>
|
|
454
487
|
{location}
|
|
455
488
|
</Text>
|
|
456
489
|
<Icon
|
|
@@ -477,10 +510,15 @@ const TitleJourney: React.FC<TitleJourneyProps> = ({
|
|
|
477
510
|
onPress,
|
|
478
511
|
isLoading,
|
|
479
512
|
}) => {
|
|
480
|
-
const
|
|
481
|
-
const maxWidth =
|
|
482
|
-
const
|
|
483
|
-
|
|
513
|
+
const headerFontFamily = useHeaderFontFamily();
|
|
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;
|
|
484
522
|
const renderShimmer = () => {
|
|
485
523
|
return (
|
|
486
524
|
<View style={Styles.flex}>
|
|
@@ -512,8 +550,7 @@ const TitleJourney: React.FC<TitleJourneyProps> = ({
|
|
|
512
550
|
style={{ maxWidth: startWidth }}
|
|
513
551
|
color={tintColor}
|
|
514
552
|
numberOfLines={1}
|
|
515
|
-
|
|
516
|
-
|
|
553
|
+
fontFamily={headerFontFamily}
|
|
517
554
|
>
|
|
518
555
|
{start}
|
|
519
556
|
</Text>
|
|
@@ -529,8 +566,7 @@ const TitleJourney: React.FC<TitleJourneyProps> = ({
|
|
|
529
566
|
typography="action_xs_bold"
|
|
530
567
|
color={tintColor}
|
|
531
568
|
numberOfLines={1}
|
|
532
|
-
|
|
533
|
-
|
|
569
|
+
fontFamily={headerFontFamily}
|
|
534
570
|
>
|
|
535
571
|
{end}
|
|
536
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}
|