Skip to main content

CountrySelect

The CountrySelect component provides a user-friendly dropdown for selecting a country. It features a searchable list, displays country flags, and offers a responsive design that adapts to both desktop and mobile viewports. It is designed to be used within a form managed by react-hook-form.

Props

PropTypeDescriptionRequiredDefault
valueCountryIso2The ISO2 code of the selected country (e.g., 'us').Yes
onChange(value: CountryIso2) => voidA callback function that is invoked when a country is selected.Yes
namestringThe name attribute for the input, used for integration with react-hook-form.Yes
sxSxPropsCustom styles to be applied to the root element.No{}
showDialCodebooleanIf true, the country's dial code will be displayed alongside its name in the list.Nofalse

Basic Usage

To use the CountrySelect component, you must wrap it in a FormProvider from react-hook-form. The component's state should be managed through the form context.

Basic CountrySelect Example

tsx
import { FormProvider, useForm } from 'react-hook-form';
import { Box, Button, Typography } from '@mui/material';
import CountrySelect from '@blocklet/payment-react/src/components/country-select'; // Adjust path as needed
import type { CountryIso2 } from 'react-international-phone';

export default function BasicCountrySelect() {
  const methods = useForm<{ country: CountryIso2 }>({
    defaultValues: {
      country: 'us',
    },
  });

  const { handleSubmit, watch, setValue } = methods;
  const countryValue = watch('country'); // Watch for changes to update the controlled component

  const onSubmit = (data: { country: CountryIso2 }) => {
    alert(`Form submitted with country: ${data.country}`);
  };

  return (
    <FormProvider {...methods}>
      <form onSubmit={handleSubmit(onSubmit)}>
        <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, maxWidth: 400 }}>
          <Typography variant="h6">Select Your Country</Typography>
          <CountrySelect
            name="country"
            value={countryValue}
            onChange={(newCountry) => {
              setValue('country', newCountry, { shouldValidate: true });
            }}
          />
          <Button type="submit" variant="contained">
            Submit
          </Button>
          <Typography>
            Current form value: {countryValue}
          </Typography>
        </Box>
      </form>
    </FormProvider>
  );
}

Features

Search and Filter

The component includes a search bar at the top of the dropdown list, allowing users to quickly find a country by its name, ISO2 code, or dial code. For example, searching for "+1" will show the United States and Canada.

Responsive UI

On desktop devices, CountrySelect renders as a standard dropdown menu. On mobile, it transforms into a full-width dialog that slides up from the bottom of the screen, providing an optimized user experience on smaller devices.

Keyboard Accessibility

CountrySelect supports full keyboard navigation. Users can use the ArrowUp and ArrowDown keys to navigate the list, Enter to select a country, and Escape to close the dropdown. Tab and Shift+Tab also cycle through the list items.

Form Integration

Designed to work seamlessly with react-hook-form. It automatically updates the form state when a selection is made, requiring it to be wrapped within a FormProvider.

Advanced Usage

Displaying Dial Codes

You can display the telephone dial code for each country in the list by setting the showDialCode prop to true.

CountrySelect with Dial Code

tsx
import { FormProvider, useForm } from 'react-hook-form';
import { Box, Button } from '@mui/material';
import CountrySelect from '@blocklet/payment-react/src/components/country-select'; // Adjust path as needed
import type { CountryIso2 } from 'react-international-phone';

export default function CountrySelectWithDialCode() {
  const methods = useForm<{ country: CountryIso2 }>({
    defaultValues: {
      country: 'gb',
    },
  });

  const { handleSubmit, watch, setValue } = methods;
  const countryValue = watch('country');

  const onSubmit = (data: { country: CountryIso2 }) => {
    alert(`Form submitted with country: ${data.country}`);
  };

  return (
    <FormProvider {...methods}>
      <form onSubmit={handleSubmit(onSubmit)}>
        <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, maxWidth: 400 }}>
          <CountrySelect
            name="country"
            value={countryValue}
            onChange={(newCountry) => setValue('country', newCountry)}
            showDialCode={true}
          />
          <Button type="submit" variant="contained">
            Submit
          </Button>
        </Box>
      </form>
    </FormProvider>
  );
}

Next Steps

This component is a building block for more complex form elements. See how it's integrated into the PhoneInput component to create a complete international phone number field.