@momo-kits/foundation 0.75.1-beta.9 → 0.75.2-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.
Files changed (112) hide show
  1. package/Application/BottomTab/BottomTabBar.tsx +478 -0
  2. package/Application/BottomTab/index.tsx +134 -0
  3. package/Application/Components.tsx +552 -0
  4. package/Application/ModalScreen.tsx +244 -0
  5. package/Application/Navigation.ts +50 -0
  6. package/Application/NavigationContainer.tsx +128 -0
  7. package/Application/Navigator.ts +151 -0
  8. package/Application/StackScreen.tsx +146 -0
  9. package/Application/index.ts +37 -0
  10. package/{Navigation → Application}/types.ts +96 -27
  11. package/Application/utils.tsx +175 -0
  12. package/Assets/DotAnimation.json +256 -0
  13. package/Assets/SpinnerAnimation.json +1027 -0
  14. package/Assets/icon.json +89 -5
  15. package/Assets/icon_bank.json +506 -0
  16. package/Assets/language.json +202 -0
  17. package/Badge/Badge.tsx +56 -0
  18. package/Badge/BadgeDot.tsx +11 -0
  19. package/Badge/BadgeRibbon.tsx +125 -0
  20. package/Badge/Shape.tsx +29 -0
  21. package/Badge/index.tsx +7 -0
  22. package/Badge/styles.ts +58 -0
  23. package/Badge/types.ts +63 -0
  24. package/Button/index.tsx +90 -39
  25. package/Button/styles.ts +19 -0
  26. package/CheckBox/index.tsx +58 -43
  27. package/CheckBox/styles.ts +1 -1
  28. package/CheckBox/types.ts +6 -4
  29. package/Consts/colors+spacing+radius.ts +18 -0
  30. package/Consts/styles.ts +0 -26
  31. package/Consts/theme.ts +5 -1
  32. package/Divider/index.tsx +3 -1
  33. package/Icon/index.tsx +14 -10
  34. package/Icon/types.ts +4 -3
  35. package/IconButton/index.tsx +24 -15
  36. package/Image/index.tsx +63 -45
  37. package/Image/styles.ts +1 -9
  38. package/Image/types.ts +5 -1
  39. package/Input/Input.tsx +227 -115
  40. package/Input/InputDropDown.tsx +132 -0
  41. package/Input/InputMoney.tsx +174 -110
  42. package/Input/InputOTP.tsx +257 -0
  43. package/Input/InputSearch.tsx +160 -130
  44. package/Input/InputTextArea.tsx +149 -121
  45. package/Input/common.tsx +43 -18
  46. package/Input/index.tsx +205 -17
  47. package/Input/styles.ts +44 -7
  48. package/Input/utils.ts +2 -2
  49. package/Layout/Card.tsx +76 -37
  50. package/Layout/FloatingButton.tsx +128 -0
  51. package/Layout/GridSystem.tsx +35 -23
  52. package/Layout/Item.tsx +29 -33
  53. package/Layout/ItemList.tsx +55 -0
  54. package/Layout/ItemSectionList.tsx +39 -0
  55. package/Layout/Screen.tsx +378 -0
  56. package/Layout/Section.tsx +73 -35
  57. package/Layout/index.ts +13 -3
  58. package/Layout/styles.ts +101 -0
  59. package/Layout/types.ts +1 -37
  60. package/Layout/utils.ts +38 -43
  61. package/Loader/DotLoader.tsx +37 -0
  62. package/Loader/Loader.tsx +13 -0
  63. package/Loader/ProgressBar.tsx +44 -0
  64. package/Loader/Spinner.tsx +29 -0
  65. package/Loader/index.tsx +4 -0
  66. package/Loader/styles.ts +10 -0
  67. package/Loader/types.ts +35 -0
  68. package/Loader/utils.ts +25 -0
  69. package/Pagination/Dot.tsx +1 -1
  70. package/Pagination/PaginationDot.tsx +8 -3
  71. package/Pagination/PaginationNumber.tsx +8 -7
  72. package/Pagination/PaginationScroll.tsx +1 -1
  73. package/Pagination/PaginationWhiteDot.tsx +8 -5
  74. package/Pagination/styles.ts +3 -0
  75. package/Pagination/types.ts +2 -0
  76. package/Popup/PopupNotify.tsx +102 -44
  77. package/Popup/PopupPromotion.tsx +63 -22
  78. package/Popup/types.ts +15 -4
  79. package/Radio/index.tsx +35 -21
  80. package/Radio/types.ts +7 -5
  81. package/Skeleton/index.tsx +1 -1
  82. package/Skeleton/types.ts +3 -0
  83. package/Switch/index.tsx +35 -24
  84. package/Switch/types.ts +5 -3
  85. package/Tag/index.tsx +1 -1
  86. package/Text/index.tsx +32 -26
  87. package/Text/styles.ts +38 -0
  88. package/Text/types.ts +25 -13
  89. package/Text/utils.ts +14 -0
  90. package/Title/index.tsx +186 -0
  91. package/Title/styles.ts +79 -0
  92. package/Title/types.ts +20 -0
  93. package/code-scanner.js +143 -0
  94. package/index.ts +17 -3
  95. package/migrate_typo.js +56 -0
  96. package/package.json +44 -39
  97. package/publish.sh +2 -5
  98. package/tsconfig.json +24 -0
  99. package/verify.js +47 -0
  100. package/Assets/header-background.png +0 -0
  101. package/Layout/ScreenContainer.tsx +0 -121
  102. package/Navigation/BottomTab.tsx +0 -39
  103. package/Navigation/Components.tsx +0 -365
  104. package/Navigation/ModalScreen.tsx +0 -226
  105. package/Navigation/Navigation.ts +0 -44
  106. package/Navigation/NavigationButton.tsx +0 -54
  107. package/Navigation/NavigationContainer.tsx +0 -77
  108. package/Navigation/Navigator.ts +0 -82
  109. package/Navigation/Observer.ts +0 -79
  110. package/Navigation/StackScreen.tsx +0 -27
  111. package/Navigation/index.ts +0 -14
  112. package/Navigation/utils.tsx +0 -137
package/Layout/utils.ts CHANGED
@@ -1,6 +1,5 @@
1
- import {Alert} from 'react-native';
2
- import React, {ReactElement} from 'react';
3
- import {SectionProps} from './types';
1
+ import React, {Fragment, ReactElement, useEffect, useState} from 'react';
2
+ import {Dimensions} from 'react-native';
4
3
 
5
4
  /**
6
5
  * validate children type
@@ -8,53 +7,49 @@ import {SectionProps} from './types';
8
7
  * @param childrenTypes
9
8
  */
10
9
  const validateChildren = (
11
- children:
12
- | React.ReactElement<any, string | React.JSXElementConstructor<any>>
13
- | string
14
- | number
15
- | {}
16
- | Iterable<React.ReactNode>
17
- | React.ReactPortal
18
- | null
19
- | undefined
20
- | boolean,
21
- childrenTypes: Array<React.FC<any>>,
10
+ children: React.ReactNode | React.ReactNode[],
11
+ childrenTypes: Array<React.ReactNode>,
22
12
  ) => {
23
- if (!__DEV__) return children;
24
-
25
- let results: React.ReactElement[] = [];
26
13
  const validateType = (child: React.ReactElement) => {
27
- return childrenTypes.some(childrenType => child?.type === childrenType);
28
- };
29
-
30
- const alertWrongType = () => {
31
- Alert.alert(
32
- 'Component Kits',
33
- `Wrong children type for this component, expected are ${childrenTypes
34
- .map(type => type.displayName)
35
- .join(', ')}.`,
14
+ const valid = childrenTypes.some(
15
+ childrenType => child?.type === childrenType || child?.type == Fragment,
36
16
  );
17
+ if (!valid) {
18
+ console.warn(
19
+ `Wrong children type for this component, expected are ${childrenTypes
20
+ .map(item => item)
21
+ .join(', ')}.`,
22
+ );
23
+ }
37
24
  };
38
-
39
25
  if (Array.isArray(children)) {
40
- const flattenChildren = children.flat();
41
- results = flattenChildren.filter((child: React.ReactElement) => {
42
- if (validateType(child)) {
43
- return child;
44
- } else {
45
- alertWrongType();
46
- }
47
- });
48
- } else {
49
- const singleChild: any = children;
50
- if (validateType(singleChild)) {
51
- results = [singleChild];
52
- } else {
53
- alertWrongType();
26
+ const flattenChildren: React.ReactElement[] = children.flat();
27
+ for (const child of flattenChildren) {
28
+ validateType(child);
54
29
  }
30
+ return flattenChildren;
31
+ } else {
32
+ validateType(children as ReactElement);
33
+ return children;
55
34
  }
35
+ };
36
+
37
+ const useGridSystem = () => {
38
+ const [numberOfColumns, setNumberOfColumns] = useState(
39
+ Dimensions.get('window').width > 600 ? 24 : 12,
40
+ );
41
+
42
+ useEffect(() => {
43
+ const subscription: any = Dimensions.addEventListener('change', () => {
44
+ const newColumns = Dimensions.get('window').width > 600 ? 24 : 12;
45
+ if (newColumns != numberOfColumns) {
46
+ setNumberOfColumns(newColumns);
47
+ }
48
+ });
49
+ return () => subscription?.remove();
50
+ }, []);
56
51
 
57
- return results;
52
+ return {numberOfColumns};
58
53
  };
59
54
 
60
- export {validateChildren};
55
+ export {useGridSystem, validateChildren};
@@ -0,0 +1,37 @@
1
+ import React, {FC, useContext} from 'react';
2
+ import AnimatedLottieView from 'lottie-react-native';
3
+ import animation from '../Assets/DotAnimation.json';
4
+ import {ApplicationContext} from '../Application';
5
+ import {hexToRGBA} from './utils';
6
+ import {LoaderProps} from './types';
7
+
8
+ const DotLoader: FC<LoaderProps> = ({color}) => {
9
+ const {theme} = useContext(ApplicationContext);
10
+
11
+ const arrayColor = [
12
+ color ?? theme.colors.primary,
13
+ theme.colors.background.surface,
14
+ color ?? theme.colors.primary,
15
+ ];
16
+
17
+ let source: any = animation;
18
+ source.assets[0].layers[0].shapes[0].it.forEach((item: any) => {
19
+ if (item.ty === 'fl' && item.c) {
20
+ item.c.k.forEach((fillItem: any, index: number) => {
21
+ if (typeof fillItem !== 'number') {
22
+ fillItem.s = hexToRGBA(arrayColor[index] as string);
23
+ }
24
+ });
25
+ }
26
+ });
27
+
28
+ return (
29
+ <AnimatedLottieView
30
+ source={source}
31
+ style={{width: 52, height: 18}}
32
+ autoPlay
33
+ />
34
+ );
35
+ };
36
+
37
+ export default DotLoader;
@@ -0,0 +1,13 @@
1
+ import React, {FC} from 'react';
2
+ import {LoaderProps} from './types';
3
+ import DotLoader from './DotLoader';
4
+ import Spinner from './Spinner';
5
+
6
+ const Loader: FC<LoaderProps> = ({type = 'dot', ...props}) => {
7
+ if (type === 'spinner') {
8
+ return <Spinner {...props} key={props.color} />;
9
+ }
10
+ return <DotLoader {...props} key={props.color} />;
11
+ };
12
+
13
+ export default Loader;
@@ -0,0 +1,44 @@
1
+ import React, {FC, useContext, useEffect, useRef} from 'react';
2
+ import {Animated, View} from 'react-native';
3
+ import styles from './styles';
4
+ import {ProgressBarProps} from './types';
5
+ import {ApplicationContext} from '../Application';
6
+ import {Radius} from '../Consts';
7
+
8
+ const ProgressBar: FC<ProgressBarProps> = ({percent = 0, style}) => {
9
+ const {theme} = useContext(ApplicationContext);
10
+ const animation = useRef(new Animated.Value(0)).current;
11
+
12
+ useEffect(() => {
13
+ Animated.timing(animation, {
14
+ toValue: percent,
15
+ duration: 200,
16
+ useNativeDriver: false,
17
+ }).start();
18
+ }, [percent, animation]);
19
+
20
+ const width = animation.interpolate({
21
+ inputRange: [0, 100],
22
+ outputRange: ['0%', '100%'],
23
+ });
24
+
25
+ return (
26
+ <View
27
+ style={[
28
+ style,
29
+ styles.progressContainer,
30
+ {backgroundColor: theme.colors.background.default},
31
+ ]}>
32
+ <Animated.View
33
+ style={{
34
+ height: 4,
35
+ borderRadius: Radius.XXS,
36
+ width,
37
+ backgroundColor: theme.colors.primary,
38
+ }}
39
+ />
40
+ </View>
41
+ );
42
+ };
43
+
44
+ export default ProgressBar;
@@ -0,0 +1,29 @@
1
+ import React, {FC, useContext} from 'react';
2
+ import AnimatedLottieView from 'lottie-react-native';
3
+ import animation from '../Assets/SpinnerAnimation.json';
4
+ import {hexToRGBA} from './utils';
5
+ import {ApplicationContext} from '../Application';
6
+ import {LoaderProps} from './types';
7
+
8
+ const Spinner: FC<LoaderProps> = ({color}) => {
9
+ const {theme} = useContext(ApplicationContext);
10
+
11
+ let source: any = animation;
12
+ source.assets[0].layers.forEach((layer: any) => {
13
+ layer.shapes[0].it.forEach((item: any) => {
14
+ if (item.ty === 'fl' && item.c) {
15
+ item.c.k = hexToRGBA(color ?? theme.colors.primary);
16
+ }
17
+ });
18
+ });
19
+
20
+ return (
21
+ <AnimatedLottieView
22
+ source={source}
23
+ style={{width: 24, height: 24}}
24
+ autoPlay
25
+ />
26
+ );
27
+ };
28
+
29
+ export default Spinner;
@@ -0,0 +1,4 @@
1
+ import Loader from './Loader';
2
+ import ProgressBar from './ProgressBar';
3
+
4
+ export {Loader, ProgressBar};
@@ -0,0 +1,10 @@
1
+ import {StyleSheet} from 'react-native';
2
+ import {Radius} from '../Consts';
3
+
4
+ export default StyleSheet.create({
5
+ progressContainer: {
6
+ width: '100%',
7
+ height: 4,
8
+ borderRadius: Radius.XXS,
9
+ },
10
+ });
@@ -0,0 +1,35 @@
1
+ import {ViewStyle} from 'react-native';
2
+
3
+ export type LoaderProps = {
4
+ /**
5
+ * Optional. Type of loader, can be 'dot' or 'spinner'.
6
+ */
7
+ type?: 'dot' | 'spinner';
8
+
9
+ /**
10
+ * Optional. Color for the loader.
11
+ */
12
+ color?: string;
13
+
14
+ /**
15
+ * Optional. Style or styles for the loader component.
16
+ */
17
+ style?: ViewStyle | ViewStyle[];
18
+ };
19
+
20
+ export type ProgressBarProps = {
21
+ /**
22
+ * Required. Percentage value to display on the progress bar.
23
+ */
24
+ percent: number;
25
+
26
+ /**
27
+ * Optional. Color for the progress bar.
28
+ */
29
+ color?: string;
30
+
31
+ /**
32
+ * Optional. Style or styles for the progress bar component.
33
+ */
34
+ style?: ViewStyle | ViewStyle[];
35
+ };
@@ -0,0 +1,25 @@
1
+ export const hexToRGBA = (hex: string) => {
2
+ const normalizedHex = hex.startsWith('#') ? hex.slice(1) : hex;
3
+
4
+ if (!/^([0-9A-Fa-f]{3}){1,2}$/.test(normalizedHex)) {
5
+ throw new Error('Invalid HEX color.');
6
+ }
7
+
8
+ const expandedHex =
9
+ normalizedHex.length === 3
10
+ ? normalizedHex
11
+ .split('')
12
+ .map(val => val + val)
13
+ .join('')
14
+ : normalizedHex;
15
+
16
+ const hexMatch = expandedHex.match(/.{2}/g);
17
+
18
+ if (!hexMatch) {
19
+ throw new Error('HEX parsing failed.');
20
+ }
21
+
22
+ return hexMatch
23
+ .map(val => parseInt(val, 16))
24
+ .map(val => Math.round((val / 255) * 1000) / 1000);
25
+ };
@@ -2,7 +2,7 @@ import React, {FC, useContext} from 'react';
2
2
  import {Animated} from 'react-native';
3
3
  import styles from './styles';
4
4
  import {DotProps} from './types';
5
- import {ApplicationContext} from '../Navigation';
5
+ import {ApplicationContext} from '../Application';
6
6
 
7
7
  const Dot: FC<DotProps> = ({active, style}) => {
8
8
  const {theme} = useContext(ApplicationContext);
@@ -4,15 +4,16 @@ import {ChildPaginationProps} from './types';
4
4
  import Dot from './Dot';
5
5
  import styles from './styles';
6
6
  import {Spacing} from '../Consts';
7
- import {ApplicationContext} from '../Navigation';
7
+ import {ApplicationContext} from '../Application';
8
8
 
9
9
  const PaginationDot: FC<ChildPaginationProps> = ({
10
10
  dataLength = 2,
11
11
  activeIndex = 0,
12
+ style,
12
13
  }) => {
13
14
  const {theme} = useContext(ApplicationContext);
14
15
  const renderDots = () => {
15
- const dots = [];
16
+ const dots: React.ReactElement[] = [];
16
17
  for (let i = 0; i < dataLength; i++) {
17
18
  dots.push(
18
19
  <Dot
@@ -27,7 +28,11 @@ const PaginationDot: FC<ChildPaginationProps> = ({
27
28
  }
28
29
  return dots;
29
30
  };
30
- return <View style={styles.paginationPinkContainer}>{renderDots()}</View>;
31
+ return (
32
+ <View style={[style, styles.row]}>
33
+ <View style={styles.paginationPinkContainer}>{renderDots()}</View>
34
+ </View>
35
+ );
31
36
  };
32
37
 
33
38
  export default PaginationDot;
@@ -1,21 +1,22 @@
1
- import React, {FC, useContext} from 'react';
1
+ import React, {FC} from 'react';
2
2
  import {View} from 'react-native';
3
3
  import {ChildPaginationProps} from './types';
4
4
  import styles from './styles';
5
5
  import {Text} from '../Text';
6
- import {ApplicationContext} from '../Navigation';
7
6
  import {Colors} from '../Consts';
8
7
 
9
8
  const PaginationNumber: FC<ChildPaginationProps> = ({
10
9
  activeIndex = 0,
11
10
  dataLength = 2,
11
+ style,
12
12
  }) => {
13
- const {theme} = useContext(ApplicationContext);
14
13
  return (
15
- <View style={[styles.paginationNumberContainer]}>
16
- <Text color={Colors.black_01} typography={'label_default'}>{`${
17
- activeIndex + 1
18
- }/${dataLength}`}</Text>
14
+ <View style={[style, styles.row]}>
15
+ <View style={styles.paginationNumberContainer}>
16
+ <Text color={Colors.black_01} typography={'label_default_medium'}>{`${
17
+ activeIndex + 1
18
+ }/${dataLength}`}</Text>
19
+ </View>
19
20
  </View>
20
21
  );
21
22
  };
@@ -2,7 +2,7 @@ import React, {FC, useContext, useRef, useState} from 'react';
2
2
  import {Animated, View} from 'react-native';
3
3
  import {ScrollIndicatorProps} from './types';
4
4
  import styles from './styles';
5
- import {ApplicationContext} from '../Navigation';
5
+ import {ApplicationContext} from '../Application';
6
6
 
7
7
  const INDICATOR_WIDTH = 24;
8
8
  const INDICATOR_CONTAINER_WIDTH = 72;
@@ -1,18 +1,17 @@
1
- import React, {FC, useContext} from 'react';
1
+ import React, {FC} from 'react';
2
2
  import {View} from 'react-native';
3
3
  import {ChildPaginationProps} from './types';
4
4
  import styles from './styles';
5
5
  import Dot from './Dot';
6
6
  import {Colors, Spacing} from '../Consts';
7
- import {ApplicationContext} from '../Navigation';
8
7
 
9
8
  const PaginationWhiteDot: FC<ChildPaginationProps> = ({
10
9
  dataLength = 2,
11
10
  activeIndex = 0,
11
+ style,
12
12
  }) => {
13
- const {theme} = useContext(ApplicationContext);
14
13
  const renderDots = () => {
15
- const dots = [];
14
+ const dots: React.ReactElement[] = [];
16
15
  for (let i = 0; i < dataLength; i++) {
17
16
  dots.push(
18
17
  <Dot
@@ -26,7 +25,11 @@ const PaginationWhiteDot: FC<ChildPaginationProps> = ({
26
25
  }
27
26
  return dots;
28
27
  };
29
- return <View style={[styles.paginationWhiteContainer]}>{renderDots()}</View>;
28
+ return (
29
+ <View style={[style, styles.row]}>
30
+ <View style={styles.paginationWhiteContainer}>{renderDots()}</View>
31
+ </View>
32
+ );
30
33
  };
31
34
 
32
35
  export default PaginationWhiteDot;
@@ -25,6 +25,8 @@ export default StyleSheet.create({
25
25
  paddingHorizontal: Spacing.S,
26
26
  borderRadius: Radius.L,
27
27
  backgroundColor: Colors.black_20 + '33',
28
+ alignItems: 'center',
29
+ justifyContent: 'center',
28
30
  },
29
31
  scrollContainer: {
30
32
  alignItems: 'center',
@@ -44,4 +46,5 @@ export default StyleSheet.create({
44
46
  height: 4,
45
47
  borderRadius: Radius.XS,
46
48
  },
49
+ row: {flexDirection: 'row'},
47
50
  });
@@ -20,6 +20,8 @@ export type PaginationProps = {
20
20
  * Represents the total number of items (pages) in the Pagination component.
21
21
  */
22
22
  dataLength: number;
23
+
24
+ style?: ViewStyle | ViewStyle[];
23
25
  };
24
26
 
25
27
  export type DotProps = {