feat(input-tel): use first preferred region to set a default region

* feat(input-tel): use first preferred region to set a default region

Takes priority over locale, but comes after user input

* chore(input-tel): add changeset
This commit is contained in:
Stijn Van Asschodt 2025-07-03 21:00:05 +02:00 committed by GitHub
parent dc5d224e98
commit 85666d6c49
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 46 additions and 16 deletions

View file

@ -0,0 +1,5 @@
---
'@lion/ui': patch
---
feat(input-tel): use first preferred region to set a default region

View file

@ -42,14 +42,6 @@ import { regionCodeToLocale } from './regionCodeToLocale.js';
* `e164` format that contains all info (both region code and national phone number). * `e164` format that contains all info (both region code and national phone number).
*/ */
export class LionInputTelDropdown extends LionInputTel { export class LionInputTelDropdown extends LionInputTel {
/**
* @configure LitElement
* @type {any}
*/
static properties = {
preferredRegions: { type: Array },
};
refs = { refs = {
/** @type {DropdownRef} */ /** @type {DropdownRef} */
dropdown: /** @type {DropdownRef} */ (createRef()), dropdown: /** @type {DropdownRef} */ (createRef()),
@ -214,11 +206,6 @@ export class LionInputTelDropdown extends LionInputTel {
constructor() { constructor() {
super(); super();
/**
* Regions that will be shown on top of the dropdown
* @type {string[]}
*/
this.preferredRegions = [];
/** /**
* Group label for all countries, when preferredCountries are shown * Group label for all countries, when preferredCountries are shown
* @protected * @protected

View file

@ -27,6 +27,7 @@ export class LionInputTel extends LocalizeMixin(LionInput) {
formatStrategy: { type: String, attribute: 'format-strategy' }, formatStrategy: { type: String, attribute: 'format-strategy' },
formatCountryCodeStyle: { type: String, attribute: 'format-country-code-style' }, formatCountryCodeStyle: { type: String, attribute: 'format-country-code-style' },
activeRegion: { type: String }, activeRegion: { type: String },
preferredRegions: { type: Array },
_phoneUtil: { type: Object, state: true }, _phoneUtil: { type: Object, state: true },
}; };
@ -156,6 +157,12 @@ export class LionInputTel extends LocalizeMixin(LionInput) {
*/ */
this.allowedRegions = []; this.allowedRegions = [];
/**
* Regions that will be shown on top of the dropdown
* @type {RegionCode[]}
*/
this.preferredRegions = [];
/** @private */ /** @private */
this.__isPhoneNumberValidatorInstance = new PhoneNumber(); this.__isPhoneNumberValidatorInstance = new PhoneNumber();
/** @configures ValidateMixin */ /** @configures ValidateMixin */
@ -326,13 +333,19 @@ export class LionInputTel extends LocalizeMixin(LionInput) {
return; return;
} }
// 3. Try to get the region from locale // 3. Get the first region in the list of preferred regions
if (this.preferredRegions?.length > 0) {
this._setActiveRegion(this.preferredRegions[0]);
return;
}
// 4. Try to get the region from locale
if (this._langIso && this._allowedOrAllRegions.includes(this._langIso)) { if (this._langIso && this._allowedOrAllRegions.includes(this._langIso)) {
this._setActiveRegion(this._langIso); this._setActiveRegion(this._langIso);
return; return;
} }
// 4. Not derivable // 5. Not derivable
this._setActiveRegion(undefined); this._setActiveRegion(undefined);
} }
} }

View file

@ -100,6 +100,20 @@ function runActiveRegionTests({ tag, phoneUtilLoadedAfterInit }) {
expect(el.activeRegion).to.equal('NL'); expect(el.activeRegion).to.equal('NL');
}); });
it('.modelValue takes precedence over .preferredRegions when both preconfigured and .modelValue updated', async () => {
const el = await fixture(
html` <${tag} .preferredRegions="${[
'DE',
'BE',
]}" .modelValue="${'+31612345678'}" ></${tag}> `,
);
if (resolvePhoneUtilLoaded) {
resolvePhoneUtilLoaded(undefined);
await el.updateComplete;
}
expect(el.activeRegion).to.equal('NL');
});
it('deducts it from value when modelValue is unparseable', async () => { it('deducts it from value when modelValue is unparseable', async () => {
const modelValue = new Unparseable('+316'); const modelValue = new Unparseable('+316');
const el = await fixture(html` <${tag} .modelValue=${modelValue}></${tag}> `); const el = await fixture(html` <${tag} .modelValue=${modelValue}></${tag}> `);
@ -122,7 +136,18 @@ function runActiveRegionTests({ tag, phoneUtilLoadedAfterInit }) {
expect(el.activeRegion).to.equal('NL'); expect(el.activeRegion).to.equal('NL');
}); });
// 3. **locale**: try to get the region from locale (`html[lang]` attribute) // 3. **preferred-region**: get the first element in the preferred regions list
it('deducts it from the .preferredRegions when provided', async () => {
const el = await fixture(html` <${tag} .preferredRegions="${['DE', 'NL']}"></${tag}> `);
if (resolvePhoneUtilLoaded) {
resolvePhoneUtilLoaded(undefined);
await el.updateComplete;
}
// Region code for country code '+49' is 'DE'
expect(el.activeRegion).to.equal('DE');
});
// 4. **locale**: try to get the region from locale (`html[lang]` attribute)
it('automatically bases it on current locale when nothing preconfigured', async () => { it('automatically bases it on current locale when nothing preconfigured', async () => {
const el = await fixture(html` <${tag}></${tag}> `); const el = await fixture(html` <${tag}></${tag}> `);
if (resolvePhoneUtilLoaded) { if (resolvePhoneUtilLoaded) {