@momo-kits/foundation 0.168.1-rn862.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 (109) hide show
  1. package/Application/BottomSheet.hooks.ts +195 -0
  2. package/Application/BottomSheet.parts.tsx +147 -0
  3. package/Application/BottomSheet.styles.ts +43 -0
  4. package/Application/BottomSheet.tsx +76 -279
  5. package/Application/BottomTab/ActiveIndicator.tsx +90 -0
  6. package/Application/BottomTab/BottomTabBar.styles.ts +65 -0
  7. package/Application/BottomTab/BottomTabBar.tsx +229 -276
  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 +227 -0
  13. package/Application/BottomTab/DuoTabBar.styles.ts +81 -0
  14. package/Application/BottomTab/DuoTabBar.tsx +29 -495
  15. package/Application/BottomTab/TabBarIcon.tsx +160 -72
  16. package/Application/BottomTab/TabScreen.tsx +164 -0
  17. package/Application/BottomTab/index.tsx +84 -351
  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/Components/DuoGlassBackground.tsx +7 -9
  22. package/Application/Components/HeaderAnimated.tsx +1 -1
  23. package/Application/Components/HeaderBackground.tsx +1 -1
  24. package/Application/Components/HeaderExtendHeader.tsx +17 -11
  25. package/Application/Components/HeaderRight.styles.ts +144 -0
  26. package/Application/Components/HeaderRight.tsx +6 -528
  27. package/Application/Components/HeaderTitle.shared.ts +43 -0
  28. package/Application/Components/HeaderTitle.styles.ts +125 -0
  29. package/Application/Components/HeaderTitle.tsx +12 -576
  30. package/Application/Components/HeaderToolkitAction.tsx +208 -0
  31. package/Application/Components/NavigationButton.tsx +9 -6
  32. package/Application/Components/SearchHeader.tsx +1 -1
  33. package/Application/Components/SwipeBackHaptic.tsx +95 -0
  34. package/Application/Components/TitleJourney.tsx +110 -0
  35. package/Application/Components/TitleLocation.tsx +73 -0
  36. package/Application/Components/TitleUser.tsx +304 -0
  37. package/Application/Components/useToolkitActions.tsx +233 -0
  38. package/Application/ModalIconButton.tsx +66 -0
  39. package/Application/ModalScreen.tsx +39 -18
  40. package/Application/Navigation.ts +1 -1
  41. package/Application/NavigationContainer.tsx +7 -8
  42. package/Application/StackScreen.tracking.ts +158 -0
  43. package/Application/StackScreen.tsx +10 -137
  44. package/Application/WidgetContainer.tsx +10 -3
  45. package/Application/__tests__/modalLayout.test.ts +128 -0
  46. package/Application/hooks.ts +137 -0
  47. package/Application/index.ts +13 -1
  48. package/Application/modalLayout.ts +177 -0
  49. package/Application/navigationOptions.tsx +217 -0
  50. package/Application/types.header.ts +116 -0
  51. package/Application/types.tabs.ts +48 -0
  52. package/Application/types.theme.ts +87 -0
  53. package/Application/types.ts +12 -244
  54. package/Application/utils.ts +107 -0
  55. package/Badge/BadgeRibbon.tsx +3 -3
  56. package/Badge/styles.ts +2 -0
  57. package/Button/index.tsx +16 -136
  58. package/Button/styles.ts +1 -1
  59. package/Button/utils.ts +139 -0
  60. package/CheckBox/index.tsx +1 -6
  61. package/Divider/DashDivider.tsx +10 -11
  62. package/Divider/index.tsx +18 -8
  63. package/Image/index.tsx +1 -46
  64. package/Input/Input.tsx +7 -8
  65. package/Input/InputDropDown.tsx +3 -4
  66. package/Input/InputMoney.tsx +38 -164
  67. package/Input/InputMoneyView.tsx +187 -0
  68. package/Input/InputOTP.tsx +1 -1
  69. package/Input/InputPhoneNumber.tsx +5 -1
  70. package/Input/InputSearch.tsx +2 -108
  71. package/Input/InputTextArea.tsx +1 -5
  72. package/Input/SearchTextTyping.tsx +104 -0
  73. package/Input/common.tsx +4 -4
  74. package/Input/moneyUtils.ts +17 -0
  75. package/Input/styles.ts +26 -2
  76. package/Layout/FloatingButton.tsx +22 -21
  77. package/Layout/ReservedRegions.tsx +21 -4
  78. package/Layout/Screen.tsx +74 -670
  79. package/Layout/Section.tsx +1 -2
  80. package/Layout/index.ts +10 -4
  81. package/Layout/layoutMetrics.ts +58 -0
  82. package/Layout/layoutTypes.ts +86 -0
  83. package/Layout/screenContent.tsx +90 -0
  84. package/Layout/screenFooter.tsx +53 -0
  85. package/Layout/screenHeader.tsx +315 -0
  86. package/Layout/screenQuickReturn.tsx +67 -0
  87. package/Layout/screenScroll.ts +110 -0
  88. package/Layout/screenTypes.ts +134 -0
  89. package/Layout/styles.ts +2 -0
  90. package/Layout/utils.ts +10 -144
  91. package/Loader/DotLoader.tsx +7 -3
  92. package/Loader/ProgressBar.tsx +2 -6
  93. package/Loader/Spinner.tsx +7 -3
  94. package/Loader/styles.ts +4 -0
  95. package/Popup/PopupNotify.tsx +70 -64
  96. package/Popup/PopupPromotion.tsx +5 -4
  97. package/Popup/types.ts +7 -0
  98. package/Popup/utils.ts +46 -24
  99. package/Radio/index.tsx +2 -10
  100. package/Radio/styles.ts +6 -0
  101. package/Skeleton/index.tsx +1 -9
  102. package/Skeleton/styles.ts +1 -0
  103. package/Tag/index.tsx +3 -3
  104. package/Text/index.tsx +11 -2
  105. package/Title/index.tsx +2 -9
  106. package/Title/styles.ts +6 -0
  107. package/package.json +21 -22
  108. package/Application/device.ts +0 -29
  109. package/Application/utils.tsx +0 -497
@@ -1,323 +1,276 @@
1
1
  import { BottomTabBarProps } from '@react-navigation/bottom-tabs';
2
- import { CommonActions, Route } from '@react-navigation/native';
3
- import React, { useCallback, useContext } from 'react';
4
- import {
5
- Platform,
6
- StyleSheet,
7
- TouchableOpacity,
8
- useWindowDimensions,
9
- View,
10
- } from 'react-native';
2
+ import React, { useContext, useState } from 'react';
3
+ import { Platform, Pressable, useWindowDimensions, View } from 'react-native';
11
4
  import Animated, {
12
5
  useAnimatedStyle,
13
6
  useSharedValue,
14
7
  withTiming,
15
8
  } from 'react-native-reanimated';
16
- import { EdgeInsets, useSafeAreaInsets } from 'react-native-safe-area-context';
17
- import { Colors, Radius, Styles } from '../../Consts';
9
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
10
+ import { Colors, Spacing } from '../../Consts';
18
11
  import { Icon } from '../../Icon';
19
12
  import { Text } from '../../Text';
20
13
  import { FloatingButtonProps } from '../types';
21
14
  import CustomBottomTabItem from './CustomBottomTabItem';
22
15
  import { ApplicationContext, MiniAppContext } from '../../Context';
16
+ import { CurvedContainer } from './CurvedContainer';
17
+ import { ActiveIndicator } from './ActiveIndicator';
18
+ import { getHorizontalBarWidth, TabBarMetrics, TabBarMotion } from './metrics';
19
+ import { getTabItems, TabItem } from './tabItems';
20
+ import { FixedScaleText } from './TabBarIcon';
21
+ import { styles } from './BottomTabBar.styles';
23
22
 
24
23
  type Props = BottomTabBarProps & {
25
- activeTintColor?: string;
26
- inactiveTintColor?: string;
24
+ activeTintColor: string;
25
+ inactiveTintColor: string;
27
26
  floatingButton?: FloatingButtonProps;
28
- activeBackgroundColor?: string;
29
- allowFontScaling?: boolean;
30
- inactiveBackgroundColor?: string;
31
- labelStyle?: any;
32
- iconStyle?: any;
33
- showLabel?: boolean;
34
- style?: any;
35
- tabStyle?: any;
36
- badgeStyle?: any;
37
27
  };
38
28
 
39
- const getPaddingBottom = (insets: EdgeInsets) => {
40
- return Math.max(insets.bottom - Platform.select({ ios: 4, default: 0 }), 0);
41
- };
29
+ /**
30
+ * the center action needs a tab on each side: Special type takes 2 or 4 tabs
31
+ */
32
+ const hasCenterAction = (floatingButton: unknown, tabCount: number) =>
33
+ !!floatingButton && tabCount % 2 === 0;
42
34
 
43
- export default function BottomTabBar({
44
- state,
45
- navigation,
46
- descriptors,
47
- activeBackgroundColor,
48
- activeTintColor,
49
- allowFontScaling,
50
- inactiveBackgroundColor,
51
- inactiveTintColor,
52
- labelStyle,
53
- iconStyle,
54
- showLabel,
55
- style,
56
- floatingButton,
57
- }: Props) {
58
- const { theme } = useContext(ApplicationContext);
59
- const { routes } = state;
60
- const widthDevice = useWindowDimensions()?.width;
61
- const insets = useSafeAreaInsets();
62
- const useFloating = floatingButton && state.routes.length % 2 === 0;
63
- const itemWidth =
64
- (widthDevice - insets.left - insets.right) /
65
- (state.routes.length + (useFloating ? 1 : 0));
66
- // const buildLink = useLinkBuilder();
67
- const indicatorAnimated = useSharedValue(0);
35
+ /**
36
+ * gap under the container: the home indicator / gesture bar area
37
+ */
38
+ const getSystemIndicatorHeight = (bottomInset: number) =>
39
+ Math.max(
40
+ Platform.OS === 'ios'
41
+ ? Math.min(bottomInset, TabBarMetrics.systemIndicatorHeight)
42
+ : bottomInset,
43
+ Spacing.S,
44
+ );
68
45
 
69
- const indicatorStyle = useAnimatedStyle(() => ({
70
- width: itemWidth,
71
- transform: [{ translateX: indicatorAnimated.value }],
46
+ /**
47
+ * center action press: the button shrinks while held; the label stays plain text
48
+ */
49
+ const useCenterActionPress = () => {
50
+ const scale = useSharedValue(1);
51
+ const buttonStyle = useAnimatedStyle(() => ({
52
+ transform: [{ scale: scale.value }],
72
53
  }));
73
- const paddingBottom = getPaddingBottom(insets);
74
- const focusedTab = state?.routes[state.index]?.name || routes[0]?.params;
54
+ const onPressIn = () => {
55
+ scale.value = withTiming(
56
+ TabBarMotion.ctaPressedScale,
57
+ TabBarMotion.ctaPress,
58
+ );
59
+ };
60
+ const onPressOut = () => {
61
+ scale.value = withTiming(1, TabBarMotion.ctaPress);
62
+ };
63
+ return { buttonStyle, onPressIn, onPressOut };
64
+ };
75
65
 
66
+ /**
67
+ * center action (.Nav/CTA): button rising out of the notch, label under it
68
+ */
69
+ const CenterAction: React.FC<{
70
+ floatingButton: FloatingButtonProps;
71
+ fixedFontScale?: boolean;
72
+ }> = ({ floatingButton, fixedFontScale }) => {
73
+ const { theme } = useContext(ApplicationContext);
76
74
  const context = useContext<any>(MiniAppContext);
77
75
  const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
78
-
79
- /**
80
- * render tab item
81
- */
82
- const renderTabItem = useCallback(
83
- (data: Route<string, any>[]) => {
84
- return data?.map(route => {
85
- const focused = route?.params?.name === focusedTab;
86
- const { options } = descriptors[route.key];
87
-
88
- const onPress = () => {
89
- const event = navigation.emit({
90
- type: 'tabPress',
91
- target: route.key,
92
- canPreventDefault: true,
93
- });
94
-
95
- if (!focused && !event.defaultPrevented) {
96
- navigation.dispatch({
97
- ...CommonActions.navigate(route.name),
98
- target: state.key,
99
- });
100
- }
101
- };
102
-
103
- const onLongPress = () => {
104
- navigation.emit({
105
- type: 'tabLongPress',
106
- target: route.key,
107
- });
108
- };
109
-
110
- return (
111
- <CustomBottomTabItem
112
- key={route.key}
113
- route={route}
114
- label={options.tabBarLabel || options.title || route.name}
115
- focused={focused}
116
- onPress={onPress}
117
- onLongPress={onLongPress}
118
- activeTintColor={activeTintColor ?? theme.colors.primary}
119
- inactiveTintColor={inactiveTintColor ?? theme.colors.text.default}
120
- activeBackgroundColor={activeBackgroundColor}
121
- inactiveBackgroundColor={inactiveBackgroundColor}
122
- icon={options.tabBarIcon}
123
- badge={options.tabBarBadge}
124
- showLabel={showLabel}
125
- labelStyle={labelStyle}
126
- iconStyle={iconStyle}
127
- style={options.tabBarStyle}
128
- badgeStyle={options.tabBarBadgeStyle}
129
- allowFontScaling={allowFontScaling}
130
- />
131
- );
132
- });
133
- },
134
- [
135
- focusedTab,
136
- descriptors,
137
- activeTintColor,
138
- theme.colors.primary,
139
- theme.colors.text.default,
140
- inactiveTintColor,
141
- activeBackgroundColor,
142
- inactiveBackgroundColor,
143
- showLabel,
144
- labelStyle,
145
- iconStyle,
146
- allowFontScaling,
147
- navigation,
148
- state.key,
149
- ],
76
+ const { icon, label, onPress, labelContent } = floatingButton;
77
+ const { buttonStyle, onPressIn, onPressOut } = useCenterActionPress();
78
+ const labelText = (
79
+ <Text
80
+ numberOfLines={1}
81
+ typography={'label_s_medium'}
82
+ color={theme.colors.text.secondary}
83
+ >
84
+ {label}
85
+ </Text>
150
86
  );
151
87
 
152
- /**
153
- * render floating button
154
- */
155
- const renderFloatingButton = useCallback(() => {
156
- const renderFloatingIcon = () => {
157
- if (typeof floatingButton?.icon === 'string') {
158
- return <Icon source={floatingButton?.icon} size={32} color={'white'} />;
159
- }
160
- return floatingButton?.icon;
161
- };
162
-
163
- return (
164
- <View style={[Styles.flex, showBaseLineDebug && styles.debugBaseLine]}>
165
- <TouchableOpacity
166
- onPress={floatingButton?.onPress}
167
- style={styles.floatingContainer}
88
+ return (
89
+ <View style={[styles.ctaSlot, showBaseLineDebug && styles.debugBaseLine]}>
90
+ <Pressable
91
+ accessibilityRole={'button'}
92
+ accessibilityLabel={label}
93
+ onPress={onPress}
94
+ onPressIn={onPressIn}
95
+ onPressOut={onPressOut}
96
+ style={styles.cta}
97
+ >
98
+ <Animated.View
99
+ style={[
100
+ styles.ctaButton,
101
+ { backgroundColor: theme.colors.primary },
102
+ buttonStyle,
103
+ ]}
168
104
  >
169
- <View
170
- style={{
171
- ...styles.floatingContent,
172
- backgroundColor: activeTintColor ?? theme.colors.primary,
173
- }}
174
- >
175
- {renderFloatingIcon()}
176
- </View>
177
- <View
178
- style={{
179
- top: -4,
180
- backgroundColor: activeTintColor ?? theme.colors.primary,
181
- borderRadius: Radius.XL,
182
- paddingHorizontal: 6,
183
- }}
184
- >
185
- <Text
186
- numberOfLines={1}
187
- typography={'description_xs_regular'}
188
- color={'white'}
189
- >
190
- {floatingButton?.label}
191
- </Text>
192
- </View>
193
- </TouchableOpacity>
194
- </View>
195
- );
196
- }, [
197
- activeTintColor,
198
- floatingButton?.icon,
199
- floatingButton?.label,
200
- floatingButton?.onPress,
201
- showBaseLineDebug,
202
- theme.colors.primary,
203
- ]);
105
+ {typeof icon === 'string' ? (
106
+ <Icon
107
+ source={icon}
108
+ size={TabBarMetrics.ctaIconSize}
109
+ color={Colors.black_01}
110
+ />
111
+ ) : (
112
+ icon
113
+ )}
114
+ </Animated.View>
115
+ <View style={styles.ctaLabel}>
116
+ {fixedFontScale ? (
117
+ <FixedScaleText>{labelText}</FixedScaleText>
118
+ ) : (
119
+ labelText
120
+ )}
121
+ {labelContent && (
122
+ <View pointerEvents={'none'} style={styles.ctaLabelOverlay}>
123
+ {labelContent}
124
+ </View>
125
+ )}
126
+ </View>
127
+ </Pressable>
128
+ </View>
129
+ );
130
+ };
204
131
 
205
- /**
206
- * animated indicator
207
- */
208
- React.useEffect(() => {
209
- let index = state.index;
210
- if (useFloating && index > (state.routes.length - 1) / 2) {
211
- index += 1;
212
- }
213
- indicatorAnimated.value = withTiming(itemWidth * index, { duration: 200 });
214
- }, [
215
- state.index,
216
- itemWidth,
217
- indicatorAnimated,
218
- useFloating,
219
- state.routes.length,
220
- ]);
132
+ /**
133
+ * horizontal navigation bar: floating container, items split evenly, Special type puts
134
+ * the center action in a notch in the middle
135
+ */
136
+ const HorizontalTabBar: React.FC<{
137
+ items: TabItem[];
138
+ width: number;
139
+ activeTintColor: string;
140
+ inactiveTintColor: string;
141
+ floatingButton?: FloatingButtonProps;
142
+ fixedFontScale?: boolean;
143
+ }> = ({
144
+ items,
145
+ width,
146
+ activeTintColor,
147
+ inactiveTintColor,
148
+ floatingButton,
149
+ fixedFontScale,
150
+ }) => {
151
+ const withCta = hasCenterAction(floatingButton, items.length);
152
+ const [layouts, setLayouts] = useState<
153
+ Record<string, { x: number; y: number; width: number }>
154
+ >({});
155
+ const selected = layouts[items.find(item => item.focused)?.route.key ?? ''];
156
+
157
+ const renderItems = (data: TabItem[]) =>
158
+ data.map(item => (
159
+ <CustomBottomTabItem
160
+ key={item.route.key}
161
+ onLayout={e => {
162
+ const { x, y, width: itemWidth } = e.nativeEvent.layout;
163
+ setLayouts(prev => ({
164
+ ...prev,
165
+ [item.route.key]: { x, y, width: itemWidth },
166
+ }));
167
+ }}
168
+ label={item.label}
169
+ focused={item.focused}
170
+ icon={item.icon}
171
+ badge={item.badge}
172
+ onPress={item.onPress}
173
+ onLongPress={item.onLongPress}
174
+ activeTintColor={activeTintColor}
175
+ inactiveTintColor={inactiveTintColor}
176
+ fixedFontScale={fixedFontScale}
177
+ />
178
+ ));
221
179
 
222
- /**
223
- * render tab bar
224
- */
225
- const renderTabBar = () => {
226
- if (useFloating) {
227
- const middleIndex = routes.length / 2;
228
- const leftArr = routes.slice(0, middleIndex);
229
- const rightArr = routes.slice(middleIndex);
180
+ const renderContent = () => {
181
+ if (withCta && floatingButton) {
182
+ const middle = items.length / 2;
230
183
  return (
231
184
  <>
232
- {renderTabItem(leftArr)}
233
- {renderFloatingButton()}
234
- {renderTabItem(rightArr)}
185
+ {renderItems(items.slice(0, middle))}
186
+ <CenterAction
187
+ floatingButton={floatingButton}
188
+ fixedFontScale={fixedFontScale}
189
+ />
190
+ {renderItems(items.slice(middle))}
235
191
  </>
236
192
  );
237
193
  }
238
- return renderTabItem(routes);
194
+ return renderItems(items);
239
195
  };
240
196
 
197
+ const customContainer = withCta && floatingButton?.container;
198
+
241
199
  return (
242
200
  <View
201
+ style={[styles.container, { width }]}
202
+ accessibilityLabel={'bottom_tab_bar'}
203
+ >
204
+ {customContainer || (
205
+ <CurvedContainer
206
+ width={width}
207
+ height={TabBarMetrics.height}
208
+ radius={TabBarMetrics.height / 2}
209
+ notchCenterX={withCta ? width / 2 : undefined}
210
+ />
211
+ )}
212
+ <View style={styles.content}>
213
+ <ActiveIndicator
214
+ axis={'x'}
215
+ offset={selected?.x}
216
+ extent={selected?.width}
217
+ radius={TabBarMetrics.indicatorRadius}
218
+ style={[
219
+ styles.indicator,
220
+ { top: selected?.y ?? TabBarMetrics.paddingVertical },
221
+ ]}
222
+ />
223
+ {renderContent()}
224
+ </View>
225
+ </View>
226
+ );
227
+ };
228
+
229
+ /**
230
+ * phone tab bar: the horizontal navigation bar floating over the tab content above the home
231
+ * indicator, so the content shows around it and through the notch. The transparent strip
232
+ * above it keeps the rising center action touchable
233
+ */
234
+ export default function BottomTabBar(props: Props) {
235
+ const { state, floatingButton, activeTintColor, inactiveTintColor } = props;
236
+ const window = useWindowDimensions();
237
+ const insets = useSafeAreaInsets();
238
+ const withCta = hasCenterAction(floatingButton, state.routes.length);
239
+ const width = getHorizontalBarWidth(
240
+ window.width,
241
+ window.height,
242
+ insets.left,
243
+ insets.right,
244
+ );
245
+
246
+ return (
247
+ <View
248
+ pointerEvents={'box-none'}
243
249
  style={[
244
- floatingButton ? styles.tabBarFloatingButton : styles.tabBar,
245
- {
246
- backgroundColor: theme.colors.background.surface,
247
- borderTopColor: theme.colors.border.default,
248
- },
250
+ styles.bar,
251
+ withCta && styles.barCtaRise,
249
252
  {
250
- paddingBottom: paddingBottom,
253
+ paddingBottom: getSystemIndicatorHeight(insets.bottom),
254
+ // centered between the side safe areas
251
255
  paddingLeft: insets.left,
252
256
  paddingRight: insets.right,
253
257
  },
254
- style,
255
258
  ]}
256
- pointerEvents={'auto'}
257
259
  >
258
- <View style={styles.content} accessibilityLabel={'bottom_tab_bar'}>
259
- {useFloating && floatingButton?.container}
260
- <Animated.View
261
- style={[{ position: 'absolute', top: 0 }, indicatorStyle]}
262
- >
263
- <View
264
- style={[
265
- styles.indicator,
266
- { backgroundColor: activeTintColor ?? theme.colors.primary },
267
- ]}
268
- />
269
- </Animated.View>
270
- {renderTabBar()}
271
- </View>
260
+ <HorizontalTabBar
261
+ items={getTabItems(props)}
262
+ width={width}
263
+ floatingButton={floatingButton}
264
+ activeTintColor={activeTintColor}
265
+ inactiveTintColor={inactiveTintColor}
266
+ />
272
267
  </View>
273
268
  );
274
269
  }
275
270
 
276
- const styles = StyleSheet.create({
277
- content: {
278
- flex: 1,
279
- flexDirection: 'row',
280
- },
281
- tabBar: {
282
- left: 0,
283
- right: 0,
284
- bottom: 0,
285
- borderTopWidth: StyleSheet.hairlineWidth,
286
- elevation: 8,
287
- },
288
- tabBarFloatingButton: {
289
- left: 0,
290
- right: 0,
291
- bottom: 0,
292
- zIndex: 1,
293
- shadowColor: Colors.black_20,
294
- shadowOffset: { width: 0, height: -2 },
295
- shadowOpacity: 0.05,
296
- shadowRadius: 3,
297
- elevation: 8,
298
- },
299
- floatingContainer: {
300
- position: 'absolute',
301
- alignItems: 'center',
302
- left: 0,
303
- right: 0,
304
- top: -2,
305
- bottom: Platform.OS === 'ios' ? -6 : 4
306
- },
307
- floatingContent: {
308
- alignItems: 'center',
309
- justifyContent: 'center',
310
- height: 48,
311
- width: 48,
312
- borderRadius: 24,
313
- top: -10,
314
- },
315
- indicator: {
316
- height: 2,
317
- width: 44,
318
- alignSelf: 'center',
319
- borderBottomLeftRadius: 1,
320
- borderBottomRightRadius: 1,
321
- },
322
- debugBaseLine: { borderWidth: 1, borderColor: Colors.green_06 },
323
- });
271
+ export {
272
+ HorizontalTabBar,
273
+ getSystemIndicatorHeight,
274
+ hasCenterAction,
275
+ useCenterActionPress,
276
+ };
@@ -0,0 +1,14 @@
1
+ import { createContext } from 'react';
2
+
3
+ type BottomTabInset = {
4
+ // space the floating tab bar takes over the bottom of a tab's content (bar + home
5
+ // indicator area, plus the rising center action when shown); 0 on the iPhone Duo rail
6
+ inset: number;
7
+ // a Screen in the tab keeps its content clear of the bar itself (inside its scroll view,
8
+ // or above the bar when static), so the tab stops padding its content
9
+ claim?: () => void;
10
+ };
11
+
12
+ const BottomTabInsetContext = createContext<BottomTabInset>({ inset: 0 });
13
+
14
+ export { BottomTabInsetContext };