npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

international-fields

v1.1.2

Published

Customizable phone input and country input components for React

Downloads

330

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-fields

Importing 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 object

Examples

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 lint

Building and Publishing to NPM

Prerequisites

  1. Create an NPM account at npmjs.com
  2. Login to NPM from your terminal:
    npm login

Build Steps

  1. Update version in package.json (if needed):

    {
      "version": "1.0.0"
    }
  2. Build the library:

    npm run build

    This will:

    • Generate TypeScript declaration files (.d.ts) in dist/
    • Build ES module (.mjs) and CommonJS (.cjs) formats
    • Bundle CSS into dist/style.css
  3. Verify the build: Check that dist/ folder contains:

    • index.mjs (ES module)
    • index.cjs (CommonJS)
    • index.d.ts (TypeScript declarations)
    • style.css (Styles)

Publishing

  1. Test locally first (optional but recommended):

    npm pack

    This creates a .tgz file you can test in another project:

    npm install /path/to/international-fields-1.0.0.tgz
  2. Publish to NPM:

    npm publish

    For scoped packages (if your package name is @username/international-fields):

    npm publish --access public
  3. Verify publication: Visit https://www.npmjs.com/package/international-fields to see your package

After Publishing

Users can install and use your package:

npm install international-fields
import { PhoneInput, CountryInput } from 'international-fields';
import 'international-fields/styles'; // Recommended

License

MIT