@momo-kits/foundation 0.75.2-beta.0 → 0.75.4-beta.0

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.
@@ -10,21 +10,26 @@ import {Text} from '../../Text';
10
10
  import {ApplicationContext} from '../index';
11
11
  import StackScreen from '../StackScreen';
12
12
  import {BottomTabProps, NavigationScreenProps} from '../types';
13
- import {getStackOptions} from '../utils';
13
+ import {getOptions, getStackOptions} from '../utils';
14
14
  import BottomTabBar from './BottomTabBar';
15
15
 
16
16
  const Tab = createBottomTabNavigator();
17
17
  const Stack = createStackNavigator();
18
18
 
19
19
  const TabScreen: React.FC<NavigationScreenProps> = ({route}) => {
20
+ const {theme} = useContext(ApplicationContext);
21
+ let options = {};
22
+ if (route.params?.options) {
23
+ options = getOptions(route.params?.options, theme);
24
+ }
20
25
  if (route.params?.nested) {
21
26
  return (
22
27
  <Stack.Navigator>
23
28
  <Stack.Screen
24
29
  name="Stack"
25
30
  component={StackScreen}
26
- initialParams={{screen: route.params?.screen}}
27
- options={{...getStackOptions(), ...route.params?.options}}
31
+ initialParams={{screen: route.params?.screen, options}}
32
+ options={{...getStackOptions()}}
28
33
  />
29
34
  </Stack.Navigator>
30
35
  );
@@ -35,7 +40,7 @@ const TabScreen: React.FC<NavigationScreenProps> = ({route}) => {
35
40
  <Stack.Screen
36
41
  name="Stack"
37
42
  component={StackScreen}
38
- initialParams={{screen: route.params?.screen}}
43
+ initialParams={{screen: route.params?.screen, options}}
39
44
  options={{...getStackOptions(), ...route.params?.options}}
40
45
  />
41
46
  </Stack.Navigator>
@@ -75,14 +80,16 @@ const BottomTab: React.FC<BottomTabProps> = ({
75
80
  )}
76
81
  tabBarOptions={{
77
82
  style: {
78
- height: 68 + Math.min(insets.bottom, 21),
83
+ height: 64 + Math.min(insets.bottom, 21),
79
84
  },
80
85
  tabStyle: {
81
86
  height: 68,
82
- paddingVertical: 8,
87
+ paddingVertical: 10,
83
88
  },
84
89
  }}>
85
90
  {tabs.map(item => {
91
+ const isNum = !isNaN(parseInt(`${item?.badgeLabel}`));
92
+ const isDot = typeof item?.badgeLabel == 'string' && !item?.badgeLabel;
86
93
  return (
87
94
  <Tab.Screen
88
95
  key={item.name}
@@ -113,12 +120,9 @@ const BottomTab: React.FC<BottomTabProps> = ({
113
120
  fontWeight: 'bold',
114
121
  alignSelf: 'center',
115
122
  fontFamily: `${theme.font}-Bold`,
116
- left: item?.showDot ? 8 : 4,
117
- top: item?.showDot ? -2 : -6,
118
- backgroundColor:
119
- typeof item?.badgeLabel === 'string'
120
- ? Colors.orange_03
121
- : Colors.red_03,
123
+ left: isDot ? 8 : 4,
124
+ top: isDot ? -2 : -6,
125
+ backgroundColor: isNum ? Colors.red_03 : Colors.orange_03,
122
126
  },
123
127
  tabBarIcon: ({color}) => (
124
128
  <Icon source={item.icon} color={color} size={28} />
@@ -183,15 +183,18 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
183
183
 
184
184
  const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
185
185
  image,
186
- backgroundColor,
187
186
  animatedValue,
188
- useBorder = false,
187
+ useSurface = false,
189
188
  }) => {
190
189
  const {theme} = useContext(ApplicationContext);
191
190
  let headerImage = theme.assets?.headerBackground;
191
+ let backgroundColor;
192
192
  if (image === null) {
193
193
  headerImage = undefined;
194
194
  }
195
+ if (useSurface) {
196
+ backgroundColor = theme.colors.background.surface;
197
+ }
195
198
  const opacity = animatedValue?.interpolate({
196
199
  inputRange: [0, 114],
197
200
  outputRange: [0, 1],
@@ -203,9 +206,9 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
203
206
  style={[
204
207
  Styles.flex,
205
208
  {
206
- backgroundColor: backgroundColor ?? theme.colors.background.default,
209
+ backgroundColor,
207
210
  overflow: 'hidden',
208
- borderBottomWidth: useBorder ? 1 : 0,
211
+ borderBottomWidth: useSurface ? 1 : 0,
209
212
  borderColor: theme.colors.border.default,
210
213
  opacity,
211
214
  },
@@ -297,14 +300,14 @@ const HeaderToolkitAction: React.FC<any> = ({
297
300
  runtimeTools = [],
298
301
  preventClose,
299
302
  }) => {
300
- const {theme, navigator} = useContext(ApplicationContext);
303
+ const {navigator} = useContext(ApplicationContext);
301
304
  const miniContext = useContext<any>(MiniAppContext);
302
305
  const [toolConfig, setToolConfig] = useState<any>();
303
306
  const {onAction} = toolConfig ?? {};
304
307
 
305
308
  let backgroundColor;
306
309
  if (tintColor != Colors.black_01) {
307
- backgroundColor = theme.colors.background.surface;
310
+ backgroundColor = 'transparent';
308
311
  }
309
312
 
310
313
  useEffect(() => {
@@ -503,7 +506,7 @@ const styles = StyleSheet.create({
503
506
  flexDirection: 'row',
504
507
  justifyContent: 'center',
505
508
  alignItems: 'center',
506
- paddingRight: Spacing.S,
509
+ paddingRight: Spacing.M,
507
510
  },
508
511
  toolkitContainer: {
509
512
  marginLeft: Spacing.S,
@@ -4,29 +4,16 @@ import {
4
4
  Platform,
5
5
  Pressable,
6
6
  StyleSheet,
7
- TouchableOpacity,
8
7
  View,
9
8
  } from 'react-native';
10
- import {Modalize} from 'react-native-modalize';
11
- import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
12
9
 
13
10
  import {ApplicationContext} from './index';
14
- import {Radius, Spacing, Styles} from '../Consts';
15
- import {Icon} from '../Icon';
16
- import {Text} from '../Text';
11
+ import {Styles} from '../Consts';
17
12
  import Navigation from './Navigation';
18
- import {BottomSheetParams, ModalParams} from './types';
13
+ import {ModalParams} from './types';
14
+ import BottomSheet from './BottomSheet';
19
15
 
20
16
  const ModalScreen: React.FC<any> = props => {
21
- /**
22
- * dismiss callback when modal | bottom sheet dismissed
23
- */
24
- useEffect(() => {
25
- return () => {
26
- props.route.params?.onDismiss?.();
27
- };
28
- }, []);
29
-
30
17
  if (props.route?.params?.isBottomSheet) {
31
18
  return <BottomSheet {...props} />;
32
19
  }
@@ -42,9 +29,14 @@ const Modal: React.FC<ModalParams> = props => {
42
29
  ...props.route.params,
43
30
  navigation,
44
31
  };
45
-
46
32
  delete params.screen;
47
33
 
34
+ useEffect(() => {
35
+ return () => {
36
+ props.route.params?.onDismiss?.();
37
+ };
38
+ }, []);
39
+
48
40
  const onDismiss = () => {
49
41
  if (barrierDismissible) {
50
42
  return;
@@ -83,89 +75,6 @@ const Modal: React.FC<ModalParams> = props => {
83
75
  );
84
76
  };
85
77
 
86
- const BottomSheet: React.FC<BottomSheetParams> = props => {
87
- const {theme, navigator} = useContext(ApplicationContext);
88
- const {
89
- screen: Screen,
90
- options,
91
- footerComponent,
92
- flatListProps,
93
- }: BottomSheetParams = props.route.params;
94
-
95
- const navigation = new Navigation(props.navigation, theme);
96
-
97
- const params = {
98
- ...props.route.params,
99
- navigation,
100
- };
101
-
102
- delete params.screen;
103
- const modalizeRef = useRef<Modalize>(null);
104
-
105
- useEffect(() => {
106
- modalizeRef.current?.open();
107
- }, []);
108
-
109
- const handleClose = () => {
110
- modalizeRef?.current?.close();
111
- };
112
-
113
- return (
114
- <SafeAreaView style={Styles.flex}>
115
- <Modalize
116
- keyboardAvoidingOffset={-20}
117
- adjustToContentHeight
118
- closeOnOverlayTap
119
- closeSnapPointStraightEnabled
120
- onClosed={() => {
121
- navigator?.pop();
122
- }}
123
- ref={modalizeRef}
124
- withHandle={false}
125
- flatListProps={flatListProps}
126
- HeaderComponent={headerDefault(
127
- options?.title ?? options?.customTitle?.title ?? '',
128
- handleClose,
129
- )}
130
- FooterComponent={footerDefault(footerComponent)}>
131
- <View style={styles.bottomSheetContainer}>
132
- <Screen {...props} {...params} />
133
- </View>
134
- </Modalize>
135
- </SafeAreaView>
136
- );
137
- };
138
-
139
- const headerDefault = (title: string, onClose: () => void) => {
140
- return (
141
- <View style={styles.header}>
142
- <Text
143
- style={styles.textOption}
144
- numberOfLines={2}
145
- typography="header_default_bold">
146
- {title ?? ''}
147
- </Text>
148
- <TouchableOpacity style={styles.buttonClose} onPress={onClose}>
149
- <Icon source="navigation_close" />
150
- </TouchableOpacity>
151
- </View>
152
- );
153
- };
154
-
155
- const footerDefault = (footerComponent: React.ReactNode) => {
156
- const insets = useSafeAreaInsets();
157
- if (!footerComponent) return;
158
- return (
159
- <View
160
- style={{
161
- marginBottom: Math.min(insets.bottom, 21) + Spacing.S,
162
- paddingHorizontal: 12,
163
- }}>
164
- {footerComponent}
165
- </View>
166
- );
167
- };
168
-
169
78
  const styles = StyleSheet.create({
170
79
  container: {flex: 1, flexDirection: 'row'},
171
80
  modalContent: {
@@ -183,62 +92,6 @@ const styles = StyleSheet.create({
183
92
  flex: 1,
184
93
  minHeight: '10%',
185
94
  },
186
- sheetContainer: {
187
- height: '100%',
188
- width: '100%',
189
- borderTopLeftRadius: Radius.M,
190
- borderTopRightRadius: Radius.M,
191
- overflow: 'hidden',
192
- },
193
- indicatorContainer: {
194
- width: '100%',
195
- paddingTop: Spacing.S,
196
- paddingBottom: Spacing.XS,
197
- alignItems: 'center',
198
- justifyContent: 'center',
199
- },
200
- indicator: {
201
- width: 40,
202
- height: 4,
203
- borderRadius: Radius.S,
204
- },
205
- bottomSheetContainer: {
206
- width: '100%',
207
- backgroundColor: 'white',
208
- borderTopRightRadius: 16,
209
- borderTopLeftRadius: 16,
210
- },
211
- header: {
212
- height: 50,
213
- width: '100%',
214
- alignItems: 'center',
215
- justifyContent: 'center',
216
- },
217
- textOption: {
218
- fontSize: 16,
219
- color: '#303233',
220
- textAlign: 'center',
221
- fontWeight: 'bold',
222
- paddingHorizontal: 60,
223
- },
224
- imageOption: {
225
- height: 1,
226
- backgroundColor: '#ebebeb',
227
- width: '100%',
228
- position: 'absolute',
229
- bottom: 1,
230
- },
231
- buttonClose: {
232
- padding: 12,
233
- position: 'absolute',
234
- right: 0,
235
- },
236
- icon: {
237
- width: 24,
238
- height: 24,
239
- tintColor: '#303233',
240
- backgroundColor: 'red',
241
- },
242
95
  });
243
96
 
244
97
  export default ModalScreen;
@@ -4,7 +4,6 @@ import {
4
4
  NavigationContainer as ReactNavigationContainer,
5
5
  NavigationContainerRef,
6
6
  } from '@react-navigation/native';
7
- import {BottomSheetModalProvider} from '@gorhom/bottom-sheet';
8
7
  import {createStackNavigator} from '@react-navigation/stack';
9
8
  import {DeviceEventEmitter} from 'react-native';
10
9
  import StackScreen from './StackScreen';
@@ -15,12 +14,6 @@ import {LocalizationObject, NavigationContainerProps} from './types';
15
14
  import {ApplicationContext} from './index';
16
15
  import kitLocalization from '../Assets/language.json';
17
16
 
18
- /**
19
- * link for deprecated
20
- */
21
-
22
- console.log(typeof BottomSheetModalProvider);
23
-
24
17
  const Stack = createStackNavigator();
25
18
 
26
19
  const NavigationContainer: React.FC<NavigationContainerProps> = ({
@@ -78,6 +78,7 @@ const StackScreen: React.FC<ScreenParams> = props => {
78
78
  context.autoTracking?.({
79
79
  appId: context.appId,
80
80
  code: context.code,
81
+ buildNumber: context.buildNumber,
81
82
  screenName,
82
83
  componentName: 'Screen',
83
84
  state: 'load',
@@ -100,6 +101,7 @@ const StackScreen: React.FC<ScreenParams> = props => {
100
101
  context.autoTracking?.({
101
102
  appId: context.appId,
102
103
  code: context.code,
104
+ buildNumber: context.buildNumber,
103
105
  screenName,
104
106
  componentName: 'Screen',
105
107
  state: 'interaction',
@@ -16,8 +16,8 @@ import {defaultContext} from '../Consts';
16
16
  const Context = createContext({});
17
17
  const ApplicationContext = createContext(defaultContext);
18
18
 
19
- const MiniAppContext = (Platform as any).MiniAppContext ?? Context;
20
- const ScreenContext = (Platform as any).ScreenContext ?? Context;
19
+ const MiniAppContext = (Platform as any).MiniAppContext ?? createContext({});
20
+ const ScreenContext = (Platform as any).ScreenContext ?? createContext({});
21
21
  const ComponentContext = (Platform as any).ComponentContext ?? Context;
22
22
 
23
23
  export {
@@ -1,6 +1,6 @@
1
1
  import {StackNavigationOptions} from '@react-navigation/stack';
2
2
  import React from 'react';
3
- import {Animated, FlatListProps, ViewProps} from 'react-native';
3
+ import {Animated, ViewProps} from 'react-native';
4
4
  import {PopupNotifyProps} from '../Popup/types';
5
5
  import Navigation from './Navigation';
6
6
  import Navigator from './Navigator';
@@ -70,16 +70,6 @@ export type Context = {
70
70
  translate?: (key: string) => string;
71
71
  };
72
72
 
73
- export type MiniAppInfo = {
74
- [key: string]: any;
75
- code: string;
76
- appId: string;
77
- buildNumber: number;
78
- flowPartnerId?: string;
79
- toolkitConfig?: any;
80
- fromCode?: string;
81
- };
82
-
83
73
  export type LocalizationObject = {
84
74
  vi: {
85
75
  [key: string]: string;
@@ -110,18 +100,27 @@ export type ScreenParams = {
110
100
  options?: NavigationOptions;
111
101
  };
112
102
 
113
- export interface ModalParams extends ScreenParams {
103
+ export type ModalParams = {
114
104
  [key: string]: any;
105
+ screen: Screen;
115
106
  onDismiss?: () => void;
116
107
  barrierDismissible?: boolean;
117
- }
108
+ };
118
109
 
119
- export interface BottomSheetParams extends ScreenParams {
110
+ export type BottomSheetParams = {
120
111
  [key: string]: any;
121
- onDismiss?: () => void;
122
- footerComponent?: React.ReactNode;
123
- flatListProps?: FlatListProps<any>;
124
- }
112
+ screen: Screen;
113
+ options: {
114
+ title: string;
115
+ surface?: boolean;
116
+ };
117
+ snapPoint?: '30%' | '50%' | '70%' | '90%' | 'content';
118
+ surface?: boolean;
119
+ onDismiss?: (type?: string) => void;
120
+ barrierDismissible?: boolean;
121
+ draggable?: boolean;
122
+ dragOnContent?: boolean;
123
+ };
125
124
 
126
125
  export type NavigationButtonProps = {
127
126
  icon: string;
@@ -165,9 +164,8 @@ export interface HeaderBackProps extends NavigationButtonProps {
165
164
 
166
165
  export type HeaderBackgroundProps = {
167
166
  image?: string | null;
168
- backgroundColor?: string | null;
169
167
  animatedValue?: Animated.Value;
170
- useBorder?: boolean;
168
+ useSurface?: boolean;
171
169
  };
172
170
 
173
171
  export type TitleCustomProps = {
@@ -223,4 +221,5 @@ export type FloatingButtonProps = {
223
221
  export type AnimatedHeader = {
224
222
  type: 'default' | 'surface';
225
223
  component?: (props?: any) => React.ReactElement;
224
+ headerTitle?: (props?: any) => React.ReactElement;
226
225
  };
@@ -12,8 +12,7 @@ import {
12
12
  } from './Components';
13
13
  import {NavigationOptions, Theme} from './types';
14
14
  import {Colors} from '../Consts';
15
- import {Platform} from 'react-native';
16
- const isIOS = Platform.OS === 'ios';
15
+
17
16
  /**
18
17
  * default options for stack screen
19
18
  */
@@ -101,11 +100,7 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
101
100
  ...options,
102
101
  headerTintColor: theme.colors.text.default,
103
102
  headerBackground: () => (
104
- <HeaderBackground
105
- image={null}
106
- backgroundColor={theme.colors.background.surface}
107
- useBorder={true}
108
- />
103
+ <HeaderBackground image={null} useSurface={true} />
109
104
  ),
110
105
  };
111
106
  } else {
@@ -142,22 +137,6 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
142
137
  };
143
138
  };
144
139
 
145
- const getAccessibilityID = (
146
- key = '',
147
- override: string | undefined = undefined,
148
- ) => {
149
- if (isIOS) {
150
- return {
151
- accessible: true,
152
- testID: override || key,
153
- };
154
- } else {
155
- return {
156
- accessibilityLabel: override || key,
157
- };
158
- }
159
- };
160
-
161
140
  const formatNameLength = (name = '') => {
162
141
  let formattedName = name;
163
142
  if (formattedName.length > 100) {
@@ -171,5 +150,4 @@ export {
171
150
  getModalOptions,
172
151
  getOptions,
173
152
  formatNameLength,
174
- getAccessibilityID,
175
153
  };
package/Button/index.tsx CHANGED
@@ -58,7 +58,7 @@ export interface ButtonProps extends TouchableOpacityProps {
58
58
  /**
59
59
  * If true, the icon of button will use the tint color provided by its container.
60
60
  */
61
- useTintColor?: boolean;
61
+ tintColor?: string;
62
62
 
63
63
  /**
64
64
  * If true, the icon of button will use be show indicator loading.
@@ -76,7 +76,7 @@ export interface ButtonProps extends TouchableOpacityProps {
76
76
  const Button: FC<ButtonProps> = ({
77
77
  type = 'primary',
78
78
  size = 'large',
79
- useTintColor = true,
79
+ tintColor = null,
80
80
  full = true,
81
81
  iconRight,
82
82
  iconLeft,
@@ -231,7 +231,7 @@ const Button: FC<ButtonProps> = ({
231
231
  const renderLeading = () => {
232
232
  const iconSize = getIconSize();
233
233
  const marginRight = getIconSpace();
234
- const color = useTintColor ? getTextColor() : undefined;
234
+ const color = tintColor ?? getTextColor();
235
235
 
236
236
  if (loading) {
237
237
  return (
@@ -245,7 +245,7 @@ const Button: FC<ButtonProps> = ({
245
245
  borderRadius: Spacing.M,
246
246
  },
247
247
  ]}>
248
- <Loader type="spinner" color={color} />
248
+ <Loader type="spinner" color={getTextColor()} />
249
249
  </View>
250
250
  );
251
251
  }
@@ -266,7 +266,7 @@ const Button: FC<ButtonProps> = ({
266
266
  * render trailing
267
267
  */
268
268
  const renderTrailing = () => {
269
- const color = useTintColor ? getTextColor() : undefined;
269
+ const color = tintColor ?? getTextColor();
270
270
  const marginLeft = getIconSpace();
271
271
 
272
272
  if (iconRight) {
package/Icon/index.tsx CHANGED
@@ -33,6 +33,7 @@ const Icon: React.FC<IconProps> = ({
33
33
  loading={false}
34
34
  source={getIconSource()}
35
35
  style={[style, {width: size, height: size}]}
36
+ resizeMode='contain'
36
37
  {...tintColorProps}
37
38
  />
38
39
  );
@@ -31,7 +31,7 @@ const InputDropDown = ({
31
31
  hintText,
32
32
  ...props
33
33
  }: InputDropDownProps) => {
34
- const {theme} = useContext(ApplicationContext);
34
+ // const {theme} = useContext(ApplicationContext);
35
35
  const full = !!value || !!placeholder;
36
36
 
37
37
  const renderIcon = (color: string | undefined) => {
@@ -76,7 +76,6 @@ const InputMoney = forwardRef(
76
76
  clear: onClearText,
77
77
  focus: () => inputRef.current?.focus(),
78
78
  blur: () => inputRef.current?.blur(),
79
- changeText: (text: string) => _onChangeText(text),
80
79
  setText: _onChangeText,
81
80
  };
82
81
  });
package/Input/common.tsx CHANGED
@@ -16,13 +16,6 @@ type FloatingViewProps = {
16
16
  style?: ViewStyle;
17
17
  };
18
18
 
19
- export interface InputRef {
20
- focus: () => void;
21
- blur: () => void;
22
- clear: () => void;
23
- setText: (text: string) => void;
24
- }
25
-
26
19
  export const DEFAULT_HEIGHT = scaleSize(104);
27
20
  export const MAX_LENGTH = 300;
28
21
 
package/Input/index.tsx CHANGED
@@ -6,6 +6,13 @@ import InputOTP from './InputOTP';
6
6
  import InputSearch from './InputSearch';
7
7
  import InputTextArea from './InputTextArea';
8
8
 
9
+ export interface InputRef {
10
+ focus: () => void;
11
+ blur: () => void;
12
+ clear: () => void;
13
+ setText: (text: string) => void;
14
+ }
15
+
9
16
  export interface InputProps extends TextInputProps {
10
17
  /**
11
18
  * Optional. Defines the size of the Input component.