Babelize Elements

Phone Input

International phone number input with country selector, flag emojis, and dial code search. Supports 50 countries with built-in formatting and validation.

Installation

bash npx shadcn@latest add @elements/phone-input

Usage

import { PhoneInput } from "@/components/ui/phone-input";
<PhoneInput
  defaultCountry="US"
  placeholder="Enter phone number"
  onValueChange={(value, country) => {
    console.log(value, country.dialCode);
  }}
/>

Props

PropTypeRequiredDescription
valuestringNoPhone number — pass this to control the component
defaultValuestringNoInitial phone number when uncontrolled
onValueChange(phone: string, country: Country) => voidNoCallback when phone number or country changes
defaultCountrystringNoDefault country code (ISO 3166-1 alpha-2, e.g. "US", "GB", "IN")
placeholderstringNoPlaceholder text
disabledbooleanNoDisable the input
showFlagsbooleanNoShow country flag next to dial code (default: true)
labelstringNoAccessible label for the input
classNamestringNoAdditional CSS classes

Any other prop — name, required, autoComplete, data-* — is spread onto the underlying <input>, and the ref is forwarded to it, so the component works inside a plain HTML form.

Country Object

PropertyTypeDescription
codestringISO 3166-1 alpha-2 code (e.g. "US", "GB", "IN")
dialCodestringDial code (e.g. "+1", "+44", "+91")
namestringCountry name
flagstringFlag emoji

Examples

With Babelize SDK

Pair Phone Input with the Babelize SDK for locale-aware validation:

"use client";

import { useState } from "react";
import { PhoneInput } from "@/components/ui/phone-input";
import { useBabelize } from "@babelize/sdk/react";

export function ContactPhone() {
  const { locale } = useBabelize();
  const [phone, setPhone] = useState("");

  return (
    <PhoneInput
      value={phone}
      onValueChange={(value, country) => {
        setPhone(value);
        // Validate against locale-specific rules
      }}
      defaultCountry={locale === "en" ? "US" : locale === "de" ? "DE" : "GB"}
      placeholder="Enter phone number"
    />
  );
}

With Form Validation

"use client";

import { useState } from "react";
import { PhoneInput } from "@/components/ui/phone-input";

export default function CheckoutForm() {
  const [phone, setPhone] = useState("");
  const [error, setError] = useState("");

  const validate = (value: string) => {
    if (value.length < 10) {
      setError("Phone number is too short");
    } else {
      setError("");
    }
  };

  return (
    <div>
      <PhoneInput
        value={phone}
        onValueChange={(value) => {
          setPhone(value);
          validate(value);
        }}
        defaultCountry="US"
        placeholder="Enter phone number"
      />
      {error && <p className="text-red-500 text-sm mt-1">{error}</p>}
    </div>
  );
}

With Country Filter

"use client";

import { PhoneInput } from "@/components/ui/phone-input";

const COUNTRIES = [
  { code: "US", dialCode: "+1", name: "United States", flag: "🇺🇸" },
  { code: "GB", dialCode: "+44", name: "United Kingdom", flag: "🇬🇧" },
  { code: "CA", dialCode: "+1", name: "Canada", flag: "🇨🇦" },
  { code: "AU", dialCode: "+61", name: "Australia", flag: "🇦🇺" },
];

export default function App() {
  return (
    <PhoneInput
      defaultCountry="US"
      onValueChange={(phone, country) => console.log(phone, country)}
    />
  );
}

Features

  • 50 countries — pre-loaded with dial codes, flags, and names
  • Dropdown search — filter countries by name or dial code
  • Flag emojis — auto-detected from country code, with showFlags toggle
  • Keyboard accessible — arrow keys, Enter, Escape, Tab navigation
  • ARIA labels — proper aria-expanded, aria-haspopup, aria-label
  • Dark mode — built with Tailwind CSS, dark-mode compatible
  • Controlled/uncontrolled — works with or without value prop

Supported Countries

The input ships with 50 countries pre-loaded. Use the dropdown search to find any country by name or dial code. The full list includes:

CountryCodeDial CodeFlag
United StatesUS+1🇺🇸
United KingdomGB+44🇬🇧
CanadaCA+1🇨🇦
AustraliaAU+61🇦🇺
IndiaIN+91🇮🇳
GermanyDE+49🇩🇪
FranceFR+33🇫🇷
JapanJP+81🇯🇵
BrazilBR+55🇧🇷
South KoreaKR+82🇰🇷
...and 40 more via the dropdown search

Dependencies

This component uses:

  • clsx and tailwind-merge (bundled as dependencies)

Peer dependencies:

  • react >= 18
  • react-dom >= 18
  • tailwindcss >= 3

Credits

Created by sapatmohit.

On this page