@momo-kits/foundation 0.167.1-beta.5 → 0.167.1-duo-test.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.
Files changed (47) hide show
  1. package/Application/BottomSheet.tsx +115 -14
  2. package/Application/BottomTab/BottomTabBar.tsx +6 -3
  3. package/Application/BottomTab/DuoBarCompression.tsx +135 -0
  4. package/Application/BottomTab/DuoTabBar.tsx +462 -0
  5. package/Application/BottomTab/index.tsx +150 -134
  6. package/Application/Components/DuoGlassBackground.tsx +179 -0
  7. package/Application/Components/DuoQuickReturnHeader.tsx +42 -0
  8. package/Application/Components/HeaderExtendHeader.tsx +75 -28
  9. package/Application/Components/HeaderLeft.tsx +38 -0
  10. package/Application/Components/HeaderRight.tsx +142 -9
  11. package/Application/Components/HeaderTitle.tsx +67 -17
  12. package/Application/Components/OptionalGlassView.ts +11 -0
  13. package/Application/Components/OptionalScrollObserver.ts +12 -0
  14. package/Application/Components/SearchHeader.tsx +22 -15
  15. package/Application/Components/SideBarButton.tsx +139 -0
  16. package/Application/ModalScreen.tsx +16 -2
  17. package/Application/NavigationContainer.tsx +36 -45
  18. package/Application/Navigator.ts +1 -3
  19. package/Application/StackScreen.tsx +63 -9
  20. package/Application/WidgetContainer.tsx +9 -7
  21. package/Application/device.ts +29 -0
  22. package/Application/types.ts +27 -1
  23. package/Application/utils.tsx +255 -7
  24. package/Consts/index.ts +0 -1
  25. package/Consts/theme.ts +5 -6
  26. package/Input/Input.tsx +3 -4
  27. package/Input/InputMoney.tsx +31 -51
  28. package/Input/InputPhoneNumber.tsx +3 -4
  29. package/Input/InputSearch.tsx +3 -4
  30. package/Input/InputTextArea.tsx +3 -4
  31. package/Layout/Card.tsx +8 -26
  32. package/Layout/FloatingButton.tsx +3 -3
  33. package/Layout/Item.tsx +1 -10
  34. package/Layout/ReservedRegions.tsx +47 -0
  35. package/Layout/Screen.tsx +199 -52
  36. package/Layout/Section.tsx +5 -18
  37. package/Layout/index.ts +4 -4
  38. package/Layout/styles.ts +5 -0
  39. package/Layout/utils.ts +465 -5
  40. package/Popup/PopupNotify.tsx +33 -22
  41. package/Popup/PopupPromotion.tsx +20 -8
  42. package/Popup/utils.ts +32 -0
  43. package/Text/index.tsx +2 -11
  44. package/Text/utils.ts +1 -2
  45. package/package.json +3 -2
  46. package/Consts/designSystemFont.ts +0 -38
  47. package/Layout/GridSystem.tsx +0 -137
@@ -1,6 +1,6 @@
1
1
  import React, { Ref, useContext } from 'react';
2
2
  import LinearGradient from 'react-native-linear-gradient';
3
- import { Dimensions, Platform, StyleSheet, View } from 'react-native';
3
+ import { Platform, StyleSheet, View } from 'react-native';
4
4
  import Animated, {
5
5
  Extrapolation,
6
6
  interpolate,
@@ -14,21 +14,19 @@ 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
- AnimatedCompatValue,
19
- useNormalizedSharedValue,
20
- } from '../utils';
17
+ import { AnimatedCompatValue, useNormalizedSharedValue } from '../utils';
18
+ import { useScreenLayout } from '../../Layout';
19
+ import { DuoMetrics, HeaderMetrics } from '../../Layout/utils';
21
20
 
22
21
  const SCREEN_PADDING = 12;
23
22
  const BACK_WIDTH = 28;
24
-
25
- const { width: screenWidth } = Dimensions.get('window');
23
+ const TOOLKIT_WIDTH = 73;
26
24
 
27
25
  const HeaderExtendHeader: React.FC<{
28
26
  headerType?: HeaderType;
29
27
  animatedValue: AnimatedCompatValue;
30
28
  heightHeader: number;
31
- headerRightWidth: number;
29
+ headerRightWidth?: number;
32
30
  inputSearchProps?: SearchHeaderProps;
33
31
  inputSearchRef?: Ref<InputRef>;
34
32
  navigation?: Navigation;
@@ -39,7 +37,7 @@ const HeaderExtendHeader: React.FC<{
39
37
  headerType = 'default',
40
38
  animatedValue,
41
39
  heightHeader,
42
- headerRightWidth = 73,
40
+ headerRightWidth: customHeaderRightWidth,
43
41
  inputSearchProps,
44
42
  inputSearchRef,
45
43
  useShadowHeader: useShadowHeaderProp = true,
@@ -51,7 +49,35 @@ const HeaderExtendHeader: React.FC<{
51
49
  const sharedValue = useNormalizedSharedValue(animatedValue);
52
50
  const gradientColor = customGradientColor ?? theme.colors.gradient;
53
51
  const headerBackground = customBackground ?? theme.assets?.headerBackground;
54
- const leftPosition = inputSearchProps?.leftPosition || BACK_WIDTH + 20;
52
+ const layout = useScreenLayout();
53
+
54
+ // the iPhone Duo status bar row keeps side bar sized back and toolkit
55
+ const backWidth = layout.statusBarClearance
56
+ ? DuoMetrics.controlSize
57
+ : BACK_WIDTH;
58
+ const toolkitWidth = layout.statusBarClearance
59
+ ? DuoMetrics.itemPitch * 2 + SCREEN_PADDING
60
+ : TOOLKIT_WIDTH;
61
+ const leftPosition =
62
+ inputSearchProps?.leftPosition ||
63
+ (layout.sideBar ? SCREEN_PADDING : backWidth + 20);
64
+ const headerRightWidth =
65
+ customHeaderRightWidth ?? (layout.sideBar ? 0 : toolkitWidth);
66
+ const contentLeft = layout.insetLeft + SCREEN_PADDING;
67
+ const contentRight = layout.insetLeft + layout.contentWidth;
68
+ // collapsed on the status bar row, the search stays between its clusters
69
+ const collapsedLeft =
70
+ layout.insetLeft + leftPosition + (layout.statusBarClearance?.left ?? 0);
71
+ const collapsedRight = contentRight - (layout.statusBarClearance?.right ?? 0);
72
+ const searchWidth = layout.contentWidth - SCREEN_PADDING * 2;
73
+ const collapsedSearchWidth =
74
+ collapsedRight - collapsedLeft - SCREEN_PADDING - headerRightWidth;
75
+ // a row taller than barHeight (iPhone Duo) centers the collapsed search on the title
76
+ const collapsedRaise =
77
+ (layout.headerHeight -
78
+ layout.headerStatusBarHeight -
79
+ HeaderMetrics.barHeight) /
80
+ 2;
55
81
 
56
82
  let useShadowHeader = useShadowHeaderProp;
57
83
  if (inputSearchProps && Platform.OS === 'android') {
@@ -70,7 +96,12 @@ const HeaderExtendHeader: React.FC<{
70
96
  }));
71
97
 
72
98
  const gradientOpacityStyle = useAnimatedStyle(() => ({
73
- opacity: interpolate(sharedValue.value, [0, 52], [1, 0], Extrapolation.CLAMP),
99
+ opacity: interpolate(
100
+ sharedValue.value,
101
+ [0, 52],
102
+ [1, 0],
103
+ Extrapolation.CLAMP,
104
+ ),
74
105
  }));
75
106
 
76
107
  const searchTranslateStyle = useAnimatedStyle(() => ({
@@ -79,7 +110,15 @@ const HeaderExtendHeader: React.FC<{
79
110
  translateX: interpolate(
80
111
  sharedValue.value,
81
112
  [0, 100],
82
- [SCREEN_PADDING, leftPosition],
113
+ [contentLeft, collapsedLeft],
114
+ Extrapolation.CLAMP,
115
+ ),
116
+ },
117
+ {
118
+ translateY: interpolate(
119
+ sharedValue.value,
120
+ [0, 100],
121
+ [0, -collapsedRaise],
83
122
  Extrapolation.CLAMP,
84
123
  ),
85
124
  },
@@ -87,19 +126,19 @@ const HeaderExtendHeader: React.FC<{
87
126
  width: interpolate(
88
127
  sharedValue.value,
89
128
  [0, 100],
90
- [
91
- screenWidth - SCREEN_PADDING * 2,
92
- screenWidth - leftPosition - 12 - headerRightWidth,
93
- ],
129
+ [searchWidth, collapsedSearchWidth],
94
130
  Extrapolation.CLAMP,
95
131
  ),
96
132
  }));
97
133
 
98
134
  const searchBackgroundStyle = useAnimatedStyle(() => {
99
135
  const t = Math.min(Math.max(sharedValue.value / 100, 0), 1);
100
- return { backgroundColor: t === 0
101
- ? theme.colors.background.surface
102
- : theme.colors.background.default };
136
+ return {
137
+ backgroundColor:
138
+ t === 0
139
+ ? theme.colors.background.surface
140
+ : theme.colors.background.default,
141
+ };
103
142
  });
104
143
 
105
144
  const extendedHeightStyle = useAnimatedStyle(() => ({
@@ -124,14 +163,17 @@ const HeaderExtendHeader: React.FC<{
124
163
  <Animated.View
125
164
  style={[
126
165
  styles.headerBox,
127
- headerType === 'extended'
128
- ? heightStyle
129
- : { height: heightHeader },
166
+ headerType === 'extended' ? heightStyle : { height: heightHeader },
130
167
  ]}
131
168
  >
132
169
  {!!gradientColor && (
133
170
  <Animated.View
134
- style={[styles.extendedHeader, gradientOpacityStyle]}
171
+ style={[
172
+ styles.extendedHeader,
173
+ // fade out within the header box, as DuoScrollGradient does
174
+ !!layout.sideBar && styles.fillHeaderBox,
175
+ gradientOpacityStyle,
176
+ ]}
135
177
  >
136
178
  <LinearGradient
137
179
  colors={[gradientColor, gradientColor + '00']}
@@ -162,10 +204,7 @@ const HeaderExtendHeader: React.FC<{
162
204
  style={[{ marginVertical: Spacing.S }, searchTranslateStyle]}
163
205
  >
164
206
  <Animated.View
165
- style={[
166
- { borderRadius: Radius.XL },
167
- searchBackgroundStyle,
168
- ]}
207
+ style={[{ borderRadius: Radius.XL }, searchBackgroundStyle]}
169
208
  >
170
209
  <InputSearch
171
210
  {...inputSearchProps}
@@ -191,7 +230,11 @@ const HeaderExtendHeader: React.FC<{
191
230
  />
192
231
  {!!gradientColor && (
193
232
  <Animated.View
194
- style={[styles.extendedHeader, gradientOpacityStyle, extendedHeightStyle]}
233
+ style={[
234
+ styles.extendedHeader,
235
+ gradientOpacityStyle,
236
+ extendedHeightStyle,
237
+ ]}
195
238
  >
196
239
  <LinearGradient
197
240
  colors={[gradientColor, gradientColor + '00']}
@@ -227,6 +270,10 @@ const styles = StyleSheet.create({
227
270
  position: 'absolute',
228
271
  width: '100%',
229
272
  },
273
+ fillHeaderBox: {
274
+ aspectRatio: undefined,
275
+ height: '100%',
276
+ },
230
277
  headerBox: {
231
278
  width: '100%',
232
279
  position: 'absolute',
@@ -4,6 +4,10 @@ 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 Animated from 'react-native-reanimated';
9
+ import { useScreenLayout, useSideBarItemStyle } from '../../Layout/utils';
10
+ import { useSideBarCounterStyle } from './DuoQuickReturnHeader';
7
11
 
8
12
  /**
9
13
  * default header left used for nav
@@ -13,9 +17,13 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
13
17
  preventBack,
14
18
  onPressLeftHeader,
15
19
  onBackHandler,
20
+ floating = false,
16
21
  }) => {
17
22
  const context = useContext<any>(MiniAppContext);
18
23
  const { navigator } = useContext(ApplicationContext);
24
+ const sideBarStyle = useSideBarItemStyle('left', 0);
25
+ const counterStyle = useSideBarCounterStyle();
26
+ const { statusBarClearance } = useScreenLayout();
19
27
 
20
28
  const goBack = useCallback(() => {
21
29
  const canGoBack = navigator?.ref?.current?.canGoBack?.();
@@ -72,6 +80,36 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
72
80
  return () => backHandler.remove();
73
81
  }, [goBackSafe]);
74
82
 
83
+ if (floating && sideBarStyle) {
84
+ return (
85
+ <Animated.View
86
+ style={[sideBarStyle, counterStyle]}
87
+ pointerEvents={'box-none'}
88
+ >
89
+ <SideBarButton
90
+ accessibilityLabel="btn_navigation_back"
91
+ icon="arrow-back"
92
+ tintColor={tintColor}
93
+ onPress={goBackSafe}
94
+ />
95
+ </Animated.View>
96
+ );
97
+ }
98
+
99
+ // on the status bar row the controls keep the side bar size
100
+ if (statusBarClearance) {
101
+ return (
102
+ <View style={styles.headerLeft}>
103
+ <SideBarButton
104
+ accessibilityLabel="btn_navigation_back"
105
+ icon="arrow-back"
106
+ tintColor={tintColor}
107
+ onPress={goBackSafe}
108
+ />
109
+ </View>
110
+ );
111
+ }
112
+
75
113
  return (
76
114
  <View style={styles.headerLeft}>
77
115
  <NavigationButton
@@ -13,6 +13,12 @@ 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 Animated from 'react-native-reanimated';
17
+ import { useScreenLayout, useSideBarItemStyle } from '../../Layout/utils';
18
+ import { useSideBarCounterStyle } from './DuoQuickReturnHeader';
19
+ import { SideBarButton, SideBarGroup, SideBarGroupItem } from './SideBarButton';
20
+ import { useDuoBarCompression } from '../BottomTab/DuoBarCompression';
21
+ import { DuoMetrics } from '../../Layout/utils';
16
22
 
17
23
  const DID_SYNC_NEW_HOME = 'did_sync_new_home';
18
24
 
@@ -21,8 +27,10 @@ const DID_SYNC_NEW_HOME = 'did_sync_new_home';
21
27
  */
22
28
  const HeaderRight: React.FC<any> = props => {
23
29
  const { translate } = useContext(ApplicationContext);
24
- const { headerRight = {} } = props;
30
+ const { headerRight = {}, floating = false } = props;
25
31
  const { useOnBoarding = false, buttonOnBoarding, onPress } = headerRight;
32
+ const sideBarStyle = useSideBarItemStyle('right', 1);
33
+ const counterStyle = useSideBarCounterStyle();
26
34
 
27
35
  if (typeof props.headerRight === 'function') {
28
36
  return props.headerRight(props);
@@ -38,6 +46,21 @@ const HeaderRight: React.FC<any> = props => {
38
46
  );
39
47
  }
40
48
 
49
+ if (floating && sideBarStyle) {
50
+ return (
51
+ <Animated.View
52
+ style={[sideBarStyle, counterStyle]}
53
+ pointerEvents={'box-none'}
54
+ >
55
+ <HeaderToolkitAction
56
+ {...props.headerRight}
57
+ tintColor={props.tintColor}
58
+ vertical
59
+ />
60
+ </Animated.View>
61
+ );
62
+ }
63
+
41
64
  return (
42
65
  <View style={styles.headerRightButton}>
43
66
  <HeaderToolkitAction {...props.headerRight} tintColor={props.tintColor} />
@@ -56,9 +79,13 @@ const HeaderToolkitAction: React.FC<any> = ({
56
79
  useMore = false,
57
80
  tools = [],
58
81
  useCloseIcon = false,
82
+ vertical = false,
59
83
  }) => {
60
84
  const { navigator } = useContext(ApplicationContext);
61
85
  const context = useContext<any>(MiniAppContext);
86
+ const { toolbarCompressed, toolbarHidden, expandToolbar, setToolbarHeight } =
87
+ useDuoBarCompression();
88
+ const { statusBarClearance } = useScreenLayout();
62
89
 
63
90
  const [isFavorite, setIsFavorite] = useState<boolean>(false);
64
91
  const [isLoading, setIsLoading] = useState(false);
@@ -260,6 +287,111 @@ const HeaderToolkitAction: React.FC<any> = ({
260
287
  group?.items?.some?.(tool => tool?.showBadge),
261
288
  );
262
289
 
290
+ const useHelpCenter = context.appId !== 'vn.momo.helpcenter';
291
+ const closeIcon = useCloseIcon
292
+ ? '16_navigation_close_circle'
293
+ : '16_basic_home';
294
+
295
+ const groupCount = useHelpCenter ? 2 : 1;
296
+ // Back slot, the optional shortcut, then the help/home capsule
297
+ const fullToolbarHeight =
298
+ DuoMetrics.controlSize +
299
+ Spacing.M +
300
+ (useShortcut ? DuoMetrics.controlSize + Spacing.M : 0) +
301
+ (groupCount > 1
302
+ ? groupCount * DuoMetrics.itemPitch
303
+ : DuoMetrics.controlSize);
304
+
305
+ useEffect(() => {
306
+ if (vertical) {
307
+ setToolbarHeight?.(fullToolbarHeight);
308
+ }
309
+ }, [vertical, fullToolbarHeight, setToolbarHeight]);
310
+
311
+ // an open tab rail takes this slot for a moment
312
+ if (vertical && toolbarHidden) {
313
+ return null;
314
+ }
315
+
316
+ // HIG "Toolbar compressed": tools fold into one button; tapping it expands the
317
+ // toolbar and compresses the tab bar instead. Not the useMore icon, to tell them apart
318
+ if (vertical && toolbarCompressed) {
319
+ return (
320
+ <SideBarButton
321
+ accessibilityLabel={'btn_navigation_toolbar'}
322
+ icon={'navigation_menu'}
323
+ tintColor={tintColor}
324
+ showBadge={showBadge}
325
+ onPress={expandToolbar}
326
+ />
327
+ );
328
+ }
329
+
330
+ if (vertical) {
331
+ return (
332
+ <View style={styles.sideBarColumn}>
333
+ {useShortcut && (
334
+ <SideBarButton
335
+ disabled={isLoading}
336
+ icon={iconShortcut}
337
+ onPress={shortcutOnPress}
338
+ tintColor={tintColor}
339
+ showBadge={showBadge}
340
+ />
341
+ )}
342
+ <SideBarGroup tintColor={tintColor}>
343
+ {useHelpCenter && (
344
+ <SideBarGroupItem
345
+ accessibilityLabel={'btn_navigation_help_center'}
346
+ icon={'help_center'}
347
+ tintColor={tintColor}
348
+ onPress={onPressHelpCenter}
349
+ />
350
+ )}
351
+ <SideBarGroupItem
352
+ accessibilityLabel={'btn_navigation_close'}
353
+ icon={closeIcon}
354
+ tintColor={tintColor}
355
+ onPress={onClose}
356
+ />
357
+ </SideBarGroup>
358
+ </View>
359
+ );
360
+ }
361
+
362
+ // on the status bar row the controls keep the side bar size
363
+ if (statusBarClearance) {
364
+ return (
365
+ <View style={styles.sideBarRow}>
366
+ {useShortcut && (
367
+ <SideBarButton
368
+ disabled={isLoading}
369
+ icon={iconShortcut}
370
+ onPress={shortcutOnPress}
371
+ tintColor={tintColor}
372
+ showBadge={showBadge}
373
+ />
374
+ )}
375
+ <SideBarGroup tintColor={tintColor} horizontal>
376
+ {useHelpCenter && (
377
+ <SideBarGroupItem
378
+ accessibilityLabel={'btn_navigation_help_center'}
379
+ icon={'help_center'}
380
+ tintColor={tintColor}
381
+ onPress={onPressHelpCenter}
382
+ />
383
+ )}
384
+ <SideBarGroupItem
385
+ accessibilityLabel={'btn_navigation_close'}
386
+ icon={closeIcon}
387
+ tintColor={tintColor}
388
+ onPress={onClose}
389
+ />
390
+ </SideBarGroup>
391
+ </View>
392
+ );
393
+ }
394
+
263
395
  return (
264
396
  <View style={Styles.row}>
265
397
  {useShortcut && (
@@ -280,7 +412,7 @@ const HeaderToolkitAction: React.FC<any> = ({
280
412
  },
281
413
  ]}
282
414
  >
283
- {context.appId !== 'vn.momo.helpcenter' && (
415
+ {useHelpCenter && (
284
416
  <>
285
417
  <TouchableOpacity
286
418
  accessibilityLabel={'btn_navigation_help_center'}
@@ -299,13 +431,7 @@ const HeaderToolkitAction: React.FC<any> = ({
299
431
  style={styles.toolkitButton}
300
432
  hitSlop={{ top: 7, bottom: 7, left: 0, right: 7 }}
301
433
  >
302
- <Icon
303
- color={tintColor}
304
- source={
305
- useCloseIcon ? '16_navigation_close_circle' : '16_basic_home'
306
- }
307
- size={20}
308
- />
434
+ <Icon color={tintColor} source={closeIcon} size={20} />
309
435
  </TouchableOpacity>
310
436
  </View>
311
437
  </View>
@@ -376,6 +502,13 @@ const styles = StyleSheet.create({
376
502
  width: 0.5,
377
503
  height: 12,
378
504
  },
505
+ sideBarColumn: {
506
+ gap: Spacing.M,
507
+ },
508
+ sideBarRow: {
509
+ flexDirection: 'row',
510
+ gap: Spacing.M,
511
+ },
379
512
  headerLeft: {
380
513
  marginLeft: 12,
381
514
  },
@@ -16,7 +16,47 @@ import {
16
16
  import { Image } from '../../Image';
17
17
  import { Icon } from '../../Icon';
18
18
  import { Skeleton } from '../../Skeleton';
19
- import { AnimatedCompatValue, useNormalizedSharedValue } from '../utils';
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
+ * extra width the 48pt back and toolkit take on the iPhone Duo status bar row
38
+ */
39
+ const STATUS_BAR_ROW_ACTIONS_EXTRA = 55;
40
+
41
+ /**
42
+ * max title width, the iPhone Duo side bar takes back and toolkit out of the bar
43
+ */
44
+ const useTitleMaxWidth = () => {
45
+ const { width, contentWidth, sideBar, statusBarClearance } =
46
+ useScreenLayout();
47
+ const clearance = statusBarClearance
48
+ ? statusBarClearance.left + statusBarClearance.right
49
+ : 0;
50
+ if (sideBar) {
51
+ return contentWidth - Spacing.M * 2 - clearance;
52
+ }
53
+ return (
54
+ width -
55
+ HEADER_ACTIONS_WIDTH -
56
+ (statusBarClearance ? STATUS_BAR_ROW_ACTIONS_EXTRA : 0) -
57
+ clearance
58
+ );
59
+ };
20
60
 
21
61
  type HeaderTitleInterpolate = {
22
62
  inputRange: number[];
@@ -37,6 +77,8 @@ const HeaderTitle: React.FC<
37
77
  HeaderTitleExtraProps & { [key: string]: any }
38
78
  > = props => {
39
79
  const context = useContext<any>(MiniAppContext);
80
+ const headerFontFamily = useHeaderFontFamily();
81
+ const maxWidth = useTitleMaxWidth();
40
82
 
41
83
  const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
42
84
 
@@ -67,7 +109,7 @@ const HeaderTitle: React.FC<
67
109
  style={[
68
110
  {
69
111
  justifyContent: 'center',
70
- maxWidth: Dimensions.get('window').width - 172,
112
+ maxWidth,
71
113
  },
72
114
  showBaseLineDebug && styles.debugBaseLine,
73
115
  ]}
@@ -85,7 +127,7 @@ const HeaderTitle: React.FC<
85
127
  fontFamily: exportFontFamily(
86
128
  'bold',
87
129
  'action_xs_bold',
88
- 'MoMoTrustDisplay',
130
+ headerFontFamily,
89
131
  ),
90
132
  color: props.tintColor,
91
133
  },
@@ -130,7 +172,8 @@ const TitleUser: React.FC<TitleUserProps> = ({
130
172
  isLoading,
131
173
  }) => {
132
174
  const { theme } = useContext(ApplicationContext);
133
- const maxWidth = Dimensions.get('window').width - 172;
175
+ const headerFontFamily = useHeaderFontFamily();
176
+ const maxWidth = useTitleMaxWidth();
134
177
  const getShortName = (name: string) => {
135
178
  const words = name.split(' ');
136
179
  const lastTwoWords = words.slice(-2);
@@ -378,7 +421,7 @@ const TitleUser: React.FC<TitleUserProps> = ({
378
421
  <View style={Styles.row}>
379
422
  <Text
380
423
  typography="action_xs_bold"
381
- fontFamily='MoMoTrustDisplay'
424
+ fontFamily={headerFontFamily}
382
425
  color={tintColor}
383
426
  numberOfLines={1}
384
427
  >
@@ -412,7 +455,8 @@ const TitleLocation: React.FC<TitleLocationProps> = ({
412
455
  onPress,
413
456
  isLoading,
414
457
  }) => {
415
- const maxWidth = Dimensions.get('window').width - 172;
458
+ const headerFontFamily = useHeaderFontFamily();
459
+ const maxWidth = useTitleMaxWidth();
416
460
  const renderShimmer = () => {
417
461
  return (
418
462
  <View style={Styles.flex}>
@@ -448,9 +492,12 @@ const TitleLocation: React.FC<TitleLocationProps> = ({
448
492
  </Text>
449
493
  )}
450
494
  <View style={Styles.row}>
451
- <Text typography="action_xs_bold"
452
- fontFamily='MoMoTrustDisplay'
453
- color={tintColor} numberOfLines={1}>
495
+ <Text
496
+ typography="action_xs_bold"
497
+ fontFamily={headerFontFamily}
498
+ color={tintColor}
499
+ numberOfLines={1}
500
+ >
454
501
  {location}
455
502
  </Text>
456
503
  <Icon
@@ -477,10 +524,15 @@ const TitleJourney: React.FC<TitleJourneyProps> = ({
477
524
  onPress,
478
525
  isLoading,
479
526
  }) => {
480
- const { width } = Dimensions.get('screen');
481
- const maxWidth = Dimensions.get('window').width - 172;
482
- const startWidth = width * 0.25;
483
- const endWidth = width * 0.75 - 212;
527
+ const headerFontFamily = useHeaderFontFamily();
528
+ const maxWidth = useTitleMaxWidth();
529
+ const { sideBar } = useScreenLayout();
530
+ // journey split is tuned against the whole bar width
531
+ const barWidth = sideBar
532
+ ? maxWidth + HEADER_ACTIONS_WIDTH
533
+ : Dimensions.get('screen').width;
534
+ const startWidth = barWidth * 0.25;
535
+ const endWidth = barWidth * 0.75 - 212;
484
536
  const renderShimmer = () => {
485
537
  return (
486
538
  <View style={Styles.flex}>
@@ -512,8 +564,7 @@ const TitleJourney: React.FC<TitleJourneyProps> = ({
512
564
  style={{ maxWidth: startWidth }}
513
565
  color={tintColor}
514
566
  numberOfLines={1}
515
- fontFamily='MoMoTrustDisplay'
516
-
567
+ fontFamily={headerFontFamily}
517
568
  >
518
569
  {start}
519
570
  </Text>
@@ -529,8 +580,7 @@ const TitleJourney: React.FC<TitleJourneyProps> = ({
529
580
  typography="action_xs_bold"
530
581
  color={tintColor}
531
582
  numberOfLines={1}
532
- fontFamily='MoMoTrustDisplay'
533
-
583
+ fontFamily={headerFontFamily}
534
584
  >
535
585
  {end}
536
586
  </Text>
@@ -0,0 +1,11 @@
1
+ import type React from 'react';
2
+
3
+ // native glass is optional so apps without @momo-kits/glass-view still bundle
4
+ let GlassView: React.ComponentType<any> | undefined;
5
+ try {
6
+ GlassView = require('@momo-kits/glass-view').GlassView;
7
+ } catch {
8
+ GlassView = undefined;
9
+ }
10
+
11
+ export { GlassView };
@@ -0,0 +1,12 @@
1
+ import type React from 'react';
2
+
3
+ // native observer is optional so apps without it in @momo-kits/reserved-regions still bundle
4
+ let ScrollObserverView: React.ComponentType<any> | undefined;
5
+ try {
6
+ ScrollObserverView =
7
+ require('@momo-kits/reserved-regions').ScrollObserverView;
8
+ } catch {
9
+ ScrollObserverView = undefined;
10
+ }
11
+
12
+ export { ScrollObserverView };