@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.
@@ -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],
@@ -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
  },
@@ -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 { 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
+ };
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: Dimensions.get('window').width - 172,
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
- 'MoMoTrustDisplay',
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 maxWidth = Dimensions.get('window').width - 172;
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='MoMoTrustDisplay'
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 maxWidth = Dimensions.get('window').width - 172;
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 typography="action_xs_bold"
452
- fontFamily='MoMoTrustDisplay'
453
- color={tintColor} numberOfLines={1}>
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 { 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;
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
- fontFamily='MoMoTrustDisplay'
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
- fontFamily='MoMoTrustDisplay'
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 { 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}