
Svelte Tel Input
Lightweight svelte tel/phone input standardizer.
🔥 Check it out live here
Installation
Svelte Tel Input is distributed via npm.
npm install --save svelte-tel-input
Features
- Support SSR/SSG.
- Parse and validate phone number.You can store one exact format (
E164), no matter how users type their phone numbers.
- Format (specified to its country), to make it more readable.
- Prevent non-digits typing into the input, except the leading
+ sign (and space optionally).
- Handle copy-pasted phone numbers, it's sanitize non-digit characters except the leading
+ sign (and space optionally).
- Automatic placeholder generation for the selected country.
- International or National formatted phone numbers.
Usage
Advanced
Snippet would be too long - Example - REPL (StackBlitz)
Basic
Example - REPL (StackBlitz)
<script lang="ts">
import { TelInput, normalizedCountries } from 'svelte-tel-input';
import type { DetailedValue, CountryCode, E164Number } from 'svelte-tel-input/types';
let selectedCountry: CountryCode | null = 'HU';
let value: E164Number | null = '+36301234567';
let valid = true;
let detailedValue: DetailedValue | null = null;
</script>
<div class="wrapper">
<select
class="country-select {!valid && 'invalid'}"
aria-label="Default select example"
name="Country"
bind:value={selectedCountry}
>
<option value={null} hidden={selectedCountry !== null}>Please select</option>
{#each normalizedCountries as country (country.id)}
<option
value={country.iso2}
selected={country.iso2 === selectedCountry}
aria-selected={country.iso2 === selectedCountry}
>
{country.iso2} (+{country.dialCode})
</option>
{/each}
</select>
<TelInput bind:country={selectedCountry} bind:value bind:valid bind:detailedValue class="basic-tel-input {!isValid && 'invalid'}" />
</div>
<style>
.wrapper :global(.basic-tel-input) {
height: 32px;
padding-left: 12px;
padding-right: 12px;
border-radius: 6px;
border: 1px solid;
outline: none;
}
.wrapper :global(.country-select) {
height: 36px;
padding-left: 12px;
padding-right: 12px;
border-radius: 6px;
border: 1px solid;
outline: none;
}
.wrapper :global(.invalid) {
border-color: red;
}
</style>
(back to top)
Props
The default export of the library is the main TelInput component. It has the following props:
| value | E164Number | null | null | E164 is the international format of phone.numbers. This is the main entry point to store and/or load an existent phone number. |
| country | CountryCode | null | null | It's accept any Country Code Alpha-2 (ISO 3166). You can set manually (e.g: by the user via a select). The parser will inspect the entered phone number and if it detect a valid country calling code, then it's automatically set the country to according to the detected country calling code. E.g: +36 -> HU |
| disabled | boolean | false | It's block the parser and prevent entering input. You must handle its styling on your own. |
| valid | boolean | true | Indicates whether the entered tel number validity. |
| detailedValue | DetailedValue |null | null | All of the formatted results of the tel input. |
| class | string | `` | You can pass down any classname to the component |
| required | boolean | null | null | Set the required attribute on the input element |
| options | TelInputOptions | check below | Allow or disallow spaces in the input field |
Config options:
{
autoPlaceholder: true,
spaces: true,
invalidateOnCountryChange: false,
format: 'national'
}
(back to top)
Dispatched Events
The default export of the library is the main TelInput component. It has the following props:
| updateValue | E164Number | null |
| updateDetailedValue | DetailedValue |null |
| updateCountry | CountryCode | null |
| updateValid | boolean |
| parseError | string |
Use case of the event driven behavior
<script lang="ts">
let value: E164Number | null = null;
const yourHandler = (e: CustomEvent<E164Number | null>) => {
value = e.detail
};
</script>
<TelInput value={cachedValue ?? value} on:updateValue={yourHandler} ... />
(back to top)
Caveats
-
In order to reset value and/or country from outside (you must pass (or set if you binded) null for the property) have some side-effects:
- Reseting the
value will set (keep the country as is):
detailedValue to null
- dispatch
updateDetailedValue event
- Reseting the
country will set:
value to null
detailedValue to null
valid to true if invalidateOnCountryChange config option is false (@default false). Otherwise it will be false.
- and dispatch
updateValid, updateValue updateDetailedValue events
- Reseting both
value and country will set:
valid to true
detailedValue to null;
-
Let's assume you pass a US E164 number, which can be a partial E164, but long enough to determine the country and you pass DE country directly. The country will be updated to US, which is determined from the E164 in this example. If the E164 is not long enough to determine its country, then the country will stay what you passed to the component (DE).
(back to top)
Goals
- Solve the problem that a users can enter the same phone number in different formats.
- Storing a phone number in a standard format, that can be indexable and searchable in any database.
- Should be accessible for the the browser. Eg. for a
<a href="tel+36201234567 />.
- The stored phone number format can be useable for any SMS gateway(e.g for 2FA) and if somebody can call the number from anywhere, it should work.
Dependencies
libphonenumber-js
(back to top)
Changelog
(back to top)
Roadmap
See the open issues for a list of proposed features (and known issues).
(back to top)
Support

(back to top)
License
Distributed under the MIT License. See LICENSE.md for more information.
(back to top)