@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.
@@ -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
- () => runOnJS(callback)(),
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
- runOnJS(() => {
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 = widthDevice / (state.routes.length + (useFloating ? 1 : 0));
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
- paddingHorizontal: Math.max(insets.left, insets.right),
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 insets = useSafeAreaInsets();
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 { 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,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
- AnimatedCompatValue,
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: number;
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 = 73,
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 leftPosition = inputSearchProps?.leftPosition || BACK_WIDTH + 20;
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(sharedValue.value, [0, 52], [1, 0], Extrapolation.CLAMP),
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
- [SCREEN_PADDING, leftPosition],
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 { backgroundColor: t === 0
101
- ? theme.colors.background.surface
102
- : theme.colors.background.default };
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={[styles.extendedHeader, gradientOpacityStyle, extendedHeightStyle]}
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
- {context.appId !== 'vn.momo.helpcenter' && (
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 { 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
+ * 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: Dimensions.get('window').width - 172,
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 = Dimensions.get('window').width - 172;
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 = Dimensions.get('window').width - 172;
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 typography="action_xs_bold"
481
+ <Text
482
+ typography="action_xs_bold"
461
483
  fontFamily={headerFontFamily}
462
- color={tintColor} numberOfLines={1}>
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 { width } = Dimensions.get('screen');
491
- const maxWidth = Dimensions.get('window').width - 172;
492
- const startWidth = width * 0.25;
493
- const endWidth = width * 0.75 - 212;
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
- fontFamily={headerFontFamily}
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
- fontFamily={headerFontFamily}
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 { width: screenWidth } = Dimensions.get('window');
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: t === 0
40
- ? theme.colors.background.surface
41
- : theme.colors.background.default,
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: screenWidth - leftPosition - 12 - headerRightWidth,
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}