@teamnhz/rn-ui-toolkit 1.0.2 → 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 (39) hide show
  1. package/dist/assets/images/ic_calendar.png +0 -0
  2. package/dist/assets/images/ic_time.png +0 -0
  3. package/dist/components/BottomSheet/index.js +58 -2
  4. package/dist/components/Buttons/index.d.ts +2 -2
  5. package/dist/components/Buttons/index.js +102 -11
  6. package/dist/components/CheckBox/index.d.ts +2 -2
  7. package/dist/components/CheckBox/index.js +112 -15
  8. package/dist/components/DateTimePicker/index.d.ts +20 -4
  9. package/dist/components/DateTimePicker/index.js +246 -20
  10. package/dist/components/Dividers/index.d.ts +3 -3
  11. package/dist/components/Dividers/index.js +41 -5
  12. package/dist/components/HorizontalFlatList/index.d.ts +2 -2
  13. package/dist/components/HorizontalFlatList/index.js +47 -8
  14. package/dist/components/Image/index.d.ts +2 -4
  15. package/dist/components/Image/index.js +22 -4
  16. package/dist/components/ImagePicker/index.d.ts +8 -1
  17. package/dist/components/ImagePicker/index.js +154 -18
  18. package/dist/components/Input/index.d.ts +12 -4
  19. package/dist/components/Input/index.js +288 -22
  20. package/dist/components/KeyboardScroll/index.d.ts +3 -0
  21. package/dist/components/KeyboardScroll/index.js +76 -0
  22. package/dist/components/Modal/index.d.ts +2 -2
  23. package/dist/components/Modal/index.js +31 -3
  24. package/dist/components/Switch/index.d.ts +13 -3
  25. package/dist/components/Switch/index.js +93 -12
  26. package/dist/components/T/index.d.ts +5 -4
  27. package/dist/components/T/index.js +69 -10
  28. package/dist/components/Toast/index.js +123 -3
  29. package/dist/components/VerticalFlatList/index.d.ts +2 -2
  30. package/dist/components/VerticalFlatList/index.js +22 -5
  31. package/dist/components/index.d.ts +29 -29
  32. package/dist/components/index.js +29 -29
  33. package/dist/styles/colors.d.ts +1 -0
  34. package/dist/styles/colors.js +30 -29
  35. package/dist/styles/images.d.ts +2 -0
  36. package/dist/styles/images.js +5 -1
  37. package/package.json +20 -16
  38. package/dist/components/ScrolledContainer/index.d.ts +0 -13
  39. 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,12 +20,21 @@ interface InputProps extends TextInputProps {
21
20
  hasError: boolean;
22
21
  message?: string;
23
22
  }) => void;
24
- /** 🔥 custom styles from parent */
25
23
  containerStyle?: object;
26
24
  inputStyle?: object;
27
25
  errorTextStyle?: object;
28
26
  leftIconStyle?: object;
29
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;
30
38
  }
31
39
  declare const Input: React.FC<InputProps>;
32
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, containerStyle, inputStyle, errorTextStyle, leftIconStyle, rightIconStyle, type = "text", disabled = false, error, value = "", customRegex, customErrorMessage, onChangeText, onValidation, onBlur: restOnBlur, onFocus: restOnFocus, multiline = false, ...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,36 +54,48 @@ 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
- style, // legacy style (container)
69
- containerStyle, // 🔥 custom container style
70
- multiline && styles.multilineContainer, // adjust container for multiline
81
+ style,
82
+ containerStyle,
83
+ multiline && styles.multilineContainer,
71
84
  ] },
72
- leftIcon && (React.createElement(TouchableOpacity, { onPress: onLeftIconPress, disabled: !onLeftIconPress, style: styles.iconWrapper },
85
+ leftIcon && (React.createElement(TouchableOpacity, { onPress: onLeftIconPress, disabled: !onLeftIconPress, style: [styles.iconWrapper, leftIconWrapperStyle] },
73
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))),
74
89
  React.createElement(TextInput, { style: [
75
90
  styles.input,
76
- disabled && styles.disabledText,
77
- multiline && styles.multilineInput, // adjust text for multiline
78
- inputStyle, // 🔥 parent custom input style
79
- ], placeholder: translatedPlaceholder, placeholderTextColor: Colors.textGrey, editable: !disabled, secureTextEntry: secureText, keyboardType: keyboardType, value: value, onChangeText: handleChangeText, onFocus: handleFocus, onBlur: handleBlur, multiline: multiline, ...rest }),
80
- type === "password" ? (React.createElement(TouchableOpacity, { onPress: () => setSecureText(!secureText), style: styles.iconWrapper },
81
- React.createElement(Image, { source: secureText ? Images.Eyeoff : Images.Eyeon, style: [styles.icon, rightIconStyle], resizeMode: "contain" }))) : (rightIcon && (React.createElement(TouchableOpacity, { onPress: onRightIconPress, disabled: !onRightIconPress, style: styles.iconWrapper },
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] },
82
99
  React.createElement(Image, { source: rightIcon, style: [styles.icon, rightIconStyle], resizeMode: "contain" }))))),
83
100
  showError && (React.createElement(Text, { style: [styles.errorText, errorTextStyle] }, showError))));
84
101
  };
@@ -92,7 +109,7 @@ const styles = StyleSheet.create({
92
109
  borderColor: Colors.primaryColor,
93
110
  backgroundColor: Colors.white,
94
111
  height: Scale.moderateScale(50),
95
- paddingHorizontal: Scale.moderateScale(10),
112
+ paddingHorizontal: Scale.moderateScale(4),
96
113
  },
97
114
  multilineContainer: {
98
115
  height: "auto",
@@ -136,4 +153,253 @@ const styles = StyleSheet.create({
136
153
  fontSize: Scale.moderateScale(12),
137
154
  marginTop: 3,
138
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
+ },
139
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;