ikualo-ui-kit-mobile 0.0.4 → 0.0.7
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/assets/styles/elements/alert.ts +2 -3
- package/assets/styles/elements/buttons.ts +16 -1
- package/assets/styles/elements/cards.ts +1 -2
- package/assets/styles/elements/dropdown.ts +8 -3
- package/package.json +4 -10
- package/src/config/paper.config.ts +2 -1
- package/src/elements/alerts/Alert.tsx +4 -3
- package/src/elements/buttons/BtnLightSmall.tsx +12 -5
- package/src/elements/cards/CardInteractive.tsx +9 -7
- package/src/elements/dropdown/Dropdown.tsx +28 -23
- package/src/elements/inputs/Input.tsx +37 -13
- package/src/elements/inputs/InputPassword.tsx +3 -0
- package/src/elements/progressBar/ProgressBar.tsx +3 -2
- package/src/elements/progressBar/ProgressBarSteps.tsx +3 -2
|
@@ -11,7 +11,6 @@ const styleAlerts = StyleSheet.create({
|
|
|
11
11
|
width: '92%',
|
|
12
12
|
borderRadius: 4,
|
|
13
13
|
borderLeftWidth: 8,
|
|
14
|
-
minHeight: 102,
|
|
15
14
|
padding: 16,
|
|
16
15
|
},
|
|
17
16
|
'alert--info': {
|
|
@@ -31,8 +30,8 @@ const styleAlerts = StyleSheet.create({
|
|
|
31
30
|
borderLeftColor: theme.colors.darkRed,
|
|
32
31
|
},
|
|
33
32
|
'alert-container-text': { flexDirection: 'row', gap: 8 },
|
|
34
|
-
'alert-container-title': { fontSize: 14, fontFamily: 'MontserratBold', color: theme.colors.text },
|
|
33
|
+
'alert-container-title': { fontSize: 14, fontFamily: 'MontserratBold', color: theme.colors.text , alignSelf: 'center' },
|
|
35
34
|
'alert-body': { marginTop: 8 },
|
|
36
35
|
});
|
|
37
36
|
|
|
38
|
-
export { styleAlerts };
|
|
37
|
+
export { styleAlerts };
|
|
@@ -156,6 +156,7 @@ const stylesBtnLightSmall = StyleSheet.create({
|
|
|
156
156
|
minHeight: 48,
|
|
157
157
|
width: 48,
|
|
158
158
|
height: 48,
|
|
159
|
+
position: 'relative',
|
|
159
160
|
},
|
|
160
161
|
'btn-light-small-content': {
|
|
161
162
|
alignSelf: 'center',
|
|
@@ -166,7 +167,6 @@ const stylesBtnLightSmall = StyleSheet.create({
|
|
|
166
167
|
minHeight: 48,
|
|
167
168
|
width: 48,
|
|
168
169
|
height: 48,
|
|
169
|
-
marginLeft: 12,
|
|
170
170
|
},
|
|
171
171
|
'btn-light-small-label': {
|
|
172
172
|
fontSize: 24,
|
|
@@ -183,8 +183,23 @@ const stylesBtnLightSmall = StyleSheet.create({
|
|
|
183
183
|
width: 48,
|
|
184
184
|
height: 48,
|
|
185
185
|
},
|
|
186
|
+
'btn-light-small--active': {
|
|
187
|
+
backgroundColor: theme.colors.secondaryLight,
|
|
188
|
+
borderColor: theme.colors.secondary,
|
|
189
|
+
borderRadius: 8,
|
|
190
|
+
borderWidth: 1,
|
|
191
|
+
maxWidth: 48,
|
|
192
|
+
minWidth: 48,
|
|
193
|
+
maxHeight: 48,
|
|
194
|
+
minHeight: 48,
|
|
195
|
+
width: 48,
|
|
196
|
+
height: 48,
|
|
197
|
+
},
|
|
186
198
|
'btn-light-small-label--disabled': {
|
|
187
199
|
color: theme.colors.disabledButtonBorder,
|
|
188
200
|
},
|
|
201
|
+
'btn-light-small-label--active': {
|
|
202
|
+
color: theme.colors.secondary,
|
|
203
|
+
},
|
|
189
204
|
});
|
|
190
205
|
export { stylesButtonContained, stylesButtonOutlined, stylesButtonText, stylesBtnLightSmall };
|
|
@@ -4,15 +4,14 @@ import { theme } from '../../../src/config/paper.config';
|
|
|
4
4
|
const styleDropdown = StyleSheet.create({
|
|
5
5
|
'dropdown-container': {
|
|
6
6
|
width: 'auto',
|
|
7
|
-
marginRight: -42,
|
|
8
7
|
flexDirection: 'row',
|
|
9
8
|
justifyContent: 'flex-end',
|
|
9
|
+
marginTop:28
|
|
10
10
|
},
|
|
11
11
|
'dropdown-menu': { flexDirection: 'row', alignItems: 'center' },
|
|
12
|
+
'dropdown-content': { backgroundColor: 'white', borderRadius: 16, padding: 16 },
|
|
12
13
|
'dropdown-label': { fontSize: 16, marginTop: 15 },
|
|
13
14
|
'dropdown-label-content': { width: 70 },
|
|
14
|
-
'dropdown-label-arrow': { fontSize: 24 },
|
|
15
|
-
'dropdown-label-width': { width: 10 },
|
|
16
15
|
'dropdown-overlay': {
|
|
17
16
|
position: 'absolute',
|
|
18
17
|
top: 0,
|
|
@@ -27,6 +26,12 @@ const styleDropdown = StyleSheet.create({
|
|
|
27
26
|
fontSize: 14,
|
|
28
27
|
color: theme.colors.boldBlack,
|
|
29
28
|
},
|
|
29
|
+
'dropdown-color--primary': {
|
|
30
|
+
color: theme.colors.primary,
|
|
31
|
+
},
|
|
32
|
+
'dropdown-highlight-color': {
|
|
33
|
+
color: theme.colors.lightPrimary,
|
|
34
|
+
}
|
|
30
35
|
});
|
|
31
36
|
|
|
32
37
|
export { styleDropdown };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ikualo-ui-kit-mobile",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"main": "src/index.ts",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"start": "expo start",
|
|
@@ -10,11 +10,10 @@
|
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@expo/metro-runtime": "~3.2.1",
|
|
13
|
+
"@expo/vector-icons": "^14.0.3",
|
|
13
14
|
"@react-navigation/bottom-tabs": "^6.5.20",
|
|
14
15
|
"@react-navigation/native": "^6.1.17",
|
|
15
16
|
"@react-navigation/stack": "^6.3.29",
|
|
16
|
-
"axios": "^1.7.2",
|
|
17
|
-
"crypto-js": "^4.2.0",
|
|
18
17
|
"expo": "~51.0.8",
|
|
19
18
|
"expo-application": "~5.9.1",
|
|
20
19
|
"expo-constants": "^16.0.1",
|
|
@@ -27,21 +26,16 @@
|
|
|
27
26
|
"expo-secure-store": "~13.0.2",
|
|
28
27
|
"expo-status-bar": "~1.12.1",
|
|
29
28
|
"expo-updates": "^0.25.14",
|
|
30
|
-
"i18next": "^23.11.5",
|
|
31
|
-
"p-retry": "^6.2.0",
|
|
32
29
|
"react": "18.2.0",
|
|
33
30
|
"react-dom": "18.2.0",
|
|
34
|
-
"react-i18next": "^14.1.2",
|
|
35
31
|
"react-native": "0.74.1",
|
|
36
32
|
"react-native-asset": "^2.1.1",
|
|
37
33
|
"react-native-country-flag": "^2.0.2",
|
|
38
|
-
"react-native-crypto-js": "^1.0.0",
|
|
39
34
|
"react-native-gesture-handler": "^2.16.2",
|
|
40
35
|
"react-native-paper": "^5.12.3",
|
|
41
36
|
"react-native-safe-area-context": "^4.10.1",
|
|
42
37
|
"react-native-screens": "^3.31.1",
|
|
43
|
-
"react-native-web": "~0.19.10"
|
|
44
|
-
"zustand": "^4.5.2"
|
|
38
|
+
"react-native-web": "~0.19.10"
|
|
45
39
|
},
|
|
46
40
|
"devDependencies": {
|
|
47
41
|
"@babel/cli": "^7.24.8",
|
|
@@ -53,4 +47,4 @@
|
|
|
53
47
|
"metro-react-native-babel-preset": "^0.77.0",
|
|
54
48
|
"typescript": "^5.1.3"
|
|
55
49
|
}
|
|
56
|
-
}
|
|
50
|
+
}
|
|
@@ -5,7 +5,7 @@ import { styleAlerts } from '../../../assets/styles/elements/alert';
|
|
|
5
5
|
import { icons } from '../../../assets/icons/_icons';
|
|
6
6
|
interface IFAlertInfo {
|
|
7
7
|
title: string;
|
|
8
|
-
text
|
|
8
|
+
text?: JSX.Element;
|
|
9
9
|
type: 'info' | 'warning' | 'error' | 'success';
|
|
10
10
|
onClose: () => void;
|
|
11
11
|
}
|
|
@@ -24,8 +24,9 @@ export const Alert = (props: IFAlertInfo) => {
|
|
|
24
24
|
<Image source={icons[type]} />
|
|
25
25
|
<Text style={styleAlerts['alert-container-title']}>{title}</Text>
|
|
26
26
|
</View>
|
|
27
|
-
<View style={styleAlerts['alert-body']}>{text}</View>
|
|
27
|
+
{text && <View style={styleAlerts['alert-body']}>{text}</View>}
|
|
28
|
+
|
|
28
29
|
</Animated.View>
|
|
29
30
|
</Portal>
|
|
30
31
|
);
|
|
31
|
-
}
|
|
32
|
+
}
|
|
@@ -1,31 +1,38 @@
|
|
|
1
|
+
|
|
1
2
|
import { Button, Text } from 'react-native-paper';
|
|
2
3
|
import { stylesBtnLightSmall } from '../../../assets/styles/elements/buttons';
|
|
4
|
+
import { View } from 'react-native';
|
|
5
|
+
import { cloneElement } from 'react';
|
|
3
6
|
|
|
4
7
|
interface IfBtnLightSmall {
|
|
5
8
|
onPress: () => void;
|
|
6
|
-
icon:
|
|
9
|
+
icon: JSX.Element;
|
|
7
10
|
disabled?: boolean;
|
|
11
|
+
active?: boolean;
|
|
8
12
|
}
|
|
9
13
|
export const BtnLightSmall = (props: IfBtnLightSmall) => {
|
|
10
|
-
const { onPress, icon, disabled = false } = props;
|
|
14
|
+
const { onPress, icon, disabled = false,active } = props;
|
|
11
15
|
const anything = '';
|
|
12
|
-
|
|
13
16
|
return (
|
|
14
17
|
<Button
|
|
15
18
|
style={[
|
|
16
19
|
stylesBtnLightSmall['btn-light-small'],
|
|
20
|
+
active && stylesBtnLightSmall['btn-light-small--active'],
|
|
17
21
|
disabled && stylesBtnLightSmall['btn-light-small--disabled'],
|
|
18
22
|
]}
|
|
19
23
|
contentStyle={stylesBtnLightSmall['btn-light-small-content']}
|
|
20
24
|
labelStyle={[
|
|
21
25
|
(stylesBtnLightSmall['btn-light-small-label'],
|
|
26
|
+
active && stylesBtnLightSmall['btn-light-small-label--active'],
|
|
22
27
|
disabled && stylesBtnLightSmall['btn-light-small-label--disabled']),
|
|
23
28
|
]}
|
|
24
29
|
onPress={onPress}
|
|
25
|
-
icon={icon}
|
|
26
30
|
disabled={disabled}
|
|
27
31
|
>
|
|
28
|
-
<
|
|
32
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
|
|
33
|
+
{cloneElement(icon, { size:21,color: active?stylesBtnLightSmall['btn-light-small--active'].borderColor: stylesBtnLightSmall['btn-light-small'].borderColor })}
|
|
34
|
+
<Text>{anything}</Text>
|
|
35
|
+
</View>
|
|
29
36
|
</Button>
|
|
30
37
|
);
|
|
31
38
|
};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { View
|
|
1
|
+
import { View } from 'react-native';
|
|
2
2
|
import { Card, Text, TouchableRipple } from 'react-native-paper';
|
|
3
3
|
import { stylesCards } from '../../../assets/styles/elements/cards';
|
|
4
|
-
import
|
|
5
|
-
|
|
4
|
+
import FontAwesome6 from '@expo/vector-icons/FontAwesome6';
|
|
5
|
+
import { cloneElement } from 'react';
|
|
6
|
+
import { theme } from '../../config/paper.config';
|
|
6
7
|
interface IFCardInteractive {
|
|
7
|
-
|
|
8
|
+
iconLeft?: JSX.Element;
|
|
9
|
+
iconRight?: JSX.Element;
|
|
8
10
|
title: string;
|
|
9
11
|
description?: string;
|
|
10
12
|
onPress: () => void;
|
|
@@ -12,13 +14,13 @@ interface IFCardInteractive {
|
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export const CardInteractive = (props: IFCardInteractive) => {
|
|
15
|
-
const {
|
|
17
|
+
const { iconLeft, title, description,iconRight, onPress } = props;
|
|
16
18
|
return (
|
|
17
19
|
<TouchableRipple onPress={onPress}>
|
|
18
20
|
<Card style={stylesCards['card-interactive']}>
|
|
19
21
|
<View style={stylesCards['card-interactive-info']}>
|
|
20
22
|
<View style={stylesCards['card-interactive-container']}>
|
|
21
|
-
{
|
|
23
|
+
{iconLeft ? cloneElement(iconLeft, { style: stylesCards['card-interactive-icon'],color:theme.colors.primary }) : ""}
|
|
22
24
|
<View>
|
|
23
25
|
<Text style={stylesCards['card-interactive-text']}>{title}</Text>
|
|
24
26
|
<View style={stylesCards['card-interactive-description']}>
|
|
@@ -26,7 +28,7 @@ export const CardInteractive = (props: IFCardInteractive) => {
|
|
|
26
28
|
</View>
|
|
27
29
|
</View>
|
|
28
30
|
</View>
|
|
29
|
-
|
|
31
|
+
{iconRight??<FontAwesome6 name="chevron-right" size={15} color={theme.colors.blackText} />}
|
|
30
32
|
</View>
|
|
31
33
|
</Card>
|
|
32
34
|
</TouchableRipple>
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
|
-
import { View } from 'react-native';
|
|
2
|
+
import { TouchableNativeFeedback, View } from 'react-native';
|
|
3
3
|
import { Button, Divider, Menu, Portal } from 'react-native-paper';
|
|
4
4
|
import { BtnIcon } from '../buttons/BtnIcon';
|
|
5
|
-
import { icons } from '../../../assets/icons/_icons';
|
|
6
5
|
import { styleDropdown } from '../../../assets/styles/elements/dropdown';
|
|
7
6
|
import { theme } from '../../config/paper.config';
|
|
7
|
+
import FontAwesome6 from '@expo/vector-icons/FontAwesome6';
|
|
8
|
+
import { TouchableHighlight } from 'react-native-gesture-handler';
|
|
8
9
|
interface IFDropdown {
|
|
9
10
|
items: IFMenuItem[];
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
iconText?: string;
|
|
12
|
+
iconToShow?: JSX.Element;
|
|
13
|
+
label?: string;
|
|
12
14
|
title?: string;
|
|
13
15
|
onPress: (value: string) => void;
|
|
14
16
|
}
|
|
@@ -19,34 +21,37 @@ interface IFMenuItem {
|
|
|
19
21
|
divider?: boolean;
|
|
20
22
|
}
|
|
21
23
|
export const Dropdown = (props: IFDropdown) => {
|
|
22
|
-
const { items,
|
|
24
|
+
const { items, iconText, label, title, iconToShow, onPress } = props;
|
|
23
25
|
const [visible, setVisible] = useState(false);
|
|
24
26
|
const openMenu = () => setVisible(true);
|
|
25
27
|
const closeMenu = () => setVisible(false);
|
|
26
|
-
|
|
27
28
|
return (
|
|
28
29
|
<View style={styleDropdown['dropdown-container']}>
|
|
29
30
|
<Menu
|
|
30
31
|
anchorPosition="bottom"
|
|
31
|
-
contentStyle={
|
|
32
|
+
contentStyle={styleDropdown['dropdown-content']}
|
|
32
33
|
visible={visible}
|
|
33
34
|
onDismiss={closeMenu}
|
|
34
35
|
anchor={
|
|
35
|
-
<View
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
36
|
+
<View
|
|
37
|
+
style={styleDropdown['dropdown-menu']}
|
|
38
|
+
>
|
|
39
|
+
{label &&
|
|
40
|
+
<BtnIcon
|
|
41
|
+
labelStyle={styleDropdown['dropdown-label']}
|
|
42
|
+
contentStyle={styleDropdown['dropdown-label-content']}
|
|
43
|
+
icon={iconText}
|
|
44
|
+
text={label}
|
|
45
|
+
direction={'left'}
|
|
46
|
+
onPress={openMenu}
|
|
47
|
+
/>
|
|
48
|
+
}
|
|
49
|
+
<TouchableHighlight
|
|
50
|
+
onPress={openMenu}
|
|
51
|
+
underlayColor={styleDropdown['dropdown-highlight-color'].color}
|
|
52
|
+
>
|
|
53
|
+
{iconToShow ?? <FontAwesome6 name="chevron-down" size={15} color={styleDropdown['dropdown-color--primary'].color} />}
|
|
54
|
+
</TouchableHighlight>
|
|
50
55
|
</View>
|
|
51
56
|
}
|
|
52
57
|
>
|
|
@@ -81,4 +86,4 @@ export const Dropdown = (props: IFDropdown) => {
|
|
|
81
86
|
<Portal>{visible && <View style={styleDropdown['dropdown-overlay']} />}</Portal>
|
|
82
87
|
</View>
|
|
83
88
|
);
|
|
84
|
-
};
|
|
89
|
+
};
|
|
@@ -28,10 +28,13 @@ interface IfInputText {
|
|
|
28
28
|
isValid?: boolean;
|
|
29
29
|
msgHelper?: string;
|
|
30
30
|
msgError?: string;
|
|
31
|
+
required?: boolean;
|
|
32
|
+
msgErrorRequired?: string;
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
export const Input = (props: IfInputText) => {
|
|
34
36
|
const [isFocus, setIsFocus] = useState<boolean>(false);
|
|
37
|
+
const [errorRequired, setErrorRequired] = useState<boolean>(false);
|
|
35
38
|
const {
|
|
36
39
|
label,
|
|
37
40
|
isDisabled,
|
|
@@ -53,15 +56,22 @@ export const Input = (props: IfInputText) => {
|
|
|
53
56
|
type,
|
|
54
57
|
placeholder,
|
|
55
58
|
pattern,
|
|
59
|
+
required,
|
|
60
|
+
msgErrorRequired
|
|
56
61
|
} = props;
|
|
57
62
|
const patternNumber = /^[0-9]*$/;
|
|
58
63
|
const patternAlphanumeric = /^[a-zA-Z0-9]*$/;
|
|
64
|
+
const patternLettersWithAccentsAndSpaces = /^[a-zA-ZáéíóúÁÉÍÓÚñÑ\s]*$/;
|
|
59
65
|
const onChangeText = (text: string) => {
|
|
60
66
|
onChange(text);
|
|
67
|
+
setErrorRequired(false);
|
|
61
68
|
if (type === 'number' && !patternNumber.test(text)) {
|
|
62
69
|
onInvalid && onInvalid();
|
|
63
70
|
} else if (type === 'alphanumeric' && !patternAlphanumeric.test(text)) {
|
|
64
71
|
onInvalid && onInvalid();
|
|
72
|
+
}
|
|
73
|
+
else if (type === 'text' && !patternLettersWithAccentsAndSpaces.test(text)) {
|
|
74
|
+
onInvalid && onInvalid();
|
|
65
75
|
} else if (pattern && !pattern.test(text)) {
|
|
66
76
|
onInvalid && onInvalid();
|
|
67
77
|
}
|
|
@@ -69,15 +79,17 @@ export const Input = (props: IfInputText) => {
|
|
|
69
79
|
return (
|
|
70
80
|
<View>
|
|
71
81
|
<TextInput
|
|
72
|
-
label={!isFocus && placeholder && value
|
|
82
|
+
label={!isFocus && placeholder && value?.trim() !== '' ? placeholder : label}
|
|
73
83
|
mode={mode ?? 'flat'}
|
|
74
84
|
disabled={isDisabled}
|
|
75
85
|
value={value}
|
|
76
86
|
onChangeText={onChangeText}
|
|
77
87
|
maxLength={maxLength}
|
|
88
|
+
selectionColor={!errorRequired ?styleInput['input'].borderBottomColor:styleInput['input-txt-error'].borderBottomColor}
|
|
78
89
|
theme={{
|
|
79
90
|
colors: {
|
|
80
|
-
onSurfaceVariant: styleInput['input-txt'].
|
|
91
|
+
onSurfaceVariant: !errorRequired ?styleInput['input'].borderBottomColor:styleInput['input-txt-error'].borderBottomColor,
|
|
92
|
+
error: styleInput['input-txt-error'].borderBottomColor,
|
|
81
93
|
},
|
|
82
94
|
}}
|
|
83
95
|
onFocus={() => {
|
|
@@ -87,44 +99,56 @@ export const Input = (props: IfInputText) => {
|
|
|
87
99
|
onBlur={() => {
|
|
88
100
|
setIsFocus(false);
|
|
89
101
|
onBlur && onBlur();
|
|
102
|
+
if (value?.trim() === '' && required) {
|
|
103
|
+
setErrorRequired(true);
|
|
104
|
+
onInvalid && onInvalid();
|
|
105
|
+
}
|
|
90
106
|
}}
|
|
91
|
-
error={error}
|
|
107
|
+
error={error || errorRequired}
|
|
92
108
|
textColor={textColor}
|
|
93
109
|
style={[styleInput['input-label'], style ?? []]}
|
|
94
110
|
contentStyle={[
|
|
95
111
|
styleInput['input-label'],
|
|
96
112
|
isFocus && isValid && styleInput['input-text--focused'],
|
|
97
|
-
!isValid && value
|
|
98
|
-
!isValid && !isFocus && value
|
|
113
|
+
!isValid && value?.trim() !== '' && styleInput['input-error-focused'],
|
|
114
|
+
!isValid && !isFocus && value?.trim() !== '' && styleInput['input-txt-error'],
|
|
115
|
+
errorRequired && styleInput['input-txt-error'],
|
|
116
|
+
errorRequired && isFocus && styleInput['input-error-focused'],
|
|
99
117
|
style ?? [],
|
|
100
118
|
]}
|
|
101
119
|
underlineColor={
|
|
102
120
|
underlineColor
|
|
103
121
|
? underlineColor
|
|
104
|
-
: isValid
|
|
105
|
-
|
|
106
|
-
|
|
122
|
+
: isValid && !errorRequired
|
|
123
|
+
? styleInput['input-text-underline'].color
|
|
124
|
+
: styleInput['input-txt-error'].borderBottomColor
|
|
107
125
|
}
|
|
108
126
|
activeUnderlineColor={
|
|
109
127
|
activeUnderlineColor
|
|
110
128
|
? activeUnderlineColor
|
|
111
|
-
: !isValid && value
|
|
112
|
-
|
|
113
|
-
|
|
129
|
+
: !isValid && value?.trim() !== ''
|
|
130
|
+
? styleInput['input-text--activeUnderline'].color
|
|
131
|
+
: errorRequired ? styleInput['input-txt-error'].color:''
|
|
114
132
|
}
|
|
115
133
|
keyboardType={type === 'number' ? 'numeric' : 'default'}
|
|
116
134
|
/>
|
|
117
|
-
{isValid && (
|
|
135
|
+
{isValid && !errorRequired && (
|
|
118
136
|
<HelperText type="info" style={styleInput['input-password-helper']} visible={true}>
|
|
119
137
|
{msgHelper}
|
|
120
138
|
</HelperText>
|
|
121
139
|
)}
|
|
122
|
-
{!isValid && msgError !== undefined && value
|
|
140
|
+
{!isValid && msgError !== undefined && value?.trim() !== '' && !errorRequired && (
|
|
123
141
|
<View style={styleInput['input-helper--error-text']}>
|
|
124
142
|
<Image style={styleInput['input-helper--error-image']} source={icons.error} />
|
|
125
143
|
<Text style={styleInput['input-password-helper--error-text']}>{msgError}</Text>
|
|
126
144
|
</View>
|
|
127
145
|
)}
|
|
146
|
+
{errorRequired && (
|
|
147
|
+
<View style={styleInput['input-helper--error-text']}>
|
|
148
|
+
<Image style={styleInput['input-helper--error-image']} source={icons.error} />
|
|
149
|
+
<Text style={styleInput['input-password-helper--error-text']}>{msgErrorRequired}</Text>
|
|
150
|
+
</View>
|
|
151
|
+
)}
|
|
128
152
|
</View>
|
|
129
153
|
);
|
|
130
154
|
};
|
|
@@ -25,6 +25,7 @@ interface IfInputPassword {
|
|
|
25
25
|
msgHelper?: string;
|
|
26
26
|
msgError?: string;
|
|
27
27
|
pattern?: RegExp;
|
|
28
|
+
readonly?: boolean;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export const InputPassword = (props: IfInputPassword) => {
|
|
@@ -49,6 +50,7 @@ export const InputPassword = (props: IfInputPassword) => {
|
|
|
49
50
|
msgError,
|
|
50
51
|
pattern,
|
|
51
52
|
onInvalid,
|
|
53
|
+
readonly
|
|
52
54
|
} = props;
|
|
53
55
|
const patternPasswordDefault = pattern ?? /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d#?!@$%^&*-]{8,}$/;
|
|
54
56
|
|
|
@@ -67,6 +69,7 @@ export const InputPassword = (props: IfInputPassword) => {
|
|
|
67
69
|
disabled={isDisabled}
|
|
68
70
|
value={value}
|
|
69
71
|
onChangeText={validateText}
|
|
72
|
+
readOnly={readonly}
|
|
70
73
|
onFocus={() => {
|
|
71
74
|
setIsFocus(true);
|
|
72
75
|
onFocus && onFocus();
|
|
@@ -6,14 +6,15 @@ interface IfProgressBarComponent {
|
|
|
6
6
|
title: string;
|
|
7
7
|
progressValue: number;
|
|
8
8
|
style?: object;
|
|
9
|
+
width: number;
|
|
9
10
|
isActive: boolean;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export const ProgressBarComponent = (props: IfProgressBarComponent) => {
|
|
13
|
-
const { title, progressValue, style, isActive } = props;
|
|
14
|
+
const { title, progressValue, style, isActive,width } = props;
|
|
14
15
|
|
|
15
16
|
return (
|
|
16
|
-
<View style={
|
|
17
|
+
<View style={{width: `${width}%`}}>
|
|
17
18
|
{title && (
|
|
18
19
|
<Text
|
|
19
20
|
style={[
|
|
@@ -15,7 +15,7 @@ interface IFProgressBar {
|
|
|
15
15
|
export const ProgressBarSteps = (props: IFProgressBarStepsProps) => {
|
|
16
16
|
const { items, currentKey, children } = props;
|
|
17
17
|
const currentItem: IFProgressBar | undefined = items.find((item) => item.key === currentKey);
|
|
18
|
-
|
|
18
|
+
const width = Math.round(100 / items.length);
|
|
19
19
|
return (
|
|
20
20
|
<>
|
|
21
21
|
<View style={styleRegisterContent['progress-bar-container']}>
|
|
@@ -23,6 +23,7 @@ export const ProgressBarSteps = (props: IFProgressBarStepsProps) => {
|
|
|
23
23
|
return (
|
|
24
24
|
<ProgressBarComponent
|
|
25
25
|
key={item.key}
|
|
26
|
+
width={width}
|
|
26
27
|
title={item.title}
|
|
27
28
|
progressValue={item.progress}
|
|
28
29
|
isActive={item.progress > 0 || item.key === currentKey}
|
|
@@ -34,4 +35,4 @@ export const ProgressBarSteps = (props: IFProgressBarStepsProps) => {
|
|
|
34
35
|
{currentItem?.child}
|
|
35
36
|
</>
|
|
36
37
|
);
|
|
37
|
-
};
|
|
38
|
+
};
|