@momo-kits/foundation 1.0.12 → 1.0.13

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.
package/Icon/index.tsx CHANGED
@@ -20,6 +20,7 @@ const Icon: React.FC<IconProps> = ({source, size, color, style = {}}) => {
20
20
 
21
21
  return (
22
22
  <Image
23
+ loading={false}
23
24
  source={getIconSource()}
24
25
  style={[style, {width: size, height: size}]}
25
26
  tintColor={color ?? theme.colors.text.default}
package/Image/index.tsx CHANGED
@@ -10,11 +10,12 @@ import {FastImagePropsWithoutStyle} from './types';
10
10
 
11
11
  export interface ImageProps extends FastImagePropsWithoutStyle {
12
12
  style?: StyleProp<ViewStyle>;
13
+ loading?: boolean;
13
14
  }
14
15
 
15
16
  const Image: React.FC<ImageProps> = ({style, source, ...rest}) => {
16
17
  const {theme} = useContext(ApplicationContext);
17
- const [loading, setLoading] = useState(typeof source === 'object');
18
+ const [loading, setLoading] = useState(rest.loading);
18
19
  const [fail, setFail] = useState(false);
19
20
 
20
21
  /**
@@ -54,7 +55,7 @@ const Image: React.FC<ImageProps> = ({style, source, ...rest}) => {
54
55
  style={styles.image}
55
56
  onLoad={() => {
56
57
  setFail(false);
57
- setLoading(true);
58
+ setLoading(rest.loading);
58
59
  }}
59
60
  onLoadEnd={() => setLoading(false)}
60
61
  onError={() => setFail(true)}
@@ -64,4 +65,7 @@ const Image: React.FC<ImageProps> = ({style, source, ...rest}) => {
64
65
  );
65
66
  };
66
67
 
68
+ Image.defaultProps = {
69
+ loading: true,
70
+ };
67
71
  export {Image};
@@ -7,16 +7,12 @@ import {
7
7
  View,
8
8
  } from 'react-native';
9
9
  import {InputSearchProps} from './index';
10
- import {getBorderColor} from './common';
11
10
  import {ApplicationContext} from '../Navigation';
12
11
  import styles from './styles';
13
12
  import {Icon} from '../Icon';
14
- import {Image} from '../Image';
15
13
  import {Text} from '../Text';
16
14
 
17
15
  const InputSearch: FC<InputSearchProps> = ({
18
- errorMessage,
19
- disabled,
20
16
  placeholder,
21
17
  onFocus,
22
18
  onBlur,
@@ -27,6 +23,7 @@ const InputSearch: FC<InputSearchProps> = ({
27
23
  buttonText = 'Hủy',
28
24
  showButtonText = true,
29
25
  showIcon = true,
26
+ showBorder = true,
30
27
  style,
31
28
  ...props
32
29
  }) => {
@@ -54,20 +51,25 @@ const InputSearch: FC<InputSearchProps> = ({
54
51
  onChangeText?.(text);
55
52
  };
56
53
 
54
+ const getBorderColor = () => {
55
+ let borderColor = showBorder
56
+ ? theme.colors.border.default
57
+ : theme.colors.background.surface;
58
+
59
+ if (focused) {
60
+ borderColor = theme.colors.primary;
61
+ }
62
+
63
+ return {borderColor};
64
+ };
65
+
57
66
  const renderInputView = () => {
58
- const disabledColor = theme.colors.text.disable;
59
67
  let textColor = theme.colors.text.default;
60
68
  let placeholderColor = theme.colors.text.hint;
61
69
 
62
- if (disabled) {
63
- textColor = disabledColor;
64
- placeholderColor = disabledColor;
65
- iconTintColor = disabledColor;
66
- }
67
70
  return (
68
71
  <TextInput
69
72
  {...props}
70
- editable={!disabled}
71
73
  textAlignVertical="top"
72
74
  ref={inputRef}
73
75
  style={[
@@ -112,7 +114,11 @@ const InputSearch: FC<InputSearchProps> = ({
112
114
  },
113
115
  ]}
114
116
  />
115
- <Icon color={iconTintColor} source={icon} />
117
+ <Icon
118
+ color={iconTintColor}
119
+ source={icon}
120
+ style={styles.iconSearchInput}
121
+ />
116
122
  </View>
117
123
  )}
118
124
  </View>
@@ -122,9 +128,11 @@ const InputSearch: FC<InputSearchProps> = ({
122
128
  <View style={[style, styles.searchInputContainer]}>
123
129
  <View
124
130
  style={[
125
- getBorderColor(focused, errorMessage, disabled),
131
+ getBorderColor(),
126
132
  styles.searchInputWrapper,
127
- {backgroundColor: theme.colors.background.surface},
133
+ {
134
+ backgroundColor: theme.colors.background.surface,
135
+ },
128
136
  ]}>
129
137
  <Icon
130
138
  source={'navigation_search'}
package/Input/index.tsx CHANGED
@@ -20,17 +20,21 @@ type InputPropsWithoutSizeAndIcon = Omit<
20
20
  InputProps,
21
21
  'size' | 'icon' | 'iconColor'
22
22
  >;
23
- type InputPropsWithoutRequiredAndSize = Omit<InputProps, 'required' | 'size'>;
23
+ type InputPropsOmitForSearch = Omit<
24
+ InputProps,
25
+ 'required' | 'size' | 'errorMessage' | 'disabled'
26
+ >;
24
27
  type InputPropsWithoutPlaceholder = Omit<InputProps, 'placeholder'>;
25
28
 
26
29
  export interface InputTextAreaProps extends InputPropsWithoutSizeAndIcon {
27
30
  height?: number;
28
31
  }
29
32
 
30
- export interface InputSearchProps extends InputPropsWithoutRequiredAndSize {
33
+ export interface InputSearchProps extends InputPropsOmitForSearch {
31
34
  buttonText?: string;
32
35
  showButtonText?: boolean;
33
36
  showIcon?: boolean;
37
+ showBorder?: boolean;
34
38
  }
35
39
 
36
40
  export interface InputMoneyProps extends InputPropsWithoutPlaceholder {}
package/Input/styles.ts CHANGED
@@ -104,8 +104,6 @@ export default StyleSheet.create({
104
104
  alignItems: 'center',
105
105
  },
106
106
  iconSearchInput: {
107
- width: 24,
108
- height: 24,
109
107
  marginLeft: Spacing.S,
110
108
  },
111
109
  searchInputContainer: {flexDirection: 'row', alignItems: 'center'},
@@ -1,10 +1,11 @@
1
- import {KeyboardAvoidingView, Platform, ScrollView, View} from 'react-native';
1
+ import {Animated, KeyboardAvoidingView, Platform, View} from 'react-native';
2
2
  import {useHeaderHeight} from '@react-navigation/stack';
3
3
  import {SafeAreaView} from 'react-native-safe-area-context';
4
4
  import React from 'react';
5
5
  import {ScreenContainerProps} from '../Navigation/types';
6
6
  import {Spacing, Styles} from '../Consts';
7
7
  import {ScreenSection, validateChildren} from './index';
8
+ import {Image} from '../Image';
8
9
 
9
10
  const ScreenContainer: React.FC<ScreenContainerProps> = ({
10
11
  children,
@@ -12,11 +13,12 @@ const ScreenContainer: React.FC<ScreenContainerProps> = ({
12
13
  enableKeyboardAvoidingView,
13
14
  scrollable,
14
15
  scrollViewProps,
16
+ headerImage,
15
17
  }) => {
16
18
  let Component: any = View;
17
19
  const headerHeight = useHeaderHeight();
18
20
  if (scrollable) {
19
- Component = ScrollView;
21
+ Component = Animated.ScrollView;
20
22
  }
21
23
 
22
24
  /**
@@ -52,6 +54,14 @@ const ScreenContainer: React.FC<ScreenContainerProps> = ({
52
54
  android: undefined,
53
55
  })}>
54
56
  <Component {...scrollViewProps} style={Styles.flex}>
57
+ {headerImage && (
58
+ <Image
59
+ source={{
60
+ uri: headerImage,
61
+ }}
62
+ style={{width: '100%', height: 300}}
63
+ />
64
+ )}
55
65
  {renderContent()}
56
66
  </Component>
57
67
  </KeyboardAvoidingView>
@@ -10,11 +10,10 @@ const BottomTab: FC<BottomTabProps> = ({tabs}) => {
10
10
  <Tab.Navigator>
11
11
  {tabs.map((item, index) => {
12
12
  return (
13
- // @ts-ignore
14
13
  <Tab.Screen
15
14
  key={`${item.label}-${index}`}
16
15
  name={item.label}
17
- component={item.component}
16
+ component={item.screen}
18
17
  options={{
19
18
  tabBarLabel: item.label,
20
19
  tabBarBadge: item?.badgeLabel,
@@ -1,5 +1,6 @@
1
1
  import React, {useContext} from 'react';
2
2
  import {
3
+ Animated,
3
4
  DeviceEventEmitter,
4
5
  StatusBar,
5
6
  StyleSheet,
@@ -47,7 +48,6 @@ const styles = StyleSheet.create({
47
48
  marginLeft: Spacing.S,
48
49
  padding: Spacing.XS,
49
50
  height: 28,
50
- borderWidth: 0.5,
51
51
  borderRadius: 14,
52
52
  borderColor: '#00000066',
53
53
  justifyContent: 'center',
@@ -62,15 +62,19 @@ const styles = StyleSheet.create({
62
62
  headerLeft: {
63
63
  marginLeft: 12,
64
64
  },
65
+ title: {fontSize: 15, lineHeight: 22, fontWeight: '600'},
65
66
  });
66
67
 
67
- const HeaderTitle = (props: any) => {
68
+ const HeaderTitle: React.FC<any> = props => {
69
+ const opacity = props.animatedValue?.interpolate({
70
+ inputRange: [0, 200],
71
+ outputRange: [0, 1],
72
+ extrapolate: 'clamp',
73
+ });
68
74
  return (
69
- <Text
75
+ <Animated.Text
70
76
  {...props}
71
- typography="header_default"
72
- weight="bold"
73
- color={props.tintColor}
77
+ style={[styles.title, {opacity, color: props.tintColor}]}
74
78
  />
75
79
  );
76
80
  };
@@ -98,19 +102,28 @@ const HeaderLeft: React.FC<any> = ({tintColor}) => {
98
102
  const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
99
103
  image,
100
104
  backgroundColor,
105
+ animatedValue,
101
106
  }) => {
102
107
  const {theme} = useContext(ApplicationContext);
103
108
  let headerImage = theme.assets?.headerBackground;
104
109
  if (image === null) {
105
110
  headerImage = undefined;
106
111
  }
112
+ const opacity = animatedValue?.interpolate({
113
+ inputRange: [0, 200],
114
+ outputRange: [0, 1],
115
+ extrapolate: 'clamp',
116
+ });
107
117
  return (
108
- <View
118
+ <Animated.View
109
119
  style={[
110
120
  Styles.flex,
111
121
  {
112
122
  backgroundColor: backgroundColor ?? theme.colors.background.default,
113
123
  overflow: 'hidden',
124
+ borderBottomWidth: headerImage ? 0 : 1,
125
+ borderColor: theme.colors.border.default,
126
+ opacity,
114
127
  },
115
128
  ]}>
116
129
  <StatusBar
@@ -119,7 +132,7 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
119
132
  {headerImage && (
120
133
  <Image style={styles.headerBackground} source={{uri: headerImage}} />
121
134
  )}
122
- </View>
135
+ </Animated.View>
123
136
  );
124
137
  };
125
138
 
@@ -193,15 +206,13 @@ const HeaderToolkitAction: React.FC<any> = ({tintColor}) => {
193
206
 
194
207
  return (
195
208
  <View style={styles.headerRightButton}>
196
- <NavigationButton
197
- icon="addFavorite"
198
- tintColor={tintColor}
199
- onPress={() => {}}
200
- />
201
209
  <View
202
210
  style={[
203
211
  styles.toolkitContainer,
204
- {backgroundColor: backgroundColor ?? '#00000066'},
212
+ {
213
+ backgroundColor: backgroundColor ?? '#00000066',
214
+ borderWidth: backgroundColor ? 0.5 : 0,
215
+ },
205
216
  ]}>
206
217
  <TouchableOpacity>
207
218
  <Icon color={tintColor} source="navigation_more_horiz" size={20} />
@@ -23,7 +23,7 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
23
23
  styles.container,
24
24
  {
25
25
  backgroundColor: backgroundColor ?? '#00000066',
26
- borderWidth: useBorder ? 0.5 : 0,
26
+ borderWidth: useBorder && backgroundColor ? 0.5 : 0,
27
27
  },
28
28
  ]}
29
29
  onPress={onPress}>
@@ -22,8 +22,9 @@ const StackScreen: React.FC<any> = props => {
22
22
  if (options) {
23
23
  params.navigation.setOptions(options);
24
24
  }
25
- }, [navigation, options]);
25
+ }, [options]);
26
26
 
27
+ console.log(params);
27
28
  return <Component {...params} />;
28
29
  };
29
30
 
@@ -1,5 +1,5 @@
1
- import {ScrollViewProps, ViewProps} from 'react-native';
2
- import React, {ComponentType, ReactElement} from 'react';
1
+ import {Animated, ScrollViewProps, ViewProps} from 'react-native';
2
+ import React from 'react';
3
3
  import Navigator from './Navigator';
4
4
 
5
5
  export type Theme = {
@@ -73,6 +73,7 @@ export interface ScreenContainerProps extends ViewProps {
73
73
  enableKeyboardAvoidingView?: boolean;
74
74
  scrollable: boolean;
75
75
  scrollViewProps?: ScrollViewProps;
76
+ headerImage?: string;
76
77
  }
77
78
 
78
79
  export type ScreenParams = {
@@ -107,11 +108,13 @@ export type NavigationOptions = {
107
108
  headerTitleAlign?: 'left' | 'center';
108
109
  customTitle?: TitleCustomProps;
109
110
  headerRight?: (props?: any) => React.ReactElement;
111
+ animatedValue?: Animated.Value;
110
112
  };
111
113
 
112
114
  export type HeaderBackgroundProps = {
113
115
  image?: string | null;
114
116
  backgroundColor?: string | null;
117
+ animatedValue?: Animated.Value;
115
118
  };
116
119
 
117
120
  export type TitleCustomProps = {
@@ -128,7 +131,7 @@ export type BottomTabItemProps = {
128
131
  icon: string;
129
132
  showDot?: boolean;
130
133
  badgeLabel?: string;
131
- component: ComponentType<any> | undefined;
134
+ screen: React.ComponentType<any>;
132
135
  };
133
136
 
134
137
  export type BottomTabProps = {
@@ -73,43 +73,58 @@ const getModalOptions = (): StackNavigationOptions => {
73
73
  };
74
74
 
75
75
  const getOptions = (params: NavigationOptions, theme: Theme) => {
76
- let surfaceTheme: {};
77
- let titleTheme: {};
76
+ let backgroundProps = {};
77
+ let titleProps = {};
78
+ let options = {};
78
79
 
79
80
  if (params.surface == true) {
80
- surfaceTheme = {
81
- headerBackground: () => (
82
- <HeaderBackground
83
- image={null}
84
- backgroundColor={theme.colors.background.surface}
85
- />
86
- ),
81
+ options = {
82
+ ...options,
87
83
  ...getTintColor({
88
84
  ...theme,
89
85
  assets: {...theme.assets, headerBackground: undefined},
90
86
  }),
91
87
  };
92
- } else {
93
- surfaceTheme = {
94
- headerBackground: HeaderBackground,
95
- ...getTintColor(theme),
88
+ backgroundProps = {
89
+ ...backgroundProps,
90
+ image: null,
91
+ backgroundColor: theme.colors.background.surface,
96
92
  };
93
+ } else {
94
+ backgroundProps = {};
95
+ options = {...options, ...getTintColor(theme)};
96
+ }
97
+
98
+ if (params.animatedValue) {
99
+ backgroundProps = {...backgroundProps, animatedValue: params.animatedValue};
100
+ titleProps = {...titleProps, animatedValue: params.animatedValue};
101
+ options = {...options, headerTransparent: true};
102
+ } else {
103
+ options = {...options, headerTransparent: false};
97
104
  }
98
105
 
99
106
  if (params.customTitle) {
100
- titleTheme = {
107
+ options = {
108
+ ...options,
101
109
  headerTitleAlign: 'left',
102
110
  headerTitle: (props: any) => {
103
111
  return <HeaderCustom {...params.customTitle} {...props} />;
104
112
  },
105
113
  };
106
114
  } else {
107
- titleTheme = {
108
- headerTitle: HeaderTitle,
115
+ options = {
116
+ ...options,
117
+ headerTitle: (props: any) => {
118
+ return <HeaderTitle {...titleProps} {...props} />;
119
+ },
109
120
  };
110
121
  }
111
122
 
112
- return {...params, ...surfaceTheme, ...titleTheme};
123
+ return {
124
+ ...params,
125
+ ...options,
126
+ headerBackground: () => <HeaderBackground {...backgroundProps} />,
127
+ };
113
128
  };
114
129
 
115
130
  export {getStackOptions, getDialogOptions, getModalOptions, getOptions};
@@ -3,7 +3,7 @@ import {StyleSheet, TouchableOpacity, View} from 'react-native';
3
3
  import {PopupPromotionProps} from './types';
4
4
  import {ApplicationContext} from '../Navigation';
5
5
  import {Image} from '../Image';
6
- import {Radius} from '../Consts';
6
+ import {Radius, Spacing} from '../Consts';
7
7
  import {Icon} from '../Icon';
8
8
 
9
9
  const PopupPromotion: React.FC<PopupPromotionProps> = ({image, onClose}) => {
@@ -55,11 +55,10 @@ const styles = StyleSheet.create({
55
55
  aspectRatio: 0.72,
56
56
  },
57
57
  iconCloseContainer: {
58
- position: 'absolute',
59
58
  width: '100%',
60
59
  flexDirection: 'row',
61
60
  justifyContent: 'center',
62
- bottom: -36,
61
+ marginTop: Spacing.L,
63
62
  },
64
63
  iconClose: {
65
64
  width: 20,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {