@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
@@ -0,0 +1,227 @@
1
+ import React, { useContext } from 'react';
2
+ import { Pressable, TouchableOpacity, View } from 'react-native';
3
+ import Animated from 'react-native-reanimated';
4
+ import { Colors, Radius } from '../../Consts';
5
+ import { ApplicationContext } from '../../Context';
6
+ import { Icon } from '../../Icon';
7
+ import { useScreenLayout } from '../../Layout/utils';
8
+ import { Text } from '../../Text';
9
+ import { FloatingButtonProps } from '../types';
10
+ import { useDuoBarCompression } from './DuoBarCompression';
11
+ import { useCenterActionPress } from './BottomTabBar';
12
+ import { TabItemContent } from './CustomBottomTabItem';
13
+ import { CurvedContainer } from './CurvedContainer';
14
+ import { TabBarMetrics } from './metrics';
15
+ import { getTabItems, TabItem } from './tabItems';
16
+ import { FixedScaleText } from './TabBarIcon';
17
+ import { usePressLift } from './usePressLift';
18
+ import { ActiveIndicator } from './ActiveIndicator';
19
+ import {
20
+ RAIL_COMPACT_SIZE,
21
+ RAIL_ITEM_HEIGHT,
22
+ styles,
23
+ } from './DuoTabBar.styles';
24
+ import type { DuoTabBarProps } from './DuoTabBar';
25
+
26
+ /**
27
+ * Center action icon: an icon name drawn at the CTA size, or a custom node
28
+ */
29
+ const CtaIcon: React.FC<{ icon: FloatingButtonProps['icon'] }> = ({ icon }) => {
30
+ if (typeof icon === 'string') {
31
+ return (
32
+ <Icon
33
+ source={icon}
34
+ size={TabBarMetrics.ctaIconSize}
35
+ color={Colors.black_01}
36
+ />
37
+ );
38
+ }
39
+ return <>{icon}</>;
40
+ };
41
+
42
+ /**
43
+ * vertical container (.Nav/Duo/Item column) with the sliding active indicator
44
+ */
45
+ const Rail: React.FC<{
46
+ items: TabItem[];
47
+ index: number;
48
+ activeTintColor: string;
49
+ inactiveTintColor: string;
50
+ onItemPress?: () => void;
51
+ }> = ({ items, index, activeTintColor, inactiveTintColor, onItemPress }) => (
52
+ <View style={styles.rail} accessibilityLabel={'bottom_tab_bar'}>
53
+ <CurvedContainer
54
+ width={TabBarMetrics.railContainerWidth}
55
+ height={items.length * RAIL_ITEM_HEIGHT + TabBarMetrics.railPaddingBottom}
56
+ radius={Radius.XL}
57
+ />
58
+ <ActiveIndicator
59
+ axis={'y'}
60
+ offset={index * RAIL_ITEM_HEIGHT}
61
+ radius={TabBarMetrics.railIndicatorRadius}
62
+ style={styles.railIndicator}
63
+ />
64
+ {items.map(item => (
65
+ <TouchableOpacity
66
+ key={item.route.key}
67
+ accessibilityRole={'tab'}
68
+ accessibilityLabel={item.label}
69
+ accessibilityState={{ selected: item.focused }}
70
+ onPress={() => {
71
+ item.onPress();
72
+ onItemPress?.();
73
+ }}
74
+ onLongPress={item.onLongPress}
75
+ style={styles.railItem}
76
+ >
77
+ <TabItemContent
78
+ vertical
79
+ fixedFontScale
80
+ label={item.label}
81
+ focused={item.focused}
82
+ icon={item.icon}
83
+ badge={item.badge}
84
+ activeTintColor={activeTintColor}
85
+ inactiveTintColor={inactiveTintColor}
86
+ />
87
+ </TouchableOpacity>
88
+ ))}
89
+ </View>
90
+ );
91
+
92
+ /**
93
+ * center action of the rail: round button with its label, under the container
94
+ */
95
+ const RailCenterAction: React.FC<{ floatingButton: FloatingButtonProps }> = ({
96
+ floatingButton,
97
+ }) => {
98
+ const { theme } = useContext(ApplicationContext);
99
+ const { buttonStyle, onPressIn, onPressOut } = useCenterActionPress();
100
+ return (
101
+ <Pressable
102
+ accessibilityRole={'button'}
103
+ accessibilityLabel={floatingButton.label}
104
+ onPress={floatingButton.onPress}
105
+ onPressIn={onPressIn}
106
+ onPressOut={onPressOut}
107
+ style={styles.railCta}
108
+ >
109
+ <Animated.View
110
+ style={[
111
+ styles.railCtaButton,
112
+ { backgroundColor: theme.colors.primary },
113
+ buttonStyle,
114
+ ]}
115
+ >
116
+ <CtaIcon icon={floatingButton.icon} />
117
+ </Animated.View>
118
+ <View style={styles.railCtaLabel}>
119
+ <FixedScaleText>
120
+ <Text
121
+ numberOfLines={1}
122
+ typography={'label_xs_medium'}
123
+ color={theme.colors.text.secondary}
124
+ >
125
+ {floatingButton.label}
126
+ </Text>
127
+ </FixedScaleText>
128
+ {floatingButton.labelContent && (
129
+ <View pointerEvents={'none'} style={styles.railCtaLabelOverlay}>
130
+ {floatingButton.labelContent}
131
+ </View>
132
+ )}
133
+ </View>
134
+ </Pressable>
135
+ );
136
+ };
137
+
138
+ /**
139
+ * vertical bar anchored to the bottom of the Duo side bar, center action below it.
140
+ * When the side bar is short, it can shrink to one button showing the current tab
141
+ * (HIG "Tab bar compressed"); tapping it expands the rail and compresses the toolbar
142
+ */
143
+ const DuoRailTabBar: React.FC<DuoTabBarProps> = props => {
144
+ const { sideBar } = useScreenLayout();
145
+ const { tabBarCompressed, expandTabBar, onTabSelected } =
146
+ useDuoBarCompression();
147
+ const compactLift = usePressLift();
148
+ const { state, floatingButton, activeTintColor, inactiveTintColor } = props;
149
+ const items = getTabItems(props);
150
+ const current = items[state.index];
151
+
152
+ if (!sideBar) {
153
+ return null;
154
+ }
155
+
156
+ // the rail lines up with the header buttons in the side bar: centered on a 48 lane kept 12
157
+ // from the strip's inner edge
158
+ const columnStyle = [
159
+ styles.railColumn,
160
+ {
161
+ [sideBar.edge]: 0,
162
+ width: sideBar.width,
163
+ bottom: sideBar.bottom,
164
+ },
165
+ sideBar.edge === 'right' ? styles.railColumnRight : styles.railColumnLeft,
166
+ ];
167
+ const cta = floatingButton && (
168
+ <RailCenterAction floatingButton={floatingButton} />
169
+ );
170
+
171
+ if (!tabBarCompressed) {
172
+ return (
173
+ <View pointerEvents={'box-none'} style={columnStyle}>
174
+ <View pointerEvents={'box-none'} style={styles.railLane}>
175
+ <Rail
176
+ items={items}
177
+ index={state.index}
178
+ activeTintColor={activeTintColor}
179
+ inactiveTintColor={inactiveTintColor}
180
+ onItemPress={onTabSelected}
181
+ />
182
+ {cta}
183
+ </View>
184
+ </View>
185
+ );
186
+ }
187
+
188
+ return (
189
+ <View pointerEvents={'box-none'} style={columnStyle}>
190
+ <View pointerEvents={'box-none'} style={styles.railLane}>
191
+ <Animated.View style={compactLift.style}>
192
+ <TouchableOpacity
193
+ accessibilityRole={'button'}
194
+ accessibilityLabel={current?.label}
195
+ accessibilityHint={'bottom_tab_bar'}
196
+ activeOpacity={1}
197
+ onPressIn={compactLift.onPressIn}
198
+ onPressOut={compactLift.onPressOut}
199
+ onPress={expandTabBar}
200
+ style={styles.railCompact}
201
+ >
202
+ <CurvedContainer
203
+ width={RAIL_COMPACT_SIZE}
204
+ height={RAIL_COMPACT_SIZE}
205
+ radius={RAIL_COMPACT_SIZE / 2}
206
+ />
207
+ {current && (
208
+ <TabItemContent
209
+ vertical
210
+ hideLabel
211
+ focused
212
+ label={current.label}
213
+ icon={current.icon}
214
+ badge={current.badge}
215
+ activeTintColor={activeTintColor}
216
+ inactiveTintColor={inactiveTintColor}
217
+ />
218
+ )}
219
+ </TouchableOpacity>
220
+ </Animated.View>
221
+ {cta}
222
+ </View>
223
+ </View>
224
+ );
225
+ };
226
+
227
+ export { DuoRailTabBar };
@@ -0,0 +1,81 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import { Spacing } from '../../Consts';
3
+ import { DuoMetrics } from '../../Layout/utils';
4
+ import { CTA_SHADOW, TabBarMetrics } from './metrics';
5
+
6
+ export const RAIL_ITEM_WIDTH = TabBarMetrics.railItemWidth;
7
+ export const RAIL_ITEM_HEIGHT = TabBarMetrics.railItemHeight;
8
+ export const RAIL_COMPACT_SIZE = DuoMetrics.controlSize;
9
+
10
+ export const styles = StyleSheet.create({
11
+ railColumn: {
12
+ position: 'absolute',
13
+ },
14
+ railColumnRight: {
15
+ alignItems: 'flex-start',
16
+ paddingLeft: Spacing.M,
17
+ },
18
+ railColumnLeft: {
19
+ alignItems: 'flex-end',
20
+ paddingRight: Spacing.M,
21
+ },
22
+ // as wide as the header buttons; the wider rail and center action overflow it evenly
23
+ railLane: {
24
+ width: DuoMetrics.controlSize,
25
+ alignItems: 'center',
26
+ gap: TabBarMetrics.railCtaGap,
27
+ },
28
+ railCompact: {
29
+ width: RAIL_COMPACT_SIZE,
30
+ height: RAIL_COMPACT_SIZE,
31
+ alignItems: 'center',
32
+ justifyContent: 'center',
33
+ },
34
+ rail: {
35
+ width: TabBarMetrics.railContainerWidth,
36
+ paddingHorizontal: TabBarMetrics.railPaddingHorizontal,
37
+ paddingBottom: TabBarMetrics.railPaddingBottom,
38
+ },
39
+ railIndicator: {
40
+ top: Spacing.XS,
41
+ left: TabBarMetrics.railPaddingHorizontal,
42
+ width: RAIL_ITEM_WIDTH,
43
+ height: TabBarMetrics.railIndicatorHeight,
44
+ },
45
+ railItem: {
46
+ width: RAIL_ITEM_WIDTH,
47
+ height: RAIL_ITEM_HEIGHT,
48
+ alignItems: 'center',
49
+ justifyContent: 'center',
50
+ },
51
+ railCta: {
52
+ width: TabBarMetrics.railCtaWidth,
53
+ height: TabBarMetrics.railCtaHeight,
54
+ alignItems: 'center',
55
+ justifyContent: 'center',
56
+ gap: TabBarMetrics.railCtaLabelGap,
57
+ },
58
+ // custom label content over the label text, centered and unclipped
59
+ railCtaLabelOverlay: {
60
+ ...StyleSheet.absoluteFillObject,
61
+ alignItems: 'center',
62
+ justifyContent: 'center',
63
+ },
64
+ railCtaLabel: {
65
+ paddingHorizontal: Spacing.XS,
66
+ },
67
+ railCtaButton: {
68
+ boxShadow: CTA_SHADOW,
69
+ width: TabBarMetrics.railCtaSize,
70
+ height: TabBarMetrics.railCtaSize,
71
+ borderRadius: TabBarMetrics.railCtaSize / 2,
72
+ alignItems: 'center',
73
+ justifyContent: 'center',
74
+ },
75
+ floating: {
76
+ position: 'absolute',
77
+ left: 0,
78
+ right: 0,
79
+ alignItems: 'center',
80
+ },
81
+ });