international-fields
v1.1.2
Published
Customizable phone input and country input components for React
Downloads
330
Maintainers
Readme
International Fields
A customizable React component library for phone input and country selection with TypeScript support.
Features
- 📱 PhoneInput Component - Phone number input with country code selection and auto-detection
- 🌍 CountryInput Component - Searchable country selector
- 🎨 Fully Customizable - Extensive props for styling and behavior
- 📦 TypeScript - Full TypeScript support with type definitions
- 🎯 Zero Dependencies - Only React and React-DOM as peer dependencies
- 🏳️ Flag Images - Beautiful flag images from flagcdn.com
- 🔍 Auto Country Detection - Automatically detects country when typing country codes
- 📋 240+ Countries - Comprehensive country data included
Installation
npm install international-fieldsImporting Styles
You can import the styles in two ways:
Option 1: Using the /styles export (Recommended)
import 'international-fields/styles';Option 2: Using the direct path
import 'international-fields/dist/style.css';Both methods work the same way. The /styles export is recommended as it's cleaner and works consistently across all bundlers (Vite, Webpack, Next.js, etc.).
Usage
PhoneInput
import { PhoneInput } from 'international-fields';
import 'international-fields/styles'; // Import styles (recommended)
function App() {
const [phone, setPhone] = useState('');
return (
<PhoneInput
value={phone}
onChange={(value, country) => {
setPhone(value);
console.log('Selected country:', country);
}}
defaultCountry="US"
placeholder="Enter phone number"
/>
);
}Key Features:
- Automatically shows default country's dial code in input (e.g., "+1" for US)
- Auto-detects country when you type a country code (e.g., typing "+44" switches to UK)
- Click the country selector button to open/close dropdown
- Type country codes directly in the input field
CountryInput
import { CountryInput } from 'international-fields';
import 'international-fields/styles'; // Import styles (recommended)
function App() {
const [country, setCountry] = useState('');
return (
<CountryInput
value={country}
onChange={(code, country) => {
setCountry(code);
console.log('Selected country:', country);
}}
placeholder="Select a country"
searchable={true}
/>
);
}PhoneInput Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | string | '' | Current phone number value |
| onChange | (value: string, country?: Country) => void | - | Callback when value changes |
| defaultCountry | string | 'US' | Default country code (ISO format) |
| placeholder | string | 'Enter phone number' | Input placeholder |
| disabled | boolean | false | Disable the input |
| className | string | '' | Custom class for wrapper |
| inputClassName | string | '' | Custom class for input element |
| flagClassName | string | '' | Custom class for flag display |
| dropdownClassName | string | '' | Custom class for dropdown |
| showFlag | boolean | true | Show country flag image |
| showDialCode | boolean | true | Show dial code in selector |
| countries | Country[] | - | Custom country list |
| customStyles | React.CSSProperties | - | Custom styles for wrapper |
| inputStyles | React.CSSProperties | - | Custom styles for input |
| onCountryChange | (country: Country) => void | - | Callback when country changes |
| allowDropdown | boolean | true | Allow country selection dropdown |
| error | boolean | false | Show error state |
| errorMessage | string | - | Error message to display |
| required | boolean | false | Mark as required field |
| name | string | - | Input name attribute |
| id | string | - | Input id attribute |
| autoFocus | boolean | false | Auto focus on mount |
CountryInput Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | string | '' | Current country code (ISO format) |
| onChange | (code: string, country?: Country) => void | - | Callback when country changes |
| placeholder | string | 'Select country' | Input placeholder |
| disabled | boolean | false | Disable the input |
| className | string | '' | Custom class for wrapper |
| inputClassName | string | '' | Custom class for input element |
| dropdownClassName | string | '' | Custom class for dropdown |
| showFlag | boolean | true | Show country flag image |
| showDialCode | boolean | false | Show dial code in dropdown |
| countries | Country[] | - | Custom country list |
| customStyles | React.CSSProperties | - | Custom styles for wrapper |
| inputStyles | React.CSSProperties | - | Custom styles for input |
| error | boolean | false | Show error state |
| errorMessage | string | - | Error message to display |
| required | boolean | false | Mark as required field |
| name | string | - | Input name attribute |
| id | string | - | Input id attribute |
| autoFocus | boolean | false | Auto focus on mount |
| searchable | boolean | true | Enable country search |
| searchPlaceholder | string | 'Search countries...' | Search input placeholder |
Types
import type { Country, PhoneInputProps, CountryInputProps } from 'international-fields';
interface Country {
code: string; // ISO country code (e.g., 'US', 'GB')
name: string; // Country name
dialCode: string; // Phone dial code (e.g., '+1', '+44')
flagUrl?: string; // Flag image URL from flagcdn.com
}Utilities
import {
countries,
getCountryByCode,
getCountryByDialCode,
getFlagUrl,
getFlagEmoji,
findCountryByDialCodeInInput
} from 'international-fields';
// Get all countries
const allCountries = countries;
// Get country by code
const usa = getCountryByCode('US');
// Get country by dial code
const uk = getCountryByDialCode('+44');
// Get flag URL for country code
const flagUrl = getFlagUrl('US'); // Returns 'https://flagcdn.com/28x21/us.png'
// Get flag emoji for country code (legacy)
const flag = getFlagEmoji('US'); // Returns 🇺🇸
// Find country from input string containing dial code
const country = findCountryByDialCodeInInput('+1 555 123 4567'); // Returns US country objectExamples
Basic Phone Input
<PhoneInput
value={phone}
onChange={(value, country) => setPhone(value)}
defaultCountry="US"
/>Phone Input with Auto Country Detection
<PhoneInput
value={phone}
onChange={(value, country) => {
setPhone(value);
// Country automatically updates when you type country codes
// e.g., typing "+44" switches to UK
}}
onCountryChange={(country) => {
console.log('Country changed to:', country.name);
}}
/>Custom Styling
<PhoneInput
className="my-phone-input"
inputClassName="custom-input"
customStyles={{ maxWidth: '400px' }}
inputStyles={{ fontSize: '18px', fontWeight: '500' }}
/>Error State
<PhoneInput
error={true}
errorMessage="Please enter a valid phone number"
/>Without Dropdown
<PhoneInput
allowDropdown={false}
showFlag={false}
defaultCountry="US"
/>Custom Country List
const customCountries = [
{ code: 'US', name: 'United States', dialCode: '+1', flagUrl: 'https://flagcdn.com/28x21/us.png' },
{ code: 'CA', name: 'Canada', dialCode: '+1', flagUrl: 'https://flagcdn.com/28x21/ca.png' },
{ code: 'MX', name: 'Mexico', dialCode: '+52', flagUrl: 'https://flagcdn.com/28x21/mx.png' },
];
<PhoneInput countries={customCountries} />Country Input
<CountryInput
value={countryCode}
onChange={(code, country) => setCountryCode(code)}
searchable={true}
placeholder="Select a country"
/>Development
# Install dependencies
npm install
# Run development server
npm run dev
# Build library
npm run build
# Build TypeScript declarations
npm run build:types
# Lint
npm run lintBuilding and Publishing to NPM
Prerequisites
- Create an NPM account at npmjs.com
- Login to NPM from your terminal:
npm login
Build Steps
Update version in package.json (if needed):
{ "version": "1.0.0" }Build the library:
npm run buildThis will:
- Generate TypeScript declaration files (
.d.ts) indist/ - Build ES module (
.mjs) and CommonJS (.cjs) formats - Bundle CSS into
dist/style.css
- Generate TypeScript declaration files (
Verify the build: Check that
dist/folder contains:index.mjs(ES module)index.cjs(CommonJS)index.d.ts(TypeScript declarations)style.css(Styles)
Publishing
Test locally first (optional but recommended):
npm packThis creates a
.tgzfile you can test in another project:npm install /path/to/international-fields-1.0.0.tgzPublish to NPM:
npm publishFor scoped packages (if your package name is
@username/international-fields):npm publish --access publicVerify publication: Visit
https://www.npmjs.com/package/international-fieldsto see your package
After Publishing
Users can install and use your package:
npm install international-fieldsimport { PhoneInput, CountryInput } from 'international-fields';
import 'international-fields/styles'; // RecommendedLicense
MIT
