import { Platform } from '@angular/cdk/platform'; import { AutofillMonitor } from '@angular/cdk/text-field'; import { AfterContentInit, AfterViewInit, ChangeDetectorRef, DoCheck, ElementRef, EventEmitter, NgZone, OnChanges, OnDestroy, Renderer2, SimpleChanges } from '@angular/core'; import { AbstractControl, FormControl, NgControl } from '@angular/forms'; import { DateAdapter } from '@angular/material/core'; import { MatDatepicker } from '@angular/material/datepicker'; import { TsDocumentService } from '@terminus/ngx-tools/browser'; import { TsFormFieldControl } from '@terminus/ui/form-field'; import { TsDatePipe } from '@terminus/ui/pipes'; import { TsStyleThemeTypes } from '@terminus/ui/utilities'; import { Subject } from 'rxjs'; export interface TextMaskInputElement { state: Record; update: Function; } /** * Define the function type for date filters. Used by {@link TsInputComponent} */ export declare type TsDateFilterFunction = (d: Date) => boolean; /** * Define the allowed {@link TsInputComponent} input types */ export declare type TsInputTypes = 'text' | 'password' | 'email' | 'hidden' | 'number' | 'search' | 'tel' | 'url'; /** * Define the allowed autocomplete variations for {@link TsInputComponent} * * NOTE: This is not all valid types; only the ones this library supports. */ export declare type TsInputAutocompleteTypes = 'off' | 'on' | 'name' | 'email' | 'username' | 'new-password' | 'current-password' | 'tel'; /** * A function that returns an array of RegExp (used to determine postal code RegExp in {@link TsInputComponent}) */ export declare type TsMaskFunction = (value: string) => (RegExp | string)[]; /** * An individual mask definition. Used by {@link TsInputComponent} */ export interface TsMask { mask: (RegExp | string)[] | TsMaskFunction | false; unmaskRegex?: RegExp; pipe?: Function; guide?: boolean; showMask?: boolean; keepCharPositions?: boolean; } /** * The collection of masks. Used by {@link TsInputComponent} */ export interface TsMaskCollection { [key: string]: TsMask; } /** * Define the allowed mask shortcut option. Used by {@link TsInputComponent} */ export declare type TsMaskShortcutOptions = 'currency' | 'date' | 'number' | 'percentage' | 'phone' | 'postal' | 'default'; /** * A presentational component to render a text input * * @example * * * https://getterminus.github.io/ui-demos-release/components/input */ export declare class TsInputComponent implements TsFormFieldControl, AfterViewInit, AfterContentInit, DoCheck, OnChanges, OnDestroy { private elementRef; private renderer; private changeDetectorRef; private autofillMonitor; protected platform: Platform; private ngZone; private documentService; private datePipe; dateAdapter: DateAdapter; ngControl: NgControl; /** * Emits when the value changes (either due to user input or programmatic change). Need for Material Datepicker. * * NOTE: Underscore naming convention needed since that is what the Material datepicker will subscribe to. */ _valueChange: EventEmitter; /** * The aria-describedby attribute on the input for improved a11y */ ariaDescribedby: string | undefined; /** * Define if the input has been autofilled */ autofilled: boolean; /** * Define an InputValueAccessor for this component */ private inputValueAccessor; /** * Store the current mask */ private currentMask; /** * Define the default format for the date mask */ private defaultDateFormat; /** * Store a reference to the document object */ private document; /** * Define the flex layout gap */ flexGap: string; /** * Define whether the input has focus * * Implemented as part of {@link TsFormFieldControl} */ focused: boolean; /** * Implemented as part of TsFormFieldControl. */ readonly labelChanges: Subject; /** * Store the last value for comparison */ private lastValue; /** * Define placeholder for callback (provided later by the control value accessor) */ private onChangeCallback; /** * Define placeholder for callback (provided later by the control value accessor) */ private onTouchedCallback; /** * Store the previous value */ private previousNativeValue; /** * Reference to itself. Passed to {@link TsFormFieldComponent}. */ selfReference: TsInputComponent; /** * Implemented as part of TsFormFieldControl. */ readonly stateChanges: Subject; /** * Base settings for the mask */ private textMaskConfig; /** * Store the mask instance */ private textMaskInputElement; private textualDateValue; /** * Define the default component ID */ protected uid: string; /** * Expose reference to the Material datepicker component */ picker: MatDatepicker; /** * Provide access to the input */ inputElement: ElementRef; /** * Determine if the input is empty * * 1. Input exists * 2. Input has no value * 3. Native input validation is valid * 4. Input is not filled by browser * * Implemented as part of {@link TsFormFieldControl}. */ get empty(): boolean; /** * Getter returning a boolean based on both the component `isDisabled` flag and the FormControl's disabled status */ get shouldBeDisabled(): boolean; /** * Determine if the label should float */ get shouldLabelFloat(): boolean; /** * Set the accessor and call the onchange callback * * @param v */ set value(v: any); get value(): any; /** * Define if the input should autocapitalize * (standard HTML5 property) */ autocapitalize: boolean; /** * Define if the input should autocomplete. See {@link TsInputAutocompleteTypes}. * * @param value */ set autocomplete(value: TsInputAutocompleteTypes); get autocomplete(): TsInputAutocompleteTypes; private _autocomplete; /** * Define a date filter to disallow certain dates for the datepicker * * @param value */ set dateFilter(value: TsDateFilterFunction | undefined); get dateFilter(): TsDateFilterFunction | undefined; private _dateFilter; /** * Allow the date locale to be changed * * @param value */ set dateLocale(value: string); get dateLocale(): string; private _dateLocale; /** * Define if the datepicker should be enabled * * @param value */ set datepicker(value: boolean); get datepicker(): boolean; private _datepicker; /** * Define the form control to get access to validators * * @param value */ set formControl(value: FormControl); get formControl(): FormControl; private _formControl; static ngAcceptInputType_formControl: FormControl | AbstractControl; /** * Define if the use-case provides it's own {@link TsFormFieldComponent} or if this component should provide it's own. */ hasExternalFormField: boolean; /** * Define if a required marker should be included */ hideRequiredMarker: boolean; /** * Define a hint for the input * * @param value */ set hint(value: string | undefined); get hint(): string | undefined; private _hint; /** * Define an ID for the component * * @param value */ set id(value: string); get id(): string; protected _id: string; /** * Define if the input should surface the ability to clear it's value */ isClearable: boolean; /** * Define if the input should be disabled * * Implemented as part of {@link TsFormFieldControl} */ isDisabled: boolean; /** * Define if the input should be focused * * @param value */ set isFocused(value: boolean); get isFocused(): boolean; private _isFocused; /** * Define if the input is required * * Implemented as part of {@link TsFormFieldControl} * * @param value */ set isRequired(value: boolean); get isRequired(): boolean; private _isRequired; /** * Define if the input should be a textarea * * NOTE: This is not meant to be used with the datepicker or mask enabled. */ isTextarea: boolean; /** * Define the label * * @param value */ set label(value: string | undefined); get label(): string | undefined; private _label; /** * Define a mask * * param value - A {@link TsMaskShortcutOptions} * * @param value */ set mask(value: TsMaskShortcutOptions | undefined); get mask(): TsMaskShortcutOptions | undefined; private _mask; /** * Define if decimals are allowed in numbers/currency/percentage masks * * @param value */ set maskAllowDecimal(value: boolean); get maskAllowDecimal(): boolean; private _maskAllowDecimal; /** * Define if the value should be sanitized before it is saved to the model */ maskSanitizeValue: boolean; /** * Define the maximum date for the datepicker * * @param value */ set maxDate(value: string | Date | undefined); get maxDate(): string | Date | undefined; private _maxDate; /** * Define the minimum date for the datepicker * * @param value */ set minDate(value: string | Date | undefined); get minDate(): string | Date | undefined; private _minDate; /** * Define the name attribute value */ name: string | undefined; /** * Define whether formControl needs a validation or a hint */ noValidationOrHint: boolean; /** * Define a date that the calendar should open to for the datepicker * * @param value */ set openTo(value: Date | undefined); get openTo(): Date | undefined; private _openTo; /** * Define a Material icon to include before the input */ prefixIcon: string | undefined; /** * Define if the input is readOnly */ readOnly: boolean; /** * Define if the input should spellcheck * (standard HTML5 property) */ spellcheck: boolean; /** * Define the starting calendar view for the datepicker * * @param value */ set startingView(value: 'month' | 'year'); get startingView(): 'month' | 'year'; private _startingView; /** * Define the tabindex for the input * * @param value */ set tabIndex(value: number); get tabIndex(): number; private _tabIndex; /** * Define the number of rows for a textarea * * NOTE: Since the 'rows' attribute of a textarea is stored as a string, we should accept both string and number. * * @param value */ set textareaRows(value: number); get textareaRows(): number; private _textareaRows; /** * Define the component theme */ theme: TsStyleThemeTypes; /** * Define the input type (text, password etc.) See {@link TsInputTypes} * * @param value */ set type(value: TsInputTypes); get type(): TsInputTypes; private _type; /** * Define if validation messages should be shown immediately or on blur */ validateOnChange: boolean; /** * The event to emit when the input value is cleared */ readonly cleared: EventEmitter; /** * Define an event when the input receives a blur event */ readonly inputBlur: EventEmitter; /** * The event to emit when the input element receives a focus event */ readonly inputFocus: EventEmitter; /** * The event to emit when the input element receives a paste event */ readonly inputPaste: EventEmitter; /** * Define an event emitter to alert consumers that a date was selected */ readonly selected: EventEmitter; constructor(elementRef: ElementRef, renderer: Renderer2, changeDetectorRef: ChangeDetectorRef, autofillMonitor: AutofillMonitor, platform: Platform, ngZone: NgZone, documentService: TsDocumentService, datePipe: TsDatePipe, inputValueAccessor: any, dateAdapter: DateAdapter, ngControl: NgControl); /** * After the view is initialized, trigger any needed animations */ ngAfterViewInit(): void; /** * HACK: Without this hack, seeded values are not initially seen so the label overlaps the content. * * The issue seems to be that the elementRef.nativeElement isn't updated with the new value immediately. When manually inspecting the * nativeElement, the value does exist. But when the `empty` getter defines it's elementRef instance, the value is not yet set. * * Material doesn't seem to have this issue. The only real difference is that they are implementing the ControlValueAccessor in the input * where we are extending another class. * * So currently, we just check to see if the value has changed, then trigger a fake input event since the CVA for ngModel listens for the * input event. */ ngAfterContentInit(): void; ngDoCheck(): void; /** * Trigger needed changes when specific inputs change * * @param changes - The changes */ ngOnChanges(changes: SimpleChanges): void; /** * Stop monitoring autofill */ ngOnDestroy(): void; /** * Fix for the iOS caret bug * * On some versions of iOS the caret gets stuck in the wrong place when holding down the delete * key. In order to get around this we need to "jiggle" the caret loose. Since this bug only * exists on iOS, we only bother to install the listener on iOS. * https://github.com/angular/material2/blob/master/src/lib/input/input.ts */ private fixIOSCaretBug; /** * Set touched on blur */ onBlur(): void; /** * Update the inner value when the formControl value is updated * * @param value - The value to set */ updateInnerValue: (value: string) => void; /** * Register onChange callback (from ControlValueAccessor interface) * * @param fn */ registerOnChange(fn: any): void; /** * Register onTouched callback (from ControlValueAccessor interface) * * @param fn */ registerOnTouched(fn: any): void; /** * Clear the input's value */ reset(): void; /** * Callback for when the focused state of the input changes * * @param nowFocused - Boolean determining if the input is gaining or losing focus */ focusChanged(nowFocused: boolean): void; /** * Write the value * * @param value - The value to write to the model */ writeValue(value: string | Date): void; /** * Update values on input * * NOTE: KNOWN BUG that allows model and UI to get out of sync when extra characters are added after a fully satisfied mask. * * @param target - The event target for the input event. */ onInput(target: HTMLInputElement | HTMLTextAreaElement): void; /** * Notify consumer of date changed from the picker being used. * * @param date - The date that has been set. */ onDateChanged(date: Date): void; /** * Remove the mask if needed * * @param value - The value to clean * @param regex - The RegExp to use to clean the value * @returns The clean value */ private cleanValue; /** * Create the collection of possible masks * * @param allowDecimal - If the number based masks should allow a decimal character * @returns The collection of masks */ private createMaskCollection; /** * Helper to determine the correct postal code match (5 characters vs 9) * * @param value - The current postal code value * @returns The correct mask */ private determinePostalMask; /** * Checks whether the input is invalid based on the native validation * * @returns Whether the native validation passes */ private isBadInput; /** * Set the model value * * @param value - The value to set */ private setValue; /** * Register our custom onChange function * * @param fn - The onChange function */ private registerOnChangeFn; /** * Set the current mask definition * * @param value - The name of the desired mask */ private setMaskDefinition; /** * Create the mask */ private setUpMask; /** * Update mask model * * HACK: Firing an event inside a timeout is the only way I can get the model to update after the mask dynamically changes. The UI * updates perfectly, but the unsanitized model value retains the previous masked value. */ private updateMaskModelHack; /** * HACK: Trim the last character of the model when the string is longer than the model * * KNOWN BUG: This hack does not work correcty for unsanitized percentage masks. * * The underlying text-mask library has a bug that allows the user to type 1 more character than the mask allows. To get around this * issue, we are checking to see if the input value is longer than the mask. If it is, trim the last character off and set the value. * See: https://github.com/text-mask/text-mask/issues/294#issuecomment-342299450 * * @param value - The value to check * @returns The trimmed value (if needed) */ private trimLastCharacter; /** * Convert an valid date string to a Date if needed * * NOTE: When using 1 time bindings we are required to pass in ISO stringified dates. Adding this * method to our setters adds support for either version * * @param date - The date * @returns The Date object */ private verifyIsDateObject; /** * Determine if a date string is valid. * * We cannot simply see if the string creates a valid date. The string '0' will technically create a valid Date. For our purposes, we can * check to verify the length is correct AND it is a valid date. This works because the mask is enforcing a consistent 'length' for valid * dates. * * @param value - The string * @returns If the string is a valid date */ private isValidDateString; /** * Implemented as part of {@link TsFormFieldControl}. */ onContainerClick(): void; /** * Focus the input element */ focus(): void; /** * Set a new date locale * * @param newLocale - The locale to set */ private setDateLocale; /** * Manually dirty check the native input `value` property */ protected dirtyCheckNativeValue(): void; }