@jmt-code/phone-selector
v0.1.4
Published
Beautiful React component for country selection with flag images, phone input validation, and elegant glassmorphism design. Features dynamic mask templates and 150+ countries support.
Maintainers
Readme
🌍 Country Phone Selector
A beautiful, modern React component for selecting countries and inputting phone numbers with intelligent validation and elegant glassmorphism design.
✨ Features
- 🎨 Beautiful Design: Modern glassmorphism UI with smooth animations
- 🏳️ Real Flag Images: High-quality flag images from flagcdn.com (no more emojis!)
- 📱 Responsive: Multiple size variants (sm, md, lg)
- ✅ Smart Validation: Country-specific phone number validation with flexible digit ranges
- 🌙 Dark Mode: Automatic dark mode support
- 🔧 TypeScript: Full TypeScript support with proper types
- ♿ Accessible: ARIA labels and keyboard navigation
- 🌐 150+ Countries: Comprehensive country database with dial codes
📦 Installation
npm install @jmt-code/phone-selectoryarn add @jmt-code/phone-selectorpnpm add @jmt-code/phone-selectorPeer Dependencies:
- react >= 17
- react-dom >= 17
🚀 Quick Start
import React, { useState } from 'react';
import { CountryPhoneInput } from '@jmt-code/phone-selector';
export default function MyComponent() {
const [value, setValue] = useState('');
return (
<CountryPhoneInput
value={value}
onChange={(data) => {
setValue(data.raw);
console.log('Phone:', data.formatted);
console.log('Country:', data.country.name);
console.log('Valid:', data.isValid);
}}
initialCountry="US"
placeholder="Enter phone number"
/>
);
}🎯 Size Variants
Compact (sm)
Perfect for forms with limited space:
<CountryPhoneInput size="sm" initialCountry="ES" />Standard (md) - Default
Balanced size for most use cases:
<CountryPhoneInput initialCountry="US" />Large (lg)
Prominent display for primary forms:
<CountryPhoneInput size="lg" initialCountry="MX" />📋 API Reference
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | string | "" | The phone number digits (without dial code) |
| onChange | (data: ChangePayload) => void | - | Callback fired when value changes |
| initialCountry | string | "US" | Initial country ISO2 code |
| countries | Country[] | All countries | Custom country list |
| size | "sm" \| "md" \| "lg" | "md" | Component size variant |
| disabled | boolean | false | Whether the component is disabled |
| className | string | - | Additional CSS class name |
| placeholder | string | - | Input placeholder text |
ChangePayload
interface ChangePayload {
country: Country; // Selected country object
raw: string; // Raw digits only (e.g., "1234567890")
formatted: string; // Full formatted number (e.g., "+1 (123) 456-7890")
isValid: boolean; // Whether the number matches validation rules
}Country Object
interface Country {
name: string; // "United States"
iso2: string; // "US"
dialCode: string; // "+1"
mask: string; // "(999) 999-9999"
flag: string; // Flag image URL
minDigits?: number; // Minimum valid digits
maxDigits?: number; // Maximum valid digits
}🎨 Styling & Customization
The component comes with beautiful glassmorphism styles, but you can customize it:
/* Custom theme example */
.my-phone-input .cpi-input {
border: 2px solid #your-brand-color;
}
.my-phone-input .cpi-select {
background: linear-gradient(135deg, #your-start, #your-end);
}
/* Dark mode customization */
@media (prefers-color-scheme: dark) {
.my-phone-input .cpi-container {
--primary-color: #your-dark-color;
}
}🌙 Dark Mode Support
Dark mode is automatically detected using prefers-color-scheme. The component seamlessly adapts with:
- Darker backgrounds with transparency
- Adjusted text colors for readability
- Smooth transitions between themes
🔧 Advanced Usage
Custom Country List
import { defaultCountries, type Country } from '@jmt-code/phone-selector';
const europeanCountries: Country[] = [
{ name: 'Spain', iso2: 'ES', dialCode: '+34', mask: '999 999 999', flag: 'https://flagcdn.com/20x15/es.png' },
{ name: 'France', iso2: 'FR', dialCode: '+33', mask: '99 99 99 99 99', flag: 'https://flagcdn.com/20x15/fr.png' },
{ name: 'Germany', iso2: 'DE', dialCode: '+49', mask: '9999 999999', flag: 'https://flagcdn.com/20x15/de.png' },
];
<CountryPhoneInput countries={europeanCountries} />Flexible Validation
Some countries support flexible digit ranges:
// Italy: accepts 8-11 digits for different number types
{
name: 'Italy',
iso2: 'IT',
dialCode: '+39',
mask: '999 999 9999',
minDigits: 8,
maxDigits: 11
}
// Spain: exactly 9 digits
{
name: 'Spain',
iso2: 'ES',
dialCode: '+34',
mask: '999 999 999',
minDigits: 9,
maxDigits: 9
}🌍 Supported Countries
Includes 150+ countries with accurate:
- 📍 Official country names
- 🏷️ ISO2 country codes
- 📞 International dial codes
- 🎭 Phone number formatting masks
- ✅ Country-specific validation rules
- 🏳️ High-quality flag images (20x15px)
Popular Countries Include:
- 🇺🇸 United States (+1) - (999) 999-9999
- 🇪🇸 Spain (+34) - 999 999 999
- 🇫🇷 France (+33) - 99 99 99 99 99
- 🇩🇪 Germany (+49) - 9999 999999
- 🇬🇧 United Kingdom (+44) - 9999 999999
- 🇮🇹 Italy (+39) - 999 999 9999
- 🇲🇽 Mexico (+52) - 99 9999 9999
- 🇧🇷 Brazil (+55) - (99) 99999-9999
- And many more...
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
📄 License
MIT © Juan Manuel
🙏 Acknowledgments
- 🏳️ Flag images provided by flagcdn.com
- 🌍 Country data compiled from international telecommunications standards
- 🎨 Design inspired by modern glassmorphism and accessibility principles
- 💝 Built with love for the React community
