@momo-kits/foundation 1.0.15 → 1.0.17
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/Input.tsx +1 -1
- package/Input/InputMoney.tsx +1 -1
- package/Input/InputSearch.tsx +2 -2
- package/Input/common.tsx +9 -4
- package/Layout/ScreenContainer.tsx +1 -1
- package/Navigation/Components.tsx +2 -2
- 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/Popup/PopupNotify.tsx +6 -6
- package/Radio/index.tsx +1 -1
- package/Radio/styles.ts +2 -2
- package/Tag/index.tsx +79 -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/Input.tsx
CHANGED
package/Input/InputMoney.tsx
CHANGED
package/Input/InputSearch.tsx
CHANGED
|
@@ -103,7 +103,7 @@ const InputSearch: FC<InputSearchProps> = ({
|
|
|
103
103
|
/>
|
|
104
104
|
</TouchableOpacity>
|
|
105
105
|
)}
|
|
106
|
-
{icon
|
|
106
|
+
{!!icon && (
|
|
107
107
|
<View style={{flexDirection: 'row'}}>
|
|
108
108
|
<View
|
|
109
109
|
style={[
|
|
@@ -115,7 +115,7 @@ const InputSearch: FC<InputSearchProps> = ({
|
|
|
115
115
|
/>
|
|
116
116
|
<Icon
|
|
117
117
|
color={iconTintColor}
|
|
118
|
-
source={icon
|
|
118
|
+
source={icon}
|
|
119
119
|
style={styles.iconSearchInput}
|
|
120
120
|
/>
|
|
121
121
|
</View>
|
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;
|
|
@@ -29,7 +30,7 @@ export const getBorderColor = (
|
|
|
29
30
|
borderColor = theme.colors.primary;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
if (
|
|
33
|
+
if (errorMessage) {
|
|
33
34
|
borderColor = theme.colors.error.primary;
|
|
34
35
|
}
|
|
35
36
|
|
|
@@ -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>
|
|
@@ -98,10 +103,10 @@ export const FloatingView: FC<FloatingViewProps> = ({
|
|
|
98
103
|
</Text>
|
|
99
104
|
)}
|
|
100
105
|
</Text>
|
|
101
|
-
{floatingIcon
|
|
106
|
+
{!!floatingIcon && (
|
|
102
107
|
<Icon
|
|
103
108
|
color={floatingIconTintColor}
|
|
104
|
-
source={floatingIcon
|
|
109
|
+
source={floatingIcon}
|
|
105
110
|
size={16}
|
|
106
111
|
style={styles.floatingIcon}
|
|
107
112
|
/>
|
|
@@ -139,7 +139,7 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
|
139
139
|
<StatusBar
|
|
140
140
|
barStyle={headerImage || theme.dark ? 'light-content' : 'dark-content'}
|
|
141
141
|
/>
|
|
142
|
-
{headerImage
|
|
142
|
+
{!!headerImage && (
|
|
143
143
|
<Image style={styles.headerBackground} source={{uri: headerImage}} />
|
|
144
144
|
)}
|
|
145
145
|
</Animated.View>
|
|
@@ -160,7 +160,7 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
|
|
|
160
160
|
<View style={Styles.row}>
|
|
161
161
|
<View>
|
|
162
162
|
<Image source={{uri: image}} style={avatarStyle} />
|
|
163
|
-
{dotColor
|
|
163
|
+
{!!dotColor && (
|
|
164
164
|
<View style={[styles.dotAvatar, {backgroundColor: dotColor}]} />
|
|
165
165
|
)}
|
|
166
166
|
</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/Popup/PopupNotify.tsx
CHANGED
|
@@ -36,11 +36,11 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
36
36
|
const renderRow = () => {
|
|
37
37
|
return (
|
|
38
38
|
<View style={Styles.row}>
|
|
39
|
-
{secondary?.title
|
|
39
|
+
{!!secondary?.title && (
|
|
40
40
|
<>
|
|
41
41
|
<View style={Styles.flex}>
|
|
42
42
|
<Button
|
|
43
|
-
title={secondary?.title
|
|
43
|
+
title={secondary?.title}
|
|
44
44
|
type="text"
|
|
45
45
|
size="medium"
|
|
46
46
|
onPress={() => {
|
|
@@ -73,11 +73,11 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
73
73
|
onAction(primary.onPress);
|
|
74
74
|
}}
|
|
75
75
|
/>
|
|
76
|
-
{secondary?.title
|
|
76
|
+
{!!secondary?.title && (
|
|
77
77
|
<>
|
|
78
78
|
<View style={styles.buttonSpace} />
|
|
79
79
|
<Button
|
|
80
|
-
title={secondary?.title
|
|
80
|
+
title={secondary?.title}
|
|
81
81
|
type="text"
|
|
82
82
|
size="medium"
|
|
83
83
|
onPress={() => {
|
|
@@ -137,7 +137,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
137
137
|
styles.container,
|
|
138
138
|
{backgroundColor: theme.colors.background.surface},
|
|
139
139
|
]}>
|
|
140
|
-
{image && <Image source={{uri: image}} style={styles.image} />}
|
|
140
|
+
{!!image && <Image source={{uri: image}} style={styles.image} />}
|
|
141
141
|
<View style={styles.content}>
|
|
142
142
|
<Text typography={'title_xs'} numberOfLines={1}>
|
|
143
143
|
{title}
|
|
@@ -147,7 +147,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
147
147
|
{description}
|
|
148
148
|
</Text>
|
|
149
149
|
</View>
|
|
150
|
-
{information
|
|
150
|
+
{!!information && (
|
|
151
151
|
<View style={styles.information}>
|
|
152
152
|
<Text
|
|
153
153
|
typography={'description_xs'}
|
package/Radio/index.tsx
CHANGED
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,79 @@
|
|
|
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
|
|
66
|
+
style={styles.icon}
|
|
67
|
+
size={16}
|
|
68
|
+
source={icon as string}
|
|
69
|
+
color={labelColor}
|
|
70
|
+
/>
|
|
71
|
+
)}
|
|
72
|
+
<Text color={labelColor} typography={'label_s'}>
|
|
73
|
+
{label}
|
|
74
|
+
</Text>
|
|
75
|
+
</View>
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
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