import { EventEmitter, OnDestroy, OnInit } from '@angular/core'; import { AbstractControl, FormControl, FormGroup, ValidationErrors } from '@angular/forms'; import { FieldConfig } from '../../models/field-config.model'; import { FormField } from '../../models/form-field.model'; import { PhoneValue } from '../../models/phone-value.model'; import { CountryDialCode } from '../../models/country-dial-code.model'; import * as i0 from "@angular/core"; /** * Reusable PHONE form control built from an `ng-select` searchable country * dropdown (flag + country name + dial code) and a national-number input, with * per-country validation powered by `libphonenumber-js`. Flags are rendered * with the dependency-light `flag-icons` CSS (a `fi fi-` span), so they * display correctly on every OS. * * The stored value is bound to one reactive form control as a * { countryCode, phoneNumber } object where `countryCode` is the DIAL CODE * string only (e.g. "+91") and `phoneNumber` is the national number. The flag * and country name are display-only and are NEVER written to the stored value * or emitted on `inputValueChange` — the backend sends and receives only the * dial code, and this component maps that dial code back to a display country * on load. * * Because countries can share a dial code (e.g. "+1" for the US and Canada), * the displayed country is resolved from the stored dial code via * `resolveCountryByDialCode` ("+1" -> United States; otherwise the first * alphabetical match). Selecting a different country that shares a dial code * does NOT change the stored `countryCode`, because the stored value only reads * the selected country's dial code. * * Supports the shared `isEditToggle` pencil pattern: when `config.isEditToggle` * is true the field first renders read-only (value + pencil); clicking the * pencil reveals the editable control. * `config.isReadonly` uses the same display without a pencil or editable * controls, and leaves the parent control's value and validation untouched. * * @export * @class PhoneComponent */ export declare class PhoneComponent implements FormField, OnInit, OnDestroy { config: FieldConfig; group: FormGroup; /** All country options rendered in the searchable dropdown. */ countries: CountryDialCode[]; /** The country currently selected for DISPLAY (flag + name + dial code). */ selectedCountry: CountryDialCode | undefined; /** The national-number control holding DIGITS ONLY (the stored value). */ phoneNumberControl: FormControl; /** The formatted national number shown in the input (display only). */ displayNumber: string; /** Country-specific example number shown as an input hint, never as a value. */ countryPlaceholder: string; phoneGuidance: string; /** Edit-toggle state (only relevant when config.isEditToggle is true). */ isEditing: boolean; /** Localized display strings, with inline ?? fallbacks at usage sites. */ constants: { ariaLabel: { clear: string; warning: string; previousMonth: string; nextMonth: string; menuIcon: string; close: string; search: string; addFormGroup: string; }; button: { cancel: string; ok: string; add: string; }; modalConfig: { ariaLabel: string; autoFocus: string; width: string; }; chips: { noOfDefaultVisibleChips: number; label: { viewAll: string; viewLess: string; }; ariaLabel: { chipsList: string; }; icons: { arrow: { id: number; iconURL: string; toolTip: string; ariaLabel: string; }; remove: { id: number; iconURL: string; toolTip: string; ariaLabel: string; }; check: { id: number; iconURL: string; toolTip: string; ariaLabel: string; }; }; }; dataTable: { label: { clearAll: string; }; message: { noRecordFound: string; }; ariaLabel: { /** * Reusable PHONE form control built from an `ng-select` searchable country * dropdown (flag + country name + dial code) and a national-number input, with * per-country validation powered by `libphonenumber-js`. Flags are rendered * with the dependency-light `flag-icons` CSS (a `fi fi-` span), so they * display correctly on every OS. * * The stored value is bound to one reactive form control as a * { countryCode, phoneNumber } object where `countryCode` is the DIAL CODE * string only (e.g. "+91") and `phoneNumber` is the national number. The flag * and country name are display-only and are NEVER written to the stored value * or emitted on `inputValueChange` — the backend sends and receives only the * dial code, and this component maps that dial code back to a display country * on load. * * Because countries can share a dial code (e.g. "+1" for the US and Canada), * the displayed country is resolved from the stored dial code via * `resolveCountryByDialCode` ("+1" -> United States; otherwise the first * alphabetical match). Selecting a different country that shares a dial code * does NOT change the stored `countryCode`, because the stored value only reads * the selected country's dial code. * * Supports the shared `isEditToggle` pencil pattern: when `config.isEditToggle` * is true the field first renders read-only (value + pencil); clicking the * pencil reveals the editable control. * `config.isReadonly` uses the same display without a pencil or editable * controls, and leaves the parent control's value and validation untouched. * * @export * @class PhoneComponent */ search: string; selectAll: string; select: string; link: string; pagination: string; }; buttons: { id: number; iconURL: string; toolTip: string; ariaLabel: string; }[]; }; datePicker: { selectDateLabel: string; dateFormatLabel: string; startDateLabel: string; endDateLabel: string; datePickerIcon: string; }; dropdown: { placeholderText: string; }; filter: { label: { filterBy: string; applyButton: string; clearAll: string; }; buttons: { id: number; iconURL: string; toolTip: string; ariaLabel: string; }[]; }; textarea: { maxLengthDefault: number; leftCharacters: string; }; autocomplete: { minCharToSearch: number; debounceTime: number; }; multiSelectAutoComplete: { label: { clearAll: string; }; ariaLabel: { selectedOption: string; removeOption: string; }; icons: { remove: string; clearAll: string; }; }; header: { alt: { logo: string; }; /** Country-specific example number shown as an input hint, never as a value. */ ariaLabel: { helpLink: string; hamburgerMenu: string; }; label: { signOut: string; }; buttons: { id: number; iconURL: string; toolTip: string; ariaLabel: string; }[]; userProfileMenuOptions: { id: number; iconURL: string; label: string; ariaLabel: string; toolTip: string; isToolTipNeeded: boolean; }[]; errors: { "2029": string; }; }; footer: { alt: { logo: string; }; links: { label: string; ariaLabel: string; redirectUrl: string; }[]; ieeeLogo: string; copyright: { link: string; textPart1: string; textPart2: string; hyperLinkPart3: string; textPart4: string; }; }; welcome: { buttons: { label: string; ariaLabel: string; url: string; }[]; }; breadcrumb: { label: { initial: string; }; }; loader: { ariaLabel: { spinner: string; }; }; defaultWelcomeBgColor: string; timePicker: { defaultTimeFormat: number; timePickerIcon: string; }; colorPicker: { label: { select: string; cancel: string; }; ariaLabel: { colorPicker: string; next: string; back: string; select: string; cancel: string; hexCodeInput: string; palette: string; }; defaultColor: string; ariaDescription: string; ariaDescribedById: string; paletteColors: { name: string; hexCode: string; }[]; }; fileUpload: { label: { fileUpload: string; allowedFileSize1: string; allowedFileSize2: string; allowedFileFormat: string; browseFiles: string; uploadProgress: string; upload: string; mb: string; uploadFor: string; uploadErrorMsg: string; of: string; filesUploaded: string; fileAlreadyExists: string; }; ariaLabel: { fileUpload: string; browseFiles: string; fileUploadIcon: string; removeFileIcon: string; deleteFileIcon: string; fileDownload: string; fileUploadInput: string; }; iconUrl: { fileUploadIcon: string; fileRemoveIcon: string; deleteIcon: string; }; buttons: { id: number; ariaLabel: string; iconURL: string; toolTip: string; disabled: boolean; }[]; message: { error: { ER1002: string; invalidFileFormat: string; invalidFileSize: string; "2026": string; "2059": string; "2060": string; "2061": string; "2062": string; "2063": string; "2064": string; }; }; limit: { maxFilesUploadedOnce: number; }; }; list: { defaultIndentation: number; dragAndDropIconUrl: string; }; search: { minCharToSearch: number; searchIcon: string; }; phone: { countryPlaceholder: string; searchPlaceholder: string; numberPlaceholder: string; ariaLabel: { countrySelector: string; search: string; valid: string; info: string; }; guidance: { selectCountry: string; country: string; format: string; example: string; prefix: string; alternatives: string; noExample: string; areaCodeMismatch: string; }; /** * Reactive validator that marks the national number invalid when it is not a * valid phone number for the selected country, using * `isValidPhoneNumber(nationalNumber, isoCode)` from libphonenumber-js. An * empty value is left to the required validator (returns null), and a * non-numeric value is rejected. Returns `{ pattern: true }` on failure so the * shared `ieeesa-form-error` renders `config.patternErrorMessage`. * @param {AbstractControl} control - The national-number control. * @return {ValidationErrors | null} `{ pattern: true }` when invalid, else null. * @memberof PhoneComponent */ invalidNumberMessage: string; validIcon: string; editAriaLabel: string; editIcon: string; }; richTextEditor: { label: { editor: string; }; ariaLabel: { editor: string; colorPicker: string; }; }; fileDownload: { buttons: { id: number; ariaLabel: string; iconURL: string; toolTip: string; disabled: boolean; }[]; preSignedDuration: string; message: { errors: { ER1002: string; "5038": string; "6027": string; "6028": string; }; }; }; breakPointMaxWidth: string; }; inputValueChange: EventEmitter; editStarted: EventEmitter; private destroy$; /** * Resolves the initial display country and national number from the parent * control value, applies validators, sets the placeholder and read-only/edit * state, and keeps the parent control in sync as the user edits. * * An initial country is selected only when the parent value contains one. * @memberof PhoneComponent */ ngOnInit(): void; /** * Refines `selectedCountry` for DISPLAY using the national number, so a value * whose dial code is shared by several countries (e.g. "+1" for the US and * Canada) shows the country the number actually belongs to. * * Resolution only overrides the current selection when (a) the number maps to * a specific ISO country via libphonenumber-js metadata, (b) that country is * present in the dropdown list, and (c) it shares the already-selected dial * code — so the dial code the backend stored is preserved and only the * displayed flag/name are corrected. A partial or invalid number resolves to * nothing and leaves the dial-code-based default (e.g. the US for "+1") in * place. The stored value is never changed by this method. * @param {string | null} nationalNumber - The stored national number digits. * @memberof PhoneComponent */ refineSelectedCountryFromNumber(nationalNumber: string | null): void; /** * Handles selection of a country from the dropdown. Updates the display * country, re-applies validators and placeholder, revalidates and syncs the * parent. The stored value still reads only the selected country's dial code, * so switching between countries that share a dial code does not change it. * @param {CountryDialCode | undefined} country - The newly selected country. * @memberof PhoneComponent */ onCountryChange(country: CountryDialCode | undefined): void; /** * Handles typing in the national-number input. Strips the input to digits * (the stored value stays digits only), stores them on the control, and * updates the display to the selected country's national format via * libphonenumber-js `AsYouType`. * @param {Event} event - The input event from the number field. * @memberof PhoneComponent */ onNumberInput(event: Event): void; private getCursorPositionAfterDigits; /** * Recomputes `displayNumber` from the stored digits, formatted into the * selected country's national format (display only; the stored value remains * digits). * @memberof PhoneComponent */ updateDisplayNumber(): void; /** * Updates the placeholder from libphonenumber-js example metadata for the * selected country. It is display-only and does not affect validation/value. * @memberof PhoneComponent */ updateCountryPlaceholder(): void; /** * Builds the masked example-format string shown on the guidance line. * * Digits are masked to "X" so the line shows the grouping, not real digits * (e.g. "(XXX) XXX-XXXX"). For countries whose dial code is shared with other * countries (the NANP "+1" plan, where the first group is the geographic area * code that identifies the country), the first digit group is replaced with * the literal "areaCode" to call it out — e.g. "(areaCode) XXX-XXXX". For all * other countries the plain "X" mask is kept, since their first group is not * a disambiguating area code. * @return {string} The masked format string for the guidance line. * @memberof PhoneComponent */ buildFormatMask(): string; /** * Whether the selected country's dial code is shared by more than one country * (e.g. "+1" for the US, Canada and other NANP territories). Only in that case * does the first number group act as a country-identifying area code. * @return {boolean} True when the dial code is shared across countries. * @memberof PhoneComponent */ isSharedDialCode(): boolean; /** * Applies the phone validators: a libphonenumber-js validity check for the * selected country plus required when `config.validation` requires it. * @memberof PhoneComponent */ applyValidators(): void; /** * Reactive validator that marks the national number invalid when it is not a * valid phone number for the selected country, using * `isValidPhoneNumber(nationalNumber, isoCode)` from libphonenumber-js. An * empty value is left to the required validator (returns null), and a * non-numeric value is rejected. Returns `{ pattern: true }` on failure so the * shared `ieeesa-form-error` renders `config.patternErrorMessage`. * @param {AbstractControl} control - The national-number control. * @return {ValidationErrors | null} `{ pattern: true }` when invalid, else null. * @memberof PhoneComponent */ phoneValidator: (control: AbstractControl) => ValidationErrors | null; /** * Determines whether the national number's own area/prefix identifies a * specific country that shares the selected country's dial code but is not * the selected country (e.g. a Canadian "+1 506…" number while the US is * selected). Returns false when no specific country can be resolved, so * incomplete or non-geographic numbers never trigger a mismatch error. * @param {string} nationalNumber - The national number digits. * @return {boolean} True when the number belongs to a different country on * the same dial code. * @memberof PhoneComponent */ isCountryMismatch(nationalNumber: string): boolean; /** * Blocks any non-digit key press so only numbers can be entered. * @param {KeyboardEvent} event * @memberof PhoneComponent */ onKeyDown(event: KeyboardEvent): void; /** * Writes the combined value back to the parent form control and mirrors the * number's validity so the shared dynamic-form validation/error display still * applies. The stored value contains ONLY the dial code and the national * number; the flag and country name are display-only. * @memberof PhoneComponent */ syncParentValue(): void; /** * Marks the field as touched on blur so validation errors only appear after * the user has interacted with the number input. * @memberof PhoneComponent */ onBlur(): void; /** * Switches from the read-only display state into edit mode (pencil click). * @memberof PhoneComponent */ enableEdit(): void; /** * Returns the composed display value for the read-only state: the dial code * followed by the raw national number (e.g. "+91 7325550148"), or empty when * no number is present. * @return {string} * @memberof PhoneComponent */ getDisplayValue(): string; /** * Builds the stored `countryCode` value: the selected country's ISO alpha-2 * short name followed by its dial code, e.g. "US +1". This disambiguates * countries that share a dial code (US vs Canada) in the payload while * keeping `PhoneValue` a flat { countryCode, phoneNumber } object. Returns * null when no country is selected. * @return {string | null} The "ISO +code" string, e.g. "US +1", or null. * @memberof PhoneComponent */ getStoredCountryCode(): string | null; /** * Returns the lowercase ISO alpha-2 code for a country, used to build the * `flag-icons` CSS class (`fi fi-`). Returns '' when unavailable. * @param {CountryDialCode | undefined} country - The country. * @return {string} Lowercase ISO alpha-2 code, or ''. * @memberof PhoneComponent */ getFlagClass(country: CountryDialCode | undefined): string; /** * Determines whether the field is required, based on the config validators. * @return {boolean} * @memberof PhoneComponent */ isRequired(): boolean; /** * Whether the number input is in a valid, non-empty state, used to show the * valid-state (green check) indicator. * @return {boolean} * @memberof PhoneComponent */ isValidState(): boolean; /** * TrackBy for the ng-select country options list. ng-select's `trackByFn` * receives the item only (not an index), so the signature matches ng-select. * @param {CountryDialCode} country - A country option. * @return {string} The country's ISO code used as the track key. * @memberof PhoneComponent */ trackByCountry: (country: CountryDialCode) => string; /** * Cleans up subscriptions. * @memberof PhoneComponent */ ngOnDestroy(): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; }