@momo-kits/foundation 1.0.15 → 1.0.16
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 +3 -2
- package/Consts/theme.ts +1 -1
- package/Input/common.tsx +6 -1
- package/Pagination/Dot.tsx +16 -0
- package/Pagination/PaginationDot.tsx +33 -0
- package/Pagination/PaginationNumber.tsx +22 -0
- package/Pagination/PaginationScroll.tsx +88 -0
- package/Pagination/PaginationWhiteDot.tsx +32 -0
- package/Pagination/index.tsx +25 -0
- package/Pagination/styles.ts +47 -0
- package/Pagination/types.ts +19 -0
- package/Radio/styles.ts +2 -2
- package/Tag/index.tsx +74 -0
- package/Tag/styles.ts +24 -0
- package/Tag/types.ts +10 -0
- package/index.ts +4 -0
- package/package.json +1 -1
package/Button/index.tsx
CHANGED
|
@@ -27,6 +27,7 @@ export interface ButtonProps extends TouchableOpacityProps {
|
|
|
27
27
|
iconLeft?: string;
|
|
28
28
|
title: string;
|
|
29
29
|
useTintColor?: boolean;
|
|
30
|
+
onPress: () => void;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
const Button: FC<ButtonProps> = ({
|
|
@@ -211,11 +212,11 @@ const Button: FC<ButtonProps> = ({
|
|
|
211
212
|
full && {width: '100%'},
|
|
212
213
|
]);
|
|
213
214
|
|
|
214
|
-
const onPressButton = (
|
|
215
|
+
const onPressButton = () => {
|
|
215
216
|
if (type === 'disabled') {
|
|
216
217
|
return () => {};
|
|
217
218
|
}
|
|
218
|
-
onPress?.(
|
|
219
|
+
onPress?.();
|
|
219
220
|
};
|
|
220
221
|
|
|
221
222
|
const activeOpacity = type === 'disabled' ? 0.75 : 0.5;
|
package/Consts/theme.ts
CHANGED
package/Input/common.tsx
CHANGED
|
@@ -4,6 +4,7 @@ import {Text} from '../Text';
|
|
|
4
4
|
import React, {FC, useContext} from 'react';
|
|
5
5
|
import {ApplicationContext} from '../Navigation';
|
|
6
6
|
import {Icon} from '../Icon';
|
|
7
|
+
import {Styles} from '../Consts';
|
|
7
8
|
|
|
8
9
|
type FloatingViewProps = {
|
|
9
10
|
floatingValue?: string;
|
|
@@ -55,7 +56,11 @@ export const ErrorView: FC<{errorMessage?: string}> = ({errorMessage}) => {
|
|
|
55
56
|
<View style={styles.errorIcon}>
|
|
56
57
|
<Icon color={errorColor} source="ic_error" size={16} />
|
|
57
58
|
</View>
|
|
58
|
-
<Text
|
|
59
|
+
<Text
|
|
60
|
+
style={Styles.flex}
|
|
61
|
+
color={errorColor}
|
|
62
|
+
numberOfLines={1}
|
|
63
|
+
typography={'description_s'}>
|
|
59
64
|
{errorMessage}
|
|
60
65
|
</Text>
|
|
61
66
|
</View>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React, {FC, useContext} from 'react';
|
|
2
|
+
import {Animated} from 'react-native';
|
|
3
|
+
import styles from './styles';
|
|
4
|
+
import {DotProps} from './types';
|
|
5
|
+
import {ApplicationContext} from '../Navigation';
|
|
6
|
+
|
|
7
|
+
const Dot: FC<DotProps> = ({active, style}) => {
|
|
8
|
+
const {theme} = useContext(ApplicationContext);
|
|
9
|
+
const dotStyle = active
|
|
10
|
+
? [styles.activeDot]
|
|
11
|
+
: [styles.inactiveDot, {backgroundColor: theme.colors.background.pressed}];
|
|
12
|
+
|
|
13
|
+
return <Animated.View style={[style, dotStyle]} />;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default Dot;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React, {FC, useContext} from 'react';
|
|
2
|
+
import {View} from 'react-native';
|
|
3
|
+
import {ChildPaginationProps} from './types';
|
|
4
|
+
import Dot from './Dot';
|
|
5
|
+
import styles from './styles';
|
|
6
|
+
import {Spacing} from '../Consts';
|
|
7
|
+
import {ApplicationContext} from '../Navigation';
|
|
8
|
+
|
|
9
|
+
const PaginationDot: FC<ChildPaginationProps> = ({
|
|
10
|
+
dataLength = 2,
|
|
11
|
+
activeIndex = 0,
|
|
12
|
+
}) => {
|
|
13
|
+
const {theme} = useContext(ApplicationContext);
|
|
14
|
+
const renderDots = () => {
|
|
15
|
+
const dots = [];
|
|
16
|
+
for (let i = 0; i < dataLength; i++) {
|
|
17
|
+
dots.push(
|
|
18
|
+
<Dot
|
|
19
|
+
key={`Dot${i}`}
|
|
20
|
+
style={[
|
|
21
|
+
i !== dataLength - 1 ? {marginRight: Spacing.XS} : {},
|
|
22
|
+
{backgroundColor: theme.colors.primary},
|
|
23
|
+
]}
|
|
24
|
+
active={activeIndex === i}
|
|
25
|
+
/>,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
return dots;
|
|
29
|
+
};
|
|
30
|
+
return <View style={styles.paginationPinkContainer}>{renderDots()}</View>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export default PaginationDot;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, {FC, useContext} from 'react';
|
|
2
|
+
import {View} from 'react-native';
|
|
3
|
+
import {ChildPaginationProps} from './types';
|
|
4
|
+
import styles from './styles';
|
|
5
|
+
import {Text} from '../Text';
|
|
6
|
+
import {ApplicationContext} from '../Navigation';
|
|
7
|
+
|
|
8
|
+
const PaginationNumber: FC<ChildPaginationProps> = ({
|
|
9
|
+
activeIndex = 0,
|
|
10
|
+
dataLength = 2,
|
|
11
|
+
}) => {
|
|
12
|
+
const {theme} = useContext(ApplicationContext);
|
|
13
|
+
return (
|
|
14
|
+
<View style={[styles.paginationNumberContainer]}>
|
|
15
|
+
<Text
|
|
16
|
+
color={theme.colors.background.surface}
|
|
17
|
+
typography={'label_default'}>{`${activeIndex + 1}/${dataLength}`}</Text>
|
|
18
|
+
</View>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default PaginationNumber;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import React, {FC, useContext, useRef, useState} from 'react';
|
|
2
|
+
import {Animated, View} from 'react-native';
|
|
3
|
+
import {ScrollIndicatorProps} from './types';
|
|
4
|
+
import styles from './styles';
|
|
5
|
+
import {ApplicationContext} from '../Navigation';
|
|
6
|
+
|
|
7
|
+
const INDICATOR_WIDTH = 24;
|
|
8
|
+
const INDICATOR_CONTAINER_WIDTH = 72;
|
|
9
|
+
const PaginationScroll: FC<ScrollIndicatorProps> = ({
|
|
10
|
+
style,
|
|
11
|
+
children,
|
|
12
|
+
scrollViewRef,
|
|
13
|
+
}) => {
|
|
14
|
+
const {theme} = useContext(ApplicationContext);
|
|
15
|
+
const left = useRef(new Animated.Value(0)).current;
|
|
16
|
+
const [scrollViewWidth, setScrollViewWidth] = useState(0);
|
|
17
|
+
const [scrollContentWidth, setScrollContentWidth] = useState(0);
|
|
18
|
+
|
|
19
|
+
const translateX = () => {
|
|
20
|
+
if (scrollViewWidth && scrollContentWidth) {
|
|
21
|
+
const value = left.interpolate({
|
|
22
|
+
inputRange: [0, scrollContentWidth - scrollViewWidth],
|
|
23
|
+
outputRange: [0, INDICATOR_CONTAINER_WIDTH - INDICATOR_WIDTH],
|
|
24
|
+
extrapolate: 'clamp',
|
|
25
|
+
});
|
|
26
|
+
return {transform: [{translateX: value}]};
|
|
27
|
+
}
|
|
28
|
+
return {};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const renderScrollView = () => {
|
|
32
|
+
return (
|
|
33
|
+
<Animated.ScrollView
|
|
34
|
+
ref={scrollViewRef}
|
|
35
|
+
onScroll={Animated.event(
|
|
36
|
+
[
|
|
37
|
+
{
|
|
38
|
+
nativeEvent: {
|
|
39
|
+
contentOffset: {
|
|
40
|
+
x: left,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
{useNativeDriver: true},
|
|
46
|
+
)}
|
|
47
|
+
alwaysBounceHorizontal={false}
|
|
48
|
+
showsHorizontalScrollIndicator={false}
|
|
49
|
+
horizontal
|
|
50
|
+
style={styles.scrollView}
|
|
51
|
+
onContentSizeChange={width => {
|
|
52
|
+
setScrollContentWidth(width);
|
|
53
|
+
}}
|
|
54
|
+
onLayout={e => {
|
|
55
|
+
setScrollViewWidth(e.nativeEvent.layout.width);
|
|
56
|
+
}}>
|
|
57
|
+
{children}
|
|
58
|
+
</Animated.ScrollView>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
61
|
+
const renderIndicator = () => {
|
|
62
|
+
return (
|
|
63
|
+
<View
|
|
64
|
+
style={[
|
|
65
|
+
styles.indicatorContainer,
|
|
66
|
+
{backgroundColor: theme.colors.background.pressed},
|
|
67
|
+
]}>
|
|
68
|
+
<Animated.View
|
|
69
|
+
style={[
|
|
70
|
+
styles.indicator,
|
|
71
|
+
{
|
|
72
|
+
backgroundColor: theme.colors.primary,
|
|
73
|
+
},
|
|
74
|
+
translateX(),
|
|
75
|
+
]}
|
|
76
|
+
/>
|
|
77
|
+
</View>
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
return (
|
|
81
|
+
<View style={[style, styles.scrollContainer]}>
|
|
82
|
+
{renderScrollView()}
|
|
83
|
+
{renderIndicator()}
|
|
84
|
+
</View>
|
|
85
|
+
);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export default PaginationScroll;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React, {FC, useContext} from 'react';
|
|
2
|
+
import {View} from 'react-native';
|
|
3
|
+
import {ChildPaginationProps} from './types';
|
|
4
|
+
import styles from './styles';
|
|
5
|
+
import Dot from './Dot';
|
|
6
|
+
import {Spacing} from '../Consts';
|
|
7
|
+
import {ApplicationContext} from '../Navigation';
|
|
8
|
+
|
|
9
|
+
const PaginationWhiteDot: FC<ChildPaginationProps> = ({
|
|
10
|
+
dataLength = 2,
|
|
11
|
+
activeIndex = 0,
|
|
12
|
+
}) => {
|
|
13
|
+
const {theme} = useContext(ApplicationContext);
|
|
14
|
+
const renderDots = () => {
|
|
15
|
+
const dots = [];
|
|
16
|
+
for (let i = 0; i < dataLength; i++) {
|
|
17
|
+
dots.push(
|
|
18
|
+
<Dot
|
|
19
|
+
style={[
|
|
20
|
+
i !== dataLength - 1 ? {marginRight: Spacing.XS} : {},
|
|
21
|
+
{backgroundColor: theme.colors.background.surface},
|
|
22
|
+
]}
|
|
23
|
+
active={activeIndex === i}
|
|
24
|
+
/>,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
return dots;
|
|
28
|
+
};
|
|
29
|
+
return <View style={[styles.paginationWhiteContainer]}>{renderDots()}</View>;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default PaginationWhiteDot;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React, {FC} from 'react';
|
|
2
|
+
import {PaginationProps} from './types';
|
|
3
|
+
import PaginationWhiteDot from './PaginationWhiteDot';
|
|
4
|
+
import PaginationDot from './PaginationDot';
|
|
5
|
+
import PaginationNumber from './PaginationNumber';
|
|
6
|
+
import PaginationScroll from './PaginationScroll';
|
|
7
|
+
|
|
8
|
+
const Pagination: FC<PaginationProps> = props => {
|
|
9
|
+
const {type} = props;
|
|
10
|
+
|
|
11
|
+
const getComponent = (): any => {
|
|
12
|
+
switch (type) {
|
|
13
|
+
case 'black_white':
|
|
14
|
+
return <PaginationWhiteDot {...props} />;
|
|
15
|
+
case 'number':
|
|
16
|
+
return <PaginationNumber {...props} />;
|
|
17
|
+
default:
|
|
18
|
+
return <PaginationDot {...props} />;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
return getComponent();
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export {Pagination, PaginationScroll};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {StyleSheet} from 'react-native';
|
|
2
|
+
import {Colors, Radius, Spacing} from '../Consts';
|
|
3
|
+
|
|
4
|
+
export default StyleSheet.create({
|
|
5
|
+
activeDot: {
|
|
6
|
+
height: 4,
|
|
7
|
+
width: 12,
|
|
8
|
+
borderRadius: Radius.XS,
|
|
9
|
+
},
|
|
10
|
+
inactiveDot: {
|
|
11
|
+
height: 4,
|
|
12
|
+
width: 4,
|
|
13
|
+
borderRadius: Radius.XS,
|
|
14
|
+
},
|
|
15
|
+
paginationPinkContainer: {
|
|
16
|
+
flexDirection: 'row',
|
|
17
|
+
},
|
|
18
|
+
paginationWhiteContainer: {
|
|
19
|
+
flexDirection: 'row',
|
|
20
|
+
padding: Spacing.XS,
|
|
21
|
+
borderRadius: Radius.S,
|
|
22
|
+
backgroundColor: Colors.black_20 + '33',
|
|
23
|
+
},
|
|
24
|
+
paginationNumberContainer: {
|
|
25
|
+
paddingHorizontal: Spacing.S,
|
|
26
|
+
backgroundColor: Colors.black_20 + '33',
|
|
27
|
+
borderRadius: Radius.L,
|
|
28
|
+
},
|
|
29
|
+
scrollContainer: {
|
|
30
|
+
alignItems: 'center',
|
|
31
|
+
width: '100%',
|
|
32
|
+
},
|
|
33
|
+
scrollView: {
|
|
34
|
+
marginBottom: Spacing.L,
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
indicator: {
|
|
38
|
+
width: 24,
|
|
39
|
+
height: 4,
|
|
40
|
+
borderRadius: Radius.XS,
|
|
41
|
+
},
|
|
42
|
+
indicatorContainer: {
|
|
43
|
+
width: 72,
|
|
44
|
+
height: 4,
|
|
45
|
+
borderRadius: Radius.XS,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {ScrollView, ScrollViewProps, ViewStyle} from 'react-native';
|
|
2
|
+
import {Ref} from 'react';
|
|
3
|
+
|
|
4
|
+
export type PaginationProps = {
|
|
5
|
+
type?: 'default' | 'black_white' | 'number' | 'scroll';
|
|
6
|
+
activeIndex: number;
|
|
7
|
+
dataLength: number;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type DotProps = {
|
|
11
|
+
active: boolean;
|
|
12
|
+
style: ViewStyle | ViewStyle[];
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export interface ScrollIndicatorProps extends ScrollViewProps {
|
|
16
|
+
scrollViewRef?: Ref<ScrollView>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type ChildPaginationProps = Omit<PaginationProps, 'type'>;
|
package/Radio/styles.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {StyleSheet} from 'react-native';
|
|
2
|
-
import {Radius
|
|
2
|
+
import {Radius} from '../Consts';
|
|
3
3
|
|
|
4
4
|
export default StyleSheet.create({
|
|
5
5
|
radio: {
|
|
@@ -7,5 +7,5 @@ export default StyleSheet.create({
|
|
|
7
7
|
width: 20,
|
|
8
8
|
borderRadius: Radius.M,
|
|
9
9
|
},
|
|
10
|
-
container: {flex: 1
|
|
10
|
+
container: {flex: 1},
|
|
11
11
|
});
|
package/Tag/index.tsx
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React, {FC} from 'react';
|
|
2
|
+
import {View} from 'react-native';
|
|
3
|
+
import {TagProps} from './types';
|
|
4
|
+
import styles from './styles';
|
|
5
|
+
import {Colors} from '../Consts';
|
|
6
|
+
import {Icon} from '../Icon';
|
|
7
|
+
import {Text} from '../Text';
|
|
8
|
+
|
|
9
|
+
const backgroundColor = {
|
|
10
|
+
default: Colors.black_04,
|
|
11
|
+
orange: Colors.orange_08,
|
|
12
|
+
green: Colors.green_08,
|
|
13
|
+
red: Colors.red_08,
|
|
14
|
+
blue: Colors.blue_08,
|
|
15
|
+
grey: Colors.black_04,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const textColor = {
|
|
19
|
+
default: Colors.black_17,
|
|
20
|
+
orange: Colors.orange_03,
|
|
21
|
+
green: Colors.green_03,
|
|
22
|
+
red: Colors.red_03,
|
|
23
|
+
blue: Colors.blue_03,
|
|
24
|
+
grey: Colors.black_12,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const Tag: FC<TagProps> = ({
|
|
28
|
+
label = 'Label',
|
|
29
|
+
icon,
|
|
30
|
+
color = 'default',
|
|
31
|
+
size = 'large',
|
|
32
|
+
style,
|
|
33
|
+
customColor,
|
|
34
|
+
}) => {
|
|
35
|
+
let labelColor = textColor[color];
|
|
36
|
+
let tagColor = backgroundColor[color];
|
|
37
|
+
|
|
38
|
+
//Check if custom color is [color]_03 (only check in dev mode)
|
|
39
|
+
const validateCustomColor = (color: string) => {
|
|
40
|
+
if (__DEV__) {
|
|
41
|
+
const colorCore: {[key: string]: string} = Colors;
|
|
42
|
+
const primaryColors = Object.keys(Colors)
|
|
43
|
+
.map(i => {
|
|
44
|
+
if (i.includes('_03')) {
|
|
45
|
+
return colorCore[i];
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
.filter(color => color);
|
|
49
|
+
return primaryColors.includes(color);
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const sizeStyle =
|
|
55
|
+
size === 'large' ? styles.container : styles.mediumContainer;
|
|
56
|
+
|
|
57
|
+
if (customColor && validateCustomColor(customColor)) {
|
|
58
|
+
labelColor = Colors.black_01;
|
|
59
|
+
tagColor = customColor;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<View style={[style, sizeStyle, {backgroundColor: tagColor}]}>
|
|
64
|
+
{!!icon && (
|
|
65
|
+
<Icon style={styles.icon} size={16} source={icon} color={labelColor} />
|
|
66
|
+
)}
|
|
67
|
+
<Text color={labelColor} typography={'label_s'}>
|
|
68
|
+
{label}
|
|
69
|
+
</Text>
|
|
70
|
+
</View>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export {Tag};
|
package/Tag/styles.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {StyleSheet} from 'react-native';
|
|
2
|
+
import {Radius, Spacing} from '../Consts';
|
|
3
|
+
|
|
4
|
+
export default StyleSheet.create({
|
|
5
|
+
container: {
|
|
6
|
+
paddingHorizontal: Spacing.S,
|
|
7
|
+
borderRadius: Radius.S,
|
|
8
|
+
flexDirection: 'row',
|
|
9
|
+
height: 24,
|
|
10
|
+
alignItems: 'center',
|
|
11
|
+
justifyContent: 'center',
|
|
12
|
+
},
|
|
13
|
+
mediumContainer: {
|
|
14
|
+
paddingHorizontal: Spacing.S,
|
|
15
|
+
borderRadius: Radius.S,
|
|
16
|
+
height: 18,
|
|
17
|
+
alignItems: 'center',
|
|
18
|
+
flexDirection: 'row',
|
|
19
|
+
justifyContent: 'center',
|
|
20
|
+
},
|
|
21
|
+
icon: {
|
|
22
|
+
marginRight: Spacing.XS,
|
|
23
|
+
},
|
|
24
|
+
});
|
package/Tag/types.ts
ADDED
package/index.ts
CHANGED