react-native-international-phone-number 0.8.0 → 0.8.2

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
@@ -72,6 +72,7 @@
72
72
  - [Exclude some countries Inside Modal](#exclude-some-countries)
73
73
  - [Show Popular Countries at the Top of the Countries List Inside Modal](#show-popular-countries-at-the-top-of-the-countries-list-inside-modal)
74
74
  - [Right to Left Input](#right-to-left-input)
75
+ - [Dont allow Zero After Calling Code](#dont-allow-zero-after-calling-code)
75
76
  - [Lib Props](#component-props-phoneinputprops)
76
77
  - [Lib Functions](#functions)
77
78
  - [Supported languages](#🎌-supported-languages-🎌)
@@ -82,6 +83,7 @@
82
83
 
83
84
  ## Old Versions
84
85
 
86
+ - [Version 0.7.x](https://github.com/AstrOOnauta/react-native-international-phone-number/tree/v0.7.x)
85
87
  - [Version 0.6.x](https://github.com/AstrOOnauta/react-native-international-phone-number/tree/v0.6.x)
86
88
  - [Version 0.5.x](https://github.com/AstrOOnauta/react-native-international-phone-number/tree/v0.5.x)
87
89
  - [Version 0.4.x](https://github.com/AstrOOnauta/react-native-international-phone-number/tree/v0.4.x)
@@ -107,7 +109,7 @@ $ yarn add react-native-international-phone-number
107
109
  create a `react-native.config.js` file at the root of your react-native project with:
108
110
 
109
111
  ```bash
110
- module.exports = {
112
+ module.exports = {
111
113
  project: {
112
114
  ios: {},
113
115
  android: {},
@@ -115,7 +117,7 @@ create a `react-native.config.js` file at the root of your react-native project
115
117
  assets: [
116
118
  './node_modules/react-native-international-phone-number/lib/assets/fonts',
117
119
  ],
118
- };
120
+ };
119
121
  ```
120
122
 
121
123
  Then link the font to your native projects with:
@@ -126,19 +128,32 @@ npx react-native-asset
126
128
 
127
129
  - Using Expo:
128
130
 
129
- 1. Install [expo-fonts](https://docs.expo.dev/versions/latest/sdk/font/): `npx expo install expo-font`;
130
- 2. Initialize the `expo-font`:
131
+ 1. Change the `app.json` file to:
131
132
 
132
133
  ```bash
133
- import { useFonts } from 'expo-font';
134
+ ...
134
135
 
135
- ...
136
+ "web": {
137
+ ...
138
+ "output": "single",
139
+ ...
140
+ },
141
+ ...
142
+ ```
143
+
144
+ 2. Install [expo-fonts](https://docs.expo.dev/versions/latest/sdk/font/): `npx expo install expo-font`;
145
+ 3. Initialize the `expo-font`:
146
+
147
+ ```bash
148
+ import { useFonts } from 'expo-font';
149
+
150
+ ...
136
151
 
137
- useFonts({
152
+ useFonts({
138
153
  'TwemojiMozilla': require('./node_modules/react-native-international-phone-number/lib/assets/fonts/TwemojiMozilla.woff2'),
139
154
  });
140
155
 
141
- ...
156
+ ...
142
157
  ```
143
158
 
144
159
  > Observation: _you need to recompile your project after adding new fonts._
@@ -693,6 +708,17 @@ export default function App() {
693
708
  ...
694
709
  ```
695
710
 
711
+ - ### Don't allow Zero After Calling Code:
712
+
713
+ ```jsx
714
+ ...
715
+ <PhoneInput
716
+ ...
717
+ allowZeroAfterCallingCode={false}
718
+ />
719
+ ...
720
+ ```
721
+
696
722
  </br>
697
723
 
698
724
  ## Component Props ([PhoneInputProps](lib/interfaces/phoneInputProps.ts))
@@ -723,6 +749,7 @@ export default function App() {
723
749
  - `modalNotFoundCountryMessage?:` string;
724
750
  - `customCaret?:` [ReactNode](https://reactnative.dev/docs/react-node);
725
751
  - `ref?:` [Ref](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/663f439d11d78b65f1dfd38d120f3728ea2cc207/types/react/index.d.ts#L100)<[IPhoneInputRef](lib/interfaces/phoneInputRef.ts)>;
752
+ - `allowZeroAfterCallingCode?:` boolean
726
753
 
727
754
  <br>
728
755
 
@@ -2545,7 +2545,7 @@ export const countries = [
2545
2545
  zh: '岡比亞',
2546
2546
  tr: 'Gambiya',
2547
2547
  },
2548
- phoneMasks: ['### ## ##'],
2548
+ phoneMasks: ['### ####'],
2549
2549
  },
2550
2550
  {
2551
2551
  callingCode: '+224',
@@ -3446,7 +3446,7 @@ export const countries = [
3446
3446
  pl: 'Kirgistan',
3447
3447
  pt: 'Quirguizistão',
3448
3448
  ro: 'Kârgâzstan',
3449
- ru: 'Kyrgyzstan',
3449
+ ru: 'Кыргызстан',
3450
3450
  ua: 'Киргизстан',
3451
3451
  zh: '吉爾吉斯斯坦',
3452
3452
  tr: 'Kırgızistan',
@@ -3637,7 +3637,7 @@ export const countries = [
3637
3637
  zh: '韓國',
3638
3638
  tr: 'Kore Cumhuriyeti',
3639
3639
  },
3640
- phoneMasks: ['## ### ####'],
3640
+ phoneMasks: ['### #### ####'],
3641
3641
  },
3642
3642
  {
3643
3643
  callingCode: '+965',
@@ -4717,7 +4717,13 @@ export const countries = [
4717
4717
  zh: '馬來西亞',
4718
4718
  tr: 'Malezya',
4719
4719
  },
4720
- phoneMasks: ['# ### ###', '## ### ###', '## ### ####'],
4720
+ phoneMasks: [
4721
+ '# ### ###',
4722
+ '## ### ###',
4723
+ '## ### ####',
4724
+ '### ### ####',
4725
+ '### #### ####',
4726
+ ],
4721
4727
  },
4722
4728
  {
4723
4729
  callingCode: '+258',
package/lib/index.js CHANGED
@@ -36,7 +36,7 @@ import {
36
36
  getFlagTextStyle,
37
37
  getInputStyle,
38
38
  } from './utils/getStyles';
39
- import styles from "./styles";
39
+ import styles from './styles';
40
40
 
41
41
  const PhoneInput = forwardRef(
42
42
  (
@@ -68,6 +68,7 @@ const PhoneInput = forwardRef(
68
68
  modalNotFoundCountryMessage,
69
69
  customCaret,
70
70
  rtl,
71
+ allowZeroAfterCallingCode,
71
72
  ...rest
72
73
  },
73
74
  ref
@@ -118,6 +119,7 @@ const PhoneInput = forwardRef(
118
119
  modalNotFoundCountryMessage,
119
120
  customCaret,
120
121
  rtl,
122
+ allowZeroAfterCallingCode,
121
123
  ...rest,
122
124
  },
123
125
  };
@@ -195,7 +197,8 @@ const PhoneInput = forwardRef(
195
197
  phoneNumber,
196
198
  callingCode ? callingCode : countryValue?.callingCode,
197
199
  countryValue?.cca2,
198
- customMask ? customMask : null
200
+ customMask ? customMask : null,
201
+ allowZeroAfterCallingCode === false ? false : true
199
202
  );
200
203
 
201
204
  if (ref) {
@@ -326,98 +329,97 @@ const PhoneInput = forwardRef(
326
329
  "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)."
327
330
  );
328
331
  } else {
329
-
330
- // Create a separate constant for each part of the component
331
- const touchableStart =
332
- <Text style={getFlagStyle(phoneInputStyles?.flag)}>
333
- {countryValue?.flag}
334
- </Text>
335
- {customCaret || (
336
- <View style={phoneInputStyles?.caret}>
337
- <View
338
- style={{
339
- flexDirection: 'row',
340
- justifyContent: 'center',
341
- paddingTop: 4,
342
- }}
343
- >
332
+ // Create a separate constant for each part of the component
333
+ const touchableStart = (
334
+ <Text style={getFlagStyle(phoneInputStyles?.flag)}>
335
+ {countryValue?.flag}
336
+ </Text>
337
+ );
338
+ {
339
+ customCaret || (
340
+ <View style={phoneInputStyles?.caret}>
344
341
  <View
345
- style={getCaretStyle(
346
- theme,
347
- phoneInputStyles?.caret
348
- )}
349
- />
342
+ style={{
343
+ flexDirection: 'row',
344
+ justifyContent: 'center',
345
+ paddingTop: 4,
346
+ }}
347
+ >
348
+ <View
349
+ style={getCaretStyle(theme, phoneInputStyles?.caret)}
350
+ />
351
+ </View>
350
352
  </View>
351
- </View>
352
- )};
353
-
354
- const touchableMiddle =
355
- <View
356
- style={getDividerStyle(
357
- theme,
358
- phoneInputStyles?.divider
359
- )}
360
- />;
361
-
362
- const touchableEnd =
363
- <Text
364
- style={getFlagTextStyle(
365
- theme,
366
- phoneInputStyles?.callingCode
367
- )}
368
- >
369
- {countryValue?.callingCode}
370
- </Text>;
371
-
372
- const touchablePart =
373
- <TouchableOpacity
374
- activeOpacity={disabled || modalDisabled ? 1 : 0.6}
375
- onPress={() =>
376
- disabled || modalDisabled ? null : setShow(true)
377
- }
378
- style={getFlagContainerStyle(
379
- theme,
380
- phoneInputStyles?.flagContainer
381
- )}
382
- >
383
- {/* LTR Display */}
384
- {!rtl && touchableStart}
385
- {!rtl && touchableMiddle}
386
- {!rtl && touchableEnd}
387
-
388
- {/* RTL Display */}
389
- {rtl && touchableEnd}
390
- {rtl && touchableMiddle}
391
- {rtl && touchableStart}
392
- </TouchableOpacity>;
393
-
394
- const inputPart =
395
- <TextInput
396
- style={getInputStyle(theme, phoneInputStyles?.input)}
397
- placeholder={
398
- placeholder === '' || placeholder
399
- ? placeholder
400
- : getPhoneNumberInputPlaceholder(language || 'en')
401
- }
402
- placeholderTextColor={
403
- placeholderTextColor ||
404
- (theme === 'dark' ? '#CCCCCC' : '#AAAAAA')
405
- }
406
- selectionColor={
407
- selectionColor ||
408
- (theme === 'dark'
409
- ? 'rgba(255,255,255, .4)'
410
- : 'rgba(0 ,0 ,0 , .4)')
411
- }
412
- editable={!disabled}
413
- value={inputValue}
414
- onChangeText={onChangeText}
415
- keyboardType="numeric"
416
- ref={textInputRef}
417
- {...rest}
418
- />;
419
-
420
-
353
+ );
354
+ }
355
+
356
+ const touchableMiddle = (
357
+ <View
358
+ style={getDividerStyle(theme, phoneInputStyles?.divider)}
359
+ />
360
+ );
361
+
362
+ const touchableEnd = (
363
+ <Text
364
+ style={getFlagTextStyle(
365
+ theme,
366
+ phoneInputStyles?.callingCode
367
+ )}
368
+ >
369
+ {countryValue?.callingCode}
370
+ </Text>
371
+ );
372
+
373
+ const touchablePart = (
374
+ <TouchableOpacity
375
+ activeOpacity={disabled || modalDisabled ? 1 : 0.6}
376
+ onPress={() =>
377
+ disabled || modalDisabled ? null : setShow(true)
378
+ }
379
+ style={getFlagContainerStyle(
380
+ theme,
381
+ phoneInputStyles?.flagContainer
382
+ )}
383
+ >
384
+ {/* LTR Display */}
385
+ {!rtl && touchableStart}
386
+ {!rtl && touchableMiddle}
387
+ {!rtl && touchableEnd}
388
+
389
+ {/* RTL Display */}
390
+ {rtl && touchableEnd}
391
+ {rtl && touchableMiddle}
392
+ {rtl && touchableStart}
393
+ </TouchableOpacity>
394
+ );
395
+
396
+ const inputPart = (
397
+ <TextInput
398
+ style={getInputStyle(theme, phoneInputStyles?.input)}
399
+ placeholder={
400
+ placeholder === '' || placeholder
401
+ ? placeholder
402
+ : getPhoneNumberInputPlaceholder(language || 'en')
403
+ }
404
+ placeholderTextColor={
405
+ placeholderTextColor ||
406
+ (theme === 'dark' ? '#CCCCCC' : '#AAAAAA')
407
+ }
408
+ selectionColor={
409
+ selectionColor ||
410
+ (theme === 'dark'
411
+ ? 'rgba(255,255,255, .4)'
412
+ : 'rgba(0 ,0 ,0 , .4)')
413
+ }
414
+ editable={!disabled}
415
+ value={inputValue}
416
+ onChangeText={onChangeText}
417
+ keyboardType="numeric"
418
+ ref={textInputRef}
419
+ {...rest}
420
+ />
421
+ );
422
+
421
423
  return (
422
424
  <>
423
425
  <View
@@ -469,31 +471,33 @@ const PhoneInput = forwardRef(
469
471
  excludedCountries={excludedCountries}
470
472
  popularCountries={popularCountries}
471
473
  ListHeaderComponent={({ countries, lang, onPress }) => {
472
- return (
473
- <View>
474
- {popularCountriesSectionTitle &&(
474
+ return (
475
+ <View>
476
+ {popularCountriesSectionTitle && (
475
477
  <Text>{popularCountriesSectionTitle}</Text>
476
- )}
477
- {countries.map((country, index) => {
478
- return (
479
- <CountryButton
480
- key={index}
481
- item={country}
482
- name={country?.name?.[lang || 'en']}
483
- onPress={() => onPress(country)}
484
- style={getCountryPickerStyle(
485
- theme,
486
- modalHeight,
487
- modalStyles
488
- )}
489
- />
490
- );
491
- })}
492
- {restOfCountriesSectionTitle &&(
493
- <Text style={styles.sectionTitle}>{restOfCountriesSectionTitle}</Text>
494
- )}
495
- </View>
496
- )
478
+ )}
479
+ {countries.map((country, index) => {
480
+ return (
481
+ <CountryButton
482
+ key={index}
483
+ item={country}
484
+ name={country?.name?.[lang || 'en']}
485
+ onPress={() => onPress(country)}
486
+ style={getCountryPickerStyle(
487
+ theme,
488
+ modalHeight,
489
+ modalStyles
490
+ )}
491
+ />
492
+ );
493
+ })}
494
+ {restOfCountriesSectionTitle && (
495
+ <Text style={styles.sectionTitle}>
496
+ {restOfCountriesSectionTitle}
497
+ </Text>
498
+ )}
499
+ </View>
500
+ );
497
501
  }}
498
502
  />
499
503
  ) : null}
@@ -34,6 +34,7 @@ interface BasePhoneInput extends TextInputProps {
34
34
  modalNotFoundCountryMessage?: string;
35
35
  customCaret?: ReactNode;
36
36
  rtl?: boolean;
37
+ allowZeroAfterCallingCode?: boolean;
37
38
  }
38
39
 
39
40
  interface IPhoneInputPropsWithoutRef extends BasePhoneInput {
@@ -1,10 +1,25 @@
1
1
  import { countries } from '../constants/countries';
2
2
 
3
+ function startsWithZero(phoneNumber, callingCode) {
4
+ const newCode = callingCode.replace('+', '');
5
+ return (
6
+ phoneNumber.startsWith('0') ||
7
+ phoneNumber.startsWith(`${newCode}0`)
8
+ );
9
+ }
10
+
11
+ function eliminateZeroAfterCallingCode(phoneNumber, callingCode) {
12
+ return startsWithZero(phoneNumber, callingCode)
13
+ ? phoneNumber.slice(1, phoneNumber.length)
14
+ : phoneNumber;
15
+ }
16
+
3
17
  export default function getInputMask(
4
18
  phoneNumber,
5
19
  callingCode,
6
20
  cca2,
7
- customMask
21
+ customMask,
22
+ allowZeroAfterCallingCode
8
23
  ) {
9
24
  let matrix = '';
10
25
 
@@ -59,9 +74,17 @@ export default function getInputMask(
59
74
  });
60
75
 
61
76
  let i = 0;
62
- const newValue = phoneNumber.replace(/\D/g, '');
77
+ const value = phoneNumber.replace(/\D/g, '');
78
+ const newValue = allowZeroAfterCallingCode
79
+ ? value
80
+ : eliminateZeroAfterCallingCode(value, callingCode);
81
+
82
+ const newMatrix =
83
+ allowZeroAfterCallingCode && startsWithZero(value, callingCode)
84
+ ? '#' + matrix
85
+ : matrix;
63
86
 
64
- return matrix.replace(/(?!\+)./g, function (a) {
87
+ return newMatrix.replace(/(?!\+)./g, function (a) {
65
88
  return /[#\d]/.test(a) && i < newValue.length
66
89
  ? newValue.charAt(i++)
67
90
  : i >= newValue.length
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.8.0",
4
+ "version": "0.8.2",
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",