311

Phone Input

Phone Input allows user to enter phone number in E.164 format.

"use client";

import en from "react-phone-number-input/locale/en";

About

The <PhoneInput /> component is built on top of react-phone-number-input, wrapping the library to deliver a more consistent API that aligns with Base UI conventions.

Understanding Phone Formats

Phone numbers can be represented in different formats depending on the context. Understanding these formats is crucial for using the component effectively.

National Format

National format represents phone numbers in their local, country-specific format. This format is most familiar to users within a specific country. For example:

  • US: (234) 567-8900
  • UK: 01234 567890
  • MY: 012-345 6789
  • JP: 0123-45-6789

International Format

International format follows the E.164 standard, which provides a consistent way to represent phone numbers globally. This format can be displayed in two variants:

  1. Without Country Code

    Shows only the subscriber number without the country calling code prefix, useful when the country is already known through the country select or other context. For example:

    • US: 234 567 8900
    • UK: 1234 567890
    • MY: 12 345 6789
    • JP: 123 45 6789
  2. With Country Code

    Includes the country calling code prefix, a universal representation that works across all countries. For example:

    • US: +1 234 567 8900
    • UK: +44 1234 567890
    • MY: +60 12 345 6789
    • JP: +81 123 45 6789

Formatting Behavior

The component automatically handles phone number formatting based on whether a country is selected.

  • When no country is selected, it uses international format with country code by default.
  • When a country is selected, it uses national format by default.

The formatting behavior can be configured to suit different use cases.

Installation

pnpm dlx shadcn@latest add junwen-k/ui-x/phone-input-primitive

Anatomy

import * as PhoneInputPrimitive from "@/components/ui/phone-input-primitive";
 
export default () => (
  <PhoneInputPrimitive.Root>
    <PhoneInputPrimitive.CountrySelect>
      <PhoneInputPrimitive.CountrySelectOption />
    </PhoneInputPrimitive.CountrySelect>
    <PhoneInputPrimitive.Input />
  </PhoneInputPrimitive.Root>
);

Examples

Default

Basic example with country select and input.

"use client";

import en from "react-phone-number-input/locale/en";

Disabled

"use client";

import en from "react-phone-number-input/locale/en";

Preferred Country

When you know the likely country of your users (such as for a local business signup), you can set a default country while still allowing international numbers. This lets users enter phone numbers in their national format for the default country, while maintaining the flexibility to use international formats for any other country.

In this example, the default country is set to Malaysia, with the initial value forced to display in international format rather than the default national format.

Preferred country has been set to MY (Malaysia).

National format (default):
012-345 6789
International format:
+60 12 345 6789
"use client";

import * as React from "react";

API Reference

Root

Manages the phone value and selected country and provides them to the parts below. Renders no element of its own.

PropTypeDefaultDescription
valueValue-The phone number in E.164 format (e.g. "+12133734253"). Use for controlled value.
defaultValueValue""The initial value when uncontrolled.
onValueChange(value: Value) => void-Called when the phone number changes.
countryCountry | null-The selected country. null means "International". Use for controlled country.
defaultCountryCountry-The initial country when uncontrolled.
onCountryChange(country: Country | null) => void-Called when the selected country changes.
preferredCountryCountry-Suggests a country while no country is selected: numbers can be typed in this country's national format while international numbers for any other country keep working.
defaultInternationalForPreferredCountrybooleanfalseForces international format for initial values that match the preferred country. Only valid together with preferredCountry.
internationalbooleanfalseForces international format when a country is explicitly selected.
withCountryCallingCodebooleanfalseKeeps the country calling code visible and undeletable in international format. Only valid together with international.
disabledbooleanfalseDisables the input and the country select.
childrenReactNode-The phone input parts.

Input

The phone number input, formatting as you type via react-phone-number-input. Renders an <input> by default.

PropTypeDefaultDescription
renderReactElement-Render as a different input element. Wrap it in useMemo — see the callout above.
smartCaretbooleantrueKeeps the caret position stable while the value is reformatted.
...propsReact.ComponentProps<typeof ReactPhoneInput>-Remaining react-phone-number-input props are spread.

CountrySelect

The country selector. Renders a native <select> wired to the country state.

PropTypeDefaultDescription
...propsReact.ComponentProps<"select">-Props spread to the select element.

CountrySelectOption

A country option. Renders an <option>.

PropTypeDefaultDescription
...propsReact.ComponentProps<"option">-Props spread to the option element.

CountryInternationalSelectOption

The "International" option. Selecting it clears the country (null).

PropTypeDefaultDescription
...propsOmit<React.ComponentProps<"option">, "value">-Props spread to the option element.

getCountryOptions

A helper that returns { countryCode, countryCallingCode } for every supported country — useful for rendering the options list.

usePhoneInput

Hook exposing the phone input context (value, country, change handlers, disabled) for building custom parts. Must be used within <PhoneInput.Root>.