svelte-tel-input 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +50 -4
- package/components/Input/AdvancedTelInput.svelte +34 -39
- package/components/Input/TelInput.svelte +66 -72
- package/package.json +10 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# svelte-tel-input
|
|
2
2
|
|
|
3
|
+
## 1.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- chore: extend REPL example ([#119](https://github.com/gyurielf/svelte-tel-input/pull/119))
|
|
8
|
+
|
|
9
|
+
- chore: polish readme ([#119](https://github.com/gyurielf/svelte-tel-input/pull/119))
|
|
10
|
+
|
|
11
|
+
- chore: update dependencies ([#119](https://github.com/gyurielf/svelte-tel-input/pull/119))
|
|
12
|
+
|
|
13
|
+
## 1.0.1
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- fix: remove types field right before packaging ([#116](https://github.com/gyurielf/svelte-tel-input/pull/116))
|
|
18
|
+
|
|
3
19
|
## 1.0.0
|
|
4
20
|
|
|
5
21
|
### Major Changes
|
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ npm install --save svelte-tel-input
|
|
|
39
39
|
|
|
40
40
|
```html
|
|
41
41
|
<script lang="ts">
|
|
42
|
-
import TelInput from 'svelte-tel-input';
|
|
42
|
+
import TelInput, { normalizedCountries } from 'svelte-tel-input';
|
|
43
43
|
import type { NormalizedTelNumber, CountryCode, E164Number } from 'svelte-tel-input/types';
|
|
44
44
|
|
|
45
45
|
// Any Country Code Alpha-2 (ISO 3166)
|
|
@@ -48,16 +48,62 @@ npm install --save svelte-tel-input
|
|
|
48
48
|
// You must use E164 number format. It's guarantee the parsing and storing consistency.
|
|
49
49
|
let value: E164Number | null = '+36301234567';
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
// Validity
|
|
52
|
+
let valid = true;
|
|
53
|
+
|
|
54
|
+
// Optional - Extended details about the parsed phone number
|
|
52
55
|
let parsedTelInput: NormalizedTelNumber | null = null;
|
|
53
56
|
</script>
|
|
54
57
|
|
|
55
|
-
<
|
|
58
|
+
<div class="wrapper">
|
|
59
|
+
<select
|
|
60
|
+
class="country-select {!valid && 'invalid'}"
|
|
61
|
+
aria-label="Default select example"
|
|
62
|
+
name="Country"
|
|
63
|
+
bind:value={selectedCountry}
|
|
64
|
+
>
|
|
65
|
+
<option value={null} hidden={selectedCountry !== null}>Please select</option>
|
|
66
|
+
{#each normalizedCountries as country (country.id)}
|
|
67
|
+
<option
|
|
68
|
+
value={country.iso2}
|
|
69
|
+
selected={country.iso2 === selectedCountry}
|
|
70
|
+
aria-selected={country.iso2 === selectedCountry}
|
|
71
|
+
>
|
|
72
|
+
{country.iso2} (+{country.dialCode})
|
|
73
|
+
</option>
|
|
74
|
+
{/each}
|
|
75
|
+
</select>
|
|
76
|
+
<TelInput bind:country bind:value bind:valid bind:parsedTelInput class="basic-tel-input {!isValid && 'invalid'}" />
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<style>
|
|
80
|
+
.wrapper :global(.basic-tel-input) {
|
|
81
|
+
height: 32px;
|
|
82
|
+
padding-left: 12px;
|
|
83
|
+
padding-right: 12px;
|
|
84
|
+
border-radius: 6px;
|
|
85
|
+
border: 1px solid;
|
|
86
|
+
outline: none;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.wrapper :global(.country-select) {
|
|
90
|
+
height: 36px;
|
|
91
|
+
padding-left: 12px;
|
|
92
|
+
padding-right: 12px;
|
|
93
|
+
border-radius: 6px;
|
|
94
|
+
border: 1px solid;
|
|
95
|
+
outline: none;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.wrapper :global(.invalid) {
|
|
99
|
+
border-color: red;
|
|
100
|
+
}
|
|
101
|
+
</style>
|
|
56
102
|
```
|
|
57
103
|
|
|
58
104
|
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
59
105
|
|
|
60
|
-
##
|
|
106
|
+
## Props
|
|
61
107
|
|
|
62
108
|
The default export of the library is the main TelInput component. It has the following props:
|
|
63
109
|
|
|
@@ -1,61 +1,56 @@
|
|
|
1
|
-
<script>import { createEventDispatcher } from
|
|
2
|
-
import { normalizedCountries } from
|
|
3
|
-
import { clickOutsideAction } from
|
|
4
|
-
import TelInput from
|
|
5
|
-
import { isSelected } from
|
|
6
|
-
export let searchText =
|
|
1
|
+
<script>import { createEventDispatcher } from "svelte";
|
|
2
|
+
import { normalizedCountries } from "../../assets";
|
|
3
|
+
import { clickOutsideAction } from "../../utils/directives/clickOutsideAction";
|
|
4
|
+
import TelInput from "./TelInput.svelte";
|
|
5
|
+
import { isSelected } from "../../utils/helpers";
|
|
6
|
+
export let searchText = "";
|
|
7
7
|
let selected;
|
|
8
8
|
export let clickOutside = true;
|
|
9
9
|
export let closeOnClick = true;
|
|
10
10
|
export let disabled = false;
|
|
11
11
|
export let parsedTelInput = null;
|
|
12
12
|
export let value;
|
|
13
|
-
$:
|
|
14
|
-
|
|
13
|
+
$:
|
|
14
|
+
selectedCountryDialCode = normalizedCountries.find((el) => el.iso2 === selected)?.dialCode || null;
|
|
15
15
|
let isOpen = false;
|
|
16
|
-
$:
|
|
16
|
+
$:
|
|
17
|
+
isValid = parsedTelInput?.isValid ?? false;
|
|
17
18
|
const toggleDropDown = (e) => {
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
e.preventDefault();
|
|
20
|
+
isOpen = !isOpen;
|
|
20
21
|
};
|
|
21
22
|
const closeDropdown = (e) => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
e?.preventDefault();
|
|
24
|
+
isOpen = false;
|
|
25
|
+
searchText = "";
|
|
25
26
|
};
|
|
26
27
|
const selectClick = () => {
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
if (closeOnClick)
|
|
29
|
+
closeDropdown();
|
|
29
30
|
};
|
|
30
31
|
const closeOnClickOutside = () => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
if (clickOutside) {
|
|
33
|
+
closeDropdown();
|
|
34
|
+
}
|
|
34
35
|
};
|
|
35
|
-
$:
|
|
36
|
-
|
|
37
|
-
? normalizedCountries
|
|
38
|
-
.filter((el) => el.label.toLowerCase().indexOf(searchText.toLowerCase()) >= 0)
|
|
39
|
-
.sort((a, b) => (a.label < b.label ? -1 : 1))
|
|
40
|
-
: normalizedCountries;
|
|
36
|
+
$:
|
|
37
|
+
filteredItems = searchText && searchText.length > 0 ? normalizedCountries.filter((el) => el.label.toLowerCase().indexOf(searchText.toLowerCase()) >= 0).sort((a, b) => a.label < b.label ? -1 : 1) : normalizedCountries;
|
|
41
38
|
const handleSelect = (val, e) => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
selectClick();
|
|
54
|
-
}
|
|
39
|
+
if (disabled)
|
|
40
|
+
return;
|
|
41
|
+
e?.preventDefault();
|
|
42
|
+
if ((selected === void 0 || selected === null) && typeof val === "object" || typeof selected === typeof val && selected !== val) {
|
|
43
|
+
selected = val;
|
|
44
|
+
onChange(val);
|
|
45
|
+
selectClick();
|
|
46
|
+
} else {
|
|
47
|
+
dispatch("same", { option: val });
|
|
48
|
+
selectClick();
|
|
49
|
+
}
|
|
55
50
|
};
|
|
56
51
|
const dispatch = createEventDispatcher();
|
|
57
52
|
const onChange = (selectedCountry) => {
|
|
58
|
-
|
|
53
|
+
dispatch("change", { option: selectedCountry });
|
|
59
54
|
};
|
|
60
55
|
</script>
|
|
61
56
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
<script>import { createEventDispatcher, onMount } from
|
|
2
|
-
import metadata from
|
|
3
|
-
import { parsePhoneNumberWithError, ParseError } from
|
|
4
|
-
import { telInputAction } from
|
|
5
|
-
import { normalizeTelInput, getCountryForPartialE164Number } from
|
|
6
|
-
import { watcher } from
|
|
1
|
+
<script>import { createEventDispatcher, onMount } from "svelte";
|
|
2
|
+
import metadata from "libphonenumber-js/metadata.min.json";
|
|
3
|
+
import { parsePhoneNumberWithError, ParseError } from "libphonenumber-js";
|
|
4
|
+
import { telInputAction } from "../../utils/directives/telInputAction";
|
|
5
|
+
import { normalizeTelInput, getCountryForPartialE164Number } from "../../utils/helpers";
|
|
6
|
+
import { watcher } from "../../stores";
|
|
7
7
|
const dispatch = createEventDispatcher();
|
|
8
8
|
export let country;
|
|
9
9
|
export let value;
|
|
@@ -12,88 +12,82 @@ export let valid = true;
|
|
|
12
12
|
export let disabled = false;
|
|
13
13
|
let inputValue = value;
|
|
14
14
|
let prevCountry = country;
|
|
15
|
-
const handleInputAction = (
|
|
16
|
-
|
|
15
|
+
const handleInputAction = (value2) => {
|
|
16
|
+
handleParsePhoneNumber(value2, country);
|
|
17
17
|
};
|
|
18
18
|
const updateCountry = (countryCode) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
country = countryCode;
|
|
20
|
+
prevCountry = countryCode;
|
|
21
|
+
return country;
|
|
22
22
|
};
|
|
23
23
|
const handleParsePhoneNumber = (input, currCountry = null) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
try {
|
|
30
|
-
parsedTelInput = normalizeTelInput(parsePhoneNumberWithError(input, currCountry ?? numberHasCountry));
|
|
31
|
-
}
|
|
32
|
-
catch (err) {
|
|
33
|
-
if (err instanceof ParseError) {
|
|
34
|
-
// Not a phone number, non-existent country, etc.
|
|
35
|
-
parsedTelInput = {
|
|
36
|
-
isValid: false,
|
|
37
|
-
error: err.message
|
|
38
|
-
};
|
|
39
|
-
dispatch('parseError', err.message);
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
throw err;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
// It's keep the html input value on the first parsed format, or the user's format.
|
|
46
|
-
if (parsedTelInput?.isValid && parsedTelInput?.formatOriginal) {
|
|
47
|
-
// It's need for refreshing html input value, if it is the same as the previouly parsed.
|
|
48
|
-
if (inputValue === parsedTelInput?.formatOriginal) {
|
|
49
|
-
inputValue = null;
|
|
50
|
-
}
|
|
51
|
-
inputValue = parsedTelInput?.formatOriginal;
|
|
52
|
-
}
|
|
53
|
-
value = parsedTelInput?.e164 ?? null;
|
|
54
|
-
valid = parsedTelInput?.isValid ?? false;
|
|
55
|
-
dispatch('valid', valid);
|
|
56
|
-
dispatch('parseInput', parsedTelInput);
|
|
24
|
+
if (input) {
|
|
25
|
+
const numberHasCountry = getCountryForPartialE164Number(input, { metadata });
|
|
26
|
+
if (numberHasCountry && numberHasCountry !== prevCountry) {
|
|
27
|
+
updateCountry(numberHasCountry);
|
|
57
28
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
29
|
+
try {
|
|
30
|
+
parsedTelInput = normalizeTelInput(
|
|
31
|
+
parsePhoneNumberWithError(input, currCountry ?? numberHasCountry)
|
|
32
|
+
);
|
|
33
|
+
} catch (err) {
|
|
34
|
+
if (err instanceof ParseError) {
|
|
35
|
+
parsedTelInput = {
|
|
36
|
+
isValid: false,
|
|
37
|
+
error: err.message
|
|
38
|
+
};
|
|
39
|
+
dispatch("parseError", err.message);
|
|
40
|
+
} else {
|
|
41
|
+
throw err;
|
|
42
|
+
}
|
|
65
43
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
44
|
+
if (parsedTelInput?.isValid && parsedTelInput?.formatOriginal) {
|
|
45
|
+
if (inputValue === parsedTelInput?.formatOriginal) {
|
|
46
|
+
inputValue = null;
|
|
47
|
+
}
|
|
48
|
+
inputValue = parsedTelInput?.formatOriginal;
|
|
70
49
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
50
|
+
value = parsedTelInput?.e164 ?? null;
|
|
51
|
+
valid = parsedTelInput?.isValid ?? false;
|
|
52
|
+
dispatch("valid", valid);
|
|
53
|
+
dispatch("parseInput", parsedTelInput);
|
|
54
|
+
} else {
|
|
55
|
+
if (currCountry !== prevCountry) {
|
|
56
|
+
value = null;
|
|
57
|
+
inputValue = "";
|
|
58
|
+
valid = true;
|
|
80
59
|
}
|
|
81
|
-
|
|
82
|
-
|
|
60
|
+
prevCountry = currCountry;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const initialize = () => {
|
|
64
|
+
if (value && country) {
|
|
65
|
+
handleParsePhoneNumber(value, country);
|
|
66
|
+
} else if (value) {
|
|
67
|
+
const numberHasCountry = getCountryForPartialE164Number(value, { metadata });
|
|
68
|
+
if (numberHasCountry) {
|
|
69
|
+
updateCountry(numberHasCountry);
|
|
70
|
+
handleParsePhoneNumber(value, country);
|
|
71
|
+
} else {
|
|
72
|
+
handleParsePhoneNumber(value);
|
|
83
73
|
}
|
|
74
|
+
} else if (parsedTelInput && parsedTelInput.phoneNumber) {
|
|
75
|
+
handleParsePhoneNumber(parsedTelInput.phoneNumber, country);
|
|
76
|
+
}
|
|
84
77
|
};
|
|
85
78
|
onMount(() => {
|
|
86
|
-
|
|
79
|
+
initialize();
|
|
87
80
|
});
|
|
88
81
|
let initRun = true;
|
|
89
82
|
const watchFunction = () => {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
83
|
+
if (!initRun) {
|
|
84
|
+
handleParsePhoneNumber(null, country);
|
|
85
|
+
}
|
|
86
|
+
initRun = false;
|
|
94
87
|
};
|
|
95
88
|
const countryChangeWatch = watcher(null, watchFunction);
|
|
96
|
-
$:
|
|
89
|
+
$:
|
|
90
|
+
$countryChangeWatch = country;
|
|
97
91
|
</script>
|
|
98
92
|
|
|
99
93
|
<input
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-tel-input",
|
|
3
3
|
"description": "svelte-tel-input",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.2",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/gyurielf/svelte-tel-input.git"
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
"engines": {
|
|
19
19
|
"npm": ">= 7",
|
|
20
20
|
"yarn": ">=2",
|
|
21
|
-
"node": ">= 16"
|
|
21
|
+
"node": ">= 16",
|
|
22
|
+
"pnpm": ">= 7"
|
|
22
23
|
},
|
|
23
24
|
"dependencies": {
|
|
24
|
-
"libphonenumber-js": "^1.10.
|
|
25
|
-
"svelte": "^3.55.0"
|
|
25
|
+
"libphonenumber-js": "^1.10.18"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@babel/core": "^7.20.12",
|
|
@@ -32,13 +32,13 @@
|
|
|
32
32
|
"@changesets/types": "^5.2.1",
|
|
33
33
|
"@macfja/svelte-persistent-store": "^2.2.1",
|
|
34
34
|
"@sveltejs/adapter-static": "^1.0.1",
|
|
35
|
-
"@sveltejs/kit": "^1.0.
|
|
35
|
+
"@sveltejs/kit": "^1.0.11",
|
|
36
36
|
"@sveltejs/package": "^1.0.2",
|
|
37
37
|
"@testing-library/jest-dom": "^5.16.5",
|
|
38
38
|
"@testing-library/svelte": "^3.2.2",
|
|
39
39
|
"@types/jest": "^29.2.5",
|
|
40
|
-
"@typescript-eslint/eslint-plugin": "^5.48.
|
|
41
|
-
"@typescript-eslint/parser": "^5.48.
|
|
40
|
+
"@typescript-eslint/eslint-plugin": "^5.48.1",
|
|
41
|
+
"@typescript-eslint/parser": "^5.48.1",
|
|
42
42
|
"autoprefixer": "^10.4.13",
|
|
43
43
|
"babel-jest": "^29.3.1",
|
|
44
44
|
"babel-loader": "^9.1.2",
|
|
@@ -55,13 +55,13 @@
|
|
|
55
55
|
"micromatch": "^4.0.5",
|
|
56
56
|
"postcss": "^8.4.21",
|
|
57
57
|
"postcss-load-config": "^4.0.1",
|
|
58
|
-
"prettier": "^2.8.
|
|
58
|
+
"prettier": "^2.8.2",
|
|
59
59
|
"prettier-plugin-svelte": "^2.9.0",
|
|
60
|
-
"svelte
|
|
60
|
+
"svelte": "^3.55.1",
|
|
61
|
+
"svelte-check": "^3.0.2",
|
|
61
62
|
"svelte-inview": "^3.0.2",
|
|
62
63
|
"svelte-jester": "^2.3.2",
|
|
63
64
|
"svelte-loader": "^3.1.4",
|
|
64
|
-
"svelte-preprocess": "^5.0.0",
|
|
65
65
|
"svelte2tsx": "^0.6.0",
|
|
66
66
|
"tailwindcss": "^3.2.4",
|
|
67
67
|
"ts-jest": "^29.0.3",
|
|
@@ -72,7 +72,6 @@
|
|
|
72
72
|
},
|
|
73
73
|
"type": "module",
|
|
74
74
|
"license": "MIT",
|
|
75
|
-
"types": "./types/index.d.ts",
|
|
76
75
|
"exports": {
|
|
77
76
|
"./package.json": "./package.json",
|
|
78
77
|
".": "./index.js",
|