|
6 | 6 | getCountryForPartialE164Number, |
7 | 7 | generatePlaceholder, |
8 | 8 | telInputAction, |
9 | | -
|
10 | 9 | allowedCharacters |
11 | | -
|
12 | 10 | } from '$lib/utils/index.js'; |
13 | 11 | import type { DetailedValue, CountryCode, E164Number, TelInputOptions } from '$lib/types'; |
14 | 12 |
|
|
24 | 22 | autoPlaceholder: true, |
25 | 23 | spaces: true, |
26 | 24 | invalidateOnCountryChange: false, |
27 | | - format: 'national' |
| 25 | + format: 'national', |
| 26 | + strictCountry: false |
28 | 27 | } satisfies TelInputOptions; |
29 | 28 |
|
30 | 29 | export let autocomplete: string | null = null; |
|
79 | 78 | country = countryCode; |
80 | 79 | prevCountry = country; |
81 | 80 | dispatch('updateCountry', country); |
| 81 | + dispatch('updateDetailedValue', detailedValue); |
82 | 82 | } |
83 | 83 | return country; |
84 | 84 | }; |
|
89 | 89 | initialCursorPosition: number |
90 | 90 | ) => { |
91 | 91 | let fvIndex = 0; |
92 | | - for(let nvIndex = 0; nvIndex < initialCursorPosition; nvIndex++) { |
93 | | -
|
| 92 | + for (let nvIndex = 0; nvIndex < initialCursorPosition; nvIndex++) { |
94 | 93 | // Since newValue has not been normalized yet, we need to map any non standard digits. |
95 | | - const nvChar = allowedCharacters(newValue[nvIndex], {spaces: false}); |
| 94 | + const nvChar = allowedCharacters(newValue[nvIndex], { spaces: false }); |
96 | 95 |
|
97 | 96 | // For each non-formatting character encountered in the value entered by the user, |
98 | 97 | // find the corresponding digit in the formatted value. |
99 | | - if(nvChar >= '0' && nvChar <= '9') { |
100 | | - while(!(formattedValue[fvIndex] >= '0' && formattedValue[fvIndex] <= '9') && fvIndex < formattedValue.length) { |
| 98 | + if (nvChar >= '0' && nvChar <= '9') { |
| 99 | + while ( |
| 100 | + !(formattedValue[fvIndex] >= '0' && formattedValue[fvIndex] <= '9') && |
| 101 | + fvIndex < formattedValue.length |
| 102 | + ) { |
101 | 103 | fvIndex++; |
102 | 104 | } |
103 | 105 | fvIndex++; |
104 | 106 | } |
105 | 107 | } |
106 | 108 |
|
107 | 109 | return fvIndex; |
108 | | - } |
| 110 | + }; |
109 | 111 |
|
110 | 112 | const handleParsePhoneNumber = async ( |
111 | 113 | rawInput: string | null, |
112 | 114 | currCountry: CountryCode | null = null |
113 | 115 | ) => { |
114 | 116 | const input = rawInput as E164Number; |
115 | 117 | if (input !== null) { |
116 | | - const numberHasCountry = getCountryForPartialE164Number(input); |
| 118 | + const detectedCountry = getCountryForPartialE164Number(input); |
| 119 | + const useCountry = options?.strictCountry |
| 120 | + ? currCountry |
| 121 | + : detectedCountry ?? currCountry; |
117 | 122 |
|
118 | | - if (numberHasCountry && numberHasCountry !== prevCountry) { |
119 | | - updateCountry(numberHasCountry); |
| 123 | + if (!options?.strictCountry && detectedCountry && detectedCountry !== prevCountry) { |
| 124 | + updateCountry(detectedCountry); |
120 | 125 | } |
121 | 126 |
|
122 | 127 | try { |
123 | 128 | detailedValue = normalizeTelInput( |
124 | | - parsePhoneNumberWithError(input, numberHasCountry ?? currCountry ?? undefined) |
| 129 | + parsePhoneNumberWithError(input, useCountry ?? undefined) |
125 | 130 | ); |
126 | 131 | } catch (err) { |
127 | 132 | if (err instanceof ParseError) { |
|
144 | 149 |
|
145 | 150 | // Need to wait for input element to update before cursor position can be restored |
146 | 151 | await tick(); |
147 | | - if(el) { |
148 | | - const newCursorPosition = findNewCursorPosition(input, inputValue, initialCursorPosition) |
| 152 | + if (el) { |
| 153 | + const newCursorPosition = findNewCursorPosition( |
| 154 | + input, |
| 155 | + inputValue, |
| 156 | + initialCursorPosition |
| 157 | + ); |
149 | 158 | el.selectionStart = newCursorPosition; |
150 | 159 | el.selectionEnd = newCursorPosition; |
151 | 160 | } |
|
154 | 163 |
|
155 | 164 | // Need to wait for input element to update before cursor position can be restored |
156 | 165 | await tick(); |
157 | | - if(el) { |
158 | | - const newCursorPosition = findNewCursorPosition(input, inputValue, initialCursorPosition) |
| 166 | + if (el) { |
| 167 | + const newCursorPosition = findNewCursorPosition( |
| 168 | + input, |
| 169 | + inputValue, |
| 170 | + initialCursorPosition |
| 171 | + ); |
159 | 172 | el.selectionStart = newCursorPosition; |
160 | 173 | el.selectionEnd = newCursorPosition; |
161 | 174 | } |
|
226 | 239 | if (castedValue) { |
227 | 240 | handleParsePhoneNumber( |
228 | 241 | castedValue, |
229 | | - getCountryForPartialE164Number(castedValue) || newCountry |
| 242 | + options?.strictCountry |
| 243 | + ? country |
| 244 | + : getCountryForPartialE164Number(castedValue) || newCountry |
230 | 245 | ); |
231 | 246 | } |
232 | 247 | }; |
233 | 248 |
|
234 | 249 | onMount(() => { |
235 | 250 | if (value) { |
236 | | - handleParsePhoneNumber(value, getCountryForPartialE164Number(value) || country); |
| 251 | + handleParsePhoneNumber( |
| 252 | + value, |
| 253 | + options?.strictCountry ? country : getCountryForPartialE164Number(value) || country |
| 254 | + ); |
237 | 255 | } |
238 | 256 | }); |
239 | 257 | </script> |
|
265 | 283 | use:telInputAction={{ |
266 | 284 | handler: handleInputAction, |
267 | 285 | spaces: combinedOptions.spaces, |
268 | | - value |
| 286 | + value, |
| 287 | + strictCountryCode: combinedOptions.strictCountry |
269 | 288 | }} |
270 | 289 | /> |
0 commit comments