react-native-international-phone-number 0.4.12 → 0.4.14

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/README.md CHANGED
@@ -47,9 +47,12 @@
47
47
  - [With Class Component](#class-component)
48
48
  - [With Function Component](#function-component)
49
49
  - [Custom Default Flag](#custom-default-flag)
50
- - [Basic Usage - Typescript](#basic-usage---typescript)
51
- - [Intermediate Usage - Typescrypt + Default Phone Number Value](#intermediate-usage---typescript--default-phone-number-value)
52
- - [Advanced Usage - React Hook Form + Typescript + Default Phone Number Value](#advanced-usage---react-hook-form--typescript--default-phone-number-value)
50
+ - [Default Phone Number Value](#default-phone-number-value)
51
+ - [Typescript](#typescript)
52
+ - [Intermediate Usage](#intermediate-usage)
53
+ - [Typescript + useRef](#typescript--useref)
54
+ - [Advanced Usage](#advanced-usage)
55
+ - [React-Hook-Form + Typescript + Default Phone Number Value](#react-hook-form--typescript--default-phone-number-value)
53
56
  - [Customizing Lib](#customizing-lib)
54
57
  - [Dark Mode](#dark-mode)
55
58
  - [Custom Lib Styles](#custom-lib-styles)
@@ -242,35 +245,29 @@ export default function App() {
242
245
  }
243
246
  ```
244
247
 
245
- <br>
246
-
247
- ## Basic Usage - Typescript
248
+ - ### Default Phone Number Value
248
249
 
249
250
  ```tsx
250
251
  import React, { useState } from 'react';
251
252
  import { View, Text } from 'react-native';
252
- import {
253
- PhoneInput,
254
- ICountry,
255
- } from 'react-native-international-phone-number';
253
+ import { PhoneInput } from 'react-native-international-phone-number';
256
254
 
257
255
  export default function App() {
258
- const [selectedCountry, setSelectedCountry] = useState<
259
- undefined | ICountry
260
- >(undefined);
261
- const [inputValue, setInputValue] = useState<string>('');
256
+ const [selectedCountry, setSelectedCountry] = useState(undefined);
257
+ const [inputValue, setInputValue] = useState('');
262
258
 
263
- function handleInputValue(phoneNumber: string) {
259
+ function handleInputValue(phoneNumber) {
264
260
  setInputValue(phoneNumber);
265
261
  }
266
262
 
267
- function handleSelectedCountry(country: ICountry) {
263
+ function handleSelectedCountry(country) {
268
264
  setSelectedCountry(country);
269
265
  }
270
266
 
271
267
  return (
272
268
  <View style={{ width: '100%', flex: 1, padding: 24 }}>
273
269
  <PhoneInput
270
+ defaultValue="+12505550199"
274
271
  value={inputValue}
275
272
  onChangePhoneNumber={handleInputValue}
276
273
  selectedCountry={selectedCountry}
@@ -291,9 +288,12 @@ export default function App() {
291
288
  }
292
289
  ```
293
290
 
294
- <br>
291
+ > Observations:
292
+ >
293
+ > 1. You need to use a default value with the following format: `+(country callling code)(area code)(number phone)`
294
+ > 2. The lib has the mechanism to set the flag and mask of the supplied `defaultValue`. However, if the supplied `defaultValue` does not match any international standard, the `input mask of the defaultValue` will be set to "BR" (please make sure that the default value is in the format mentioned above).
295
295
 
296
- ## Intermediate Usage - Typescript + Default Phone Number Value
296
+ - ### Typescript
297
297
 
298
298
  ```tsx
299
299
  import React, { useState } from 'react';
@@ -320,7 +320,6 @@ export default function App() {
320
320
  return (
321
321
  <View style={{ width: '100%', flex: 1, padding: 24 }}>
322
322
  <PhoneInput
323
- defaultValue="+12505550199"
324
323
  value={inputValue}
325
324
  onChangePhoneNumber={handleInputValue}
326
325
  selectedCountry={selectedCountry}
@@ -341,14 +340,65 @@ export default function App() {
341
340
  }
342
341
  ```
343
342
 
344
- > Observations:
345
- >
346
- > 1. You need to use a default value with the following format: `+(country callling code)(area code)(number phone)`
347
- > 2. The lib has the mechanism to set the flag and mask of the supplied `defaultValue`. However, if the supplied `defaultValue` does not match any international standard, the `input mask of the defaultValue` will be set to "BR" (please make sure that the default value is in the format mentioned above).
348
-
349
343
  <br>
350
344
 
351
- ## Advanced Usage - React-Hook-Form + Typescript + Default Phone Number Value
345
+ ## Intermediate Usage
346
+
347
+ - ### Typescript + useRef
348
+
349
+ ```tsx
350
+ import React, { useState, useRef } from 'react';
351
+ import { View, Text } from 'react-native';
352
+ import {
353
+ PhoneInput,
354
+ ICountry,
355
+ IPhoneInputRef,
356
+ } from 'react-native-international-phone-number';
357
+
358
+ export default function App() {
359
+ const phoneInputRef = useRef<IPhoneInputRef>(null);
360
+
361
+ function onSubmitRef() {
362
+ Alert.alert(
363
+ 'Intermediate Result',
364
+ `${phoneInputRef.current?.selectedCountry?.callingCode} ${phoneInputRef.current?.value}`
365
+ );
366
+ }
367
+
368
+ return (
369
+ <View style={{ width: '100%', flex: 1, padding: 24 }}>
370
+ <PhoneInput ref={phoneInputRef} />
371
+ <TouchableOpacity
372
+ style={{
373
+ width: '100%',
374
+ paddingVertical: 12,
375
+ backgroundColor: '#2196F3',
376
+ borderRadius: 4,
377
+ marginTop: 10,
378
+ }}
379
+ onPress={onSubmit}
380
+ >
381
+ <Text
382
+ style={{
383
+ color: '#F3F3F3',
384
+ textAlign: 'center',
385
+ fontSize: 16,
386
+ fontWeight: 'bold',
387
+ }}
388
+ >
389
+ Submit
390
+ </Text>
391
+ </TouchableOpacity>
392
+ </View>
393
+ );
394
+ }
395
+ ```
396
+
397
+ > Observation: Don't use the useRef hook combined with the useState hook to manage the phoneNumber and selectedCountry values. Instead, choose to use just one of them (useRef or useState).
398
+
399
+ ## Advanced Usage
400
+
401
+ - ### React-Hook-Form + Typescript + Default Phone Number Value
352
402
 
353
403
  ```tsx
354
404
  import React, { useState, useEffect } from 'react';
@@ -357,7 +407,7 @@ import {
357
407
  PhoneInput,
358
408
  ICountry,
359
409
  } from 'react-native-international-phone-number';
360
- import { Controller, FieldValues, useForm } from 'react-hook-form';
410
+ import { Controller, FieldValues } from 'react-hook-form';
361
411
 
362
412
  interface FormProps extends FieldValues {
363
413
  phoneNumber: string;
@@ -368,9 +418,6 @@ export default function App() {
368
418
  undefined | ICountry
369
419
  >(undefined);
370
420
 
371
- const { control, handleSubmit, setValue, watch } =
372
- useForm<FormProps>();
373
-
374
421
  function handleSelectedCountry(country: ICountry) {
375
422
  setSelectedCountry(country);
376
423
  }
@@ -382,12 +429,6 @@ export default function App() {
382
429
  );
383
430
  }
384
431
 
385
- useEffect(() => {
386
- const watchPhoneNumber = watch('phoneNumber');
387
-
388
- setValue('phoneNumber', watchPhoneNumber);
389
- }, []);
390
-
391
432
  return (
392
433
  <View style={{ width: '100%', flex: 1, padding: 24 }}>
393
434
  <Controller
@@ -511,16 +552,17 @@ export default function App() {
511
552
  ## Component Props ([PhoneInputProps](https://github.com/AstrOOnauta/react-native-international-phone-number/blob/master/lib/interfaces/phoneInputProps.ts))
512
553
 
513
554
  - `defaultValue?:` string;
514
- - `value:` string;
515
- - `onChangePhoneNumber:` (phoneNumber: string) => void;
516
- - `selectedCountry:` undefined | [ICountry](https://github.com/AstrOOnauta/react-native-international-phone-number/blob/master/lib/interfaces/country.ts);
517
- - `onChangeSelectedCountry:` (country: [ICountry](https://github.com/AstrOOnauta/react-native-international-phone-number/blob/master/lib/interfaces/country.ts)) => void;
555
+ - `value?:` string;
556
+ - `onChangePhoneNumber?:` (phoneNumber: string) => void;
557
+ - `selectedCountry?:` undefined | [ICountry](https://github.com/AstrOOnauta/react-native-international-phone-number/blob/master/lib/interfaces/country.ts);
558
+ - `onChangeSelectedCountry?:` (country: [ICountry](https://github.com/AstrOOnauta/react-native-international-phone-number/blob/master/lib/interfaces/country.ts)) => void;
518
559
  - `disabled?:` boolean;
519
560
  - `modalDisabled?:` boolean;
520
561
  - `withDarkTheme?:` boolean;
521
562
  - `containerStyle?:` StyleProp<[ViewStyle](https://reactnative.dev/docs/view-style-props)>;
522
563
  - `flagContainerStyle?:` StyleProp<[ViewStyle](https://reactnative.dev/docs/view-style-props)>;
523
564
  - `inputStyle?:` StyleProp<[TextStyle](https://reactnative.dev/docs/text-style-props)>;
565
+ - `ref?:` [Ref](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/663f439d11d78b65f1dfd38d120f3728ea2cc207/types/react/index.d.ts#L100)<[IPhoneInputRef](https://github.com/AstrOOnauta/react-native-international-phone-number/blob/master/lib/interfaces/phoneInputRef.ts)>
524
566
 
525
567
  <br>
526
568
 
package/lib/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ICountry } from './interfaces/country';
2
+ import { IPhoneInputRef } from './interfaces/phoneInputRef';
2
3
  import { PhoneInputProps } from './interfaces/phoneInputProps';
3
4
 
4
5
  declare function PhoneInput(props: PhoneInputProps): JSX.Element;
@@ -29,5 +30,6 @@ export {
29
30
  getCountriesByCallingCode,
30
31
  getCountriesByName,
31
32
  ICountry,
33
+ IPhoneInputRef,
32
34
  PhoneInputProps,
33
35
  };
package/lib/index.js CHANGED
@@ -1,4 +1,9 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React, {
2
+ useEffect,
3
+ useState,
4
+ useRef,
5
+ forwardRef,
6
+ } from 'react';
2
7
  import {
3
8
  StyleSheet,
4
9
  Dimensions,
@@ -17,196 +22,316 @@ import getCountryByCca2 from './utils/getCountryByCca2';
17
22
  import getCountryByPhoneNumber from './utils/getCountryByPhoneNumber';
18
23
  import phoneMask from './utils/inputMask';
19
24
 
20
- function PhoneInput({
21
- placeholder,
22
- placeholderTextColor,
23
- selectionColor,
24
- containerStyle,
25
- flagContainerStyle,
26
- inputStyle,
27
- withDarkTheme,
28
- disabled,
29
- modalDisabled,
30
- defaultValue,
31
- onChangePhoneNumber,
32
- selectedCountry,
33
- onChangeSelectedCountry,
34
- ...rest
35
- }) {
36
- const [containerWidth, setContainerWidth] = useState(
37
- Dimensions.get('window').width
38
- );
39
- const [defaultCca2, setDefaultCca2] = useState('');
40
-
41
- function onSelect(country) {
42
- onChangePhoneNumber('');
43
- if (onChangeSelectedCountry) {
44
- onChangeSelectedCountry({
45
- name: country.name,
46
- cca2: country.cca2,
47
- flag: country.flag,
48
- callingCode: `+${country.callingCode[0]}`,
49
- });
50
- }
51
- }
52
-
53
- function onChangeText(phoneNumber, callingCode) {
54
- const res = phoneMask(
55
- phoneNumber,
56
- callingCode ? callingCode : selectedCountry?.callingCode,
57
- selectedCountry?.cca2
25
+ const PhoneInput = forwardRef(
26
+ (
27
+ {
28
+ placeholder,
29
+ placeholderTextColor,
30
+ selectionColor,
31
+ containerStyle,
32
+ flagContainerStyle,
33
+ inputStyle,
34
+ withDarkTheme,
35
+ disabled,
36
+ modalDisabled,
37
+ defaultValue,
38
+ onChangePhoneNumber,
39
+ selectedCountry,
40
+ onChangeSelectedCountry,
41
+ ...rest
42
+ },
43
+ ref
44
+ ) => {
45
+ const [containerWidth, setContainerWidth] = useState(
46
+ Dimensions.get('window').width
58
47
  );
48
+ const [defaultCca2, setDefaultCca2] = useState('');
49
+ const [inputValue, setInputValue] = useState(null);
50
+ const [countryValue, setCountryValue] = useState(null);
59
51
 
60
- onChangePhoneNumber(res);
61
- }
52
+ const textInputRef = useRef(null);
62
53
 
63
- useEffect(() => {
64
- onChangePhoneNumber('');
65
- if (defaultValue) {
66
- const matchingCountry = getCountryByPhoneNumber(defaultValue);
54
+ const refBase = {
55
+ ...textInputRef.current,
56
+ onFocus: textInputRef.current?.focus,
57
+ focus: textInputRef.current?.focus,
58
+ getValue: () => inputValue,
59
+ value: inputValue,
60
+ getSelectedCountry: () => countryValue,
61
+ selectedCountry: countryValue,
62
+ props: {
63
+ placeholder,
64
+ placeholderTextColor,
65
+ selectionColor,
66
+ containerStyle,
67
+ flagContainerStyle,
68
+ inputStyle,
69
+ withDarkTheme,
70
+ disabled,
71
+ modalDisabled,
72
+ defaultValue,
73
+ onChangePhoneNumber,
74
+ selectedCountry,
75
+ onChangeSelectedCountry,
76
+ ...rest,
77
+ },
78
+ };
67
79
 
68
- if (matchingCountry) {
69
- setDefaultCca2(matchingCountry.cca2);
80
+ function updateRef(phoneNumber, country) {
81
+ if (ref) {
82
+ ref.current = {
83
+ ...refBase,
84
+ getValue: () => phoneNumber,
85
+ value: phoneNumber,
86
+ getSelectedCountry: () => country,
87
+ selectedCountry: country,
88
+ props: {
89
+ ...refBase.props,
90
+ value: phoneNumber,
91
+ selectedCountry: country,
92
+ },
93
+ };
94
+ }
95
+ }
70
96
 
71
- onChangeSelectedCountry(matchingCountry);
97
+ function onSelect(country) {
98
+ if (ref) {
99
+ setInputValue('');
72
100
  } else {
73
- setDefaultCca2(null);
74
- onChangeSelectedCountry(null);
75
- onChangeText('', null);
76
-
77
- console.warn(
78
- "The default number provided (defaultValue) don't match with anyone country. Please, correct it to be shown in the input. For more information: https://github.com/AstrOOnauta/react-native-international-phone-number#intermediate-usage---typescript--default-phone-number-value"
79
- );
101
+ onChangePhoneNumber('');
80
102
  }
81
- } else {
82
- if (!selectedCountry) {
83
- onChangeSelectedCountry({
84
- callingCode: '+55',
85
- cca2: 'BR',
86
- flag: 'flag-br',
87
- name: 'Brazil',
88
- });
103
+
104
+ if (onChangeSelectedCountry || ref) {
105
+ const newValue = {
106
+ name: country.name,
107
+ cca2: country.cca2,
108
+ flag: country.flag,
109
+ callingCode: `+${country.callingCode[0]}`,
110
+ };
111
+
112
+ if (ref) {
113
+ setCountryValue(newValue);
114
+ updateRef('', newValue);
115
+ } else {
116
+ onChangeSelectedCountry(newValue);
117
+ }
89
118
  }
90
119
  }
91
- }, [defaultValue]);
92
-
93
- useEffect(() => {
94
- if (
95
- defaultValue &&
96
- selectedCountry &&
97
- selectedCountry.cca2 === defaultCca2 &&
98
- !rest.value
99
- ) {
100
- const callingCode = selectedCountry.callingCode;
101
120
 
102
- let phoneNumber = defaultValue;
121
+ function onChangeText(phoneNumber, callingCode) {
122
+ const res = phoneMask(
123
+ phoneNumber,
124
+ callingCode ? callingCode : countryValue?.callingCode,
125
+ countryValue?.cca2
126
+ );
103
127
 
104
- if (
105
- callingCode === '+1' &&
106
- selectedCountry.cca2 !== 'CA' &&
107
- selectedCountry.cca2 !== 'US'
108
- ) {
109
- phoneNumber = defaultValue
110
- .replace(/\s/g, '')
111
- .substring(
112
- callingCode.length + 3,
113
- defaultValue.replace(/\D/g, '').length +
114
- callingCode.length
115
- );
116
- } else if (
117
- callingCode === '+39' &&
118
- selectedCountry.cca2 === 'VA'
119
- ) {
120
- phoneNumber = defaultValue
121
- .replace(/\s/g, '')
122
- .substring(
123
- callingCode.length + 5,
124
- defaultValue.replace(/\D/g, '').length +
125
- callingCode.length
126
- );
128
+ if (ref) {
129
+ setInputValue(res);
130
+ updateRef(res, countryValue);
127
131
  } else {
128
- phoneNumber = defaultValue
129
- .replace(/\s/g, '')
130
- .substring(
131
- callingCode.length,
132
- defaultValue.replace(/\D/g, '').length +
133
- callingCode.length
134
- );
132
+ onChangePhoneNumber(res);
135
133
  }
136
- onChangeText(phoneNumber, callingCode);
137
134
  }
138
- }, [selectedCountry]);
139
135
 
140
- return (
141
- <View
142
- style={[
143
- withDarkTheme
144
- ? {
145
- ...styles.darkContainer,
146
- backgroundColor: disabled
147
- ? '#858585'
148
- : styles.darkContainer.backgroundColor,
149
- }
150
- : {
151
- ...styles.lightContainer,
152
- backgroundColor: disabled
153
- ? '#E3E3E3'
154
- : styles.lightContainer.backgroundColor,
155
- },
156
- containerStyle ? containerStyle : {},
157
- ]}
158
- onLayout={(e) => setContainerWidth(e.nativeEvent.layout.width)}
159
- >
160
- <CountryPicker
161
- containerButtonStyle={[
162
- flagContainerBase,
163
- selectedCountry?.cca2 === 'VA' ? { width: 140 } : {},
164
- flagContainerStyle ? flagContainerStyle : {},
165
- ]}
166
- onSelect={onSelect}
167
- withFilter
168
- withAlphaFilter
169
- withCallingCode
170
- withCallingCodeButton={selectedCountry || defaultCca2}
171
- theme={withDarkTheme ? DARK_THEME : DEFAULT_THEME}
172
- countryCode={
173
- selectedCountry ? selectedCountry.cca2 : defaultCca2
174
- }
175
- modalProps={
176
- disabled || modalDisabled ? { visible: false } : {}
177
- }
178
- />
179
- <TextInput
180
- style={[
181
- withDarkTheme ? styles.darkInput : styles.lightInput,
182
- { width: containerWidth - 100 },
183
- inputStyle ? inputStyle : {},
184
- ]}
185
- placeholder={
186
- placeholder ? placeholder : 'Insert your phone number'
136
+ useEffect(() => {
137
+ if (ref) {
138
+ setInputValue('');
139
+ } else {
140
+ onChangePhoneNumber('');
141
+ }
142
+
143
+ if (defaultValue) {
144
+ const matchingCountry = getCountryByPhoneNumber(defaultValue);
145
+
146
+ if (matchingCountry) {
147
+ setDefaultCca2(matchingCountry.cca2);
148
+
149
+ if (ref) {
150
+ setCountryValue(matchingCountry);
151
+ updateRef('', matchingCountry);
152
+ } else {
153
+ onChangeSelectedCountry(matchingCountry);
154
+ }
155
+ } else {
156
+ setDefaultCca2(null);
157
+
158
+ if (ref) {
159
+ setCountryValue(null);
160
+ updateRef('', null);
161
+ } else {
162
+ onChangeSelectedCountry(null);
163
+ }
164
+
165
+ onChangeText('', null);
166
+
167
+ console.warn(
168
+ "The default number provided (defaultValue) don't match with anyone country. Please, correct it to be shown in the input. For more information: https://github.com/AstrOOnauta/react-native-international-phone-number#intermediate-usage---typescript--default-phone-number-value"
169
+ );
187
170
  }
188
- placeholderTextColor={
189
- placeholderTextColor
190
- ? placeholderTextColor
191
- : withDarkTheme
192
- ? '#CCCCCC'
193
- : '#DDDDDD'
171
+ } else {
172
+ if (!countryValue) {
173
+ const defaultCountry = {
174
+ callingCode: '+55',
175
+ cca2: 'BR',
176
+ flag: 'flag-br',
177
+ name: 'Brazil',
178
+ };
179
+
180
+ if (ref) {
181
+ setCountryValue(defaultCountry);
182
+ updateRef('', defaultCountry);
183
+ } else {
184
+ onChangeSelectedCountry(defaultCountry);
185
+ }
186
+ } else {
187
+ if (ref) {
188
+ updateRef('', countryValue);
189
+ }
194
190
  }
195
- selectionColor={
196
- selectionColor
197
- ? selectionColor
198
- : withDarkTheme
199
- ? 'rgba(255,255,255, .4)'
200
- : 'rgba(0 ,0 ,0 , .4)'
191
+ }
192
+ }, [defaultValue]);
193
+
194
+ useEffect(() => {
195
+ if (
196
+ defaultValue &&
197
+ countryValue &&
198
+ countryValue.cca2 === defaultCca2 &&
199
+ !inputValue
200
+ ) {
201
+ const callingCode = countryValue.callingCode;
202
+
203
+ let phoneNumber = defaultValue;
204
+
205
+ if (
206
+ callingCode === '+1' &&
207
+ countryValue.cca2 !== 'CA' &&
208
+ countryValue.cca2 !== 'US'
209
+ ) {
210
+ phoneNumber = defaultValue
211
+ .replace(/\s/g, '')
212
+ .substring(
213
+ callingCode.length + 3,
214
+ defaultValue.replace(/\D/g, '').length +
215
+ callingCode.length
216
+ );
217
+ } else if (
218
+ callingCode === '+39' &&
219
+ countryValue.cca2 === 'VA'
220
+ ) {
221
+ phoneNumber = defaultValue
222
+ .replace(/\s/g, '')
223
+ .substring(
224
+ callingCode.length + 5,
225
+ defaultValue.replace(/\D/g, '').length +
226
+ callingCode.length
227
+ );
228
+ } else {
229
+ phoneNumber = defaultValue
230
+ .replace(/\s/g, '')
231
+ .substring(
232
+ callingCode.length,
233
+ defaultValue.replace(/\D/g, '').length +
234
+ callingCode.length
235
+ );
201
236
  }
202
- editable={!disabled}
203
- onChangeText={onChangeText}
204
- keyboardType="numeric"
205
- {...rest}
206
- />
207
- </View>
208
- );
209
- }
237
+ onChangeText(phoneNumber, callingCode);
238
+ }
239
+ }, [countryValue]);
240
+
241
+ useEffect(() => {
242
+ if (!ref) {
243
+ setInputValue(rest.value);
244
+ setCountryValue(selectedCountry);
245
+ }
246
+ }, [selectedCountry]);
247
+
248
+ if (
249
+ ref &&
250
+ (rest.value ||
251
+ onChangePhoneNumber ||
252
+ selectedCountry ||
253
+ onChangeSelectedCountry)
254
+ ) {
255
+ throw new Error(
256
+ "Error: Don't use the useRef hook combined with the useState hook to manage the phoneNumber and selectedCountry values. Instead, choose to use just one of them (useRef or useState)."
257
+ );
258
+ } else {
259
+ return (
260
+ <View
261
+ style={[
262
+ withDarkTheme
263
+ ? {
264
+ ...styles.darkContainer,
265
+ backgroundColor: disabled
266
+ ? '#858585'
267
+ : styles.darkContainer.backgroundColor,
268
+ }
269
+ : {
270
+ ...styles.lightContainer,
271
+ backgroundColor: disabled
272
+ ? '#E3E3E3'
273
+ : styles.lightContainer.backgroundColor,
274
+ },
275
+ containerStyle ? containerStyle : {},
276
+ ]}
277
+ onLayout={(e) =>
278
+ setContainerWidth(e.nativeEvent.layout.width)
279
+ }
280
+ >
281
+ <CountryPicker
282
+ containerButtonStyle={[
283
+ flagContainerBase,
284
+ countryValue?.cca2 === 'VA' ? { width: 140 } : {},
285
+ flagContainerStyle ? flagContainerStyle : {},
286
+ ]}
287
+ onSelect={onSelect}
288
+ withFilter
289
+ withAlphaFilter
290
+ withCallingCode
291
+ withCallingCodeButton={countryValue || defaultCca2}
292
+ theme={withDarkTheme ? DARK_THEME : DEFAULT_THEME}
293
+ countryCode={
294
+ countryValue ? countryValue?.cca2 : defaultCca2
295
+ }
296
+ modalProps={
297
+ disabled || modalDisabled ? { visible: false } : {}
298
+ }
299
+ />
300
+ <TextInput
301
+ style={[
302
+ withDarkTheme ? styles.darkInput : styles.lightInput,
303
+ { width: containerWidth - 100 },
304
+ inputStyle ? inputStyle : {},
305
+ ]}
306
+ placeholder={
307
+ placeholder ? placeholder : 'Insert your phone number'
308
+ }
309
+ placeholderTextColor={
310
+ placeholderTextColor
311
+ ? placeholderTextColor
312
+ : withDarkTheme
313
+ ? '#CCCCCC'
314
+ : '#DDDDDD'
315
+ }
316
+ selectionColor={
317
+ selectionColor
318
+ ? selectionColor
319
+ : withDarkTheme
320
+ ? 'rgba(255,255,255, .4)'
321
+ : 'rgba(0 ,0 ,0 , .4)'
322
+ }
323
+ editable={!disabled}
324
+ value={inputValue}
325
+ onChangeText={onChangeText}
326
+ keyboardType="numeric"
327
+ ref={textInputRef}
328
+ {...rest}
329
+ />
330
+ </View>
331
+ );
332
+ }
333
+ }
334
+ );
210
335
 
211
336
  const containerBase = {
212
337
  flexDirection: 'row',
@@ -6,8 +6,10 @@ import {
6
6
  } from 'react-native';
7
7
 
8
8
  import { ICountry } from './country';
9
+ import { Ref } from 'react';
10
+ import { IPhoneInputRef } from './phoneInputRef';
9
11
 
10
- export interface PhoneInputProps extends TextInputProps {
12
+ interface IPhoneInputPropsWithoutRef extends TextInputProps {
11
13
  placeholder?: string;
12
14
  placeholderTextColor?: string;
13
15
  containerStyle?: StyleProp<ViewStyle>;
@@ -21,4 +23,26 @@ export interface PhoneInputProps extends TextInputProps {
21
23
  onChangePhoneNumber: (phoneNumber: string) => void;
22
24
  selectedCountry: undefined | ICountry;
23
25
  onChangeSelectedCountry: (country: ICountry) => void;
26
+ ref?: never;
24
27
  }
28
+
29
+ interface IPhoneInputPropsWithRef extends TextInputProps {
30
+ placeholder?: string;
31
+ placeholderTextColor?: string;
32
+ containerStyle?: StyleProp<ViewStyle>;
33
+ flagContainerStyle?: StyleProp<ViewStyle>;
34
+ inputStyle?: StyleProp<TextStyle>;
35
+ withDarkTheme?: boolean;
36
+ disabled?: boolean;
37
+ modalDisabled?: boolean;
38
+ defaultValue?: string;
39
+ value?: never;
40
+ onChangePhoneNumber?: never;
41
+ selectedCountry?: never;
42
+ onChangeSelectedCountry?: never;
43
+ ref: Ref<IPhoneInputRef>;
44
+ }
45
+
46
+ export type PhoneInputProps =
47
+ | IPhoneInputPropsWithRef
48
+ | IPhoneInputPropsWithoutRef;
@@ -0,0 +1,14 @@
1
+ import { TextInput } from 'react-native';
2
+
3
+ import { ICountry } from './country';
4
+ import { PhoneInputProps } from './phoneInputProps';
5
+
6
+ export interface IPhoneInputRef extends TextInput {
7
+ props: PhoneInputProps;
8
+ onFocus: () => void;
9
+ focus: () => void;
10
+ getValue: () => string;
11
+ value: string;
12
+ getSelectedCountry: () => ICountry;
13
+ selectedCountry: ICountry;
14
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-native-international-phone-number",
3
3
  "author": "AstrOOnauta (https://github.com/AstrOOnauta)",
4
- "version": "0.4.12",
4
+ "version": "0.4.14",
5
5
  "description": "International mobile phone input component with mask for React Native",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",