phone input: fix broken incoming values
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
import { AsYouType, type PhoneNumber, type CountryCode } from 'libphonenumber-js';
|
import { AsYouType, type PhoneNumber, type CountryCode } from 'libphonenumber-js';
|
||||||
import { generateIdentifier } from './util';
|
import { generateIdentifier } from './util';
|
||||||
import type { ClassValue } from 'svelte/elements';
|
import type { ClassValue } from 'svelte/elements';
|
||||||
|
import { untrack } from 'svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
name?: string;
|
name?: string;
|
||||||
@@ -31,6 +32,7 @@
|
|||||||
|
|
||||||
const id = $derived(generateIdentifier('phone-input', name));
|
const id = $derived(generateIdentifier('phone-input', name));
|
||||||
let lastRawValue = $state('');
|
let lastRawValue = $state('');
|
||||||
|
let lastValue = $state<PhoneNumber | undefined>(value);
|
||||||
let country = $state<ICountry | undefined>();
|
let country = $state<ICountry | undefined>();
|
||||||
let selectedCountryItem = $state<ComboboxOption | undefined>();
|
let selectedCountryItem = $state<ComboboxOption | undefined>();
|
||||||
let countriesOpen = $state<boolean>(false);
|
let countriesOpen = $state<boolean>(false);
|
||||||
@@ -101,6 +103,19 @@
|
|||||||
if (country) return country.isoCode as CountryCode;
|
if (country) return country.isoCode as CountryCode;
|
||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let renderValue = value?.formatNational() ?? '';
|
||||||
|
let renderInputElement = $state<HTMLInputElement | null>(null);
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (value) {
|
||||||
|
untrack(() => {
|
||||||
|
if (renderInputElement) {
|
||||||
|
renderInputElement.value = value?.formatNational() ?? '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#snippet renderIcon(item: ComboboxOption)}
|
{#snippet renderIcon(item: ComboboxOption)}
|
||||||
@@ -139,6 +154,8 @@
|
|||||||
|
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<StyledRawInput
|
<StyledRawInput
|
||||||
|
value={renderValue}
|
||||||
|
bind:ref={renderInputElement}
|
||||||
type="tel"
|
type="tel"
|
||||||
{placeholder}
|
{placeholder}
|
||||||
validate={{
|
validate={{
|
||||||
@@ -178,18 +195,21 @@
|
|||||||
input.value = formatted;
|
input.value = formatted;
|
||||||
}, 1);
|
}, 1);
|
||||||
}
|
}
|
||||||
value = formatter.getNumber();
|
lastValue = formatter.getNumber();
|
||||||
|
|
||||||
if (formatter.isValid() && formatter.isInternational() && value) {
|
if (formatter.isValid() && formatter.isInternational() && value) {
|
||||||
const country = formatter.getCountry();
|
const country = formatter.getCountry();
|
||||||
if (country) {
|
if (country) {
|
||||||
setCountryByISO(country);
|
setCountryByISO(country);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (value) input.value = value.formatNational();
|
if (lastValue) input.value = lastValue.formatNational();
|
||||||
}, 1);
|
}, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
onblur={() => {
|
||||||
|
value = lastValue;
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user