@teamnhz/rn-ui-toolkit 1.0.1 → 1.0.3

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.
Files changed (40) hide show
  1. package/README.md +3 -2
  2. package/dist/assets/images/ic_calendar.png +0 -0
  3. package/dist/assets/images/ic_time.png +0 -0
  4. package/dist/components/BottomSheet/index.js +58 -2
  5. package/dist/components/Buttons/index.d.ts +2 -2
  6. package/dist/components/Buttons/index.js +102 -11
  7. package/dist/components/CheckBox/index.d.ts +2 -2
  8. package/dist/components/CheckBox/index.js +112 -15
  9. package/dist/components/DateTimePicker/index.d.ts +25 -3
  10. package/dist/components/DateTimePicker/index.js +248 -22
  11. package/dist/components/Dividers/index.d.ts +3 -3
  12. package/dist/components/Dividers/index.js +41 -5
  13. package/dist/components/HorizontalFlatList/index.d.ts +2 -2
  14. package/dist/components/HorizontalFlatList/index.js +47 -8
  15. package/dist/components/Image/index.d.ts +2 -4
  16. package/dist/components/Image/index.js +22 -4
  17. package/dist/components/ImagePicker/index.d.ts +8 -1
  18. package/dist/components/ImagePicker/index.js +154 -18
  19. package/dist/components/Input/index.d.ts +17 -3
  20. package/dist/components/Input/index.js +302 -19
  21. package/dist/components/KeyboardScroll/index.d.ts +3 -0
  22. package/dist/components/KeyboardScroll/index.js +76 -0
  23. package/dist/components/Modal/index.d.ts +2 -2
  24. package/dist/components/Modal/index.js +31 -3
  25. package/dist/components/Switch/index.d.ts +13 -3
  26. package/dist/components/Switch/index.js +93 -12
  27. package/dist/components/T/index.d.ts +5 -4
  28. package/dist/components/T/index.js +69 -10
  29. package/dist/components/Toast/index.js +123 -3
  30. package/dist/components/VerticalFlatList/index.d.ts +2 -2
  31. package/dist/components/VerticalFlatList/index.js +22 -5
  32. package/dist/components/index.d.ts +29 -29
  33. package/dist/components/index.js +29 -29
  34. package/dist/styles/colors.d.ts +1 -0
  35. package/dist/styles/colors.js +30 -29
  36. package/dist/styles/images.d.ts +2 -0
  37. package/dist/styles/images.js +5 -1
  38. package/package.json +20 -16
  39. package/dist/components/ScrolledContainer/index.d.ts +0 -13
  40. package/dist/components/ScrolledContainer/index.js +0 -30
@@ -1,10 +1,10 @@
1
1
  import React, { useCallback } from "react";
2
- import { View, Text, TouchableOpacity, StyleSheet, Image, Alert } from "react-native";
2
+ import { View, Text, TouchableOpacity, StyleSheet, Image, Alert, } from "react-native";
3
3
  import { BottomSheet, Dividers } from "../index";
4
4
  import { launchCamera, launchImageLibrary } from "react-native-image-picker";
5
5
  import ImageCropPicker from "react-native-image-crop-picker";
6
6
  import { Colors, Images, Scale, Typography } from "../../styles";
7
- const ImagePicker = ({ mediaType, isMultiSelect = false, onSuccess, visible, onClose, }) => {
7
+ const ImagePicker = ({ mediaType, isMultiSelect = false, onSuccess, visible, onClose, containerStyle, rowStyle, textStyle, iconStyle, }) => {
8
8
  const onComplete = useCallback((data) => {
9
9
  onSuccess(data);
10
10
  onClose();
@@ -42,7 +42,11 @@ const ImagePicker = ({ mediaType, isMultiSelect = false, onSuccess, visible, onC
42
42
  const onGallery = () => {
43
43
  if (mediaType === "photo") {
44
44
  if (isMultiSelect) {
45
- ImageCropPicker.openPicker({ mediaType: "photo", multiple: true, maxFiles: 5 })
45
+ ImageCropPicker.openPicker({
46
+ mediaType: "photo",
47
+ multiple: true,
48
+ maxFiles: 5,
49
+ })
46
50
  .then((images) => {
47
51
  if (images.length > 5) {
48
52
  Alert.alert("Limit Exceeded", "You can only select up to 5 images.");
@@ -76,19 +80,19 @@ const ImagePicker = ({ mediaType, isMultiSelect = false, onSuccess, visible, onC
76
80
  });
77
81
  }
78
82
  };
79
- return (React.createElement(BottomSheet, { visible: visible, onClose: onClose, height: 210 },
80
- React.createElement(View, { style: styles.container },
81
- React.createElement(TouchableOpacity, { style: styles.row, onPress: onCamera },
82
- React.createElement(Image, { source: Images.video_icon, style: styles.icon }),
83
- React.createElement(Text, { style: styles.text }, "Camera")),
83
+ return (React.createElement(BottomSheet, { visible: visible, onClose: onClose, height: 230 },
84
+ React.createElement(View, { style: [styles.container, containerStyle] },
85
+ React.createElement(TouchableOpacity, { style: [styles.row, rowStyle], onPress: onCamera },
86
+ React.createElement(Image, { source: Images.video_icon, style: [styles.icon, iconStyle] }),
87
+ React.createElement(Text, { style: [styles.text, textStyle] }, "Camera")),
84
88
  React.createElement(Dividers, { small: true }),
85
- React.createElement(TouchableOpacity, { style: styles.row, onPress: onGallery },
86
- React.createElement(Image, { source: Images.image_icon, style: styles.icon }),
87
- React.createElement(Text, { style: styles.text }, "Gallery")),
89
+ React.createElement(TouchableOpacity, { style: [styles.row, rowStyle], onPress: onGallery },
90
+ React.createElement(Image, { source: Images.image_icon, style: [styles.icon, iconStyle] }),
91
+ React.createElement(Text, { style: [styles.text, textStyle] }, "Gallery")),
88
92
  React.createElement(Dividers, { small: true }),
89
- React.createElement(TouchableOpacity, { style: styles.row, onPress: onClose },
90
- React.createElement(Image, { source: Images.image_icon, style: styles.icon }),
91
- React.createElement(Text, { style: styles.text }, "Cancel")))));
93
+ React.createElement(TouchableOpacity, { style: [styles.row, rowStyle], onPress: onClose },
94
+ React.createElement(Image, { source: Images.cancel, style: [styles.icon, iconStyle] }),
95
+ React.createElement(Text, { style: [styles.text, textStyle] }, "Cancel")))));
92
96
  };
93
97
  export default ImagePicker;
94
98
  const styles = StyleSheet.create({
@@ -96,14 +100,146 @@ const styles = StyleSheet.create({
96
100
  row: {
97
101
  flexDirection: "row",
98
102
  alignItems: "center",
99
- // paddingVertical: 12,
100
103
  },
101
- text: { ...Typography.style.standardU(), color: Colors.black },
102
- separator: { height: 1, backgroundColor: Colors.borderGrey, marginVertical: 8 },
104
+ text: { ...Typography.style.standardU(), color: Colors.white },
103
105
  icon: {
104
106
  width: Scale.moderateScale(20),
105
107
  height: Scale.moderateScale(20),
106
108
  marginRight: 10,
107
- tintColor: Colors.darkBlue,
109
+ tintColor: Colors.white,
108
110
  },
109
111
  });
112
+ // import React, { useCallback } from "react";
113
+ // import { View, Text, TouchableOpacity, StyleSheet, Image, Alert } from "react-native";
114
+ // import { BottomSheet, Dividers } from "../index";
115
+ // import { launchCamera, launchImageLibrary } from "react-native-image-picker";
116
+ // import ImageCropPicker from "react-native-image-crop-picker";
117
+ // import { Colors, Images, Scale, Typography } from "../../styles";
118
+ // type Props = {
119
+ // mediaType: "photo" | "video";
120
+ // isMultiSelect?: boolean;
121
+ // onSuccess: (data: any) => void;
122
+ // visible: boolean;
123
+ // onClose: () => void;
124
+ // };
125
+ // const ImagePicker: React.FC<Props> = ({
126
+ // mediaType,
127
+ // isMultiSelect = false,
128
+ // onSuccess,
129
+ // visible,
130
+ // onClose,
131
+ // }) => {
132
+ // const onComplete = useCallback(
133
+ // (data: any) => {
134
+ // onSuccess(data);
135
+ // onClose();
136
+ // },
137
+ // [onSuccess, onClose]
138
+ // );
139
+ // const onCamera = () => {
140
+ // if (mediaType === "photo") {
141
+ // if (isMultiSelect) {
142
+ // ImageCropPicker.openCamera({ mediaType: "photo" })
143
+ // .then((response) => onComplete([response]))
144
+ // .catch(() => {});
145
+ // } else {
146
+ // ImageCropPicker.openCamera({ mediaType: "photo" })
147
+ // .then((response) =>
148
+ // ImageCropPicker.openCropper({
149
+ // path: response?.path,
150
+ // width: response?.width,
151
+ // height: response?.height,
152
+ // mediaType: "photo",
153
+ // freeStyleCropEnabled: true,
154
+ // }).then(onComplete)
155
+ // )
156
+ // .catch(() => {});
157
+ // }
158
+ // } else {
159
+ // launchCamera({ mediaType: "video" }, (response) => {
160
+ // if (response?.assets) {
161
+ // onComplete({
162
+ // path: response.assets[0]?.uri,
163
+ // duration: response.assets[0]?.duration,
164
+ // });
165
+ // }
166
+ // });
167
+ // }
168
+ // };
169
+ // const onGallery = () => {
170
+ // if (mediaType === "photo") {
171
+ // if (isMultiSelect) {
172
+ // ImageCropPicker.openPicker({ mediaType: "photo", multiple: true, maxFiles: 5 })
173
+ // .then((images) => {
174
+ // if (images.length > 5) {
175
+ // Alert.alert("Limit Exceeded", "You can only select up to 5 images.");
176
+ // } else {
177
+ // onComplete(images);
178
+ // }
179
+ // })
180
+ // .catch(() => {});
181
+ // } else {
182
+ // ImageCropPicker.openPicker({ mediaType: "photo" })
183
+ // .then((response) =>
184
+ // ImageCropPicker.openCropper({
185
+ // path: response?.path,
186
+ // width: response?.width,
187
+ // height: response?.height,
188
+ // mediaType: "photo",
189
+ // freeStyleCropEnabled: true,
190
+ // }).then(onComplete)
191
+ // )
192
+ // .catch(() => {});
193
+ // }
194
+ // } else {
195
+ // launchImageLibrary({ mediaType: "video" }, (result) => {
196
+ // if (result?.assets) {
197
+ // onComplete({
198
+ // path: result.assets[0]?.uri,
199
+ // duration: result.assets[0]?.duration,
200
+ // });
201
+ // }
202
+ // });
203
+ // }
204
+ // };
205
+ // return (
206
+ // <BottomSheet visible={visible} onClose={onClose} height={210}>
207
+ // <View style={styles.container}>
208
+ // {/* Camera */}
209
+ // <TouchableOpacity style={styles.row} onPress={onCamera}>
210
+ // <Image source={Images.video_icon} style={styles.icon} />
211
+ // <Text style={styles.text}>Camera</Text>
212
+ // </TouchableOpacity>
213
+ // <Dividers small/>
214
+ // {/* Gallery */}
215
+ // <TouchableOpacity style={styles.row} onPress={onGallery}>
216
+ // <Image source={Images.image_icon} style={styles.icon} />
217
+ // <Text style={styles.text}>Gallery</Text>
218
+ // </TouchableOpacity>
219
+ // <Dividers small/>
220
+ // {/* Cancel */}
221
+ // <TouchableOpacity style={styles.row} onPress={onClose}>
222
+ // <Image source={Images.image_icon} style={styles.icon} />
223
+ // <Text style={styles.text}>Cancel</Text>
224
+ // </TouchableOpacity>
225
+ // </View>
226
+ // </BottomSheet>
227
+ // );
228
+ // };
229
+ // export default ImagePicker;
230
+ // const styles = StyleSheet.create({
231
+ // container: { flex: 1, padding: 16 },
232
+ // row: {
233
+ // flexDirection: "row",
234
+ // alignItems: "center",
235
+ // // paddingVertical: 12,
236
+ // },
237
+ // text: { ...Typography.style.standardU(), color: Colors.black },
238
+ // separator: { height: 1, backgroundColor: Colors.borderGrey, marginVertical: 8 },
239
+ // icon: {
240
+ // width: Scale.moderateScale(20),
241
+ // height: Scale.moderateScale(20),
242
+ // marginRight: 10,
243
+ // tintColor: Colors.darkBlue,
244
+ // },
245
+ // });
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { TextInputProps, ImageSourcePropType } from "react-native";
2
+ import { TextInputProps, ImageSourcePropType, ReturnKeyTypeOptions } from "react-native";
3
3
  import { InputType } from "../../utils/regex";
4
4
  interface InputProps extends TextInputProps {
5
5
  intlType?: string;
@@ -9,8 +9,7 @@ interface InputProps extends TextInputProps {
9
9
  onLeftIconPress?: () => void;
10
10
  onRightIconPress?: () => void;
11
11
  type?: InputType;
12
- disabled?: boolean;
13
- /** error message from parent (Formik, RHF, Zod, etc.) */
12
+ editable?: boolean;
14
13
  error?: string | boolean;
15
14
  value?: string;
16
15
  customRegex?: RegExp;
@@ -21,6 +20,21 @@ interface InputProps extends TextInputProps {
21
20
  hasError: boolean;
22
21
  message?: string;
23
22
  }) => void;
23
+ containerStyle?: object;
24
+ inputStyle?: object;
25
+ errorTextStyle?: object;
26
+ leftIconStyle?: object;
27
+ rightIconStyle?: object;
28
+ leftIconWrapperStyle?: object;
29
+ rightIconWrapperStyle?: object;
30
+ maxLength?: number;
31
+ placeholder?: string;
32
+ inputPlaceholderTextColor?: string;
33
+ returnKeyType?: ReturnKeyTypeOptions | undefined;
34
+ countryCode?: string;
35
+ onPressCountryCode?: () => void;
36
+ countryCodeWrapperStyle?: object;
37
+ countryCodeTextStyle?: object;
24
38
  }
25
39
  declare const Input: React.FC<InputProps>;
26
40
  export default Input;
@@ -4,17 +4,22 @@ import { useTranslation } from "react-i18next";
4
4
  import { Colors, Typography, Scale, Images } from "../../styles";
5
5
  import { defaultRegex } from "../../utils/regex";
6
6
  import { messages } from "../../constants/messages";
7
- const Input = ({ intlType, textKey, placeholder, leftIcon, rightIcon, onLeftIconPress, onRightIconPress, style, type = "text", disabled = false, error, value = "", customRegex, customErrorMessage, onChangeText, onValidation, onBlur: restOnBlur, onFocus: restOnFocus, ...rest }) => {
7
+ const Input = ({ intlType, textKey, placeholder, inputPlaceholderTextColor, leftIcon, rightIcon, onLeftIconPress, onRightIconPress, style, containerStyle, inputStyle, errorTextStyle, leftIconStyle, rightIconStyle, leftIconWrapperStyle, rightIconWrapperStyle, type = "text", editable = true, error, value = "", customRegex, customErrorMessage, onChangeText, onValidation, onBlur: restOnBlur, onFocus: restOnFocus, multiline = false, maxLength, returnKeyType, countryCode, onPressCountryCode, countryCodeTextStyle, countryCodeWrapperStyle, ...rest }) => {
8
8
  const { t } = useTranslation();
9
9
  const [secureText, setSecureText] = useState(type === "password");
10
10
  const [internalError, setInternalError] = useState(null);
11
11
  const [wasBlurred, setWasBlurred] = useState(false);
12
12
  const [isFocused, setIsFocused] = useState(false);
13
- const translatedPlaceholder = intlType && textKey ? String(t(textKey, { ns: intlType, value })) : placeholder;
14
- const keyboardType = type === "email" ? "email-address" : type === "number" ? "numeric" : "default";
15
- // internal validator (non-Formik, non-RHF)
13
+ const translatedPlaceholder = intlType && textKey
14
+ ? String(t(textKey, { ns: intlType, value }))
15
+ : placeholder;
16
+ const keyboardType = type === "email"
17
+ ? "email-address"
18
+ : type === "number"
19
+ ? "numeric"
20
+ : "default";
16
21
  const validateInternal = useCallback((text) => {
17
- if (!wasBlurred)
22
+ if (!wasBlurred || !editable)
18
23
  return;
19
24
  const regexToUse = customRegex ?? defaultRegex[type];
20
25
  const fallbackMsg = messages.invalid[type] || "Invalid input";
@@ -27,7 +32,7 @@ const Input = ({ intlType, textKey, placeholder, leftIcon, rightIcon, onLeftIcon
27
32
  setInternalError(null);
28
33
  onValidation?.({ type, hasError: false });
29
34
  }
30
- }, [wasBlurred, type, customRegex, customErrorMessage, onValidation]);
35
+ }, [wasBlurred, editable, type, customRegex, customErrorMessage, onValidation]);
31
36
  useEffect(() => {
32
37
  if (!customRegex)
33
38
  return;
@@ -49,31 +54,50 @@ const Input = ({ intlType, textKey, placeholder, leftIcon, rightIcon, onLeftIcon
49
54
  setIsFocused(false);
50
55
  if (!wasBlurred)
51
56
  setWasBlurred(true);
52
- validateInternal(value || "");
57
+ if (editable)
58
+ validateInternal(value || "");
53
59
  restOnBlur?.(e);
54
60
  };
55
- // Decide which error to show: external error (Formik/RHF/etc) > internal error
56
61
  const rawError = (typeof error === "string" ? error : undefined) ?? internalError ?? null;
62
+ // const showError = (() => {
63
+ // if (!rawError || !editable) return null;
64
+ // return wasBlurred && !isFocused ? rawError : null;
65
+ // })();
57
66
  const showError = (() => {
58
- if (!rawError)
67
+ if (!rawError || !editable)
59
68
  return null;
69
+ // If error comes from parent, show it directly
70
+ if (typeof error === "string" && error.length > 0) {
71
+ return rawError;
72
+ }
60
73
  return wasBlurred && !isFocused ? rawError : null;
61
74
  })();
62
- return (React.createElement(View, { style: { marginBottom: 10 } },
75
+ return (React.createElement(View, null,
63
76
  React.createElement(View, { style: [
64
77
  styles.container,
65
- disabled && styles.disabled,
78
+ !editable && styles.disabled,
66
79
  !!showError && styles.errorBorder,
67
80
  isFocused && styles.focusedBorder,
68
81
  style,
82
+ containerStyle,
83
+ multiline && styles.multilineContainer,
69
84
  ] },
70
- leftIcon && (React.createElement(TouchableOpacity, { onPress: onLeftIconPress, disabled: !onLeftIconPress, style: styles.iconWrapper },
71
- React.createElement(Image, { source: leftIcon, style: styles.icon, resizeMode: "contain" }))),
72
- React.createElement(TextInput, { style: [styles.input, disabled && styles.disabledText], placeholder: translatedPlaceholder, placeholderTextColor: Colors.textGrey, editable: !disabled, secureTextEntry: secureText, keyboardType: keyboardType, value: value, onChangeText: handleChangeText, onFocus: handleFocus, onBlur: handleBlur, ...rest }),
73
- type === "password" ? (React.createElement(TouchableOpacity, { onPress: () => setSecureText(!secureText), style: styles.iconWrapper },
74
- React.createElement(Image, { source: secureText ? Images.Eyeoff : Images.Eyeon, style: styles.icon, resizeMode: "contain" }))) : (rightIcon && (React.createElement(TouchableOpacity, { onPress: onRightIconPress, disabled: !onRightIconPress, style: styles.iconWrapper },
75
- React.createElement(Image, { source: rightIcon, style: styles.icon, resizeMode: "contain" }))))),
76
- showError && React.createElement(Text, { style: styles.errorText }, showError)));
85
+ leftIcon && (React.createElement(TouchableOpacity, { onPress: onLeftIconPress, disabled: !onLeftIconPress, style: [styles.iconWrapper, leftIconWrapperStyle] },
86
+ React.createElement(Image, { source: leftIcon, style: [styles.icon, leftIconStyle], resizeMode: "contain" }))),
87
+ countryCode && (React.createElement(TouchableOpacity, { onPress: onPressCountryCode, disabled: !onPressCountryCode, style: [styles.countryCodeWrapper, countryCodeWrapperStyle] },
88
+ React.createElement(Text, { style: [styles.countryCodeText, countryCodeTextStyle] }, countryCode))),
89
+ React.createElement(TextInput, { style: [
90
+ styles.input,
91
+ !editable && styles.disabledText,
92
+ multiline && styles.multilineInput,
93
+ inputStyle,
94
+ ], placeholder: translatedPlaceholder, placeholderTextColor: inputPlaceholderTextColor
95
+ ? inputPlaceholderTextColor
96
+ : Colors.textGrey, editable: editable, secureTextEntry: secureText, keyboardType: keyboardType, value: value, onChangeText: handleChangeText, onFocus: handleFocus, onBlur: handleBlur, multiline: multiline, maxLength: maxLength, returnKeyType: returnKeyType, ...rest }),
97
+ type === "password" ? (React.createElement(TouchableOpacity, { onPress: () => setSecureText(!secureText), style: [styles.iconWrapper, rightIconWrapperStyle] },
98
+ React.createElement(Image, { source: secureText ? Images.Eyeon : Images.Eyeoff, style: [styles.icon, rightIconStyle], resizeMode: "contain" }))) : (rightIcon && (React.createElement(TouchableOpacity, { onPress: onRightIconPress, disabled: !onRightIconPress, style: [styles.iconWrapper, rightIconWrapperStyle] },
99
+ React.createElement(Image, { source: rightIcon, style: [styles.icon, rightIconStyle], resizeMode: "contain" }))))),
100
+ showError && (React.createElement(Text, { style: [styles.errorText, errorTextStyle] }, showError))));
77
101
  };
78
102
  export default Input;
79
103
  const styles = StyleSheet.create({
@@ -85,7 +109,13 @@ const styles = StyleSheet.create({
85
109
  borderColor: Colors.primaryColor,
86
110
  backgroundColor: Colors.white,
87
111
  height: Scale.moderateScale(50),
88
- paddingHorizontal: Scale.moderateScale(10),
112
+ paddingHorizontal: Scale.moderateScale(4),
113
+ },
114
+ multilineContainer: {
115
+ height: "auto",
116
+ minHeight: Scale.moderateScale(80),
117
+ alignItems: "flex-start",
118
+ paddingVertical: Scale.moderateScale(8),
89
119
  },
90
120
  focusedBorder: {
91
121
  borderColor: Colors.primaryColor,
@@ -96,6 +126,10 @@ const styles = StyleSheet.create({
96
126
  textTransform: "none",
97
127
  color: Colors.textColor,
98
128
  },
129
+ multilineInput: {
130
+ textAlignVertical: "top",
131
+ paddingTop: Scale.moderateScale(5),
132
+ },
99
133
  iconWrapper: {
100
134
  padding: Scale.moderateScale(5),
101
135
  },
@@ -119,4 +153,253 @@ const styles = StyleSheet.create({
119
153
  fontSize: Scale.moderateScale(12),
120
154
  marginTop: 3,
121
155
  },
156
+ countryCodeWrapper: {
157
+ paddingHorizontal: Scale.moderateScale(6),
158
+ justifyContent: "center",
159
+ alignItems: "center",
160
+ borderRightWidth: 1,
161
+ borderRightColor: Colors.borderGrey,
162
+ marginRight: Scale.moderateScale(6),
163
+ },
164
+ countryCodeText: {
165
+ ...Typography.style.standardU(),
166
+ fontSize: Scale.moderateScale(14),
167
+ color: Colors.textColor,
168
+ },
122
169
  });
170
+ // import React, { useState, useCallback, useEffect } from "react";
171
+ // import {
172
+ // View,
173
+ // TextInput,
174
+ // TextInputProps,
175
+ // StyleSheet,
176
+ // Image,
177
+ // ImageSourcePropType,
178
+ // TouchableOpacity,
179
+ // Text,
180
+ // NativeSyntheticEvent,
181
+ // TextInputFocusEventData,
182
+ // } from "react-native";
183
+ // import { useTranslation } from "react-i18next";
184
+ // import { Colors, Typography, Scale, Images } from "../../styles";
185
+ // import { defaultRegex, InputType } from "../../utils/regex";
186
+ // import { messages } from "../../constants/messages";
187
+ // interface InputProps extends TextInputProps {
188
+ // intlType?: string;
189
+ // textKey?: string;
190
+ // leftIcon?: ImageSourcePropType;
191
+ // rightIcon?: ImageSourcePropType;
192
+ // onLeftIconPress?: () => void;
193
+ // onRightIconPress?: () => void;
194
+ // type?: InputType;
195
+ // editable?: boolean;
196
+ // error?: string | boolean;
197
+ // value?: string;
198
+ // customRegex?: RegExp;
199
+ // customErrorMessage?: string;
200
+ // onChangeText?: (text: string) => void;
201
+ // onValidation?: (errorObj: { type: InputType; hasError: boolean; message?: string }) => void;
202
+ // containerStyle?: object;
203
+ // inputStyle?: object;
204
+ // errorTextStyle?: object;
205
+ // leftIconStyle?: object;
206
+ // rightIconStyle?: object;
207
+ // }
208
+ // const Input: React.FC<InputProps> = ({
209
+ // intlType,
210
+ // textKey,
211
+ // placeholder,
212
+ // leftIcon,
213
+ // rightIcon,
214
+ // onLeftIconPress,
215
+ // onRightIconPress,
216
+ // style,
217
+ // containerStyle,
218
+ // inputStyle,
219
+ // errorTextStyle,
220
+ // leftIconStyle,
221
+ // rightIconStyle,
222
+ // type = "text",
223
+ // editable = true,
224
+ // error,
225
+ // value = "",
226
+ // customRegex,
227
+ // customErrorMessage,
228
+ // onChangeText,
229
+ // onValidation,
230
+ // onBlur: restOnBlur,
231
+ // onFocus: restOnFocus,
232
+ // multiline = false,
233
+ // ...rest
234
+ // }) => {
235
+ // const { t } = useTranslation();
236
+ // const [secureText, setSecureText] = useState(type === "password");
237
+ // const [internalError, setInternalError] = useState<string | null>(null);
238
+ // const [wasBlurred, setWasBlurred] = useState(false);
239
+ // const [isFocused, setIsFocused] = useState(false);
240
+ // const translatedPlaceholder =
241
+ // intlType && textKey ? String(t(textKey, { ns: intlType, value })) : placeholder;
242
+ // const keyboardType: TextInputProps["keyboardType"] =
243
+ // type === "email" ? "email-address" : type === "number" ? "numeric" : "default";
244
+ // const validateInternal = useCallback(
245
+ // (text: string) => {
246
+ // if (!wasBlurred || !editable) return;
247
+ // const regexToUse = customRegex ?? defaultRegex[type];
248
+ // const fallbackMsg = messages.invalid[type] || "Invalid input";
249
+ // const msg = customErrorMessage || fallbackMsg;
250
+ // if (text === "" || !regexToUse.test(text)) {
251
+ // setInternalError(msg);
252
+ // onValidation?.({ type, hasError: true, message: msg });
253
+ // } else {
254
+ // setInternalError(null);
255
+ // onValidation?.({ type, hasError: false });
256
+ // }
257
+ // },
258
+ // [wasBlurred, editable, type, customRegex, customErrorMessage, onValidation]
259
+ // );
260
+ // useEffect(() => {
261
+ // if (!customRegex) return;
262
+ // if (internalError && value && customRegex.test(value)) {
263
+ // setInternalError(null);
264
+ // onValidation?.({ type, hasError: false });
265
+ // }
266
+ // }, [value]);
267
+ // const handleChangeText = (text: string) => {
268
+ // onChangeText?.(text);
269
+ // if (wasBlurred) validateInternal(text);
270
+ // };
271
+ // const handleFocus = (e?: NativeSyntheticEvent<TextInputFocusEventData>) => {
272
+ // setIsFocused(true);
273
+ // restOnFocus?.(e as any);
274
+ // };
275
+ // const handleBlur = (e?: NativeSyntheticEvent<TextInputFocusEventData>) => {
276
+ // setIsFocused(false);
277
+ // if (!wasBlurred) setWasBlurred(true);
278
+ // if (editable) validateInternal(value || "");
279
+ // restOnBlur?.(e as any);
280
+ // };
281
+ // const rawError = (typeof error === "string" ? error : undefined) ?? internalError ?? null;
282
+ // const showError = (() => {
283
+ // if (!rawError || !editable) return null;
284
+ // return wasBlurred && !isFocused ? rawError : null;
285
+ // })();
286
+ // return (
287
+ // <View style={{ marginBottom: 10 }}>
288
+ // <View
289
+ // style={[
290
+ // styles.container,
291
+ // !editable && styles.disabled,
292
+ // !!showError && styles.errorBorder,
293
+ // isFocused && styles.focusedBorder,
294
+ // style,
295
+ // containerStyle,
296
+ // multiline && styles.multilineContainer,
297
+ // ]}
298
+ // >
299
+ // {leftIcon && (
300
+ // <TouchableOpacity
301
+ // onPress={onLeftIconPress}
302
+ // disabled={!onLeftIconPress}
303
+ // style={styles.iconWrapper}
304
+ // >
305
+ // <Image source={leftIcon} style={[styles.icon, leftIconStyle]} resizeMode="contain" />
306
+ // </TouchableOpacity>
307
+ // )}
308
+ // <TextInput
309
+ // style={[
310
+ // styles.input,
311
+ // !editable && styles.disabledText,
312
+ // multiline && styles.multilineInput,
313
+ // inputStyle,
314
+ // ]}
315
+ // placeholder={translatedPlaceholder}
316
+ // placeholderTextColor={Colors.textGrey}
317
+ // editable={editable}
318
+ // secureTextEntry={secureText}
319
+ // keyboardType={keyboardType}
320
+ // value={value}
321
+ // onChangeText={handleChangeText}
322
+ // onFocus={handleFocus}
323
+ // onBlur={handleBlur}
324
+ // multiline={multiline}
325
+ // {...rest}
326
+ // />
327
+ // {type === "password" ? (
328
+ // <TouchableOpacity onPress={() => setSecureText(!secureText)} style={styles.iconWrapper}>
329
+ // <Image
330
+ // source={secureText ? Images.Eyeoff : Images.Eyeon}
331
+ // style={[styles.icon, rightIconStyle]}
332
+ // resizeMode="contain"
333
+ // />
334
+ // </TouchableOpacity>
335
+ // ) : (
336
+ // rightIcon && (
337
+ // <TouchableOpacity
338
+ // onPress={onRightIconPress}
339
+ // disabled={!onRightIconPress}
340
+ // style={styles.iconWrapper}
341
+ // >
342
+ // <Image source={rightIcon} style={[styles.icon, rightIconStyle]} resizeMode="contain" />
343
+ // </TouchableOpacity>
344
+ // )
345
+ // )}
346
+ // </View>
347
+ // {showError && <Text style={[styles.errorText, errorTextStyle]}>{showError}</Text>}
348
+ // </View>
349
+ // );
350
+ // };
351
+ // export default Input;
352
+ // const styles = StyleSheet.create({
353
+ // container: {
354
+ // flexDirection: "row",
355
+ // alignItems: "center",
356
+ // borderRadius: 5,
357
+ // borderWidth: 1,
358
+ // borderColor: Colors.primaryColor,
359
+ // backgroundColor: Colors.white,
360
+ // height: Scale.moderateScale(50),
361
+ // paddingHorizontal: Scale.moderateScale(4),
362
+ // },
363
+ // multilineContainer: {
364
+ // height: "auto",
365
+ // minHeight: Scale.moderateScale(80),
366
+ // alignItems: "flex-start",
367
+ // paddingVertical: Scale.moderateScale(8),
368
+ // },
369
+ // focusedBorder: {
370
+ // borderColor: Colors.primaryColor,
371
+ // },
372
+ // input: {
373
+ // flex: 1,
374
+ // ...Typography.style.standardU(),
375
+ // textTransform: "none",
376
+ // color: Colors.textColor,
377
+ // },
378
+ // multilineInput: {
379
+ // textAlignVertical: "top",
380
+ // paddingTop: Scale.moderateScale(5),
381
+ // },
382
+ // iconWrapper: {
383
+ // padding: Scale.moderateScale(5),
384
+ // },
385
+ // icon: {
386
+ // width: Scale.moderateScale(20),
387
+ // height: Scale.moderateScale(20),
388
+ // tintColor: Colors.primaryColor,
389
+ // },
390
+ // disabled: {
391
+ // backgroundColor: Colors.lightGrey,
392
+ // borderColor: Colors.borderGrey,
393
+ // },
394
+ // disabledText: {
395
+ // color: Colors.disabledGrey,
396
+ // },
397
+ // errorBorder: {
398
+ // borderColor: Colors.dangerRed,
399
+ // },
400
+ // errorText: {
401
+ // color: Colors.dangerRed,
402
+ // fontSize: Scale.moderateScale(12),
403
+ // marginTop: 3,
404
+ // },
405
+ // });
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ declare const KeyboardScroll: (props: any) => React.JSX.Element;
3
+ export default KeyboardScroll;