diff --git a/.changeset/chilled-rules-explode.md b/.changeset/chilled-rules-explode.md new file mode 100644 index 000000000..644bfeef5 --- /dev/null +++ b/.changeset/chilled-rules-explode.md @@ -0,0 +1,5 @@ +--- +'@lion/input-tel-dropdown': patch +--- + +substract and export getFlagSymbol function diff --git a/.changeset/plenty-penguins-greet.md b/.changeset/plenty-penguins-greet.md new file mode 100644 index 000000000..6238a4f41 --- /dev/null +++ b/.changeset/plenty-penguins-greet.md @@ -0,0 +1,6 @@ +--- +'@lion/input-tel': patch +'@lion/input-tel-dropdown': patch +--- + +Add option to style the country-code with parentheses in the formatter diff --git a/.changeset/tame-papayas-double.md b/.changeset/tame-papayas-double.md new file mode 100644 index 000000000..993497b9a --- /dev/null +++ b/.changeset/tame-papayas-double.md @@ -0,0 +1,5 @@ +--- +'@lion/input-tel': patch +--- + +Remove unwanted characters in input-tel parser diff --git a/docs/components/input-tel-dropdown/use-cases.md b/docs/components/input-tel-dropdown/use-cases.md index 28225b887..70feaed1e 100644 --- a/docs/components/input-tel-dropdown/use-cases.md +++ b/docs/components/input-tel-dropdown/use-cases.md @@ -81,3 +81,79 @@ export const preferredRegionCodes = () => { `; }; ``` + +## Format + +### Format strategy + +Determines what the formatter output should look like. +Formatting strategies as provided by awesome-phonenumber / google-libphonenumber. + +Possible values: + +| strategy | output | +| :------------ | ------------------------------------: | +| e164 | `+46707123456` | +| international | `+46 70 712 34 56` | +| national | not applicable for input-tel-dropdown | +| significant | not applicable for input-tel-dropdown | +| rfc3966 | `tel:+46-70-712-34-56` | + +Also see: + +- [awesome-phonenumber documentation](https://www.npmjs.com/package/awesome-phonenumber) + +```js preview-story +export const formatStrategy = () => { + loadDefaultFeedbackMessages(); + const inputTel = createRef(); + return html` + + + + `; +}; +``` + +### Format country code style + +You can style the country code with parentheses. + +```js preview-story +export const formatCountryCodeStyle = () => { + loadDefaultFeedbackMessages(); + const inputTel = createRef(); + return html` + + + + `; +}; +``` diff --git a/docs/components/input-tel/use-cases.md b/docs/components/input-tel/use-cases.md index d747fca92..dfd88b138 100644 --- a/docs/components/input-tel/use-cases.md +++ b/docs/components/input-tel/use-cases.md @@ -176,7 +176,9 @@ export const oneAllowedRegion = () => { }; ``` -## Format strategy +## Format + +### Format strategy Determines what the formatter output should look like. Formatting strategies as provided by awesome-phonenumber / google-libphonenumber. @@ -223,7 +225,37 @@ export const formatStrategy = () => { }; ``` -## Live format +### Format country code style + +You can also style the country code with parentheses. + +```js preview-story +export const formatCountryCodeStyle = () => { + loadDefaultFeedbackMessages(); + const inputTel = createRef(); + return html` + + + + `; +}; +``` + +### Live format Type '6' in the example below to see how the phone number is formatted during typing. diff --git a/packages/input-tel-dropdown/index.js b/packages/input-tel-dropdown/index.js index bcce24fb2..1764327a0 100644 --- a/packages/input-tel-dropdown/index.js +++ b/packages/input-tel-dropdown/index.js @@ -1 +1,2 @@ +export { getFlagSymbol } from './src/getFlagSymbol.js'; export { LionInputTelDropdown } from './src/LionInputTelDropdown.js'; diff --git a/packages/input-tel-dropdown/src/LionInputTelDropdown.js b/packages/input-tel-dropdown/src/LionInputTelDropdown.js index 9a3daa87d..79d9cba88 100644 --- a/packages/input-tel-dropdown/src/LionInputTelDropdown.js +++ b/packages/input-tel-dropdown/src/LionInputTelDropdown.js @@ -2,6 +2,7 @@ import { render, html, css, ref, createRef } from '@lion/core'; import { LionInputTel } from '@lion/input-tel'; import { localize } from '@lion/localize'; +import { getFlagSymbol } from './getFlagSymbol.js'; /** * Note: one could consider to implement LionInputTelDropdown as a @@ -31,14 +32,6 @@ import { localize } from '@lion/localize'; * @typedef {TemplateDataForDropdownInputTel & {data: {regionMetaList:RegionMeta[]}}} TemplateDataForIntlInputTel */ -// eslint-disable-next-line prefer-destructuring -/** - * @param {string} char - */ -function getRegionalIndicatorSymbol(char) { - return String.fromCodePoint(0x1f1e6 - 65 + char.toUpperCase().charCodeAt(0)); -} - /** * LionInputTelDropdown renders a dropdown like element next to the text field, inside the * prefix slot. This could be a LionSelect, a LionSelectRich or a native select. @@ -288,7 +281,11 @@ export class LionInputTelDropdown extends LionInputTel { _initModelValueBasedOnDropdown() { if (!this._initialModelValue && !this.dirty && this._phoneUtil) { const countryCode = this._phoneUtil.getCountryCodeForRegionCode(this.activeRegion); - this.__initializedRegionCode = `+${countryCode}`; + if (this.formatCountryCodeStyle === 'parentheses') { + this.__initializedRegionCode = `(+${countryCode})`; + } else { + this.__initializedRegionCode = `+${countryCode}`; + } this.modelValue = this.__initializedRegionCode; this._initialModelValue = this.__initializedRegionCode; this.initInteractionState(); @@ -335,7 +332,11 @@ export class LionInputTelDropdown extends LionInputTel { } else { // In case of dropdown has +31, and input has only +3 const valueObj = this.value.split(' '); - this.modelValue = this._callParser(this.value.replace(valueObj[0], `+${countryCode}`)); + if (this.formatCountryCodeStyle === 'parentheses' && !this.value.includes('(')) { + this.modelValue = this._callParser(this.value.replace(valueObj[0], `(+${countryCode})`)); + } else { + this.modelValue = this._callParser(this.value.replace(valueObj[0], `+${countryCode}`)); + } } } @@ -419,8 +420,7 @@ export class LionInputTelDropdown extends LionInputTel { const countryCode = this._phoneUtil && this._phoneUtil.getCountryCodeForRegionCode(regionCode); - const flagSymbol = - getRegionalIndicatorSymbol(regionCode[0]) + getRegionalIndicatorSymbol(regionCode[1]); + const flagSymbol = getFlagSymbol(regionCode); const destinationList = this.preferredRegions.includes(regionCode) ? this.__regionMetaListPreferred diff --git a/packages/input-tel-dropdown/src/getFlagSymbol.js b/packages/input-tel-dropdown/src/getFlagSymbol.js new file mode 100644 index 000000000..7f4621755 --- /dev/null +++ b/packages/input-tel-dropdown/src/getFlagSymbol.js @@ -0,0 +1,13 @@ +/** + * @param {string} char + */ +function getRegionalIndicatorSymbol(char) { + return String.fromCodePoint(0x1f1e6 - 65 + char.toUpperCase().charCodeAt(0)); +} + +/** + * @param {string} regionCode + */ +export function getFlagSymbol(regionCode) { + return getRegionalIndicatorSymbol(regionCode[0]) + getRegionalIndicatorSymbol(regionCode[1]); +} diff --git a/packages/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.js b/packages/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.js index 2a28e836f..68d4959a9 100644 --- a/packages/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.js +++ b/packages/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.js @@ -1,17 +1,17 @@ -import { - expect, - fixture as _fixture, - fixtureSync as _fixtureSync, - html, - defineCE, - unsafeStatic, - aTimeout, -} from '@open-wc/testing'; -import sinon from 'sinon'; // @ts-ignore import { PhoneUtilManager } from '@lion/input-tel'; // @ts-ignore import { mockPhoneUtilManager, restorePhoneUtilManager } from '@lion/input-tel/test-helpers'; +import { + aTimeout, + defineCE, + expect, + fixture as _fixture, + fixtureSync as _fixtureSync, + html, + unsafeStatic, +} from '@open-wc/testing'; +import sinon from 'sinon'; import { LionInputTelDropdown } from '../src/LionInputTelDropdown.js'; /** @@ -252,17 +252,18 @@ export function runInputTelDropdownSuite({ klass } = { klass: LionInputTelDropdo await aTimeout(0); expect(spy).to.have.been.calledOnce; restorePhoneUtilManager(); + spy.restore(); }); }); describe('On dropdown value change', () => { it('changes the currently active country code in the textbox', async () => { - const el = await fixture( - html` <${tag} .allowedRegions="${[ - 'NL', - 'BE', - ]}" .modelValue="${'+31612345678'}"> `, - ); + const el = await fixture(html` + <${tag} + .allowedRegions="${['NL', 'BE']}" + .modelValue="${'+31612345678'}" + > + `); // @ts-ignore mimicUserChangingDropdown(el.refs.dropdown.value, 'BE'); await el.updateComplete; @@ -282,6 +283,21 @@ export function runInputTelDropdownSuite({ klass } = { klass: LionInputTelDropdo expect(el.value).to.equal('+32'); }); + it('changes the currently active country code in the textbox when empty with parentheses', async () => { + const el = await fixture( + html` <${tag} format-country-code-style="parentheses" .allowedRegions="${[ + 'NL', + 'BE', + ]}"> `, + ); + el.value = ''; + // @ts-ignore + mimicUserChangingDropdown(el.refs.dropdown.value, 'BE'); + await el.updateComplete; + await el.updateComplete; + expect(el.value).to.equal('(+32)'); + }); + it('changes the currently active country code in the textbox when invalid', async () => { const el = await fixture(html` <${tag} .allowedRegions="${['NL', 'BE']}"> `); el.value = '+3'; @@ -381,5 +397,19 @@ export function runInputTelDropdownSuite({ klass } = { klass: LionInputTelDropdo ); }); }); + + describe('is empthy', () => { + it('ignores initial countrycode', async () => { + const el = await fixture(html` <${tag}> `); + // @ts-ignore + expect(el._isEmpty()).to.be.true; + }); + + it('ignores initial countrycode with parentheses', async () => { + const el = await fixture(html` <${tag} format-country-code-style="parentheses"> `); + // @ts-ignore + expect(el._isEmpty()).to.be.true; + }); + }); }); } diff --git a/packages/input-tel/src/LionInputTel.js b/packages/input-tel/src/LionInputTel.js index aa9a67ac0..516ccd55c 100644 --- a/packages/input-tel/src/LionInputTel.js +++ b/packages/input-tel/src/LionInputTel.js @@ -14,7 +14,7 @@ import { localizeNamespaceLoader } from './localizeNamespaceLoader.js'; * @typedef {import('awesome-phonenumber').PhoneNumberTypes} PhoneNumberTypes * @typedef {import('@lion/form-core/types/FormatMixinTypes').FormatOptions} FormatOptions * @typedef {* & import('awesome-phonenumber').default} AwesomePhoneNumber - * @typedef {FormatOptions & {regionCode: RegionCode; formatStrategy: PhoneNumberFormat}} FormatOptionsTel + * @typedef {FormatOptions & {regionCode: RegionCode; formatStrategy: PhoneNumberFormat; formatCountryCodeStyle: string;}} FormatOptionsTel */ export class LionInputTel extends LocalizeMixin(LionInput) { @@ -24,6 +24,7 @@ export class LionInputTel extends LocalizeMixin(LionInput) { static properties = { allowedRegions: { type: Array }, formatStrategy: { type: String, attribute: 'format-strategy' }, + formatCountryCodeStyle: { type: String, attribute: 'format-country-code-style' }, activeRegion: { type: String }, _phoneUtil: { type: Object, state: true }, _needsLightDomRender: { type: Number, state: true }, @@ -139,6 +140,13 @@ export class LionInputTel extends LocalizeMixin(LionInput) { */ this.formatStrategy = 'international'; + /** + * Extra styling of the format strategy + * default | parentheses + * @type {string} + */ + this.formatCountryCodeStyle = 'default'; + /** * The regions that should be considered when international phone numbers are detected. * (when not configured, all regions worldwide will be considered) @@ -208,6 +216,12 @@ export class LionInputTel extends LocalizeMixin(LionInput) { (this.formatOptions).formatStrategy = this.formatStrategy; } + if (changedProperties.has('formatCountryCodeStyle')) { + this._calculateValues({ source: null }); + /** @type {FormatOptionsTel} */ + (this.formatOptions).formatCountryCodeStyle = this.formatCountryCodeStyle; + } + if (changedProperties.has('modelValue') || changedProperties.has('allowedRegions')) { this.__calculateActiveRegion(); } @@ -239,6 +253,7 @@ export class LionInputTel extends LocalizeMixin(LionInput) { return formatPhoneNumber(modelValue, { regionCode: /** @type {RegionCode} */ (this.activeRegion), formatStrategy: this.formatStrategy, + formatCountryCodeStyle: this.formatCountryCodeStyle, }); } @@ -265,6 +280,7 @@ export class LionInputTel extends LocalizeMixin(LionInput) { return liveFormatPhoneNumber(viewValue, { regionCode: /** @type {RegionCode} */ (this.activeRegion), formatStrategy: this.formatStrategy, + formatCountryCodeStyle: this.formatCountryCodeStyle, currentCaretIndex, prevViewValue, }); @@ -313,7 +329,10 @@ export class LionInputTel extends LocalizeMixin(LionInput) { } // 2. Try to derive action region from user value - const value = !(this.modelValue instanceof Unparseable) ? this.modelValue : this.value; + const regex = /[+0-9]+/gi; + const value = !(this.modelValue instanceof Unparseable) + ? this.modelValue + : this.value.match(regex)?.join(''); const regionDerivedFromValue = value && this._phoneUtil && this._phoneUtil(value).g?.regionCode; if (regionDerivedFromValue && this._allowedOrAllRegions.includes(regionDerivedFromValue)) { diff --git a/packages/input-tel/src/formatters.js b/packages/input-tel/src/formatters.js index b1dd28fe3..89639fb1a 100644 --- a/packages/input-tel/src/formatters.js +++ b/packages/input-tel/src/formatters.js @@ -6,14 +6,37 @@ import { PhoneUtilManager } from './PhoneUtilManager.js'; * @typedef {* & import('awesome-phonenumber').default} AwesomePhoneNumber */ +/** + * @param {string} value + * @param {object} options + * @param {RegionCode} options.regionCode + * @param {string} options.formatCountryCodeStyle + */ +export function getFormatCountryCodeStyle(value, { regionCode, formatCountryCodeStyle }) { + const countryCode = PhoneUtilManager?.PhoneUtil?.getCountryCodeForRegionCode(regionCode); + if ( + formatCountryCodeStyle === 'parentheses' && + countryCode && + value.includes(`+${countryCode}`) && + !value.includes(`(`) + ) { + return value.replace(`+${countryCode}`, `(+${countryCode})`); + } + return value; +} + /** * @param {string} modelValue * @param {object} options * @param {RegionCode} options.regionCode * @param {PhoneNumberFormat} [options.formatStrategy='international'] + * @param {string} [options.formatCountryCodeStyle='default'] * @returns {string} */ -export function formatPhoneNumber(modelValue, { regionCode, formatStrategy = 'international' }) { +export function formatPhoneNumber( + modelValue, + { regionCode, formatStrategy = 'international', formatCountryCodeStyle = 'default' }, +) { // Do not format when not loaded if (!PhoneUtilManager.isLoaded) { return modelValue; @@ -50,8 +73,15 @@ export function formatPhoneNumber(modelValue, { regionCode, formatStrategy = 'in default: break; } + + if (formatCountryCodeStyle !== 'default') { + return getFormatCountryCodeStyle(formattedValue, { regionCode, formatCountryCodeStyle }); + } return formattedValue; } + if (formatCountryCodeStyle !== 'default') { + return getFormatCountryCodeStyle(modelValue, { regionCode, formatCountryCodeStyle }); + } return modelValue; } diff --git a/packages/input-tel/src/parsers.js b/packages/input-tel/src/parsers.js index 3c9567e8c..a08625a34 100644 --- a/packages/input-tel/src/parsers.js +++ b/packages/input-tel/src/parsers.js @@ -18,10 +18,11 @@ export function parsePhoneNumber(viewValue, { regionCode }) { // eslint-disable-next-line prefer-destructuring const PhoneNumber = /** @type {AwesomePhoneNumber} */ (PhoneUtilManager.PhoneUtil); - + const regex = /[+0-9]+/gi; + const strippedViewValue = viewValue.match(regex)?.join(''); let pn; try { - pn = PhoneNumber(viewValue, regionCode); + pn = PhoneNumber(strippedViewValue, regionCode); // eslint-disable-next-line no-empty } catch (_) {} diff --git a/packages/input-tel/src/preprocessors.js b/packages/input-tel/src/preprocessors.js index 217def3ed..b1832092f 100644 --- a/packages/input-tel/src/preprocessors.js +++ b/packages/input-tel/src/preprocessors.js @@ -1,5 +1,5 @@ +import { formatPhoneNumber, getFormatCountryCodeStyle } from './formatters.js'; import { PhoneUtilManager } from './PhoneUtilManager.js'; -import { formatPhoneNumber } from './formatters.js'; /** * @typedef {import('../types').RegionCode} RegionCode @@ -14,11 +14,12 @@ import { formatPhoneNumber } from './formatters.js'; * @param {string} options.prevViewValue * @param {number} options.currentCaretIndex * @param {PhoneNumberFormat} options.formatStrategy + * @param {string?} [options.formatCountryCodeStyle='default'] * @returns {{viewValue:string; caretIndex:number;}|undefined} */ export function liveFormatPhoneNumber( viewValue, - { regionCode, formatStrategy, prevViewValue, currentCaretIndex }, + { regionCode, formatStrategy, prevViewValue, currentCaretIndex, formatCountryCodeStyle }, ) { const diff = viewValue.length - prevViewValue.length; // Do not format when not loaded @@ -36,7 +37,12 @@ export function liveFormatPhoneNumber( } } - const newViewValue = formatPhoneNumber(ayt.number(), { regionCode, formatStrategy }); + let parenthesesAdded = false; + let newViewValue = formatPhoneNumber(ayt.number(), { regionCode, formatStrategy }); + if (formatCountryCodeStyle === 'parentheses' && regionCode && !newViewValue.includes(`(`)) { + newViewValue = getFormatCountryCodeStyle(newViewValue, { regionCode, formatCountryCodeStyle }); + parenthesesAdded = true; + } /** * Given following situation: @@ -45,7 +51,16 @@ export function liveFormatPhoneNumber( * - prevViewValue `+36123` (we inserted '1' at position 2) * => we should get `+31 6123`, and new caretIndex should be 3, and not newViewValue.length */ + const countryCode = PhoneUtilManager?.PhoneUtil?.getCountryCodeForRegionCode(regionCode); const diffBetweenNewAndCurrent = newViewValue.length - viewValue.length; - const newCaretIndex = currentCaretIndex + diffBetweenNewAndCurrent; + let newCaretIndex = currentCaretIndex + diffBetweenNewAndCurrent; + if ( + parenthesesAdded && + countryCode && + viewValue.length > countryCode.toString().length + 1 && + currentCaretIndex <= countryCode.toString().length + 1 + ) { + newCaretIndex -= 2; + } return newViewValue ? { viewValue: newViewValue, caretIndex: newCaretIndex } : undefined; } diff --git a/packages/input-tel/test-suites/LionInputTel.suite.js b/packages/input-tel/test-suites/LionInputTel.suite.js index 779cef9d6..2da5047d3 100644 --- a/packages/input-tel/test-suites/LionInputTel.suite.js +++ b/packages/input-tel/test-suites/LionInputTel.suite.js @@ -10,6 +10,7 @@ import { import sinon from 'sinon'; import { mimicUserInput } from '@lion/form-core/test-helpers'; import { localize } from '@lion/localize'; +import { Unparseable } from '@lion/form-core'; import { LionInputTel } from '../src/LionInputTel.js'; import { PhoneNumber } from '../src/validators.js'; import { PhoneUtilManager } from '../src/PhoneUtilManager.js'; @@ -103,6 +104,28 @@ function runActiveRegionTests({ tag, phoneUtilLoadedAfterInit }) { expect(el.activeRegion).to.equal('NL'); }); + it('deducts it from value when modelValue is unparseable', async () => { + const modelValue = new Unparseable('+316'); + const el = await fixture(html` <${tag} .modelValue=${modelValue}> `); + if (resolvePhoneUtilLoaded) { + resolvePhoneUtilLoaded(undefined); + await el.updateComplete; + } + // Region code for country code '31' is 'NL' + expect(el.activeRegion).to.equal('NL'); + }); + + it('deducts it from value when modelValue is unparseable and contains parentheses', async () => { + const modelValue = new Unparseable('(+31)6'); + const el = await fixture(html` <${tag} .modelValue=${modelValue}> `); + if (resolvePhoneUtilLoaded) { + resolvePhoneUtilLoaded(undefined); + await el.updateComplete; + } + // Region code for country code '31' is 'NL' + expect(el.activeRegion).to.equal('NL'); + }); + // 3. **locale**: try to get the region from locale (`html[lang]` attribute) it('automatically bases it on current locale when nothing preconfigured', async () => { const el = await fixture(html` <${tag}> `); @@ -270,6 +293,16 @@ export function runInputTelSuite({ klass = LionInputTel } = {}) { await aTimeout(0); expect(el.formattedValue).to.equal('612345678'); }); + + it('formats according to formatCountryCodeStyle', async () => { + const el = await fixture( + html` <${tag} format-country-code-style="parentheses" .modelValue="${'+31612345678'}" .allowedRegions="${[ + 'NL', + ]}"> `, + ); + await aTimeout(0); + expect(el.formattedValue).to.equal('(+31) 6 12345678'); + }); }); // TODO: this should be allowed for in FormatMixin => diff --git a/packages/input-tel/test/formatters.test.js b/packages/input-tel/test/formatters.test.js index b53fe02a5..3a1e3b9ab 100644 --- a/packages/input-tel/test/formatters.test.js +++ b/packages/input-tel/test/formatters.test.js @@ -25,4 +25,42 @@ describe('formatPhoneNumber', () => { formatPhoneNumber('+46707123456', { regionCode: 'SE', formatStrategy: 'significant' }), ).to.equal('707123456'); }); + + it('formats a phone number according to provided formatCountryCodeStyle', () => { + expect( + formatPhoneNumber('0707123456', { + regionCode: 'SE', + formatStrategy: 'e164', + formatCountryCodeStyle: 'parentheses', + }), + ).to.equal('(+46)707123456'); + expect( + formatPhoneNumber('+46707123456', { + regionCode: 'SE', + formatStrategy: 'international', + formatCountryCodeStyle: 'parentheses', + }), + ).to.equal('(+46) 70 712 34 56'); + expect( + formatPhoneNumber('+46707123456', { + regionCode: 'SE', + formatStrategy: 'national', + formatCountryCodeStyle: 'parentheses', + }), + ).to.equal('070-712 34 56'); + expect( + formatPhoneNumber('+46707123456', { + regionCode: 'SE', + formatStrategy: 'rfc3966', + formatCountryCodeStyle: 'parentheses', + }), + ).to.equal('tel:(+46)-70-712-34-56'); + expect( + formatPhoneNumber('+46707123456', { + regionCode: 'SE', + formatStrategy: 'significant', + formatCountryCodeStyle: 'parentheses', + }), + ).to.equal('707123456'); + }); }); diff --git a/packages/input-tel/test/parsers.test.js b/packages/input-tel/test/parsers.test.js index 9f1852d02..69d1ed96a 100644 --- a/packages/input-tel/test/parsers.test.js +++ b/packages/input-tel/test/parsers.test.js @@ -13,4 +13,12 @@ describe('parsePhoneNumber', () => { expect(parsePhoneNumber('0707123456', { regionCode: 'NL' })).to.equal('+31707123456'); expect(parsePhoneNumber('0707123456', { regionCode: 'DE' })).to.equal('+49707123456'); }); + + it('removes unwanted characters', () => { + expect(parsePhoneNumber('(+31)707123456', { regionCode: 'NL' })).to.equal('+31707123456'); + expect(parsePhoneNumber('+31 70 7123456', { regionCode: 'NL' })).to.equal('+31707123456'); + expect(parsePhoneNumber('+31-70-7123456', { regionCode: 'NL' })).to.equal('+31707123456'); + expect(parsePhoneNumber('+31|70|7123456', { regionCode: 'NL' })).to.equal('+31707123456'); + expect(parsePhoneNumber('tel:+31707123456', { regionCode: 'NL' })).to.equal('+31707123456'); + }); }); diff --git a/packages/input-tel/test/preprocessors.test.js b/packages/input-tel/test/preprocessors.test.js index 749d56212..c6b1780c2 100644 --- a/packages/input-tel/test/preprocessors.test.js +++ b/packages/input-tel/test/preprocessors.test.js @@ -16,7 +16,7 @@ describe('liveFormatPhoneNumber', () => { prevViewValue: '+36123', currentCaretIndex: 2, }), - ).to.eql({ viewValue: '+31 6 123', caretIndex: 4 }); + ).to.eql({ caretIndex: 4, viewValue: '+31 6 123' }); }); it('live formats a complete view value', () => { @@ -29,4 +29,54 @@ describe('liveFormatPhoneNumber', () => { }), ).to.eql({ caretIndex: 12, viewValue: '+31 6 12345678' }); }); + + describe('with formatCountryCodeStyle is set to parantheses', () => { + it('live formats an incomplete view value', () => { + expect( + liveFormatPhoneNumber('+316123', { + regionCode: 'NL', + formatStrategy: 'international', + prevViewValue: '+31613', + currentCaretIndex: 5, + formatCountryCodeStyle: 'parentheses', + }), + ).to.eql({ caretIndex: 9, viewValue: '(+31) 6 123' }); + }); + + it('live formats a complete view value', () => { + expect( + liveFormatPhoneNumber('+31612345678', { + regionCode: 'NL', + formatStrategy: 'international', + prevViewValue: '+3161234578', + currentCaretIndex: 10, + formatCountryCodeStyle: 'parentheses', + }), + ).to.eql({ caretIndex: 14, viewValue: '(+31) 6 12345678' }); + }); + + it('does not update if parentheses are already in place', () => { + expect( + liveFormatPhoneNumber('(+31)6123', { + regionCode: 'NL', + formatStrategy: 'international', + prevViewValue: '(+31)123', + currentCaretIndex: 5, + formatCountryCodeStyle: 'parentheses', + }), + ).to.eql({ caretIndex: 5, viewValue: '(+31)6123' }); + }); + + it('sets the correct caretIndex if currentCaretIndex in between the countryCode', () => { + expect( + liveFormatPhoneNumber('+316123', { + regionCode: 'NL', + formatStrategy: 'international', + prevViewValue: '+36123', + currentCaretIndex: 2, + formatCountryCodeStyle: 'parentheses', + }), + ).to.eql({ caretIndex: 4, viewValue: '(+31) 6 123' }); + }); + }); });