@momo-kits/foundation 0.92.6-rc.1 → 0.92.6-rc.10
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/Application/ModalScreen.tsx +1 -1
- package/Application/Navigation.ts +2 -2
- package/Application/StackScreen.tsx +1 -1
- package/Application/types.ts +1 -1
- package/Icon/types.ts +2 -1
- package/Image/index.tsx +38 -34
- package/Input/Input.tsx +28 -7
- package/Input/InputDropDown.tsx +10 -5
- package/Input/InputMoney.tsx +13 -4
- package/Input/InputOTP.tsx +14 -6
- package/Input/InputSearch.tsx +19 -4
- package/Input/InputTextArea.tsx +26 -6
- package/Input/common.tsx +27 -13
- package/Input/index.tsx +19 -5
- package/Layout/FloatingButton.tsx +128 -0
- package/Layout/Screen.tsx +49 -26
- package/Layout/styles.ts +11 -7
- package/Layout/utils.ts +2 -2
- package/Popup/PopupNotify.tsx +30 -30
- package/Popup/types.ts +0 -6
- package/package.json +2 -4
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import {Modalize} from 'react-native-modalize';
|
|
11
11
|
import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
|
|
12
12
|
|
|
13
|
-
import {ApplicationContext} from '
|
|
13
|
+
import {ApplicationContext} from './index';
|
|
14
14
|
import {Radius, Spacing, Styles} from '../Consts';
|
|
15
15
|
import {Icon} from '../Icon';
|
|
16
16
|
import {Text} from '../Text';
|
|
@@ -6,8 +6,8 @@ import {getOptions} from './utils';
|
|
|
6
6
|
import {HeaderToolkitAction} from './Components';
|
|
7
7
|
|
|
8
8
|
class Navigation {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
instance: NavigationProp<any>;
|
|
10
|
+
readonly theme: Theme;
|
|
11
11
|
|
|
12
12
|
constructor(instance: any, theme: Theme) {
|
|
13
13
|
this.instance = instance;
|
package/Application/types.ts
CHANGED
|
@@ -120,7 +120,7 @@ export interface BottomSheetParams extends ScreenParams {
|
|
|
120
120
|
[key: string]: any;
|
|
121
121
|
onDismiss?: () => void;
|
|
122
122
|
footerComponent?: React.ReactNode;
|
|
123
|
-
flatListProps
|
|
123
|
+
flatListProps?: FlatListProps<any>;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
export type NavigationButtonProps = {
|
package/Icon/types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {ImageStyle} from 'react-native-fast-image';
|
|
2
|
+
import {StyleProp} from "react-native";
|
|
2
3
|
|
|
3
4
|
export type IconProps = {
|
|
4
5
|
/**
|
|
@@ -23,5 +24,5 @@ export type IconProps = {
|
|
|
23
24
|
* Optional. Used to apply custom styling to the Icon component.
|
|
24
25
|
* Accepts an object of style properties.
|
|
25
26
|
*/
|
|
26
|
-
style?: ImageStyle
|
|
27
|
+
style?: StyleProp<ImageStyle>;
|
|
27
28
|
};
|
package/Image/index.tsx
CHANGED
|
@@ -2,7 +2,11 @@ import React, {useContext, useEffect, useRef, useState} from 'react';
|
|
|
2
2
|
import {StyleSheet, View} from 'react-native';
|
|
3
3
|
import FastImage, {Source} from 'react-native-fast-image';
|
|
4
4
|
import styles from './styles';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
ApplicationContext,
|
|
7
|
+
ComponentContext,
|
|
8
|
+
MiniAppContext,
|
|
9
|
+
} from '../Application';
|
|
6
10
|
import {Skeleton} from '../Skeleton';
|
|
7
11
|
import {Icon} from '../Icon';
|
|
8
12
|
import {Styles} from '../Consts';
|
|
@@ -30,9 +34,9 @@ const Image: React.FC<ImageProps> = ({
|
|
|
30
34
|
};
|
|
31
35
|
|
|
32
36
|
useEffect(() => {
|
|
33
|
-
if(app.enableAutoId){
|
|
37
|
+
if (app.enableAutoId) {
|
|
34
38
|
component?.addChildren?.(test.accessibilityLabel, 'add');
|
|
35
|
-
return () => component?.addChildren(test.accessibilityLabel, 'remove');
|
|
39
|
+
return () => component?.addChildren?.(test.accessibilityLabel, 'remove');
|
|
36
40
|
}
|
|
37
41
|
}, []);
|
|
38
42
|
|
|
@@ -57,37 +61,37 @@ const Image: React.FC<ImageProps> = ({
|
|
|
57
61
|
};
|
|
58
62
|
|
|
59
63
|
return (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
64
|
+
<FastImage
|
|
65
|
+
{...rest}
|
|
66
|
+
{...test}
|
|
67
|
+
source={source}
|
|
68
|
+
style={[styles.container, style]}
|
|
69
|
+
onProgress={() => {
|
|
70
|
+
error.current = false;
|
|
71
|
+
if (status !== 'loading' && loading) {
|
|
72
|
+
setStatus('loading');
|
|
73
|
+
}
|
|
74
|
+
}}
|
|
75
|
+
onLoadStart={() => {
|
|
76
|
+
error.current = false;
|
|
77
|
+
}}
|
|
78
|
+
onLoad={() => {
|
|
79
|
+
error.current = false;
|
|
80
|
+
}}
|
|
81
|
+
onLoadEnd={() => {
|
|
82
|
+
let current: Status = 'success';
|
|
83
|
+
if (error.current) {
|
|
84
|
+
current = 'error';
|
|
85
|
+
}
|
|
86
|
+
if (status !== current) {
|
|
87
|
+
setStatus(current);
|
|
88
|
+
}
|
|
89
|
+
}}
|
|
90
|
+
onError={() => {
|
|
91
|
+
error.current = true;
|
|
92
|
+
}}>
|
|
93
|
+
{renderContent()}
|
|
94
|
+
</FastImage>
|
|
91
95
|
);
|
|
92
96
|
};
|
|
93
97
|
|
package/Input/Input.tsx
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useContext,
|
|
4
|
+
useImperativeHandle,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from 'react';
|
|
2
8
|
import {
|
|
3
9
|
NativeSyntheticEvent,
|
|
4
10
|
Platform,
|
|
@@ -8,12 +14,12 @@ import {
|
|
|
8
14
|
View,
|
|
9
15
|
} from 'react-native';
|
|
10
16
|
import {ApplicationContext, ComponentContext} from '../Application';
|
|
11
|
-
import
|
|
17
|
+
import {Icon} from '../Icon';
|
|
18
|
+
import {Loader} from '../Loader';
|
|
12
19
|
import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
13
20
|
import {InputProps} from './index';
|
|
14
|
-
import
|
|
21
|
+
import styles from './styles';
|
|
15
22
|
import {checkTyping} from './utils';
|
|
16
|
-
import {Loader} from '../Loader';
|
|
17
23
|
|
|
18
24
|
const Input = forwardRef(
|
|
19
25
|
(
|
|
@@ -42,7 +48,9 @@ const Input = forwardRef(
|
|
|
42
48
|
keyboardType,
|
|
43
49
|
style,
|
|
44
50
|
params,
|
|
51
|
+
hintText,
|
|
45
52
|
accessibilityLabel,
|
|
53
|
+
editable = true,
|
|
46
54
|
...props
|
|
47
55
|
}: InputProps,
|
|
48
56
|
ref,
|
|
@@ -51,7 +59,7 @@ const Input = forwardRef(
|
|
|
51
59
|
const [focused, setFocused] = useState(false);
|
|
52
60
|
const [haveValue, setHaveValue] = useState(!!value || !!props.defaultValue);
|
|
53
61
|
const [secureTextInput, setSecureTextInput] = useState(secureTextEntry);
|
|
54
|
-
const inputRef =
|
|
62
|
+
const inputRef = useRef<TextInput | null>(null);
|
|
55
63
|
|
|
56
64
|
const onClearText = () => {
|
|
57
65
|
inputRef?.current?.clear();
|
|
@@ -73,6 +81,15 @@ const Input = forwardRef(
|
|
|
73
81
|
onBlur?.(e);
|
|
74
82
|
};
|
|
75
83
|
|
|
84
|
+
useImperativeHandle(ref, () => {
|
|
85
|
+
return {
|
|
86
|
+
clear: onClearText,
|
|
87
|
+
focus: () => inputRef.current?.focus(),
|
|
88
|
+
blur: () => inputRef.current?.blur(),
|
|
89
|
+
setText: (text: string) => _onChangeText(text),
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
|
|
76
93
|
const renderIcon = (color: string | undefined) => {
|
|
77
94
|
if (loading) {
|
|
78
95
|
return <Loader type={'spinner'} color={color} style={styles.icon} />;
|
|
@@ -152,7 +169,7 @@ const Input = forwardRef(
|
|
|
152
169
|
<TextInput
|
|
153
170
|
{...props}
|
|
154
171
|
accessibilityLabel={accessibilityLabel}
|
|
155
|
-
editable={
|
|
172
|
+
editable={editable && !disabled}
|
|
156
173
|
secureTextEntry={secure}
|
|
157
174
|
textAlignVertical="center"
|
|
158
175
|
ref={inputRef}
|
|
@@ -217,7 +234,11 @@ const Input = forwardRef(
|
|
|
217
234
|
}}>
|
|
218
235
|
<View style={[style, styles.wrapper]}>
|
|
219
236
|
{renderInputView()}
|
|
220
|
-
<ErrorView
|
|
237
|
+
<ErrorView
|
|
238
|
+
errorMessage={errorMessage}
|
|
239
|
+
errorSpacing={errorSpacing}
|
|
240
|
+
hintText={hintText}
|
|
241
|
+
/>
|
|
221
242
|
</View>
|
|
222
243
|
</ComponentContext.Provider>
|
|
223
244
|
);
|
package/Input/InputDropDown.tsx
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React, {useContext} from 'react';
|
|
2
2
|
import {TextInput, TouchableOpacity, View} from 'react-native';
|
|
3
3
|
import {ApplicationContext, ComponentContext} from '../Application';
|
|
4
|
-
import
|
|
5
|
-
import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
6
|
-
import {InputDropDownProps} from './index';
|
|
4
|
+
import {Styles} from '../Consts';
|
|
7
5
|
import {Icon} from '../Icon';
|
|
8
6
|
import {Loader} from '../Loader';
|
|
9
|
-
import {
|
|
7
|
+
import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
8
|
+
import {InputDropDownProps} from './index';
|
|
9
|
+
import styles from './styles';
|
|
10
10
|
|
|
11
11
|
const InputDropDown = ({
|
|
12
12
|
value,
|
|
@@ -28,6 +28,7 @@ const InputDropDown = ({
|
|
|
28
28
|
style,
|
|
29
29
|
params,
|
|
30
30
|
accessibilityLabel,
|
|
31
|
+
hintText,
|
|
31
32
|
...props
|
|
32
33
|
}: InputDropDownProps) => {
|
|
33
34
|
const {theme} = useContext(ApplicationContext);
|
|
@@ -118,7 +119,11 @@ const InputDropDown = ({
|
|
|
118
119
|
onPress={onPress}
|
|
119
120
|
style={[style, full && styles.wrapper]}>
|
|
120
121
|
{renderInputView()}
|
|
121
|
-
<ErrorView
|
|
122
|
+
<ErrorView
|
|
123
|
+
errorMessage={errorMessage}
|
|
124
|
+
errorSpacing={errorSpacing}
|
|
125
|
+
hintText={hintText}
|
|
126
|
+
/>
|
|
122
127
|
</TouchableOpacity>
|
|
123
128
|
</ComponentContext.Provider>
|
|
124
129
|
);
|
package/Input/InputMoney.tsx
CHANGED
|
@@ -13,10 +13,10 @@ import {
|
|
|
13
13
|
View,
|
|
14
14
|
} from 'react-native';
|
|
15
15
|
import {ApplicationContext, ComponentContext} from '../Application';
|
|
16
|
-
import
|
|
16
|
+
import {Icon} from '../Icon';
|
|
17
17
|
import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
18
18
|
import {InputMoneyProps} from './index';
|
|
19
|
-
import
|
|
19
|
+
import styles from './styles';
|
|
20
20
|
import {formatMoneyToNumber, formatNumberToMoney} from './utils';
|
|
21
21
|
|
|
22
22
|
const InputMoney = forwardRef(
|
|
@@ -39,13 +39,14 @@ const InputMoney = forwardRef(
|
|
|
39
39
|
params,
|
|
40
40
|
defaultValue = '',
|
|
41
41
|
accessibilityLabel,
|
|
42
|
+
hintText,
|
|
42
43
|
...props
|
|
43
44
|
}: InputMoneyProps,
|
|
44
45
|
ref,
|
|
45
46
|
) => {
|
|
46
47
|
const {theme} = useContext(ApplicationContext);
|
|
47
48
|
const [focused, setFocused] = useState(false);
|
|
48
|
-
const inputRef =
|
|
49
|
+
const inputRef = useRef<TextInput>(null);
|
|
49
50
|
|
|
50
51
|
const validateText = (text: string) => {
|
|
51
52
|
const valueFormat = formatMoneyToNumber(text, 'đ');
|
|
@@ -72,6 +73,10 @@ const InputMoney = forwardRef(
|
|
|
72
73
|
|
|
73
74
|
useImperativeHandle(ref, () => {
|
|
74
75
|
return {
|
|
76
|
+
clear: onClearText,
|
|
77
|
+
focus: () => inputRef.current?.focus(),
|
|
78
|
+
blur: () => inputRef.current?.blur(),
|
|
79
|
+
changeText: (text: string) => _onChangeText(text),
|
|
75
80
|
setText: _onChangeText,
|
|
76
81
|
};
|
|
77
82
|
});
|
|
@@ -177,7 +182,11 @@ const InputMoney = forwardRef(
|
|
|
177
182
|
}}>
|
|
178
183
|
<View style={[style, styles.wrapper]}>
|
|
179
184
|
{renderInputView()}
|
|
180
|
-
<ErrorView
|
|
185
|
+
<ErrorView
|
|
186
|
+
errorMessage={errorMessage}
|
|
187
|
+
errorSpacing={errorSpacing}
|
|
188
|
+
hintText={hintText}
|
|
189
|
+
/>
|
|
181
190
|
</View>
|
|
182
191
|
</ComponentContext.Provider>
|
|
183
192
|
);
|
package/Input/InputOTP.tsx
CHANGED
|
@@ -15,12 +15,12 @@ import {
|
|
|
15
15
|
TouchableOpacity,
|
|
16
16
|
View,
|
|
17
17
|
} from 'react-native';
|
|
18
|
-
import {CaretProps, InputOTPProps} from './index';
|
|
19
|
-
import {scaleSize, Text} from '../Text';
|
|
20
|
-
import styles from './styles';
|
|
21
|
-
import {ErrorView, getBorderColor} from './common';
|
|
22
18
|
import {ApplicationContext, ComponentContext} from '../Application';
|
|
23
19
|
import {Spacing} from '../Consts';
|
|
20
|
+
import {scaleSize, Text} from '../Text';
|
|
21
|
+
import {ErrorView, getBorderColor} from './common';
|
|
22
|
+
import {CaretProps, InputOTPProps} from './index';
|
|
23
|
+
import styles from './styles';
|
|
24
24
|
|
|
25
25
|
const OTPCaret: FC<CaretProps> = ({index, length}) => {
|
|
26
26
|
const DURATION = 300;
|
|
@@ -81,6 +81,7 @@ const InputOTP = forwardRef(
|
|
|
81
81
|
params,
|
|
82
82
|
style,
|
|
83
83
|
accessibilityLabel,
|
|
84
|
+
hintText,
|
|
84
85
|
...props
|
|
85
86
|
}: InputOTPProps,
|
|
86
87
|
ref,
|
|
@@ -88,13 +89,16 @@ const InputOTP = forwardRef(
|
|
|
88
89
|
const MAX_LENGTH = 10;
|
|
89
90
|
const [value, setValue] = useState('');
|
|
90
91
|
const [focused, setFocused] = useState(false);
|
|
91
|
-
const inputRef = useRef<TextInput>(null);
|
|
92
|
+
const inputRef = useRef<TextInput | null>(null);
|
|
92
93
|
const {theme} = useContext(ApplicationContext);
|
|
93
94
|
|
|
94
95
|
useImperativeHandle(ref, () => ({
|
|
95
96
|
onChangeText: (text: string) => {
|
|
96
97
|
_onChangeText(text);
|
|
97
98
|
},
|
|
99
|
+
focus: () => inputRef.current?.focus(),
|
|
100
|
+
blur: () => inputRef.current?.blur(),
|
|
101
|
+
setText: (text: string) => _onChangeText(text),
|
|
98
102
|
}));
|
|
99
103
|
|
|
100
104
|
const onFocusInput = () => {
|
|
@@ -239,7 +243,11 @@ const InputOTP = forwardRef(
|
|
|
239
243
|
onPress={onFocusInput}
|
|
240
244
|
style={[style, styles.otpWrapper]}>
|
|
241
245
|
{renderInputView()}
|
|
242
|
-
<ErrorView
|
|
246
|
+
<ErrorView
|
|
247
|
+
errorMessage={errorMessage}
|
|
248
|
+
errorSpacing={errorSpacing}
|
|
249
|
+
hintText={hintText}
|
|
250
|
+
/>
|
|
243
251
|
</TouchableOpacity>
|
|
244
252
|
</ComponentContext.Provider>
|
|
245
253
|
);
|
package/Input/InputSearch.tsx
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useContext,
|
|
4
|
+
useImperativeHandle,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from 'react';
|
|
2
8
|
import {
|
|
3
9
|
NativeSyntheticEvent,
|
|
4
10
|
TextInput,
|
|
@@ -6,11 +12,11 @@ import {
|
|
|
6
12
|
TouchableOpacity,
|
|
7
13
|
View,
|
|
8
14
|
} from 'react-native';
|
|
9
|
-
import {InputSearchProps} from './index';
|
|
10
15
|
import {ApplicationContext, ComponentContext} from '../Application';
|
|
11
|
-
import styles from './styles';
|
|
12
16
|
import {Icon} from '../Icon';
|
|
13
17
|
import {Text} from '../Text';
|
|
18
|
+
import {InputSearchProps} from './index';
|
|
19
|
+
import styles from './styles';
|
|
14
20
|
import {checkTyping} from './utils';
|
|
15
21
|
|
|
16
22
|
const InputSearch = forwardRef(
|
|
@@ -38,7 +44,7 @@ const InputSearch = forwardRef(
|
|
|
38
44
|
const {theme} = useContext(ApplicationContext);
|
|
39
45
|
const [focused, setFocused] = useState(false);
|
|
40
46
|
const [haveValue, setHaveValue] = useState(!!value || !!defaultValue);
|
|
41
|
-
const inputRef =
|
|
47
|
+
const inputRef = useRef<TextInput | null>(null);
|
|
42
48
|
|
|
43
49
|
const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
|
44
50
|
setFocused(true);
|
|
@@ -60,6 +66,15 @@ const InputSearch = forwardRef(
|
|
|
60
66
|
onChangeText?.(text);
|
|
61
67
|
};
|
|
62
68
|
|
|
69
|
+
useImperativeHandle(ref, () => {
|
|
70
|
+
return {
|
|
71
|
+
clear: onClearText,
|
|
72
|
+
focus: () => inputRef.current?.focus(),
|
|
73
|
+
blur: () => inputRef.current?.blur(),
|
|
74
|
+
setText: (text: string) => _onChangeText(text),
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
|
|
63
78
|
const renderInputView = () => {
|
|
64
79
|
return (
|
|
65
80
|
<TextInput
|
package/Input/InputTextArea.tsx
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useContext,
|
|
4
|
+
useImperativeHandle,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from 'react';
|
|
2
8
|
import {
|
|
3
9
|
NativeSyntheticEvent,
|
|
4
10
|
TextInput,
|
|
@@ -6,7 +12,8 @@ import {
|
|
|
6
12
|
TouchableOpacity,
|
|
7
13
|
View,
|
|
8
14
|
} from 'react-native';
|
|
9
|
-
import
|
|
15
|
+
import {ApplicationContext} from '../Application';
|
|
16
|
+
import {Icon} from '../Icon';
|
|
10
17
|
import {Text} from '../Text';
|
|
11
18
|
import {
|
|
12
19
|
DEFAULT_HEIGHT,
|
|
@@ -16,8 +23,7 @@ import {
|
|
|
16
23
|
MAX_LENGTH,
|
|
17
24
|
} from './common';
|
|
18
25
|
import {InputTextAreaProps} from './index';
|
|
19
|
-
import
|
|
20
|
-
import {ApplicationContext} from '../Application';
|
|
26
|
+
import styles from './styles';
|
|
21
27
|
|
|
22
28
|
const InputTextArea = forwardRef(
|
|
23
29
|
(
|
|
@@ -39,6 +45,7 @@ const InputTextArea = forwardRef(
|
|
|
39
45
|
errorSpacing,
|
|
40
46
|
style,
|
|
41
47
|
accessibilityLabel,
|
|
48
|
+
hintText,
|
|
42
49
|
...props
|
|
43
50
|
}: InputTextAreaProps,
|
|
44
51
|
ref,
|
|
@@ -46,7 +53,7 @@ const InputTextArea = forwardRef(
|
|
|
46
53
|
const {theme} = useContext(ApplicationContext);
|
|
47
54
|
const [focused, setFocused] = useState(false);
|
|
48
55
|
const [inputValue, setInputValue] = useState(defaultValue ?? '');
|
|
49
|
-
const inputRef =
|
|
56
|
+
const inputRef = useRef<TextInput | null>(null);
|
|
50
57
|
|
|
51
58
|
const onClearText = () => {
|
|
52
59
|
inputRef?.current?.clear();
|
|
@@ -68,6 +75,15 @@ const InputTextArea = forwardRef(
|
|
|
68
75
|
onBlur?.(e);
|
|
69
76
|
};
|
|
70
77
|
|
|
78
|
+
useImperativeHandle(ref, () => {
|
|
79
|
+
return {
|
|
80
|
+
clear: onClearText,
|
|
81
|
+
focus: () => inputRef.current?.focus(),
|
|
82
|
+
blur: () => inputRef.current?.blur(),
|
|
83
|
+
setText: (text: string) => _onChangeText(text),
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
|
|
71
87
|
const renderCountingView = () => {
|
|
72
88
|
return (
|
|
73
89
|
<View style={styles.countingView}>
|
|
@@ -151,7 +167,11 @@ const InputTextArea = forwardRef(
|
|
|
151
167
|
return (
|
|
152
168
|
<View style={[style, styles.wrapper]}>
|
|
153
169
|
{renderInputView()}
|
|
154
|
-
<ErrorView
|
|
170
|
+
<ErrorView
|
|
171
|
+
errorMessage={errorMessage}
|
|
172
|
+
errorSpacing={errorSpacing}
|
|
173
|
+
hintText={hintText}
|
|
174
|
+
/>
|
|
155
175
|
</View>
|
|
156
176
|
);
|
|
157
177
|
},
|
package/Input/common.tsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {View, ViewStyle} from 'react-native';
|
|
2
|
-
import styles from './styles';
|
|
3
|
-
import {scaleSize, Text} from '../Text';
|
|
4
1
|
import React, {FC, useContext} from 'react';
|
|
2
|
+
import {View, ViewStyle} from 'react-native';
|
|
5
3
|
import {ApplicationContext} from '../Application';
|
|
6
|
-
import {Icon} from '../Icon';
|
|
7
|
-
import {Styles} from '../Consts';
|
|
8
4
|
import {Theme} from '../Application/types';
|
|
5
|
+
import {Styles} from '../Consts';
|
|
6
|
+
import {Icon} from '../Icon';
|
|
7
|
+
import {scaleSize, Text} from '../Text';
|
|
8
|
+
import styles from './styles';
|
|
9
9
|
|
|
10
10
|
type FloatingViewProps = {
|
|
11
11
|
floatingValue?: string;
|
|
@@ -16,6 +16,13 @@ type FloatingViewProps = {
|
|
|
16
16
|
style?: ViewStyle;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
+
export interface InputRef {
|
|
20
|
+
focus: () => void;
|
|
21
|
+
blur: () => void;
|
|
22
|
+
clear: () => void;
|
|
23
|
+
setText: (text: string) => void;
|
|
24
|
+
}
|
|
25
|
+
|
|
19
26
|
export const DEFAULT_HEIGHT = scaleSize(104);
|
|
20
27
|
export const MAX_LENGTH = 300;
|
|
21
28
|
|
|
@@ -48,24 +55,31 @@ export const getSizeStyle = (size?: 'small' | 'large') => {
|
|
|
48
55
|
}
|
|
49
56
|
return styles.container;
|
|
50
57
|
};
|
|
51
|
-
export const ErrorView: FC<{
|
|
52
|
-
errorMessage
|
|
53
|
-
errorSpacing
|
|
54
|
-
|
|
58
|
+
export const ErrorView: FC<{
|
|
59
|
+
errorMessage?: string;
|
|
60
|
+
errorSpacing?: boolean;
|
|
61
|
+
hintText?: string;
|
|
62
|
+
}> = ({errorMessage, errorSpacing, hintText}) => {
|
|
55
63
|
const {theme} = useContext(ApplicationContext);
|
|
56
64
|
const errorColor = theme.colors.error.primary;
|
|
57
|
-
|
|
65
|
+
const hintColor = theme.colors.text.hint;
|
|
66
|
+
const hintTextDefault = hintText ?? 'Không thể chỉnh sửa';
|
|
67
|
+
if (errorMessage || hintText) {
|
|
58
68
|
return (
|
|
59
69
|
<View style={styles.errorView}>
|
|
60
70
|
<View style={styles.errorIcon}>
|
|
61
|
-
<Icon
|
|
71
|
+
<Icon
|
|
72
|
+
color={errorMessage ? errorColor : hintColor}
|
|
73
|
+
source="ic_error"
|
|
74
|
+
size={16}
|
|
75
|
+
/>
|
|
62
76
|
</View>
|
|
63
77
|
<Text
|
|
64
78
|
style={Styles.flex}
|
|
65
|
-
color={errorColor}
|
|
79
|
+
color={errorMessage ? errorColor : hintColor}
|
|
66
80
|
numberOfLines={2}
|
|
67
81
|
typography={'description_default_regular'}>
|
|
68
|
-
{errorMessage}
|
|
82
|
+
{errorMessage ?? hintTextDefault}
|
|
69
83
|
</Text>
|
|
70
84
|
</View>
|
|
71
85
|
);
|
package/Input/index.tsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import {TextInputProps, ViewStyle} from 'react-native';
|
|
1
2
|
import Input from './Input';
|
|
2
|
-
import
|
|
3
|
-
import InputSearch from './InputSearch';
|
|
3
|
+
import InputDropDown from './InputDropDown';
|
|
4
4
|
import InputMoney from './InputMoney';
|
|
5
5
|
import InputOTP from './InputOTP';
|
|
6
|
-
import
|
|
7
|
-
import
|
|
6
|
+
import InputSearch from './InputSearch';
|
|
7
|
+
import InputTextArea from './InputTextArea';
|
|
8
8
|
|
|
9
9
|
export interface InputProps extends TextInputProps {
|
|
10
10
|
/**
|
|
@@ -77,11 +77,25 @@ export interface InputProps extends TextInputProps {
|
|
|
77
77
|
*/
|
|
78
78
|
leadingIconColor?: string;
|
|
79
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Optional. Represents the font weight of the text in the Input component.
|
|
82
|
+
*/
|
|
80
83
|
fontWeight?: 'Regular' | 'Bold';
|
|
81
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Optional. callback function to be called when the icon is pressed.
|
|
87
|
+
*/
|
|
82
88
|
onPressIcon?: () => void;
|
|
83
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Optional. params for element tracking.
|
|
92
|
+
*/
|
|
84
93
|
params?: any;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Optional. Represents text below the Input component.
|
|
97
|
+
*/
|
|
98
|
+
hintText?: string;
|
|
85
99
|
}
|
|
86
100
|
|
|
87
101
|
type InputPropsWithoutSizeAndIcon = Omit<
|
|
@@ -267,4 +281,4 @@ export interface InputDropDownProps extends InputProps {
|
|
|
267
281
|
style?: ViewStyle | ViewStyle[];
|
|
268
282
|
}
|
|
269
283
|
|
|
270
|
-
export {Input,
|
|
284
|
+
export {Input, InputDropDown, InputMoney, InputOTP, InputSearch, InputTextArea};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import {default as React, useContext, useEffect, useRef, useState} from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Animated,
|
|
4
|
+
LayoutChangeEvent,
|
|
5
|
+
StyleSheet,
|
|
6
|
+
TouchableOpacity,
|
|
7
|
+
} from 'react-native';
|
|
8
|
+
import {ApplicationContext} from '../Application';
|
|
9
|
+
import {Icon} from '../Icon';
|
|
10
|
+
import {Text} from '../Text';
|
|
11
|
+
|
|
12
|
+
export interface FloatingButtonProps {
|
|
13
|
+
label?: string;
|
|
14
|
+
onPress?: () => void;
|
|
15
|
+
position?: 'center' | 'right';
|
|
16
|
+
icon?: string;
|
|
17
|
+
iconColor?: string;
|
|
18
|
+
size?: 'small' | 'large';
|
|
19
|
+
animatedValue?: Animated.Value;
|
|
20
|
+
bottom?: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|
24
|
+
label = '',
|
|
25
|
+
onPress = () => {},
|
|
26
|
+
position = 'right',
|
|
27
|
+
icon = '',
|
|
28
|
+
iconColor = '',
|
|
29
|
+
size = 'small',
|
|
30
|
+
animatedValue,
|
|
31
|
+
bottom = 12,
|
|
32
|
+
}: FloatingButtonProps) => {
|
|
33
|
+
const {theme} = useContext(ApplicationContext);
|
|
34
|
+
const maxWidth = useRef(0);
|
|
35
|
+
const minWidth = size == 'small' ? 36 : 48;
|
|
36
|
+
const [widthAnimated, setWidthAnimated] = useState<Animated.Value>();
|
|
37
|
+
const lastOffset = useRef(0);
|
|
38
|
+
const debounce = useRef<any>();
|
|
39
|
+
const [showText, setShowText] = React.useState(true);
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
if (!label) return;
|
|
43
|
+
|
|
44
|
+
const listener = animatedValue?.addListener(({value}) => {
|
|
45
|
+
clearTimeout(debounce.current);
|
|
46
|
+
debounce.current = setTimeout(() => {
|
|
47
|
+
const down = value > lastOffset.current;
|
|
48
|
+
lastOffset.current = value;
|
|
49
|
+
if (down) {
|
|
50
|
+
Animated.timing(widthAnimated!, {
|
|
51
|
+
toValue: minWidth,
|
|
52
|
+
duration: 300,
|
|
53
|
+
useNativeDriver: false,
|
|
54
|
+
}).start(() => setShowText(false));
|
|
55
|
+
} else {
|
|
56
|
+
Animated.timing(widthAnimated!, {
|
|
57
|
+
toValue: maxWidth.current,
|
|
58
|
+
duration: 300,
|
|
59
|
+
useNativeDriver: false,
|
|
60
|
+
}).start(() => setShowText(true));
|
|
61
|
+
}
|
|
62
|
+
}, 500);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return () => {
|
|
66
|
+
if (listener != null) {
|
|
67
|
+
animatedValue?.removeListener(listener);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}, [label, widthAnimated]);
|
|
71
|
+
|
|
72
|
+
const handleLayout = (event: LayoutChangeEvent) => {
|
|
73
|
+
const layout = event.nativeEvent.layout;
|
|
74
|
+
if (widthAnimated) return;
|
|
75
|
+
maxWidth.current = layout.width;
|
|
76
|
+
setWidthAnimated(new Animated.Value(layout.width));
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<Animated.View
|
|
81
|
+
onLayout={handleLayout}
|
|
82
|
+
style={[
|
|
83
|
+
styles.container,
|
|
84
|
+
{
|
|
85
|
+
right: position === 'right' ? 12 : undefined,
|
|
86
|
+
alignSelf: position === 'center' ? 'center' : 'flex-end',
|
|
87
|
+
width: widthAnimated,
|
|
88
|
+
height: size == 'small' ? 36 : 48,
|
|
89
|
+
backgroundColor: theme.colors.primary,
|
|
90
|
+
bottom,
|
|
91
|
+
},
|
|
92
|
+
]}>
|
|
93
|
+
<TouchableOpacity
|
|
94
|
+
style={{flexDirection: 'row', alignItems: 'center'}}
|
|
95
|
+
onPress={onPress}>
|
|
96
|
+
<Icon
|
|
97
|
+
source={icon}
|
|
98
|
+
size={size === 'small' ? 12 : 24}
|
|
99
|
+
color={iconColor}
|
|
100
|
+
/>
|
|
101
|
+
{showText && !!label && (
|
|
102
|
+
<Text
|
|
103
|
+
style={styles.label}
|
|
104
|
+
color="white"
|
|
105
|
+
typography="action_default_bold">
|
|
106
|
+
{label}
|
|
107
|
+
</Text>
|
|
108
|
+
)}
|
|
109
|
+
</TouchableOpacity>
|
|
110
|
+
</Animated.View>
|
|
111
|
+
);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const styles = StyleSheet.create({
|
|
115
|
+
container: {
|
|
116
|
+
flexDirection: 'row',
|
|
117
|
+
alignContent: 'center',
|
|
118
|
+
alignItems: 'center',
|
|
119
|
+
position: 'absolute',
|
|
120
|
+
borderRadius: 100,
|
|
121
|
+
paddingHorizontal: 12,
|
|
122
|
+
flexWrap: 'wrap',
|
|
123
|
+
alignSelf: 'flex-end',
|
|
124
|
+
},
|
|
125
|
+
label: {
|
|
126
|
+
marginLeft: 8,
|
|
127
|
+
},
|
|
128
|
+
});
|
package/Layout/Screen.tsx
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
import {useHeaderHeight} from '@react-navigation/stack';
|
|
2
|
+
import React, {
|
|
3
|
+
forwardRef,
|
|
4
|
+
Fragment,
|
|
5
|
+
ReactNode,
|
|
6
|
+
useContext,
|
|
7
|
+
useEffect,
|
|
8
|
+
useRef,
|
|
9
|
+
} from 'react';
|
|
1
10
|
import {
|
|
2
11
|
Animated,
|
|
3
12
|
KeyboardAvoidingView,
|
|
@@ -8,27 +17,19 @@ import {
|
|
|
8
17
|
View,
|
|
9
18
|
ViewProps,
|
|
10
19
|
} from 'react-native';
|
|
11
|
-
import {useHeaderHeight} from '@react-navigation/stack';
|
|
12
20
|
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
|
13
|
-
import React, {
|
|
14
|
-
forwardRef,
|
|
15
|
-
Fragment,
|
|
16
|
-
ReactNode,
|
|
17
|
-
useContext,
|
|
18
|
-
useEffect,
|
|
19
|
-
useRef,
|
|
20
|
-
} from 'react';
|
|
21
|
-
import {Colors, Spacing, Styles} from '../Consts';
|
|
22
|
-
import {Card, Section, validateChildren} from './index';
|
|
23
21
|
import {
|
|
24
22
|
ApplicationContext,
|
|
25
23
|
HeaderBackground,
|
|
26
24
|
HeaderTitle,
|
|
27
25
|
} from '../Application';
|
|
28
26
|
import Navigation from '../Application/Navigation';
|
|
29
|
-
import styles from './styles';
|
|
30
27
|
import {AnimatedHeader, NavigationOptions} from '../Application/types';
|
|
28
|
+
import {Colors, Spacing, Styles} from '../Consts';
|
|
29
|
+
import {FloatingButton, FloatingButtonProps} from './FloatingButton';
|
|
31
30
|
import {Image} from '../Image';
|
|
31
|
+
import {Card, Section, validateChildren} from './index';
|
|
32
|
+
import styles from './styles';
|
|
32
33
|
import {HeaderType} from './types';
|
|
33
34
|
|
|
34
35
|
export interface ScreenProps extends ViewProps {
|
|
@@ -82,6 +83,16 @@ export interface ScreenProps extends ViewProps {
|
|
|
82
83
|
* Optional. layout card offset overlap header banner.
|
|
83
84
|
*/
|
|
84
85
|
layoutOffset?: -8 | -24 | -56;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Optional. Props for the floating action button.
|
|
89
|
+
*/
|
|
90
|
+
floatingButtonProps?: Omit<FloatingButtonProps, 'animatedValue' | 'bottom'>;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Optional. If `true`, the screen content is using grid layout by span.
|
|
94
|
+
*/
|
|
95
|
+
useGridLayout?: boolean;
|
|
85
96
|
}
|
|
86
97
|
|
|
87
98
|
const Screen = forwardRef(
|
|
@@ -98,20 +109,23 @@ const Screen = forwardRef(
|
|
|
98
109
|
layoutOffset = -56,
|
|
99
110
|
backgroundColor,
|
|
100
111
|
headerType = 'default',
|
|
112
|
+
floatingButtonProps,
|
|
113
|
+
useGridLayout = true,
|
|
101
114
|
}: ScreenProps,
|
|
102
115
|
ref,
|
|
103
116
|
) => {
|
|
104
|
-
const animatedValue = useRef<Animated.Value
|
|
117
|
+
const animatedValue = useRef<Animated.Value>(new Animated.Value(0));
|
|
105
118
|
const {theme} = useContext(ApplicationContext);
|
|
106
119
|
const insets = useSafeAreaInsets();
|
|
107
120
|
const heightHeader = useHeaderHeight();
|
|
108
121
|
const currentTint = useRef(Colors.black_01);
|
|
122
|
+
const isTab = navigation?.instance?.getState?.()?.type == 'tab';
|
|
123
|
+
|
|
109
124
|
let styleAnimatedHeader: NavigationOptions;
|
|
110
125
|
let handleScroll;
|
|
111
126
|
let headerBackground: string | undefined = undefined;
|
|
112
127
|
let Component: any = View;
|
|
113
128
|
let keyboardVerticalOffset = heightHeader - 20;
|
|
114
|
-
animatedValue.current = undefined;
|
|
115
129
|
|
|
116
130
|
if (headerType == 'extended' || animatedHeader) {
|
|
117
131
|
keyboardVerticalOffset = -20;
|
|
@@ -155,7 +169,7 @@ const Screen = forwardRef(
|
|
|
155
169
|
|
|
156
170
|
useEffect(() => {
|
|
157
171
|
if (!animatedHeader) {
|
|
158
|
-
let headerOptions: NavigationOptions
|
|
172
|
+
let headerOptions: NavigationOptions;
|
|
159
173
|
switch (headerType) {
|
|
160
174
|
case 'none':
|
|
161
175
|
headerOptions = {
|
|
@@ -176,12 +190,9 @@ const Screen = forwardRef(
|
|
|
176
190
|
image={null}
|
|
177
191
|
backgroundColor={theme.colors.background.surface}
|
|
178
192
|
useBorder={true}
|
|
179
|
-
animatedValue={animatedValue.current}
|
|
180
193
|
/>
|
|
181
194
|
),
|
|
182
|
-
headerTitle: (props: any) =>
|
|
183
|
-
<HeaderTitle {...props} animatedValue={animatedValue.current} />
|
|
184
|
-
),
|
|
195
|
+
headerTitle: (props: any) => <HeaderTitle {...props} />,
|
|
185
196
|
};
|
|
186
197
|
break;
|
|
187
198
|
|
|
@@ -213,8 +224,7 @@ const Screen = forwardRef(
|
|
|
213
224
|
if (scrollable) {
|
|
214
225
|
Component = Animated.ScrollView;
|
|
215
226
|
handleScroll = scrollViewProps?.onScroll;
|
|
216
|
-
if (animatedHeader) {
|
|
217
|
-
animatedValue.current = new Animated.Value(0);
|
|
227
|
+
if (animatedHeader || floatingButtonProps) {
|
|
218
228
|
handleScroll = Animated.event(
|
|
219
229
|
[
|
|
220
230
|
{
|
|
@@ -224,9 +234,9 @@ const Screen = forwardRef(
|
|
|
224
234
|
},
|
|
225
235
|
],
|
|
226
236
|
{
|
|
227
|
-
useNativeDriver:
|
|
237
|
+
useNativeDriver: false,
|
|
228
238
|
listener: (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
229
|
-
if (animatedHeader
|
|
239
|
+
if (animatedHeader?.type == 'surface') {
|
|
230
240
|
const offsetY = e.nativeEvent.contentOffset.y;
|
|
231
241
|
let color = Colors.black_01;
|
|
232
242
|
if (offsetY > 50) {
|
|
@@ -239,7 +249,6 @@ const Screen = forwardRef(
|
|
|
239
249
|
});
|
|
240
250
|
}
|
|
241
251
|
}
|
|
242
|
-
scrollViewProps?.onScroll?.(e);
|
|
243
252
|
},
|
|
244
253
|
},
|
|
245
254
|
);
|
|
@@ -322,6 +331,7 @@ const Screen = forwardRef(
|
|
|
322
331
|
android: undefined,
|
|
323
332
|
})}>
|
|
324
333
|
{Header}
|
|
334
|
+
|
|
325
335
|
<Component
|
|
326
336
|
{...scrollViewProps}
|
|
327
337
|
ref={ref}
|
|
@@ -332,12 +342,25 @@ const Screen = forwardRef(
|
|
|
332
342
|
style={[styles.screenBanner, {maxHeight: 210 + layoutOffset}]}>
|
|
333
343
|
{renderHeader()}
|
|
334
344
|
</View>
|
|
335
|
-
{renderContent(children)}
|
|
345
|
+
{useGridLayout ? renderContent(children) : children}
|
|
336
346
|
</Component>
|
|
347
|
+
|
|
348
|
+
{floatingButtonProps && (
|
|
349
|
+
<View>
|
|
350
|
+
<FloatingButton
|
|
351
|
+
{...floatingButtonProps}
|
|
352
|
+
animatedValue={animatedValue.current}
|
|
353
|
+
bottom={
|
|
354
|
+
Footer || isTab ? 12 : Math.min(insets.bottom, 21) + Spacing.S
|
|
355
|
+
}
|
|
356
|
+
/>
|
|
357
|
+
</View>
|
|
358
|
+
)}
|
|
359
|
+
|
|
337
360
|
{Footer && (
|
|
338
361
|
<View
|
|
339
362
|
style={[
|
|
340
|
-
styles.
|
|
363
|
+
styles.shadow,
|
|
341
364
|
{
|
|
342
365
|
paddingBottom: Math.min(insets.bottom, 21) + Spacing.S,
|
|
343
366
|
backgroundColor: theme.colors.background.surface,
|
package/Layout/styles.ts
CHANGED
|
@@ -80,17 +80,21 @@ export default StyleSheet.create({
|
|
|
80
80
|
paddingHorizontal: undefined,
|
|
81
81
|
paddingVertical: undefined,
|
|
82
82
|
},
|
|
83
|
-
|
|
83
|
+
shadow: {
|
|
84
84
|
paddingTop: Spacing.S,
|
|
85
85
|
...Platform.select({
|
|
86
|
-
android: {
|
|
87
|
-
elevation: 4,
|
|
88
|
-
},
|
|
89
86
|
ios: {
|
|
87
|
+
shadowColor: Colors.black_17,
|
|
88
|
+
shadowOffset: {
|
|
89
|
+
width: 2,
|
|
90
|
+
height: 2,
|
|
91
|
+
},
|
|
92
|
+
shadowOpacity: 0.25,
|
|
93
|
+
shadowRadius: 10,
|
|
94
|
+
},
|
|
95
|
+
android: {
|
|
90
96
|
shadowColor: Colors.black_20,
|
|
91
|
-
|
|
92
|
-
shadowOpacity: 0.1,
|
|
93
|
-
shadowRadius: 3,
|
|
97
|
+
elevation: 24,
|
|
94
98
|
},
|
|
95
99
|
}),
|
|
96
100
|
},
|
package/Layout/utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {Dimensions} from 'react-native';
|
|
2
1
|
import React, {Fragment, ReactElement, useEffect, useState} from 'react';
|
|
2
|
+
import {Dimensions} from 'react-native';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* validate children type
|
|
@@ -52,4 +52,4 @@ const useGridSystem = () => {
|
|
|
52
52
|
return {numberOfColumns};
|
|
53
53
|
};
|
|
54
54
|
|
|
55
|
-
export {
|
|
55
|
+
export {useGridSystem, validateChildren};
|
package/Popup/PopupNotify.tsx
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React, {useContext, useEffect, useRef, useState} from 'react';
|
|
2
2
|
import {ScrollView, StyleSheet, TouchableOpacity, View} from 'react-native';
|
|
3
|
-
import {PopupNotifyProps} from './types';
|
|
4
|
-
import {Radius, Spacing, Styles} from '../Consts';
|
|
5
|
-
import {Image} from '../Image';
|
|
6
|
-
import {Text} from '../Text';
|
|
7
3
|
import {ApplicationContext, MiniAppContext} from '../Application';
|
|
8
4
|
import {Button} from '../Button';
|
|
5
|
+
import {Radius, Spacing, Styles} from '../Consts';
|
|
9
6
|
import {Icon} from '../Icon';
|
|
7
|
+
import {Image} from '../Image';
|
|
8
|
+
import {Text} from '../Text';
|
|
9
|
+
import {PopupNotifyProps} from './types';
|
|
10
10
|
|
|
11
11
|
const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
12
12
|
id,
|
|
@@ -23,14 +23,12 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
23
23
|
const {theme, navigator, translate} = useContext(ApplicationContext);
|
|
24
24
|
const [scrollContent, setScrollContent] = useState(false);
|
|
25
25
|
const closeAction = useRef('touch_outside');
|
|
26
|
-
|
|
27
26
|
let descriptionStyle = {};
|
|
28
27
|
let Description: any = View;
|
|
29
28
|
if (scrollContent) {
|
|
30
29
|
Description = ScrollView;
|
|
31
30
|
descriptionStyle = {height: 80};
|
|
32
31
|
}
|
|
33
|
-
|
|
34
32
|
/**
|
|
35
33
|
* tracking
|
|
36
34
|
*/
|
|
@@ -160,30 +158,32 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
160
158
|
* build close action
|
|
161
159
|
*/
|
|
162
160
|
const buildCloseIcon = () => {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
161
|
+
if (typeof onIconClose === 'function') {
|
|
162
|
+
return (
|
|
163
|
+
<TouchableOpacity
|
|
164
|
+
accessibilityLabel={'ic_popup_close'}
|
|
165
|
+
style={styles.iconCloseContainer}
|
|
166
|
+
onPress={() => {
|
|
167
|
+
closeAction.current = 'icon_close';
|
|
168
|
+
onAction(onIconClose);
|
|
169
|
+
}}>
|
|
170
|
+
<View
|
|
171
|
+
style={[
|
|
172
|
+
styles.iconClose,
|
|
173
|
+
{
|
|
174
|
+
backgroundColor: theme.colors.text.default,
|
|
175
|
+
borderColor: theme.colors.background.surface,
|
|
176
|
+
},
|
|
177
|
+
]}>
|
|
178
|
+
<Icon
|
|
179
|
+
source="navigation_close"
|
|
180
|
+
color={theme.colors.background.surface}
|
|
181
|
+
size={14}
|
|
182
|
+
/>
|
|
183
|
+
</View>
|
|
184
|
+
</TouchableOpacity>
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
187
|
};
|
|
188
188
|
|
|
189
189
|
return (
|
package/Popup/types.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {TextStyle} from 'react-native';
|
|
2
1
|
import React from 'react';
|
|
3
2
|
|
|
4
3
|
export type PopupNotifyProps = {
|
|
@@ -79,9 +78,4 @@ type PopupAction = {
|
|
|
79
78
|
onPress: () => void;
|
|
80
79
|
};
|
|
81
80
|
|
|
82
|
-
export type HighlightText = {
|
|
83
|
-
text: string;
|
|
84
|
-
style: TextStyle;
|
|
85
|
-
};
|
|
86
|
-
|
|
87
81
|
type PopupActionDirection = 'row' | 'column' | 'auto';
|
package/package.json
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@momo-kits/foundation",
|
|
3
|
-
"version": "0.92.6-rc.
|
|
3
|
+
"version": "0.92.6-rc.10",
|
|
4
4
|
"description": "React Native Component Kits",
|
|
5
5
|
"main": "index.ts",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"postinstall": "node verify.js"
|
|
8
|
-
},
|
|
6
|
+
"scripts": {},
|
|
9
7
|
"keywords": [
|
|
10
8
|
"@momo-kits/foundation"
|
|
11
9
|
],
|