catamphetamine / react-phone-number-input

React component for international phone number input
http://catamphetamine.gitlab.io/react-phone-number-input/
MIT License
925 stars 194 forks source link

Can Custom Inputs (inputComponent) Auto-format As User Types? #388

Closed austenator closed 2 years ago

austenator commented 3 years ago

I'm passing in a custom input (a wrapped MUI TextField) to PhoneInput's inputComponent prop, but now I don't get all the cool "auto-format-as-the-user-types" or "auto-detect-country-as-user-enters-number" functionality (see image below, it should be "+1 (333) 333"). image

Do I have to manually call formatPhoneNumber() during the onChange or is this expected behavior?

<PhoneInput placeholder={placeholderText}
    value={phoneNumber}
    defaultCountry={'US'}
    onChange={setPhoneNumber}
    inputComponent={PhoneNumberInput} />

While PhoneNumberInput is:

// Cut down for brevity
export const PhoneNumberInput = (props, ref) => {
  return (
    <TextField />
  );
};
export default forwardRef(PhoneNumberInput);
austenator commented 3 years ago

I'm dumb.

For future interested parties the solution was ensuring the onChange event was passed all the way to the inputComponent. This was tricky because for me the inputComponent (PhoneNumberInput) passes down through three children before getting to the <input />. Hope this helps others.

austenator commented 3 years ago

Just wanting to check in, so while I did get the "auto-format-as-the-user-types" working when the defaultCountry is present, when I remove the defaultCountry (and force international) I notice some discrepancies between no custom input and custom input:

No Custom Input (default):

<PhoneInput 
  international
  value={phoneNumber}
  onChange={setPhoneNumber} 
/>

https://user-images.githubusercontent.com/21992376/135346187-8d145e5a-fc3d-43cf-9352-2dbd57044b42.mov

Custom Input (my situation)

<PhoneInput
    international
    value={phoneNumber}
    onChange={setPhoneNumber}
   {... other props for custom input}
    inputComponent={PhoneNumberInput}
 />

https://user-images.githubusercontent.com/21992376/135346371-d77df80e-78c4-4d09-bd39-c1f77fa6dd1c.mov

Differences

  1. In default country calling code is automatically added (in this case '+' and '+1') as user types.
  2. In default, it formats as I type based on the country calling code ('+1 XXX XXX XXXX' vs '1XXXXXXXXX').

Are these differences supposed to behave the same between default & custom input or am I missing something?

Thanks!

catamphetamine commented 3 years ago

Seems like formatting doesn't work on your custom input in your environment, but weirdly it kinda works exclusively on Backspace. You could share a demo somewhere on codesandbox.io — maybe that would make things clearer. Or maybe it wouldn't.

austenator commented 3 years ago

@catamphetamine curious as to if you know any projects who utilize PhoneInput with a MUI (or other) custom component? That way I could self-troubleshoot.

My custom component wraps a few abstraction components (MyCustomInput -> MyTextField -> TextFieldWrapper -> MUI TextField) making it a HOC, so maybe that's the problem? But I know for sure the ref is being passed all the way down, so I'm guessing it has to do with the onChange event (but not sure since the is firing the onChange correctly).

but weirdly it kinda works exclusively on Backspace.

This is because it finally picks up the country of origin just before backspacing (the flag changes). The formatting works if the country is selected, but going from 'international' input without a country selected doesn't format the text the same.

I'll try to make that codesandbox and recreate it.

catamphetamine commented 3 years ago

curious as to if you know any projects who utilize PhoneInput with a MUI (or other) custom component? That way I could self-troubleshoot.

None.

My custom component wraps a few abstraction components (MyCustomInput -> MyTextField -> TextFieldWrapper -> MUI TextField) making it a HOC, so maybe that's the problem?

Could be anything.

The formatting works if the country is selected, but going from 'international' input without a country selected doesn't format the text the same.

I see.

austenator commented 2 years ago

I ended up resolving this by passing additional props from the PhoneInput component onwards to the custom input via {...props}. I also had to add the value from the phone input into the inputProps of my custom component. Hope this helps someone in the future. Cheers and thanks for the great component.