{"_id":"@codehogs/rn-country-phone-codes","name":"@codehogs/rn-country-phone-codes","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@codehogs/rn-country-phone-codes","version":"1.0.0","description":"React Native phone input with country picker and libphonenumber-js validation (iOS, Android, Web)","main":"src/index.js","type":"module","keywords":["react-native","phone","country","libphonenumber","e164","validation","codehogs","intl-phone"],"author":{"name":"CodeHogs"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/codehogs/rn-country-phone-codes.git"},"bugs":{"url":"https://github.com/codehogs/rn-country-phone-codes/issues"},"homepage":"https://github.com/codehogs/rn-country-phone-codes#readme","publishConfig":{"access":"public"},"scripts":{"test":"node src/test-smoke.mjs"},"dependencies":{"libphonenumber-js":"^1.12.40"},"peerDependencies":{"react":">=17.0.0","react-native":">=0.71.0"},"exports":{".":{"import":"./src/index.js","default":"./src/index.js"}},"_id":"@codehogs/rn-country-phone-codes@1.0.0","gitHead":"bf27226212ac992f8100620a190b3f92f806e490","_nodeVersion":"22.17.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-Ox+ODFXLgPyz4zcrRffn8P3ra7eSeCO/6PfiW6z0x5TNzLyUfCxlzTPnl+cz0U+YImReHfR/Dv28zH75aztxPQ==","shasum":"dd10e2608dc8fc87f47abb7330f8dda57b064dc7","tarball":"https://registry.npmjs.org/@codehogs/rn-country-phone-codes/-/rn-country-phone-codes-1.0.0.tgz","fileCount":13,"unpackedSize":34874,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDSHv9JbJtqD8KSsi+5xQshs3tGAyqGTK1jUClfZG0pIAIgRLT60kGl7+8qA+AwtWvviLxeDQePome7Jww9NNkz0y8="}]},"_npmUser":{"name":"codehogs","email":"jananijayasuriya330@gmail.com"},"directories":{},"maintainers":[{"name":"codehogs","email":"jananijayasuriya330@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/rn-country-phone-codes_1.0.0_1774336274588_0.6370823105750414"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-24T07:11:14.434Z","1.0.0":"2026-03-24T07:11:14.752Z","modified":"2026-03-24T07:11:15.037Z"},"maintainers":[{"name":"codehogs","email":"jananijayasuriya330@gmail.com"}],"description":"React Native phone input with country picker and libphonenumber-js validation (iOS, Android, Web)","homepage":"https://github.com/codehogs/rn-country-phone-codes#readme","keywords":["react-native","phone","country","libphonenumber","e164","validation","codehogs","intl-phone"],"repository":{"type":"git","url":"git+https://github.com/codehogs/rn-country-phone-codes.git"},"author":{"name":"CodeHogs"},"bugs":{"url":"https://github.com/codehogs/rn-country-phone-codes/issues"},"license":"MIT","readme":"# @codehogs/rn-country-phone-codes\n\nInternational phone number input for **React Native**: searchable country picker, **per-country validation**, and **E.164** output using [libphonenumber-js](https://www.npmjs.com/package/libphonenumber-js) (same rules engine family as Google’s libphonenumber). Works on **iOS**, **Android**, and **Web** when using React Native for Web.\n\n## Why this library\n\n- **Accurate validation** uses **ISO 3166-1 alpha-2** (`iso2`) and libphonenumber metadata, not dial-code-only regex (important for shared codes like `+1`).\n- **Clear API**: one main component, optional utilities, or headless modal + helpers.\n- **Flexible UI**: style props and render props for custom design systems.\n\n## Requirements\n\n| Dependency | Version |\n|------------|---------|\n| `react` | ≥ 17 |\n| `react-native` | ≥ 0.71 |\n\n`libphonenumber-js` is installed **automatically** as a dependency of this package (you do not need to add it separately).\n\n## Installation\n\n```bash\nnpm install @codehogs/rn-country-phone-codes\n```\n\n```bash\nyarn add @codehogs/rn-country-phone-codes\n```\n\n```bash\npnpm add @codehogs/rn-country-phone-codes\n```\n\n## Quick start\n\n```javascript\nimport React, { useState } from 'react';\nimport { View } from 'react-native';\nimport { PhoneNumberInput } from '@codehogs/rn-country-phone-codes';\n\nexport default function SignUpPhone() {\n  const [phone, setPhone] = useState('');\n  const [valid, setValid] = useState(false);\n\n  return (\n    <View style={{ padding: 16 }}>\n      <PhoneNumberInput\n        defaultCountry=\"LK\"\n        value={phone}\n        onChangeText={setPhone}\n        onValidChange={setValid}\n        onParsedChange={(result) => {\n          if (result?.e164Number) console.log('E.164:', result.e164Number);\n        }}\n        placeholder=\"Mobile number\"\n      />\n    </View>\n  );\n}\n```\n\nThe user enters the **national** number (no `+`); the country is chosen with the flag/dial code control. Pasting a full international number starting with `+` is supported and will update the country when possible.\n\n## Exports\n\n### Components\n\n| Export | Description |\n|--------|-------------|\n| `PhoneNumberInput` | Country selector + phone field + validation callbacks |\n| `CountryPickerModal` | Searchable country list in a modal (use alone if you build your own field) |\n| `CountryListItem` | Default row for the list |\n\n### Data\n\n| Export | Description |\n|--------|-------------|\n| `COUNTRIES` / `COUNTRY_LIST` | All regions from libphonenumber (`iso2`, `dialCode`, `country`, `flag`) |\n| `getSortedCountries(preferredIso2?)` | Same list sorted, optionally pinning one `iso2` first |\n\n### Phone helpers\n\n| Function | Description |\n|----------|-------------|\n| `validatePhoneNumber({ country, phoneNumber })` | `{ isValid, e164Number, nationalNumber, countryIso2, dialCode, … }` |\n| `parsePhoneNumber(country, phoneNumber)` | Structured parse result; `null` if empty |\n| `formatPhoneNumber(country, phoneNumber, formatStyle?)` | `'INTERNATIONAL'` \\| `'E.164'` \\| `'NATIONAL'` |\n| `formatToE164(country, phoneNumber)` | E.164 string or `null` |\n| `isValidPhoneNumberForCountry(country, phoneNumber)` | boolean |\n| `formatNationalInput(iso2, digits, enabled?)` | As-you-type national formatting |\n| `sanitizePhoneNumber` / `sanitizeForParse` | Strip formatting for parsing |\n\n### Country helpers\n\n| Function | Description |\n|----------|-------------|\n| `getCountryByIso2(iso2)` | `CountryItem` or `undefined` |\n| `getCountriesByDialCode(dialCode)` | e.g. all `+1` countries |\n| `getDialCodeForIso2(iso2)` | e.g. `\"+94\"` |\n\n## `CountryItem` shape\n\nEach country is:\n\n```javascript\n{\n  iso2: 'US',           // ISO 3166-1 alpha-2 — used for validation\n  dialCode: '+1',\n  country: 'United States',\n  flag: '🇺🇸',\n}\n```\n\n## `PhoneNumberInput` props\n\n### Value / country\n\n| Prop | Type | Description |\n|------|------|-------------|\n| `value` | `string` | Controlled national value |\n| `defaultValue` | `string` | Uncontrolled initial value |\n| `defaultCountry` | `string` | Default `iso2` (e.g. `\"LK\"`) |\n| `selectedCountry` | `CountryItem` | Controlled selected country |\n| `countries` | `CountryItem[]` | Override list (defaults to `getSortedCountries(defaultCountry)`) |\n\n### Callbacks\n\n| Prop | Description |\n|------|-------------|\n| `onChangeText(text)` | National string (formatted if `autoFormat`) |\n| `onChangeFormattedText(e164)` | Fires with **E.164** when the number is **valid** |\n| `onChangeCountry(country)` | Country changed (picker or international paste) |\n| `onValidChange(isValid)` | Validation flag |\n| `onParsedChange(result \\| null)` | Full parse; `null` when empty |\n\n### Behavior\n\n| Prop | Default | Description |\n|------|---------|-------------|\n| `autoFormat` | `true` | National formatting with `AsYouType` |\n| `enableSearch` | `true` | Search in country modal |\n| `allowZeroAfterCountryCode` | `true` | National leading zeros (e.g. some regions) |\n| `showFlag` | `true` | Show flag on trigger |\n| `showDialCode` | `true` | Show dial code on trigger |\n| `showCountryName` | `false` | Show country name on trigger |\n| `disabled` | `false` | Disable input |\n| `error` | `false` | Error border |\n| `errorText` | `string` | Message below field |\n\n### Styles & render props\n\n| Style props | Render props |\n|-------------|----------------|\n| `containerStyle`, `inputContainerStyle`, `countryButtonStyle`, `textInputStyle` | `renderCountryTrigger({ selectedCountry, openPicker })` |\n| `flagTextStyle`, `dialCodeTextStyle`, `countryTextStyle`, `errorTextStyle` | `renderInput({ value, onChangeText, ... })` |\n| `modalStyle`, `searchInputStyle`, `itemStyle`, `itemTextStyle` | `renderCountryItem({ item, onPress })` |\n\nAlso: `placeholder`, `searchPlaceholder`, `modalTitle`.\n\n## Custom trigger example\n\n```javascript\n<PhoneNumberInput\n  defaultCountry=\"IN\"\n  renderCountryTrigger={({ selectedCountry, openPicker }) => (\n    <TouchableOpacity onPress={openPicker}>\n      <Text>\n        {selectedCountry.flag} {selectedCountry.dialCode}\n      </Text>\n    </TouchableOpacity>\n  )}\n/>\n```\n\n## Platform notes\n\n- **iOS / Android**: Uses standard `Modal`, `TextInput`, `FlatList`; touch targets and padding are tuned per platform (and **web** when `Platform.OS === 'web'`).\n- **Web (React Native for Web)**: Same components; ensure your app includes `react-native-web` setup. If `Intl.DisplayNames` is unavailable in your environment, country names fall back to the `iso2` code (rare on modern JS engines).\n\n## Validation accuracy\n\nValidation is delegated to **libphonenumber-js** using the selected country’s **`iso2`**. That matches how real phone metadata is keyed (shared dial codes, variable length, etc.). This package does **not** maintain per-country regex by hand.\n\n## License\n\nMIT\n\n## Maintainer\n\nPublished under the **CodeHogs** scope as `@codehogs/rn-country-phone-codes`.\n","readmeFilename":"README.md","_rev":"1-fcf4198cead71045704b18b13c99a940"}