@momo-kits/foundation 0.169.1 → 0.169.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.
Files changed (38) hide show
  1. package/Application/BottomSheet.hooks.ts +17 -37
  2. package/Application/BottomSheet.parts.tsx +81 -165
  3. package/Application/BottomSheet.styles.ts +7 -23
  4. package/Application/BottomSheet.tsx +15 -67
  5. package/Application/BottomTab/ActiveIndicator.tsx +90 -0
  6. package/Application/BottomTab/BottomTabBar.styles.ts +48 -43
  7. package/Application/BottomTab/BottomTabBar.tsx +229 -223
  8. package/Application/BottomTab/BottomTabInset.tsx +14 -0
  9. package/Application/BottomTab/CurvedContainer.tsx +153 -0
  10. package/Application/BottomTab/CustomBottomTabItem.tsx +132 -108
  11. package/Application/BottomTab/DuoBarCompression.tsx +4 -12
  12. package/Application/BottomTab/DuoRailTabBar.tsx +174 -96
  13. package/Application/BottomTab/DuoTabBar.styles.ts +42 -84
  14. package/Application/BottomTab/DuoTabBar.tsx +35 -115
  15. package/Application/BottomTab/TabBarIcon.tsx +160 -72
  16. package/Application/BottomTab/TabScreen.tsx +48 -61
  17. package/Application/BottomTab/index.tsx +85 -125
  18. package/Application/BottomTab/metrics.ts +164 -0
  19. package/Application/BottomTab/tabItems.ts +46 -0
  20. package/Application/BottomTab/usePressLift.ts +32 -0
  21. package/Application/ModalIconButton.tsx +66 -0
  22. package/Application/ModalScreen.tsx +32 -15
  23. package/Application/__tests__/modalLayout.test.ts +128 -0
  24. package/Application/index.ts +10 -0
  25. package/Application/modalLayout.ts +177 -0
  26. package/Application/types.tabs.ts +5 -0
  27. package/Application/utils.ts +0 -36
  28. package/Layout/ReservedRegions.tsx +21 -4
  29. package/Layout/Screen.tsx +11 -2
  30. package/Layout/index.ts +2 -0
  31. package/Popup/PopupNotify.tsx +38 -68
  32. package/Popup/PopupPromotion.tsx +5 -4
  33. package/Popup/utils.ts +1 -26
  34. package/package.json +2 -1
  35. package/Application/BottomTab/DuoTabBar.parts.tsx +0 -202
  36. package/Application/BottomTab/badge.ts +0 -41
  37. package/Application/BottomTab/hooks.ts +0 -358
  38. package/Application/BottomTab/index.styles.ts +0 -30
@@ -16,43 +16,24 @@ import {
16
16
  } from 'react-native';
17
17
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
18
18
  import { useHeaderHeight } from '@react-navigation/elements';
19
- import { Spacing } from '../Consts';
20
- import { DuoMetrics, useScreenLayout } from '../Layout/utils';
21
19
  import { scheduleOnRN } from 'react-native-worklets';
22
20
  import { BottomSheetParams, NavigatorProps } from './types';
23
- import { getDuoTopInset, isIPhoneDuo } from './utils';
24
- import { DUO_REGULAR_MIN_WIDTH, getSideInset } from './BottomSheet.styles';
21
+ import { isIPhoneDuo } from './utils';
22
+ import { useModalLayout } from './modalLayout';
25
23
 
24
+ /**
25
+ * Sheet geometry for the current window: foldable placement and size from
26
+ * `useModalLayout`, plus the insets and offsets the keyboard handling needs.
27
+ */
26
28
  export const useBottomSheetLayout = () => {
27
29
  const windowSize = useWindowDimensions();
28
30
  const isDuo = isIPhoneDuo();
29
- const isDuoCentered =
30
- isDuo &&
31
- Math.min(windowSize.width, windowSize.height) >= DUO_REGULAR_MIN_WIDTH;
32
- const isDuoFloating = isDuo && !isDuoCentered;
33
- const { sideBar } = useScreenLayout();
34
- const sideColumnWidth = (sideBar?.width ?? 0) - Spacing.M;
35
- const sideColumn =
36
- isDuoFloating &&
37
- sideColumnWidth >= DuoMetrics.controlSize + Spacing.M &&
38
- sideBar
39
- ? sideBar
40
- : undefined;
41
- const hasSideColumn = !!sideColumn;
31
+ const { isFoldable, placement, sheet, scrimOpacity } = useModalLayout();
42
32
  // 'screen' is the outer display on iPhone Duo, even when unfolded
43
33
  const screenHeight = Dimensions.get('screen').height;
44
34
  const heightDevice = isDuo ? windowSize.height : screenHeight;
45
35
  const insets = useSafeAreaInsets();
46
36
  const heightHeader = useHeaderHeight();
47
- const topGap = Math.max(
48
- sideColumn
49
- ? insets.top
50
- : getDuoTopInset(insets, windowSize.width, windowSize.height),
51
- Spacing.XL,
52
- );
53
- const sideInsetLeft = isDuoFloating ? getSideInset(insets.left) : 0;
54
- const sideInsetRight = isDuoFloating ? getSideInset(insets.right) : 0;
55
- const indicatorShift = (sideInsetRight - sideInsetLeft) / 2;
56
37
  const isIOS = Platform.OS === 'ios';
57
38
  const bottomInset = isIOS ? Math.min(insets.bottom, 21) : insets.bottom;
58
39
  const keyboardOffset = heightHeader - bottomInset;
@@ -60,17 +41,11 @@ export const useBottomSheetLayout = () => {
60
41
  return {
61
42
  windowSize,
62
43
  isDuo,
63
- isDuoCentered,
64
- isDuoFloating,
65
- sideColumn,
66
- sideColumnWidth,
67
- hasSideColumn,
44
+ isFoldable,
45
+ placement,
46
+ sheet,
47
+ scrimOpacity,
68
48
  heightDevice,
69
- insets,
70
- topGap,
71
- sideInsetLeft,
72
- sideInsetRight,
73
- indicatorShift,
74
49
  bottomInset,
75
50
  keyboardOffset,
76
51
  };
@@ -124,9 +99,14 @@ export const useDuoKeyboardLift = (
124
99
  return keyboardLift;
125
100
  };
126
101
 
102
+ /**
103
+ * Slide of the sheet and fade of the scrim behind it, up to the
104
+ * `scrimOpacity` of the modal spec (lighter on foldables).
105
+ */
127
106
  export const useSheetAnimatedStyles = (
128
107
  translateY: SharedValue<number>,
129
108
  heightDevice: number,
109
+ scrimOpacity: number,
130
110
  ) => {
131
111
  const animatedStyle = useAnimatedStyle(() => {
132
112
  return {
@@ -139,7 +119,7 @@ export const useSheetAnimatedStyles = (
139
119
  opacity: interpolate(
140
120
  translateY.value,
141
121
  [0, heightDevice],
142
- [1, 0],
122
+ [scrimOpacity, 0],
143
123
  Extrapolation.CLAMP,
144
124
  ),
145
125
  };
@@ -1,169 +1,90 @@
1
1
  import React from 'react';
2
- import {
3
- PanResponderInstance,
4
- ScaledSize,
5
- TouchableOpacity,
6
- View,
7
- } from 'react-native';
8
- import type { EdgeInsets } from 'react-native-safe-area-context';
9
- import { Radius, Spacing, Styles } from '../Consts';
2
+ import { PanResponderInstance, View, ViewStyle } from 'react-native';
3
+ import { Spacing, Styles } from '../Consts';
10
4
  import layoutStyles from '../Layout/styles';
11
5
  import { Text } from '../Text';
12
- import { Icon } from '../Icon';
13
- import { InnerEdgeStyles, type SideBarLayout } from '../Layout/utils';
14
- import { SideBarButton } from './Components/SideBarButton';
15
- import {
16
- INDICATOR_HEIGHT,
17
- SIDE_COLUMN_OFFSET,
18
- styles,
19
- } from './BottomSheet.styles';
6
+ import { INDICATOR_HEIGHT, styles } from './BottomSheet.styles';
7
+ import { ModalIconButton } from './ModalIconButton';
8
+ import { type ModalLayout } from './modalLayout';
20
9
  import { BottomSheetParams, Theme } from './types';
21
10
 
22
- type SheetPartsParams = {
11
+ type SheetHeaderParams = {
23
12
  panHandlers: PanResponderInstance['panHandlers'];
24
- indicatorShift: number;
25
13
  useDivider: boolean;
26
14
  theme: Theme;
27
- hasSideColumn: boolean;
28
15
  showBack: boolean;
29
16
  onPressBack: () => void;
30
17
  onPressClose: () => void;
31
18
  iconBack: string;
32
19
  options: BottomSheetParams['options'];
33
20
  leftOptions: BottomSheetParams['leftOptions'];
34
- sideColumn?: SideBarLayout;
35
- windowHeight: number;
36
- sheetTop: number;
37
- sideColumnHeight: number;
38
- sideColumnWidth: number;
39
21
  };
40
22
 
23
+ /**
24
+ * Drag handle and header row: back, title (or a custom header) and close, with
25
+ * the 32 modal icon buttons on every device.
26
+ */
41
27
  export const renderSheetHeader = ({
42
28
  panHandlers,
43
- indicatorShift,
44
29
  useDivider,
45
30
  theme,
46
- hasSideColumn,
47
31
  showBack,
48
32
  onPressBack,
49
33
  onPressClose,
50
34
  iconBack,
51
35
  options,
52
36
  leftOptions,
53
- }: SheetPartsParams) => {
54
- const showButtons = !hasSideColumn;
55
- return (
56
- <View {...panHandlers}>
57
- <View style={{ height: INDICATOR_HEIGHT }}>
58
- <View
59
- style={[
60
- styles.indicator,
61
- indicatorShift !== 0 && {
62
- transform: [{ translateX: indicatorShift }],
63
- },
64
- ]}
65
- />
66
- </View>
67
- <View
68
- style={[
69
- styles.header,
70
- useDivider && styles.headerDivider,
71
- useDivider && {
72
- borderBottomColor: theme.colors.border.default,
73
- },
74
- ]}
75
- >
76
- {showButtons && showBack ? (
77
- <TouchableOpacity style={styles.iconButton} onPress={onPressBack}>
78
- <Icon source={iconBack} />
79
- </TouchableOpacity>
80
- ) : null}
81
-
82
- {options.header ? (
83
- <View style={Styles.flex}>{options.header}</View>
84
- ) : (
85
- <>
86
- {showButtons && !leftOptions ? (
87
- <View style={styles.iconButton} />
88
- ) : null}
89
- <Text
90
- style={[
91
- Styles.flex,
92
- styles.title,
93
- !showButtons && styles.titleInset,
94
- ]}
95
- numberOfLines={1}
96
- typography="header_default_bold"
97
- >
98
- {options.title ?? ''}
99
- </Text>
100
- </>
101
- )}
102
- {showButtons ? (
103
- <TouchableOpacity style={styles.iconButton} onPress={onPressClose}>
104
- <Icon source="navigation_close" />
105
- </TouchableOpacity>
106
- ) : null}
107
- </View>
37
+ }: SheetHeaderParams) => (
38
+ <View {...panHandlers}>
39
+ <View style={{ height: INDICATOR_HEIGHT }}>
40
+ <View style={styles.indicator} />
108
41
  </View>
109
- );
110
- };
111
-
112
- /**
113
- * iPhone Duo folded: back and close move to the side bar column, drawn on
114
- * the part of the sheet under the side safe area. They line up with the
115
- * header row, stay below the status bar cluster on a tall sheet and above a
116
- * camera at the bottom end of the strip.
117
- */
118
- export const renderSheetSideColumn = ({
119
- sideColumn,
120
- windowHeight,
121
- sheetTop,
122
- sideColumnHeight,
123
- sideColumnWidth,
124
- showBack,
125
- iconBack,
126
- onPressBack,
127
- onPressClose,
128
- }: SheetPartsParams) => {
129
- if (!sideColumn) {
130
- return null;
131
- }
132
- const lowestTop =
133
- windowHeight - sideColumn.bottom - sideColumnHeight - sheetTop;
134
- const top = Math.min(
135
- Math.max(sideColumn.top - sheetTop, SIDE_COLUMN_OFFSET),
136
- lowestTop,
137
- );
138
-
139
- return (
140
42
  <View
141
- pointerEvents={'box-none'}
142
43
  style={[
143
- styles.sideColumn,
144
- sideColumn.edge === 'right' ? styles.alignRight : styles.alignLeft,
145
- InnerEdgeStyles[sideColumn.edge],
146
- { top, width: sideColumnWidth },
44
+ styles.header,
45
+ useDivider && styles.headerDivider,
46
+ useDivider && {
47
+ borderBottomColor: theme.colors.border.default,
48
+ },
147
49
  ]}
148
50
  >
149
51
  {showBack ? (
150
- <SideBarButton icon={iconBack} onPress={onPressBack} />
52
+ <ModalIconButton icon={iconBack} onPress={onPressBack} />
151
53
  ) : null}
152
- <SideBarButton icon="navigation_close" onPress={onPressClose} />
54
+
55
+ {options.header ? (
56
+ <View style={Styles.flex}>{options.header}</View>
57
+ ) : (
58
+ <>
59
+ {!leftOptions ? <View style={styles.iconButtonSpace} /> : null}
60
+ <Text
61
+ style={[Styles.flex, styles.title]}
62
+ numberOfLines={1}
63
+ typography="header_default_bold"
64
+ >
65
+ {options.title ?? ''}
66
+ </Text>
67
+ </>
68
+ )}
69
+ <ModalIconButton icon="navigation_close" onPress={onPressClose} />
153
70
  </View>
154
- );
155
- };
71
+ </View>
72
+ );
156
73
 
74
+ /**
75
+ * Footer pinned under the sheet content, `null` when the sheet has none.
76
+ */
157
77
  export const renderSheetFooter = ({
158
78
  footerComponent,
159
79
  theme,
160
- sideInsetStyle,
161
80
  }: {
162
81
  footerComponent: BottomSheetParams['footerComponent'];
163
82
  theme: Theme;
164
- sideInsetStyle: any;
165
- }) =>
166
- footerComponent && (
83
+ }) => {
84
+ if (!footerComponent) {
85
+ return null;
86
+ }
87
+ return (
167
88
  <View
168
89
  style={[
169
90
  layoutStyles.shadow,
@@ -171,61 +92,56 @@ export const renderSheetFooter = ({
171
92
  paddingBottom: Spacing.S,
172
93
  backgroundColor: theme.colors.background.surface,
173
94
  },
174
- sideInsetStyle,
175
95
  ]}
176
96
  >
177
97
  {footerComponent}
178
98
  </View>
179
99
  );
100
+ };
180
101
 
181
102
  type SheetStyleParams = {
182
103
  backgroundColor: string;
183
104
  isDuo: boolean;
184
- isDuoFloating: boolean;
185
- isDuoCentered: boolean;
186
- windowSize: ScaledSize;
187
- topGap: number;
105
+ isFoldable: boolean;
106
+ placement: ModalLayout['placement'];
107
+ sheet: ModalLayout['sheet'];
188
108
  keyboardLift: number;
189
- sideColumn?: SideBarLayout;
190
- sideColumnHeight: number;
191
- insets: EdgeInsets;
192
109
  showBaseLineDebug: boolean;
193
110
  };
194
111
 
112
+ /**
113
+ * Sheet container style. On foldables the sheet is centered in the placement
114
+ * area, clear of the iPhone Duo control column and on the right half when half
115
+ * folded; the keyboard lift comes off its max height.
116
+ */
195
117
  export const getSheetStyle = ({
196
118
  backgroundColor,
197
119
  isDuo,
198
- isDuoFloating,
199
- isDuoCentered,
200
- windowSize,
201
- topGap,
120
+ isFoldable,
121
+ placement,
122
+ sheet,
202
123
  keyboardLift,
203
- sideColumn,
204
- sideColumnHeight,
205
- insets,
206
124
  showBaseLineDebug,
207
- }: SheetStyleParams) => [
208
- styles.sheetContainer,
209
- {
210
- backgroundColor,
211
- borderTopLeftRadius: isDuo ? Radius.XL : Radius.M,
212
- borderTopRightRadius: isDuo ? Radius.XL : Radius.M,
213
- },
214
- isDuo && {
215
- maxHeight: windowSize.height - topGap - keyboardLift,
216
- marginBottom: keyboardLift,
217
- },
218
- isDuoFloating && { marginHorizontal: Spacing.M },
219
- sideColumn && {
220
- minHeight: SIDE_COLUMN_OFFSET + sideColumnHeight + sideColumn.bottom,
221
- },
222
- isDuoCentered && styles.centered,
223
- isDuoCentered && {
224
- // keeps the portrait width in landscape, like system sheets
225
- width: Math.min(
226
- Math.min(windowSize.width, windowSize.height) - Spacing.L * 2,
227
- windowSize.width - Math.max(insets.left, insets.right, Spacing.L) * 2,
228
- ),
229
- },
230
- showBaseLineDebug && styles.debugBaseLine,
231
- ];
125
+ }: SheetStyleParams) => {
126
+ const { width, maxHeight } = sheet;
127
+ let foldableStyle: ViewStyle | undefined;
128
+ if (isFoldable && width !== undefined && maxHeight !== undefined) {
129
+ foldableStyle = {
130
+ width,
131
+ marginLeft: placement.x + (placement.width - width) / 2,
132
+ maxHeight: maxHeight - keyboardLift,
133
+ minHeight: sheet.minHeight,
134
+ };
135
+ }
136
+ return [
137
+ styles.sheetContainer,
138
+ {
139
+ backgroundColor,
140
+ borderTopLeftRadius: sheet.radius,
141
+ borderTopRightRadius: sheet.radius,
142
+ },
143
+ isDuo && { marginBottom: keyboardLift },
144
+ foldableStyle,
145
+ showBaseLineDebug && styles.debugBaseLine,
146
+ ];
147
+ };
@@ -1,17 +1,10 @@
1
1
  import { StyleSheet } from 'react-native';
2
2
  import { Colors, Radius, Spacing } from '../Consts';
3
- import { DuoMetrics } from '../Layout/utils';
4
-
5
- // iPhone Duo inner display: center the sheet instead of spanning the width
6
- export const DUO_REGULAR_MIN_WIDTH = 600;
3
+ import { MODAL_ICON_BUTTON_SIZE } from './ModalIconButton';
7
4
 
8
5
  export const INDICATOR_HEIGHT = 16;
9
6
  export const HEADER_HEIGHT = 56;
10
7
  export const DUO_ORIENTATIONS = ['portrait', 'landscape'];
11
- export const SIDE_COLUMN_OFFSET =
12
- INDICATOR_HEIGHT + (HEADER_HEIGHT - DuoMetrics.controlSize) / 2;
13
-
14
- export const getSideInset = (inset: number) => Math.max(inset - Spacing.M, 0);
15
8
 
16
9
  export const styles = StyleSheet.create({
17
10
  container: {
@@ -20,7 +13,7 @@ export const styles = StyleSheet.create({
20
13
  },
21
14
  overlay: {
22
15
  flex: 1,
23
- backgroundColor: 'rgba(0, 0, 0, 0.6)',
16
+ backgroundColor: Colors.black_20,
24
17
  },
25
18
  indicator: {
26
19
  width: 40,
@@ -35,25 +28,16 @@ export const styles = StyleSheet.create({
35
28
  height: HEADER_HEIGHT,
36
29
  flexDirection: 'row',
37
30
  alignItems: 'center',
31
+ paddingHorizontal: Spacing.M,
32
+ gap: Spacing.S,
38
33
  },
39
34
  title: { textAlign: 'center' },
40
- titleInset: { paddingHorizontal: Spacing.M },
41
- iconButton: {
42
- width: 24,
43
- height: 24,
44
- alignItems: 'center',
45
- justifyContent: 'center',
46
- marginHorizontal: Spacing.M,
35
+ iconButtonSpace: {
36
+ width: MODAL_ICON_BUTTON_SIZE,
37
+ height: MODAL_ICON_BUTTON_SIZE,
47
38
  },
48
39
  shrink: { flexShrink: 1 },
49
- sideColumn: {
50
- position: 'absolute',
51
- gap: Spacing.M,
52
- },
53
- alignRight: { right: 0 },
54
- alignLeft: { left: 0 },
55
40
  debugBaseLine: { borderWidth: 1, borderColor: Colors.green_06 },
56
41
  headerDivider: { borderBottomWidth: 1 },
57
42
  sheetContainer: { overflow: 'hidden' },
58
- centered: { alignSelf: 'center' },
59
43
  });
@@ -1,23 +1,15 @@
1
- import React, {
2
- useCallback,
3
- useContext,
4
- useEffect,
5
- useRef,
6
- useState,
7
- } from 'react';
1
+ import React, { useCallback, useContext, useEffect, useRef } from 'react';
8
2
  import {
9
3
  KeyboardAvoidingView,
10
4
  Modal,
11
5
  PanResponder,
12
6
  Platform,
13
7
  Pressable,
14
- StatusBar,
15
8
  StyleSheet,
16
9
  View,
17
10
  } from 'react-native';
18
11
  import { ApplicationContext, MiniAppContext } from '../Context';
19
12
  import { BottomSheetParams } from './types';
20
- import { Spacing } from '../Consts';
21
13
  import Animated, {
22
14
  Easing,
23
15
  useSharedValue,
@@ -25,7 +17,6 @@ import Animated, {
25
17
  withTiming,
26
18
  } from 'react-native-reanimated';
27
19
  import { scheduleOnRN } from 'react-native-worklets';
28
- import { DuoMetrics } from '../Layout/utils';
29
20
  import { DUO_ORIENTATIONS, styles } from './BottomSheet.styles';
30
21
  import {
31
22
  useBottomSheetLayout,
@@ -37,7 +28,6 @@ import {
37
28
  getSheetStyle,
38
29
  renderSheetFooter,
39
30
  renderSheetHeader,
40
- renderSheetSideColumn,
41
31
  } from './BottomSheet.parts';
42
32
 
43
33
  const BottomSheet: React.FC<BottomSheetParams> = props => {
@@ -46,17 +36,11 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
46
36
  const {
47
37
  windowSize,
48
38
  isDuo,
49
- isDuoCentered,
50
- isDuoFloating,
51
- sideColumn,
52
- sideColumnWidth,
53
- hasSideColumn,
39
+ isFoldable,
40
+ placement,
41
+ sheet,
42
+ scrimOpacity,
54
43
  heightDevice,
55
- insets,
56
- topGap,
57
- sideInsetLeft,
58
- sideInsetRight,
59
- indicatorShift,
60
44
  bottomInset,
61
45
  keyboardOffset,
62
46
  } = useBottomSheetLayout();
@@ -82,7 +66,6 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
82
66
  const translateY = useSharedValue(heightDevice);
83
67
  const onDismissRef = useRef(props.route.params?.onDismiss);
84
68
  onDismissRef.current = props.route.params?.onDismiss;
85
- const [sheetTop, setSheetTop] = useState(windowSize.height);
86
69
  const keyboardLift = useDuoKeyboardLift(
87
70
  isDuo,
88
71
  useKeyboardAvoidingView,
@@ -170,52 +153,25 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
170
153
 
171
154
  const showBack = !!leftOptions?.onPressIconLeft;
172
155
  const iconBack = leftOptions?.iconLeft ?? 'ic_back';
173
- const sideColumnCount = showBack ? 2 : 1;
174
- const sideColumnHeight =
175
- sideColumnCount * DuoMetrics.controlSize +
176
- (sideColumnCount - 1) * Spacing.M;
177
- const coversStatusBar = !!sideColumn && sheetTop < sideColumn.top;
178
156
 
179
- useEffect(() => {
180
- if (!coversStatusBar) {
181
- return;
182
- }
183
- const entry = StatusBar.pushStackEntry({
184
- barStyle: theme.dark ? 'light-content' : 'dark-content',
185
- animated: true,
186
- });
187
- return () => StatusBar.popStackEntry(entry);
188
- }, [coversStatusBar, theme.dark]);
189
-
190
- const partsParams = {
157
+ const headerParams = {
191
158
  panHandlers: panResponder.panHandlers,
192
- indicatorShift,
193
159
  useDivider,
194
160
  theme,
195
- hasSideColumn,
196
161
  showBack,
197
162
  onPressBack,
198
163
  onPressClose,
199
164
  iconBack,
200
165
  options,
201
166
  leftOptions,
202
- sideColumn,
203
- windowHeight: windowSize.height,
204
- sheetTop,
205
- sideColumnHeight,
206
- sideColumnWidth,
207
167
  };
208
168
 
209
169
  const { animatedStyle, animatedOverlayStyle } = useSheetAnimatedStyles(
210
170
  translateY,
211
171
  heightDevice,
172
+ scrimOpacity,
212
173
  );
213
174
 
214
- const sideInsetStyle = isDuoFloating && {
215
- paddingLeft: sideInsetLeft,
216
- paddingRight: sideInsetRight,
217
- };
218
-
219
175
  const screen = (
220
176
  <Screen
221
177
  {...props}
@@ -256,39 +212,32 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
256
212
  </Pressable>
257
213
 
258
214
  <Animated.View
259
- onLayout={
260
- isDuoFloating ? e => setSheetTop(e.nativeEvent.layout.y) : undefined
261
- }
262
215
  style={[
263
216
  animatedStyle,
264
217
  getSheetStyle({
265
218
  backgroundColor,
266
219
  isDuo,
267
- isDuoFloating,
268
- isDuoCentered,
269
- windowSize,
270
- topGap,
220
+ isFoldable,
221
+ placement,
222
+ sheet,
271
223
  keyboardLift,
272
- sideColumn,
273
- sideColumnHeight,
274
- insets,
275
224
  showBaseLineDebug,
276
225
  }),
277
226
  ]}
278
227
  >
279
- {isDuo ? (
228
+ {isFoldable ? (
280
229
  // content shrinks so a tall sheet keeps its header and footer
281
- <View style={[styles.shrink, sideInsetStyle]}>
282
- {renderSheetHeader(partsParams)}
230
+ <View style={styles.shrink}>
231
+ {renderSheetHeader(headerParams)}
283
232
  <View style={styles.shrink}>{screen}</View>
284
233
  </View>
285
234
  ) : (
286
235
  <>
287
- {renderSheetHeader(partsParams)}
236
+ {renderSheetHeader(headerParams)}
288
237
  {screen}
289
238
  </>
290
239
  )}
291
- {renderSheetFooter({ footerComponent, theme, sideInsetStyle })}
240
+ {renderSheetFooter({ footerComponent, theme })}
292
241
  {useBottomInset && (
293
242
  <View
294
243
  style={{
@@ -297,7 +246,6 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
297
246
  }}
298
247
  />
299
248
  )}
300
- {renderSheetSideColumn(partsParams)}
301
249
  </Animated.View>
302
250
  </KeyboardAvoidingView>
303
251
  </Container>