react-native-international-phone-number 0.4.13 → 0.4.15
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 +48 -1
- package/lib/index.d.ts +1 -6
- package/lib/index.js +85 -71
- package/lib/interfaces/phoneInputProps.ts +27 -1
- package/lib/utils/inputMask.js +13 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
- [With Function Component](#function-component)
|
|
49
49
|
- [Custom Default Flag](#custom-default-flag)
|
|
50
50
|
- [Default Phone Number Value](#default-phone-number-value)
|
|
51
|
+
- [Custom Phone Mask](#custom-phone-mask)
|
|
51
52
|
- [Typescript](#typescript)
|
|
52
53
|
- [Intermediate Usage](#intermediate-usage)
|
|
53
54
|
- [Typescript + useRef](#typescript--useref)
|
|
@@ -293,6 +294,49 @@ export default function App() {
|
|
|
293
294
|
> 1. You need to use a default value with the following format: `+(country callling code)(area code)(number phone)`
|
|
294
295
|
> 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
296
|
|
|
297
|
+
- ### Custom Phone Mask
|
|
298
|
+
|
|
299
|
+
```tsx
|
|
300
|
+
import React, { useState } from 'react';
|
|
301
|
+
import { View, Text } from 'react-native';
|
|
302
|
+
import { PhoneInput } from 'react-native-international-phone-number';
|
|
303
|
+
|
|
304
|
+
export default function App() {
|
|
305
|
+
const [selectedCountry, setSelectedCountry] = useState(undefined);
|
|
306
|
+
const [inputValue, setInputValue] = useState('');
|
|
307
|
+
|
|
308
|
+
function handleInputValue(phoneNumber) {
|
|
309
|
+
setInputValue(phoneNumber);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function handleSelectedCountry(country) {
|
|
313
|
+
setSelectedCountry(country);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return (
|
|
317
|
+
<View style={{ width: '100%', flex: 1, padding: 24 }}>
|
|
318
|
+
<PhoneInput
|
|
319
|
+
customMask={['#### ####', '##### ####']}
|
|
320
|
+
value={inputValue}
|
|
321
|
+
onChangePhoneNumber={handleInputValue}
|
|
322
|
+
selectedCountry={selectedCountry}
|
|
323
|
+
onChangeSelectedCountry={handleSelectedCountry}
|
|
324
|
+
/>
|
|
325
|
+
<View style={{ marginTop: 10 }}>
|
|
326
|
+
<Text>
|
|
327
|
+
Country:{' '}
|
|
328
|
+
{`${selectedCountry?.name} (${selectedCountry?.cca2})`}
|
|
329
|
+
</Text>
|
|
330
|
+
<Text>
|
|
331
|
+
Phone Number:{' '}
|
|
332
|
+
{`${selectedCountry?.callingCode} ${inputValue}`}
|
|
333
|
+
</Text>
|
|
334
|
+
</View>
|
|
335
|
+
</View>
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
296
340
|
- ### Typescript
|
|
297
341
|
|
|
298
342
|
```tsx
|
|
@@ -394,6 +438,8 @@ export default function App() {
|
|
|
394
438
|
}
|
|
395
439
|
```
|
|
396
440
|
|
|
441
|
+
> 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).
|
|
442
|
+
|
|
397
443
|
## Advanced Usage
|
|
398
444
|
|
|
399
445
|
- ### React-Hook-Form + Typescript + Default Phone Number Value
|
|
@@ -549,6 +595,7 @@ export default function App() {
|
|
|
549
595
|
|
|
550
596
|
## Component Props ([PhoneInputProps](https://github.com/AstrOOnauta/react-native-international-phone-number/blob/master/lib/interfaces/phoneInputProps.ts))
|
|
551
597
|
|
|
598
|
+
- `customMask?:` string[];
|
|
552
599
|
- `defaultValue?:` string;
|
|
553
600
|
- `value?:` string;
|
|
554
601
|
- `onChangePhoneNumber?:` (phoneNumber: string) => void;
|
|
@@ -560,7 +607,7 @@ export default function App() {
|
|
|
560
607
|
- `containerStyle?:` StyleProp<[ViewStyle](https://reactnative.dev/docs/view-style-props)>;
|
|
561
608
|
- `flagContainerStyle?:` StyleProp<[ViewStyle](https://reactnative.dev/docs/view-style-props)>;
|
|
562
609
|
- `inputStyle?:` StyleProp<[TextStyle](https://reactnative.dev/docs/text-style-props)>;
|
|
563
|
-
- `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/
|
|
610
|
+
- `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)>
|
|
564
611
|
|
|
565
612
|
<br>
|
|
566
613
|
|
package/lib/index.d.ts
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import { Ref } from 'react';
|
|
2
|
-
|
|
3
1
|
import { ICountry } from './interfaces/country';
|
|
4
2
|
import { IPhoneInputRef } from './interfaces/phoneInputRef';
|
|
5
3
|
import { PhoneInputProps } from './interfaces/phoneInputProps';
|
|
6
4
|
|
|
7
|
-
declare function PhoneInput
|
|
8
|
-
props: PhoneInputProps,
|
|
9
|
-
ref?: Ref<IPhoneInputRef>
|
|
10
|
-
): JSX.Element;
|
|
5
|
+
declare function PhoneInput(props: PhoneInputProps): JSX.Element;
|
|
11
6
|
|
|
12
7
|
declare function getAllCountries(): ICountry[];
|
|
13
8
|
|
package/lib/index.js
CHANGED
|
@@ -38,6 +38,7 @@ const PhoneInput = forwardRef(
|
|
|
38
38
|
onChangePhoneNumber,
|
|
39
39
|
selectedCountry,
|
|
40
40
|
onChangeSelectedCountry,
|
|
41
|
+
customMask,
|
|
41
42
|
...rest
|
|
42
43
|
},
|
|
43
44
|
ref
|
|
@@ -122,7 +123,8 @@ const PhoneInput = forwardRef(
|
|
|
122
123
|
const res = phoneMask(
|
|
123
124
|
phoneNumber,
|
|
124
125
|
callingCode ? callingCode : countryValue?.callingCode,
|
|
125
|
-
countryValue?.cca2
|
|
126
|
+
countryValue?.cca2,
|
|
127
|
+
customMask ? customMask : null,
|
|
126
128
|
);
|
|
127
129
|
|
|
128
130
|
if (ref) {
|
|
@@ -245,79 +247,91 @@ const PhoneInput = forwardRef(
|
|
|
245
247
|
}
|
|
246
248
|
}, [selectedCountry]);
|
|
247
249
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
? '#E3E3E3'
|
|
262
|
-
: styles.lightContainer.backgroundColor,
|
|
263
|
-
},
|
|
264
|
-
containerStyle ? containerStyle : {},
|
|
265
|
-
]}
|
|
266
|
-
onLayout={(e) =>
|
|
267
|
-
setContainerWidth(e.nativeEvent.layout.width)
|
|
268
|
-
}
|
|
269
|
-
>
|
|
270
|
-
<CountryPicker
|
|
271
|
-
containerButtonStyle={[
|
|
272
|
-
flagContainerBase,
|
|
273
|
-
countryValue?.cca2 === 'VA' ? { width: 140 } : {},
|
|
274
|
-
flagContainerStyle ? flagContainerStyle : {},
|
|
275
|
-
]}
|
|
276
|
-
onSelect={onSelect}
|
|
277
|
-
withFilter
|
|
278
|
-
withAlphaFilter
|
|
279
|
-
withCallingCode
|
|
280
|
-
withCallingCodeButton={countryValue || defaultCca2}
|
|
281
|
-
theme={withDarkTheme ? DARK_THEME : DEFAULT_THEME}
|
|
282
|
-
countryCode={
|
|
283
|
-
countryValue ? countryValue?.cca2 : defaultCca2
|
|
284
|
-
}
|
|
285
|
-
modalProps={
|
|
286
|
-
disabled || modalDisabled ? { visible: false } : {}
|
|
287
|
-
}
|
|
288
|
-
/>
|
|
289
|
-
<TextInput
|
|
250
|
+
if (
|
|
251
|
+
ref &&
|
|
252
|
+
(rest.value ||
|
|
253
|
+
onChangePhoneNumber ||
|
|
254
|
+
selectedCountry ||
|
|
255
|
+
onChangeSelectedCountry)
|
|
256
|
+
) {
|
|
257
|
+
throw new Error(
|
|
258
|
+
"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)."
|
|
259
|
+
);
|
|
260
|
+
} else {
|
|
261
|
+
return (
|
|
262
|
+
<View
|
|
290
263
|
style={[
|
|
291
|
-
withDarkTheme
|
|
292
|
-
|
|
293
|
-
|
|
264
|
+
withDarkTheme
|
|
265
|
+
? {
|
|
266
|
+
...styles.darkContainer,
|
|
267
|
+
backgroundColor: disabled
|
|
268
|
+
? '#858585'
|
|
269
|
+
: styles.darkContainer.backgroundColor,
|
|
270
|
+
}
|
|
271
|
+
: {
|
|
272
|
+
...styles.lightContainer,
|
|
273
|
+
backgroundColor: disabled
|
|
274
|
+
? '#E3E3E3'
|
|
275
|
+
: styles.lightContainer.backgroundColor,
|
|
276
|
+
},
|
|
277
|
+
containerStyle ? containerStyle : {},
|
|
294
278
|
]}
|
|
295
|
-
|
|
296
|
-
|
|
279
|
+
onLayout={(e) =>
|
|
280
|
+
setContainerWidth(e.nativeEvent.layout.width)
|
|
297
281
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
:
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
282
|
+
>
|
|
283
|
+
<CountryPicker
|
|
284
|
+
containerButtonStyle={[
|
|
285
|
+
flagContainerBase,
|
|
286
|
+
countryValue?.cca2 === 'VA' ? { width: 140 } : {},
|
|
287
|
+
flagContainerStyle ? flagContainerStyle : {},
|
|
288
|
+
]}
|
|
289
|
+
onSelect={onSelect}
|
|
290
|
+
withFilter
|
|
291
|
+
withAlphaFilter
|
|
292
|
+
withCallingCode
|
|
293
|
+
withCallingCodeButton={countryValue || defaultCca2}
|
|
294
|
+
theme={withDarkTheme ? DARK_THEME : DEFAULT_THEME}
|
|
295
|
+
countryCode={
|
|
296
|
+
countryValue ? countryValue?.cca2 : defaultCca2
|
|
297
|
+
}
|
|
298
|
+
modalProps={
|
|
299
|
+
disabled || modalDisabled ? { visible: false } : {}
|
|
300
|
+
}
|
|
301
|
+
/>
|
|
302
|
+
<TextInput
|
|
303
|
+
style={[
|
|
304
|
+
withDarkTheme ? styles.darkInput : styles.lightInput,
|
|
305
|
+
{ width: containerWidth - 100 },
|
|
306
|
+
inputStyle ? inputStyle : {},
|
|
307
|
+
]}
|
|
308
|
+
placeholder={
|
|
309
|
+
placeholder ? placeholder : 'Insert your phone number'
|
|
310
|
+
}
|
|
311
|
+
placeholderTextColor={
|
|
312
|
+
placeholderTextColor
|
|
313
|
+
? placeholderTextColor
|
|
314
|
+
: withDarkTheme
|
|
315
|
+
? '#CCCCCC'
|
|
316
|
+
: '#DDDDDD'
|
|
317
|
+
}
|
|
318
|
+
selectionColor={
|
|
319
|
+
selectionColor
|
|
320
|
+
? selectionColor
|
|
321
|
+
: withDarkTheme
|
|
322
|
+
? 'rgba(255,255,255, .4)'
|
|
323
|
+
: 'rgba(0 ,0 ,0 , .4)'
|
|
324
|
+
}
|
|
325
|
+
editable={!disabled}
|
|
326
|
+
value={inputValue}
|
|
327
|
+
onChangeText={onChangeText}
|
|
328
|
+
keyboardType="numeric"
|
|
329
|
+
ref={textInputRef}
|
|
330
|
+
{...rest}
|
|
331
|
+
/>
|
|
332
|
+
</View>
|
|
333
|
+
);
|
|
334
|
+
}
|
|
321
335
|
}
|
|
322
336
|
);
|
|
323
337
|
|
|
@@ -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
|
-
|
|
12
|
+
interface IPhoneInputPropsWithoutRef extends TextInputProps {
|
|
11
13
|
placeholder?: string;
|
|
12
14
|
placeholderTextColor?: string;
|
|
13
15
|
containerStyle?: StyleProp<ViewStyle>;
|
|
@@ -21,4 +23,28 @@ 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;
|
|
27
|
+
customMask?:Array<string>;
|
|
24
28
|
}
|
|
29
|
+
|
|
30
|
+
interface IPhoneInputPropsWithRef extends TextInputProps {
|
|
31
|
+
placeholder?: string;
|
|
32
|
+
placeholderTextColor?: string;
|
|
33
|
+
containerStyle?: StyleProp<ViewStyle>;
|
|
34
|
+
flagContainerStyle?: StyleProp<ViewStyle>;
|
|
35
|
+
inputStyle?: StyleProp<TextStyle>;
|
|
36
|
+
withDarkTheme?: boolean;
|
|
37
|
+
disabled?: boolean;
|
|
38
|
+
modalDisabled?: boolean;
|
|
39
|
+
defaultValue?: string;
|
|
40
|
+
value?: never;
|
|
41
|
+
onChangePhoneNumber?: never;
|
|
42
|
+
selectedCountry?: never;
|
|
43
|
+
onChangeSelectedCountry?: never;
|
|
44
|
+
ref: Ref<IPhoneInputRef>;
|
|
45
|
+
customMask?:Array<string>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type PhoneInputProps =
|
|
49
|
+
| IPhoneInputPropsWithRef
|
|
50
|
+
| IPhoneInputPropsWithoutRef;
|
package/lib/utils/inputMask.js
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { countries } from './countries';
|
|
2
2
|
|
|
3
|
-
export default function phoneMask(phoneNumber, callingCode, cca2) {
|
|
3
|
+
export default function phoneMask(phoneNumber, callingCode, cca2, customMask) {
|
|
4
4
|
let matrix = '';
|
|
5
5
|
|
|
6
6
|
countries.forEach((item) => {
|
|
7
7
|
const newCode = item.callingCode.replace(/[\s#]/g, '');
|
|
8
|
+
const phoneMask = Array.isArray(customMask) && customMask || item.phoneMasks;
|
|
8
9
|
|
|
9
10
|
if (callingCode && callingCode.includes(newCode)) {
|
|
10
|
-
if (
|
|
11
|
+
if (phoneMask.length === 1) {
|
|
11
12
|
if (cca2 !== 'CA' && cca2 !== 'US' && cca2 !== 'IT') {
|
|
12
|
-
matrix =
|
|
13
|
+
matrix = phoneMask[0].replace(/[0-9]/g, '').trim();
|
|
13
14
|
}
|
|
14
|
-
} else if (
|
|
15
|
+
} else if (phoneMask.length > 1) {
|
|
15
16
|
let hasDifferentLengthsOfPhoneNumbers = false;
|
|
16
17
|
|
|
17
|
-
for (let i = 0; i <
|
|
18
|
+
for (let i = 0; i < phoneMask.length; i++) {
|
|
18
19
|
if (
|
|
19
|
-
phoneNumber.length >
|
|
20
|
+
phoneNumber.length > phoneMask[0].length &&
|
|
20
21
|
newCode !== '+1'
|
|
21
22
|
) {
|
|
22
23
|
hasDifferentLengthsOfPhoneNumbers = true;
|
|
@@ -25,17 +26,17 @@ export default function phoneMask(phoneNumber, callingCode, cca2) {
|
|
|
25
26
|
|
|
26
27
|
if (!hasDifferentLengthsOfPhoneNumbers) {
|
|
27
28
|
if (cca2 === 'CA' || cca2 === 'US') {
|
|
28
|
-
matrix =
|
|
29
|
+
matrix = phoneMask[0].replace(/\d/g, '#').trim();
|
|
29
30
|
} else {
|
|
30
|
-
matrix =
|
|
31
|
+
matrix = phoneMask[0].replace(/[0-9]/g, '').trim();
|
|
31
32
|
}
|
|
32
33
|
} else {
|
|
33
|
-
for (let i = 0; i <
|
|
34
|
+
for (let i = 0; i < phoneMask.length; i++) {
|
|
34
35
|
if (
|
|
35
|
-
phoneNumber.length >
|
|
36
|
-
|
|
36
|
+
phoneNumber.length > phoneMask[i].length &&
|
|
37
|
+
phoneMask[i + 1]
|
|
37
38
|
) {
|
|
38
|
-
matrix =
|
|
39
|
+
matrix = phoneMask[i + 1]
|
|
39
40
|
.replace(/[0-9]/g, '')
|
|
40
41
|
.trim();
|
|
41
42
|
}
|
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.
|
|
4
|
+
"version": "0.4.15",
|
|
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",
|