Skip to content

Commit b120bca

Browse files
committed
BREAKING: rename loadUtils to attachUtils and loadUtilsOnInit to loadUtils
1 parent 3b443ca commit b120bca

23 files changed

+548
-751
lines changed

Gruntfile.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ module.exports = function(grunt) {
2424
grunt.registerTask('js', ['shell:eslint', 'shell:genTsDeclaration', 'shell:genReactTsDeclaration', 'shell:buildJs', 'replace', 'react', 'vue']);
2525
grunt.registerTask('jsfast', ['shell:buildJs', 'replace']);
2626
// just react
27-
grunt.registerTask('react', ['replace:reactWithUtils', 'shell:buildReact', 'replace:removeImport']);
27+
grunt.registerTask('react', ['replace:reactWithUtils', 'shell:buildReact']);
2828
// just vue
29-
grunt.registerTask('vue', ['replace:vueWithUtils', 'shell:buildVue', 'replace:removeImport']);
29+
grunt.registerTask('vue', ['replace:vueWithUtils', 'shell:buildVue']);
3030

3131
// Run tests with a server so that async imports/fetches work.
3232
grunt.registerTask('jasmine:test', ['connect:test', 'jasmine']);

README.md

Lines changed: 48 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ _Note: We have now dropped support for all versions of Internet Explorer because
8484
<script>
8585
const input = document.querySelector("#phone");
8686
window.intlTelInput(input, {
87-
loadUtilsOnInit: "https://cdn.jsdelivr.net/npm/[email protected]/build/js/utils.js",
87+
loadUtils: () => import("https://cdn.jsdelivr.net/npm/[email protected]/build/js/utils.js"),
8888
});
8989
</script>
9090
```
@@ -110,20 +110,11 @@ _Note: We have now dropped support for all versions of Internet Explorer because
110110

111111
const input = document.querySelector("#phone");
112112
intlTelInput(input, {
113-
loadUtilsOnInit: () => import("intl-tel-input/utils")
113+
loadUtils: () => import("intl-tel-input/utils"),
114114
});
115115
```
116116

117-
Most bundlers (such as Webpack, Vite, or Parcel) will see this and place the [utilities script](#utilities-script) in a separate bundle and load it asynchronously, only when needed. If this doesn’t work with your bundler or you want to load the utils module from some other location (such as a CDN) you can set the `loadUtilsOnInit` option to the URL to load from as a string. For example:
118-
119-
```js
120-
import intlTelInput from 'intl-tel-input';
121-
122-
const input = document.querySelector("#phone");
123-
intlTelInput(input, {
124-
loadUtilsOnInit: `https://cdn.jsdelivr.net/npm/intl-tel-input@${intlTelInput.version}/build/js/utils.js`;
125-
});
126-
```
117+
Most bundlers (such as Webpack, Vite, or Parcel) will see this and place the [utilities script](#utilities-script) in a separate bundle and load it asynchronously, only when needed. If this doesn’t work with your bundler or you want to load the utils module from some other location (such as a CDN or your own hosted version), you can do that as well - see other examples.
127118

128119
## Getting Started (Not using a bundler)
129120
1. Download the [latest release](https://github.com/jackocnr/intl-tel-input/releases/latest), or better yet install it with [npm](https://www.npmjs.com/package/intl-tel-input)
@@ -149,7 +140,7 @@ intlTelInput(input, {
149140
<script>
150141
const input = document.querySelector("#phone");
151142
window.intlTelInput(input, {
152-
loadUtilsOnInit: "path/to/utils.js"
143+
loadUtils: () => import("https://my-domain/path/to/utils.js"),
153144
});
154145
</script>
155146
```
@@ -316,14 +307,33 @@ intlTelInput(input, {
316307
Type: `String` Default: `""`
317308
Set the initial country selection by specifying its country code e.g. `"us"` for the United States. (Be careful not to do this unless you are sure of the user's country, as it can lead to tricky issues if set incorrectly and the user auto-fills their national number and submits the form without checking - in certain cases, this can pass validation and you can end up storing a number with the wrong dial code). You can also set `initialCountry` to `"auto"`, which will look up the user's country based on their IP address (requires the `geoIpLookup` option - [see example](https://intl-tel-input.com/examples/lookup-country.html)). Note that however you use `initialCountry`, it will not update the country selection if the input already contains a number with an international dial code.
318309

319-
**loadUtilsOnInit** (see [v25 discussion](https://github.com/jackocnr/intl-tel-input/discussions/1842))
320-
Type: `String` or `() => Promise<module>` Default: `""` Example: `"/build/js/utils.js"`
310+
**loadUtils**
311+
Type: `() => Promise<module>` Default: `null` Example: `() => import("/path/to/utils.js")`
312+
313+
This is one way to lazy load the included utils.js (to enable formatting/validation etc) - see [Loading The Utilities Script](#loading-the-utilities-script) for more options.
321314

322-
This is one way to (lazy) load the included utils.js (to enable formatting/validation etc) - see [Loading The Utilities Script](#loading-the-utilities-script) for more options. You will need to host the [utils.js](https://github.com/jackocnr/intl-tel-input/blob/master/build/js/utils.js) file, and then set the `loadUtilsOnInit` option to that URL, or alternatively just point it to a CDN hosted version e.g. `"https://cdn.jsdelivr.net/npm/[email protected]/build/js/utils.js"`. The script is loaded via a [dynamic import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) statement, which means the URL cannot be relative - it must be absolute.
315+
The `loadUtils` option takes a function which returns a Promise which resolves to the utils module. You can `import` the utils module in different ways: (A) from a CDN, (B) from your own hosted version of [utils.js](https://github.com/jackocnr/intl-tel-input/blob/master/build/js/utils.js), or (C) if you use a bundler like Webpack, Vite or Parcel, you can import it directly from the package.
323316

324-
Alternatively, this can be a function that returns a promise for the utils module. When using a bundler like Webpack, this can be used to tell the bundler that the utils script should be kept in a separate file from the rest of your code. For example: `{ loadUtilsOnInit: () => import("intl-tel-input/utils") }`.
317+
```js
318+
// (A) import utils module from a CDN
319+
intlTelInput(htmlInputElement, {
320+
loadUtils: () => import("https://cdn.jsdelivr.net/npm/[email protected]/build/js/utils.js"),
321+
});
325322

326-
The script is only fetched when you initialise the plugin, and additionally, only when the page has finished loading (on the window load event) to prevent blocking (the script is ~260KB). When instantiating the plugin, a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) object is returned under the `promise` instance property, so you can do something like `iti.promise.then(callback)` to know when initialisation requests like this have finished. See [Utilities Script](#utilities-script) for more information.
323+
// (B) import utils module from your own hosted version of utils.js
324+
intlTelInput(htmlInputElement, {
325+
loadUtils: () => import("https://my-domain.com/path/to/utils.js"),
326+
});
327+
328+
// (C) if your bundler supports it, you can import utils module directly from the package
329+
intlTelInput(htmlInputElement, {
330+
loadUtils: () => import("intl-tel-input/utils"),
331+
});
332+
```
333+
334+
The module is only loaded when you initialise the plugin, and additionally, only when the page has finished loading (on the window load event) to prevent blocking (the script is ~260KB). When instantiating the plugin, a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) object is returned under the `promise` instance property, so you can do something like `iti.promise.then(callback)` to know when initialisation requests like this have finished. See [Utilities Script](#utilities-script) for more information.
335+
336+
If you want more control over when this file is lazy loaded, you can manually invoke the `attachUtils` static method whenever you like, instead of using the `loadUtils` initialisation option.
327337

328338
**nationalMode**
329339
Type: `Boolean` Default: `true`
@@ -355,11 +365,6 @@ As the user types in the input, ignore any irrelevant characters. The user can o
355365
Type: `Boolean` Default: `true on mobile devices, false otherwise`
356366
Control when the country list appears as a fullscreen popup vs an inline dropdown. By default, it will appear as a fullscreen popup on mobile devices (based on user-agent and screen width), to make better use of the limited space (similar to how a native `<select>` works), and as an inline dropdown on larger devices/screens. Play with this option on [Storybook](https://intl-tel-input.com/storybook/?path=/docs/intltelinput--usefullscreenpopup) (using the React component).
357367

358-
**utilsScript** ⚠️ DEPRECATED
359-
Type: `String` or `() => Promise<module>` Default: `""` Example: `"/build/js/utils.js"`
360-
361-
This option is deprecated and has been renamed to `loadUtilsOnInit`. Please see the deatails for that option and use it instead.
362-
363368
**validationNumberTypes**
364369
Type: `String` Default: `["MOBILE"]`
365370
Specify an array of [the keys](https://github.com/jackocnr/intl-tel-input/blob/master/src/js/utils.js#L162) from the enum `intlTelInput.utils.numberType` to set the number type(s) to enforce during validation with `isValidNumber`, as well as the number length to enforce with `strictMode`. Set it to `null` to not enforce any particular type. By default, it's set to `["MOBILE"]` so `isValidNumber` will only return `true` for mobile numbers. Alternatively, you could set it to `["TOLL_FREE", "PREMIUM_RATE"]` to get `isValidNumber` to return `true` for only those kinds of numbers.
@@ -493,18 +498,11 @@ const iti = intlTelInput.getInstance(input);
493498
iti.isValidNumber(); // etc
494499
```
495500

496-
**loadUtils** (see [v25 discussion](https://github.com/jackocnr/intl-tel-input/discussions/1842))
497-
An alternative to the `loadUtilsOnInit` option, this method lets you manually load the utils.js script on demand, to enable formatting/validation etc. See [Loading The Utilities Script](#loading-the-utilities-script) for more information. This method should only be called once per page. A [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) object is returned so you can use `loadUtils().then(callback)` to know when it's finished.
501+
**attachUtils**
502+
An alternative to the `loadUtils` option, this method lets you manually load the utils.js script on demand, to enable formatting/validation etc. See [Loading The Utilities Script](#loading-the-utilities-script) for more information. This method should only be called once per page. A [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) object is returned so you can use `attachUtils().then(...)` to know when it's finished.
498503
```js
499-
// Load from a URL:
500-
intlTelInput.loadUtils("/build/js/utils.js");
501-
502-
// Or manage load via some other method with a function:
503-
intlTelInput.loadUtils(async () => {
504-
// Your own loading logic here. Return a JavaScript "module" object with
505-
// the utils as the default export.
506-
return { default: { /* a copy of the utils module */ } }
507-
});
504+
const loadUtils = () => import("/build/js/utils.js");
505+
intlTelInput.attachUtils(loadUtils);
508506
```
509507

510508
## Events
@@ -592,18 +590,29 @@ The utils script provides lots of great functionality (see above section), but c
592590
**Option 1: intlTelInputWithUtils**
593591
If you're not concerned about filesize (e.g. you're lazy loading this script), the easiest thing to do is to just use the full bundle (`/build/js/intlTelInputWithUtils.js`), which comes with the utils script included. This script can be used exactly like the main intlTelInput.js - so it can either be loaded directly onto the page (which defines `window.intlTelInput` like usual), or it can be imported like so: `import intlTelInput from "intl-tel-input/intlTelInputWithUtils"`.
594592

595-
**Option 2: loadUtilsOnInit**
596-
If you *are* concerned about filesize, you can lazy load the utils script when the plugin initialises, using the `loadUtilsOnInit` initialisation option. You will need to host the [utils.js](https://github.com/jackocnr/intl-tel-input/blob/master/build/js/utils.js) file, and then set the `loadUtilsOnInit` option to that URL, or just point it to a CDN hosted version e.g. `"https://cdn.jsdelivr.net/npm/[email protected]/build/js/utils.js"`.
593+
**Option 2: loadUtils**
594+
If you *are* concerned about filesize, you can lazy load the utils module when the plugin initialises, using the `loadUtils` initialisation option.
597595

598-
Alternatively, you can set the `loadUtilsOnInit` option to a function that returns a promise for the utils script as a JS module object. If you use a bundler like Webpack, Vite, or Parcel to build your app, you can use it like this automatically separate the utils into a different bundle:
596+
The `loadUtils` option takes a function which returns a Promise which resolves to the utils module. You can `import` the utils module in different ways: (A) from a CDN, (B) from your own hosted version of [utils.js](https://github.com/jackocnr/intl-tel-input/blob/master/build/js/utils.js), or (C) if you use a bundler like Webpack, Vite or Parcel, you can import it directly from the package.
599597

600598
```js
599+
// (A) import utils module from a CDN
600+
intlTelInput(htmlInputElement, {
601+
loadUtils: () => import("https://cdn.jsdelivr.net/npm/[email protected]/build/js/utils.js"),
602+
});
603+
604+
// (B) import utils module from your own hosted version of utils.js
605+
intlTelInput(htmlInputElement, {
606+
loadUtils: () => import("https://my-domain.com/path/to/utils.js"),
607+
});
608+
609+
// (C) if your bundler supports it, you can import utils module directly from the package
601610
intlTelInput(htmlInputElement, {
602-
loadUtilsOnInit: () => import("intl-tel-input/utils)
611+
loadUtils: () => import("intl-tel-input/utils"),
603612
});
604613
```
605614

606-
If you want more control over when this file is lazy loaded, you can manually invoke the `loadUtils` static method, instead of using `loadUtilsOnInit`.
615+
If you want more control over when this file is lazy loaded, you can manually invoke the `attachUtils` static method whenever you like, instead of using the `loadUtils` initialisation option.
607616

608617
## Troubleshooting
609618

build/js/intlTelInput.d.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ declare module "intl-tel-input" {
299299
instances: {
300300
[key: string]: Iti;
301301
};
302-
loadUtils: (source: string | UtilsLoader) => Promise<unknown> | null;
302+
attachUtils: (source: UtilsLoader) => Promise<unknown> | null;
303303
startedLoadingAutoCountry: boolean;
304304
startedLoadingUtilsScript: boolean;
305305
version: string | undefined;
@@ -348,16 +348,14 @@ declare module "intl-tel-input" {
348348
}) | null;
349349
i18n: I18n;
350350
initialCountry: string;
351-
loadUtilsOnInit: string | UtilsLoader;
351+
loadUtils: UtilsLoader;
352352
nationalMode: boolean;
353353
onlyCountries: string[];
354354
placeholderNumberType: NumberType;
355355
showFlags: boolean;
356356
separateDialCode: boolean;
357357
strictMode: boolean;
358358
useFullscreenPopup: boolean;
359-
/** @deprecated Please use the `loadUtilsOnInit` option. */
360-
utilsScript: string | UtilsLoader;
361359
validationNumberTypes: NumberType[] | null;
362360
}
363361
export type SomeOptions = Partial<AllOptions>;

build/js/intlTelInput.js

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,8 +1664,8 @@ var factoryOutput = (() => {
16641664
i18n: {},
16651665
//* Initial country.
16661666
initialCountry: "",
1667-
//* Specify the path to the libphonenumber script to enable validation/formatting.
1668-
loadUtilsOnInit: "",
1667+
//* A function to load the utils script.
1668+
loadUtils: null,
16691669
//* National vs international formatting for numbers e.g. placeholders and displaying existing numbers.
16701670
nationalMode: true,
16711671
//* Display only these countries.
@@ -1686,8 +1686,6 @@ var factoryOutput = (() => {
16861686
navigator.userAgent
16871687
) || window.innerWidth <= 500
16881688
) : false,
1689-
//* Deprecated! Use `loadUtilsOnInit` instead.
1690-
utilsScript: "",
16911689
//* The number type to enforce during validation.
16921690
validationNumberTypes: ["MOBILE"]
16931691
};
@@ -2198,15 +2196,11 @@ var factoryOutput = (() => {
21982196
}
21992197
//* Init many requests: utils script / geo ip lookup.
22002198
_initRequests() {
2201-
let { loadUtilsOnInit, utilsScript, initialCountry, geoIpLookup } = this.options;
2202-
if (!loadUtilsOnInit && utilsScript) {
2203-
console.warn("intl-tel-input: The `utilsScript` option is deprecated and will be removed in a future release! Please use the `loadUtilsOnInit` option instead.");
2204-
loadUtilsOnInit = utilsScript;
2205-
}
2206-
if (loadUtilsOnInit && !intlTelInput.utils) {
2199+
let { loadUtils, initialCountry, geoIpLookup } = this.options;
2200+
if (loadUtils && !intlTelInput.utils) {
22072201
this._handlePageLoad = () => {
22082202
window.removeEventListener("load", this._handlePageLoad);
2209-
intlTelInput.loadUtils(loadUtilsOnInit)?.catch(() => {
2203+
intlTelInput.attachUtils(loadUtils)?.catch(() => {
22102204
});
22112205
};
22122206
if (intlTelInput.documentReady()) {
@@ -3088,33 +3082,23 @@ var factoryOutput = (() => {
30883082
}
30893083
}
30903084
};
3091-
var loadUtils = (source) => {
3085+
var attachUtils = (source) => {
30923086
if (!intlTelInput.utils && !intlTelInput.startedLoadingUtilsScript) {
30933087
let loadCall;
3094-
if (typeof source === "string") {
3095-
loadCall = import(
3096-
/* webpackIgnore: true */
3097-
/* @vite-ignore */
3098-
source
3099-
);
3100-
} else if (typeof source === "function") {
3088+
if (typeof source === "function") {
31013089
try {
31023090
loadCall = Promise.resolve(source());
31033091
} catch (error) {
31043092
return Promise.reject(error);
31053093
}
31063094
} else {
3107-
return Promise.reject(new TypeError(`The argument passed to loadUtils must be a URL string or a function that returns a promise for the utilities module, not ${typeof source}`));
3095+
return Promise.reject(new TypeError(`The argument passed to attachUtils must be a function that returns a promise for the utilities module, not ${typeof source}`));
31083096
}
31093097
intlTelInput.startedLoadingUtilsScript = true;
31103098
return loadCall.then((module) => {
31113099
const utils = module?.default;
31123100
if (!utils || typeof utils !== "object") {
3113-
if (typeof source === "string") {
3114-
throw new TypeError(`The module loaded from ${source} did not set utils as its default export.`);
3115-
} else {
3116-
throw new TypeError("The loader function passed to loadUtils did not resolve to a module object with utils as its default export.");
3117-
}
3101+
throw new TypeError("The loader function passed to attachUtils did not resolve to a module object with utils as its default export.");
31183102
}
31193103
intlTelInput.utils = utils;
31203104
forEachInstance("handleUtils");
@@ -3147,7 +3131,7 @@ var factoryOutput = (() => {
31473131
},
31483132
//* A map from instance ID to instance object.
31493133
instances: {},
3150-
loadUtils,
3134+
attachUtils,
31513135
startedLoadingUtilsScript: false,
31523136
startedLoadingAutoCountry: false,
31533137
version: "24.8.2"

build/js/intlTelInput.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)