@momo-kits/foundation 1.0.0 → 1.0.1

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 (62) hide show
  1. package/ActivityIndicator.tsx +244 -0
  2. package/Button/index.tsx +94 -164
  3. package/Button/types.ts +12 -3
  4. package/CheckBox/index.tsx +57 -0
  5. package/CheckBox/styles.ts +14 -0
  6. package/CheckBox/types.ts +7 -0
  7. package/Consts/colors+spacing+radius.ts +6 -4
  8. package/Consts/index.ts +4 -73
  9. package/Consts/styles.ts +1 -1
  10. package/Consts/theme.ts +65 -0
  11. package/ContentLoader/index.tsx +8 -11
  12. package/Icon/index.tsx +11 -11
  13. package/Icon/types.ts +1 -4
  14. package/IconButton/index.tsx +52 -72
  15. package/IconButton/styles.ts +19 -0
  16. package/IconButton/types.ts +1 -2
  17. package/Image/index.tsx +19 -18
  18. package/Image/types.ts +0 -1
  19. package/Input/TextArea.tsx +202 -0
  20. package/Input/index.tsx +200 -0
  21. package/Input/styles.ts +92 -0
  22. package/Input/types.ts +23 -0
  23. package/Layout/GridSystem.tsx +109 -0
  24. package/Layout/ScreenContainer.tsx +78 -0
  25. package/Layout/ScreenSection.tsx +104 -0
  26. package/Layout/SectionItem.tsx +60 -0
  27. package/Layout/index.ts +11 -5
  28. package/Layout/types.ts +6 -33
  29. package/Layout/utils.ts +55 -23
  30. package/Navigation/Components.tsx +16 -8
  31. package/Navigation/ModalScreen.tsx +35 -25
  32. package/Navigation/Navigation.ts +2 -2
  33. package/Navigation/NavigationButton.tsx +5 -3
  34. package/Navigation/NavigationContainer.tsx +59 -17
  35. package/Navigation/StackScreen.tsx +8 -2
  36. package/Navigation/index.ts +5 -3
  37. package/Navigation/types.ts +53 -36
  38. package/Navigation/utils.tsx +20 -18
  39. package/Radio/index.tsx +34 -0
  40. package/Radio/styles.ts +11 -0
  41. package/Radio/types.ts +7 -0
  42. package/Switch/index.tsx +37 -0
  43. package/Switch/styles.ts +23 -0
  44. package/Switch/types.ts +5 -0
  45. package/Text/index.tsx +36 -120
  46. package/Text/styles.ts +24 -23
  47. package/Text/types.ts +2 -0
  48. package/index.ts +18 -1
  49. package/package.json +1 -1
  50. package/publish.sh +8 -6
  51. package/CheckBox/index.js +0 -74
  52. package/CheckBox/styles.js +0 -3
  53. package/Layout/Row.tsx +0 -42
  54. package/Layout/Screen.tsx +0 -68
  55. package/Layout/Section.tsx +0 -30
  56. package/Layout/View.tsx +0 -84
  57. package/Layout/styles.ts +0 -24
  58. package/Navigation/ScreenContainer.tsx +0 -38
  59. package/SizedBox/index.js +0 -23
  60. package/SizedBox/styles.js +0 -7
  61. package/TextInput/index.js +0 -225
  62. package/TextInput/styles.js +0 -55
package/CheckBox/index.js DELETED
@@ -1,74 +0,0 @@
1
- import React, {useContext} from 'react';
2
- import {TouchableOpacity} from 'react-native';
3
- import PropTypes from 'prop-types';
4
- import {ApplicationContext, Index} from '@components';
5
-
6
- const Index = props => {
7
- const {theme} = useContext(ApplicationContext);
8
- const {style, value, disabled, size, shape, onPress} = props;
9
-
10
- /**
11
- * export icon name
12
- */
13
- const getIconName = () => {
14
- switch (shape) {
15
- case 'circle':
16
- if (value) {
17
- return 'checkbox-marked-circle';
18
- }
19
- return 'checkbox-blank-circle-outline';
20
- case 'rectangle':
21
- if (value) {
22
- return 'checkbox-marked';
23
- }
24
- return 'checkbox-blank-outline';
25
-
26
- default:
27
- return 'checkbox-blank-outline';
28
- }
29
- };
30
-
31
- /**
32
- * export icon color
33
- */
34
- const getIconColor = () => {
35
- if (disabled) {
36
- return theme.colors.textSecondary;
37
- }
38
- if (value) {
39
- return theme.colors.primary;
40
- }
41
- return theme.colors.text;
42
- };
43
-
44
- return (
45
- <TouchableOpacity disabled={disabled} onPress={onPress}>
46
- <Index
47
- name={getIconName()}
48
- size={size}
49
- color={getIconColor()}
50
- style={style}
51
- />
52
- </TouchableOpacity>
53
- );
54
- };
55
-
56
- Index.propTypes = {
57
- style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
58
- value: PropTypes.bool,
59
- disabled: PropTypes.bool,
60
- size: PropTypes.number,
61
- onPress: PropTypes.func,
62
- shape: PropTypes.oneOf(['circle', 'rectangle']),
63
- };
64
-
65
- Index.defaultProps = {
66
- style: {},
67
- value: false,
68
- disabled: false,
69
- size: 24,
70
- onPress: () => {},
71
- shape: 'circle',
72
- };
73
-
74
- export default Index;
@@ -1,3 +0,0 @@
1
- import {StyleSheet} from 'react-native';
2
-
3
- export default StyleSheet.create({});
package/Layout/Row.tsx DELETED
@@ -1,42 +0,0 @@
1
- import React, {useContext} from 'react';
2
- import {View} from 'react-native';
3
- import styles from './styles';
4
- import {MMSectionContext} from './Section';
5
- import {DEFAULT_SCREEN_PADDING, screenWidth} from './utils';
6
-
7
- const MMRow: React.FC<any> = props => {
8
- const haveMargin = useContext(MMSectionContext);
9
- const rowWidth = haveMargin
10
- ? screenWidth - DEFAULT_SCREEN_PADDING * 4
11
- : screenWidth - DEFAULT_SCREEN_PADDING * 2;
12
-
13
- const {children} = props;
14
- let totalGap = 0;
15
- return (
16
- <View
17
- style={[
18
- styles.row,
19
- {
20
- width: rowWidth,
21
- },
22
- ]}>
23
- {React.Children.map(children, (child, index) => {
24
- let isEndLine = false;
25
- totalGap += child.props.span;
26
- if (totalGap >= 12) {
27
- totalGap = 0;
28
- isEndLine = true;
29
- }
30
- if (totalGap + children[index + 1]?.props?.span > 12) {
31
- totalGap = 0;
32
- }
33
- return React.cloneElement(child, {
34
- isEndLine: isEndLine,
35
- isRowChild: true,
36
- });
37
- })}
38
- </View>
39
- );
40
- };
41
-
42
- export default MMRow;
package/Layout/Screen.tsx DELETED
@@ -1,68 +0,0 @@
1
- import React from 'react';
2
- import {ScrollView, View} from 'react-native';
3
- import styles from './styles';
4
- import {MMScreenProps} from './types';
5
- import {MMSection} from './index';
6
- import {
7
- DEFAULT_GUTTER,
8
- DEFAULT_SCREEN_PADDING,
9
- screenWidth,
10
- validateChildren,
11
- } from './utils';
12
-
13
- const MMScreen = (props: MMScreenProps) => {
14
- const {children, scrollable} = props;
15
-
16
- const parentWidth = screenWidth - DEFAULT_SCREEN_PADDING * 2;
17
-
18
- const colWidth = (parentWidth - DEFAULT_GUTTER * 11) / 12;
19
- const renderOverlay = () => {
20
- return (
21
- <View
22
- pointerEvents="none"
23
- style={{
24
- position: 'absolute',
25
- top: 0,
26
- bottom: 0,
27
- left: 0,
28
- right: 0,
29
- flexDirection: 'row',
30
- marginHorizontal: 12,
31
- }}>
32
- {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map((i, ii) => {
33
- return (
34
- <View
35
- pointerEvents="none"
36
- style={{
37
- width: colWidth,
38
- height: '100%',
39
- opacity: 0.2,
40
- backgroundColor: '#bae7ff',
41
- marginRight: ii !== 12 ? DEFAULT_GUTTER : 0,
42
- }}
43
- />
44
- );
45
- })}
46
- </View>
47
- );
48
- };
49
-
50
- if (scrollable) {
51
- return (
52
- <ScrollView
53
- showsVerticalScrollIndicator={false}
54
- style={[styles.screen, {width: screenWidth}]}>
55
- {validateChildren(children, MMSection)}
56
- {renderOverlay()}
57
- </ScrollView>
58
- );
59
- }
60
- return (
61
- <View style={[styles.screen, {width: screenWidth}]}>
62
- {validateChildren(children, MMSection)}
63
- {renderOverlay()}
64
- </View>
65
- );
66
- };
67
-
68
- export default MMScreen;
@@ -1,30 +0,0 @@
1
- import React, {createContext} from 'react';
2
- import {View} from 'react-native';
3
- import styles from './styles';
4
- import {MMSectionProps} from './types';
5
- import {MMRow} from './index';
6
- import {DEFAULT_SCREEN_PADDING, screenWidth, validateChildren} from './utils';
7
-
8
- export const MMSectionContext = createContext({});
9
-
10
- const MMSection: React.FC<MMSectionProps> = props => {
11
- const {haveMargin = false, children} = props;
12
- return (
13
- <MMSectionContext.Provider value={haveMargin}>
14
- <View
15
- style={[
16
- styles.section,
17
- {
18
- width: haveMargin
19
- ? screenWidth - DEFAULT_SCREEN_PADDING * 2
20
- : screenWidth,
21
- marginHorizontal: haveMargin ? DEFAULT_SCREEN_PADDING : 0,
22
- },
23
- ]}>
24
- {validateChildren(children, MMRow)}
25
- </View>
26
- </MMSectionContext.Provider>
27
- );
28
- };
29
-
30
- export default MMSection;
package/Layout/View.tsx DELETED
@@ -1,84 +0,0 @@
1
- import React, {useContext} from 'react';
2
- import {View} from 'react-native';
3
- import {MMViewProps} from './types';
4
- import styles from './styles';
5
- import {MMSectionContext} from './Section';
6
- import {screenWidth} from './utils';
7
- import {Colors, Shadow} from '@momo-kits/core';
8
-
9
- const MMView: React.FC<MMViewProps> = props => {
10
- const {
11
- span = 12,
12
- children,
13
- isEndLine,
14
- alignItems,
15
- justifyContent,
16
- padding,
17
- backgroundColor,
18
- borderRadius,
19
- direction,
20
- shadow = 'none',
21
- isRowChild = false,
22
- } = props;
23
- const NUM_OF_SPAN = 12;
24
- const DEFAULT_SCREEN_PADDING = 12;
25
- const GUTTER = 12;
26
- const haveMargin = useContext(MMSectionContext);
27
- const shadowStyle =
28
- shadow !== 'none' ? (shadow === 'light' ? Shadow.Light : Shadow.Dark) : {};
29
-
30
- const parentWidth = haveMargin
31
- ? screenWidth - DEFAULT_SCREEN_PADDING * 4
32
- : screenWidth - DEFAULT_SCREEN_PADDING * 2;
33
-
34
- const paddingStyle = {
35
- paddingTop: padding?.[0] || 0,
36
- paddingRight: padding?.[1] || 0,
37
- paddingBottom: padding?.[2] || 0,
38
- paddingLeft: padding?.[3] || 0,
39
- };
40
- const colWidth =
41
- (span * (parentWidth - GUTTER * (NUM_OF_SPAN - 1))) / NUM_OF_SPAN +
42
- GUTTER * (span - 1);
43
-
44
- const renderOverlay = () => {
45
- return (
46
- <View
47
- pointerEvents={'none'}
48
- style={{
49
- position: 'absolute',
50
- top: 0,
51
- bottom: 0,
52
- left: 0,
53
- right: 0,
54
- borderColor: Colors.pink_08,
55
- borderWidth: 1,
56
- }}
57
- />
58
- );
59
- };
60
-
61
- return (
62
- <View
63
- style={[
64
- styles.col,
65
- {
66
- width: colWidth,
67
- marginRight: isEndLine ? 0 : GUTTER,
68
- marginBottom: isRowChild ? GUTTER : 0,
69
- alignItems,
70
- backgroundColor,
71
- borderRadius,
72
- justifyContent,
73
- flexDirection: direction,
74
- },
75
- paddingStyle,
76
- shadowStyle,
77
- ]}>
78
- {children}
79
- {renderOverlay()}
80
- </View>
81
- );
82
- };
83
-
84
- export default MMView;
package/Layout/styles.ts DELETED
@@ -1,24 +0,0 @@
1
- import {StyleSheet} from 'react-native';
2
- import {Colors} from '@momo-kits/core';
3
-
4
- const styles = StyleSheet.create({
5
- col: {
6
- minHeight: 1,
7
- },
8
- row: {
9
- minHeight: 1,
10
- flexDirection: 'row',
11
- flexWrap: 'wrap',
12
- },
13
- section: {
14
- paddingHorizontal: 12,
15
- marginBottom: 12,
16
- },
17
- screen: {
18
- flex: 1,
19
- backgroundColor: Colors.black_01,
20
- paddingVertical: 12,
21
- },
22
- });
23
-
24
- export default styles;
@@ -1,38 +0,0 @@
1
- import {KeyboardAvoidingView, Platform} from 'react-native';
2
- import {useHeaderHeight} from '@react-navigation/stack';
3
- import React, {useLayoutEffect} from 'react';
4
- import {SafeAreaView, ScreenContainerProps, Styles} from '../index';
5
-
6
- const ScreenContainer: React.FC<ScreenContainerProps> = ({
7
- style,
8
- children,
9
- navigation,
10
- options,
11
- edges = ['bottom', 'left', 'right'],
12
- enableKeyboardAvoidingView = false,
13
- }) => {
14
- const headerHeight = useHeaderHeight();
15
-
16
- useLayoutEffect(() => {
17
- if (options) {
18
- navigation.setOptions(options);
19
- }
20
- }, [navigation, options]);
21
-
22
- return (
23
- <SafeAreaView style={[Styles.flex, style]} edges={edges}>
24
- <KeyboardAvoidingView
25
- style={Styles.flex}
26
- keyboardVerticalOffset={headerHeight}
27
- enabled={enableKeyboardAvoidingView}
28
- behavior={Platform.select({
29
- ios: 'padding',
30
- android: undefined,
31
- })}>
32
- {children}
33
- </KeyboardAvoidingView>
34
- </SafeAreaView>
35
- );
36
- };
37
-
38
- export default ScreenContainer;
package/SizedBox/index.js DELETED
@@ -1,23 +0,0 @@
1
- import React from 'react';
2
- import {View} from 'react-native';
3
- import PropTypes from 'prop-types';
4
- import styles from './styles';
5
-
6
- const Index = props => {
7
- const {width, height, children} = props;
8
- return <View style={[styles.default, {width, height}]}>{children}</View>;
9
- };
10
-
11
- Index.propTypes = {
12
- width: PropTypes.number,
13
- height: PropTypes.number,
14
- children: PropTypes.element,
15
- };
16
-
17
- Index.defaultProps = {
18
- width: 0,
19
- height: 0,
20
- children: null,
21
- };
22
-
23
- export default Index;
@@ -1,7 +0,0 @@
1
- import {StyleSheet} from 'react-native';
2
-
3
- export default StyleSheet.create({
4
- default: {
5
- overflow: 'hidden',
6
- },
7
- });
@@ -1,225 +0,0 @@
1
- import React, {
2
- forwardRef,
3
- useContext,
4
- useImperativeHandle,
5
- useRef,
6
- useState,
7
- } from 'react';
8
- import {TextInput, TouchableOpacity, View} from 'react-native';
9
- import PropTypes from 'prop-types';
10
- import {
11
- ApplicationContext,
12
- getFontFamily,
13
- Index,
14
- SizedBox,
15
- Text,
16
- } from '@components';
17
- import styles from './styles';
18
- import {Opacity} from '@configs';
19
-
20
- const Index = forwardRef((props, ref) => {
21
- const {theme, font} = useContext(ApplicationContext);
22
- const {
23
- style,
24
- size,
25
- label,
26
- info,
27
- onPressInfo,
28
- onChangeText,
29
- error,
30
- trailing,
31
- numberOfLines,
32
- } = props;
33
-
34
- const inputRef = useRef();
35
- const [focus, setFocus] = useState(false);
36
-
37
- useImperativeHandle(ref, () => inputRef.current);
38
-
39
- /**
40
- * get border color
41
- */
42
- const getBorderColor = () => {
43
- if (error) {
44
- return theme.colors.error;
45
- }
46
- if (focus) {
47
- return theme.colors.primary;
48
- }
49
- return theme.colors.border;
50
- };
51
-
52
- /**
53
- * get size style
54
- */
55
- const getSizeStyle = () => {
56
- if (numberOfLines > 1) {
57
- return [styles.small, {height: numberOfLines * 24}];
58
- }
59
- switch (size) {
60
- case 'large':
61
- return styles.large;
62
- case 'small':
63
- return styles.small;
64
-
65
- default:
66
- return styles.large;
67
- }
68
- };
69
-
70
- /**
71
- * get text style
72
- */
73
- const getTextStyle = () => {
74
- let textStyle;
75
- switch (size) {
76
- case 'large':
77
- textStyle = styles.textLarge;
78
- break;
79
- case 'small':
80
- textStyle = styles.textSmall;
81
- break;
82
- default:
83
- textStyle = styles.textLarge;
84
- break;
85
- }
86
-
87
- return {
88
- ...textStyle,
89
- fontFamily: getFontFamily({
90
- fontFamily: font,
91
- fontWeight: textStyle.fontWeight,
92
- }),
93
- };
94
- };
95
-
96
- /**
97
- * on clear text
98
- */
99
- const onClear = () => {
100
- inputRef?.current?.clear?.();
101
- onChangeText?.('');
102
- };
103
-
104
- /**
105
- * on blur
106
- */
107
- const onBlur = () => {
108
- setFocus(false);
109
- props.onBlur?.();
110
- };
111
-
112
- /**
113
- * on forcus
114
- */
115
- const onFocus = () => {
116
- setFocus(true);
117
- props.onFocus?.();
118
- };
119
-
120
- /**
121
- * render info icon button
122
- */
123
- const renderInfo = () => {
124
- if (info) {
125
- return (
126
- <TouchableOpacity style={styles.rowInfo} onPress={onPressInfo}>
127
- <Index
128
- name="information-outline"
129
- color={theme.colors.secondary}
130
- size={16}
131
- />
132
- </TouchableOpacity>
133
- );
134
- }
135
- };
136
-
137
- /**
138
- * render clear action
139
- */
140
- const renderClear = () => {
141
- if (focus) {
142
- return (
143
- <TouchableOpacity onPress={onClear}>
144
- <Index name="close-circle" />
145
- </TouchableOpacity>
146
- );
147
- }
148
- };
149
-
150
- /**
151
- * render trailing
152
- */
153
- const renderTrailing = () => {
154
- if (trailing) {
155
- return <View style={styles.trailingContent}>{trailing}</View>;
156
- }
157
- };
158
-
159
- return (
160
- <View style={[styles.container, style]}>
161
- <View style={[getSizeStyle(), {borderColor: getBorderColor()}]}>
162
- <View style={styles.rowContent}>
163
- <TextInput
164
- {...props}
165
- ref={inputRef}
166
- multiline={numberOfLines > 1}
167
- textAlignVertical={numberOfLines > 1 ? 'top' : 'center'}
168
- style={[
169
- styles.inputContent,
170
- {color: theme.colors.text},
171
- numberOfLines > 1 && styles.multilineContent,
172
- getTextStyle(),
173
- ]}
174
- placeholderTextColor={theme.colors.textSecondary + Opacity['40']}
175
- onFocus={onFocus}
176
- onBlur={onBlur}
177
- />
178
- {renderClear()}
179
- {renderTrailing()}
180
- <View
181
- style={[styles.infoContent, {backgroundColor: theme.colors.card}]}>
182
- <Text typography="subtitle" type="secondary">
183
- {label}
184
- </Text>
185
- {renderInfo()}
186
- </View>
187
- </View>
188
- </View>
189
- {error && (
190
- <>
191
- <SizedBox height={4} />
192
- <Text typography="subtitle" color="error">
193
- {error}
194
- </Text>
195
- </>
196
- )}
197
- </View>
198
- );
199
- });
200
-
201
- Index.propTypes = {
202
- style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
203
- size: PropTypes.oneOf(['large', 'small']),
204
- label: PropTypes.string,
205
- error: PropTypes.string,
206
- info: PropTypes.bool,
207
- autoCorrect: PropTypes.bool,
208
- spellCheck: PropTypes.bool,
209
- onPressInfo: PropTypes.func,
210
- trailing: PropTypes.element,
211
- };
212
-
213
- Index.defaultProps = {
214
- style: {},
215
- size: 'large',
216
- label: 'Label',
217
- error: null,
218
- info: false,
219
- autoCorrect: false,
220
- spellCheck: false,
221
- onPressInfo: () => {},
222
- trailing: null,
223
- };
224
-
225
- export default Index;
@@ -1,55 +0,0 @@
1
- import {StyleSheet} from 'react-native';
2
-
3
- export default StyleSheet.create({
4
- container: {
5
- width: '100%',
6
- },
7
- large: {
8
- height: 60,
9
- width: '100%',
10
- borderWidth: 1,
11
- borderRadius: 8,
12
- },
13
- small: {
14
- height: 50,
15
- width: '100%',
16
- borderWidth: 1,
17
- borderRadius: 8,
18
- },
19
- inputContent: {flex: 1, height: '100%'},
20
- textLarge: {
21
- fontSize: 20,
22
- fontWeight: 'bold',
23
- },
24
- textSmall: {fontSize: 16},
25
- rowInfo: {
26
- paddingLeft: 4,
27
- flex: 1,
28
- flexDirection: 'row',
29
- alignItems: 'center',
30
- },
31
- rowContent: {
32
- flex: 1,
33
- flexDirection: 'row',
34
- alignItems: 'center',
35
- paddingHorizontal: 16,
36
- },
37
- infoContent: {
38
- position: 'absolute',
39
- flexDirection: 'row',
40
- alignItems: 'center',
41
- left: 8,
42
- top: -8,
43
- height: 16,
44
- paddingHorizontal: 8,
45
- overflow: 'hidden',
46
- },
47
- trailingContent: {
48
- marginLeft: 12,
49
- justifyContent: 'center',
50
- alignItems: 'center',
51
- },
52
- multilineContent: {
53
- paddingTop: 12,
54
- },
55
- });