svelte-tel-input 3.5.1 → 3.6.0
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/README.md +4 -4
- package/dist/components/input/TelInput.svelte +53 -11
- package/dist/types/index.d.ts +5 -0
- package/dist/utils/directives/telInputAction.d.ts +2 -1
- package/dist/utils/directives/telInputAction.js +3 -2
- package/dist/utils/helpers.d.ts +4 -3
- package/dist/utils/helpers.js +9 -9
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -63,12 +63,12 @@ _Snippet would be too long_ - [Example](https://github.com/gyurielf/svelte-tel-i
|
|
|
63
63
|
name="Country"
|
|
64
64
|
bind:value={selectedCountry}
|
|
65
65
|
>
|
|
66
|
-
<option value={null} hidden={
|
|
66
|
+
<option value={null} hidden={selectedCountry !== null}>Please select</option>
|
|
67
67
|
{#each normalizedCountries as currentCountry (currentCountry.id)}
|
|
68
68
|
<option
|
|
69
69
|
value={currentCountry.iso2}
|
|
70
|
-
selected={currentCountry.iso2 ===
|
|
71
|
-
aria-selected={currentCountry.iso2 ===
|
|
70
|
+
selected={currentCountry.iso2 === selectedCountry}
|
|
71
|
+
aria-selected={currentCountry.iso2 === selectedCountry}
|
|
72
72
|
>
|
|
73
73
|
{currentCountry.iso2} (+{currentCountry.dialCode})
|
|
74
74
|
</option>
|
|
@@ -79,7 +79,7 @@ _Snippet would be too long_ - [Example](https://github.com/gyurielf/svelte-tel-i
|
|
|
79
79
|
bind:value
|
|
80
80
|
bind:valid
|
|
81
81
|
bind:detailedValue
|
|
82
|
-
class="basic-tel-input {!
|
|
82
|
+
class="basic-tel-input {!valid ? 'invalid' : ''}"
|
|
83
83
|
/>
|
|
84
84
|
</div>
|
|
85
85
|
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
<script>import { createEventDispatcher, onMount } from "svelte";
|
|
1
|
+
<script>import { createEventDispatcher, onMount, tick } from "svelte";
|
|
2
2
|
import { parsePhoneNumberWithError, ParseError } from "libphonenumber-js/max";
|
|
3
3
|
import {
|
|
4
4
|
normalizeTelInput,
|
|
5
5
|
getCountryForPartialE164Number,
|
|
6
6
|
generatePlaceholder,
|
|
7
|
-
telInputAction
|
|
7
|
+
telInputAction,
|
|
8
|
+
allowedCharacters
|
|
8
9
|
} from "../../utils/index.js";
|
|
9
10
|
const dispatch = createEventDispatcher();
|
|
10
11
|
const defaultOptions = {
|
|
11
12
|
autoPlaceholder: true,
|
|
12
13
|
spaces: true,
|
|
13
14
|
invalidateOnCountryChange: false,
|
|
14
|
-
format: "national"
|
|
15
|
+
format: "national",
|
|
16
|
+
strictCountry: false
|
|
15
17
|
};
|
|
16
18
|
export let autocomplete = null;
|
|
17
19
|
let classes = "";
|
|
@@ -44,19 +46,34 @@ const updateCountry = (countryCode) => {
|
|
|
44
46
|
country = countryCode;
|
|
45
47
|
prevCountry = country;
|
|
46
48
|
dispatch("updateCountry", country);
|
|
49
|
+
dispatch("updateDetailedValue", detailedValue);
|
|
47
50
|
}
|
|
48
51
|
return country;
|
|
49
52
|
};
|
|
50
|
-
const
|
|
53
|
+
const findNewCursorPosition = (newValue, formattedValue, initialCursorPosition) => {
|
|
54
|
+
let fvIndex = 0;
|
|
55
|
+
for (let nvIndex = 0; nvIndex < initialCursorPosition; nvIndex++) {
|
|
56
|
+
const nvChar = allowedCharacters(newValue[nvIndex], { spaces: false });
|
|
57
|
+
if (nvChar >= "0" && nvChar <= "9") {
|
|
58
|
+
while (!(formattedValue[fvIndex] >= "0" && formattedValue[fvIndex] <= "9") && fvIndex < formattedValue.length) {
|
|
59
|
+
fvIndex++;
|
|
60
|
+
}
|
|
61
|
+
fvIndex++;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return fvIndex;
|
|
65
|
+
};
|
|
66
|
+
const handleParsePhoneNumber = async (rawInput, currCountry = null) => {
|
|
51
67
|
const input = rawInput;
|
|
52
68
|
if (input !== null) {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
69
|
+
const detectedCountry = getCountryForPartialE164Number(input);
|
|
70
|
+
const useCountry = options?.strictCountry ? currCountry : detectedCountry ?? currCountry;
|
|
71
|
+
if (!options?.strictCountry && detectedCountry && detectedCountry !== prevCountry) {
|
|
72
|
+
updateCountry(detectedCountry);
|
|
56
73
|
}
|
|
57
74
|
try {
|
|
58
75
|
detailedValue = normalizeTelInput(
|
|
59
|
-
parsePhoneNumberWithError(input,
|
|
76
|
+
parsePhoneNumberWithError(input, useCountry ?? void 0)
|
|
60
77
|
);
|
|
61
78
|
} catch (err) {
|
|
62
79
|
if (err instanceof ParseError) {
|
|
@@ -71,10 +88,31 @@ const handleParsePhoneNumber = (rawInput, currCountry = null) => {
|
|
|
71
88
|
}
|
|
72
89
|
const formatOption = combinedOptions.format === "national" ? "nationalNumber" : "e164";
|
|
73
90
|
const formattedValue = combinedOptions.format === "national" ? "formatOriginal" : "formatInternational";
|
|
91
|
+
const initialCursorPosition = el?.selectionStart || 0;
|
|
74
92
|
if (combinedOptions.spaces && detailedValue?.[formattedValue]) {
|
|
75
93
|
inputValue = detailedValue[formattedValue] ?? null;
|
|
94
|
+
await tick();
|
|
95
|
+
if (el) {
|
|
96
|
+
const newCursorPosition = findNewCursorPosition(
|
|
97
|
+
input,
|
|
98
|
+
inputValue,
|
|
99
|
+
initialCursorPosition
|
|
100
|
+
);
|
|
101
|
+
el.selectionStart = newCursorPosition;
|
|
102
|
+
el.selectionEnd = newCursorPosition;
|
|
103
|
+
}
|
|
76
104
|
} else if (detailedValue?.[formatOption]) {
|
|
77
105
|
inputValue = detailedValue[formatOption] ?? null;
|
|
106
|
+
await tick();
|
|
107
|
+
if (el) {
|
|
108
|
+
const newCursorPosition = findNewCursorPosition(
|
|
109
|
+
input,
|
|
110
|
+
inputValue,
|
|
111
|
+
initialCursorPosition
|
|
112
|
+
);
|
|
113
|
+
el.selectionStart = newCursorPosition;
|
|
114
|
+
el.selectionEnd = newCursorPosition;
|
|
115
|
+
}
|
|
78
116
|
}
|
|
79
117
|
value = detailedValue?.e164 ?? input ?? null;
|
|
80
118
|
valid = detailedValue?.isValid ?? false;
|
|
@@ -124,13 +162,16 @@ export const updateValue = (newValue, newCountry) => {
|
|
|
124
162
|
if (castedValue) {
|
|
125
163
|
handleParsePhoneNumber(
|
|
126
164
|
castedValue,
|
|
127
|
-
getCountryForPartialE164Number(castedValue) || newCountry
|
|
165
|
+
options?.strictCountry ? country : getCountryForPartialE164Number(castedValue) || newCountry
|
|
128
166
|
);
|
|
129
167
|
}
|
|
130
168
|
};
|
|
131
169
|
onMount(() => {
|
|
132
170
|
if (value) {
|
|
133
|
-
handleParsePhoneNumber(
|
|
171
|
+
handleParsePhoneNumber(
|
|
172
|
+
value,
|
|
173
|
+
options?.strictCountry ? country : getCountryForPartialE164Number(value) || country
|
|
174
|
+
);
|
|
134
175
|
}
|
|
135
176
|
});
|
|
136
177
|
</script>
|
|
@@ -162,6 +203,7 @@ onMount(() => {
|
|
|
162
203
|
use:telInputAction={{
|
|
163
204
|
handler: handleInputAction,
|
|
164
205
|
spaces: combinedOptions.spaces,
|
|
165
|
-
value
|
|
206
|
+
value,
|
|
207
|
+
strictCountryCode: combinedOptions.strictCountry
|
|
166
208
|
}}
|
|
167
209
|
/>
|
package/dist/types/index.d.ts
CHANGED
|
@@ -75,6 +75,11 @@ export interface TelInputOptions {
|
|
|
75
75
|
* @default false
|
|
76
76
|
*/
|
|
77
77
|
invalidateOnCountryChange?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Prevent automatic country parsing from the input value. It validates via the passed `country` property value.
|
|
80
|
+
* @default false
|
|
81
|
+
*/
|
|
82
|
+
strictCountry?: boolean;
|
|
78
83
|
/**
|
|
79
84
|
* "international": `+36 20 123 4567`,
|
|
80
85
|
* "default": `20 123 4567`
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { E164Number } from 'libphonenumber-js';
|
|
2
|
-
export declare const telInputAction: (node: HTMLInputElement, { handler, spaces }: {
|
|
2
|
+
export declare const telInputAction: (node: HTMLInputElement, { handler, spaces, strictCountryCode }: {
|
|
3
3
|
handler: (val: string) => void;
|
|
4
4
|
spaces: boolean;
|
|
5
5
|
value: E164Number | null;
|
|
6
|
+
strictCountryCode: boolean;
|
|
6
7
|
}) => {
|
|
7
8
|
update(params: {
|
|
8
9
|
handler: (val: string) => void;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { inspectAllowedChars, inputParser } from '../../index.js';
|
|
2
|
-
export const telInputAction = (node, { handler, spaces }) => {
|
|
2
|
+
export const telInputAction = (node, { handler, spaces, strictCountryCode }) => {
|
|
3
3
|
const onInput = (event) => {
|
|
4
4
|
if (node && node.contains(event.target)) {
|
|
5
5
|
const currentValue = event.target.value;
|
|
6
6
|
const formattedInput = inputParser(currentValue, {
|
|
7
7
|
parseCharacter: inspectAllowedChars,
|
|
8
|
-
allowSpaces: spaces
|
|
8
|
+
allowSpaces: spaces,
|
|
9
|
+
disallowPlusSign: strictCountryCode
|
|
9
10
|
});
|
|
10
11
|
node.value = formattedInput;
|
|
11
12
|
handler(formattedInput);
|
package/dist/utils/helpers.d.ts
CHANGED
|
@@ -69,8 +69,9 @@ export declare const isSupportedCountry: (country: CountryCode, metadata: Metada
|
|
|
69
69
|
export declare const allowedCharacters: (character: string, { spaces }?: {
|
|
70
70
|
spaces?: boolean;
|
|
71
71
|
}) => string;
|
|
72
|
-
export declare const inputParser: (text: string, { allowSpaces, parseCharacter }: {
|
|
72
|
+
export declare const inputParser: (text: string, { allowSpaces, parseCharacter, disallowPlusSign }: {
|
|
73
73
|
allowSpaces: boolean;
|
|
74
|
-
|
|
74
|
+
disallowPlusSign: boolean;
|
|
75
|
+
parseCharacter: (char: string, val: string, allowSpaces: boolean, disallowPlusSign: boolean) => string | undefined;
|
|
75
76
|
}) => string;
|
|
76
|
-
export declare const inspectAllowedChars: (character: string, value: string, allowSpaces
|
|
77
|
+
export declare const inspectAllowedChars: (character: string, value: string, allowSpaces: boolean, disallowPlusSign: boolean) => string;
|
package/dist/utils/helpers.js
CHANGED
|
@@ -31,16 +31,16 @@ export const normalizeTelInput = (input) => {
|
|
|
31
31
|
isPossible: input ? input.isPossible() : false,
|
|
32
32
|
phoneNumber: input ? input.number : null,
|
|
33
33
|
countryCallingCode: input ? input.countryCallingCode : null,
|
|
34
|
-
formattedNumber: input ? input.
|
|
34
|
+
formattedNumber: input ? new AsYouType().input(input.number) : null,
|
|
35
35
|
nationalNumber: input ? input.nationalNumber : null,
|
|
36
|
-
formatInternational: input ? input.
|
|
36
|
+
formatInternational: input ? new AsYouType().input(input.number) : null,
|
|
37
37
|
formatOriginal: input
|
|
38
|
-
?
|
|
39
|
-
.
|
|
38
|
+
? new AsYouType()
|
|
39
|
+
.input(input.number)
|
|
40
40
|
.slice(input.countryCallingCode.length + 1)
|
|
41
41
|
.trim()
|
|
42
42
|
: null,
|
|
43
|
-
formatNational: input ? input.
|
|
43
|
+
formatNational: input ? new AsYouType(input.country).input(input.number) : null,
|
|
44
44
|
uri: input ? input.getURI() : null,
|
|
45
45
|
e164: input ? input.number : null
|
|
46
46
|
}).filter(([, value]) => value !== null));
|
|
@@ -265,19 +265,19 @@ export const allowedCharacters = (character, { spaces } = {
|
|
|
265
265
|
// Allow digits
|
|
266
266
|
return DIGITS[character];
|
|
267
267
|
};
|
|
268
|
-
export const inputParser = (text, { allowSpaces, parseCharacter }) => {
|
|
268
|
+
export const inputParser = (text, { allowSpaces, parseCharacter, disallowPlusSign }) => {
|
|
269
269
|
let value = '';
|
|
270
270
|
for (let index = 0; index < text.length; index++) {
|
|
271
|
-
const character = parseCharacter(text[index], value, allowSpaces);
|
|
271
|
+
const character = parseCharacter(text[index], value, allowSpaces, disallowPlusSign);
|
|
272
272
|
if (character !== undefined) {
|
|
273
273
|
value += character;
|
|
274
274
|
}
|
|
275
275
|
}
|
|
276
276
|
return value;
|
|
277
277
|
};
|
|
278
|
-
export const inspectAllowedChars = (character, value, allowSpaces) => {
|
|
278
|
+
export const inspectAllowedChars = (character, value, allowSpaces, disallowPlusSign) => {
|
|
279
279
|
// Leading plus is allowed
|
|
280
|
-
if (character === '+') {
|
|
280
|
+
if (!disallowPlusSign && character === '+') {
|
|
281
281
|
if (!value) {
|
|
282
282
|
return character;
|
|
283
283
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-tel-input",
|
|
3
3
|
"description": "svelte-tel-input",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.6.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/gyurielf/svelte-tel-input.git"
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"pnpm": ">= 8"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"svelte": "^3.58.0 || ^4.0.0"
|
|
30
|
+
"svelte": "^3.58.0 || ^4.0.0 || ^5.0.0"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"libphonenumber-js": "1.10.43"
|