goveo / react-international-phone

☎️ International phone input component for React
https://react-international-phone.vercel.app/
MIT License
295 stars 54 forks source link

usePhoneInput hook does not work correctly with default values and the forceDialCode prop #190

Closed camilopl33 closed 5 months ago

camilopl33 commented 5 months ago

! IMPORTANT:

This bug solution is resolve with update the dependency to version 4.3.0 and this resolve the error if you use the UI library MUI:

import {
    BaseTextFieldProps,
    InputAdornment,
    MenuItem,
    Select,
    TextField,
    Typography,
} from "@mui/material";
import type { CountryIso2 } from "react-international-phone";
import {
    FlagImage,
    defaultCountries,
    parseCountry,
    usePhoneInput,
} from "react-international-phone";

  interface MuiPhoneProps extends BaseTextFieldProps {
    value: string;
    onChange: (value: string) => void;
  }

  export default function MuiPhone({
    value,
    onChange,
    ...restProps
  }: MuiPhoneProps) {
    const { inputValue, phone, handlePhoneValueChange, inputRef, country, setCountry } =
        usePhoneInput({
        defaultCountry: "ua",
        value,
        countries: defaultCountries,
        onChange: (data) => {
          onChange(data.phone);
        },
          forceDialCode: true,

        });

      console.log(phone)

    return (
      <TextField
        variant="outlined"
        label="Phone number"
        color="primary"
        placeholder="Phone number"
        value={inputValue}
        onChange={handlePhoneValueChange}
        type="tel"
        inputRef={inputRef}
        InputProps={{
          startAdornment: (
            <InputAdornment
              position="start"
              style={{ marginRight: "2px", marginLeft: "-8px" }}
            >
              <Select
                MenuProps={{
                  style: {
                    height: "300px",
                    width: "360px",
                    top: "10px",
                    left: "-34px",
                  },
                  transformOrigin: {
                    vertical: "top",
                    horizontal: "left",
                  },
                }}
                sx={{
                  width: "max-content",
                  // Remove default outline (display only on focus)
                  fieldset: {
                    display: "none",
                  },
                  '&.Mui-focused:has(div[aria-expanded="false"])': {
                    fieldset: {
                      display: "block",
                    },
                  },
                  // Update default spacing
                  ".MuiSelect-select": {
                    padding: "8px",
                    paddingRight: "24px !important",
                  },
                  svg: {
                    right: 0,
                  },
                }}
                value={country}
                onChange={(e) => setCountry(e.target.value as CountryIso2)}
                renderValue={(value) => (
                  <FlagImage  iso2={value.iso2} style={{ display: "flex" }} />
                )}
              >
                {defaultCountries.map((c) => {
                  const country = parseCountry(c);
                  return (
                    <MenuItem key={country.iso2} value={country.iso2}>
                      <FlagImage
                        iso2={country.iso2}
                        style={{ marginRight: "8px" }}
                      />
                      <Typography marginRight="8px">{country.name}</Typography>
                      <Typography color="gray">+{country.dialCode}</Typography>
                    </MenuItem>
                  );
                })}
              </Select>
            </InputAdornment>
          ),
        }}
        {...restProps}
      />
    );
  }

Describe the bug

The phone component does not work correctly with default values and the forceDialCode prop. No matter how many times you provide data to set a default value, the component does not detect it if this property is active.

To Reproduce

Steps to reproduce the behavior:

  1. Go to the phone component setup.
  2. Set a default value for the phone number.
  3. Enable the forceDialCode prop.
  4. See error: The default value is not detected by the component.
  5. Expected behavior
  6. The phone component should correctly recognize and display the default value even when the forceDialCode prop is active.

Code sandbox

https://codesandbox.io/p/sandbox/react-international-phone-demo-forked-k3yj2c?

Additional context

This issue occurs when the forceDialCode prop is used in conjunction with setting a default phone number value. The component should properly initialize with the provided default value but fails to do so when forceDialCode is active.

camilopl33 commented 5 months ago

image

Note

I explored the code and tested further, and found that it only fails when the value doesn't start with the current dial code. I believe there is an issue with the second case condition in the phone number formatting logic.