jackocnr / intl-tel-input

A JavaScript plugin for entering and validating international telephone numbers
https://intl-tel-input.com
MIT License
7.36k stars 1.92k forks source link

Error trying to load the utilsScript from node_modules #1670

Closed r-agolli closed 1 week ago

r-agolli commented 2 weeks ago

Hi, Sorry i'm having dificulties importing the utilsScript file from node_modules for react app. If you could help would be great. I get 2 errors that appear when i want to load the local file of utils.js, but have no issue when im using the CDN for utils.js. The 2 errors are:

Here is the code i have, i have tried async await for lazy loading but still... Thanks beforehand: P.S im using the html markup and not the React Component since i wanted to give some styling i couldn't do with the component layout

import React, { useEffect, useRef, useState } from "react";
import intlTelInput from "intl-tel-input";
import "intl-tel-input/build/css/intlTelInput.css";
// import IntlTelInput from "intl-tel-input/react";
import en from "intl-tel-input/i18n/en";
import "./PhoneInput.css";

const errorMap = [
  "Invalid number",
  "Invalid country code",
  "Too short",
  "Too long",
  "Invalid number",
];

const PhoneInput = () => {
  const telInputRef = useRef(null);
  const [info, setInfo] = useState("");
  const [error, setError] = useState("");
  const [notice, setNotice] = useState("");

  useEffect(() => {
    const input = telInputRef.current;

    const utilss = async () => {
      return await import("intl-tel-input/build/js/utils.js");
    };

    const iti = intlTelInput(input, {
      i18n: en,
      separateDialCode: true,
      strictMode: true,
      useFullscreenPopup: false,
      utilsScript: utilss,
      // "https://cdn.jsdelivr.net/npm/intl-tel-input@23.1.0/build/js/utils.js",
      // "node_modules/intl-tel-input/build/js/utils.js?1716383386062", //1716383386062
      // "/node_modules/intl-tel-input/build/js/utils.js",
      // "/node_modules/intl-tel-input/build/js/utils.js?1716383386062",
    });

    return () => {
      iti.destroy();
    };
  }, []);

  return (
    <>
      <div className="w-full">
        <p>Enter your phone number:</p>
        <input
          id="phone"
          type="tel"
          name="phone"
          ref={telInputRef}
          className="phone-input"
        />
        <input type="submit" className="btn" value="Verify" />
      </div>
      {info && <div className="alert alert-info">{info}</div>}
      {error && <div className="alert alert-error">{error}</div>}
      {/* <form>
        <IntlTelInput
          ref={telInputRef}
          onChangeNumber={setNumber}
          onChangeValidity={setIsValid}
          onChangeErrorCode={setErrorCode}
          initOptions={{
            initialCountry: "us",
          }}
        />
        {/* <button className="button" type="button" onClick={handleSetNumber}>
          Set Number
        </button>
        <button className="button" type="button" onClick={handleSubmit}>
          Validate
        </button> */}
      {notice && <div className="notice">{notice}</div>}
    </>
  );
};

export default PhoneInput;
jackocnr commented 2 weeks ago

No it wont work when you pass the result of async await as the utilsScript option. As per the readme, the utilsScript option just takes the path to the utils.js. If it works when you pass the CDN URL, then the problem is with your local URL - you first need to host the utils.js file somewhere, and only when you can access that file by typing a URL in your browser, can you then pass that URL as the utilsScript option, if that makes sense. I'm afraid I can't help with your hosting issues - if you can't figure it out you might want to ask for help on StackOverflow etc.

As an alternative, if you're not worried about file size, you can just import intlTelInput from "intl-tel-input/intlTelInputWithUtils" to bundle the utils script with the main plugin JS, and then there's no need to use the utilsScript option.

P.S im using the html markup and not the React Component since i wanted to give some styling i couldn't do with the component layout

Can you give more detail about this? What exactly did you want to do that you couldn't?

r-agolli commented 1 week ago

Thanks a lot, i will just import the intlTelInputWithUtils since im not worried much rn about the file size. About the styling issue i mentioned is that i cannot directly implement for example tailwind classes. Have tried to do so, but still it doesnt react. Also tried to do direct styles or do css selectors for the React Component, but still it wont change it. Only way was to do it wish the input css selector, but that one is general and it messes up all the inputs, so not quite efficient. But thats why im using the html markup. But thanks a lot though, appreciate the help!

jackocnr commented 1 week ago

Hmm well yes I suppose if you wanted to add Tailwind CSS classes to different elements that are generated by the plugin, then there's no way to do that. Unfortunately, we generate so many different elements that it would be unrealistic to support adding custom CSS classes to every single one.

With that said, you have the same amount of control if you use the react component or the pure JS plugin. In both cases, you only have control over the input element. With the react component, you can pass the prop inputProps={{className: "something"}}. Is this not working for you?

What is it exactly that you can do with the JS plugin, which you can't do with the react component?

r-agolli commented 1 week ago

Ohh yeah greatt, thanks a lot. Didn't find this inputProps={{className: "something"}} in the documentation that it could be done this way. This is very helpful. Again thanks alot!!!

jackocnr commented 1 week ago

For future reference, if using the react component, make sure to check the readme here: https://github.com/jackocnr/intl-tel-input/tree/master/react

jackocnr commented 1 week ago

And note you can do import IntlTelInput from "intl-tel-input/reactWithUtils" to bundle utils, as we were discussing before.