react-native-international-phone-number 0.11.0 → 0.11.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
@@ -1,7 +1,7 @@
1
1
  <br>
2
2
 
3
3
  <div align = "center">
4
- <img src="lib/assets/images/preview.png" alt="React Native International Phone Number Input Lib preview">
4
+ <img src="https://astroonauta.github.io/react-native-international-phone-number/lib/assets/images/preview.png" alt="React Native International Phone Number Input Lib preview">
5
5
  </div>
6
6
 
7
7
  <br>
@@ -69,11 +69,11 @@
69
69
  - [Basic Usage](#basic-usage)
70
70
  - [With Class Component](#class-component)
71
71
  - [With Function Component](#function-component)
72
- - [With Typescript + defaultValue](#typescript)
72
+ - [With Typescript + defaultValue](#typescript--defaultvalue)
73
73
  - [Intermediate Usage](#intermediate-usage)
74
- - [Typescript + useRef + defaultValue](#typescript--useref)
74
+ - [Typescript + useRef + defaultValue](#typescript--useref--defaultvalue)
75
75
  - [Advanced Usage](#advanced-usage)
76
- - [React-Hook-Form + Typescript + defaultValue](#react-hook-form--typescript--default-phone-number-value)
76
+ - [React-Hook-Form + Typescript + defaultValue](#react-hook-form--typescript--defaultvalue)
77
77
  - [Customizing Lib](#customizing-lib)
78
78
  - [Lib Props](#component-props-phoneinputprops)
79
79
  - [Lib Functions](#functions)
@@ -217,8 +217,8 @@ export class App extends React.Component {
217
217
  - ### Function Component:
218
218
 
219
219
  ```jsx
220
- import React, {useState} from 'react';
221
- import {View, Text} from 'react-native';
220
+ import React, { useState } from 'react';
221
+ import { View, Text } from 'react-native';
222
222
  import PhoneInput, {
223
223
  isValidPhoneNumber,
224
224
  } from 'react-native-international-phone-number';
@@ -236,24 +236,27 @@ export default function App() {
236
236
  }
237
237
 
238
238
  return (
239
- <View style={{width: '100%', flex: 1, padding: 24}}>
239
+ <View style={{ width: '100%', flex: 1, padding: 24 }}>
240
240
  <PhoneInput
241
241
  value={inputValue}
242
242
  onChangePhoneNumber={handleInputValue}
243
243
  selectedCountry={selectedCountry}
244
244
  onChangeSelectedCountry={handleSelectedCountry}
245
245
  />
246
- <View style={{marginTop: 10}}>
246
+ <View style={{ marginTop: 10 }}>
247
247
  <Text>
248
248
  Country:{' '}
249
249
  {`${selectedCountry?.translations?.eng?.common} (${selectedCountry?.cca2})`}
250
250
  </Text>
251
251
  <Text>
252
- Phone Number: {`${selectedCountry?.idd?.root} ${inputValue}`}
252
+ Phone Number:{' '}
253
+ {`${selectedCountry?.idd?.root} ${inputValue}`}
253
254
  </Text>
254
255
  <Text>
255
256
  isValid:{' '}
256
- {isValidPhoneNumber(inputValue, selectedCountry) ? 'true' : 'false'}
257
+ {isValidPhoneNumber(inputValue, selectedCountry)
258
+ ? 'true'
259
+ : 'false'}
257
260
  </Text>
258
261
  </View>
259
262
  </View>
@@ -264,15 +267,16 @@ export default function App() {
264
267
  - ### Typescript + DefaultValue
265
268
 
266
269
  ```tsx
267
- import React, {useState} from 'react';
268
- import {View, Text} from 'react-native';
270
+ import React, { useState } from 'react';
271
+ import { View, Text } from 'react-native';
269
272
  import PhoneInput, {
270
273
  ICountry,
271
274
  isValidPhoneNumber,
272
275
  } from 'react-native-international-phone-number';
273
276
 
274
277
  export default function App() {
275
- const [selectedCountry, setSelectedCountry] = useState<null | ICountry>(null);
278
+ const [selectedCountry, setSelectedCountry] =
279
+ useState<null | ICountry>(null);
276
280
  const [inputValue, setInputValue] = useState<string>('');
277
281
 
278
282
  function handleInputValue(phoneNumber: string) {
@@ -284,7 +288,7 @@ export default function App() {
284
288
  }
285
289
 
286
290
  return (
287
- <View style={{width: '100%', flex: 1, padding: 24}}>
291
+ <View style={{ width: '100%', flex: 1, padding: 24 }}>
288
292
  <PhoneInput
289
293
  defaultValue="+12505550199"
290
294
  value={inputValue}
@@ -292,17 +296,20 @@ export default function App() {
292
296
  selectedCountry={selectedCountry}
293
297
  onChangeSelectedCountry={handleSelectedCountry}
294
298
  />
295
- <View style={{marginTop: 10}}>
299
+ <View style={{ marginTop: 10 }}>
296
300
  <Text>
297
301
  Country:{' '}
298
302
  {`${selectedCountry?.translations?.eng?.common} (${selectedCountry?.cca2})`}
299
303
  </Text>
300
304
  <Text>
301
- Phone Number: {`${selectedCountry?.idd?.root} ${inputValue}`}
305
+ Phone Number:{' '}
306
+ {`${selectedCountry?.idd?.root} ${inputValue}`}
302
307
  </Text>
303
308
  <Text>
304
309
  isValid:{' '}
305
- {isValidPhoneNumber(inputValue, selectedCountry) ? 'true' : 'false'}
310
+ {isValidPhoneNumber(inputValue, selectedCountry)
311
+ ? 'true'
312
+ : 'false'}
306
313
  </Text>
307
314
  </View>
308
315
  </View>
@@ -317,8 +324,8 @@ export default function App() {
317
324
  - ### Typescript + useRef + defaultValue
318
325
 
319
326
  ```tsx
320
- import React, {useRef} from 'react';
321
- import {View, Text} from 'react-native';
327
+ import React, { useRef } from 'react';
328
+ import { View, Text } from 'react-native';
322
329
  import PhoneInput, {
323
330
  ICountry,
324
331
  IPhoneInputRef,
@@ -330,12 +337,12 @@ export default function App() {
330
337
  function onSubmitRef() {
331
338
  Alert.alert(
332
339
  'Intermediate Result',
333
- `Country: ${inputRef.current?.selectedCountry?.translations?.eng?.common} \nPhone Number: ${inputRef.current?.fullPhoneNumber} \nisValid: ${inputRef.current?.isValid}`,
340
+ `Country: ${inputRef.current?.selectedCountry?.translations?.eng?.common} \nPhone Number: ${inputRef.current?.fullPhoneNumber} \nisValid: ${inputRef.current?.isValid}`
334
341
  );
335
342
  }
336
343
 
337
344
  return (
338
- <View style={{width: '100%', flex: 1, padding: 24}}>
345
+ <View style={{ width: '100%', flex: 1, padding: 24 }}>
339
346
  <PhoneInput ref={phoneInputRef} defaultValue="+12505550199" />
340
347
  <TouchableOpacity
341
348
  style={{
@@ -345,14 +352,16 @@ export default function App() {
345
352
  borderRadius: 4,
346
353
  marginTop: 10,
347
354
  }}
348
- onPress={onSubmit}>
355
+ onPress={onSubmit}
356
+ >
349
357
  <Text
350
358
  style={{
351
359
  color: '#F3F3F3',
352
360
  textAlign: 'center',
353
361
  fontSize: 16,
354
362
  fontWeight: 'bold',
355
- }}>
363
+ }}
364
+ >
356
365
  Submit
357
366
  </Text>
358
367
  </TouchableOpacity>
@@ -368,22 +377,22 @@ export default function App() {
368
377
  - ### React-Hook-Form + Typescript + defaultValue
369
378
 
370
379
  ```tsx
371
- import React, {useState, useEffect} from 'react';
372
- import {View, Text, TouchableOpacity, Alert} from 'react-native';
380
+ import React, { useState, useEffect } from 'react';
381
+ import { View, Text, TouchableOpacity, Alert } from 'react-native';
373
382
  import PhoneInput, {
374
383
  ICountry,
375
384
  isValidPhoneNumber,
376
385
  } from 'react-native-international-phone-number';
377
- import {Controller, FieldValues} from 'react-hook-form';
386
+ import { Controller, FieldValues } from 'react-hook-form';
378
387
 
379
388
  interface FormProps extends FieldValues {
380
389
  phoneNumber: string;
381
390
  }
382
391
 
383
392
  export default function App() {
384
- const [selectedCountry, setSelectedCountry] = useState<undefined | ICountry>(
385
- undefined,
386
- );
393
+ const [selectedCountry, setSelectedCountry] = useState<
394
+ undefined | ICountry
395
+ >(undefined);
387
396
 
388
397
  function handleSelectedCountry(country: ICountry) {
389
398
  setSelectedCountry(country);
@@ -393,21 +402,21 @@ export default function App() {
393
402
  const phoneNumber = `${selectedCountry?.idd?.root} ${form.phoneNumber}`;
394
403
  const isValid = isValidPhoneNumber(
395
404
  form.phoneNumber,
396
- selectedCountry as ICountry,
405
+ selectedCountry as ICountry
397
406
  );
398
407
 
399
408
  Alert.alert(
400
409
  'Advanced Result',
401
- `Country: ${selectedCountry?.translations?.eng?.common} \nPhone Number: ${phoneNumber} \nisValid: ${isValid}`,
410
+ `Country: ${selectedCountry?.translations?.eng?.common} \nPhone Number: ${phoneNumber} \nisValid: ${isValid}`
402
411
  );
403
412
  }
404
413
 
405
414
  return (
406
- <View style={{width: '100%', flex: 1, padding: 24}}>
415
+ <View style={{ width: '100%', flex: 1, padding: 24 }}>
407
416
  <Controller
408
417
  name="phoneNumber"
409
418
  control={control}
410
- render={({field: {onChange, value}}) => (
419
+ render={({ field: { onChange, value } }) => (
411
420
  <PhoneInput
412
421
  defaultValue="+12505550199"
413
422
  value={value}
@@ -424,14 +433,16 @@ export default function App() {
424
433
  backgroundColor: '#2196F3',
425
434
  borderRadius: 4,
426
435
  }}
427
- onPress={handleSubmit(onSubmit)}>
436
+ onPress={handleSubmit(onSubmit)}
437
+ >
428
438
  <Text
429
439
  style={{
430
440
  color: '#F3F3F3',
431
441
  textAlign: 'center',
432
442
  fontSize: 16,
433
443
  fontWeight: 'bold',
434
- }}>
444
+ }}
445
+ >
435
446
  Submit
436
447
  </Text>
437
448
  </TouchableOpacity>
@@ -495,51 +506,56 @@ export default function App() {
495
506
 
496
507
  ## Component Props ([PhoneInputProps](lib/interfaces/phoneInputProps.ts))
497
508
 
498
- | Prop | Type | Description |
499
- | -------------------------------------- | ------------------------------- | ------------------------------------------------------------------------- |
500
- | `theme` | `ITheme` | Theme configuration for the component |
501
- | `language` | `ILanguage` | Language for country names and UI |
502
- | `defaultValue` | `string` | Default phone number value (format: `+(country code)(area code)(number)`) |
503
- | `value` | `string` | Controlled phone number value |
504
- | `onChangePhoneNumber` | `(phoneNumber: string) => void` | Callback when phone number changes |
505
- | `defaultCountry` | `ICountryCca2` | Default selected country (ISO 3166-1 alpha-2) |
506
- | `selectedCountry` | `ICountry` | Currently selected country object |
507
- | `onChangeSelectedCountry` | `(country: ICountry) => void` | Callback when country selection changes |
508
- | `placeholder` | `string` | Placeholder text for phone input |
509
- | `phoneInputPlaceholderTextColor` | `string` | Color of placeholder text |
510
- | `phoneInputSelectionColor` | `string` | Color of text selection |
511
- | `phoneInputStyles` | `IPhoneInputStyles` | Custom styles for phone input component |
512
- | `modalStyles` | `ICountrySelectStyles` | Custom styles for country selection modal |
513
- | `disabled` | `boolean` | Disable the entire phone input |
514
- | `modalDisabled` | `boolean` | Disable only the country selection modal |
515
- | `customMask` | `string` | Custom phone number mask (format like this: `(###) ###-####`) |
516
- | `visibleCountries` | `ICountryCca2[]` | Array of country codes to show in modal |
517
- | `hiddenCountries` | `ICountryCca2[]` | Array of country codes to hide from modal |
518
- | `popularCountries` | `ICountryCca2[]` | Array of country codes to show in popular section |
519
- | `customCaret` | `() => ReactNode` | Custom dropdown arrow component |
520
- | `rtl` | `boolean` | Enable right-to-left layout |
521
- | `isFullScreen` | `boolean` | Show modal in full screen mode |
522
- | `modalType` | `'bottomSheet' \| 'popup'` | Type of modal presentation |
523
- | `modalDragHandleIndicatorComponent` | `() => ReactNode` | Custom drag handle indicator component |
524
- | `modalSearchInputPlaceholderTextColor` | `string` | Color of modal search placeholder text |
525
- | `modalSearchInputPlaceholder` | `string` | Placeholder text for modal search input |
526
- | `modalSearchInputSelectionColor` | `string` | Color of modal search text selection |
527
- | `modalPopularCountriesTitle` | `string` | Title for popular countries section |
528
- | `modalAllCountriesTitle` | `string` | Title for all countries section |
529
- | `modalSectionTitleComponent` | `() => ReactNode` | Custom section title component |
530
- | `modalCountryItemComponent` | `() => ReactNode` | Custom country item component |
531
- | `modalCloseButtonComponent` | `() => ReactNode` | Custom close button component |
532
- | `modalSectionTitleDisabled` | `boolean` | Disable section titles in modal |
533
- | `modalNotFoundCountryMessage` | `string` | Message when no countries found |
534
- | `disabledModalBackdropPress` | `boolean` | Disable modal close on backdrop press |
535
- | `removedModalBackdrop` | `boolean` | Remove modal backdrop entirely |
536
- | `onModalBackdropPress` | `() => void` | Callback when modal backdrop is pressed |
537
- | `onModalRequestClose` | `() => void` | Callback when modal close is requested |
538
- | `showModalAlphabetFilter` | `boolean` | Show alphabet filter in modal |
539
- | `showModalSearchInput` | `boolean` | Show search input in modal |
540
- | `showModalCloseButton` | `boolean` | Show close button in modal |
541
- | `showModalScrollIndicator` | `boolean` | Show scroll indicator in modal |
542
- | `ref` | `Ref<IPhoneInputRef>` | Ref to access component methods |
509
+ | Prop | Type | Description |
510
+ | -------------------------------------- | ---------------------------------- | ------------------------------------------------------------------------- |
511
+ | `theme` | `ITheme` | Theme configuration for the component |
512
+ | `language` | `ILanguage` | Language for country names and UI |
513
+ | `defaultValue` | `string` | Default phone number value (format: `+(country code)(area code)(number)`) |
514
+ | `value` | `string` | Controlled phone number value |
515
+ | `onChangePhoneNumber` | `(phoneNumber: string) => void` | Callback when phone number changes |
516
+ | `defaultCountry` | `ICountryCca2` | Default selected country (ISO 3166-1 alpha-2) |
517
+ | `selectedCountry` | `ICountry` | Currently selected country object |
518
+ | `onChangeSelectedCountry` | `(country: ICountry) => void` | Callback when country selection changes |
519
+ | `placeholder` | `string` | Placeholder text for phone input |
520
+ | `phoneInputPlaceholderTextColor` | `string` | Color of placeholder text |
521
+ | `phoneInputSelectionColor` | `string` | Color of text selection |
522
+ | `phoneInputStyles` | `IPhoneInputStyles` | Custom styles for phone input component |
523
+ | `modalStyles` | `ICountrySelectStyles` | Custom styles for country selection modal |
524
+ | `disabled` | `boolean` | Disable the entire phone input |
525
+ | `modalDisabled` | `boolean` | Disable only the country selection modal |
526
+ | `customMask` | `string` | Custom phone number mask (format like this: `(###) ###-####`) |
527
+ | `visibleCountries` | `ICountryCca2[]` | Array of country codes to show in modal |
528
+ | `hiddenCountries` | `ICountryCca2[]` | Array of country codes to hide from modal |
529
+ | `popularCountries` | `ICountryCca2[]` | Array of country codes to show in popular section |
530
+ | `customCaret` | `() => ReactNode` | Custom dropdown arrow component |
531
+ | `customFlag` | `(country: ICountry) => ReactNode` | Custom flag component to replace default flag emoji |
532
+ | `rtl` | `boolean` | Enable right-to-left layout |
533
+ | `isFullScreen` | `boolean` | Show modal in full screen mode |
534
+ | `modalType` | `'bottomSheet' \| 'popup'` | Type of modal presentation |
535
+ | `modalDragHandleIndicatorComponent` | `() => ReactNode` | Custom drag handle indicator component |
536
+ | `modalSearchInputPlaceholderTextColor` | `string` | Color of modal search placeholder text |
537
+ | `modalSearchInputPlaceholder` | `string` | Placeholder text for modal search input |
538
+ | `modalSearchInputSelectionColor` | `string` | Color of modal search text selection |
539
+ | `modalPopularCountriesTitle` | `string` | Title for popular countries section |
540
+ | `modalAllCountriesTitle` | `string` | Title for all countries section |
541
+ | `modalSectionTitleComponent` | `() => ReactNode` | Custom section title component |
542
+ | `modalCountryItemComponent` | `() => ReactNode` | Custom country item component |
543
+ | `modalCloseButtonComponent` | `() => ReactNode` | Custom close button component |
544
+ | `modalSectionTitleDisabled` | `boolean` | Disable section titles in modal |
545
+ | `modalNotFoundCountryMessage` | `string` | Message when no countries found |
546
+ | `disabledModalBackdropPress` | `boolean` | Disable modal close on backdrop press |
547
+ | `removedModalBackdrop` | `boolean` | Remove modal backdrop entirely |
548
+ | `onModalBackdropPress` | `() => void` | Callback when modal backdrop is pressed |
549
+ | `onModalRequestClose` | `() => void` | Callback when modal close is requested |
550
+ | `showModalAlphabetFilter` | `boolean` | Show alphabet filter in modal |
551
+ | `showModalSearchInput` | `boolean` | Show search input in modal |
552
+ | `showModalCloseButton` | `boolean` | Show close button in modal |
553
+ | `showModalScrollIndicator` | `boolean` | Show scroll indicator in modal |
554
+ | `allowFontScaling` | `boolean` | Allow font scaling based on device settings (default: `true`) |
555
+ | `initialBottomsheetHeight` | `number \| string` | Initial height of the bottom sheet modal |
556
+ | `minBottomsheetHeight` | `number \| string` | Minimum height of the bottom sheet modal |
557
+ | `maxBottomsheetHeight` | `number \| string` | Maximum height of the bottom sheet modal |
558
+ | `ref` | `Ref<IPhoneInputRef>` | Ref to access component methods |
543
559
 
544
560
  <br>
545
561
 
@@ -605,15 +621,25 @@ When utilizing this package, you may need to target the PhoneInput component in
605
621
 
606
622
  ```jsx
607
623
  const phoneInput = getByTestId('countryPickerPhoneInput');
608
- const flagContainerButton = getByTestId('countryPickerFlagContainerButton');
609
- const countrySelectModalContainer = getByTestId('countrySelectContainer');
624
+ const flagContainerButton = getByTestId(
625
+ 'countryPickerFlagContainerButton'
626
+ );
627
+ const countrySelectModalContainer = getByTestId(
628
+ 'countrySelectContainer'
629
+ );
610
630
  const countrySelectModalContent = getByTestId('countrySelectContent');
611
631
  const countrySelectBackdrop = getByTestId('countrySelectBackdrop');
612
632
  const countrySelectList = getByTestId('countrySelectList');
613
- const countrySelectSearchInput = getByTestId('countrySelectSearchInput');
633
+ const countrySelectSearchInput = getByTestId(
634
+ 'countrySelectSearchInput'
635
+ );
614
636
  const countrySelectItem = getByTestId('countrySelectItem');
615
- const countrySelectCloseButton = getByTestId('countrySelectCloseButton');
616
- const countrySelectAlphabetFilter = getByTestId('countrySelectAlphabetFilter');
637
+ const countrySelectCloseButton = getByTestId(
638
+ 'countrySelectCloseButton'
639
+ );
640
+ const countrySelectAlphabetFilter = getByTestId(
641
+ 'countrySelectAlphabetFilter'
642
+ );
617
643
  ```
618
644
 
619
645
  <br>
package/lib/index.js CHANGED
@@ -1,7 +1,18 @@
1
1
  /* eslint-disable react-native/no-inline-styles */
2
2
  /* eslint-disable react-hooks/exhaustive-deps */
3
- import React, {useEffect, useState, useRef, forwardRef} from 'react';
4
- import {View, Text, TouchableOpacity, TextInput, Platform} from 'react-native';
3
+ import React, {
4
+ useEffect,
5
+ useState,
6
+ useRef,
7
+ forwardRef,
8
+ } from 'react';
9
+ import {
10
+ View,
11
+ Text,
12
+ TouchableOpacity,
13
+ TextInput,
14
+ Platform,
15
+ } from 'react-native';
5
16
  import CountrySelect, {
6
17
  getAllCountries,
7
18
  getCountriesByName,
@@ -14,7 +25,7 @@ import parsePhoneNumber, {
14
25
  } from 'libphonenumber-js';
15
26
 
16
27
  import getCountryByPhoneNumber from './utils/getCountryByPhoneNumber';
17
- import {getPhoneNumberLength} from './utils/getPhoneNumberLength';
28
+ import { getPhoneNumberLength } from './utils/getPhoneNumberLength';
18
29
  import isValidPhoneNumber from './utils/isValidPhoneNumber';
19
30
  import {
20
31
  getCountriesButtonAccessibilityHint,
@@ -58,6 +69,9 @@ const PhoneInput = forwardRef(
58
69
  rtl,
59
70
  isFullScreen = false,
60
71
  modalType = Platform.OS === 'web' ? 'popup' : 'bottomSheet',
72
+ minBottomsheetHeight,
73
+ maxBottomsheetHeight,
74
+ initialBottomsheetHeight,
61
75
  modalDragHandleIndicatorComponent,
62
76
  modalSearchInputPlaceholderTextColor,
63
77
  modalSearchInputPlaceholder,
@@ -77,6 +91,8 @@ const PhoneInput = forwardRef(
77
91
  showModalSearchInput,
78
92
  showModalCloseButton,
79
93
  showModalScrollIndicator,
94
+ allowFontScaling = true,
95
+ customFlag,
80
96
  accessibilityLabelPhoneInput,
81
97
  accessibilityHintPhoneInput,
82
98
  accessibilityLabelCountriesButton,
@@ -97,7 +113,7 @@ const PhoneInput = forwardRef(
97
113
  accessibilityHintAlphabetLetter,
98
114
  ...rest
99
115
  },
100
- ref,
116
+ ref
101
117
  ) => {
102
118
  const [show, setShow] = useState(false);
103
119
  const [defaultCca2, setDefaultCca2] = useState('');
@@ -112,11 +128,27 @@ const PhoneInput = forwardRef(
112
128
  focus: () => textInputRef.current?.focus(),
113
129
  blur: () => textInputRef.current?.blur(),
114
130
  clear: () => textInputRef.current?.clear(),
131
+ isFocused: () => textInputRef.current?.isFocused(),
132
+ setNativeProps: (nativeProps) =>
133
+ textInputRef.current?.setNativeProps(nativeProps),
134
+ measure: (callback) => textInputRef.current?.measure(callback),
135
+ measureInWindow: (callback) =>
136
+ textInputRef.current?.measureInWindow(callback),
137
+ measureLayout: (relativeToNativeNode, onSuccess, onFail) =>
138
+ textInputRef.current?.measureLayout(
139
+ relativeToNativeNode,
140
+ onSuccess,
141
+ onFail
142
+ ),
115
143
  getValue: () => inputValue,
116
144
  value: inputValue,
117
- getFullPhoneNumber: () => `${countryValue?.idd?.root} ${inputValue}`,
145
+ getFullPhoneNumber: () =>
146
+ `${countryValue?.idd?.root} ${inputValue}`,
118
147
  fullPhoneNumber: `${countryValue?.idd?.root} ${inputValue}`,
119
- phoneNumberLength: getPhoneNumberLength(countryValue, inputValue),
148
+ phoneNumberLength: getPhoneNumberLength(
149
+ countryValue,
150
+ inputValue
151
+ ),
120
152
  getSelectedCountry: () => countryValue,
121
153
  selectedCountry: countryValue,
122
154
  isValid: isValidPhoneNumber(inputValue, selectedCountry),
@@ -143,6 +175,9 @@ const PhoneInput = forwardRef(
143
175
  rtl,
144
176
  isFullScreen,
145
177
  modalType,
178
+ minBottomsheetHeight,
179
+ maxBottomsheetHeight,
180
+ initialBottomsheetHeight,
146
181
  modalSearchInputPlaceholderTextColor,
147
182
  modalSearchInputPlaceholder,
148
183
  modalSearchInputSelectionColor,
@@ -160,6 +195,7 @@ const PhoneInput = forwardRef(
160
195
  showModalSearchInput,
161
196
  showModalCloseButton,
162
197
  showModalScrollIndicator,
198
+ customFlag,
163
199
  accessibilityLabelPhoneInput,
164
200
  accessibilityHintPhoneInput,
165
201
  accessibilityLabelCountriesButton,
@@ -174,6 +210,7 @@ const PhoneInput = forwardRef(
174
210
  accessibilityHintCountriesList,
175
211
  accessibilityLabelCountryItem,
176
212
  accessibilityHintCountryItem,
213
+ allowFontScaling,
177
214
  ...rest,
178
215
  },
179
216
  };
@@ -186,7 +223,8 @@ const PhoneInput = forwardRef(
186
223
  value: phoneNumber?.replace(/\D/g, ''),
187
224
  getValueFormatted: () => phoneNumber,
188
225
  valueFormatted: phoneNumber,
189
- getFullPhoneNumber: () => `${country?.idd?.root} ${phoneNumber}`,
226
+ getFullPhoneNumber: () =>
227
+ `${country?.idd?.root} ${phoneNumber}`,
190
228
  fullPhoneNumber: `${country?.idd?.root} ${phoneNumber}`,
191
229
  getSelectedCountry: () => country,
192
230
  selectedCountry: country,
@@ -249,14 +287,16 @@ const PhoneInput = forwardRef(
249
287
  const metadata = new Metadata();
250
288
  metadata.selectNumberingPlan(countryValue?.cca2);
251
289
 
252
- const possibleLengths = countryValue ? metadata.possibleLengths() : [];
290
+ const possibleLengths = countryValue
291
+ ? metadata.possibleLengths()
292
+ : [];
253
293
 
254
294
  let validCallingCode = callingCode
255
295
  ? callingCode
256
296
  : countryValue?.idd?.root;
257
297
 
258
298
  const res = formatIncompletePhoneNumber(
259
- `${validCallingCode}${phoneNumber}`,
299
+ `${validCallingCode}${phoneNumber}`
260
300
  );
261
301
 
262
302
  formattedNumber = res;
@@ -264,8 +304,14 @@ const PhoneInput = forwardRef(
264
304
  if (res.startsWith(0)) {
265
305
  formattedNumber = parsePhoneNumber(res)?.formatNational();
266
306
  } else {
267
- if (validCallingCode && res && res.startsWith(validCallingCode)) {
268
- formattedNumber = res.substring(validCallingCode.length).trim();
307
+ if (
308
+ validCallingCode &&
309
+ res &&
310
+ res.startsWith(validCallingCode)
311
+ ) {
312
+ formattedNumber = res
313
+ .substring(validCallingCode.length)
314
+ .trim();
269
315
  }
270
316
  }
271
317
 
@@ -273,7 +319,9 @@ const PhoneInput = forwardRef(
273
319
  ? possibleLengths.slice(-1)[0] + 1
274
320
  : possibleLengths.slice(-1)[0];
275
321
 
276
- if (formattedNumber?.replace(/\D/g, '')?.length > possibleLength) {
322
+ if (
323
+ formattedNumber?.replace(/\D/g, '')?.length > possibleLength
324
+ ) {
277
325
  return;
278
326
  }
279
327
 
@@ -299,7 +347,7 @@ const PhoneInput = forwardRef(
299
347
 
300
348
  onChangeText(
301
349
  phoneNumber.replace(matchingCountry?.idd?.root, ''),
302
- null,
350
+ null
303
351
  );
304
352
  }
305
353
 
@@ -357,7 +405,11 @@ const PhoneInput = forwardRef(
357
405
  }, [defaultValue]);
358
406
 
359
407
  useEffect(() => {
360
- if (defaultValue && countryValue && countryValue.cca2 === defaultCca2) {
408
+ if (
409
+ defaultValue &&
410
+ countryValue &&
411
+ countryValue.cca2 === defaultCca2
412
+ ) {
361
413
  const callingCode = countryValue?.idd?.root;
362
414
 
363
415
  let phoneNumber = defaultValue;
@@ -379,9 +431,16 @@ const PhoneInput = forwardRef(
379
431
  // Create a separate constant for each part of the component
380
432
  const touchableStart = (
381
433
  <>
382
- <Text style={getFlagStyle(phoneInputStyles?.flag)}>
383
- {countryValue?.flag || countryValue?.cca2}
384
- </Text>
434
+ {(customFlag &&
435
+ countryValue &&
436
+ customFlag(countryValue)) || (
437
+ <Text
438
+ style={getFlagStyle(phoneInputStyles?.flag)}
439
+ allowFontScaling={allowFontScaling}
440
+ >
441
+ {countryValue?.flag || countryValue?.cca2}
442
+ </Text>
443
+ )}
385
444
  {(customCaret && customCaret()) || (
386
445
  <View style={phoneInputStyles?.caret}>
387
446
  <View
@@ -389,8 +448,14 @@ const PhoneInput = forwardRef(
389
448
  flexDirection: 'row',
390
449
  justifyContent: 'center',
391
450
  paddingTop: 4,
392
- }}>
393
- <View style={getCaretStyle(theme, phoneInputStyles?.caret)} />
451
+ }}
452
+ >
453
+ <View
454
+ style={getCaretStyle(
455
+ theme,
456
+ phoneInputStyles?.caret
457
+ )}
458
+ />
394
459
  </View>
395
460
  </View>
396
461
  )}
@@ -398,11 +463,19 @@ const PhoneInput = forwardRef(
398
463
  );
399
464
 
400
465
  const touchableMiddle = (
401
- <View style={getDividerStyle(theme, phoneInputStyles?.divider)} />
466
+ <View
467
+ style={getDividerStyle(theme, phoneInputStyles?.divider)}
468
+ />
402
469
  );
403
470
 
404
471
  const touchableEnd = (
405
- <Text style={getFlagTextStyle(theme, phoneInputStyles?.callingCode)}>
472
+ <Text
473
+ style={getFlagTextStyle(
474
+ theme,
475
+ phoneInputStyles?.callingCode
476
+ )}
477
+ allowFontScaling={allowFontScaling}
478
+ >
406
479
  {countryValue?.idd?.root}
407
480
  </Text>
408
481
  );
@@ -420,8 +493,14 @@ const PhoneInput = forwardRef(
420
493
  getCountriesButtonAccessibilityHint(language || 'eng')
421
494
  }
422
495
  activeOpacity={disabled || modalDisabled ? 1 : 0.6}
423
- onPress={() => (disabled || modalDisabled ? null : setShow(true))}
424
- style={getFlagContainerStyle(theme, phoneInputStyles?.flagContainer)}>
496
+ onPress={() =>
497
+ disabled || modalDisabled ? null : setShow(true)
498
+ }
499
+ style={getFlagContainerStyle(
500
+ theme,
501
+ phoneInputStyles?.flagContainer
502
+ )}
503
+ >
425
504
  {/* LTR Display */}
426
505
  {!rtl && touchableStart}
427
506
  {!rtl && touchableMiddle}
@@ -448,7 +527,9 @@ const PhoneInput = forwardRef(
448
527
  }
449
528
  selectionColor={
450
529
  phoneInputSelectionColor ||
451
- (theme === 'dark' ? 'rgba(255,255,255, .4)' : 'rgba(0 ,0 ,0 , .4)')
530
+ (theme === 'dark'
531
+ ? 'rgba(255,255,255, .4)'
532
+ : 'rgba(0 ,0 ,0 , .4)')
452
533
  }
453
534
  editable={!disabled}
454
535
  value={inputValue}
@@ -465,6 +546,7 @@ const PhoneInput = forwardRef(
465
546
  accessibilityHintPhoneInput ||
466
547
  getPhoneNumberInputAccessibilityHint(language || 'eng')
467
548
  }
549
+ allowFontScaling={allowFontScaling}
468
550
  {...rest}
469
551
  />
470
552
  );
@@ -475,8 +557,9 @@ const PhoneInput = forwardRef(
475
557
  style={getContainerStyle(
476
558
  theme,
477
559
  phoneInputStyles?.container,
478
- disabled,
479
- )}>
560
+ disabled
561
+ )}
562
+ >
480
563
  {/* LTR Display */}
481
564
  {!rtl && touchablePart}
482
565
  {!rtl && inputPart}
@@ -504,11 +587,18 @@ const PhoneInput = forwardRef(
504
587
  }
505
588
  visibleCountries={visibleCountries}
506
589
  popularCountries={popularCountries}
507
- onBackdropPress={() => onModalBackdropPress || setShow(false)}
508
- onRequestClose={() => onModalRequestClose || setShow(false)}
590
+ onBackdropPress={() =>
591
+ onModalBackdropPress || setShow(false)
592
+ }
593
+ onRequestClose={() =>
594
+ onModalRequestClose || setShow(false)
595
+ }
509
596
  countrySelectStyle={modalStyles}
510
597
  isFullScreen={isFullScreen}
511
598
  modalType={modalType}
599
+ minBottomsheetHeight={minBottomsheetHeight}
600
+ maxBottomsheetHeight={maxBottomsheetHeight}
601
+ initialBottomsheetHeight={initialBottomsheetHeight}
512
602
  allCountriesTitle={modalAllCountriesTitle}
513
603
  popularCountriesTitle={modalPopularCountriesTitle}
514
604
  sectionTitleComponent={
@@ -527,18 +617,35 @@ const PhoneInput = forwardRef(
527
617
  showSearchInput={showModalSearchInput}
528
618
  showAlphabetFilter={showModalAlphabetFilter}
529
619
  countryNotFoundMessage={modalNotFoundCountryMessage}
530
- accessibilityLabelBackdrop={accessibilityLabelBackdrop}
620
+ customFlag={customFlag}
621
+ accessibilityLabelBackdrop={
622
+ accessibilityLabelBackdrop
623
+ }
531
624
  accessibilityHintBackdrop={accessibilityHintBackdrop}
532
- accessibilityLabelCloseButton={accessibilityLabelCloseButton}
533
- accessibilityHintCloseButton={accessibilityHintCloseButton}
534
- accessibilityLabelSearchInput={accessibilityLabelSearchInput}
535
- accessibilityHintSearchInput={accessibilityHintSearchInput}
625
+ accessibilityLabelCloseButton={
626
+ accessibilityLabelCloseButton
627
+ }
628
+ accessibilityHintCloseButton={
629
+ accessibilityHintCloseButton
630
+ }
631
+ accessibilityLabelSearchInput={
632
+ accessibilityLabelSearchInput
633
+ }
634
+ accessibilityHintSearchInput={
635
+ accessibilityHintSearchInput
636
+ }
536
637
  accessibilityLabelCountriesList={
537
638
  accessibilityLabelCountriesList
538
639
  }
539
- accessibilityHintCountriesList={accessibilityHintCountriesList}
540
- accessibilityLabelCountryItem={accessibilityLabelCountryItem}
541
- accessibilityHintCountryItem={accessibilityHintCountryItem}
640
+ accessibilityHintCountriesList={
641
+ accessibilityHintCountriesList
642
+ }
643
+ accessibilityLabelCountryItem={
644
+ accessibilityLabelCountryItem
645
+ }
646
+ accessibilityHintCountryItem={
647
+ accessibilityHintCountryItem
648
+ }
542
649
  accessibilityLabelAlphabetFilter={
543
650
  accessibilityLabelAlphabetFilter
544
651
  }
@@ -551,13 +658,14 @@ const PhoneInput = forwardRef(
551
658
  accessibilityHintAlphabetLetter={
552
659
  accessibilityHintAlphabetLetter
553
660
  }
661
+ allowFontScaling={allowFontScaling}
554
662
  />
555
663
  </>
556
664
  ) : null}
557
665
  </>
558
666
  );
559
667
  }
560
- },
668
+ }
561
669
  );
562
670
 
563
671
  export default PhoneInput;
@@ -1,15 +1,17 @@
1
- import {Ref, ReactNode} from 'react';
2
- import {TextInputProps} from 'react-native';
1
+ import * as React from 'react';
2
+ import { Ref } from 'react';
3
+ import { TextInputProps } from 'react-native';
3
4
  import {
4
5
  ICountry,
5
6
  ICountryCca2,
6
7
  ICountrySelectLanguages,
7
8
  ICountrySelectStyle,
9
+ ISectionTitle,
8
10
  } from 'react-native-country-select';
9
11
 
10
- import {ITheme} from './theme';
11
- import {IPhoneInputStyles} from './phoneInputStyles';
12
- import {IPhoneInputRef} from './phoneInputRef';
12
+ import { ITheme } from './theme';
13
+ import { IPhoneInputStyles } from './phoneInputStyles';
14
+ import { IPhoneInputRef } from './phoneInputRef';
13
15
 
14
16
  interface BasePhoneInput extends TextInputProps {
15
17
  theme?: ITheme;
@@ -27,25 +29,34 @@ interface BasePhoneInput extends TextInputProps {
27
29
  visibleCountries?: Array<ICountryCca2>;
28
30
  hiddenCountries?: Array<ICountryCca2>;
29
31
  popularCountries?: Array<ICountryCca2>;
30
- customCaret?: () => ReactNode;
32
+ customCaret?: () => React.ReactElement;
31
33
  rtl?: boolean;
34
+ allowFontScaling?: boolean;
32
35
  isFullScreen?: boolean;
33
36
  modalType?: 'bottomSheet' | 'popup';
34
- modalDragHandleIndicatorComponent?: () => ReactNode;
37
+ minBottomsheetHeight?: number | string;
38
+ maxBottomsheetHeight?: number | string;
39
+ initialBottomsheetHeight?: number | string;
40
+ modalDragHandleIndicatorComponent?: () => React.ReactElement;
35
41
  modalSearchInputPlaceholderTextColor?: string;
36
42
  modalSearchInputPlaceholder?: string;
37
43
  modalSearchInputSelectionColor?: string;
38
44
  modalPopularCountriesTitle?: string;
39
45
  modalAllCountriesTitle?: string;
40
- modalSectionTitleComponent?: () => ReactNode;
41
- modalCountryItemComponent?: () => ReactNode;
42
- modalCloseButtonComponent?: () => ReactNode;
46
+ modalSectionTitleComponent?: (
47
+ item: ISectionTitle
48
+ ) => React.ReactElement;
49
+ modalCountryItemComponent?: (item: ICountry) => React.ReactElement;
50
+ modalCloseButtonComponent?: () => React.ReactElement;
43
51
  modalSectionTitleDisabled?: boolean;
44
52
  modalNotFoundCountryMessage?: string;
45
53
  disabledModalBackdropPress?: boolean;
46
54
  removedModalBackdrop?: boolean;
47
55
  onModalBackdropPress?: () => void;
48
56
  onModalRequestClose?: () => void;
57
+ customFlag?: (
58
+ country: ICountry
59
+ ) => React.ReactElement | null | undefined;
49
60
  showModalAlphabetFilter?: boolean;
50
61
  showModalSearchInput?: boolean;
51
62
  showModalCloseButton?: boolean;
@@ -1,12 +1,45 @@
1
- import {TextInput} from 'react-native';
2
- import {ICountry} from 'react-native-country-select';
1
+ import { TextInput } from 'react-native';
2
+ import { ICountry } from 'react-native-country-select';
3
3
 
4
- import {PhoneInputProps} from './phoneInputProps';
4
+ import { PhoneInputProps } from './phoneInputProps';
5
5
 
6
6
  export interface IPhoneInputRef extends TextInput {
7
7
  props: PhoneInputProps;
8
+ // Métodos nativos do TextInput
8
9
  onFocus: () => void;
9
10
  focus: () => void;
11
+ blur: () => void;
12
+ clear: () => void;
13
+ isFocused: () => boolean;
14
+ setNativeProps: (nativeProps: object) => void;
15
+ measure: (
16
+ callback: (
17
+ x: number,
18
+ y: number,
19
+ width: number,
20
+ height: number,
21
+ pageX: number,
22
+ pageY: number
23
+ ) => void
24
+ ) => void;
25
+ measureInWindow: (
26
+ callback: (
27
+ x: number,
28
+ y: number,
29
+ width: number,
30
+ height: number
31
+ ) => void
32
+ ) => void;
33
+ measureLayout: (
34
+ relativeToNativeNode: number,
35
+ onSuccess: (
36
+ x: number,
37
+ y: number,
38
+ width: number,
39
+ height: number
40
+ ) => void,
41
+ onFail: () => void
42
+ ) => void;
10
43
  getValue: () => string;
11
44
  value: string;
12
45
  getValueFormatted: () => string;
package/lib/styles.js CHANGED
@@ -1,4 +1,4 @@
1
- import {Platform, StyleSheet} from 'react-native';
1
+ import { Platform, StyleSheet } from 'react-native';
2
2
 
3
3
  const containerBase = {
4
4
  flexDirection: 'row',
@@ -8,7 +8,7 @@ const containerBase = {
8
8
  borderStyle: 'solid',
9
9
  borderRadius: 8,
10
10
  width: '100%',
11
- height: 48,
11
+ minHeight: 48,
12
12
  };
13
13
 
14
14
  const flagContainerBase = {
@@ -1,5 +1,3 @@
1
- import {Platform} from 'react-native';
2
-
3
1
  import styles from '../styles';
4
2
 
5
3
  export function getContainerStyle(theme, containerStyle, disabled) {
@@ -41,10 +39,10 @@ export function getCaretStyle(theme, caretStyle) {
41
39
  }
42
40
  : {},
43
41
  caretStyle?.fontSize !== undefined
44
- ? {borderWidth: caretStyle?.fontSize * 0.45}
42
+ ? { borderWidth: caretStyle?.fontSize * 0.45 }
45
43
  : {},
46
44
  caretStyle && caretStyle?.display === 'none'
47
- ? {display: 'none', borderWidth: 0}
45
+ ? { display: 'none', borderWidth: 0 }
48
46
  : {},
49
47
  ];
50
48
  }
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.11.0",
4
+ "version": "0.11.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",
@@ -44,8 +44,8 @@
44
44
  "react-native": "*"
45
45
  },
46
46
  "dependencies": {
47
- "react-native-country-select": "0.3.1",
48
- "libphonenumber-js": "1.12.23"
47
+ "react-native-country-select": "0.3.4",
48
+ "libphonenumber-js": "1.12.25"
49
49
  },
50
50
  "devDependencies": {
51
51
  "metro-react-native-babel-preset": "^0.61.0"