Used to check for browser translation.
用于检测浏览器翻译。
ブラウザの翻訳を検出する
Components

PhoneInput


The PhoneInput component provides a user-friendly field for entering international phone numbers. It integrates seamlessly with react-hook-form and includes a built-in, searchable country selector. It is designed to work in tandem with a country selection field, ensuring data consistency across your form.

Features#

  • React Hook Form Integration: Built to work directly with useFormContext for easy state management and validation.
  • Interactive Country Selector: Includes the CountrySelect component as a prefix, offering country flags, names, and a search field.
  • Two-Way Country Synchronization: Automatically syncs the selected country with another form field (e.g., a billing address country field).
  • Asynchronous Validation: Leverages google-libphonenumber for robust validation without blocking the main thread on initial load.
  • Responsive Design: The country selector adapts to the viewport, using a dropdown on desktop and a dialog on mobile devices.

Props#

The PhoneInput component accepts all standard props from Material-UI's TextField in addition to its own specific props.

Prop

Type

Description

Default

name

string

Required. The name of the field to be registered with react-hook-form.

-

countryFieldName

string

The name of the form field that stores the selected country's ISO 3166-1 alpha-2 code. The component synchronizes with this field.

'billing_address.country'

...rest

TextFieldProps

Any other props accepted by the Material-UI TextField component, such as label, placeholder, required, helperText, and error.

-

Usage#

The PhoneInput must be wrapped in a FormProvider from react-hook-form. It is designed to be used alongside a component that controls the country selection, such as the CountrySelect component.

Basic Example#

This example demonstrates a complete form with a PhoneInput and a separate CountrySelect for the billing address. The two are synchronized via the countryFieldName prop.

import { FormProvider, useForm } from 'react-hook-form';
import { Button, Stack } from '@mui/material';
import PhoneInput from '@blocklet/payment-react/components/ui/form-elements/phone-input';
import CountrySelect from '@blocklet/payment-react/components/ui/form-elements/country-select';
import { validatePhoneNumber } from '@blocklet/payment-react/libs/phone-validator';

export default function PhoneForm() {
const methods = useForm({
mode: 'onBlur', // Validate on blur
defaultValues: {
phone: '',
'billing_address.country': 'us', // Default country
},
});

const { control, handleSubmit, formState: { errors } } = methods;

const onSubmit = (data) => {
alert(JSON.stringify(data, null, 2));
};

return (
<FormProvider {...methods}>
<form onSubmit={handleSubmit(onSubmit)}>
<Stack spacing={2}>
<CountrySelect
name="billing_address.country"
value={methods.watch('billing_address.country')}
onChange={(country) => methods.setValue('billing_address.country', country, { shouldValidate: true })}
/>
<PhoneInput
label="Phone Number"
name="phone"
// countryFieldName is implicitly 'billing_address.country'
required
{...methods.register('phone', {
required: 'Phone number is required.',
validate: async (value) => {
const isValid = await validatePhoneNumber(value);
return isValid || 'Please enter a valid phone number';
},
})}
error={!!errors.phone}
helperText={errors.phone?.message}
/>
<Button type="submit" variant="contained">
Submit
</Button>
</Stack>
</form>
</FormProvider>
);
}

Validation#

Phone number validation is handled by the validatePhoneNumber utility. This function asynchronously loads the google-libphonenumber library to perform validation without impacting your application's initial load time.

To apply validation, use the validate function in the rules object when registering the field with react-hook-form, as shown in the example above.

Country Synchronization#

The key feature of PhoneInput is its ability to synchronize with an external country field.

  • Default Behavior: By default, it listens to and updates a form field named billing_address.country.
  • Customization: You can specify a different field name by passing the countryFieldName prop.

This two-way synchronization works as follows:

  1. When the user selects a country in the CountrySelect component (or any other component controlling the countryFieldName value), the flag and dial code inside the PhoneInput update automatically.
  2. When the user changes the country from the dropdown within the PhoneInput, the value of the countryFieldName field is updated, ensuring the entire form state remains consistent.

This is particularly useful in forms like an AddressForm where the phone number's country should match the billing address country.