@momo-kits/foundation 0.81.1-optimize.21 → 0.81.1-rc.0
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/BottomSheet.tsx +27 -23
- package/Application/BottomTab/BottomTabBar.tsx +2 -2
- package/Application/BottomTab/index.tsx +2 -3
- package/Application/Components.tsx +288 -42
- package/Application/Localize.ts +44 -0
- package/Application/ModalScreen.tsx +2 -2
- package/Application/Navigation.ts +4 -18
- package/Application/NavigationContainer.tsx +10 -21
- package/Application/Navigator.ts +14 -16
- package/Application/StackScreen.tsx +211 -113
- package/Application/index.ts +5 -3
- package/Application/types.ts +30 -11
- package/Application/utils.tsx +60 -18
- package/Badge/BadgeDotAnimation.tsx +95 -0
- package/Badge/index.tsx +2 -1
- package/Badge/styles.ts +50 -6
- package/Button/index.tsx +0 -1
- package/Icon/types.ts +0 -1
- package/Input/Input.tsx +51 -17
- package/Input/InputDropDown.tsx +44 -47
- package/Input/InputMoney.tsx +56 -6
- package/Input/InputOTP.tsx +10 -6
- package/Input/InputSearch.tsx +259 -146
- package/Input/TextTyping.tsx +113 -0
- package/Input/common.tsx +29 -10
- package/Input/index.tsx +75 -74
- package/Input/styles.ts +43 -7
- package/Layout/FloatingButton.tsx +1 -1
- package/Layout/GridSystem.tsx +1 -1
- package/Layout/ItemList.tsx +3 -2
- package/Layout/Screen.tsx +174 -91
- package/Layout/styles.ts +0 -6
- package/Layout/types.ts +1 -1
- package/Pagination/PaginationScroll.tsx +2 -2
- package/Pagination/styles.ts +1 -1
- package/Popup/PopupNotify.tsx +3 -3
- package/Tag/index.tsx +9 -2
- package/Tag/styles.ts +3 -2
- package/Tag/types.ts +12 -0
- package/Title/index.tsx +6 -9
- package/Title/styles.ts +4 -4
- package/code-scanner.js +4 -4
- package/package.json +6 -5
- package/publish.sh +12 -22
- package/verify.js +36 -42
package/Application/index.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import {Platform} from 'react-native';
|
|
2
|
+
import {createContext} from 'react';
|
|
2
3
|
import {NavigationContainer} from './NavigationContainer';
|
|
4
|
+
import Localize from './Localize';
|
|
3
5
|
import Screen from '../Layout/Screen';
|
|
4
6
|
import {
|
|
5
7
|
HeaderAnimated,
|
|
6
8
|
HeaderBackground,
|
|
7
9
|
HeaderCustom,
|
|
8
|
-
HeaderRightAction,
|
|
9
10
|
HeaderTitle,
|
|
10
11
|
NavigationButton,
|
|
12
|
+
HeaderRightAction,
|
|
11
13
|
} from './Components';
|
|
12
14
|
import BottomTab from './BottomTab';
|
|
13
|
-
import {createContext} from 'react';
|
|
14
15
|
import {defaultContext} from '../Consts';
|
|
15
16
|
|
|
16
17
|
const Context = createContext({});
|
|
@@ -26,12 +27,13 @@ export {
|
|
|
26
27
|
ScreenContext,
|
|
27
28
|
ComponentContext,
|
|
28
29
|
NavigationContainer,
|
|
30
|
+
Localize,
|
|
29
31
|
Screen,
|
|
30
32
|
BottomTab,
|
|
31
33
|
NavigationButton,
|
|
34
|
+
HeaderRightAction,
|
|
32
35
|
HeaderTitle,
|
|
33
36
|
HeaderBackground,
|
|
34
|
-
HeaderRightAction,
|
|
35
37
|
HeaderCustom,
|
|
36
38
|
HeaderAnimated,
|
|
37
39
|
};
|
package/Application/types.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import {EventArg} from '@react-navigation/core';
|
|
1
2
|
import {StackNavigationOptions} from '@react-navigation/stack';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import {Animated, ViewProps} from 'react-native';
|
|
4
5
|
import {PopupNotifyProps} from '../Popup/types';
|
|
6
|
+
import Localize from './Localize';
|
|
5
7
|
import Navigation from './Navigation';
|
|
6
8
|
import Navigator from './Navigator';
|
|
7
9
|
|
|
@@ -84,8 +86,8 @@ export type NavigationContainerProps = {
|
|
|
84
86
|
options?: NavigationOptions;
|
|
85
87
|
theme: Theme;
|
|
86
88
|
maxApi: any;
|
|
87
|
-
localization?: LocalizationObject;
|
|
88
89
|
initialParams?: any;
|
|
90
|
+
localize: Localize;
|
|
89
91
|
};
|
|
90
92
|
|
|
91
93
|
export type NavigationScreenProps = {
|
|
@@ -114,6 +116,7 @@ export type BottomSheetParams = {
|
|
|
114
116
|
title: string;
|
|
115
117
|
surface?: boolean;
|
|
116
118
|
};
|
|
119
|
+
useNativeModal?: boolean;
|
|
117
120
|
surface?: boolean;
|
|
118
121
|
onDismiss?: (type?: string) => void;
|
|
119
122
|
barrierDismissible?: boolean;
|
|
@@ -127,7 +130,7 @@ export type NavigationButtonProps = {
|
|
|
127
130
|
tintColor?: string;
|
|
128
131
|
useBorder?: boolean;
|
|
129
132
|
onPress: () => void;
|
|
130
|
-
badgeType?: 'dot' | 'number';
|
|
133
|
+
badgeType?: 'dot' | 'number' | 'dot-animation';
|
|
131
134
|
badgeValue?: number;
|
|
132
135
|
accessibilityLabel?: string;
|
|
133
136
|
};
|
|
@@ -135,7 +138,7 @@ export type NavigationButtonProps = {
|
|
|
135
138
|
export type PinnedToolType = {
|
|
136
139
|
key: string;
|
|
137
140
|
badgeValue?: number;
|
|
138
|
-
badgeType?: 'number' | 'dot';
|
|
141
|
+
badgeType?: 'number' | 'dot' | 'dot-animation';
|
|
139
142
|
};
|
|
140
143
|
|
|
141
144
|
export type RuntimeToolType = {
|
|
@@ -144,19 +147,29 @@ export type RuntimeToolType = {
|
|
|
144
147
|
key: string;
|
|
145
148
|
};
|
|
146
149
|
|
|
147
|
-
export interface NavigationOptions
|
|
150
|
+
export interface NavigationOptions
|
|
151
|
+
extends Omit<StackNavigationOptions, 'headerRight'> {
|
|
148
152
|
preventBack?: PopupNotifyProps;
|
|
149
153
|
onPressLeftHeader?: () => void;
|
|
150
154
|
surface?: boolean;
|
|
151
155
|
hiddenBack?: boolean;
|
|
152
156
|
customTitle?: TitleCustomProps;
|
|
153
|
-
|
|
154
|
-
pinnedTool?: PinnedToolType;
|
|
155
|
-
runtimeTools?: RuntimeToolType[];
|
|
156
|
-
preventClose?: PopupNotifyProps;
|
|
157
|
-
};
|
|
157
|
+
headerRight?: HeaderRightToolkit | HeaderRightActions | any;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
export type HeaderRightToolkit = {
|
|
161
|
+
type?: 'toolkit';
|
|
162
|
+
pinnedTool?: PinnedToolType;
|
|
163
|
+
runtimeTools?: RuntimeToolType[];
|
|
164
|
+
preventClose?: PopupNotifyProps;
|
|
165
|
+
useMore?: boolean;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export type HeaderRightActions = {
|
|
169
|
+
type?: 'icon';
|
|
170
|
+
buttons: NavigationButtonProps[];
|
|
171
|
+
};
|
|
172
|
+
|
|
160
173
|
export interface HeaderBackProps extends NavigationButtonProps {
|
|
161
174
|
preventBack?: PopupNotifyProps;
|
|
162
175
|
onPressLeftHeader?: () => void;
|
|
@@ -198,6 +211,11 @@ export type BottomTabItemProps = {
|
|
|
198
211
|
screen: Screen;
|
|
199
212
|
options: NavigationOptions;
|
|
200
213
|
initialParams?: any;
|
|
214
|
+
listeners?: {
|
|
215
|
+
tabPress?: (e: EventArg<'tabPress', true, undefined>) => void;
|
|
216
|
+
focus?: (e: EventArg<'focus', false, unknown>) => void;
|
|
217
|
+
blur?: (e: EventArg<'blur', false, unknown>) => void;
|
|
218
|
+
};
|
|
201
219
|
};
|
|
202
220
|
|
|
203
221
|
export type BottomTabProps = {
|
|
@@ -206,8 +224,9 @@ export type BottomTabProps = {
|
|
|
206
224
|
initialRouteName?: string;
|
|
207
225
|
navigation: Navigation;
|
|
208
226
|
listeners?: {
|
|
209
|
-
tabPress?:
|
|
210
|
-
focus?:
|
|
227
|
+
tabPress?: (e: EventArg<'tabPress', true, undefined>) => void;
|
|
228
|
+
focus?: (e: EventArg<'focus', false, unknown>) => void;
|
|
229
|
+
blur?: (e: EventArg<'blur', false, unknown>) => void;
|
|
211
230
|
};
|
|
212
231
|
floatingButton?: FloatingButtonProps;
|
|
213
232
|
};
|
package/Application/utils.tsx
CHANGED
|
@@ -7,11 +7,13 @@ import {
|
|
|
7
7
|
HeaderBackground,
|
|
8
8
|
HeaderCustom,
|
|
9
9
|
HeaderLeft,
|
|
10
|
+
HeaderRight,
|
|
10
11
|
HeaderTitle,
|
|
11
|
-
HeaderToolkitAction,
|
|
12
12
|
} from './Components';
|
|
13
|
-
import {NavigationOptions
|
|
13
|
+
import {NavigationOptions} from './types';
|
|
14
14
|
import {Colors} from '../Consts';
|
|
15
|
+
import Navigation from './Navigation';
|
|
16
|
+
import {LayoutChangeEvent} from 'react-native';
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* default options for stack screen
|
|
@@ -22,7 +24,7 @@ const getStackOptions = (): StackNavigationOptions => {
|
|
|
22
24
|
headerTitle: HeaderTitle,
|
|
23
25
|
headerBackground: (props: any) => <HeaderBackground {...props} />,
|
|
24
26
|
headerLeft: (props: any) => <HeaderLeft {...props} />,
|
|
25
|
-
headerRight: (props: any) => <
|
|
27
|
+
headerRight: (props: any) => <HeaderRight {...props} />,
|
|
26
28
|
headerTintColor: Colors.black_01,
|
|
27
29
|
};
|
|
28
30
|
};
|
|
@@ -72,33 +74,42 @@ const getModalOptions = (): StackNavigationOptions => {
|
|
|
72
74
|
/**
|
|
73
75
|
* build react-navigation options
|
|
74
76
|
*/
|
|
75
|
-
const getOptions = (params: NavigationOptions,
|
|
77
|
+
const getOptions = (params: NavigationOptions, navigation?: Navigation) => {
|
|
76
78
|
let options = {};
|
|
77
79
|
|
|
80
|
+
/**
|
|
81
|
+
* left header factory
|
|
82
|
+
*/
|
|
78
83
|
if (
|
|
79
84
|
typeof params.onPressLeftHeader === 'function' ||
|
|
80
85
|
params.preventBack !== undefined ||
|
|
81
86
|
typeof params.hiddenBack === 'boolean'
|
|
82
87
|
) {
|
|
88
|
+
let headerLeft: any = (props: any) => (
|
|
89
|
+
<HeaderLeft
|
|
90
|
+
{...props}
|
|
91
|
+
preventBack={params.preventBack}
|
|
92
|
+
onPressLeftHeader={params.onPressLeftHeader}
|
|
93
|
+
/>
|
|
94
|
+
);
|
|
95
|
+
if (params.hiddenBack) {
|
|
96
|
+
headerLeft = null;
|
|
97
|
+
}
|
|
83
98
|
options = {
|
|
84
99
|
...options,
|
|
85
|
-
headerLeft
|
|
86
|
-
? null
|
|
87
|
-
: (props: any) => (
|
|
88
|
-
<HeaderLeft
|
|
89
|
-
{...props}
|
|
90
|
-
preventBack={params.preventBack}
|
|
91
|
-
onPressLeftHeader={params.onPressLeftHeader}
|
|
92
|
-
/>
|
|
93
|
-
),
|
|
100
|
+
headerLeft,
|
|
94
101
|
};
|
|
95
102
|
}
|
|
96
103
|
|
|
104
|
+
/**
|
|
105
|
+
* surface header style
|
|
106
|
+
*/
|
|
97
107
|
if (typeof params.surface === 'boolean') {
|
|
108
|
+
console.warn('surface options is deprecated, headerType instead in screen');
|
|
98
109
|
if (params.surface) {
|
|
99
110
|
options = {
|
|
100
111
|
...options,
|
|
101
|
-
headerTintColor:
|
|
112
|
+
headerTintColor: Colors.black_17,
|
|
102
113
|
headerBackground: () => (
|
|
103
114
|
<HeaderBackground image={null} useSurface={true} />
|
|
104
115
|
),
|
|
@@ -112,7 +123,13 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
|
|
|
112
123
|
}
|
|
113
124
|
}
|
|
114
125
|
|
|
126
|
+
/**
|
|
127
|
+
* custom title
|
|
128
|
+
*/
|
|
115
129
|
if (params.customTitle) {
|
|
130
|
+
console.warn(
|
|
131
|
+
'customTitle options is deprecated, please used headerTitle instead'
|
|
132
|
+
);
|
|
116
133
|
options = {
|
|
117
134
|
...options,
|
|
118
135
|
headerTitleAlign: 'left',
|
|
@@ -122,12 +139,37 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
|
|
|
122
139
|
};
|
|
123
140
|
}
|
|
124
141
|
|
|
125
|
-
|
|
142
|
+
/**
|
|
143
|
+
* header right
|
|
144
|
+
*/
|
|
145
|
+
if (params.headerRight) {
|
|
146
|
+
let headerRight: any = (props: any) => {
|
|
147
|
+
return (
|
|
148
|
+
<HeaderRight
|
|
149
|
+
{...props}
|
|
150
|
+
{...params.headerRight}
|
|
151
|
+
onLayout={(e: LayoutChangeEvent) => {
|
|
152
|
+
navigation?.onHeaderRightChange?.(e.nativeEvent.layout.width);
|
|
153
|
+
}}
|
|
154
|
+
/>
|
|
155
|
+
);
|
|
156
|
+
};
|
|
157
|
+
if (typeof params.headerRight === 'function') {
|
|
158
|
+
headerRight = (props: any) => {
|
|
159
|
+
return (
|
|
160
|
+
<HeaderRight
|
|
161
|
+
{...props}
|
|
162
|
+
onLayout={(e: LayoutChangeEvent) => {
|
|
163
|
+
navigation?.onHeaderRightChange?.(e.nativeEvent.layout.width);
|
|
164
|
+
}}>
|
|
165
|
+
{params.headerRight(props)}
|
|
166
|
+
</HeaderRight>
|
|
167
|
+
);
|
|
168
|
+
};
|
|
169
|
+
}
|
|
126
170
|
options = {
|
|
127
171
|
...options,
|
|
128
|
-
headerRight
|
|
129
|
-
return <HeaderToolkitAction {...params.toolkitParams} {...props} />;
|
|
130
|
-
},
|
|
172
|
+
headerRight,
|
|
131
173
|
};
|
|
132
174
|
}
|
|
133
175
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import React, {useEffect, useRef} from 'react';
|
|
2
|
+
import {Animated, View} from 'react-native';
|
|
3
|
+
import {BadgeDotProps} from './types';
|
|
4
|
+
import styles from './styles';
|
|
5
|
+
|
|
6
|
+
const DURATION = 500;
|
|
7
|
+
|
|
8
|
+
const BadgeDotAnimation = ({size, style}: BadgeDotProps) => {
|
|
9
|
+
// Refs for animated values
|
|
10
|
+
const scaleAnim = useRef(new Animated.Value(1)).current;
|
|
11
|
+
const waveScaleAnim = useRef(new Animated.Value(1)).current;
|
|
12
|
+
const waveOpacityAnim = useRef(new Animated.Value(0)).current;
|
|
13
|
+
|
|
14
|
+
const dotStyle =
|
|
15
|
+
size === 'small' ? styles.dotAnimationSmall : styles.dotAnimation;
|
|
16
|
+
const waveStyle = size === 'small' ? styles.waveSmall : styles.wave;
|
|
17
|
+
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
// Infinite loop animation for the scale and wave effect
|
|
20
|
+
const animation = Animated.loop(
|
|
21
|
+
Animated.parallel([
|
|
22
|
+
// Dot pulse animation
|
|
23
|
+
Animated.sequence([
|
|
24
|
+
Animated.spring(scaleAnim, {
|
|
25
|
+
toValue: 1, // Scale up slightly
|
|
26
|
+
friction: 5, // Controls the "bounciness" of the spring
|
|
27
|
+
tension: 30, // Controls the "stiffness" of the spring
|
|
28
|
+
useNativeDriver: true,
|
|
29
|
+
}),
|
|
30
|
+
Animated.spring(scaleAnim, {
|
|
31
|
+
toValue: 1.1,
|
|
32
|
+
friction: 5,
|
|
33
|
+
tension: 30,
|
|
34
|
+
useNativeDriver: true,
|
|
35
|
+
}),
|
|
36
|
+
]), // Wave animation
|
|
37
|
+
Animated.sequence([
|
|
38
|
+
Animated.timing(waveScaleAnim, {
|
|
39
|
+
toValue: 2.5,
|
|
40
|
+
duration: DURATION * 3,
|
|
41
|
+
useNativeDriver: true,
|
|
42
|
+
}),
|
|
43
|
+
Animated.timing(waveScaleAnim, {
|
|
44
|
+
toValue: 1, // Reset wave size
|
|
45
|
+
duration: 0,
|
|
46
|
+
useNativeDriver: true,
|
|
47
|
+
}),
|
|
48
|
+
]), // Wave opacity animation
|
|
49
|
+
Animated.sequence([
|
|
50
|
+
Animated.timing(waveOpacityAnim, {
|
|
51
|
+
toValue: 0.3, // Wave becomes visible
|
|
52
|
+
duration: DURATION * 2,
|
|
53
|
+
useNativeDriver: true,
|
|
54
|
+
}),
|
|
55
|
+
Animated.timing(waveOpacityAnim, {
|
|
56
|
+
toValue: 0, // Wave fades out
|
|
57
|
+
duration: DURATION,
|
|
58
|
+
useNativeDriver: true,
|
|
59
|
+
}),
|
|
60
|
+
]),
|
|
61
|
+
])
|
|
62
|
+
);
|
|
63
|
+
animation.start();
|
|
64
|
+
|
|
65
|
+
return () => {
|
|
66
|
+
animation.stop();
|
|
67
|
+
};
|
|
68
|
+
}, []);
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<View style={[styles.dotAnimationContainer, style]}>
|
|
72
|
+
{/* Wave Animation */}
|
|
73
|
+
<Animated.View
|
|
74
|
+
style={[
|
|
75
|
+
waveStyle,
|
|
76
|
+
{
|
|
77
|
+
transform: [{scale: waveScaleAnim}],
|
|
78
|
+
opacity: waveOpacityAnim,
|
|
79
|
+
},
|
|
80
|
+
]}
|
|
81
|
+
/>
|
|
82
|
+
{/* Dot Animation */}
|
|
83
|
+
<Animated.View
|
|
84
|
+
style={[
|
|
85
|
+
dotStyle,
|
|
86
|
+
{
|
|
87
|
+
transform: [{scale: scaleAnim}],
|
|
88
|
+
},
|
|
89
|
+
]}
|
|
90
|
+
/>
|
|
91
|
+
</View>
|
|
92
|
+
);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export default BadgeDotAnimation;
|
package/Badge/index.tsx
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import Badge from './Badge';
|
|
2
2
|
import BadgeDot from './BadgeDot';
|
|
3
3
|
import BadgeRibbon from './BadgeRibbon';
|
|
4
|
+
import BadgeDotAnimation from './BadgeDotAnimation';
|
|
4
5
|
import {BadgeProps, BadgeDotProps, BadgeRibbonProps} from './types';
|
|
5
6
|
|
|
6
|
-
export {Badge, BadgeRibbon, BadgeDot};
|
|
7
|
+
export {Badge, BadgeRibbon, BadgeDot, BadgeDotAnimation};
|
|
7
8
|
export type {BadgeProps, BadgeDotProps, BadgeRibbonProps};
|
package/Badge/styles.ts
CHANGED
|
@@ -2,6 +2,10 @@ import {StyleSheet} from 'react-native';
|
|
|
2
2
|
import {Colors, Radius, Spacing} from '../Consts';
|
|
3
3
|
import {scaleSize} from '../Text';
|
|
4
4
|
|
|
5
|
+
const DOT_SIZE = 16;
|
|
6
|
+
|
|
7
|
+
const DOT_SMALL_SIZE = 10;
|
|
8
|
+
|
|
5
9
|
export default StyleSheet.create({
|
|
6
10
|
badge: {
|
|
7
11
|
paddingHorizontal: Spacing.XS,
|
|
@@ -15,21 +19,61 @@ export default StyleSheet.create({
|
|
|
15
19
|
borderColor: Colors.black_01,
|
|
16
20
|
alignSelf: 'baseline',
|
|
17
21
|
},
|
|
22
|
+
dotAnimationContainer: {
|
|
23
|
+
position: 'relative',
|
|
24
|
+
alignItems: 'center',
|
|
25
|
+
justifyContent: 'center',
|
|
26
|
+
},
|
|
18
27
|
dot: {
|
|
19
|
-
width:
|
|
20
|
-
height:
|
|
28
|
+
width: DOT_SIZE,
|
|
29
|
+
height: DOT_SIZE,
|
|
21
30
|
borderWidth: 2,
|
|
22
31
|
borderColor: Colors.black_01,
|
|
23
32
|
backgroundColor: Colors.red_03,
|
|
24
|
-
borderRadius:
|
|
33
|
+
borderRadius: DOT_SIZE / 2,
|
|
25
34
|
},
|
|
26
35
|
dotSmall: {
|
|
27
|
-
width:
|
|
28
|
-
height:
|
|
36
|
+
width: DOT_SMALL_SIZE,
|
|
37
|
+
height: DOT_SMALL_SIZE,
|
|
29
38
|
borderWidth: 1,
|
|
30
39
|
borderColor: Colors.black_01,
|
|
31
40
|
backgroundColor: Colors.red_03,
|
|
32
|
-
borderRadius:
|
|
41
|
+
borderRadius: DOT_SMALL_SIZE / 2,
|
|
42
|
+
},
|
|
43
|
+
dotAnimation: {
|
|
44
|
+
width: DOT_SIZE,
|
|
45
|
+
height: DOT_SIZE,
|
|
46
|
+
borderColor: Colors.black_01,
|
|
47
|
+
backgroundColor: Colors.red_03,
|
|
48
|
+
borderRadius: DOT_SIZE / 2,
|
|
49
|
+
borderWidth: 0,
|
|
50
|
+
},
|
|
51
|
+
dotAnimationSmall: {
|
|
52
|
+
width: DOT_SMALL_SIZE,
|
|
53
|
+
height: DOT_SMALL_SIZE,
|
|
54
|
+
borderColor: Colors.black_01,
|
|
55
|
+
backgroundColor: Colors.red_03,
|
|
56
|
+
borderRadius: DOT_SMALL_SIZE / 2,
|
|
57
|
+
borderWidth: 0,
|
|
58
|
+
},
|
|
59
|
+
wave: {
|
|
60
|
+
width: DOT_SIZE,
|
|
61
|
+
height: DOT_SIZE,
|
|
62
|
+
borderColor: Colors.black_01,
|
|
63
|
+
backgroundColor: Colors.red_03,
|
|
64
|
+
borderRadius: DOT_SIZE / 2,
|
|
65
|
+
opacity: 0,
|
|
66
|
+
position: 'absolute',
|
|
67
|
+
borderWidth: 0,
|
|
68
|
+
},
|
|
69
|
+
waveSmall: {
|
|
70
|
+
width: DOT_SMALL_SIZE,
|
|
71
|
+
height: DOT_SMALL_SIZE,
|
|
72
|
+
borderColor: Colors.black_01,
|
|
73
|
+
backgroundColor: Colors.red_03,
|
|
74
|
+
borderRadius: DOT_SMALL_SIZE / 2,
|
|
75
|
+
borderWidth: 0,
|
|
76
|
+
position: 'absolute',
|
|
33
77
|
},
|
|
34
78
|
ribbon: {
|
|
35
79
|
alignSelf: 'baseline',
|
package/Button/index.tsx
CHANGED
package/Icon/types.ts
CHANGED
package/Input/Input.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, {
|
|
2
2
|
forwardRef,
|
|
3
|
+
ReactNode,
|
|
3
4
|
useContext,
|
|
4
5
|
useImperativeHandle,
|
|
5
6
|
useRef,
|
|
@@ -16,11 +17,15 @@ import {
|
|
|
16
17
|
import {ApplicationContext, ComponentContext} from '../Application';
|
|
17
18
|
import {Icon} from '../Icon';
|
|
18
19
|
import {Loader} from '../Loader';
|
|
20
|
+
import {Text} from '../Text';
|
|
19
21
|
import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
20
22
|
import {InputProps} from './index';
|
|
21
23
|
import styles from './styles';
|
|
22
24
|
import {checkTyping} from './utils';
|
|
23
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Input default component
|
|
28
|
+
*/
|
|
24
29
|
const Input = forwardRef(
|
|
25
30
|
(
|
|
26
31
|
{
|
|
@@ -34,16 +39,19 @@ const Input = forwardRef(
|
|
|
34
39
|
onFocus,
|
|
35
40
|
errorMessage,
|
|
36
41
|
icon,
|
|
42
|
+
iconColor,
|
|
43
|
+
onPressIcon,
|
|
44
|
+
trailing,
|
|
45
|
+
trailingColor,
|
|
46
|
+
onPressTrailing,
|
|
37
47
|
disabled = false,
|
|
38
48
|
floatingIconColor,
|
|
39
|
-
iconColor,
|
|
40
49
|
required = false,
|
|
41
50
|
errorSpacing,
|
|
42
51
|
loading = false,
|
|
43
52
|
leadingIcon,
|
|
44
53
|
leadingIconColor,
|
|
45
54
|
fontWeight = 'Regular',
|
|
46
|
-
onPressIcon,
|
|
47
55
|
secureTextEntry,
|
|
48
56
|
keyboardType,
|
|
49
57
|
style,
|
|
@@ -51,9 +59,10 @@ const Input = forwardRef(
|
|
|
51
59
|
hintText,
|
|
52
60
|
accessibilityLabel,
|
|
53
61
|
editable = true,
|
|
62
|
+
onPressFloatingIcon,
|
|
54
63
|
...props
|
|
55
64
|
}: InputProps,
|
|
56
|
-
ref
|
|
65
|
+
ref
|
|
57
66
|
) => {
|
|
58
67
|
const {theme} = useContext(ApplicationContext);
|
|
59
68
|
const [focused, setFocused] = useState(false);
|
|
@@ -90,7 +99,11 @@ const Input = forwardRef(
|
|
|
90
99
|
};
|
|
91
100
|
});
|
|
92
101
|
|
|
93
|
-
|
|
102
|
+
/**
|
|
103
|
+
* Render trailing icon or text
|
|
104
|
+
* @param color
|
|
105
|
+
*/
|
|
106
|
+
const renderTrailing = (color?: string) => {
|
|
94
107
|
if (loading) {
|
|
95
108
|
return <Loader type={'spinner'} color={color} style={styles.icon} />;
|
|
96
109
|
}
|
|
@@ -109,24 +122,46 @@ const Input = forwardRef(
|
|
|
109
122
|
</TouchableOpacity>
|
|
110
123
|
);
|
|
111
124
|
}
|
|
112
|
-
if (icon) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
125
|
+
if (icon || trailing) {
|
|
126
|
+
const renderIconTouchable = (icon: ReactNode) => {
|
|
127
|
+
return (
|
|
128
|
+
<TouchableOpacity
|
|
129
|
+
onPress={onPressTrailing ?? onPressIcon}
|
|
130
|
+
style={styles.icon}>
|
|
131
|
+
{icon}
|
|
132
|
+
</TouchableOpacity>
|
|
133
|
+
);
|
|
134
|
+
};
|
|
135
|
+
const trailingValue = icon || trailing;
|
|
136
|
+
if (trailingValue?.includes('_') || trailingValue?.includes('http')) {
|
|
137
|
+
return renderIconTouchable(
|
|
138
|
+
<Icon
|
|
139
|
+
color={color}
|
|
140
|
+
source={(icon || trailing) as string}
|
|
141
|
+
size={24}
|
|
142
|
+
/>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
return renderIconTouchable(
|
|
146
|
+
<Text
|
|
147
|
+
typography="action_xs_bold"
|
|
148
|
+
color={color ?? theme.colors.primary}
|
|
149
|
+
numberOfLines={1}>
|
|
150
|
+
{trailingValue!.substring(0, 15)}
|
|
151
|
+
</Text>
|
|
120
152
|
);
|
|
121
153
|
}
|
|
122
154
|
};
|
|
123
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Render input view
|
|
158
|
+
*/
|
|
124
159
|
const renderInputView = () => {
|
|
125
160
|
const disabledColor = theme.colors.text.disable;
|
|
126
161
|
const secure = secureTextInput && secureTextEntry;
|
|
127
162
|
let textColor = theme.colors.text.default;
|
|
128
163
|
let placeholderColor = theme.colors.text.hint;
|
|
129
|
-
let iconTintColor = iconColor;
|
|
164
|
+
let iconTintColor = trailingColor ?? iconColor;
|
|
130
165
|
|
|
131
166
|
if (disabled) {
|
|
132
167
|
textColor = disabledColor;
|
|
@@ -155,6 +190,7 @@ const Input = forwardRef(
|
|
|
155
190
|
disabled={disabled}
|
|
156
191
|
required={required}
|
|
157
192
|
floatingIcon={floatingIcon}
|
|
193
|
+
onPress={onPressFloatingIcon}
|
|
158
194
|
/>
|
|
159
195
|
<View style={styles.inputView}>
|
|
160
196
|
{!!leadingIcon && (
|
|
@@ -204,21 +240,19 @@ const Input = forwardRef(
|
|
|
204
240
|
/>
|
|
205
241
|
</TouchableOpacity>
|
|
206
242
|
)}
|
|
207
|
-
{
|
|
243
|
+
{renderTrailing(iconTintColor)}
|
|
208
244
|
</View>
|
|
209
245
|
</View>
|
|
210
246
|
);
|
|
211
247
|
};
|
|
212
248
|
|
|
213
249
|
let inputState = 'active';
|
|
214
|
-
|
|
215
250
|
if (value && value?.length > 0) {
|
|
216
251
|
inputState = 'filled';
|
|
217
252
|
}
|
|
218
253
|
if (errorMessage && errorMessage?.length > 0) {
|
|
219
254
|
inputState = 'error';
|
|
220
255
|
}
|
|
221
|
-
|
|
222
256
|
if (disabled) {
|
|
223
257
|
inputState = 'disabled';
|
|
224
258
|
}
|
|
@@ -242,7 +276,7 @@ const Input = forwardRef(
|
|
|
242
276
|
</View>
|
|
243
277
|
</ComponentContext.Provider>
|
|
244
278
|
);
|
|
245
|
-
}
|
|
279
|
+
}
|
|
246
280
|
);
|
|
247
281
|
|
|
248
282
|
export default Input;
|