@momo-kits/foundation 1.0.0 → 1.0.3

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 (68) hide show
  1. package/Button/index.tsx +118 -171
  2. package/CheckBox/index.tsx +63 -0
  3. package/CheckBox/styles.ts +14 -0
  4. package/CheckBox/types.ts +10 -0
  5. package/Consts/colors+spacing+radius.ts +6 -4
  6. package/Consts/index.ts +4 -73
  7. package/Consts/styles.ts +1 -1
  8. package/Consts/theme.ts +121 -0
  9. package/ContentLoader/index.tsx +9 -13
  10. package/Icon/index.tsx +14 -11
  11. package/Icon/types.ts +1 -4
  12. package/IconButton/index.tsx +67 -67
  13. package/IconButton/styles.ts +19 -0
  14. package/Image/index.tsx +22 -21
  15. package/Image/types.ts +0 -1
  16. package/Input/Input.tsx +161 -0
  17. package/Input/TextArea.tsx +162 -0
  18. package/Input/common.tsx +70 -0
  19. package/Input/index.tsx +26 -0
  20. package/Input/styles.ts +92 -0
  21. package/Layout/GridSystem.tsx +109 -0
  22. package/Layout/ScreenContainer.tsx +84 -0
  23. package/Layout/ScreenSection.tsx +117 -0
  24. package/Layout/SectionItem.tsx +63 -0
  25. package/Layout/index.ts +11 -5
  26. package/Layout/types.ts +6 -33
  27. package/Layout/utils.ts +69 -23
  28. package/Navigation/Components.tsx +42 -9
  29. package/Navigation/ModalScreen.tsx +65 -40
  30. package/Navigation/Navigation.ts +5 -2
  31. package/Navigation/NavigationButton.tsx +10 -5
  32. package/Navigation/NavigationContainer.tsx +17 -13
  33. package/Navigation/StackScreen.tsx +8 -2
  34. package/Navigation/index.ts +5 -3
  35. package/Navigation/types.ts +72 -38
  36. package/Navigation/utils.tsx +37 -14
  37. package/Playground/index.tsx +132 -0
  38. package/Playground/styles.ts +16 -0
  39. package/Playground/types.ts +15 -0
  40. package/Popup/PopupNotify.tsx +210 -0
  41. package/Popup/PopupPromotion.tsx +66 -0
  42. package/Popup/index.tsx +4 -0
  43. package/Popup/types.ts +23 -0
  44. package/Radio/index.tsx +42 -0
  45. package/Radio/styles.ts +12 -0
  46. package/Radio/types.ts +7 -0
  47. package/Switch/index.tsx +35 -0
  48. package/Switch/styles.ts +23 -0
  49. package/Switch/types.ts +5 -0
  50. package/Text/index.tsx +36 -118
  51. package/Text/styles.ts +24 -23
  52. package/Text/types.ts +5 -12
  53. package/index.ts +21 -4
  54. package/package.json +3 -4
  55. package/Button/types.ts +0 -18
  56. package/CheckBox/index.js +0 -74
  57. package/CheckBox/styles.js +0 -3
  58. package/IconButton/types.ts +0 -17
  59. package/Layout/Row.tsx +0 -42
  60. package/Layout/Screen.tsx +0 -68
  61. package/Layout/Section.tsx +0 -30
  62. package/Layout/View.tsx +0 -84
  63. package/Layout/styles.ts +0 -24
  64. package/Navigation/ScreenContainer.tsx +0 -38
  65. package/SizedBox/index.js +0 -23
  66. package/SizedBox/styles.js +0 -7
  67. package/TextInput/index.js +0 -225
  68. package/TextInput/styles.js +0 -55
package/Button/index.tsx CHANGED
@@ -1,98 +1,87 @@
1
- import React, {useContext} from 'react';
1
+ import React, {FC, useContext} from 'react';
2
2
  import {
3
- ActivityIndicator,
4
3
  StyleSheet,
5
4
  TouchableOpacity,
5
+ TouchableOpacityProps,
6
6
  View,
7
7
  } from 'react-native';
8
- import {NavigationContext, Colors, Styles, Text} from '../index';
8
+ import {ApplicationContext} from '../Navigation';
9
+ import {Text} from '../Text';
10
+ import {Typography} from '../Text/types';
11
+ import {Colors} from '../Consts';
9
12
  import styles from './styles';
13
+ import {Image} from '../Image';
14
+
15
+ export interface ButtonProps extends TouchableOpacityProps {
16
+ type?:
17
+ | 'primary'
18
+ | 'secondary'
19
+ | 'tonal'
20
+ | 'outline'
21
+ | 'danger'
22
+ | 'text'
23
+ | 'disabled';
24
+ size?: 'large' | 'medium' | 'small';
25
+ full?: boolean;
26
+ iconRight?: string;
27
+ iconLeft?: string;
28
+ title: string;
29
+ useTintColor?: boolean;
30
+ }
31
+
32
+ const Button: FC<ButtonProps> = ({
33
+ type,
34
+ size,
35
+ useTintColor,
36
+ full,
37
+ iconRight,
38
+ iconLeft,
39
+ title,
40
+ onPress,
41
+ ...rest
42
+ }) => {
43
+ const {theme} = useContext(ApplicationContext);
10
44
 
11
- const Index = props => {
12
- const {theme} = useContext(NavigationContext);
13
- const {
14
- style,
15
- textStyle,
16
- type,
17
- size,
18
- full,
19
- disabled,
20
- leading,
21
- trailing,
22
- loading,
23
- children,
24
- } = props;
25
-
26
- /**
27
- * export size style
28
- */
29
45
  const getSizeStyle = () => {
30
- switch (size) {
31
- case 'large':
32
- return styles.large;
33
- case 'medium':
34
- return styles.medium;
35
- case 'small':
36
- return styles.small;
37
-
38
- default:
39
- return styles.large;
40
- }
46
+ const styleSheet: {[key: string]: any} = styles;
47
+ return styleSheet[size ?? 'small'];
41
48
  };
42
49
 
43
- /**
44
- * export type style
45
- */
46
50
  const getTypeStyle = () => {
47
- if (disabled) {
48
- return {
49
- backgroundColor: theme.colors.border,
50
- };
51
- }
52
51
  switch (type) {
52
+ case 'disabled':
53
+ return {
54
+ backgroundColor: theme.colors.background.disable,
55
+ };
53
56
  case 'primary':
54
57
  return {backgroundColor: theme.colors.primary};
55
58
  case 'secondary':
56
59
  return {
57
- backgroundColor: theme.colors.card,
60
+ backgroundColor: theme.colors.background.surface,
58
61
  borderWidth: 1,
59
- borderColor: theme.colors.border,
62
+ borderColor: theme.colors.border.default,
60
63
  };
61
64
  case 'outline':
62
65
  return {
63
- backgroundColor: theme.colors.card,
66
+ backgroundColor: theme.colors.background.surface,
64
67
  borderWidth: 1,
65
68
  borderColor: theme.colors.primary,
66
69
  };
70
+ case 'tonal':
71
+ return {
72
+ backgroundColor: theme.colors.background.tonal,
73
+ };
74
+ case 'danger':
75
+ return {
76
+ backgroundColor: theme.colors.error.primary,
77
+ };
67
78
  case 'text':
68
79
  return {};
69
-
70
80
  default:
71
81
  return {backgroundColor: theme.colors.primary};
72
82
  }
73
83
  };
74
84
 
75
- /**
76
- * export loading color
77
- */
78
- const getLoadingColor = () => {
79
- if (disabled) {
80
- return theme.colors.textSecondary;
81
- }
82
- switch (type) {
83
- case 'primary':
84
- return Colors.black_01;
85
- case 'secondary':
86
- return theme.colors.text;
87
- case 'outline':
88
- return theme.colors.primary;
89
- case 'text':
90
- return theme.colors.primary;
91
- default:
92
- return theme.colors.primary;
93
- }
94
- };
95
-
96
85
  /**
97
86
  * export icon size
98
87
  */
@@ -128,109 +117,74 @@ const Index = props => {
128
117
  /**
129
118
  * export typography style
130
119
  */
131
- const getTypography = () => {
120
+ const getTypography = (): Typography => {
132
121
  switch (size) {
133
122
  case 'large':
134
- return 'h4';
123
+ return 'action_default';
135
124
  case 'medium':
136
- return 'title';
125
+ return 'action_s';
137
126
  case 'small':
138
- return 'subtitle';
127
+ return 'action_xs';
139
128
 
140
129
  default:
141
- return 'h4';
130
+ return 'action_default';
142
131
  }
143
132
  };
144
133
 
145
- /**
146
- * render Text
147
- */
148
- const renderText = () => {
149
- const typography = getTypography();
150
- if (disabled) {
151
- return (
152
- <Text
153
- typography={typography}
154
- weight="bold"
155
- type="secondary"
156
- numberOfLines={1}
157
- style={textStyle}>
158
- {children}
159
- </Text>
160
- );
161
- }
134
+ const getTextColor = (): string => {
162
135
  switch (type) {
136
+ case 'disabled':
137
+ return theme.colors.text.disable;
163
138
  case 'primary':
164
- return (
165
- <Text
166
- typography={typography}
167
- weight="bold"
168
- color="white"
169
- numberOfLines={1}
170
- style={textStyle}>
171
- {children}
172
- </Text>
173
- );
139
+ return Colors.black_01;
174
140
  case 'secondary':
175
- return (
176
- <Text
177
- typography={typography}
178
- weight="bold"
179
- numberOfLines={1}
180
- style={textStyle}>
181
- {children}
182
- </Text>
183
- );
141
+ return theme.colors.text.default;
184
142
  case 'outline':
185
- return (
186
- <Text
187
- typography={typography}
188
- weight="bold"
189
- color="primary"
190
- numberOfLines={1}
191
- style={textStyle}>
192
- {children}
193
- </Text>
194
- );
143
+ return theme.colors.primary;
144
+ case 'tonal':
145
+ return theme.colors.primary;
146
+ case 'danger':
147
+ return Colors.black_01;
195
148
  case 'text':
196
- return (
197
- <Text
198
- typography={typography}
199
- type="secondary"
200
- weight="bold"
201
- numberOfLines={1}
202
- style={textStyle}>
203
- {children}
204
- </Text>
205
- );
206
-
149
+ return theme.colors.primary;
207
150
  default:
208
- return (
209
- <Text
210
- typography={typography}
211
- weight="bold"
212
- numberOfLines={1}
213
- style={textStyle}>
214
- {children}
215
- </Text>
216
- );
151
+ return Colors.black_01;
217
152
  }
218
153
  };
219
154
 
155
+ /**
156
+ * render title
157
+ */
158
+ const renderTitle = () => {
159
+ const typography = getTypography();
160
+ const color = getTextColor();
161
+ return (
162
+ <Text typography={typography} color={color} numberOfLines={1}>
163
+ {title}
164
+ </Text>
165
+ );
166
+ };
167
+
220
168
  /**
221
169
  * render leading
222
170
  */
223
171
  const renderLeading = () => {
224
- if (leading) {
172
+ if (iconLeft) {
225
173
  const iconSize = getIconSize();
226
174
  const marginRight = getIconSpace();
175
+ const color = useTintColor ? getTextColor() : undefined;
176
+
227
177
  return (
228
178
  <View
229
179
  style={[
230
180
  styles.leading,
231
181
  {width: iconSize, height: iconSize, marginRight},
232
182
  ]}>
233
- {leading}
183
+ <Image
184
+ tintColor={color}
185
+ source={{uri: iconLeft}}
186
+ style={{width: iconSize, height: iconSize}}
187
+ />
234
188
  </View>
235
189
  );
236
190
  }
@@ -241,16 +195,8 @@ const Index = props => {
241
195
  */
242
196
  const renderTrailing = () => {
243
197
  const marginLeft = getIconSpace();
244
- if (loading) {
245
- return (
246
- <View style={[styles.trailing, {marginLeft}]}>
247
- <View style={Styles.flexCenter}>
248
- <ActivityIndicator color={getLoadingColor()} />
249
- </View>
250
- </View>
251
- );
252
- }
253
- if (trailing) {
198
+ const color = useTintColor ? getTextColor() : undefined;
199
+ if (iconRight) {
254
200
  const iconSize = getIconSize();
255
201
  return (
256
202
  <View
@@ -258,7 +204,11 @@ const Index = props => {
258
204
  styles.trailing,
259
205
  {width: iconSize, height: iconSize, marginLeft},
260
206
  ]}>
261
- {trailing}
207
+ <Image
208
+ tintColor={color}
209
+ source={{uri: iconRight}}
210
+ style={{width: iconSize, height: iconSize}}
211
+ />
262
212
  </View>
263
213
  );
264
214
  }
@@ -268,40 +218,37 @@ const Index = props => {
268
218
  getSizeStyle(),
269
219
  getTypeStyle(),
270
220
  full && {width: '100%'},
271
- style,
272
221
  ]);
273
222
 
223
+ const onPressButton = (e: any) => {
224
+ if (type === 'disabled') {
225
+ return () => {};
226
+ }
227
+ onPress?.(e);
228
+ };
229
+
230
+ const activeOpacity = type === 'disabled' ? 0.75 : 0.5;
231
+
274
232
  return (
275
- <TouchableOpacity {...props} style={buttonStyle}>
233
+ <TouchableOpacity
234
+ {...rest}
235
+ activeOpacity={activeOpacity}
236
+ onPress={onPressButton}
237
+ style={buttonStyle}>
276
238
  {renderLeading()}
277
- {renderText()}
239
+ {renderTitle()}
278
240
  {renderTrailing()}
279
241
  </TouchableOpacity>
280
242
  );
281
243
  };
282
244
 
283
- // Index.propTypes = {
284
- // textStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
285
- // type: PropTypes.oneOf(['primary', 'secondary','' ,'outline', 'text']),
286
- // size: PropTypes.oneOf(['large', 'medium', 'small']),
287
- // full: PropTypes.bool,
288
- // disabled: PropTypes.bool,
289
- // leading: PropTypes.element,
290
- // trailing: PropTypes.element,
291
- // loading: PropTypes.bool,
292
- // children: PropTypes.string,
293
- // };
294
-
295
- Index.defaultProps = {
296
- textStyle: {},
245
+ Button.defaultProps = {
297
246
  type: 'primary',
298
247
  size: 'large',
299
248
  full: true,
300
249
  disabled: false,
301
- leading: null,
302
- trailing: null,
303
- loading: false,
304
- children: 'Button',
250
+ title: 'Button',
251
+ useTintColor: true,
305
252
  };
306
253
 
307
- export default Index;
254
+ export {Button};
@@ -0,0 +1,63 @@
1
+ import React, {FC, useContext} from 'react';
2
+ import {TouchableOpacity, View} from 'react-native';
3
+
4
+ import {CheckBoxProps} from './types';
5
+ import {Text} from '@momo-kits/foundation';
6
+ import styles from './styles';
7
+ import Image from 'react-native-fast-image';
8
+ import {ApplicationContext} from '../Navigation';
9
+ import {Colors} from '../Consts';
10
+
11
+ const IC_INDETERMINATED = 'https://img.mservice.com.vn/app/img/kits/minus.png';
12
+ const IC_CHECKED_DEFAULT =
13
+ 'https://img.mservice.com.vn/app/img/kits/checked_ic.png';
14
+ const CheckBox: FC<CheckBoxProps> = props => {
15
+ const {theme} = useContext(ApplicationContext);
16
+ const {value, disabled, onChange, style, label, indeterminated} = props;
17
+
18
+ const haveValue = value || indeterminated;
19
+ let borderColor = haveValue
20
+ ? theme.colors.primary
21
+ : theme.colors.text.default;
22
+ let backgroundColor = haveValue
23
+ ? theme.colors.primary
24
+ : theme.colors.background.surface;
25
+
26
+ let iconSource = value ? IC_CHECKED_DEFAULT : undefined;
27
+
28
+ if (indeterminated) {
29
+ iconSource = IC_INDETERMINATED;
30
+ }
31
+
32
+ if (disabled) {
33
+ borderColor = haveValue
34
+ ? theme.colors.background.disable
35
+ : theme.colors.border.disable;
36
+ backgroundColor = haveValue
37
+ ? theme.colors.background.disable
38
+ : theme.colors.background.surface;
39
+ }
40
+ const checkboxStyle = {borderColor, backgroundColor, borderWidth: 1};
41
+
42
+ const onChangeValue = () => {
43
+ onChange?.(!value);
44
+ };
45
+ return (
46
+ <TouchableOpacity
47
+ activeOpacity={0.8}
48
+ onPress={onChangeValue}
49
+ disabled={disabled}
50
+ style={[style, styles.container]}>
51
+ <View style={[checkboxStyle, styles.checkbox]}>
52
+ <Image style={styles.icon} source={{uri: iconSource}} />
53
+ </View>
54
+ <Text typography={'description_default'}>{label}</Text>
55
+ </TouchableOpacity>
56
+ );
57
+ };
58
+
59
+ CheckBox.defaultProps = {
60
+ disabled: false,
61
+ };
62
+
63
+ export {CheckBox};
@@ -0,0 +1,14 @@
1
+ import {StyleSheet} from 'react-native';
2
+ import {Radius, Spacing} from '../Consts';
3
+
4
+ export default StyleSheet.create({
5
+ checkbox: {
6
+ width: 24,
7
+ height: 24,
8
+ borderRadius: Radius.XS,
9
+ borderWidth: 2,
10
+ marginRight: Spacing.S,
11
+ },
12
+ container: {flexDirection: 'row'},
13
+ icon: {width: 20, height: 20},
14
+ });
@@ -0,0 +1,10 @@
1
+ import {ViewStyle} from 'react-native';
2
+
3
+ export type CheckBoxProps = {
4
+ value: boolean;
5
+ disabled?: boolean;
6
+ label?: string;
7
+ onChange: (value: boolean) => void;
8
+ indeterminated?: boolean;
9
+ style?: ViewStyle;
10
+ };
@@ -144,16 +144,18 @@ const Colors = {
144
144
  red_11: '#fef8f8',
145
145
  };
146
146
  const Spacing = {
147
- XS: 2,
148
- S: 4,
147
+ XXS: 2,
148
+ XS: 4,
149
+ S: 8,
149
150
  M: 12,
150
151
  L: 16,
151
152
  XL: 24,
152
153
  };
153
154
 
154
155
  const Radius = {
155
- XS: 2,
156
- S: 4,
156
+ XXS: 2,
157
+ XS: 4,
158
+ S: 8,
157
159
  M: 12,
158
160
  L: 16,
159
161
  XL: 24,
package/Consts/index.ts CHANGED
@@ -1,76 +1,7 @@
1
- import {Context, Theme} from '../Navigation/types';
1
+ export const GutterSize = 12;
2
+ export const ScreenPadding = 12;
3
+ export const NumberOfColumns = 12;
2
4
 
3
- const defaultTheme: Theme = {
4
- dark: false,
5
- colors: {
6
- background_default: '',
7
- background_surface: '',
8
- background_pressed: '',
9
- background_selected: '',
10
- background_disable: '',
11
- background_primary: '',
12
- background_tonal: '',
13
- text_default: '',
14
- text_secondary: '',
15
- text_hint: '',
16
- text_disable: '',
17
- text_white: '',
18
- text_primary: '',
19
- text_interactive: '',
20
- text_highlight: '',
21
- text_success: '',
22
- text_warning: '',
23
- text_error: '',
24
- border_default: '',
25
- border_disable: '',
26
- border_primary: '',
27
- border_primary_disable: '',
28
- border_error: '',
29
- border_error_disable: '',
30
- border_success: '',
31
- border_success_disable: '',
32
- },
33
- font: 'SFProText',
34
- };
35
-
36
- const defaultDarkTheme: Theme = {
37
- dark: true,
38
- colors: {
39
- background_default: '',
40
- background_surface: '',
41
- background_pressed: '',
42
- background_selected: '',
43
- background_disable: '',
44
- background_primary: '',
45
- background_tonal: '',
46
- text_default: '',
47
- text_secondary: '',
48
- text_hint: '',
49
- text_disable: '',
50
- text_white: '',
51
- text_primary: '',
52
- text_interactive: '',
53
- text_highlight: '',
54
- text_success: '',
55
- text_warning: '',
56
- text_error: '',
57
- border_default: '',
58
- border_disable: '',
59
- border_primary: '',
60
- border_primary_disable: '',
61
- border_error: '',
62
- border_error_disable: '',
63
- border_success: '',
64
- border_success_disable: '',
65
- },
66
- font: 'Raleway',
67
- };
68
-
69
- const defaultContext: Context = {
70
- theme: defaultTheme,
71
- navigator: undefined,
72
- };
73
-
74
- export {defaultContext, defaultTheme, defaultDarkTheme};
75
5
  export * from './colors+spacing+radius';
6
+ export * from './theme';
76
7
  export * from './styles';
package/Consts/styles.ts CHANGED
@@ -117,7 +117,7 @@ const Styles = StyleSheet.create({
117
117
  overflow: 'hidden',
118
118
  justifyContent: 'center',
119
119
  alignItems: 'center',
120
- paddingHorizontal: 8,
120
+ paddingHorizontal: 4,
121
121
  },
122
122
  //text
123
123
  textCenter: {textAlign: 'center'},