@momo-kits/foundation 0.77.7 → 0.77.8-beta.2

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/Button/index.tsx CHANGED
@@ -62,13 +62,13 @@ export interface ButtonProps extends TouchableOpacityProps {
62
62
  }
63
63
 
64
64
  const Button: FC<ButtonProps> = ({
65
- type,
66
- size,
67
- useTintColor,
68
- full,
65
+ type = 'primary',
66
+ size = 'large',
67
+ useTintColor = true,
68
+ full = false,
69
69
  iconRight,
70
70
  iconLeft,
71
- title,
71
+ title = 'Button',
72
72
  onPress,
73
73
  ...rest
74
74
  }) => {
@@ -266,13 +266,4 @@ const Button: FC<ButtonProps> = ({
266
266
  );
267
267
  };
268
268
 
269
- Button.defaultProps = {
270
- type: 'primary',
271
- size: 'large',
272
- full: true,
273
- disabled: false,
274
- title: 'Button',
275
- useTintColor: true,
276
- };
277
-
278
269
  export {Button};
package/Layout/Screen.tsx CHANGED
@@ -176,7 +176,7 @@ const Screen: React.FC<ScreenProps> = ({
176
176
  <View
177
177
  style={{
178
178
  paddingTop: Spacing.S,
179
- paddingBottom: insets.bottom + Spacing.S,
179
+ paddingBottom: Math.min(insets.bottom, 20) + Spacing.S,
180
180
  backgroundColor: theme.colors.background.surface,
181
181
  }}>
182
182
  <Section>{Footer}</Section>
@@ -0,0 +1,39 @@
1
+ import React, {FC, useContext} from 'react';
2
+ import {View, ViewProps} from 'react-native';
3
+ import AnimatedLottieView from 'lottie-react-native';
4
+ import animation from '../Assets/DotAnimation.json';
5
+ import {ApplicationContext} from '../Application';
6
+ import {hexToRGBA} from './utils';
7
+
8
+ const DotLoader: FC<ViewProps> = ({style}) => {
9
+ const {theme} = useContext(ApplicationContext);
10
+
11
+ const arrayColor = [
12
+ theme.colors.primary,
13
+ theme.colors.secondary,
14
+ theme.colors.primary,
15
+ ];
16
+
17
+ let source = animation;
18
+ source.assets[0].layers[0].shapes[0].it.forEach(item => {
19
+ if (item.ty === 'fl' && item.c) {
20
+ item.c.k.forEach((fillItem, index) => {
21
+ if (typeof fillItem !== 'number') {
22
+ fillItem.s = hexToRGBA(arrayColor[index]);
23
+ }
24
+ });
25
+ }
26
+ });
27
+
28
+ return (
29
+ <View style={style}>
30
+ <AnimatedLottieView
31
+ source={source}
32
+ style={{width: 52, height: 18}}
33
+ autoPlay
34
+ />
35
+ </View>
36
+ );
37
+ };
38
+
39
+ export default DotLoader;
@@ -0,0 +1,14 @@
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', style}) => {
7
+ if (type === 'spinner') {
8
+ return <Spinner style={style} />;
9
+ }
10
+
11
+ return <DotLoader style={style} />;
12
+ };
13
+
14
+ 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,31 @@
1
+ import React, {FC, useContext} from 'react';
2
+ import {View, ViewProps} from 'react-native';
3
+ import AnimatedLottieView from 'lottie-react-native';
4
+ import animation from '../Assets/SpinnerAnimation.json';
5
+ import {hexToRGBA} from './utils';
6
+ import {ApplicationContext} from '../Application';
7
+
8
+ const Spinner: FC<ViewProps> = ({style}) => {
9
+ const {theme} = useContext(ApplicationContext);
10
+
11
+ let source = animation;
12
+ source.assets[0].layers.forEach(layer => {
13
+ layer.shapes[0].it.forEach(item => {
14
+ if (item.ty === 'fl' && item.c) {
15
+ item.c.k = hexToRGBA(theme.colors.primary);
16
+ }
17
+ });
18
+ });
19
+
20
+ return (
21
+ <View style={style}>
22
+ <AnimatedLottieView
23
+ source={source}
24
+ style={{width: 24, height: 24}}
25
+ autoPlay
26
+ />
27
+ </View>
28
+ );
29
+ };
30
+
31
+ 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,11 @@
1
+ import {ViewStyle} from 'react-native';
2
+
3
+ export type LoaderProps = {
4
+ type?: 'dot' | 'spinner';
5
+ style?: ViewStyle | ViewStyle[];
6
+ };
7
+
8
+ export type ProgressBarProps = {
9
+ percent: number;
10
+ style?: ViewStyle | ViewStyle[];
11
+ };
@@ -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
+ };
@@ -110,9 +110,10 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
110
110
  */
111
111
  const buildCloseIcon = () => {
112
112
  return (
113
- <View style={styles.iconCloseContainer}>
114
- <TouchableOpacity
115
- onPress={() => onAction(onIconClose)}
113
+ <TouchableOpacity
114
+ style={styles.iconCloseContainer}
115
+ onPress={() => onAction(onIconClose)}>
116
+ <View
116
117
  style={[
117
118
  styles.iconClose,
118
119
  {
@@ -125,8 +126,8 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
125
126
  color={theme.colors.background.surface}
126
127
  size={14}
127
128
  />
128
- </TouchableOpacity>
129
- </View>
129
+ </View>
130
+ </TouchableOpacity>
130
131
  );
131
132
  };
132
133
 
@@ -191,8 +192,9 @@ const styles = StyleSheet.create({
191
192
  },
192
193
  iconCloseContainer: {
193
194
  position: 'absolute',
194
- top: -Spacing.S,
195
- right: -Spacing.S,
195
+ top: -Spacing.M,
196
+ right: -Spacing.M,
197
+ padding: Spacing.XS,
196
198
  },
197
199
  iconClose: {
198
200
  width: 20,
@@ -20,18 +20,21 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({image, onClose}) => {
20
20
  navigator?.pop();
21
21
  onClose?.();
22
22
  }}
23
- style={[
24
- styles.iconClose,
25
- {
26
- backgroundColor: theme.colors.text.default,
27
- borderColor: theme.colors.background.surface,
28
- },
29
- ]}>
30
- <Icon
31
- source="navigation_close"
32
- color={theme.colors.background.surface}
33
- size={14}
34
- />
23
+ style={styles.iconButton}>
24
+ <View
25
+ style={[
26
+ styles.iconClose,
27
+ {
28
+ backgroundColor: theme.colors.text.default,
29
+ borderColor: theme.colors.background.surface,
30
+ },
31
+ ]}>
32
+ <Icon
33
+ source="navigation_close"
34
+ color={theme.colors.background.surface}
35
+ size={14}
36
+ />
37
+ </View>
35
38
  </TouchableOpacity>
36
39
  </View>
37
40
  );
@@ -58,7 +61,10 @@ const styles = StyleSheet.create({
58
61
  width: '100%',
59
62
  flexDirection: 'row',
60
63
  justifyContent: 'center',
61
- marginTop: Spacing.L,
64
+ marginTop: Spacing.S,
65
+ },
66
+ iconButton: {
67
+ padding: 8,
62
68
  },
63
69
  iconClose: {
64
70
  width: 20,
@@ -0,0 +1,51 @@
1
+ const scanner = require('react-scanner');
2
+ const path = require('path');
3
+
4
+ const scan = async config => {
5
+ return await scanner.run(config);
6
+ };
7
+
8
+ const calcSum = array => {
9
+ return array.reduce((a, b) => a + b, 0);
10
+ };
11
+
12
+ const calculateAdoptionRate = (kitJsonPath, miniappJsonPath) => {
13
+ const kitJson = require(kitJsonPath);
14
+ const miniAppJson = require(miniappJsonPath);
15
+ const numOfKitComponents = calcSum(Object.values(kitJson));
16
+ const numOfMiniAppComponents = calcSum(Object.values(miniAppJson));
17
+ const adoptionRate = (numOfKitComponents / numOfMiniAppComponents) * 100;
18
+ console.log("Number of kit's components: ", numOfKitComponents);
19
+ console.log("Number of miniapp's components: ", numOfMiniAppComponents);
20
+ console.log('Adoption rate: ', adoptionRate);
21
+ };
22
+
23
+ const main = async () => {
24
+ const [scanPath, kitJsonRelativePath, miniappJsonRelativePath] =
25
+ process.argv.slice(2);
26
+
27
+ const kitJsonPath = path.resolve(process.cwd(), kitJsonRelativePath);
28
+ const miniappJsonPath = path.resolve(process.cwd(), miniappJsonRelativePath);
29
+
30
+ const config1 = {
31
+ crawlFrom: scanPath,
32
+ includeSubComponents: true,
33
+ importedFrom: /@momo-kits\/.+/,
34
+ processors: [['count-components', {outputTo: kitJsonPath}]],
35
+ rootDir: './',
36
+ };
37
+
38
+ const config2 = {
39
+ crawlFrom: scanPath,
40
+ includeSubComponents: true,
41
+ processors: [['count-components', {outputTo: miniappJsonPath}]],
42
+ rootDir: './',
43
+ };
44
+
45
+ await scan(config1);
46
+ await scan(config2);
47
+
48
+ calculateAdoptionRate(kitJsonPath, miniappJsonPath);
49
+ };
50
+
51
+ main().catch(console.error);
package/index.ts CHANGED
@@ -43,3 +43,5 @@ export * from './Tag';
43
43
  export * from './Tag/types';
44
44
  export * from './Pagination';
45
45
  export * from './Pagination/types';
46
+ export * from './Loader';
47
+ export * from './Loader/types';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.77.7",
3
+ "version": "0.77.8-beta.02",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {
@@ -10,14 +10,16 @@
10
10
  "@momo-kits/foundation"
11
11
  ],
12
12
  "dependencies": {
13
+ "@gorhom/bottom-sheet": "2.4.1",
13
14
  "react-native-safe-area-context": "3.1.4",
14
15
  "react-native-linear-gradient": "2.5.6",
16
+ "react-native-gesture-handler": "1.10.3",
17
+ "react-native-fast-image": "8.1.5",
15
18
  "@react-navigation/bottom-tabs": "git+https://gitlab.com/dung.huynh1/react-navigation-bottom-tabs.git#main",
16
19
  "@react-navigation/core": "5.16.1",
17
20
  "@react-navigation/native": "5.9.8",
18
21
  "@react-navigation/routers": "5.7.4",
19
- "@react-navigation/stack": "git+https://gitlab.com/dung.huynh1/react-navigation-stack.git#main",
20
- "@gorhom/bottom-sheet": "2.4.1"
22
+ "@react-navigation/stack": "git+https://gitlab.com/dung.huynh1/react-navigation-stack.git#main"
21
23
  },
22
24
  "peerDependencies": {
23
25
  "react-native": "*"
@@ -34,7 +36,8 @@
34
36
  "jest": "^26.6.3",
35
37
  "metro-react-native-babel-preset": "^0.64.0",
36
38
  "react-test-renderer": "17.0.1",
37
- "typescript": "^4.0.3"
39
+ "typescript": "^4.0.3",
40
+ "react-scanner": "^1.1.0"
38
41
  },
39
42
  "author": "@momo-kits/foundation",
40
43
  "license": "ISC"
@@ -1,54 +0,0 @@
1
- import {Platform, StyleSheet, TouchableOpacity as TouchRN} from 'react-native';
2
- import {TouchableOpacity as TouchGesture} from 'react-native-gesture-handler';
3
- import React, {useContext} from 'react';
4
- import {NavigationButtonProps} from './types';
5
- import {ApplicationContext} from './index';
6
- import {Icon} from '../Icon';
7
- import {Colors} from '../Consts';
8
-
9
- const TouchableOpacity = Platform.OS === 'ios' ? TouchRN : TouchGesture;
10
- const NavigationButton: React.FC<NavigationButtonProps> = ({
11
- icon,
12
- tintColor,
13
- onPress,
14
- backgroundColor,
15
- useBorder = true,
16
- accessibilityLabel,
17
- }) => {
18
- const {theme} = useContext(ApplicationContext);
19
- if (!backgroundColor && tintColor != Colors.black_01) {
20
- backgroundColor = theme.colors.background.surface;
21
- }
22
-
23
- return (
24
- <TouchableOpacity
25
- accessibilityLabel={`NavigationButton/${accessibilityLabel}`}
26
- style={[
27
- styles.container,
28
- {
29
- backgroundColor: backgroundColor ?? '#00000066',
30
- borderWidth: useBorder && backgroundColor ? 0.5 : 0,
31
- },
32
- ]}
33
- onPress={onPress}>
34
- <Icon
35
- source={icon}
36
- color={tintColor ?? theme.colors.text.default}
37
- size={20}
38
- />
39
- </TouchableOpacity>
40
- );
41
- };
42
-
43
- const styles = StyleSheet.create({
44
- container: {
45
- height: 28,
46
- width: 28,
47
- borderRadius: 14,
48
- borderColor: '#00000066',
49
- justifyContent: 'center',
50
- alignItems: 'center',
51
- },
52
- });
53
-
54
- export default NavigationButton;