UNPKG

@taiga-ui/kit

Version:
296 lines (290 loc) • 12.4 kB
import { __decorate, __param } from 'tslib'; import { InjectionToken, EventEmitter, Optional, Self, Inject, ChangeDetectorRef, Input, Output, ContentChild, TemplateRef, ViewChild, Component, ChangeDetectionStrategy, forwardRef, NgModule } from '@angular/core'; import { NgControl } from '@angular/forms'; import { TuiDestroyService, AbstractTuiControl, isNativeFocused, getClipboardDataText, setNativeFocused, tuiRequiredSetter, tuiDefaultProp, TUI_FOCUSABLE_ITEM_ACCESSOR, TuiActiveZoneModule } from '@taiga-ui/cdk'; import { formatPhone, TuiDataListDirective, TuiHostedDropdownComponent, TuiPrimitiveTextfieldComponent, TUI_DATA_LIST_HOST, TuiPrimitiveTextfieldModule, TuiHostedDropdownModule, TuiTextfieldControllerModule } from '@taiga-ui/core'; import { fromEvent, merge, Observable } from 'rxjs'; import { DOCUMENT } from '@angular/common'; import { FIXED_DROPDOWN_CONTROLLER_PROVIDER } from '@taiga-ui/kit/providers'; import { windowToggle, flatMap, startWith, takeUntil } from 'rxjs/operators'; import { TuiValueAccessorModule } from '@taiga-ui/kit/directives'; import { TextMaskModule } from 'angular2-text-mask'; const SELECTION_STREAM = new InjectionToken('A stream of selection changes'); const INPUT_PHONE_PROVIDERS = [ TuiDestroyService, FIXED_DROPDOWN_CONTROLLER_PROVIDER, { provide: SELECTION_STREAM, deps: [TuiDestroyService, DOCUMENT], useFactory: selectionStreamFactory, }, ]; function selectionStreamFactory(destroy$, documentRef) { return fromEvent(documentRef, 'selectionchange').pipe(windowToggle(merge(fromEvent(documentRef, 'mouseup'), fromEvent(documentRef, 'keydown')), () => fromEvent(documentRef, 'mousedown')), flatMap(windowed$ => windowed$.pipe(startWith(null))), takeUntil(destroy$)); } var TuiInputPhoneComponent_1; const NON_PLUS_AND_DIGITS_REGEX = /[ \-_\(\)]/g; // @dynamic let TuiInputPhoneComponent = TuiInputPhoneComponent_1 = class TuiInputPhoneComponent extends AbstractTuiControl { constructor(control, changeDetectorRef, selection$) { super(control, changeDetectorRef); this.phoneMaskAfterCountryCode = '(###) ###-##-##'; this.allowText = false; this.search = ''; this.searchChange = new EventEmitter(); this.textMaskOptions = { mask: value => this.allowText && !this.value && isText(value) && value !== '+' ? false : [ ...this.countryCode.split(''), ' ', ...this.phoneMaskAfterCountryCode .replace(/[^#\- \(\)]+/g, '') .split('') .map(item => (item === '#' ? /\d/ : item)), ], pipe: value => { if (this.allowText) { return value; } return value === '' && this.focused && !this.readOnly ? `${this.countryCode} ` : value.replace(/-$/, ''); }, guide: false, }; this.countryCode = '+7'; this.open = false; selection$.subscribe(() => { this.setCaretPosition(); }); } set countryCodeSetter(countryCode) { this.updateValueWithNewContryCode(countryCode); this.countryCode = countryCode; } get nativeFocusableElement() { return !this.textfield || this.computedDisabled ? null : this.textfield.nativeFocusableElement; } get focused() { return (isNativeFocused(this.nativeFocusableElement) || (!!this.dropdown && this.dropdown.focused)); } get nativeValue() { return this.value ? formatPhone(this.value, this.countryCode, this.phoneMaskAfterCountryCode) : this.search || ''; } get inputMode() { return this.allowText ? "text" /* Text */ : "numeric" /* Numeric */; } onHovered(hovered) { this.updateHovered(hovered); } onDrop(event) { if (!event.dataTransfer) { return; } this.setValueWithoutPrefix(event.dataTransfer.getData('text')); event.preventDefault(); } onPaste(event) { this.setValueWithoutPrefix(getClipboardDataText(event)); } onActiveZone(active) { this.updateFocused(active); if (active && !this.nativeValue && !this.readOnly && !this.allowText) { this.updateSearch(this.countryCode); return; } if (this.nativeValue === this.countryCode || (this.search !== null && isNaN(parseInt(this.search.replace(NON_PLUS_AND_DIGITS_REGEX, ''), 10)))) { this.updateSearch(''); } } onBackspace(event) { if ((event.target.selectionStart || 0) <= this.nonRemovableLength && event.target.selectionStart === event.target.selectionEnd) { event.preventDefault(); } } onValueChange(value) { const parsed = isText(value) ? value : value.replace(NON_PLUS_AND_DIGITS_REGEX, ''); this.updateSearch(parsed); this.updateValue(parsed === this.countryCode || isText(parsed) ? '' : parsed); this.open = true; } handleOption(item) { this.focusInput(); this.updateValue(item); this.updateSearch(''); this.open = false; } setDisabledState() { super.setDisabledState(); this.open = false; } writeValue(value) { super.writeValue(value); this.updateSearch(''); } getFallbackValue() { return ''; } get caretIsInForbiddenArea() { const { nativeFocusableElement } = this; if (!nativeFocusableElement) { return false; } const { selectionStart, selectionEnd } = nativeFocusableElement; return (isNativeFocused(nativeFocusableElement) && selectionStart !== null && selectionStart < this.nonRemovableLength && selectionStart === selectionEnd); } get nonRemovableLength() { return this.isTextValue ? 0 : this.countryCode.length + 1; } get maxPhoneLength() { return (this.countryCode.length + this.phoneMaskAfterCountryCode.replace(/[^#]+/g, '').length); } get isTextValue() { return !!this.search && isText(this.search); } setCaretPosition() { if (this.caretIsInForbiddenArea && !!this.nativeFocusableElement) { this.nativeFocusableElement.setSelectionRange(this.nonRemovableLength, this.nonRemovableLength); } } setValueWithoutPrefix(value) { if (this.readOnly) { return; } this.open = true; this.updateValue(this.cleanValue(value)); this.updateSearch(this.allowText && isText(value) ? value : value.replace(NON_PLUS_AND_DIGITS_REGEX, '')); } cleanValue(value) { const reg = this.countryCode === '+7' ? /^7|^8/ : new RegExp(this.countryCode.substring(1)); const oldValueExist = this.value.length > this.countryCode.length && this.value.length < this.maxPhoneLength; const newValueLength = value.replace(NON_PLUS_AND_DIGITS_REGEX, '').length; const cleanNewValue = value.replace(/[^0-9]+/g, ''); const selectionLength = getSelection().toString().length; if (oldValueExist && selectionLength === 0) { return `${this.value}${cleanNewValue}`.slice(0, this.maxPhoneLength); } if (newValueLength < this.maxPhoneLength - 1) { return `${this.countryCode}${cleanNewValue}`.slice(0, this.maxPhoneLength); } return `${this.countryCode}${cleanNewValue.replace(reg, '')}`.slice(0, this.maxPhoneLength); } focusInput() { if (this.nativeFocusableElement) { setNativeFocused(this.nativeFocusableElement, true, true); } } updateSearch(search) { if (this.search === search) { return; } this.search = search; this.searchChange.emit(search); } updateValueWithNewContryCode(newCountryCode) { if (!this.isTextValue) { this.updateValue(this.value.replace(this.countryCode, newCountryCode)); } } }; TuiInputPhoneComponent.ctorParameters = () => [ { type: NgControl, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NgControl,] }] }, { type: ChangeDetectorRef, decorators: [{ type: Inject, args: [ChangeDetectorRef,] }] }, { type: Observable, decorators: [{ type: Inject, args: [SELECTION_STREAM,] }] } ]; __decorate([ Input('countryCode'), tuiRequiredSetter() ], TuiInputPhoneComponent.prototype, "countryCodeSetter", null); __decorate([ Input(), tuiDefaultProp() ], TuiInputPhoneComponent.prototype, "phoneMaskAfterCountryCode", void 0); __decorate([ Input(), tuiDefaultProp() ], TuiInputPhoneComponent.prototype, "allowText", void 0); __decorate([ Input(), tuiDefaultProp() ], TuiInputPhoneComponent.prototype, "search", void 0); __decorate([ Output() ], TuiInputPhoneComponent.prototype, "searchChange", void 0); __decorate([ ContentChild(TuiDataListDirective, { read: TemplateRef }) ], TuiInputPhoneComponent.prototype, "datalist", void 0); __decorate([ ViewChild(TuiHostedDropdownComponent) ], TuiInputPhoneComponent.prototype, "dropdown", void 0); __decorate([ ViewChild(TuiPrimitiveTextfieldComponent) ], TuiInputPhoneComponent.prototype, "textfield", void 0); TuiInputPhoneComponent = TuiInputPhoneComponent_1 = __decorate([ Component({ selector: 'tui-input-phone', template: "<tui-hosted-dropdown\n class=\"hosted\"\n [content]=\"datalist || ''\"\n [(open)]=\"open\"\n (tuiActiveZoneChange)=\"onActiveZone($event)\"\n>\n <tui-primitive-textfield\n class=\"textfield\"\n tuiValueAccessor\n tuiTextfieldType=\"tel\"\n [tuiTextfieldInputMode]=\"inputMode\"\n [pseudoHovered]=\"pseudoHovered\"\n [pseudoFocused]=\"computedFocused\"\n [invalid]=\"computedInvalid\"\n [nativeId]=\"nativeId\"\n [readOnly]=\"readOnly\"\n [disabled]=\"computedDisabled\"\n [focusable]=\"focusable\"\n [textMask]=\"textMaskOptions\"\n [value]=\"nativeValue\"\n (valueChange)=\"onValueChange($event)\"\n (hoveredChange)=\"onHovered($event)\"\n (drop)=\"onDrop($event)\"\n (keydown.backspace)=\"onBackspace($event)\"\n (paste.prevent)=\"onPaste($event)\"\n >\n <ng-content></ng-content>\n </tui-primitive-textfield>\n</tui-hosted-dropdown>\n", changeDetection: ChangeDetectionStrategy.OnPush, providers: [ { provide: TUI_FOCUSABLE_ITEM_ACCESSOR, useExisting: forwardRef(() => TuiInputPhoneComponent_1), }, { provide: TUI_DATA_LIST_HOST, useExisting: forwardRef(() => TuiInputPhoneComponent_1), }, INPUT_PHONE_PROVIDERS, ], styles: [":host{display:block;border-radius:var(--tui-radius-m)}:host._disabled{pointer-events:none}.hosted{display:block;border-radius:inherit}.textfield{border-radius:inherit}"] }), __param(0, Optional()), __param(0, Self()), __param(0, Inject(NgControl)), __param(1, Inject(ChangeDetectorRef)), __param(2, Inject(SELECTION_STREAM)) ], TuiInputPhoneComponent); function isText(value) { return isNaN(parseInt(value.replace(NON_PLUS_AND_DIGITS_REGEX, ''), 10)); } let TuiInputPhoneModule = class TuiInputPhoneModule { }; TuiInputPhoneModule = __decorate([ NgModule({ imports: [ TextMaskModule, TuiPrimitiveTextfieldModule, TuiHostedDropdownModule, TuiTextfieldControllerModule, TuiActiveZoneModule, TuiValueAccessorModule, ], declarations: [TuiInputPhoneComponent], exports: [TuiInputPhoneComponent], }) ], TuiInputPhoneModule); /** * Generated bundle index. Do not edit. */ export { INPUT_PHONE_PROVIDERS, SELECTION_STREAM, TuiInputPhoneComponent, TuiInputPhoneModule, selectionStreamFactory }; //# sourceMappingURL=taiga-ui-kit-components-input-phone.js.map