MUI Components
NPM

MUIPhoneInput

MUIPhoneInput wraps react-international-phone inside a TextField, with a searchable country dropdown. It emits a structured MUIPhoneInputValue (phone, country, dialCode, phoneNo).

Installation

Make sure to install react-international-phone package before using this component.

npm install react-international-phone
yarn add react-international-phone
pnpm add react-international-phone

Usage

import MUIPhoneInput, {
  type MUIPhoneInputProps,
  type MUIPhoneInputValue
} from '@nish1896/mui-components/misc/phone-input';
const [phone, setPhone] = useState<MUIPhoneInputValue>();

<MUIPhoneInput
  fieldName="phone"
  value={phone}
  onValueChange={({ newValue }) => setPhone(newValue)}
/>
Tip

For validation, consider enforcing the following minimum lengths:

  • phone and phoneNo: at least 6 characters
  • country: exactly 2 characters (ISO country code)
  • dialCode: 1–4 digits, depending on the selected country

Return Value

The input and return value is represented as an MUIPhoneInputValue object:

type MUIPhoneInputValue = {
  phone: string;
  country: CountryIso2;  // imported from 'react-international-phone'
  dialCode: string;
  phoneNo: string;
}

After input, the returned phone value has this shape:

{
  phone: "+918885511000"
  country: "in"
  dialCode: "91"
  phoneNo: "8885511000"
}

Where:

PropertyDescription
phoneFull phone number including country dial code
countrySelected ISO 3166-1 alpha-2 country code
dialCodeCountry dialing code without the + prefix
phoneNoNational phone number without the dial code

Why is the country stored separately?

Some countries share the same dialing code. For example:

  • πŸ‡ΊπŸ‡Έ United States: +1 (765) 232-3423
  • πŸ‡¨πŸ‡¦ Canada: +1 (416) 345-6234
  • πŸ‡΅πŸ‡· Puerto Rico: +1 (787) 234-4442

Although all three numbers begin with +1, they belong to different countries. Storing the selected country separately removes that ambiguity and makes it easier to perform country-specific validation and processing.

For example:

const { phone, country, phoneNo } = value;

Use:

  • phone when you need the complete international number.
  • phoneNo when you only need the national number.
  • country for country-specific logic or validation.

This is the main reason the field value shape changed from a string to an object in v4.

Search Countries

Because the country list is large, MUIPhoneInput has an inline search field that allows users to search for and select their preferred country. The search matches the country name, ISO2 country code, and dial code.

The search field is enabled by default and can be customized using searchCountryProps, an object with the following properties:

  • allowCountrySearch - Shows or hides the inline search field. Defaults to true.
  • textFieldProps - TextFieldProps for customizing the search text field.
  • renderCountryMenuItem - Customizes the content of each MenuItem in the country search dropdown.
  • noCountryFoundText - Text shown when no countries match the search. Defaults to "No countries found".
<MUIPhoneInput
  fieldName="phoneNumber"
  value={phoneNumber}
  onValueChange={({ newValue }) => setPhoneNumber(newValue)}
  searchCountryProps={{
    textFieldProps: {
      variant: 'outlined'
    }
    renderCountryMenuItem: country => `${country.dialCode} - ${country.name}`,
    noCountryFoundText: 'No matching country found'
  }}
/>

The search field is rendered inside the country dropdown and remains pinned to the top while the country list is scrolled.

API

MUIPhoneInputProps also accepts most TextFieldProps, with some props excluded, including name, value, onChange.

Props marked with * are required.

NameTypeDescription
fieldName*string
Name/path of the field. Used to derive the id, the default label, and the name attribute. This prop is required for all components.
valueMUIPhoneInputValue | string | null
Current phone value. May be initialized with a phone string, but onValueChange always emits the structured MUIPhoneInputValue shape.
onValueChange*({ newValue, phoneData }) => void
Called after the phone value is normalized to the structured MUIPhoneInputValue shape, along with the raw payload from react-international-phone.
phoneInputPropsUsePhoneInputConfig
Configuration passed to react-international-phone's usePhoneInput hook β€” defaultCountry, countries, preferredCountries, forceDialCode, etc.
searchCountryPropsSearchCountryProps
Options for the inline country search field in the country dropdown β€” allowCountrySearch, textFieldProps, renderCountryMenuItem, noCountryFoundText, menuItemProps (forwarded to every country MenuItem, including the disabled "no results" item).
menuItemProps added in v2.
countrySelectPropsCountrySelectProps
Props forwarded to the internal MUI Select that renders the flag/dial-code trigger and country dropdown β€” e.g. a custom size or sx (merged with the component's own). value, defaultValue, onChange, onOpen, onClose, renderValue, MenuProps, disabled, children and ref are controlled by the component.
Added in v2.
requiredboolean
Indicates that the field is mandatory by adding an asterisk symbol (*) to the form label and setting the relevant accessibility attributes.
errorMessagestring | string[]
Validation error for the field β€” pass a single message string, or a string[] when the field can fail multiple rules at once (every message is shown together). A non-empty string or array puts the field in an error state; undefined/''/[] clear it.
Normalize your form library's error shape to this at the call site (e.g. an RHF FieldError via its .message). Use renderError to customize how the message(s) are rendered.
renderError(errors: string[]) => ReactNode
Custom renderer for the resolved error message(s), called only when the field is in an error state. Always receives a string[] β€” use errors[0] for the common single-message case, or map over errors when a field fails several rules. By default a single message renders as text and multiple messages render on separate lines.
hideErrorMessageboolean
If true, hides the error message text while keeping the field in an error state.
helperTextReactNode
Content displayed in the FormHelperText component below the field when there is no visible validation error.
showLabelAboveFormFieldboolean
When true, renders the field label above the form field in the FormLabel component, instead of inside or beside it.
hideLabelboolean
When true, hides the rendered field label while preserving accessible labeling where possible.
formLabelPropsFormLabelProps
FormLabelProps forwarded to the internal FormLabel. The id is managed by the component. Multiple fields can be configured using the ConfigProvider component.
formHelperTextPropsFormHelperTextProps
FormHelperTextProps forwarded to the internal FormHelperText. The id is managed by the component. Multiple fields can be configured using the ConfigProvider component.
customIds{ field, label, helperText, error }
Overrides the default field, label, helper text, and error IDs used for accessibility.

Playground

Integrated with Formik β€” the structured MUIPhoneInputValue with validation on phoneNo, plus preferredCountries, forceDialCode and a hidden country search.

Reference