@momo-kits/foundation 0.77.8-beta.3 → 0.77.8-beta.5
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/BottomTab.tsx +13 -3
- package/Application/ModalScreen.tsx +16 -14
- package/Application/types.ts +3 -0
- package/Button/index.tsx +20 -0
- package/CheckBox/index.tsx +1 -1
- package/CheckBox/styles.ts +1 -1
- package/Input/Input.tsx +126 -106
- package/Input/InputMoney.tsx +118 -110
- package/Input/InputSearch.tsx +129 -134
- package/Input/InputTextArea.tsx +126 -118
- package/Input/common.tsx +10 -4
- package/Input/index.tsx +12 -0
- package/Layout/GridSystem.tsx +1 -1
- package/Layout/Screen.tsx +14 -4
- package/Layout/index.ts +1 -1
- package/Layout/utils.ts +6 -9
- package/Loader/DotLoader.tsx +14 -16
- package/Loader/Loader.tsx +3 -4
- package/Loader/Spinner.tsx +11 -13
- package/Loader/types.ts +2 -0
- package/Pagination/PaginationWhiteDot.tsx +1 -3
- package/Popup/types.ts +9 -1
- package/Radio/index.tsx +1 -1
- package/Text/index.tsx +1 -16
- package/Text/utils.ts +1 -1
- package/package.json +1 -1
- package/tsconfig.json +25 -0
- /package/{code-scanner.ts → code-scanner.js} +0 -0
|
@@ -8,17 +8,27 @@ import {ApplicationContext} from './index';
|
|
|
8
8
|
|
|
9
9
|
const Tab = createBottomTabNavigator();
|
|
10
10
|
|
|
11
|
-
const BottomTab: React.FC<BottomTabProps> = ({tabs, listeners}) => {
|
|
11
|
+
const BottomTab: React.FC<BottomTabProps> = ({tabs, listeners, navigation}) => {
|
|
12
12
|
const {theme} = useContext(ApplicationContext);
|
|
13
|
+
|
|
14
|
+
const defaultListener = {
|
|
15
|
+
focus: (item: any) => {
|
|
16
|
+
const focusItem = tabs.find(i => item.target.includes(i.name));
|
|
17
|
+
if (focusItem?.options) {
|
|
18
|
+
navigation?.setOptions?.(focusItem.options);
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
13
23
|
return (
|
|
14
|
-
<Tab.Navigator>
|
|
24
|
+
<Tab.Navigator backBehavior={'firstRoute'}>
|
|
15
25
|
{tabs.map(item => {
|
|
16
26
|
return (
|
|
17
27
|
<Tab.Screen
|
|
18
28
|
key={item.name}
|
|
19
29
|
name={item.name}
|
|
20
30
|
component={item.screen}
|
|
21
|
-
listeners={listeners}
|
|
31
|
+
listeners={listeners ?? defaultListener}
|
|
22
32
|
options={{
|
|
23
33
|
tabBarLabel: ({color, focused}) => {
|
|
24
34
|
return (
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import React, {useContext, useEffect,
|
|
1
|
+
import React, {useContext, useEffect, useRef} from 'react';
|
|
2
2
|
import {
|
|
3
|
+
Dimensions,
|
|
3
4
|
KeyboardAvoidingView,
|
|
4
5
|
Platform,
|
|
5
6
|
Pressable,
|
|
6
7
|
StyleSheet,
|
|
7
8
|
View,
|
|
8
9
|
} from 'react-native';
|
|
9
|
-
import {SafeAreaView
|
|
10
|
+
import {SafeAreaView} from 'react-native-safe-area-context';
|
|
10
11
|
import {BottomSheetBackdrop, BottomSheetModal} from '@gorhom/bottom-sheet';
|
|
11
12
|
import Navigation from './Navigation';
|
|
12
13
|
import {BottomSheetParams, ModalParams} from './types';
|
|
@@ -84,7 +85,12 @@ const Modal: React.FC<ModalParams> = props => {
|
|
|
84
85
|
|
|
85
86
|
const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
86
87
|
const {theme, navigator} = useContext(ApplicationContext);
|
|
87
|
-
const {
|
|
88
|
+
const {height} = Dimensions.get('window');
|
|
89
|
+
const {
|
|
90
|
+
screen,
|
|
91
|
+
options,
|
|
92
|
+
snapPoints = [height * 0.5, height * 0.9],
|
|
93
|
+
}: BottomSheetParams = props.route.params;
|
|
88
94
|
const Component = useRef(screen).current;
|
|
89
95
|
const navigation = new Navigation(props.navigation, theme);
|
|
90
96
|
const params = {
|
|
@@ -94,11 +100,14 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
94
100
|
|
|
95
101
|
delete params.screen;
|
|
96
102
|
|
|
97
|
-
const snapPoints = useMemo(() => ['50%', '90%'], []);
|
|
98
|
-
const {bottom} = useSafeAreaInsets();
|
|
99
103
|
const bottomSheetRef = useRef<any>(null);
|
|
100
104
|
const mountedRef = useRef(true);
|
|
101
105
|
|
|
106
|
+
let backgroundColor = theme.colors.background.default;
|
|
107
|
+
if (options?.surface) {
|
|
108
|
+
backgroundColor = theme.colors.background.surface;
|
|
109
|
+
}
|
|
110
|
+
|
|
102
111
|
useEffect(() => {
|
|
103
112
|
bottomSheetRef.current?.present();
|
|
104
113
|
return () => {
|
|
@@ -114,16 +123,11 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
114
123
|
/>
|
|
115
124
|
);
|
|
116
125
|
|
|
117
|
-
let backgroundColor = theme.colors.background.default;
|
|
118
|
-
if (options?.surface) {
|
|
119
|
-
backgroundColor = theme.colors.background.surface;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
126
|
return (
|
|
123
127
|
<SafeAreaView style={Styles.flex}>
|
|
124
128
|
<BottomSheetModal
|
|
125
129
|
ref={bottomSheetRef}
|
|
126
|
-
snapPoints={snapPoints}
|
|
130
|
+
snapPoints={snapPoints?.map(item => item + 68)}
|
|
127
131
|
onDismiss={() => {
|
|
128
132
|
if (mountedRef.current) {
|
|
129
133
|
navigator?.pop();
|
|
@@ -131,9 +135,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
131
135
|
}}
|
|
132
136
|
handleComponent={null}
|
|
133
137
|
backdropComponent={backdropComponent}>
|
|
134
|
-
<View
|
|
135
|
-
style={{paddingBottom: bottom}}
|
|
136
|
-
accessibilityLabel={'BottomSheet'}>
|
|
138
|
+
<View accessibilityLabel={'BottomSheet'}>
|
|
137
139
|
<View style={[styles.sheetContainer, {backgroundColor}]}>
|
|
138
140
|
<View style={styles.indicatorContainer}>
|
|
139
141
|
<View
|
package/Application/types.ts
CHANGED
|
@@ -108,6 +108,7 @@ export interface ModalParams extends ScreenParams {
|
|
|
108
108
|
export interface BottomSheetParams extends ScreenParams {
|
|
109
109
|
[key: string]: any;
|
|
110
110
|
onDismiss?: () => void;
|
|
111
|
+
snapPoints?: ReadonlyArray<number>;
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
export type NavigationButtonProps = {
|
|
@@ -171,10 +172,12 @@ export type BottomTabItemProps = {
|
|
|
171
172
|
showDot?: boolean;
|
|
172
173
|
badgeLabel?: string;
|
|
173
174
|
screen: Screen;
|
|
175
|
+
options: NavigationOptions;
|
|
174
176
|
};
|
|
175
177
|
|
|
176
178
|
export type BottomTabProps = {
|
|
177
179
|
tabs: BottomTabItemProps[];
|
|
180
|
+
navigation: Navigation;
|
|
178
181
|
listeners?: {
|
|
179
182
|
tabPress?: any;
|
|
180
183
|
focus?: any;
|
package/Button/index.tsx
CHANGED
|
@@ -11,6 +11,7 @@ import {Typography} from '../Text/types';
|
|
|
11
11
|
import {Colors} from '../Consts';
|
|
12
12
|
import styles from './styles';
|
|
13
13
|
import {Icon} from '../Icon';
|
|
14
|
+
import {Loader} from '../Loader';
|
|
14
15
|
|
|
15
16
|
export interface ButtonProps extends TouchableOpacityProps {
|
|
16
17
|
/**
|
|
@@ -55,6 +56,11 @@ export interface ButtonProps extends TouchableOpacityProps {
|
|
|
55
56
|
*/
|
|
56
57
|
useTintColor?: boolean;
|
|
57
58
|
|
|
59
|
+
/**
|
|
60
|
+
* If true, the icon of button will use be show indicator loading.
|
|
61
|
+
*/
|
|
62
|
+
loading?: boolean;
|
|
63
|
+
|
|
58
64
|
/**
|
|
59
65
|
* A callback function that is called when the button is pressed.
|
|
60
66
|
*/
|
|
@@ -68,6 +74,7 @@ const Button: FC<ButtonProps> = ({
|
|
|
68
74
|
full = true,
|
|
69
75
|
iconRight,
|
|
70
76
|
iconLeft,
|
|
77
|
+
loading = false,
|
|
71
78
|
title = 'Button',
|
|
72
79
|
onPress,
|
|
73
80
|
...rest
|
|
@@ -223,6 +230,19 @@ const Button: FC<ButtonProps> = ({
|
|
|
223
230
|
const renderTrailing = () => {
|
|
224
231
|
const marginLeft = getIconSpace();
|
|
225
232
|
const color = useTintColor ? getTextColor() : undefined;
|
|
233
|
+
if (loading) {
|
|
234
|
+
const iconSize = getIconSize();
|
|
235
|
+
const color = getTextColor();
|
|
236
|
+
return (
|
|
237
|
+
<View
|
|
238
|
+
style={[
|
|
239
|
+
styles.trailing,
|
|
240
|
+
{width: iconSize, height: iconSize, marginLeft},
|
|
241
|
+
]}>
|
|
242
|
+
<Loader type="spinner" color={color} />
|
|
243
|
+
</View>
|
|
244
|
+
);
|
|
245
|
+
}
|
|
226
246
|
if (iconRight) {
|
|
227
247
|
const iconSize = getIconSize();
|
|
228
248
|
return (
|
package/CheckBox/index.tsx
CHANGED
package/CheckBox/styles.ts
CHANGED
package/Input/Input.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {FC,
|
|
1
|
+
import React, {FC, forwardRef, useContext, useRef, useState} from 'react';
|
|
2
2
|
import {
|
|
3
3
|
NativeSyntheticEvent,
|
|
4
4
|
TextInput,
|
|
@@ -12,124 +12,144 @@ import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
|
12
12
|
import {InputProps} from './index';
|
|
13
13
|
import {Icon} from '../Icon';
|
|
14
14
|
import {checkTyping} from './utils';
|
|
15
|
+
import {Loader} from '../Loader';
|
|
15
16
|
|
|
16
|
-
const Input: FC<InputProps> = (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
17
|
+
const Input: FC<InputProps> = forwardRef(
|
|
18
|
+
(
|
|
19
|
+
{
|
|
20
|
+
value,
|
|
21
|
+
onChangeText,
|
|
22
|
+
floatingValue,
|
|
23
|
+
floatingIcon,
|
|
24
|
+
size,
|
|
25
|
+
placeholder,
|
|
26
|
+
onBlur,
|
|
27
|
+
onFocus,
|
|
28
|
+
errorMessage,
|
|
29
|
+
icon,
|
|
30
|
+
disabled,
|
|
31
|
+
floatingIconColor,
|
|
32
|
+
iconColor,
|
|
33
|
+
required,
|
|
34
|
+
errorSpacing,
|
|
35
|
+
loading,
|
|
36
|
+
...props
|
|
37
|
+
},
|
|
38
|
+
ref,
|
|
39
|
+
) => {
|
|
40
|
+
const {theme} = useContext(ApplicationContext);
|
|
41
|
+
const [focused, setFocused] = useState(false);
|
|
42
|
+
const [haveValue, setHaveValue] = useState(!!value || !!props.defaultValue);
|
|
43
|
+
const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
|
|
36
44
|
|
|
37
|
-
|
|
45
|
+
const onClearText = () => {
|
|
46
|
+
inputRef?.current?.clear();
|
|
47
|
+
_onChangeText('');
|
|
48
|
+
};
|
|
38
49
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
50
|
+
const _onChangeText = (text: string) => {
|
|
51
|
+
checkTyping(text, haveValue, setHaveValue);
|
|
52
|
+
onChangeText?.(text);
|
|
53
|
+
};
|
|
43
54
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
55
|
+
const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
|
56
|
+
setFocused(true);
|
|
57
|
+
onFocus?.(e);
|
|
58
|
+
};
|
|
48
59
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
60
|
+
const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
|
61
|
+
setFocused(false);
|
|
62
|
+
onBlur?.(e);
|
|
63
|
+
};
|
|
53
64
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
65
|
+
const renderIcon = (color: string | undefined) => {
|
|
66
|
+
if (loading) {
|
|
67
|
+
return <Loader type={'spinner'} color={color} />;
|
|
68
|
+
}
|
|
69
|
+
if (icon) {
|
|
70
|
+
return <Icon color={color} source={icon} size={24} />;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
58
73
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
74
|
+
const renderInputView = () => {
|
|
75
|
+
const disabledColor = theme.colors.text.disable;
|
|
76
|
+
let textColor = theme.colors.text.default;
|
|
77
|
+
let placeholderColor = theme.colors.text.hint;
|
|
78
|
+
let iconTintColor = iconColor;
|
|
64
79
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
80
|
+
if (disabled) {
|
|
81
|
+
textColor = disabledColor;
|
|
82
|
+
placeholderColor = disabledColor;
|
|
83
|
+
iconTintColor = disabledColor;
|
|
84
|
+
}
|
|
70
85
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
/>
|
|
86
|
-
<View style={styles.inputView}>
|
|
87
|
-
<TextInput
|
|
88
|
-
{...props}
|
|
89
|
-
accessibilityLabel={`TextInput`}
|
|
90
|
-
editable={!disabled}
|
|
91
|
-
textAlignVertical="top"
|
|
92
|
-
ref={inputRef}
|
|
93
|
-
style={[
|
|
94
|
-
styles.input,
|
|
95
|
-
{
|
|
96
|
-
color: textColor,
|
|
97
|
-
fontFamily: `${theme.font}-Regular`,
|
|
98
|
-
},
|
|
99
|
-
]}
|
|
100
|
-
textBreakStrategy="highQuality"
|
|
101
|
-
value={value}
|
|
102
|
-
onChangeText={_onChangeText}
|
|
103
|
-
onFocus={_onFocus}
|
|
104
|
-
onBlur={_onBlur}
|
|
105
|
-
placeholder={placeholder}
|
|
106
|
-
selectionColor={theme.colors.primary}
|
|
107
|
-
placeholderTextColor={placeholderColor}
|
|
86
|
+
return (
|
|
87
|
+
<View
|
|
88
|
+
style={[
|
|
89
|
+
styles.inputWrapper,
|
|
90
|
+
{backgroundColor: theme.colors.background.surface},
|
|
91
|
+
getSizeStyle(size),
|
|
92
|
+
getBorderColor(theme, focused, errorMessage, disabled),
|
|
93
|
+
]}>
|
|
94
|
+
<FloatingView
|
|
95
|
+
floatingValue={floatingValue}
|
|
96
|
+
floatingIconColor={floatingIconColor}
|
|
97
|
+
disabled={disabled}
|
|
98
|
+
required={required}
|
|
99
|
+
floatingIcon={floatingIcon}
|
|
108
100
|
/>
|
|
101
|
+
<View style={styles.inputView}>
|
|
102
|
+
<TextInput
|
|
103
|
+
{...props}
|
|
104
|
+
accessibilityLabel={`TextInput`}
|
|
105
|
+
editable={!disabled}
|
|
106
|
+
textAlignVertical="top"
|
|
107
|
+
ref={inputRef}
|
|
108
|
+
style={[
|
|
109
|
+
styles.input,
|
|
110
|
+
{
|
|
111
|
+
color: textColor,
|
|
112
|
+
fontFamily: `${theme.font}-Regular`,
|
|
113
|
+
},
|
|
114
|
+
]}
|
|
115
|
+
textBreakStrategy="highQuality"
|
|
116
|
+
value={value}
|
|
117
|
+
onChangeText={_onChangeText}
|
|
118
|
+
onFocus={_onFocus}
|
|
119
|
+
onBlur={_onBlur}
|
|
120
|
+
placeholder={placeholder}
|
|
121
|
+
selectionColor={theme.colors.primary}
|
|
122
|
+
placeholderTextColor={placeholderColor}
|
|
123
|
+
/>
|
|
124
|
+
</View>
|
|
125
|
+
<View style={styles.iconView}>
|
|
126
|
+
{focused && haveValue && (
|
|
127
|
+
<TouchableOpacity
|
|
128
|
+
style={styles.iconWrapper}
|
|
129
|
+
onPress={onClearText}>
|
|
130
|
+
<Icon
|
|
131
|
+
source="24_navigation_close_circle_full"
|
|
132
|
+
size={16}
|
|
133
|
+
color={theme.colors.text.hint}
|
|
134
|
+
/>
|
|
135
|
+
</TouchableOpacity>
|
|
136
|
+
)}
|
|
137
|
+
{renderIcon(iconTintColor)}
|
|
138
|
+
</View>
|
|
109
139
|
</View>
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
)}
|
|
120
|
-
{!!icon && <Icon color={iconTintColor} source={icon} size={24} />}
|
|
121
|
-
</View>
|
|
140
|
+
);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
return (
|
|
144
|
+
<View
|
|
145
|
+
style={styles.wrapper}
|
|
146
|
+
accessibilityLabel={`Input/${floatingValue}`}>
|
|
147
|
+
{renderInputView()}
|
|
148
|
+
<ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
|
|
122
149
|
</View>
|
|
123
150
|
);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return (
|
|
127
|
-
<View style={styles.wrapper} accessibilityLabel={`Input/${floatingValue}`}>
|
|
128
|
-
{renderInputView()}
|
|
129
|
-
<ErrorView errorMessage={errorMessage} />
|
|
130
|
-
</View>
|
|
131
|
-
);
|
|
132
|
-
};
|
|
151
|
+
},
|
|
152
|
+
);
|
|
133
153
|
|
|
134
154
|
Input.defaultProps = {
|
|
135
155
|
size: 'small',
|