@taiga-ui/kit
Version:
Taiga UI Angular main components kit
296 lines (290 loc) • 12.4 kB
JavaScript
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