custom_phone_field 1.0.1 copy "custom_phone_field: ^1.0.1" to clipboard
custom_phone_field: ^1.0.1 copied to clipboard

A smart and customizable Flutter package for phone number input with country selection, validation, and formatting.

Custom Phone Field #

pub package license

A beautiful and customizable phone number input field for Flutter applications. This package provides a ready-to-use phone input field with country selection, validation, and customization options.

Features #

  • 🌍 Country selection with flags and dial codes
  • 📱 Phone number validation with country-specific rules
  • 🎨 Two widget options: CustomPhoneInput (pre-built) and PhoneField (customizable)
  • 🔄 Form integration with validation
  • 🌐 Internationalization support (20+ languages)
  • ♿ Accessibility support
  • 📦 Lightweight and easy to use

Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  custom_phone_field: ^1.0.1

Quick Start #

Using CustomPhoneInput (Pre-built Widget) #

import 'package:custom_phone_field/custom_phone_field.dart';

CustomPhoneInput(
  initialCountry: 'US',
  onCountryChanged: (country) {
    print('Selected country: ${country.name}');
  },
  onPhoneNumberChanged: (phoneNumber) {
    print('Phone number: $phoneNumber');
  },
  validator: (value) {
    if (value == null || value.isEmpty) {
      return 'Please enter a phone number';
    }
    return null;
  },
)

Using PhoneField (Customizable Widget) #

import 'package:custom_phone_field/custom_phone_field.dart';

PhoneField(
  initialCountry: 'US',
  onCountryChanged: (country) {
    print('Selected country: ${country.name}');
  },
  builder: (context, country, openPicker) {
    return Row(
      children: [
        // Country selector
        GestureDetector(
          onTap: openPicker,
          child: Container(
            padding: EdgeInsets.all(8),
            child: Row(
              children: [
                Text('+${country.dialCode}'),
                Icon(Icons.arrow_drop_down),
              ],
            ),
          ),
        ),
        // Phone input
        Expanded(
          child: TextField(
            keyboardType: TextInputType.phone,
            decoration: InputDecoration(
              hintText: 'Enter phone number',
            ),
          ),
        ),
      ],
    );
  },
)

Available Widgets #

1. CustomPhoneInput #

A pre-built, ready-to-use phone input field with common customizations.

CustomPhoneInput({
  Key? key,
  String initialCountry = 'EG',
  String languageCode = 'en',
  List<String> availableCountries = const [],
  void Function(Country country)? onCountryChanged,
  void Function(String phoneNumber)? onPhoneNumberChanged,
  String? initialValue,
  bool enabled = true,
  bool readOnly = false,
  InputDecoration? decoration,
  TextStyle? style,
  String? Function(String?)? validator,
})

Properties

Property Type Description
initialCountry String Initial country code (default: 'EG')
languageCode String Language code for localization (default: 'en')
availableCountries List<String> List of available country codes
onCountryChanged Function(Country) Callback when country is changed
onPhoneNumberChanged Function(String) Callback when phone number is changed
initialValue String? Initial phone number value
enabled bool Whether the field is enabled
readOnly bool Whether the field is read-only
decoration InputDecoration? Custom input decoration
style TextStyle? Custom text style
validator Function(String?)? Form validation callback

2. PhoneField #

A customizable phone field widget that allows complete control over the UI.

PhoneField({
  Key? key,
  required Widget Function(
    BuildContext context,
    Country country,
    VoidCallback openPicker,
  ) builder,
  String initialCountry = 'EG',
  String languageCode = 'en',
  List<String> availableCountries = const [],
  void Function(Country country)? onCountryChanged,
})

The PhoneField widget provides a base implementation that you can customize using the builder pattern. The builder function receives:

  • context: The current BuildContext
  • country: The currently selected Country object with properties:
    • name: Country name
    • code: ISO country code (e.g., 'US')
    • dialCode: Country dial code (e.g., '+1')
    • flag: Country flag emoji
    • minLength: Minimum phone number length
    • maxLength: Maximum phone number length
    • nameTranslations: Map of country names in different languages
  • openPicker: A callback function to open the country picker dialog

Country Model #

The Country model provides detailed information about each country:

class Country {
  final String name;
  final Map<String, String> nameTranslations;
  final String flag;
  final String code;
  final String dialCode;
  final String regionCode;
  final int minLength;
  final int maxLength;
  final String pattern;
  final List<String> allowedCharacters;
  final bool requiresAreaCode;
  final String? areaCodePattern;
  final String? exampleNumber;
}

Examples #

Basic Usage with CustomPhoneInput #

CustomPhoneInput(
  onPhoneNumberChanged: (phoneNumber) {
    print('Phone number: $phoneNumber');
  },
)

Form Integration #

final _formKey = GlobalKey<FormState>();

Form(
  key: _formKey,
  child: CustomPhoneInput(
    validator: (value) {
      if (value == null || value.isEmpty) {
        return 'Please enter a phone number';
      }
      return null;
    },
  ),
)

Custom Styling #

CustomPhoneInput(
  initialCountry: 'US',
  style: TextStyle(
    fontSize: 16,
    color: Colors.black87,
  ),
  decoration: InputDecoration(
    labelText: 'Phone Number',
    hintText: 'Enter your phone number',
    prefixIcon: Icon(Icons.phone),
  ),
)

Restricted Countries #

CustomPhoneInput(
  availableCountries: ['US', 'CA', 'GB', 'AU'],
  initialCountry: 'US',
)

Custom Implementation with PhoneField #

PhoneField(
  initialCountry: 'US',
  onCountryChanged: (country) {
    print('Selected country: ${country.name}');
  },
  builder: (context, country, openPicker) {
    return Container(
      decoration: BoxDecoration(
        border: Border.all(color: Colors.grey),
        borderRadius: BorderRadius.circular(8),
      ),
      child: Row(
        children: [
          // Country flag and code
          GestureDetector(
            onTap: openPicker,
            child: Container(
              padding: EdgeInsets.all(8),
              child: Row(
                children: [
                  Text(country.flag),
                  SizedBox(width: 8),
                  Text('+${country.dialCode}'),
                ],
              ),
            ),
          ),
          // Phone input
          Expanded(
            child: TextField(
              keyboardType: TextInputType.phone,
              decoration: InputDecoration(
                border: InputBorder.none,
                hintText: 'Enter phone number',
              ),
            ),
          ),
        ],
      ),
    );
  },
)

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License #

Copyright (c) 2025 Habeeb

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments #

Support #

If you find this package helpful, please give it a star on GitHub and share it with others!

For issues and feature requests, please use the GitHub issue tracker.

1
likes
0
points
41
downloads

Publisher

unverified uploader

Weekly Downloads

A smart and customizable Flutter package for phone number input with country selection, validation, and formatting.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, intl, shared_preferences

More

Packages that depend on custom_phone_field