@momo-kits/foundation 1.0.10 → 1.0.11
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/Image/index.tsx +2 -2
- package/Input/Input.tsx +3 -8
- package/Input/{MoneyInput.tsx → InputMoney.tsx} +15 -27
- package/Input/{SearchInput.tsx → InputSearch.tsx} +4 -3
- package/Input/{TextArea.tsx → InputTextArea.tsx} +6 -5
- package/Input/common.tsx +6 -0
- package/Input/index.tsx +7 -7
- package/Input/utils.ts +63 -0
- package/Layout/ScreenContainer.tsx +4 -1
- package/Navigation/BottomTab.tsx +41 -0
- package/Navigation/Components.tsx +1 -12
- package/Navigation/ModalScreen.tsx +5 -1
- package/Navigation/NavigationButton.tsx +5 -0
- package/Navigation/index.ts +2 -0
- package/Navigation/types.ts +15 -2
- package/Popup/PopupPromotion.tsx +42 -26
- package/Popup/types.ts +1 -1
- package/Radio/index.tsx +20 -6
- package/{ContentLoader → Skeleton}/index.tsx +3 -5
- package/Skeleton/types.ts +3 -0
- package/index.ts +2 -2
- package/package.json +1 -1
- package/ContentLoader/types.ts +0 -3
- /package/{ContentLoader → Skeleton}/styles.ts +0 -0
package/Image/index.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native';
|
|
|
3
3
|
import FastImage from 'react-native-fast-image';
|
|
4
4
|
import styles from './styles';
|
|
5
5
|
import {ApplicationContext} from '../Navigation';
|
|
6
|
-
import {
|
|
6
|
+
import {Skeleton} from '../Skeleton';
|
|
7
7
|
import {Icon} from '../Icon';
|
|
8
8
|
import {Styles} from '../Consts';
|
|
9
9
|
import {FastImagePropsWithoutStyle} from './types';
|
|
@@ -24,7 +24,7 @@ const Image: React.FC<ImageProps> = ({style, source, ...rest}) => {
|
|
|
24
24
|
const renderContent = () => {
|
|
25
25
|
if (loading || fail) {
|
|
26
26
|
let content = (
|
|
27
|
-
<
|
|
27
|
+
<Skeleton style={[StyleSheet.absoluteFill, styles.image]} />
|
|
28
28
|
);
|
|
29
29
|
if (fail) {
|
|
30
30
|
content = (
|
package/Input/Input.tsx
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import {ApplicationContext} from '../Navigation';
|
|
10
10
|
import styles from './styles';
|
|
11
11
|
import {Image} from '../Image';
|
|
12
|
-
import {ErrorView, FloatingView, getBorderColor} from './common';
|
|
12
|
+
import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
13
13
|
import {InputProps} from './index';
|
|
14
14
|
import {Icon} from '../Icon';
|
|
15
15
|
|
|
@@ -36,17 +36,12 @@ const Input: FC<InputProps> = ({
|
|
|
36
36
|
|
|
37
37
|
const onClearText = () => {
|
|
38
38
|
inputRef?.current?.clear();
|
|
39
|
+
_onChangeText('');
|
|
39
40
|
};
|
|
40
41
|
|
|
41
42
|
const _onChangeText = (text: string) => {
|
|
42
43
|
onChangeText?.(text);
|
|
43
44
|
};
|
|
44
|
-
const getSizeStyle = () => {
|
|
45
|
-
if (size === 'small') {
|
|
46
|
-
return styles.smallContainer;
|
|
47
|
-
}
|
|
48
|
-
return styles.container;
|
|
49
|
-
};
|
|
50
45
|
|
|
51
46
|
const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
|
52
47
|
setFocused(true);
|
|
@@ -73,7 +68,7 @@ const Input: FC<InputProps> = ({
|
|
|
73
68
|
return (
|
|
74
69
|
<View
|
|
75
70
|
style={[
|
|
76
|
-
getSizeStyle(),
|
|
71
|
+
getSizeStyle(size),
|
|
77
72
|
getBorderColor(focused, errorMessage, disabled),
|
|
78
73
|
styles.inputWrapper,
|
|
79
74
|
{backgroundColor: theme.colors.background.surface},
|
|
@@ -9,15 +9,16 @@ import {
|
|
|
9
9
|
import {ApplicationContext} from '../Navigation';
|
|
10
10
|
import styles from './styles';
|
|
11
11
|
import {Image} from '../Image';
|
|
12
|
-
import {ErrorView, FloatingView, getBorderColor} from './common';
|
|
13
|
-
import {
|
|
12
|
+
import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
13
|
+
import {InputMoneyProps} from './index';
|
|
14
14
|
import {Icon} from '../Icon';
|
|
15
|
+
import {formatMoneyToNumber, formatNumberToMoney} from './utils';
|
|
15
16
|
|
|
16
|
-
const
|
|
17
|
+
const InputMoney: FC<InputMoneyProps> = ({
|
|
17
18
|
onChangeText,
|
|
18
19
|
floatingValue,
|
|
19
20
|
floatingIcon,
|
|
20
|
-
size,
|
|
21
|
+
size = 'small',
|
|
21
22
|
onBlur,
|
|
22
23
|
onFocus,
|
|
23
24
|
errorMessage,
|
|
@@ -30,29 +31,20 @@ const MoneyInput: FC<MoneyInputProps> = ({
|
|
|
30
31
|
}) => {
|
|
31
32
|
const {theme} = useContext(ApplicationContext);
|
|
32
33
|
const [focused, setFocused] = useState(false);
|
|
33
|
-
const [value, setValue] = useState('');
|
|
34
34
|
const inputRef = useRef<any>(null);
|
|
35
|
-
|
|
35
|
+
const [value, setValue] = useState('');
|
|
36
36
|
const onClearText = () => {
|
|
37
37
|
inputRef?.current?.clear();
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const formatNumberWithDots = (num: string) => {
|
|
41
|
-
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.');
|
|
38
|
+
setValue('');
|
|
39
|
+
onChangeText?.('');
|
|
42
40
|
};
|
|
43
41
|
const _onChangeText = (text: string) => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const formattedNumber = formatNumberWithDots(numericValue);
|
|
47
|
-
const formattedValue = `${formattedNumber}đ`;
|
|
48
|
-
onChangeText?.(formattedValue);
|
|
49
|
-
setValue(formattedValue);
|
|
50
|
-
};
|
|
51
|
-
const getSizeStyle = () => {
|
|
52
|
-
if (size === 'small') {
|
|
53
|
-
return styles.smallContainer;
|
|
42
|
+
if (text.length < value.length && value.indexOf(text) === 0) {
|
|
43
|
+
text = value.slice(0, -2) + 'đ';
|
|
54
44
|
}
|
|
55
|
-
|
|
45
|
+
const valueFormat = formatMoneyToNumber(text, 'đ');
|
|
46
|
+
setValue(formatNumberToMoney(valueFormat, 'đ'));
|
|
47
|
+
onChangeText?.(formatMoneyToNumber(text, 'đ').toString());
|
|
56
48
|
};
|
|
57
49
|
|
|
58
50
|
const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
|
@@ -80,7 +72,7 @@ const MoneyInput: FC<MoneyInputProps> = ({
|
|
|
80
72
|
return (
|
|
81
73
|
<View
|
|
82
74
|
style={[
|
|
83
|
-
getSizeStyle(),
|
|
75
|
+
getSizeStyle(size),
|
|
84
76
|
getBorderColor(focused, errorMessage, disabled),
|
|
85
77
|
styles.inputWrapper,
|
|
86
78
|
{backgroundColor: theme.colors.background.surface},
|
|
@@ -144,8 +136,4 @@ const MoneyInput: FC<MoneyInputProps> = ({
|
|
|
144
136
|
);
|
|
145
137
|
};
|
|
146
138
|
|
|
147
|
-
|
|
148
|
-
size: 'small',
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
export default MoneyInput;
|
|
139
|
+
export default InputMoney;
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
TouchableOpacity,
|
|
7
7
|
View,
|
|
8
8
|
} from 'react-native';
|
|
9
|
-
import {
|
|
9
|
+
import {InputSearchProps} from './index';
|
|
10
10
|
import {getBorderColor} from './common';
|
|
11
11
|
import {ApplicationContext} from '../Navigation';
|
|
12
12
|
import styles from './styles';
|
|
@@ -14,7 +14,7 @@ import {Icon} from '../Icon';
|
|
|
14
14
|
import {Image} from '../Image';
|
|
15
15
|
import {Text} from '../Text';
|
|
16
16
|
|
|
17
|
-
const
|
|
17
|
+
const InputSearch: FC<InputSearchProps> = ({
|
|
18
18
|
errorMessage,
|
|
19
19
|
disabled,
|
|
20
20
|
placeholder,
|
|
@@ -47,6 +47,7 @@ const SearchInput: FC<SearchInputProps> = ({
|
|
|
47
47
|
|
|
48
48
|
const onClearText = () => {
|
|
49
49
|
inputRef?.current?.clear();
|
|
50
|
+
_onChangeText('');
|
|
50
51
|
};
|
|
51
52
|
|
|
52
53
|
const _onChangeText = (text: string) => {
|
|
@@ -148,4 +149,4 @@ const SearchInput: FC<SearchInputProps> = ({
|
|
|
148
149
|
);
|
|
149
150
|
};
|
|
150
151
|
|
|
151
|
-
export default
|
|
152
|
+
export default InputSearch;
|
|
@@ -16,10 +16,10 @@ import {
|
|
|
16
16
|
getBorderColor,
|
|
17
17
|
MAX_LENGTH,
|
|
18
18
|
} from './common';
|
|
19
|
-
import {
|
|
19
|
+
import {InputTextAreaProps} from './index';
|
|
20
20
|
import {Icon} from '../Icon';
|
|
21
21
|
|
|
22
|
-
const
|
|
22
|
+
const InputTextArea: FC<InputTextAreaProps> = props => {
|
|
23
23
|
const {theme} = useContext(ApplicationContext);
|
|
24
24
|
const {
|
|
25
25
|
errorMessage,
|
|
@@ -44,6 +44,7 @@ const TextArea: FC<TextAreaProps> = props => {
|
|
|
44
44
|
|
|
45
45
|
const onClearText = () => {
|
|
46
46
|
inputRef?.current?.clear();
|
|
47
|
+
_onChangeText('');
|
|
47
48
|
};
|
|
48
49
|
|
|
49
50
|
const _onChangeText = (text: string) => {
|
|
@@ -84,7 +85,7 @@ const TextArea: FC<TextAreaProps> = props => {
|
|
|
84
85
|
<View
|
|
85
86
|
style={[
|
|
86
87
|
getBorderColor(focused, errorMessage, disabled),
|
|
87
|
-
styles.
|
|
88
|
+
styles.textAreaWrapper,
|
|
88
89
|
{
|
|
89
90
|
height: height || DEFAULT_HEIGHT,
|
|
90
91
|
backgroundColor: theme.colors.background.surface,
|
|
@@ -144,8 +145,8 @@ const TextArea: FC<TextAreaProps> = props => {
|
|
|
144
145
|
);
|
|
145
146
|
};
|
|
146
147
|
|
|
147
|
-
|
|
148
|
+
InputTextArea.defaultProps = {
|
|
148
149
|
maxLength: MAX_LENGTH,
|
|
149
150
|
};
|
|
150
151
|
|
|
151
|
-
export default
|
|
152
|
+
export default InputTextArea;
|
package/Input/common.tsx
CHANGED
|
@@ -41,6 +41,12 @@ export const getBorderColor = (
|
|
|
41
41
|
return {borderColor};
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
+
export const getSizeStyle = (size?: 'small' | 'large') => {
|
|
45
|
+
if (size === 'small') {
|
|
46
|
+
return styles.smallContainer;
|
|
47
|
+
}
|
|
48
|
+
return styles.container;
|
|
49
|
+
};
|
|
44
50
|
export const ErrorView: FC<{errorMessage?: string}> = ({errorMessage}) => {
|
|
45
51
|
const {theme} = useContext(ApplicationContext);
|
|
46
52
|
const errorColor = theme.colors.error.primary;
|
package/Input/index.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Input from './Input';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
2
|
+
import InputTextArea from './InputTextArea';
|
|
3
|
+
import InputSearch from './InputSearch';
|
|
4
|
+
import InputMoney from './InputMoney';
|
|
5
5
|
import {TextInputProps} from 'react-native';
|
|
6
6
|
|
|
7
7
|
export interface InputProps extends TextInputProps {
|
|
@@ -23,16 +23,16 @@ type InputPropsWithoutSizeAndIcon = Omit<
|
|
|
23
23
|
type InputPropsWithoutRequiredAndSize = Omit<InputProps, 'required' | 'size'>;
|
|
24
24
|
type InputPropsWithoutPlaceholder = Omit<InputProps, 'placeholder'>;
|
|
25
25
|
|
|
26
|
-
export interface
|
|
26
|
+
export interface InputTextAreaProps extends InputPropsWithoutSizeAndIcon {
|
|
27
27
|
height?: number;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export interface
|
|
30
|
+
export interface InputSearchProps extends InputPropsWithoutRequiredAndSize {
|
|
31
31
|
buttonText?: string;
|
|
32
32
|
showButtonText?: boolean;
|
|
33
33
|
showIcon?: boolean;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export interface
|
|
36
|
+
export interface InputMoneyProps extends InputPropsWithoutPlaceholder {}
|
|
37
37
|
|
|
38
|
-
export {Input,
|
|
38
|
+
export {Input, InputTextArea, InputSearch, InputMoney};
|
package/Input/utils.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const formatNumberToMoney = (number: number, currency = '') => {
|
|
2
|
+
if (!number || isNaN(number) || Number(number) === 0) {
|
|
3
|
+
return `0${currency}`;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const array = [];
|
|
7
|
+
let result = '';
|
|
8
|
+
let isNegative = false;
|
|
9
|
+
|
|
10
|
+
if (number < 0) {
|
|
11
|
+
isNegative = true;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const numberString = Math.abs(number).toString();
|
|
15
|
+
if (numberString.length < 3) {
|
|
16
|
+
return numberString + currency;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let count = 0;
|
|
20
|
+
for (let i = numberString.length - 1; i >= 0; i -= 1) {
|
|
21
|
+
count += 1;
|
|
22
|
+
if (numberString[i] === '.' || numberString[i] === ',') {
|
|
23
|
+
array.push(',');
|
|
24
|
+
count = 0;
|
|
25
|
+
} else {
|
|
26
|
+
array.push(numberString[i]);
|
|
27
|
+
}
|
|
28
|
+
if (count === 3 && i >= 1) {
|
|
29
|
+
array.push('.');
|
|
30
|
+
count = 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
for (let i = array.length - 1; i >= 0; i -= 1) {
|
|
35
|
+
result += array[i];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (isNegative) {
|
|
39
|
+
result = `-${result}`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return result + currency;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const formatMoneyToNumber = (money: string, currencyUnit: string) => {
|
|
46
|
+
if (money && money.length > 0) {
|
|
47
|
+
const moneyString = money
|
|
48
|
+
.replace(currencyUnit, '')
|
|
49
|
+
.replace(/,/g, '')
|
|
50
|
+
.replace(/đ/g, '')
|
|
51
|
+
.replace(/\./g, '')
|
|
52
|
+
.replace(/ /g, '');
|
|
53
|
+
const number = Number(moneyString);
|
|
54
|
+
if (isNaN(number)) {
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
return number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return Number(money);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export {formatMoneyToNumber, formatNumberToMoney};
|
|
@@ -11,6 +11,7 @@ const ScreenContainer: React.FC<ScreenContainerProps> = ({
|
|
|
11
11
|
edges,
|
|
12
12
|
enableKeyboardAvoidingView,
|
|
13
13
|
scrollable,
|
|
14
|
+
scrollViewProps,
|
|
14
15
|
}) => {
|
|
15
16
|
let Component: any = View;
|
|
16
17
|
const headerHeight = useHeaderHeight();
|
|
@@ -50,7 +51,9 @@ const ScreenContainer: React.FC<ScreenContainerProps> = ({
|
|
|
50
51
|
ios: 'padding',
|
|
51
52
|
android: undefined,
|
|
52
53
|
})}>
|
|
53
|
-
<Component style={Styles.flex}>
|
|
54
|
+
<Component {...scrollViewProps} style={Styles.flex}>
|
|
55
|
+
{renderContent()}
|
|
56
|
+
</Component>
|
|
54
57
|
</KeyboardAvoidingView>
|
|
55
58
|
</SafeAreaView>
|
|
56
59
|
);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React, {FC} from 'react';
|
|
2
|
+
import {View} from 'react-native';
|
|
3
|
+
import {BottomTabItemProps, BottomTabProps} from './types';
|
|
4
|
+
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
|
|
5
|
+
import {Icon} from '@momo-kits/foundation';
|
|
6
|
+
|
|
7
|
+
const Tab = createBottomTabNavigator();
|
|
8
|
+
|
|
9
|
+
const BottomTab: FC<BottomTabProps> = ({tabs}) => {
|
|
10
|
+
return (
|
|
11
|
+
<Tab.Navigator>
|
|
12
|
+
{tabs.map((item, index) => {
|
|
13
|
+
return (
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
<Tab.Screen
|
|
16
|
+
key={`${item.label}-${index}`}
|
|
17
|
+
name={item.label}
|
|
18
|
+
component={item.component}
|
|
19
|
+
options={{
|
|
20
|
+
tabBarLabel: item.label,
|
|
21
|
+
tabBarBadge: item?.badgeLabel,
|
|
22
|
+
tabBarBadgeStyle: {
|
|
23
|
+
borderColor: 'white',
|
|
24
|
+
borderWidth: 2,
|
|
25
|
+
fontSize: 10,
|
|
26
|
+
lineHeight: 14,
|
|
27
|
+
fontWeight: 'bold',
|
|
28
|
+
alignSelf: 'center',
|
|
29
|
+
},
|
|
30
|
+
tabBarIcon: ({color, size}) => (
|
|
31
|
+
<Icon source={item.icon} color={color} size={size} />
|
|
32
|
+
),
|
|
33
|
+
}}
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
})}
|
|
37
|
+
</Tab.Navigator>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default BottomTab;
|
|
@@ -88,19 +88,9 @@ const HeaderLeft: React.FC<any> = ({tintColor}) => {
|
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
-
let backgroundColor;
|
|
92
|
-
if (tintColor != Colors.black_01) {
|
|
93
|
-
backgroundColor = theme.colors.background.surface;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
91
|
return (
|
|
97
92
|
<View style={styles.headerLeft}>
|
|
98
|
-
<NavigationButton
|
|
99
|
-
icon="ic_back"
|
|
100
|
-
tintColor={tintColor}
|
|
101
|
-
backgroundColor={backgroundColor}
|
|
102
|
-
onPress={goBack}
|
|
103
|
-
/>
|
|
93
|
+
<NavigationButton icon="ic_back" tintColor={tintColor} onPress={goBack} />
|
|
104
94
|
</View>
|
|
105
95
|
);
|
|
106
96
|
};
|
|
@@ -206,7 +196,6 @@ const HeaderToolkitAction: React.FC<any> = ({tintColor}) => {
|
|
|
206
196
|
<NavigationButton
|
|
207
197
|
icon="addFavorite"
|
|
208
198
|
tintColor={tintColor}
|
|
209
|
-
backgroundColor={backgroundColor}
|
|
210
199
|
onPress={() => {}}
|
|
211
200
|
/>
|
|
212
201
|
<View
|
|
@@ -121,7 +121,11 @@ const BottomSheet: React.FC<BottomSheetParams> = ({navigation, route}) => {
|
|
|
121
121
|
<BottomSheetModal
|
|
122
122
|
ref={bottomSheetRef}
|
|
123
123
|
snapPoints={snapPoints}
|
|
124
|
-
onDismiss={
|
|
124
|
+
onDismiss={() => {
|
|
125
|
+
if (mountedRef.current) {
|
|
126
|
+
navigation.pop();
|
|
127
|
+
}
|
|
128
|
+
}}
|
|
125
129
|
handleComponent={null}
|
|
126
130
|
backdropComponent={backdropComponent}>
|
|
127
131
|
<View style={{paddingBottom: bottom}}>
|
|
@@ -3,6 +3,7 @@ import React, {useContext} from 'react';
|
|
|
3
3
|
import {NavigationButtonProps} from './types';
|
|
4
4
|
import {ApplicationContext} from './index';
|
|
5
5
|
import {Icon} from '../Icon';
|
|
6
|
+
import {Colors} from '../Consts';
|
|
6
7
|
|
|
7
8
|
const NavigationButton: React.FC<NavigationButtonProps> = ({
|
|
8
9
|
icon,
|
|
@@ -12,6 +13,10 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
|
|
|
12
13
|
useBorder = true,
|
|
13
14
|
}) => {
|
|
14
15
|
const {theme} = useContext(ApplicationContext);
|
|
16
|
+
if (!backgroundColor && tintColor != Colors.black_01) {
|
|
17
|
+
backgroundColor = theme.colors.background.surface;
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
return (
|
|
16
21
|
<TouchableOpacity
|
|
17
22
|
style={[
|
package/Navigation/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import {NavigationContainer, ApplicationContext} from './NavigationContainer';
|
|
|
2
2
|
import ScreenContainer from '../Layout/ScreenContainer';
|
|
3
3
|
import NavigationButton from './NavigationButton';
|
|
4
4
|
import {HeaderRightAction} from './Components';
|
|
5
|
+
import BottomTab from './BottomTab';
|
|
5
6
|
|
|
6
7
|
export {
|
|
7
8
|
NavigationContainer,
|
|
@@ -9,4 +10,5 @@ export {
|
|
|
9
10
|
ScreenContainer,
|
|
10
11
|
NavigationButton,
|
|
11
12
|
HeaderRightAction,
|
|
13
|
+
BottomTab,
|
|
12
14
|
};
|
package/Navigation/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {ViewProps} from 'react-native';
|
|
2
|
-
import React from 'react';
|
|
1
|
+
import {ScrollViewProps, ViewProps} from 'react-native';
|
|
2
|
+
import React, {ComponentType, ReactElement} from 'react';
|
|
3
3
|
import Navigator from './Navigator';
|
|
4
4
|
|
|
5
5
|
export type Theme = {
|
|
@@ -72,6 +72,7 @@ export interface ScreenContainerProps extends ViewProps {
|
|
|
72
72
|
edges?: any[];
|
|
73
73
|
enableKeyboardAvoidingView?: boolean;
|
|
74
74
|
scrollable: boolean;
|
|
75
|
+
scrollViewProps?: ScrollViewProps;
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
export type ScreenParams = {
|
|
@@ -121,3 +122,15 @@ export type TitleCustomProps = {
|
|
|
121
122
|
tintColor?: string;
|
|
122
123
|
content?: React.ReactNode;
|
|
123
124
|
};
|
|
125
|
+
|
|
126
|
+
export type BottomTabItemProps = {
|
|
127
|
+
label: string;
|
|
128
|
+
icon: string;
|
|
129
|
+
showDot?: boolean;
|
|
130
|
+
badgeLabel?: string;
|
|
131
|
+
component: ComponentType<any> | undefined;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export type BottomTabProps = {
|
|
135
|
+
tabs: BottomTabItemProps[];
|
|
136
|
+
};
|
package/Popup/PopupPromotion.tsx
CHANGED
|
@@ -1,21 +1,40 @@
|
|
|
1
1
|
import React, {useContext} from 'react';
|
|
2
|
-
import {StyleSheet, View} from 'react-native';
|
|
2
|
+
import {StyleSheet, TouchableOpacity, View} from 'react-native';
|
|
3
3
|
import {PopupPromotionProps} from './types';
|
|
4
4
|
import {ApplicationContext} from '../Navigation';
|
|
5
5
|
import {Image} from '../Image';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import {Radius} from '../Consts';
|
|
7
|
+
import {Icon} from '../Icon';
|
|
8
8
|
|
|
9
|
-
const PopupPromotion: React.FC<PopupPromotionProps> = ({image,
|
|
9
|
+
const PopupPromotion: React.FC<PopupPromotionProps> = ({image, onClose}) => {
|
|
10
10
|
const {theme, navigator} = useContext(ApplicationContext);
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
* @param callback
|
|
13
|
+
* build close action
|
|
15
14
|
*/
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
const buildCloseIcon = () => {
|
|
16
|
+
return (
|
|
17
|
+
<View style={styles.iconCloseContainer}>
|
|
18
|
+
<TouchableOpacity
|
|
19
|
+
onPress={() => {
|
|
20
|
+
navigator?.pop();
|
|
21
|
+
onClose?.();
|
|
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
|
+
/>
|
|
35
|
+
</TouchableOpacity>
|
|
36
|
+
</View>
|
|
37
|
+
);
|
|
19
38
|
};
|
|
20
39
|
|
|
21
40
|
return (
|
|
@@ -26,37 +45,34 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({image, primary}) => {
|
|
|
26
45
|
uri: image,
|
|
27
46
|
}}
|
|
28
47
|
/>
|
|
29
|
-
|
|
30
|
-
<Button
|
|
31
|
-
title={primary?.title}
|
|
32
|
-
onPress={() => {
|
|
33
|
-
onAction(primary?.onPress);
|
|
34
|
-
}}
|
|
35
|
-
/>
|
|
36
|
-
</View>
|
|
48
|
+
{buildCloseIcon()}
|
|
37
49
|
</>
|
|
38
50
|
);
|
|
39
51
|
};
|
|
40
52
|
|
|
41
53
|
const styles = StyleSheet.create({
|
|
42
54
|
container: {
|
|
43
|
-
aspectRatio: 0.
|
|
55
|
+
aspectRatio: 0.72,
|
|
44
56
|
},
|
|
45
|
-
|
|
57
|
+
iconCloseContainer: {
|
|
46
58
|
position: 'absolute',
|
|
47
|
-
bottom: 0,
|
|
48
59
|
width: '100%',
|
|
49
|
-
|
|
50
|
-
|
|
60
|
+
flexDirection: 'row',
|
|
61
|
+
justifyContent: 'center',
|
|
62
|
+
bottom: -36,
|
|
63
|
+
},
|
|
64
|
+
iconClose: {
|
|
65
|
+
width: 20,
|
|
66
|
+
height: 20,
|
|
67
|
+
alignItems: 'center',
|
|
68
|
+
justifyContent: 'center',
|
|
69
|
+
borderRadius: Radius.M,
|
|
70
|
+
borderWidth: 2,
|
|
51
71
|
},
|
|
52
72
|
});
|
|
53
73
|
|
|
54
74
|
PopupPromotion.defaultProps = {
|
|
55
75
|
image: 'https://google.com',
|
|
56
|
-
primary: {
|
|
57
|
-
title: 'Primary',
|
|
58
|
-
onPress: () => {},
|
|
59
|
-
},
|
|
60
76
|
};
|
|
61
77
|
|
|
62
78
|
export default PopupPromotion;
|
package/Popup/types.ts
CHANGED
package/Radio/index.tsx
CHANGED
|
@@ -17,12 +17,24 @@ const Radio: FC<RadioProps> = ({
|
|
|
17
17
|
}) => {
|
|
18
18
|
const {theme} = useContext(ApplicationContext);
|
|
19
19
|
const selected = value === groupValue;
|
|
20
|
-
|
|
21
|
-
let
|
|
20
|
+
let disabledStyle = {};
|
|
21
|
+
let checkBoxStyle = {
|
|
22
|
+
borderWidth: 2,
|
|
23
|
+
borderColor: theme.colors.text.default,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
if (selected) {
|
|
27
|
+
checkBoxStyle = {
|
|
28
|
+
borderWidth: 6,
|
|
29
|
+
borderColor: theme.colors.primary,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
22
32
|
if (disabled) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
33
|
+
disabledStyle = {
|
|
34
|
+
borderColor: selected
|
|
35
|
+
? theme.colors.background.tonal
|
|
36
|
+
: theme.colors.text.disable,
|
|
37
|
+
};
|
|
26
38
|
}
|
|
27
39
|
|
|
28
40
|
return (
|
|
@@ -39,7 +51,9 @@ const Radio: FC<RadioProps> = ({
|
|
|
39
51
|
<View
|
|
40
52
|
style={[
|
|
41
53
|
styles.radio,
|
|
42
|
-
|
|
54
|
+
checkBoxStyle,
|
|
55
|
+
disabledStyle,
|
|
56
|
+
{marginRight: !!label ? Spacing.XS : 0},
|
|
43
57
|
]}
|
|
44
58
|
/>
|
|
45
59
|
{!!label && <Text typography={'description_default'}>{label}</Text>}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React, {useContext, useEffect, useMemo, useRef} from 'react';
|
|
2
2
|
import {Animated, Platform, useWindowDimensions, View} from 'react-native';
|
|
3
3
|
import LinearGradient from 'react-native-linear-gradient';
|
|
4
|
-
import {
|
|
4
|
+
import {SkeletonTypes} from './types';
|
|
5
5
|
import {ApplicationContext} from '../Navigation';
|
|
6
6
|
import {Styles} from '../Consts';
|
|
7
7
|
import styles from './styles';
|
|
8
|
-
const
|
|
8
|
+
const Skeleton: React.FC<SkeletonTypes> = ({style}) => {
|
|
9
9
|
const {width} = useWindowDimensions();
|
|
10
10
|
const {theme} = useContext(ApplicationContext);
|
|
11
11
|
const beginShimmerPosition = useRef(new Animated.Value(-1)).current;
|
|
@@ -62,6 +62,4 @@ const ContentLoader: React.FC<ContentLoaderTypes> = ({style}) => {
|
|
|
62
62
|
);
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
export {ContentLoader};
|
|
65
|
+
export {Skeleton};
|
package/index.ts
CHANGED
|
@@ -22,8 +22,8 @@ export * from './Icon/types';
|
|
|
22
22
|
export * from './IconButton';
|
|
23
23
|
export * from './Image';
|
|
24
24
|
export * from './Image/types';
|
|
25
|
-
export * from './
|
|
26
|
-
export * from './
|
|
25
|
+
export * from './Skeleton';
|
|
26
|
+
export * from './Skeleton/types';
|
|
27
27
|
export * from './CheckBox';
|
|
28
28
|
export * from './CheckBox/types';
|
|
29
29
|
export * from './Radio';
|
package/package.json
CHANGED
package/ContentLoader/types.ts
DELETED
|
File without changes
|