diff --git a/projects/demo-integrations/cypress/tests/addons/phone/phone-non-strict.cy.ts b/projects/demo-integrations/cypress/tests/addons/phone/phone-non-strict.cy.ts new file mode 100644 index 000000000..e1e3b8fc8 --- /dev/null +++ b/projects/demo-integrations/cypress/tests/addons/phone/phone-non-strict.cy.ts @@ -0,0 +1,201 @@ +import {DemoPath} from '@demo/constants'; + +import {BROWSER_SUPPORTS_REAL_EVENTS} from '../../../support/constants'; + +describe('Phone', () => { + describe('Non-strict', () => { + beforeEach(() => { + cy.visit(`/${DemoPath.PhonePackage}/API?strict=false`); + cy.get('#demo-content input') + .should('be.visible') + .first() + .focus() + .as('input'); + }); + + describe('basic typing (1 character per keydown)', () => { + const tests = [ + // [Typed value, Masked value, caretIndex] + ['7920', '+7 920', '+7 920'.length], + ['7920341', '+7 920 341', '+7 920 341'.length], + ['792034156', '+7 920 341-56', '+7 920 341-56'.length], + ['79203415627', '+7 920 341-56-27', '+7 920 341-56-27'.length], + ['792034156274234123', '+7 920 341-56-27', '+7 920 341-56-27'.length], + ['79 nd4 e', '+7 94', '+7 94'.length], + ] as const; + + tests.forEach(([typedValue, maskedValue, caretIndex]) => { + it(`Type "${typedValue}" => "${maskedValue}"`, () => { + cy.get('@input') + .type(typedValue) + .should('have.value', maskedValue) + .should('have.prop', 'selectionStart', caretIndex) + .should('have.prop', 'selectionEnd', caretIndex); + }); + }); + }); + + describe('basic erasing (value = "+7 920 424-11-32"', () => { + beforeEach(() => { + cy.get('@input').type('+79204241132'); + }); + + const tests = [ + // [How many times "Backspace"-key was pressed, caretPosition, Masked value] + [1, '+7 920 424-11-3'.length, '+7 920 424-11-3'], + [2, '+7 920 424-11'.length, '+7 920 424-11'], + [3, '+7 920 424-1'.length, '+7 920 424-1'], + [4, '+7 920 424'.length, '+7 920 424'], + [13, ''.length, ''], + ] as const; + + tests.forEach(([n, caretIndex, maskedValue]) => { + it(`Backspace x${n} => "${maskedValue}"`, () => { + cy.get('@input') + .type('{backspace}'.repeat(n)) + .should('have.value', maskedValue) + .should('have.prop', 'selectionStart', caretIndex) + .should('have.prop', 'selectionEnd', caretIndex); + }); + }); + }); + + describe('Editing somewhere in the middle of a value (NOT the last character)', () => { + beforeEach(() => { + cy.get('@input').type('+7 920 424-11-32'); + }); + + it('+7 920 424-1|1-32 => Backspace => +7 920 424-|13-2 => Type "2" => +7 920 424-2|1-32', () => { + cy.get('@input') + .type('{leftArrow}'.repeat('13-2'.length)) + .type('{backspace}') + .should('have.value', '+7 920 424-13-2') + .should('have.prop', 'selectionStart', '+7 920 424-'.length) + .should('have.prop', 'selectionEnd', '+7 920 424-'.length) + .type('2') + .should('have.value', '+7 920 424-21-32') + .should('have.prop', 'selectionStart', '+7 920 424-2'.length) + .should('have.prop', 'selectionEnd', '+7 920 424-2'.length); + }); + + it('+7 9|20 424-11-32 => Backspace => +7 2|04241132', () => { + cy.get('@input') + .type('{leftArrow}'.repeat('20 424-11-32'.length)) + .type('{backspace}') + .should('have.value', '+7 204241132') + .should('have.prop', 'selectionStart', '+7 '.length) + .should('have.prop', 'selectionEnd', '+7 '.length); + }); + }); + + describe('Text selection', () => { + beforeEach(() => { + cy.get('@input').type('+7 920 424-11-32'); + }); + + describe( + 'Select range and press Backspace', + BROWSER_SUPPORTS_REAL_EVENTS, + () => { + it('+7 920 424-11-32 => Select "+7 920 424-|11|-32" => Backspace => +7 920 424-|32', () => { + cy.get('@input') + .type('{leftArrow}'.repeat('-32'.length)) + .realPress([ + 'Shift', + ...Array('11'.length).fill('ArrowLeft'), + ]); + + cy.get('@input') + .type('{backspace}') + .should('have.value', '+7 920 424-32') + .should('have.prop', 'selectionStart', '+7 920 424-'.length) + .should('have.prop', 'selectionEnd', '+7 920 424-'.length); + }); + + it('+7 920 424-11-32 => Select "+7 920 424-1|1-3|2" => Backspace => +7 920 424-1|2', () => { + cy.get('@input') + .type('{leftArrow}') + .realPress([ + 'Shift', + ...Array('1-3'.length).fill('ArrowLeft'), + ]); + + cy.get('@input') + .type('{backspace}') + .should('have.value', '+7 920 424-12') + .should('have.prop', 'selectionStart', '+7 920 424-1'.length) + .should('have.prop', 'selectionEnd', '+7 920 424-1'.length); + }); + }, + ); + + describe( + 'Select range and type a digit', + BROWSER_SUPPORTS_REAL_EVENTS, + () => { + it('+7 920 424-11-32 => Select "+7 920 424-|11|-32" => Type "5" => +7 920 424-5|3-2', () => { + cy.get('@input') + .type('{leftArrow}'.repeat('-32'.length)) + .realPress([ + 'Shift', + ...Array('11'.length).fill('ArrowLeft'), + ]); + + cy.get('@input') + .type('5') + .should('have.value', '+7 920 424-53-2') + .should('have.prop', 'selectionStart', '+7 920 424-5'.length) + .should('have.prop', 'selectionEnd', '+7 920 424-5'.length); + }); + + it('+7 920 424-11-32 => Select "+7 920 424-1|1-3|2" => Type "5" => +7 920 424-15-|2', () => { + cy.get('@input') + .type('{leftArrow}') + .realPress([ + 'Shift', + ...Array('1-3'.length).fill('ArrowLeft'), + ]); + + cy.get('@input') + .type('5') + .should('have.value', '+7 920 424-15-2') + .should( + 'have.prop', + 'selectionStart', + '+7 920 424-15-'.length, + ) + .should('have.prop', 'selectionEnd', '+7 920 424-15-'.length); + }); + }, + ); + }); + }); + + describe('Some countries', () => { + it('US: +1 212 343-3355', () => { + openCounrty('US'); + + cy.get('@input').type('12123433355'); + cy.get('@input').should('have.value', '+1 212 343-3355'); + }); + + it('KZ: +7 771 931-1111', () => { + openCounrty('KZ'); + + cy.get('@input').type('77719311111'); + cy.get('@input').should('have.value', '+7 771 931-1111'); + }); + + it('BY: +375 44 748-82-69', () => { + openCounrty('BY'); + + cy.get('@input').type('375447488269'); + cy.get('@input').should('have.value', '+375 44 748-82-69'); + }); + }); +}); + +function openCounrty(code: string): void { + cy.visit(`/${DemoPath.PhonePackage}/API?strict=false&countryCode=${code}`); + cy.get('#demo-content input').should('be.visible').first().focus().as('input'); +} diff --git a/projects/demo/src/pages/phone/examples/3-non-strict/component.ts b/projects/demo/src/pages/phone/examples/3-non-strict/component.ts new file mode 100644 index 000000000..c9799fe84 --- /dev/null +++ b/projects/demo/src/pages/phone/examples/3-non-strict/component.ts @@ -0,0 +1,35 @@ +import {ChangeDetectionStrategy, Component} from '@angular/core'; +import {maskitoGetCountryFromNumber} from '@maskito/phone'; +import metadata from 'libphonenumber-js/min/metadata'; + +import mask from './mask'; + +@Component({ + selector: 'phone-doc-example-3', + template: ` + + Basic + + + +
Country code: {{ countryIsoCode }}
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class PhoneMaskDocExample3 { + value = ''; + readonly mask = mask; + + get countryIsoCode(): string { + return maskitoGetCountryFromNumber(this.value, metadata) || ''; + } +} diff --git a/projects/demo/src/pages/phone/examples/3-non-strict/mask.ts b/projects/demo/src/pages/phone/examples/3-non-strict/mask.ts new file mode 100644 index 000000000..fb8bf58ac --- /dev/null +++ b/projects/demo/src/pages/phone/examples/3-non-strict/mask.ts @@ -0,0 +1,8 @@ +import {maskitoPhoneOptionsGenerator} from '@maskito/phone'; +import metadata from 'libphonenumber-js/min/metadata'; + +export default maskitoPhoneOptionsGenerator({ + countryIsoCode: 'RU', + metadata, + strict: false, +}); diff --git a/projects/demo/src/pages/phone/examples/4-lazy-metadata/component.ts b/projects/demo/src/pages/phone/examples/4-lazy-metadata/component.ts new file mode 100644 index 000000000..2f22667a6 --- /dev/null +++ b/projects/demo/src/pages/phone/examples/4-lazy-metadata/component.ts @@ -0,0 +1,38 @@ +import {ChangeDetectionStrategy, Component, OnInit} from '@angular/core'; +import {MASKITO_DEFAULT_OPTIONS} from '@maskito/core'; +import {maskitoPhoneOptionsGenerator} from '@maskito/phone'; + +@Component({ + selector: 'phone-doc-example-4', + template: ` + + Lazy metadata + + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class PhoneMaskDocExample4 implements OnInit { + value = '+7 920 123-4567'; + mask? = MASKITO_DEFAULT_OPTIONS; + + async ngOnInit(): Promise { + const metadata = await import('libphonenumber-js/min/metadata').then( + m => m.default, + ); + + this.mask = maskitoPhoneOptionsGenerator({ + countryIsoCode: 'RU', + metadata, + }); + } +} diff --git a/projects/demo/src/pages/phone/phone-doc.component.ts b/projects/demo/src/pages/phone/phone-doc.component.ts index 317cd1e1d..78661774c 100644 --- a/projects/demo/src/pages/phone/phone-doc.component.ts +++ b/projects/demo/src/pages/phone/phone-doc.component.ts @@ -30,8 +30,25 @@ export class PhoneDocComponent implements GeneratorOptions { ), }; + readonly nonStrict: TuiDocExample = { + [DocExamplePrimaryTab.MaskitoOptions]: import( + './examples/3-non-strict/mask.ts?raw' + ), + }; + + readonly lazyMetadata: TuiDocExample = { + [DocExamplePrimaryTab.MaskitoOptions]: import( + './examples/2-validation/mask.ts?raw' + ), + [DocExamplePrimaryTab.Angular]: import( + './examples/2-validation/component.ts?raw' + ), + }; + metadata = metadata; + strict = true; + countryCodeVariants = getCountries(this.metadata); countryIsoCode: CountryCode = 'RU'; diff --git a/projects/demo/src/pages/phone/phone-doc.module.ts b/projects/demo/src/pages/phone/phone-doc.module.ts index 0a2ac8adf..0735cd6b0 100644 --- a/projects/demo/src/pages/phone/phone-doc.module.ts +++ b/projects/demo/src/pages/phone/phone-doc.module.ts @@ -6,6 +6,7 @@ import {MaskitoModule} from '@maskito/angular'; import {TuiAddonDocModule, tuiGenerateRoutes} from '@taiga-ui/addon-doc'; import { TuiErrorModule, + TuiFlagPipeModule, TuiLinkModule, TuiNotificationModule, TuiTextfieldControllerModule, @@ -14,6 +15,8 @@ import {TuiFieldErrorPipeModule, TuiInputModule} from '@taiga-ui/kit'; import {PhoneMaskDocExample1} from './examples/1-basic/component'; import {PhoneMaskDocExample2} from './examples/2-validation/component'; +import {PhoneMaskDocExample3} from './examples/3-non-strict/component'; +import {PhoneMaskDocExample4} from './examples/4-lazy-metadata/component'; import {PhoneDocComponent} from './phone-doc.component'; @NgModule({ @@ -24,6 +27,7 @@ import {PhoneDocComponent} from './phone-doc.component'; MaskitoModule, TuiAddonDocModule, TuiInputModule, + TuiFlagPipeModule, TuiLinkModule, TuiErrorModule, TuiNotificationModule, @@ -31,7 +35,13 @@ import {PhoneDocComponent} from './phone-doc.component'; TuiTextfieldControllerModule, RouterModule.forChild(tuiGenerateRoutes(PhoneDocComponent)), ], - declarations: [PhoneDocComponent, PhoneMaskDocExample1, PhoneMaskDocExample2], + declarations: [ + PhoneDocComponent, + PhoneMaskDocExample1, + PhoneMaskDocExample2, + PhoneMaskDocExample3, + PhoneMaskDocExample4, + ], exports: [PhoneDocComponent], }) export class PhoneDocModule {} diff --git a/projects/demo/src/pages/phone/phone-doc.template.html b/projects/demo/src/pages/phone/phone-doc.template.html index 07c187cf1..8a41fcc46 100644 --- a/projects/demo/src/pages/phone/phone-doc.template.html +++ b/projects/demo/src/pages/phone/phone-doc.template.html @@ -64,6 +64,65 @@

+ + + + + +

+ Setting the + strict + option to + false + enables non-strict mask mode. There is no strict country + code in the mask in this mode. +

+

+ The + countryIsoCode + option is optional in that case, but if you specify it, the + mask will try to add that country's calling code when you + try to insert a phone number without a calling code. +

+
+
+ + + + + +

+ You can load metadata lazily, below is an example of how to + do it in Angular. +

+

+ You can also + + customize the metadata + + to reduce metadata size. See instructions + + here + +

+
+
@@ -95,6 +154,15 @@ > Country ISO-code + + Strict mode + diff --git a/projects/phone/src/index.ts b/projects/phone/src/index.ts index 6879aa146..7eec94a8c 100644 --- a/projects/phone/src/index.ts +++ b/projects/phone/src/index.ts @@ -1 +1 @@ -export {maskitoPhoneOptionsGenerator} from './lib/masks'; +export {maskitoGetCountryFromNumber, maskitoPhoneOptionsGenerator} from './lib/masks'; diff --git a/projects/phone/src/lib/masks/index.ts b/projects/phone/src/lib/masks/index.ts index 80d274f5e..8e101ca9c 100644 --- a/projects/phone/src/lib/masks/index.ts +++ b/projects/phone/src/lib/masks/index.ts @@ -1 +1 @@ -export {maskitoPhoneOptionsGenerator} from './phone'; +export {maskitoGetCountryFromNumber, maskitoPhoneOptionsGenerator} from './phone'; diff --git a/projects/phone/src/lib/masks/phone/index.ts b/projects/phone/src/lib/masks/phone/index.ts index 42ed7a2d9..a401b6298 100644 --- a/projects/phone/src/lib/masks/phone/index.ts +++ b/projects/phone/src/lib/masks/phone/index.ts @@ -5,3 +5,4 @@ export { phoneLengthPostprocessorGenerator, validatePhonePreprocessorGenerator, } from './processors'; +export {maskitoGetCountryFromNumber} from './utils'; diff --git a/projects/phone/src/lib/masks/phone/phone-mask-free.ts b/projects/phone/src/lib/masks/phone/phone-mask-free.ts new file mode 100644 index 000000000..e3746e1ab --- /dev/null +++ b/projects/phone/src/lib/masks/phone/phone-mask-free.ts @@ -0,0 +1,38 @@ +import {MASKITO_DEFAULT_OPTIONS, MaskitoOptions} from '@maskito/core'; +import {AsYouType, CountryCode, MetadataJson} from 'libphonenumber-js/core'; + +import { + phoneLengthPostprocessorGenerator, + validatePhonePreprocessorGenerator, +} from './processors'; +import {generatePhoneMask, getPhoneTemplate} from './utils'; + +export function maskitoPhoneFreeOptionsGenerator({ + defaultIsoCode, + metadata, +}: { + defaultIsoCode?: CountryCode; + metadata: MetadataJson; +}): Required { + const formatter = new AsYouType(defaultIsoCode, metadata); + const prefix = `+`; + + return { + ...MASKITO_DEFAULT_OPTIONS, + mask: ({value}) => { + const template = getPhoneTemplate(formatter, value); + + const mask = generatePhoneMask({value, template, prefix}); + + return template.length === 1 ? ['+', /\d/] : mask; + }, + postprocessors: [phoneLengthPostprocessorGenerator(metadata)], + preprocessors: [ + validatePhonePreprocessorGenerator({ + prefix, + countryIsoCode: defaultIsoCode, + metadata, + }), + ], + }; +} diff --git a/projects/phone/src/lib/masks/phone/phone-mask-strict.ts b/projects/phone/src/lib/masks/phone/phone-mask-strict.ts new file mode 100644 index 000000000..a3eb85030 --- /dev/null +++ b/projects/phone/src/lib/masks/phone/phone-mask-strict.ts @@ -0,0 +1,57 @@ +import {MASKITO_DEFAULT_OPTIONS, MaskitoOptions} from '@maskito/core'; +import { + maskitoAddOnFocusPlugin, + maskitoCaretGuard, + maskitoPrefixPostprocessorGenerator, + maskitoRemoveOnBlurPlugin, +} from '@maskito/kit'; +import { + AsYouType, + CountryCode, + getCountryCallingCode, + MetadataJson, +} from 'libphonenumber-js/core'; + +import { + cutInitCountryCodePreprocessor, + phoneLengthPostprocessorGenerator, + validatePhonePreprocessorGenerator, +} from './processors'; +import {generatePhoneMask, getPhoneTemplate} from './utils'; + +export function maskitoPhoneStrictOptionsGenerator({ + countryIsoCode, + metadata, +}: { + countryIsoCode: CountryCode; + metadata: MetadataJson; +}): Required { + const code = getCountryCallingCode(countryIsoCode, metadata); + const formatter = new AsYouType(countryIsoCode, metadata); + const prefix = `+${code} `; + + return { + ...MASKITO_DEFAULT_OPTIONS, + mask: ({value}) => { + const template = getPhoneTemplate(formatter, value); + + return generatePhoneMask({value, template, prefix}); + }, + plugins: [ + maskitoCaretGuard((value, [from, to]) => [ + from === to ? prefix.length : 0, + value.length, + ]), + maskitoRemoveOnBlurPlugin(prefix), + maskitoAddOnFocusPlugin(prefix), + ], + postprocessors: [ + maskitoPrefixPostprocessorGenerator(prefix), + phoneLengthPostprocessorGenerator(metadata), + ], + preprocessors: [ + cutInitCountryCodePreprocessor({countryIsoCode, metadata}), + validatePhonePreprocessorGenerator({prefix, countryIsoCode, metadata}), + ], + }; +} diff --git a/projects/phone/src/lib/masks/phone/phone-mask.ts b/projects/phone/src/lib/masks/phone/phone-mask.ts index 7b4826143..d7e88021b 100644 --- a/projects/phone/src/lib/masks/phone/phone-mask.ts +++ b/projects/phone/src/lib/masks/phone/phone-mask.ts @@ -1,57 +1,19 @@ -import {MASKITO_DEFAULT_OPTIONS, MaskitoOptions} from '@maskito/core'; -import { - maskitoAddOnFocusPlugin, - maskitoCaretGuard, - maskitoPrefixPostprocessorGenerator, - maskitoRemoveOnBlurPlugin, -} from '@maskito/kit'; -import { - AsYouType, - CountryCode, - getCountryCallingCode, - MetadataJson, -} from 'libphonenumber-js/core'; +import {MaskitoOptions} from '@maskito/core'; +import {CountryCode, MetadataJson} from 'libphonenumber-js/core'; -import { - cutInitCountryCodePreprocessor, - phoneLengthPostprocessorGenerator, - validatePhonePreprocessorGenerator, -} from './processors'; -import {generatePhoneMask, getPhoneTemplate} from './utils'; +import {maskitoPhoneFreeOptionsGenerator} from './phone-mask-free'; +import {maskitoPhoneStrictOptionsGenerator} from './phone-mask-strict'; export function maskitoPhoneOptionsGenerator({ countryIsoCode, metadata, + strict = true, }: { - countryIsoCode: CountryCode; + countryIsoCode?: CountryCode; metadata: MetadataJson; + strict?: boolean; }): Required { - const code = getCountryCallingCode(countryIsoCode, metadata); - const formatter = new AsYouType(countryIsoCode, metadata); - const prefix = `+${code} `; - - return { - ...MASKITO_DEFAULT_OPTIONS, - mask: ({value}) => { - const template = getPhoneTemplate(formatter, value); - - return generatePhoneMask({value, template, prefix}); - }, - plugins: [ - maskitoCaretGuard((value, [from, to]) => [ - from === to ? prefix.length : 0, - value.length, - ]), - maskitoRemoveOnBlurPlugin(prefix), - maskitoAddOnFocusPlugin(prefix), - ], - postprocessors: [ - maskitoPrefixPostprocessorGenerator(prefix), - phoneLengthPostprocessorGenerator(metadata, countryIsoCode), - ], - preprocessors: [ - cutInitCountryCodePreprocessor({countryIsoCode, metadata}), - validatePhonePreprocessorGenerator({prefix, countryIsoCode, metadata}), - ], - }; + return strict && countryIsoCode + ? maskitoPhoneStrictOptionsGenerator({countryIsoCode, metadata}) + : maskitoPhoneFreeOptionsGenerator({defaultIsoCode: countryIsoCode, metadata}); } diff --git a/projects/phone/src/lib/masks/phone/processors/phone-length-postprocessor.ts b/projects/phone/src/lib/masks/phone/processors/phone-length-postprocessor.ts index e92b1c3bb..c608f2d4b 100644 --- a/projects/phone/src/lib/masks/phone/processors/phone-length-postprocessor.ts +++ b/projects/phone/src/lib/masks/phone/processors/phone-length-postprocessor.ts @@ -1,17 +1,16 @@ import {MaskitoPostprocessor} from '@maskito/core'; -import {CountryCode, MetadataJson} from 'libphonenumber-js/core'; +import {MetadataJson} from 'libphonenumber-js/core'; import {cutPhoneByValidLength} from '../utils'; const MIN_LENGTH = 3; export function phoneLengthPostprocessorGenerator( metadata: MetadataJson, - countryIsoCode: CountryCode, ): MaskitoPostprocessor { return ({value, selection}) => ({ value: value.length > MIN_LENGTH - ? cutPhoneByValidLength({phone: value, countryIsoCode, metadata}) + ? cutPhoneByValidLength({phone: value, metadata}) : value, selection, }); diff --git a/projects/phone/src/lib/masks/phone/processors/validate-phone-preprocessor.ts b/projects/phone/src/lib/masks/phone/processors/validate-phone-preprocessor.ts index 6a77263a3..a91af76b2 100644 --- a/projects/phone/src/lib/masks/phone/processors/validate-phone-preprocessor.ts +++ b/projects/phone/src/lib/masks/phone/processors/validate-phone-preprocessor.ts @@ -12,7 +12,7 @@ export function validatePhonePreprocessorGenerator({ metadata, }: { prefix: string; - countryIsoCode: CountryCode; + countryIsoCode?: CountryCode; metadata: MetadataJson; }): MaskitoPreprocessor { return ({elementState, data}) => { @@ -29,14 +29,17 @@ export function validatePhonePreprocessorGenerator({ try { const validationError = validatePhoneNumberLength( data, - countryIsoCode, + {defaultCountry: countryIsoCode}, metadata, ); if (!validationError) { // handle past-event with different code, for example for 8 / +7 - const phone = parsePhoneNumber(data, countryIsoCode, metadata); - const nationalSignificantNumber = phone.nationalNumber; + const phone = countryIsoCode + ? parsePhoneNumber(data, countryIsoCode, metadata) + : parsePhoneNumber(data, metadata); + + const {nationalNumber, countryCallingCode} = phone; return { elementState: { @@ -44,8 +47,8 @@ export function validatePhonePreprocessorGenerator({ value: selectionIncludesPrefix ? '' : prefix, }, data: selectionIncludesPrefix - ? `${prefix}${nationalSignificantNumber}` - : nationalSignificantNumber, + ? `+${countryCallingCode} ${nationalNumber}` + : nationalNumber, }; } } catch { diff --git a/projects/phone/src/lib/masks/phone/utils/cut-phone-by-valid-length.ts b/projects/phone/src/lib/masks/phone/utils/cut-phone-by-valid-length.ts index 2bf765af2..8985d6546 100644 --- a/projects/phone/src/lib/masks/phone/utils/cut-phone-by-valid-length.ts +++ b/projects/phone/src/lib/masks/phone/utils/cut-phone-by-valid-length.ts @@ -1,16 +1,10 @@ -import { - CountryCode, - MetadataJson, - validatePhoneNumberLength, -} from 'libphonenumber-js/core'; +import {MetadataJson, validatePhoneNumberLength} from 'libphonenumber-js/core'; export function cutPhoneByValidLength({ phone, - countryIsoCode, metadata, }: { phone: string; - countryIsoCode: CountryCode; metadata: MetadataJson; }): string { const validationResult = validatePhoneNumberLength(phone, metadata); @@ -18,7 +12,6 @@ export function cutPhoneByValidLength({ if (validationResult === 'INVALID_LENGTH' || validationResult === 'TOO_LONG') { return cutPhoneByValidLength({ phone: phone.slice(0, phone.length - 1), - countryIsoCode, metadata, }); } diff --git a/projects/phone/src/lib/masks/phone/utils/get-country-from-number.ts b/projects/phone/src/lib/masks/phone/utils/get-country-from-number.ts new file mode 100644 index 000000000..8d00c0847 --- /dev/null +++ b/projects/phone/src/lib/masks/phone/utils/get-country-from-number.ts @@ -0,0 +1,12 @@ +import {AsYouType, CountryCode, MetadataJson} from 'libphonenumber-js/core'; + +export function maskitoGetCountryFromNumber( + number: string, + metadata: MetadataJson, +): CountryCode | undefined { + const formatter = new AsYouType({}, metadata); + + formatter.input(number); + + return formatter.getCountry(); +} diff --git a/projects/phone/src/lib/masks/phone/utils/index.ts b/projects/phone/src/lib/masks/phone/utils/index.ts index 84365115c..4bae960af 100644 --- a/projects/phone/src/lib/masks/phone/utils/index.ts +++ b/projects/phone/src/lib/masks/phone/utils/index.ts @@ -1,3 +1,4 @@ export * from './cut-phone-by-valid-length'; export * from './generate-phone-mask'; +export * from './get-country-from-number'; export * from './get-phone-template';