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';