Repository: jackocnr/intl-tel-input
Branch: master
Commit: 419966a2c2dc
Files: 394
Total size: 874.7 KB
Directory structure:
gitextract_v3v4kr9z/
├── .eslintignore
├── .eslintrc.js
├── .github/
│ ├── CONTRIBUTING.md
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── 1_bug_report.yml
│ │ ├── 2_feature_request.yml
│ │ └── config.yml
│ ├── copilot-instructions.md
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── .gitmodules
├── .node-version
├── .npmrc
├── .vscode/
│ ├── extensions.json
│ └── settings.json
├── CHANGELOG.md
├── Gruntfile.js
├── LICENSE
├── README.md
├── angular/
│ ├── README.md
│ ├── build.js
│ ├── demo/
│ │ ├── form/
│ │ │ ├── form.component.ts
│ │ │ ├── index.html
│ │ │ └── main.ts
│ │ ├── set-number/
│ │ │ ├── index.html
│ │ │ ├── main.ts
│ │ │ └── set-number.component.ts
│ │ ├── simple/
│ │ │ ├── index.html
│ │ │ ├── main.ts
│ │ │ └── simple.component.ts
│ │ ├── toggle-disabled/
│ │ │ ├── index.html
│ │ │ ├── main.ts
│ │ │ └── toggle-disabled.component.ts
│ │ └── validation/
│ │ ├── index.html
│ │ ├── main.ts
│ │ └── validation.component.ts
│ ├── src/
│ │ └── intl-tel-input/
│ │ ├── angular.ts
│ │ └── angularWithUtils.ts
│ └── tsconfig.json
├── build.js
├── composer.json
├── cspell.json
├── demo.html
├── functions/
│ └── _middleware.js
├── grunt/
│ ├── bump.js
│ ├── clean.js
│ ├── closure-compiler.js
│ ├── connect.js
│ ├── cssmin.js
│ ├── generate-sprite.js
│ ├── replace.js
│ ├── sass.js
│ ├── shell.js
│ ├── translations.js
│ └── watch.js
├── index.js
├── jest.config.js
├── package.json
├── playwright.config.ts
├── react/
│ ├── README.md
│ ├── build.js
│ ├── demo/
│ │ ├── set-number/
│ │ │ ├── SetNumberApp.tsx
│ │ │ └── set-number.html
│ │ ├── simple/
│ │ │ ├── SimpleApp.tsx
│ │ │ └── simple.html
│ │ ├── toggle-disabled/
│ │ │ ├── ToggleDisabledApp.tsx
│ │ │ └── toggle-disabled.html
│ │ └── validation/
│ │ ├── ValidationApp.tsx
│ │ └── validation.html
│ ├── src/
│ │ └── intl-tel-input/
│ │ ├── react.tsx
│ │ └── reactWithUtils.tsx
│ └── tsconfig.json
├── scripts/
│ ├── check-lpn-metadata.cjs
│ └── playwright-linux-docker.sh
├── site/
│ ├── .gitignore
│ ├── Gruntfile.js
│ ├── README.md
│ ├── esbuild/
│ │ ├── build.mjs
│ │ └── externalUtilsPlugin.mjs
│ ├── grunt/
│ │ ├── copy.js
│ │ ├── cssmin.js
│ │ ├── fetchStats.js
│ │ ├── replace.js
│ │ ├── sass.js
│ │ ├── shell.js
│ │ ├── template.js
│ │ ├── templateGruntHelpers.js
│ │ ├── templateNav.js
│ │ ├── templateUtils.js
│ │ └── watch.js
│ ├── package.json
│ ├── src/
│ │ ├── 404/
│ │ │ ├── 404_content.html
│ │ │ └── 404_page_template.html.ejs
│ │ ├── css/
│ │ │ ├── _base.scss
│ │ │ ├── _forms.scss
│ │ │ ├── _layout.scss
│ │ │ ├── _navbar.scss
│ │ │ ├── _variables.scss
│ │ │ ├── docs.scss
│ │ │ ├── highlightjs_overrides.scss
│ │ │ ├── homepage.scss
│ │ │ ├── large_flags_overrides.scss
│ │ │ ├── playground.scss
│ │ │ └── website.scss
│ │ ├── docs/
│ │ │ ├── docs_content_template.html.ejs
│ │ │ ├── docs_nav_template.html.ejs
│ │ │ ├── docs_page_template.html.ejs
│ │ │ └── markdown/
│ │ │ ├── accessibility.md
│ │ │ ├── angular_component.md
│ │ │ ├── choose_integration.md
│ │ │ ├── events.md
│ │ │ ├── faq.md
│ │ │ ├── getting_started.md
│ │ │ ├── localisation.md
│ │ │ ├── methods.md
│ │ │ ├── options.md
│ │ │ ├── react_component.md
│ │ │ ├── svelte_component.md
│ │ │ ├── theming.md
│ │ │ ├── troubleshooting.md
│ │ │ ├── utils.md
│ │ │ └── vue_component.md
│ │ ├── examples/
│ │ │ ├── copy/
│ │ │ │ ├── angular_component_desc.html
│ │ │ │ ├── display_number_desc.html
│ │ │ │ ├── hidden_input_desc.html
│ │ │ │ ├── large_flags_desc.html
│ │ │ │ ├── lookup_country_desc.html
│ │ │ │ ├── multiple_instances_desc.html
│ │ │ │ ├── react_component_desc.html
│ │ │ │ ├── right_to_left_desc.html
│ │ │ │ ├── single_country_desc.html
│ │ │ │ ├── svelte_component_desc.html
│ │ │ │ ├── validation_practical_desc.html
│ │ │ │ ├── validation_precise_desc.html
│ │ │ │ └── vue_component_desc.html
│ │ │ ├── css/
│ │ │ │ ├── multiple_instances.css
│ │ │ │ └── validation.css
│ │ │ ├── examples_content_template.html.ejs
│ │ │ ├── examples_nav_template.html.ejs
│ │ │ ├── examples_page_template.html.ejs
│ │ │ ├── html/
│ │ │ │ ├── component.html
│ │ │ │ ├── display_number.html
│ │ │ │ ├── display_number_display_code.html
│ │ │ │ ├── multiple_instances.html
│ │ │ │ ├── multiple_instances_display_code.html
│ │ │ │ ├── simple_input.html
│ │ │ │ ├── simple_input_display_code.html
│ │ │ │ ├── validation.html
│ │ │ │ └── validation_display_code.html
│ │ │ └── js/
│ │ │ ├── angular_component.ts
│ │ │ ├── angular_component_display_code.js
│ │ │ ├── hidden_input.js
│ │ │ ├── hidden_input_display_code.js
│ │ │ ├── lookup_country.js
│ │ │ ├── lookup_country_display_code.js
│ │ │ ├── multiple_instances.js
│ │ │ ├── multiple_instances_display_code.js
│ │ │ ├── react_component.js
│ │ │ ├── react_component_display_code.js
│ │ │ ├── right_to_left.js
│ │ │ ├── right_to_left_display_code.js
│ │ │ ├── simple_init_plugin.js
│ │ │ ├── simple_init_plugin_display_code.js
│ │ │ ├── single_country.js
│ │ │ ├── single_country_display_code.js
│ │ │ ├── svelte_component.svelte
│ │ │ ├── svelte_component_display_code.svelte
│ │ │ ├── svelte_main.js
│ │ │ ├── validation.js
│ │ │ ├── validation_display_code.js
│ │ │ ├── viteSvelteDemo.config.mjs
│ │ │ ├── viteVueDemo.config.js
│ │ │ ├── vue_component.vue
│ │ │ ├── vue_component_display_code.vue
│ │ │ └── vue_main.js
│ │ ├── homepage/
│ │ │ ├── homepage_content.html
│ │ │ └── homepage_page_template.html.ejs
│ │ ├── js/
│ │ │ ├── homepage.js
│ │ │ └── iti-live-results.js
│ │ ├── layout_template.html.ejs
│ │ ├── playground/
│ │ │ ├── js/
│ │ │ │ ├── modules/
│ │ │ │ │ ├── clipboard.js
│ │ │ │ │ ├── forms.js
│ │ │ │ │ ├── i18n.js
│ │ │ │ │ ├── initCode.js
│ │ │ │ │ ├── itiController.js
│ │ │ │ │ ├── playgroundConfig.js
│ │ │ │ │ ├── stateUtils.js
│ │ │ │ │ └── urlState.js
│ │ │ │ ├── playground.js
│ │ │ │ └── templates/
│ │ │ │ └── playgroundConstants.js.ejs
│ │ │ ├── playground_content.html
│ │ │ └── playground_page_template.html.ejs
│ │ └── shared/
│ │ ├── common_body_end.html
│ │ ├── common_head_end_prod.html
│ │ ├── common_meta_tags.html
│ │ ├── common_styles.html.ejs
│ │ ├── iti_live_results_script.html.ejs
│ │ └── iti_script.html.ejs
│ └── static/
│ ├── _redirects
│ ├── ads.txt
│ ├── css/
│ │ └── intlTelInput-largeFlags.css
│ └── screenshotting.html
├── src/
│ ├── css/
│ │ ├── _metadata.scss
│ │ ├── demo.scss
│ │ ├── intlTelInput.scss
│ │ └── intlTelInputWithAssets.scss
│ └── js/
│ ├── intl-tel-input/
│ │ ├── data.ts
│ │ ├── i18n/
│ │ │ ├── ar/
│ │ │ │ └── index.ts
│ │ │ ├── bg/
│ │ │ │ └── index.ts
│ │ │ ├── bn/
│ │ │ │ └── index.ts
│ │ │ ├── bs/
│ │ │ │ └── index.ts
│ │ │ ├── ca/
│ │ │ │ └── index.ts
│ │ │ ├── cs/
│ │ │ │ └── index.ts
│ │ │ ├── da/
│ │ │ │ └── index.ts
│ │ │ ├── de/
│ │ │ │ └── index.ts
│ │ │ ├── el/
│ │ │ │ └── index.ts
│ │ │ ├── en/
│ │ │ │ └── index.ts
│ │ │ ├── es/
│ │ │ │ └── index.ts
│ │ │ ├── et/
│ │ │ │ └── index.ts
│ │ │ ├── fa/
│ │ │ │ └── index.ts
│ │ │ ├── fi/
│ │ │ │ └── index.ts
│ │ │ ├── fr/
│ │ │ │ └── index.ts
│ │ │ ├── hi/
│ │ │ │ └── index.ts
│ │ │ ├── hr/
│ │ │ │ └── index.ts
│ │ │ ├── hu/
│ │ │ │ └── index.ts
│ │ │ ├── id/
│ │ │ │ └── index.ts
│ │ │ ├── index.ts
│ │ │ ├── it/
│ │ │ │ └── index.ts
│ │ │ ├── ja/
│ │ │ │ └── index.ts
│ │ │ ├── kn/
│ │ │ │ └── index.ts
│ │ │ ├── ko/
│ │ │ │ └── index.ts
│ │ │ ├── lt/
│ │ │ │ └── index.ts
│ │ │ ├── mr/
│ │ │ │ └── index.ts
│ │ │ ├── nl/
│ │ │ │ └── index.ts
│ │ │ ├── no/
│ │ │ │ └── index.ts
│ │ │ ├── pl/
│ │ │ │ └── index.ts
│ │ │ ├── pt/
│ │ │ │ └── index.ts
│ │ │ ├── ro/
│ │ │ │ └── index.ts
│ │ │ ├── ru/
│ │ │ │ └── index.ts
│ │ │ ├── sk/
│ │ │ │ └── index.ts
│ │ │ ├── sl/
│ │ │ │ └── index.ts
│ │ │ ├── sq/
│ │ │ │ └── index.ts
│ │ │ ├── sr/
│ │ │ │ └── index.ts
│ │ │ ├── sv/
│ │ │ │ └── index.ts
│ │ │ ├── te/
│ │ │ │ └── index.ts
│ │ │ ├── th/
│ │ │ │ └── index.ts
│ │ │ ├── tr/
│ │ │ │ └── index.ts
│ │ │ ├── types.ts
│ │ │ ├── uk/
│ │ │ │ └── index.ts
│ │ │ ├── ur/
│ │ │ │ └── index.ts
│ │ │ ├── uz/
│ │ │ │ └── index.ts
│ │ │ ├── vi/
│ │ │ │ └── index.ts
│ │ │ ├── zh/
│ │ │ │ └── index.ts
│ │ │ └── zh-hk/
│ │ │ └── index.ts
│ │ └── intlTelInputWithUtils.ts
│ ├── intl-tel-input.ts
│ ├── modules/
│ │ ├── constants.ts
│ │ ├── core/
│ │ │ ├── countrySearch.ts
│ │ │ ├── icons.ts
│ │ │ ├── numerals.ts
│ │ │ ├── options.ts
│ │ │ └── ui.ts
│ │ ├── data/
│ │ │ ├── country-data.ts
│ │ │ ├── intl-regionless.ts
│ │ │ └── nanp-regionless.ts
│ │ ├── format/
│ │ │ ├── caret.ts
│ │ │ └── formatting.ts
│ │ ├── types/
│ │ │ ├── events.ts
│ │ │ ├── forEachInstanceArgsMap.ts
│ │ │ └── public-api.ts
│ │ └── utils/
│ │ ├── dom.ts
│ │ ├── isAndroid.ts
│ │ └── string.ts
│ └── utils.js
├── svelte/
│ ├── README.md
│ ├── demo/
│ │ ├── set-number/
│ │ │ ├── App.svelte
│ │ │ ├── index.html
│ │ │ ├── main.js
│ │ │ └── vite.config.mjs
│ │ ├── simple/
│ │ │ ├── App.svelte
│ │ │ ├── index.html
│ │ │ ├── main.js
│ │ │ └── vite.config.mjs
│ │ ├── toggle-disabled/
│ │ │ ├── App.svelte
│ │ │ ├── index.html
│ │ │ ├── main.js
│ │ │ └── vite.config.mjs
│ │ └── validation/
│ │ ├── App.svelte
│ │ ├── index.html
│ │ ├── main.js
│ │ └── vite.config.mjs
│ ├── src/
│ │ └── intl-tel-input/
│ │ ├── IntlTelInput.svelte
│ │ └── IntlTelInputWithUtils.svelte
│ ├── viteConfig.mjs
│ └── viteConfigWithUtils.mjs
├── tests/
│ ├── integration/
│ │ ├── core/
│ │ │ ├── dropdownShortcuts.test.js
│ │ │ ├── easternNumerals.test.js
│ │ │ ├── initialValues.test.js
│ │ │ ├── multipleInstances.test.js
│ │ │ ├── regionless.test.js
│ │ │ ├── usingDropdown.test.js
│ │ │ └── usingInput.test.js
│ │ ├── events/
│ │ │ ├── closeCountryDropdownEvent.test.js
│ │ │ ├── countryChangeEvent.test.js
│ │ │ └── openCountryDropdownEvent.test.js
│ │ ├── helpers/
│ │ │ ├── helpers.js
│ │ │ └── matchers.js
│ │ ├── methods/
│ │ │ ├── destroy.test.js
│ │ │ ├── getExtension.test.js
│ │ │ ├── getInstance.test.js
│ │ │ ├── getNumber.test.js
│ │ │ ├── getNumberType.test.js
│ │ │ ├── getSelectedCountryData.test.js
│ │ │ ├── getValidationError.test.js
│ │ │ ├── isValidNumber.test.js
│ │ │ ├── isValidNumberPrecise.test.js
│ │ │ ├── setCountry.test.js
│ │ │ ├── setDisabled.test.js
│ │ │ ├── setNumber.test.js
│ │ │ └── setPlaceholderNumberType.test.js
│ │ ├── options/
│ │ │ ├── allowDropdown.test.js
│ │ │ ├── allowNumberExtensions.test.js
│ │ │ ├── allowPhonewords.test.js
│ │ │ ├── allowedNumberTypes.test.js
│ │ │ ├── autoPlaceholder.test.js
│ │ │ ├── containerClass.test.js
│ │ │ ├── countryNameLocale.test.js
│ │ │ ├── countryOrder.test.js
│ │ │ ├── countrySearch.test.js
│ │ │ ├── customPlaceholder.test.js
│ │ │ ├── dropdownContainer.test.js
│ │ │ ├── excludeCountries.test.js
│ │ │ ├── fixDropdownWidth.test.js
│ │ │ ├── formatAsYouType.test.js
│ │ │ ├── formatOnDisplay.test.js
│ │ │ ├── geoIpLookup.test.js
│ │ │ ├── hiddenInput.test.js
│ │ │ ├── i18n-locales.test.js
│ │ │ ├── i18n.test.js
│ │ │ ├── initialCountry.test.js
│ │ │ ├── loadUtils.test.js
│ │ │ ├── nationalMode.test.js
│ │ │ ├── onlyCountries.test.js
│ │ │ ├── placeholderNumberType.test.js
│ │ │ ├── separateDialCode.test.js
│ │ │ ├── showFlags.test.js
│ │ │ ├── strictMode.test.js
│ │ │ └── useFullscreenPopup.test.js
│ │ └── static/
│ │ ├── attachUtils.test.js
│ │ ├── defaults.test.js
│ │ └── getCountryData.test.js
│ └── unit/
│ ├── core/
│ │ ├── countrySearch.test.js
│ │ └── options.test.js
│ ├── data/
│ │ ├── country-data.test.js
│ │ └── nanp-regionless.test.js
│ ├── format/
│ │ ├── caret.test.js
│ │ └── formatting.test.js
│ ├── intl-tel-input/
│ │ └── constructor.test.js
│ └── utils/
│ ├── dom.test.js
│ └── string.test.js
├── tests-e2e/
│ ├── angular.spec.ts
│ ├── fixtures/
│ │ └── vanilla.html
│ ├── react.spec.ts
│ ├── simple.spec.ts
│ ├── svelte.spec.ts
│ ├── visual.spec.ts
│ └── vue.spec.ts
├── tsconfig.json
└── vue/
├── README.md
├── demo/
│ ├── set-number/
│ │ ├── App.vue
│ │ ├── index.html
│ │ ├── main.js
│ │ └── vite.config.js
│ ├── simple/
│ │ ├── App.vue
│ │ ├── index.html
│ │ ├── main.js
│ │ └── vite.config.js
│ ├── toggle-disabled/
│ │ ├── App.vue
│ │ ├── index.html
│ │ ├── main.js
│ │ └── vite.config.js
│ └── validation/
│ ├── App.vue
│ ├── index.html
│ ├── main.js
│ └── vite.config.js
├── src/
│ ├── IntlTelInput.vue
│ ├── IntlTelInputWithUtils.vue
│ ├── env.d.ts
│ └── exports/
│ ├── IntlTelInput.ts
│ └── IntlTelInputWithUtils.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.mts
================================================
FILE CONTENTS
================================================
================================================
FILE: .eslintignore
================================================
**/demo/**
**/grunt/**
**/build/**
**/third_party/**
**/tmp/**
Gruntfile.js
**/intl-tel-input/utils.js
site/static/js/highlight.min.js
site/static/js/silktide-consent-manager.js
site/src/examples/js/*_display_code*
playwright-report/
================================================
FILE: .eslintrc.js
================================================
module.exports = {
root: true,
env: {
browser: true,
es2021: true,
node: true,
"jest/globals": true,
},
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
],
parser: "@typescript-eslint/parser",
parserOptions: {
"ecmaVersion": "latest",
"sourceType": "module",
},
plugins: [
"@typescript-eslint",
"react",
"jest",
],
globals: {
goog: true,
i18n: true,
require: true,
},
rules: {
semi: ["error", "always"],
"comma-dangle": ["error", "always-multiline"],
quotes: ["error", "double"],
"no-unused-vars": "off",
"no-prototype-builtins": "off",
"class-methods-use-this": "error",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-unused-vars": ["error", {
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"caughtErrorsIgnorePattern": "^_",
"ignoreRestSiblings": true,
}],
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-require-imports": "off",
},
overrides: [{
files: [".eslintrc.{js,cjs}"],
env: { "node": true },
parserOptions: { "sourceType": "script" },
}],
settings: {
"import/resolver": {
"typescript": {},
},
"react": {
"version": "detect",
},
},
};
================================================
FILE: .github/CONTRIBUTING.md
================================================
# Contributing
I'm very open to contributions, big and small! For general instructions on submitting a pull request on GitHub, see these guides: [Fork A Repo](https://help.github.com/articles/fork-a-repo) and [Creating a pull request from a fork](https://help.github.com/articles/creating-a-pull-request-from-a-fork/).
## Table of Contents
- [Changes to the plugin](#changes-to-the-plugin)
- [Updating the flag images](#updating-the-flag-images)
- [Adding a new translation](#adding-a-new-translation)
## Changes to the plugin
### Setup
Once you have [forked the repository](https://help.github.com/articles/fork-a-repo) and checked out your fork on your local machine, you need to initialise the submodules with `git submodule update --init --recursive`, then run `npm install`, and then `npm run build`. You should now be able to open the included demo.html in your browser and have a working plugin!
### Making changes
Any time you make changes, you’ll need to rebuild the plugin. You can run `npm run watch` to do this automatically. Else you can manually run one of the build commands below:
- `npm run build` to build everything (slow)
- Builds flag images, translations, CSS, and all of the JS (see below)
- `npm run build:js` to build all of the JS (slow)
- Builds utils script, main plugin module, TS type declaration files, react/vue/angular/svelte components and demo bundles
- `npm run build:jsfast` to just build the JS needed for the demo/tests (fast)
- `npm run build:css` to just build the CSS (fast)
- And lots more - see [package.json "scripts" section](https://github.com/jackocnr/intl-tel-input/blob/master/package.json#L7-L29) for full list
### Tests
After building all the assets (`npm run build`) you can run `npm test` to run all the tests (Jest + Playwright). For Playwright, you may also need to install the browsers first with `npx playwright install`.
## Updating the flag images
We get our flags from the [flag-icons](https://github.com/lipis/flag-icons) project. If there is a problem with the flags, you'll need to raise it with them. When there is an update in that project that you want to pull into this project, you can update the npm package with `npm install flag-icons@VERSION --save-dev`, and then rebuild the flag sprite images with `npm run build:img`. Once you've checked everything looks ok (by opening the included demo.html in your browser), you can then create a pull request on GitHub. _NOTE: since we removed the build files from the repo, the only changes you will be committing are in package.json and package-lock.json._
## Adding a new translation
NOTE: that country names are now translated automatically using the native `Intl.DisplayNames` (see `countryNameLocale` option), so there's no need to provide translations for these anymore.
The [provided translations](https://github.com/jackocnr/intl-tel-input/tree/master/src/js/intl-tel-input/i18n) are now just for the user interface strings (e.g. the country search placeholder). If we don't yet support a language you need, it's easy to contribute this yourself - you only need to provide a handful of strings (for example, see the [English translations](https://github.com/jackocnr/intl-tel-input/blob/master/src/js/intl-tel-input/i18n/en/index.ts)).
The translation files are located in src/js/intl-tel-input/i18n/. There is a directory for each language we support (e.g. "en" for English). Inside each of these directories, there is an index.ts, which contains the translations. All you need to do to add a new translation is create a new language directory, create the index.ts file and populate it with your translation strings, following the same pattern as the other languages.
If you haven't already, you will need to run `npm install` to install the project dependencies, and then you can run `npm run build:translations` to automatically add your new language to the root index.ts file. Once you have tested and confirmed that the new translations are working, you can create a pull request on GitHub.
================================================
FILE: .github/FUNDING.yml
================================================
github: jackocnr
================================================
FILE: .github/ISSUE_TEMPLATE/1_bug_report.yml
================================================
name: Bug Report
description: Report a bug or issue with intl-tel-input
labels: ["bug"]
body:
- type: checkboxes
attributes:
label: Prerequisites
description: Take a couple of minutes to help our maintainers work faster.
options:
- label: I am using the latest version (v26.8.1) of both intl-tel-input and utils.js.
required: true
- label: This plugin uses libphonenumber for formatting, validation, and placeholder numbers. If my issue relates to one of these things, I confirm I have used their [test site](https://libphonenumber.appspot.com) to ensure the issue is not with them, and will provide a link to the test results page showing this. Else, I have [reported the issue](https://github.com/google/libphonenumber/blob/master/CONTRIBUTING.md) to them instead of here.
required: true
- label: I have searched the existing issues (including closed issues) to ensure this has not already been discussed.
required: true
- type: textarea
id: current
attributes:
label: Current behaviour
description: A concise description of what you're experiencing.
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behaviour
description: A concise description of what you expected to happen.
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to reproduce
description: How can we reproduce the issue? (e.g. provide a [Playground](https://intl-tel-input.com/playground) link with the right configuration)
value: |
1.
2.
3.
validations:
required: true
- type: textarea
id: comments
attributes:
label: Anything else?
description: Additional comments, screenshots/videos, initialisation options, browser/device info, etc.
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/2_feature_request.yml
================================================
name: Feature Request
description: Suggest a new feature or improvement
labels: ["enhancement"]
body:
- type: textarea
id: description
attributes:
label: Description
description: Describe the feature or improvement you'd like to see.
validations:
required: true
- type: textarea
id: use-case
attributes:
label: Use case
description: Why do you need this feature? What problem does it solve?
validations:
required: true
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: Ask the community
url: https://github.com/jackocnr/intl-tel-input/discussions
about: Ask questions and get help from the community
================================================
FILE: .github/copilot-instructions.md
================================================
At the beginning of a chat, remind me to run `npm run watch`, so any changes get automatically built, meaning I can manually test them in the browser, and also when you run the tests, they will be running the latest code. Do not offer to run the build command yourself. Do not ever make changes to files in the build/ directories, e.g. the root ./build/ directory, or the component build/ directories (angular/build/, react/build/, svelte/build/ and vue/build/). These files are auto-generated, so do not update them.
When making changes to the root src/ directory, do not touch any of the files in the component directories (angular/, react/, svelte/ and vue/). A lot of the files in those directories are just symlinks to the root src/ directory.
When making changes to the root src/ code, make sure to also update the tests (in the root tests/ directory) if necessary, and run the tests to make sure they are passing.
When making changes to the root src/ code, make sure to also update the website documentation and example pages if necessary. The documentation is located in the site/src/docs/ directory, and the examples are located in the site/src/examples/ directory. If you are not sure how to update the documentation or examples, just ask me.
When writing code, prioritise clarity and brevity. Try to follow the existing code style as much as possible.
When making changes in the root site/ directory, remember there are no tests for this, so don't bother running the tests. This also applies to the component directories (angular/, react/, svelte/ and vue/), as they also don't have tests.
When making changes in the component directories (angular/, react/, svelte/ and vue/), note that the "withUtils" files are auto-generated, so do not update them. For example, when making changes to react/src/intl-tel-input/react.tsx, do not update react/src/intl-tel-input/react-withUtils.tsx, as it is auto-generated. The same applies to the other component directories.
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
push:
branches: [ "**" ]
pull_request:
branches: [ "**" ]
permissions:
contents: read
jobs:
build-and-test:
name: Build and Test (Node ${{ matrix.node-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [20]
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Run JS tests
run: npm run test:js -- --runInBand
- name: Run e2e tests
run: npm run test:e2e:linux
- name: Upload Playwright artifacts
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright
path: |
playwright-report/
test-results/
================================================
FILE: .gitignore
================================================
/node_modules/
/lib/*
!/lib/libphonenumber
/.sass-cache/
/.grunt/
/tmp/
/vendor/
/.idea/
*.iml
.DS_Store
/build/
/react/build/
/svelte/build/
/vue/build/
/angular/build/
/*/demo/*/*-bundle.js
/test-results/
/playwright-report/
/.claude/
================================================
FILE: .gitmodules
================================================
[submodule "third_party/libphonenumber"]
path = third_party/libphonenumber
url = https://github.com/google/libphonenumber
================================================
FILE: .node-version
================================================
v20.12.0
================================================
FILE: .npmrc
================================================
# Jest uses the `vm` module, which does not have production ready module support
# yet. This option lets us use dynamic imports.
node-options='--experimental-vm-modules'
================================================
FILE: .vscode/extensions.json
================================================
{
"recommendations": [
"rvest.vs-code-prettier-eslint",
"davidanson.vscode-markdownlint",
"aaron-bond.better-comments"
]
}
================================================
FILE: .vscode/settings.json
================================================
{
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint",
"editor.formatOnPaste": false, //* required
"editor.formatOnType": false, //* required
"editor.formatOnSaveMode": "file", //* required to format on save
"vs-code-prettier-eslint.prettierLast": false, //* set as "true" to run 'prettier' last not first
"typescript.tsdk": "node_modules/typescript/lib",
"files.associations": {
"LICENSE": "text",
},
"markdownlint.config": {
"blanks-around-headings": false,
"blanks-around-lists": false,
"ul-style": false,
"blanks-around-fences": false,
"ol-prefix": false,
"no-inline-html": false,
},
"cSpell.language": "en-GB",
"cSpell.enabledLanguageIds": [
"asciidoc",
"c",
"cpp",
"csharp",
"css",
"dotenv",
"go",
"handlebars",
"html",
"ignore",
"jade",
"java",
"javascript",
"javascriptreact",
"json",
"jsonc",
"latex",
"less",
"markdown",
"php",
"plaintext",
"pug",
"python",
"restructuredtext",
"rust",
"scala",
"scss",
"text",
"typescript",
"typescriptreact",
"yaml",
"yml",
"COBOL",
"ACUCOBOL"
],
"files.trimTrailingWhitespace": true,
"[markdown]": {
"files.trimTrailingWhitespace": false
}
}
================================================
FILE: CHANGELOG.md
================================================
See the Github Releases page for changelog: https://github.com/jackocnr/intl-tel-input/releases
Or to view a specific version, e.g. v20.0.0, update the URL accordingly, e.g. https://github.com/jackocnr/intl-tel-input/releases/tag/v20.0.0
## Breaking changes
- v26.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v26.0.0
- v25.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v25.0.0
- v24.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v24.0.0
- v23.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v23.0.0
- v22.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v22.0.0
- v21.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v21.0.0
- v20.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v20.0.0
- v19.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v19.0.0
- v18.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v18.0.0
- v17.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v17.0.0
- v16.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v16.0.0
- v15.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v15.0.0
- v14.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v14.0.0
- v13.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v13.0.0
- v12.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v12.0.0
- v11.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v11.0.0
- v10.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v10.0.0
- v9.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v9.0.0
- v8.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v8.0.0
- v7.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v7.0.0
- v6.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v6.0.0
- v5.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v5.0.0
- v4.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v4.0.0
- v3.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v3.0.0
- v2.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v2.0.0
- v1.0.0 https://github.com/jackocnr/intl-tel-input/releases/tag/v1.0.0
================================================
FILE: Gruntfile.js
================================================
module.exports = function(grunt) {
// load all tasks from package.json
require('load-grunt-config')(grunt);
require('time-grunt')(grunt);
require('google-closure-compiler').grunt(grunt, {
platfrom: 'native'
});
/**
* BUILD TASKS
*/
// build everything ready for a commit
grunt.registerTask('build', [
'clean:allBuild',
'build:img',
'translations',
'build:js',
]);
// build translations
grunt.registerTask('build:translations', [
'clean:buildJs',
'clean:tmpIntermediates',
'translations',
'build:js',
]);
// build utils
grunt.registerTask('build:utils', [
'clean:utils',
'closure-compiler:utils',
'shell:checkLpnMetadata',
]);
// just CSS
grunt.registerTask('build:css', [
'clean:buildCss',
'sass',
'cssmin',
]);
// just images (and CSS)
grunt.registerTask('build:img', [
'clean:buildImg',
'generate-sprite',
'build:css',
]);
// just javascript
grunt.registerTask('build:js', [
'clean:buildJs',
'clean:tmpIntermediates',
'shell:eslint',
'closure-compiler:utils',
'shell:genTsDeclaration',
'shell:buildJs',
'build:components',
]);
// just 4 components
grunt.registerTask('build:components', [
'clean:reactBuild',
'clean:vueBuild',
'clean:angularBuild',
'clean:svelteBuild',
'build:react',
'build:vue',
'build:angular',
'build:svelte',
]);
// Ensure build/js/utils.js exists (src/js/intl-tel-input/utils.js is a symlink to it).
grunt.registerTask('ensure:utils', 'Build utils if missing', function() {
if (!grunt.file.exists('build/js/utils.js')) {
grunt.task.run('closure-compiler:utils');
}
});
// fast version which only builds the main plugin JS files (see root build.js file for details)
grunt.registerTask('build:jsfast', [
'clean:buildJsKeepUtils',
'clean:tmpIntermediates',
'ensure:utils',
'shell:buildJs',
]);
// just react
grunt.registerTask('build:react', [
'clean:reactBuild',
'replace:reactWithUtils',
'shell:genReactTsDeclaration',
'shell:buildReact',
]);
// just vue
grunt.registerTask('build:vue', [
'clean:vueBuild',
'replace:vueWithUtils',
'shell:buildVue',
]);
// just angular
grunt.registerTask('build:angular', [
'clean:angularBuild',
'replace:angularWithUtils',
'shell:genAngularTsDeclarationAndJs',
'shell:buildAngular',
]);
// just svelte
grunt.registerTask('build:svelte', [
'clean:svelteBuild',
'replace:svelteWithUtils',
'shell:buildSvelte',
]);
/**
* VERSIONING TASKS
*/
// (1) build for tests, and run tests before allowing a version bump
// (2) bump version number in package.json etc
// (3) rebuild js to update version numbers in those files, as well as readme etc
// (4) commit, tag and push
grunt.registerTask('version', [
'build:jsfast',
'shell:test',
'bump-only',
'versionNumbers',
'bump-commit',
]);
grunt.registerTask('version:minor', [
'build:jsfast',
'shell:test',
'bump-only:minor',
'versionNumbers',
'bump-commit'
]);
grunt.registerTask('version:major', [
'build:jsfast',
'shell:test',
'bump-only:major',
'versionNumbers',
'bump-commit'
]);
// update version numbers in docs etc
grunt.registerTask('versionNumbers', [
'replace:siteDocs',
'replace:issueTemplate',
'replace:packageLockInner',
]);
};
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2014-2016 Jack O'Connor
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# International Telephone Input
[](https://github.com/jackocnr/intl-tel-input/actions/workflows/ci.yml)
[](https://www.nerdydata.com/reports/international-telephone-input/719de9d2-d0e7-4988-b02f-9f9d52687076)
A JavaScript plugin for entering, formatting and validating international telephone numbers. Includes TypeScript definitions, plus React, Vue, Angular and Svelte components.
[Explore docs »](https://intl-tel-input.com/docs/choose-integration)
Use [Twilio's API to build phone verification, SMS 2FA, appointment reminders, marketing notifications and so much more](https://www.twilio.com/blog/international-telephone-input-twilio?utm_source=github&utm_medium=referral&utm_campaign=intl_tel_input). We can't wait to see what you build.
## React, Vue, Angular and Svelte Components
We provide React, Vue, Angular and Svelte (beta) components alongside the regular JavaScript plugin. This readme is for the JavaScript plugin. View the [React Component](https://intl-tel-input.com/docs/react-component), the [Vue Component](https://intl-tel-input.com/docs/vue-component) the [Angular Component](https://intl-tel-input.com/docs/angular-component), or the [Svelte component](https://intl-tel-input.com/docs/svelte-component).
## Docs and Examples
We have a newly updated website, where you can find [a full set of docs](https://intl-tel-input.com/docs/getting-started.html), a [live playground](https://intl-tel-input.com/playground/) where you can try out all of the options, as well as plenty of [examples](https://intl-tel-input.com/examples/validation-practical.html) of different setups.
## Features
* Automatically select the user's current country using an IP lookup
* Automatically set the input placeholder to an example number for the selected country
* Navigate the country dropdown by typing a country's name, or using the up/down keys
* Automatically format the number as the user types
* Optionally, only allow numeric characters and cap the number at the maximum valid length
* The user types their national number, and the plugin gives you the full standardised international number
* Number validation, including specific error types
* High-resolution flag images
* Accessibility provided via ARIA tags
* Typescript type definitions included
* Easily customise styles by overriding CSS variables, e.g. support dark mode
* React, Vue, Angular and Svelte components also included
* Translations provided in over 40 languages, as well as support for RTL layout and alternative numeral sets
* Lots of initialisation options for customisation, as well as instance methods/events for interaction
## Contributing
See the [contributing guide](https://github.com/jackocnr/intl-tel-input/blob/master/.github/CONTRIBUTING.md) for instructions on setting up the project and making changes, and also on how to update the flag images, or how to add a new translation.
## Attributions
* Flag images from [flag-icons](https://github.com/lipis/flag-icons)
* Original country data from mledoze's [World countries in JSON, CSV and XML](https://github.com/mledoze/countries)
* Formatting/validation/example number code from [libphonenumber](https://github.com/googlei18n/libphonenumber)
User testing powered by [BrowserStack Open-Source Program](https://www.browserstack.com/open-source)
Browser testing via
================================================
FILE: angular/README.md
================================================
# IntlTelInput Angular Component
An Angular component for the [intl-tel-input](https://github.com/jackocnr/intl-tel-input) JavaScript plugin. View the [source code](https://github.com/jackocnr/intl-tel-input/blob/master/angular/src/intl-tel-input/angular.ts).
[Explore docs »](https://intl-tel-input.com/docs/angular-component)
================================================
FILE: angular/build.js
================================================
const { build } = require("esbuild");
const fs = require("fs");
const packageJson = require("../package.json");
const mainShared = {
bundle: true,
external: ["@angular/core", "@angular/forms"],
logLevel: "info",
minify: false,
define: { "process.env.VERSION": `"${packageJson.version}"` },
};
async function buildMain() {
//* Angular Component - Default (ES Modules)
await build({
...mainShared,
entryPoints: ["angular/build/temp/intl-tel-input/angular.js"],
format: "esm",
outfile: "angular/build/IntlTelInput.js",
});
//* Angular Component With Utils - Default (ES Modules)
await build({
...mainShared,
entryPoints: ["angular/build/temp/intl-tel-input/angularWithUtils.js"],
format: "esm",
outfile: "angular/build/IntlTelInputWithUtils.js",
});
// remove temp folder after builds are complete
fs.rmSync("angular/build/temp", { recursive: true, force: true });
}
buildMain().catch(console.error);
const demoShared = {
bundle: true,
define: { "process.env.VERSION": `"${packageJson.version}"` },
format: "iife",
};
build({
...demoShared,
entryPoints: ["angular/demo/simple/main.ts"],
outfile: "angular/demo/simple/simple-bundle.js",
});
build({
...demoShared,
entryPoints: ["angular/demo/validation/main.ts"],
outfile: "angular/demo/validation/validation-bundle.js",
});
build({
...demoShared,
entryPoints: ["angular/demo/set-number/main.ts"],
outfile: "angular/demo/set-number/set-number-bundle.js",
});
build({
...demoShared,
entryPoints: ["angular/demo/toggle-disabled/main.ts"],
outfile: "angular/demo/toggle-disabled/toggle-disabled-bundle.js",
});
build({
...demoShared,
entryPoints: ["angular/demo/form/main.ts"],
outfile: "angular/demo/form/form-bundle.js",
});
================================================
FILE: angular/demo/form/form.component.ts
================================================
import { Component, OnInit, ViewChild } from "@angular/core";
import {
FormControl,
FormGroup,
ReactiveFormsModule,
Validators,
} from "@angular/forms";
import { IntlTelInputComponent } from "../../src/intl-tel-input/angularWithUtils";
@Component({
selector: "app-root",
template: `
A simple Angular app using reactive forms with the IntlTelInput component for phone number entry and validation.
Enter a phone number and click "Validate" to see form validation in action.
A simple Angular app, using the IntlTelInput component to handle phone number entry, calling setNumber and validation.
Click "Set Number" then click "Validate" to check that the angular internals have updated correctly.
A simple Angular app, using the IntlTelInput component to handle phone number entry.
A simple Angular app, using the IntlTelInput component to show it toggle.
Click the button to enable/disable component.
A simple Angular app, using the IntlTelInput component to handle phone number entry and validation.
Enter a phone number below and click "Validate".