svelte-tel-input 2.1.1 → 3.0.1
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 +49 -0
- package/README.md +67 -14
- package/assets/index.d.ts +0 -2
- package/assets/index.js +0 -2
- package/components/Input/TelInput.svelte +62 -61
- package/components/Input/TelInput.svelte.d.ts +7 -6
- package/package.json +17 -17
- package/types/index.d.ts +16 -11
- package/assets/regions.d.ts +0 -1
- package/assets/regions.js +0 -43
- package/assets/telTypes.d.ts +0 -5
- package/assets/telTypes.js +0 -16
- package/components/Input/AdvancedTelInput.svelte +0 -156
- package/components/Input/AdvancedTelInput.svelte.d.ts +0 -24
- package/utils/directives/seoJsonLdAction.d.ts +0 -2
- package/utils/directives/seoJsonLdAction.js +0 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,54 @@
|
|
|
1
1
|
# svelte-tel-input
|
|
2
2
|
|
|
3
|
+
## 3.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- chore: update readme with advanced example REPL ([#162](https://github.com/gyurielf/svelte-tel-input/pull/162))
|
|
8
|
+
|
|
9
|
+
- fix: auto country update after manual country change ([#162](https://github.com/gyurielf/svelte-tel-input/pull/162))
|
|
10
|
+
|
|
11
|
+
## 3.0.0
|
|
12
|
+
|
|
13
|
+
### Major Changes
|
|
14
|
+
|
|
15
|
+
- breaking: rename `parsedTelInput` property: ([#156](https://github.com/gyurielf/svelte-tel-input/pull/156))
|
|
16
|
+
`parsedTelInput` is `detailedValue` from now.
|
|
17
|
+
|
|
18
|
+
```diff
|
|
19
|
+
-<TelInput bind:parsedTelInput ... />;
|
|
20
|
+
+<TelInput bind:detailedValue ... />;
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
breaking: rename dispatched events:
|
|
24
|
+
`parseInput` is splitted to two (`updateValue` and `updateDetailedValue` ) event.
|
|
25
|
+
`valid` is `updateValid` from now.
|
|
26
|
+
|
|
27
|
+
```diff
|
|
28
|
+
-<TelInput on:parseInput={...} on:valid={...} ... />;
|
|
29
|
+
+<TelInput on:updateValue={...} on:updateDetailedValue={...} on:updateValid={...} on:updateCountry={...} ... />;
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
breaking: rename `NormalizedTelNumber` type to `DetailedValue`:
|
|
33
|
+
|
|
34
|
+
```diff
|
|
35
|
+
-import type { NormalizedTelNumber } from 'svelte-tel-input/types';
|
|
36
|
+
+import type { DetailedValue } from 'svelte-tel-input/types';
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
feat: new event added: `updateCountry`
|
|
40
|
+
|
|
41
|
+
```html
|
|
42
|
+
<TelInput on:updateCountry="{...}" ... />;
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
feat: now the component is fully supports the event driven behavior. So you don't have to bind properties.
|
|
46
|
+
|
|
47
|
+
```diff
|
|
48
|
+
-<TelInput bind:value ... />;
|
|
49
|
+
+<TelInput value={yourValue} ... />;
|
|
50
|
+
```
|
|
51
|
+
|
|
3
52
|
## 2.1.1
|
|
4
53
|
|
|
5
54
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -28,6 +28,10 @@ npm install --save svelte-tel-input
|
|
|
28
28
|
|
|
29
29
|
## Usage
|
|
30
30
|
|
|
31
|
+
### Advanced
|
|
32
|
+
|
|
33
|
+
_Snippet would be too long_ - [REPL](https://stackblitz.com/edit/svelte-tel-input-repl-1jfaar?file=README.md) (StackBlitz)
|
|
34
|
+
|
|
31
35
|
### Basic
|
|
32
36
|
|
|
33
37
|
[REPL](https://stackblitz.com/edit/svelte-tel-input-repl?file=README.md) (StackBlitz)
|
|
@@ -35,10 +39,10 @@ npm install --save svelte-tel-input
|
|
|
35
39
|
```html
|
|
36
40
|
<script lang="ts">
|
|
37
41
|
import { TelInput, normalizedCountries } from 'svelte-tel-input';
|
|
38
|
-
import type {
|
|
42
|
+
import type { DetailedValue, CountryCode, E164Number } from 'svelte-tel-input/types';
|
|
39
43
|
|
|
40
44
|
// Any Country Code Alpha-2 (ISO 3166)
|
|
41
|
-
let
|
|
45
|
+
let selectedCountry: CountryCode | null = 'HU';
|
|
42
46
|
|
|
43
47
|
// You must use E164 number format. It's guarantee the parsing and storing consistency.
|
|
44
48
|
let value: E164Number | null = '+36301234567';
|
|
@@ -47,7 +51,7 @@ npm install --save svelte-tel-input
|
|
|
47
51
|
let valid = true;
|
|
48
52
|
|
|
49
53
|
// Optional - Extended details about the parsed phone number
|
|
50
|
-
let
|
|
54
|
+
let detailedValue: DetailedValue | null = null;
|
|
51
55
|
</script>
|
|
52
56
|
|
|
53
57
|
<div class="wrapper">
|
|
@@ -68,7 +72,7 @@ npm install --save svelte-tel-input
|
|
|
68
72
|
</option>
|
|
69
73
|
{/each}
|
|
70
74
|
</select>
|
|
71
|
-
<TelInput bind:country bind:value bind:valid bind:
|
|
75
|
+
<TelInput bind:country={selectedCountry} bind:value bind:valid bind:detailedValue class="basic-tel-input {!isValid && 'invalid'}" />
|
|
72
76
|
</div>
|
|
73
77
|
|
|
74
78
|
<style>
|
|
@@ -102,16 +106,65 @@ npm install --save svelte-tel-input
|
|
|
102
106
|
|
|
103
107
|
The default export of the library is the main TelInput component. It has the following props:
|
|
104
108
|
|
|
105
|
-
|
|
|
106
|
-
|
|
|
107
|
-
|
|
|
108
|
-
|
|
|
109
|
-
|
|
|
110
|
-
|
|
|
111
|
-
|
|
|
112
|
-
| class
|
|
113
|
-
|
|
|
114
|
-
|
|
|
109
|
+
| Property name | Type | Default Value | Usage |
|
|
110
|
+
| ------------- | ---------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
111
|
+
| value | `E164Number \| null` | `null` | [E164](https://en.wikipedia.org/wiki/E.164) is the international format of phone.numbers. This is the main entry point to store and/or load an existent phone number. |
|
|
112
|
+
| 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` |
|
|
113
|
+
| disabled | `boolean` | `false` | It's block the parser and prevent entering input. You must handle its styling on your own. |
|
|
114
|
+
| valid | `boolean` | `true` | Indicates whether the entered tel number validity. |
|
|
115
|
+
| detailedValue | `DetailedValue \|null` | `null` | All of the formatted results of the tel input. |
|
|
116
|
+
| class | `string` | `` | You can pass down any classname to the component |
|
|
117
|
+
| required | `boolean \| null` | `null` | Set the required attribute on the input element |
|
|
118
|
+
| options | `TelInputOptions` | check below | Allow or disallow spaces in the input field |
|
|
119
|
+
|
|
120
|
+
Config options:
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
{
|
|
124
|
+
// Generates country specific placeholder for the selected country.
|
|
125
|
+
autoPlaceholder: true,
|
|
126
|
+
// Allow or disallow spaces in the input field
|
|
127
|
+
spaces: true,
|
|
128
|
+
// If you have a parsed phone number and you change country manually from outside, then it's set the `valid` prop to false.
|
|
129
|
+
invalidateOnCountryChange: false
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
134
|
+
|
|
135
|
+
## Dispatched Events
|
|
136
|
+
|
|
137
|
+
The default export of the library is the main TelInput component. It has the following props:
|
|
138
|
+
|
|
139
|
+
| Event name | Type |
|
|
140
|
+
| ------------------- | ---------------------- |
|
|
141
|
+
| updateValue | `E164Number \| null` |
|
|
142
|
+
| updateDetailedValue | `DetailedValue \|null` |
|
|
143
|
+
| updateCountry | `CountryCode \| null` |
|
|
144
|
+
| updateValid | `boolean` |
|
|
145
|
+
| parseError | `string` |
|
|
146
|
+
|
|
147
|
+
## Use case of the event driven behavior
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
<script lang="ts">
|
|
151
|
+
// Imports, etc....
|
|
152
|
+
let value: E164Number | null = null;
|
|
153
|
+
const yourHandler = (e: CustomEvent<E164Number | null>) => {
|
|
154
|
+
value = e.detail //
|
|
155
|
+
// do stuff...
|
|
156
|
+
};
|
|
157
|
+
</script>
|
|
158
|
+
|
|
159
|
+
<TelInput value={cachedValue ?? value} on:updateValue={yourHandler} ... />
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
163
|
+
|
|
164
|
+
## Caveats
|
|
165
|
+
|
|
166
|
+
- In order to reset the component from outside, you must pass (or set if you binded) `null` for both the `value` and `country` properties.
|
|
167
|
+
- 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`).
|
|
115
168
|
|
|
116
169
|
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
117
170
|
|
package/assets/index.d.ts
CHANGED
package/assets/index.js
CHANGED
|
@@ -7,14 +7,15 @@ import {
|
|
|
7
7
|
generatePlaceholder
|
|
8
8
|
} from "../../utils/helpers";
|
|
9
9
|
import { watcher } from "../../stores";
|
|
10
|
+
const dispatch = createEventDispatcher();
|
|
10
11
|
const defaultOptions = {
|
|
11
12
|
autoPlaceholder: true,
|
|
12
|
-
spaces: true
|
|
13
|
+
spaces: true,
|
|
14
|
+
invalidateOnCountryChange: false
|
|
13
15
|
};
|
|
14
|
-
const dispatch = createEventDispatcher();
|
|
15
16
|
export let country;
|
|
16
17
|
export let value;
|
|
17
|
-
export let
|
|
18
|
+
export let detailedValue = null;
|
|
18
19
|
export let valid = true;
|
|
19
20
|
export let disabled = false;
|
|
20
21
|
export let placeholder = null;
|
|
@@ -22,11 +23,10 @@ export let options = defaultOptions;
|
|
|
22
23
|
export let required = null;
|
|
23
24
|
let inputValue = value;
|
|
24
25
|
let prevCountry = country;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
};
|
|
26
|
+
const combinedOptions = {
|
|
27
|
+
...defaultOptions,
|
|
28
|
+
...options
|
|
29
|
+
};
|
|
30
30
|
const handleInputAction = (value2) => {
|
|
31
31
|
if (disabled)
|
|
32
32
|
return;
|
|
@@ -35,6 +35,7 @@ const handleInputAction = (value2) => {
|
|
|
35
35
|
const updateCountry = (countryCode) => {
|
|
36
36
|
country = countryCode;
|
|
37
37
|
prevCountry = countryCode;
|
|
38
|
+
dispatch("updateCountry", country);
|
|
38
39
|
return country;
|
|
39
40
|
};
|
|
40
41
|
const handleParsePhoneNumber = (input, currCountry = null) => {
|
|
@@ -44,12 +45,12 @@ const handleParsePhoneNumber = (input, currCountry = null) => {
|
|
|
44
45
|
updateCountry(numberHasCountry);
|
|
45
46
|
}
|
|
46
47
|
try {
|
|
47
|
-
|
|
48
|
-
parsePhoneNumberWithError(input, currCountry ??
|
|
48
|
+
detailedValue = normalizeTelInput(
|
|
49
|
+
parsePhoneNumberWithError(input, numberHasCountry ?? currCountry ?? void 0)
|
|
49
50
|
);
|
|
50
51
|
} catch (err) {
|
|
51
52
|
if (err instanceof ParseError) {
|
|
52
|
-
|
|
53
|
+
detailedValue = {
|
|
53
54
|
isValid: false,
|
|
54
55
|
error: err.message
|
|
55
56
|
};
|
|
@@ -58,86 +59,85 @@ const handleParsePhoneNumber = (input, currCountry = null) => {
|
|
|
58
59
|
throw err;
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
|
-
if (
|
|
62
|
-
if (inputValue ===
|
|
62
|
+
if (detailedValue?.isValid && combinedOptions.spaces && detailedValue?.formatOriginal) {
|
|
63
|
+
if (inputValue === detailedValue?.formatOriginal) {
|
|
63
64
|
inputValue = null;
|
|
65
|
+
inputValue = "";
|
|
64
66
|
}
|
|
65
|
-
inputValue =
|
|
66
|
-
} else if (
|
|
67
|
-
if (inputValue ===
|
|
67
|
+
inputValue = detailedValue?.formatOriginal;
|
|
68
|
+
} else if (detailedValue?.isValid && detailedValue?.nationalNumber) {
|
|
69
|
+
if (inputValue === detailedValue?.nationalNumber) {
|
|
68
70
|
inputValue = null;
|
|
71
|
+
inputValue = "";
|
|
69
72
|
}
|
|
70
|
-
inputValue =
|
|
73
|
+
inputValue = detailedValue?.nationalNumber;
|
|
71
74
|
}
|
|
72
|
-
value =
|
|
73
|
-
valid =
|
|
74
|
-
dispatch("
|
|
75
|
-
dispatch("
|
|
76
|
-
|
|
75
|
+
value = detailedValue?.e164 ?? input ?? null;
|
|
76
|
+
valid = detailedValue?.isValid ?? false;
|
|
77
|
+
dispatch("updateValid", valid);
|
|
78
|
+
dispatch("updateValue", value);
|
|
79
|
+
dispatch("updateDetailedValue", detailedValue);
|
|
80
|
+
} else if (input === null && currCountry !== null) {
|
|
77
81
|
if (currCountry !== prevCountry) {
|
|
82
|
+
prevCountry = currCountry;
|
|
83
|
+
valid = !options.invalidateOnCountryChange;
|
|
78
84
|
value = null;
|
|
79
|
-
inputValue
|
|
80
|
-
|
|
81
|
-
|
|
85
|
+
if (inputValue !== null || inputValue !== "") {
|
|
86
|
+
inputValue = null;
|
|
87
|
+
inputValue = "";
|
|
88
|
+
}
|
|
89
|
+
detailedValue = null;
|
|
90
|
+
dispatch("updateValid", valid);
|
|
91
|
+
dispatch("updateValue", value);
|
|
92
|
+
dispatch("updateDetailedValue", detailedValue);
|
|
82
93
|
}
|
|
94
|
+
} else {
|
|
95
|
+
valid = true;
|
|
96
|
+
value = null;
|
|
97
|
+
detailedValue = null;
|
|
83
98
|
prevCountry = currCountry;
|
|
84
|
-
dispatch("
|
|
85
|
-
dispatch("
|
|
99
|
+
dispatch("updateValid", valid);
|
|
100
|
+
dispatch("updateDetailedValue", detailedValue);
|
|
101
|
+
inputValue = null;
|
|
102
|
+
inputValue = "";
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
let countryWatchInitRun = true;
|
|
106
|
+
const countryChangeWatchFunction = () => {
|
|
107
|
+
if (!countryWatchInitRun) {
|
|
108
|
+
handleParsePhoneNumber(null, country);
|
|
86
109
|
}
|
|
110
|
+
countryWatchInitRun = false;
|
|
87
111
|
};
|
|
112
|
+
const countryChangeWatch = watcher(null, countryChangeWatchFunction);
|
|
113
|
+
$:
|
|
114
|
+
$countryChangeWatch = country;
|
|
115
|
+
$:
|
|
116
|
+
getPlaceholder = combinedOptions.autoPlaceholder ? country ? generatePlaceholder(country) : null : placeholder;
|
|
88
117
|
const initialize = () => {
|
|
89
118
|
if (value && country) {
|
|
90
119
|
handleParsePhoneNumber(value, country);
|
|
91
120
|
} else if (value) {
|
|
92
121
|
const numberHasCountry = getCountryForPartialE164Number(value);
|
|
93
122
|
if (numberHasCountry) {
|
|
94
|
-
|
|
95
|
-
handleParsePhoneNumber(value, country);
|
|
123
|
+
handleParsePhoneNumber(value, numberHasCountry);
|
|
96
124
|
} else {
|
|
97
|
-
handleParsePhoneNumber(value);
|
|
125
|
+
handleParsePhoneNumber(value, null);
|
|
98
126
|
}
|
|
99
127
|
}
|
|
100
128
|
};
|
|
101
129
|
onMount(() => {
|
|
102
130
|
initialize();
|
|
103
131
|
});
|
|
104
|
-
let countryWatchInitRun = true;
|
|
105
|
-
const countryChangeWatchFunction = () => {
|
|
106
|
-
if (!countryWatchInitRun) {
|
|
107
|
-
handleParsePhoneNumber(null, country);
|
|
108
|
-
}
|
|
109
|
-
countryWatchInitRun = false;
|
|
110
|
-
};
|
|
111
|
-
let resetValueWatchInitRun = true;
|
|
112
|
-
const resetValueWatchFunction = () => {
|
|
113
|
-
if (!resetValueWatchInitRun) {
|
|
114
|
-
inputValue = "";
|
|
115
|
-
updateCountry(null);
|
|
116
|
-
valid = true;
|
|
117
|
-
parsedTelInput = null;
|
|
118
|
-
dispatch("parseInput", parsedTelInput);
|
|
119
|
-
}
|
|
120
|
-
resetValueWatchInitRun = false;
|
|
121
|
-
};
|
|
122
|
-
const countryChangeWatch = watcher(null, countryChangeWatchFunction);
|
|
123
|
-
$:
|
|
124
|
-
$countryChangeWatch = country;
|
|
125
|
-
const resetValueWatch = watcher(null, resetValueWatchFunction);
|
|
126
|
-
$:
|
|
127
|
-
if (value === null && inputValue !== "") {
|
|
128
|
-
$resetValueWatch = value;
|
|
129
|
-
}
|
|
130
|
-
$:
|
|
131
|
-
getPlaceholder = combinedOptions.autoPlaceholder ? country ? generatePlaceholder(country) : null : placeholder;
|
|
132
132
|
</script>
|
|
133
133
|
|
|
134
134
|
<input
|
|
135
|
-
|
|
135
|
+
type="tel"
|
|
136
136
|
placeholder={getPlaceholder}
|
|
137
|
+
{required}
|
|
137
138
|
{disabled}
|
|
138
|
-
type="tel"
|
|
139
|
-
value={inputValue}
|
|
140
139
|
{...$$restProps}
|
|
140
|
+
value={inputValue}
|
|
141
141
|
class={$$props.class}
|
|
142
142
|
on:beforeinput
|
|
143
143
|
on:blur
|
|
@@ -148,5 +148,6 @@ $:
|
|
|
148
148
|
on:keypress
|
|
149
149
|
on:keyup
|
|
150
150
|
on:paste
|
|
151
|
+
on:click
|
|
151
152
|
use:telInputAction={{ handler: handleInputAction, spaces: combinedOptions.spaces }}
|
|
152
153
|
/>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { SvelteComponentTyped } from "svelte";
|
|
2
|
-
import type {
|
|
2
|
+
import type { DetailedValue, CountryCode, E164Number, TelInputOptions } from '../../types';
|
|
3
3
|
declare const __propDef: {
|
|
4
4
|
props: {
|
|
5
5
|
[x: string]: any;
|
|
6
6
|
country: CountryCode | null;
|
|
7
7
|
value: E164Number | null;
|
|
8
|
-
|
|
8
|
+
detailedValue?: Partial<DetailedValue> | null | undefined;
|
|
9
9
|
valid?: boolean | undefined;
|
|
10
10
|
disabled?: boolean | undefined;
|
|
11
11
|
placeholder?: string | null | undefined;
|
|
@@ -22,11 +22,12 @@ declare const __propDef: {
|
|
|
22
22
|
keypress: KeyboardEvent;
|
|
23
23
|
keyup: KeyboardEvent;
|
|
24
24
|
paste: ClipboardEvent;
|
|
25
|
-
|
|
25
|
+
click: MouseEvent;
|
|
26
|
+
updateCountry: CustomEvent<CountryCode | null>;
|
|
26
27
|
parseError: CustomEvent<string>;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
updateDetailedValue: CustomEvent<Partial<DetailedValue> | null>;
|
|
29
|
+
updateValid: CustomEvent<boolean>;
|
|
30
|
+
updateValue: CustomEvent<E164Number | null>;
|
|
30
31
|
} & {
|
|
31
32
|
[evt: string]: CustomEvent<any>;
|
|
32
33
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-tel-input",
|
|
3
3
|
"description": "svelte-tel-input",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "3.0.1",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/gyurielf/svelte-tel-input.git"
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"pnpm": ">= 7"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"libphonenumber-js": "^1.10.
|
|
25
|
+
"libphonenumber-js": "^1.10.36",
|
|
26
26
|
"svelte": "^3.58.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
@@ -30,35 +30,35 @@
|
|
|
30
30
|
"@changesets/get-github-info": "^0.5.2",
|
|
31
31
|
"@changesets/types": "^5.2.1",
|
|
32
32
|
"@macfja/svelte-persistent-store": "^2.3.0",
|
|
33
|
-
"@playwright/test": "^1.
|
|
33
|
+
"@playwright/test": "^1.35.1",
|
|
34
34
|
"@sveltejs/adapter-static": "^2.0.2",
|
|
35
|
-
"@sveltejs/kit": "^1.
|
|
35
|
+
"@sveltejs/kit": "^1.20.4",
|
|
36
36
|
"@sveltejs/package": "^1.0.2",
|
|
37
37
|
"@testing-library/svelte": "^3.2.2",
|
|
38
38
|
"@testing-library/user-event": "^14.4.3",
|
|
39
|
-
"@typescript-eslint/eslint-plugin": "^5.59.
|
|
40
|
-
"@typescript-eslint/parser": "^5.59.
|
|
39
|
+
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
|
40
|
+
"@typescript-eslint/parser": "^5.59.11",
|
|
41
41
|
"autoprefixer": "^10.4.14",
|
|
42
42
|
"cssnano": "^6.0.1",
|
|
43
|
-
"dotenv": "^16.0
|
|
44
|
-
"edit-package-json": "^0.8.
|
|
45
|
-
"eslint": "^8.
|
|
43
|
+
"dotenv": "^16.3.0",
|
|
44
|
+
"edit-package-json": "^0.8.14",
|
|
45
|
+
"eslint": "^8.43.0",
|
|
46
46
|
"eslint-config-prettier": "^8.8.0",
|
|
47
47
|
"eslint-plugin-svelte3": "^4.0.0",
|
|
48
48
|
"husky": "^8.0.3",
|
|
49
|
-
"jsdom": "^22.
|
|
49
|
+
"jsdom": "^22.1.0",
|
|
50
50
|
"micromatch": "^4.0.5",
|
|
51
|
-
"postcss": "^8.4.
|
|
51
|
+
"postcss": "^8.4.24",
|
|
52
52
|
"prettier": "^2.8.8",
|
|
53
|
-
"prettier-plugin-svelte": "^2.10.
|
|
53
|
+
"prettier-plugin-svelte": "^2.10.1",
|
|
54
54
|
"schema-dts": "^1.1.2",
|
|
55
|
-
"svelte-check": "^3.3
|
|
56
|
-
"svelte2tsx": "^0.6.
|
|
55
|
+
"svelte-check": "^3.4.3",
|
|
56
|
+
"svelte2tsx": "^0.6.15",
|
|
57
57
|
"tailwindcss": "^3.3.2",
|
|
58
|
-
"tslib": "^2.5.
|
|
58
|
+
"tslib": "^2.5.3",
|
|
59
59
|
"typescript": "^5.0.4",
|
|
60
|
-
"vite": "^4.3.
|
|
61
|
-
"vitest": "^0.
|
|
60
|
+
"vite": "^4.3.9",
|
|
61
|
+
"vitest": "^0.32.2"
|
|
62
62
|
},
|
|
63
63
|
"type": "module",
|
|
64
64
|
"license": "MIT",
|
package/types/index.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export interface PhoneNumberError {
|
|
|
34
34
|
error: PhoneNumberParseError;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
export interface
|
|
37
|
+
export interface DetailedValue {
|
|
38
38
|
countryCode?: CountryCode | null;
|
|
39
39
|
isValid: boolean;
|
|
40
40
|
phoneNumber: string | null;
|
|
@@ -52,16 +52,6 @@ export interface NormalizedTelNumber {
|
|
|
52
52
|
export type PhoneNumberParseError = 'NOT_A_NUMBER' | 'INVALID_COUNTRY' | 'TOO_SHORT' | 'TOO_LONG';
|
|
53
53
|
export type PhoneType = 'FIXED_LINE' | 'MOBILE';
|
|
54
54
|
|
|
55
|
-
export type {
|
|
56
|
-
CountryCallingCode,
|
|
57
|
-
CountryCode,
|
|
58
|
-
E164Number,
|
|
59
|
-
NationalNumber,
|
|
60
|
-
PhoneNumber,
|
|
61
|
-
Countries,
|
|
62
|
-
MetadataJson
|
|
63
|
-
};
|
|
64
|
-
|
|
65
55
|
export interface TelInputValidity {
|
|
66
56
|
value: boolean | null;
|
|
67
57
|
errorMessage?: string;
|
|
@@ -80,6 +70,11 @@ export interface TelInputOptions {
|
|
|
80
70
|
* @default true
|
|
81
71
|
*/
|
|
82
72
|
spaces?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Set validation to false if you change the country property.
|
|
75
|
+
* @default false
|
|
76
|
+
*/
|
|
77
|
+
invalidateOnCountryChange?: boolean;
|
|
83
78
|
/**
|
|
84
79
|
* "formatInternational": "+36 20 123 4567",
|
|
85
80
|
* "formatOriginal": "20 123 4567",
|
|
@@ -88,3 +83,13 @@ export interface TelInputOptions {
|
|
|
88
83
|
*/
|
|
89
84
|
// format: 'original' | 'national' | 'international';
|
|
90
85
|
}
|
|
86
|
+
|
|
87
|
+
export type {
|
|
88
|
+
CountryCallingCode,
|
|
89
|
+
CountryCode,
|
|
90
|
+
E164Number,
|
|
91
|
+
NationalNumber,
|
|
92
|
+
PhoneNumber,
|
|
93
|
+
Countries,
|
|
94
|
+
MetadataJson
|
|
95
|
+
};
|
package/assets/regions.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const rawRegions: (string | number | string[])[][];
|
package/assets/regions.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
// Country model:
|
|
2
|
-
// [
|
|
3
|
-
// Country name,
|
|
4
|
-
// Regions,
|
|
5
|
-
// iso2 code,
|
|
6
|
-
// International dial code,
|
|
7
|
-
// Format (if available),
|
|
8
|
-
// Order priority (if >1 country with same dial code),
|
|
9
|
-
// Area codes (if >1 country with same dial code)
|
|
10
|
-
// ]
|
|
11
|
-
//
|
|
12
|
-
// Regions:
|
|
13
|
-
// ['america', 'europe', 'asia', 'oceania', 'africa']
|
|
14
|
-
//
|
|
15
|
-
// Sub-regions:
|
|
16
|
-
// ['north-america', 'south-america', 'central-america', 'carribean',
|
|
17
|
-
// 'eu-union', 'ex-ussr', 'ex-yugos', 'baltic', 'middle-east', 'north-africa']
|
|
18
|
-
export const rawRegions = [
|
|
19
|
-
['American Samoa', ['oceania'], 'as', '1684'],
|
|
20
|
-
['Anguilla', ['america', 'carribean'], 'ai', '1264'],
|
|
21
|
-
['Bermuda', ['america', 'north-america'], 'bm', '1441'],
|
|
22
|
-
['British Virgin Islands', ['america', 'carribean'], 'vg', '1284'],
|
|
23
|
-
['Cayman Islands', ['america', 'carribean'], 'ky', '1345'],
|
|
24
|
-
['Cook Islands', ['oceania'], 'ck', '682'],
|
|
25
|
-
['Falkland Islands', ['america', 'south-america'], 'fk', '500'],
|
|
26
|
-
['Faroe Islands', ['europe'], 'fo', '298'],
|
|
27
|
-
['Gibraltar', ['europe'], 'gi', '350'],
|
|
28
|
-
['Greenland', ['america'], 'gl', '299'],
|
|
29
|
-
['Jersey', ['europe', 'eu-union'], 'je', '44', '.... ......'],
|
|
30
|
-
['Montserrat', ['america', 'carribean'], 'ms', '1664'],
|
|
31
|
-
['Niue', ['asia'], 'nu', '683'],
|
|
32
|
-
['Norfolk Island', ['oceania'], 'nf', '672'],
|
|
33
|
-
['Northern Mariana Islands', ['oceania'], 'mp', '1670'],
|
|
34
|
-
['Saint Barthélemy', ['america', 'carribean'], 'bl', '590', '', 1],
|
|
35
|
-
['Saint Helena', ['africa'], 'sh', '290'],
|
|
36
|
-
['Saint Martin', ['america', 'carribean'], 'mf', '590', '', 2],
|
|
37
|
-
['Saint Pierre and Miquelon', ['america', 'north-america'], 'pm', '508'],
|
|
38
|
-
['Sint Maarten', ['america', 'carribean'], 'sx', '1721'],
|
|
39
|
-
['Tokelau', ['oceania'], 'tk', '690'],
|
|
40
|
-
['Turks and Caicos Islands', ['america', 'carribean'], 'tc', '1649'],
|
|
41
|
-
['U.S. Virgin Islands', ['america', 'carribean'], 'vi', '1340'],
|
|
42
|
-
['Wallis and Futuna', ['oceania'], 'wf', '681']
|
|
43
|
-
];
|
package/assets/telTypes.d.ts
DELETED
package/assets/telTypes.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { capitalize } from '../utils/helpers';
|
|
2
|
-
export const telTypes = [
|
|
3
|
-
'PREMIUM_RATE',
|
|
4
|
-
'TOLL_FREE',
|
|
5
|
-
'SHARED_COST',
|
|
6
|
-
'VOIP',
|
|
7
|
-
'PERSONAL_NUMBER',
|
|
8
|
-
'PAGER',
|
|
9
|
-
'UAN',
|
|
10
|
-
'VOICEMAIL',
|
|
11
|
-
'FIXED_LINE_OR_MOBILE',
|
|
12
|
-
'FIXED_LINE',
|
|
13
|
-
'MOBILE'
|
|
14
|
-
].map((el) => {
|
|
15
|
-
return { id: el, value: el, label: capitalize(el.split('_').join(' ')) };
|
|
16
|
-
});
|
|
@@ -1,156 +0,0 @@
|
|
|
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
|
-
let selected;
|
|
8
|
-
export let clickOutside = true;
|
|
9
|
-
export let closeOnClick = true;
|
|
10
|
-
export let disabled = false;
|
|
11
|
-
export let parsedTelInput = null;
|
|
12
|
-
export let value;
|
|
13
|
-
$:
|
|
14
|
-
selectedCountryDialCode = normalizedCountries.find((el) => el.iso2 === selected)?.dialCode || null;
|
|
15
|
-
let isOpen = false;
|
|
16
|
-
$:
|
|
17
|
-
isValid = parsedTelInput?.isValid ?? false;
|
|
18
|
-
const toggleDropDown = (e) => {
|
|
19
|
-
e.preventDefault();
|
|
20
|
-
isOpen = !isOpen;
|
|
21
|
-
};
|
|
22
|
-
const closeDropdown = (e) => {
|
|
23
|
-
e?.preventDefault();
|
|
24
|
-
isOpen = false;
|
|
25
|
-
searchText = "";
|
|
26
|
-
};
|
|
27
|
-
const selectClick = () => {
|
|
28
|
-
if (closeOnClick)
|
|
29
|
-
closeDropdown();
|
|
30
|
-
};
|
|
31
|
-
const closeOnClickOutside = () => {
|
|
32
|
-
if (clickOutside) {
|
|
33
|
-
closeDropdown();
|
|
34
|
-
}
|
|
35
|
-
};
|
|
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;
|
|
38
|
-
const handleSelect = (val, e) => {
|
|
39
|
-
if (disabled)
|
|
40
|
-
return;
|
|
41
|
-
e?.preventDefault();
|
|
42
|
-
if (selected === void 0 || selected === null || typeof selected === typeof val && selected !== val) {
|
|
43
|
-
selected = val;
|
|
44
|
-
onChange(val);
|
|
45
|
-
selectClick();
|
|
46
|
-
} else {
|
|
47
|
-
dispatch("same", { option: val });
|
|
48
|
-
selectClick();
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
const dispatch = createEventDispatcher();
|
|
52
|
-
const onChange = (selectedCountry) => {
|
|
53
|
-
dispatch("change", { option: selectedCountry });
|
|
54
|
-
};
|
|
55
|
-
</script>
|
|
56
|
-
|
|
57
|
-
<div
|
|
58
|
-
class="flex rounded-lg {isValid
|
|
59
|
-
? ``
|
|
60
|
-
: ` ring-pink-500 dark:ring-pink-500 ring-1 focus-within:ring-offset-1 focus-within:ring-offset-pink-500/50 focus-within:ring-2`}"
|
|
61
|
-
use:clickOutsideAction={closeOnClickOutside}
|
|
62
|
-
>
|
|
63
|
-
<button
|
|
64
|
-
id="states-button"
|
|
65
|
-
data-dropdown-toggle="dropdown-states"
|
|
66
|
-
class="flex-shrink-0 overflow-hidden z-10 inline-flex items-center py-2.5 px-4 text-sm font-medium text-center text-gray-500 bg-gray-100 border border-gray-300 rounded-l-lg hover:bg-gray-200 focus:outline-none dark:bg-gray-700 dark:hover:bg-gray-600 dark:text-white dark:border-gray-600"
|
|
67
|
-
type="button"
|
|
68
|
-
on:click={toggleDropDown}
|
|
69
|
-
>
|
|
70
|
-
{#if selected && selected !== null}
|
|
71
|
-
<div class="inline-flex items-center text-left">
|
|
72
|
-
<span class="flag flag-{selected.toLowerCase()} flex-shrink-0 mr-3" />
|
|
73
|
-
<span class=" text-gray-500">+{selectedCountryDialCode}</span>
|
|
74
|
-
</div>
|
|
75
|
-
{:else}
|
|
76
|
-
Please select
|
|
77
|
-
{/if}
|
|
78
|
-
<svg
|
|
79
|
-
aria-hidden="true"
|
|
80
|
-
class="ml-1 w-4 h-4"
|
|
81
|
-
fill="currentColor"
|
|
82
|
-
viewBox="0 0 20 20"
|
|
83
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
84
|
-
>
|
|
85
|
-
<path
|
|
86
|
-
fill-rule="evenodd"
|
|
87
|
-
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
|
|
88
|
-
clip-rule="evenodd"
|
|
89
|
-
/>
|
|
90
|
-
</svg>
|
|
91
|
-
</button>
|
|
92
|
-
{#if isOpen}
|
|
93
|
-
<div
|
|
94
|
-
id="dropdown-countries"
|
|
95
|
-
class="z-10 max-w-fit bg-white rounded divide-y divide-gray-100 shadow dark:bg-gray-700 absolute translate-y-11 overflow-hidden"
|
|
96
|
-
data-popper-reference-hidden=""
|
|
97
|
-
data-popper-escaped=""
|
|
98
|
-
data-popper-placement="bottom"
|
|
99
|
-
aria-orientation="vertical"
|
|
100
|
-
aria-labelledby="country-button"
|
|
101
|
-
tabindex="-1"
|
|
102
|
-
>
|
|
103
|
-
<ul
|
|
104
|
-
class="text-sm text-gray-700 dark:text-gray-200 max-h-48 overflow-y-auto"
|
|
105
|
-
aria-labelledby="countries-button"
|
|
106
|
-
role="listbox"
|
|
107
|
-
>
|
|
108
|
-
{#if true}
|
|
109
|
-
<input
|
|
110
|
-
aria-autocomplete="list"
|
|
111
|
-
type="text"
|
|
112
|
-
class="px-4 py-2 text-gray-900 focus:outline-none w-full sticky top-0"
|
|
113
|
-
bind:value={searchText}
|
|
114
|
-
/>
|
|
115
|
-
{/if}
|
|
116
|
-
{#each filteredItems as country (country.id)}
|
|
117
|
-
{@const isActive = isSelected(country.iso2, selected)}
|
|
118
|
-
<li role="option" aria-selected={isActive}>
|
|
119
|
-
<button
|
|
120
|
-
value={country.iso2}
|
|
121
|
-
type="button"
|
|
122
|
-
class="inline-flex py-2 px-4 w-full text-sm hover:bg-gray-100 dark:hover:bg-gray-600
|
|
123
|
-
active:bg-gray-800 dark:active:bg-gray-800 overflow-hidden
|
|
124
|
-
{isActive
|
|
125
|
-
? 'bg-gray-600 dark:text-white'
|
|
126
|
-
: 'dark:hover:text-white dark:text-gray-400'}"
|
|
127
|
-
on:click={(e) => {
|
|
128
|
-
handleSelect(country.iso2, e);
|
|
129
|
-
}}
|
|
130
|
-
>
|
|
131
|
-
<div class="inline-flex items-center text-left">
|
|
132
|
-
<span
|
|
133
|
-
class="flag flag-{country.iso2.toLowerCase()} flex-shrink-0 mr-3"
|
|
134
|
-
/>
|
|
135
|
-
<span class="mr-2">{country.name}</span>
|
|
136
|
-
<span class=" text-gray-500">+{country.dialCode}</span>
|
|
137
|
-
</div>
|
|
138
|
-
</button>
|
|
139
|
-
</li>
|
|
140
|
-
{/each}
|
|
141
|
-
</ul>
|
|
142
|
-
</div>
|
|
143
|
-
{/if}
|
|
144
|
-
|
|
145
|
-
<TelInput
|
|
146
|
-
id="tel-input"
|
|
147
|
-
bind:country={selected}
|
|
148
|
-
bind:parsedTelInput
|
|
149
|
-
bind:value
|
|
150
|
-
class="border border-gray-300 border-l-gray-100 dark:border-l-gray-700 dark:border-gray-600 {isValid
|
|
151
|
-
? `bg-gray-50 dark:bg-gray-700
|
|
152
|
-
dark:placeholder-gray-400 dark:text-white text-gray-900`
|
|
153
|
-
: `dark:bg-gray-700`} text-sm rounded-r-lg block w-full p-2.5
|
|
154
|
-
focus:outline-none"
|
|
155
|
-
/>
|
|
156
|
-
</div>
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { SvelteComponentTyped } from "svelte";
|
|
2
|
-
import type { NormalizedTelNumber, E164Number } from '../../types';
|
|
3
|
-
declare const __propDef: {
|
|
4
|
-
props: {
|
|
5
|
-
searchText?: string | undefined;
|
|
6
|
-
clickOutside?: boolean | undefined;
|
|
7
|
-
closeOnClick?: boolean | undefined;
|
|
8
|
-
disabled?: boolean | undefined;
|
|
9
|
-
parsedTelInput?: NormalizedTelNumber | null | undefined;
|
|
10
|
-
value: E164Number | null;
|
|
11
|
-
};
|
|
12
|
-
events: {
|
|
13
|
-
change: CustomEvent<any>;
|
|
14
|
-
} & {
|
|
15
|
-
[evt: string]: CustomEvent<any>;
|
|
16
|
-
};
|
|
17
|
-
slots: {};
|
|
18
|
-
};
|
|
19
|
-
export type AdvancedTelInputProps = typeof __propDef.props;
|
|
20
|
-
export type AdvancedTelInputEvents = typeof __propDef.events;
|
|
21
|
-
export type AdvancedTelInputSlots = typeof __propDef.slots;
|
|
22
|
-
export default class AdvancedTelInput extends SvelteComponentTyped<AdvancedTelInputProps, AdvancedTelInputEvents, AdvancedTelInputSlots> {
|
|
23
|
-
}
|
|
24
|
-
export {};
|