import { FocusMonitor, FocusOrigin } from '@angular/cdk/a11y';
import { ChangeDetectorRef, OnChanges, OnDestroy } from '@angular/core';
import { AbstractControl, ControlValueAccessor, FormArray, FormControlDirective, FormControlName, FormGroup, NgModel, ValidationErrors } from '@angular/forms';
import { Observable, Subject } from 'rxjs';
import { DirectiveSuperclass } from './directive-superclass';
import * as i0 from "@angular/core";
/**
* Extend this when creating a form control to reduce some boilerplate.
*
* When you simply need to use the same control that you're binding to via ngModel or formControl
* on the inside of your custom component, then simply bind the inside control to `ngControl.control`:
* ```ts
* @Component({
* selector: 'app-one-input',
* template: `
*
* `,
* })
* export class OneInputComponent extends FormComponentSuperclass {}
* ```
*
* If you have some custom component logic that requires its own state management,
* use viewModel as the internal state
* ```ts
* @Component({
* selector: 'app-counter',
* template: `
*
* `,
* })
* export class CounterComponent extends FormComponentSuperclass {
* viewModel = new FormControl(0);
*
* increment() {
* this.viewModel.setValue(this.viewModel.value + 1);
* }
* }
* ```
*
* Example when you need to transform the value used outside of the component to the
* structure representing internal viewModel:
* ```ts
* @Component({
* selector: 'app-local-date',
* template: `
*
* `,
* })
* export class LocalDateComponent extends FormComponentSuperclass {
* viewModel = new FormControl();
*
* outerToInner(incomingValues$: Observable): Observable {
* return incomingValues$.pipe(
* map((date) => {
* if (!date) {
* return ''; // happens during initialization
* }
* return date.toISOString().substr(0, 16);
* })
* );
* }
*
* innerToOuter(outgoingValues$: Observable): Observable {
* return outgoingValues$.pipe(
* map((inner) => {
* if (!inner) {
* return (null as unknown) as Date;
* }
* return new Date(inner + 'Z');
* })
* );
* }
* }
* ```
*/
export declare abstract class FormComponentSuperclass extends DirectiveSuperclass implements ControlValueAccessor, OnChanges, OnDestroy {
/**
* A reference to the outer control. Use ngControl.control inside of the template
* if you want to simply forward the outer control.
*/
ngControl: FormControlDirective | FormControlName | NgModel;
/**
* Tracks internal control value (view-model).
*/
protected viewModel?: AbstractControl | FormGroup<{
[K in keyof InnerType]: any;
}> | FormArray;
/**
* Resolved viewModel.
*
* Since `viewModel` is set in the class that extends from this class,
* the `this.viewModel` is undefined at the time the observable expression
* is defined. That's why we use the trick of `of(null).pipe(map(() => ...))`.
* This way `this.viewModel` is defined when observable is subscribed to.
*/
private viewModel$;
private viewModelValueChanges$;
/**
* Stream of values that are either set on the outer control
* or set via the value property
*/
private incomingValues$$;
protected hostEl: HTMLElement;
protected focusMonitor: FocusMonitor;
protected changeDetectorRef: ChangeDetectorRef;
protected focusMonitor$: Observable;
/**
* Built-in validator reference
*/
private validator;
private disabled$$;
disabled$: Observable;
id: string;
stateChanges: Subject;
get value(): OuterType;
set value(val: OuterType);
private _value;
get disabled(): boolean;
set disabled(value: boolean | string);
private _focused;
get focused(): boolean;
set focused(val: boolean);
/**
* Stream that takes all incoming values, optionally applies user-provided
* transformation, and commits the value to the inner form control
*/
private outerToInner$;
/**
* Stream that listens to values as user types in the input, optionally applies
* user-provided transformation, and emits the result to the outer form control
*/
private innerToOuter$;
latestValue$: Observable;
innerControlValues$: Observable;
constructor();
ngOnChanges(changes: any): void;
ngOnDestroy(): void;
/**
* Implement this method in the consuming component for built-in validation.
* @param control The control being validated
*/
validate?(control: AbstractControl): ValidationErrors | null;
writeValue(): void;
registerOnChange(): void;
registerOnTouched(): void;
/** Call this to "commit" a control visit, traditionally done e.g. on blur. */
onTouched(): void;
/** Called as angular propagates disabled changes to this `ControlValueAccessor`. You normally do not need to use it. */
setDisabledState(isDisabled: boolean): void;
/**
* Override this to modify a value coming from the outside to the format needed within this component.
* Example:
* ```ts
* return values$.pipe(map(val => val.toString()));
* ```
* @param values$ Stream of values set from the outside
* @returns Stream of transformed values that conform to the type of inner control
*/
protected outerToInner: (values$: Observable) => Observable;
/**
* Override this to modify a value coming from within this component to the format expected on the outside.
* Example:
* ```ts
* return values$.pipe(map(val => parseInt(val)));
* ```
* @param values$ Stream of inner formControl.valueChanges
* @returns Stream of transformed values that conform to the type of outer control
*/
protected innerToOuter: (values$: Observable) => Observable;
/**
* Call this to emit a new value when it changes.
*/
private emitOutgoingValue;
/**
* Sets the instance of this component as the valueAccessor. Since this is
* done here, there's no need to do that on the component that extends this class.
* https://github.com/angular/components/blob/master/guides/creating-a-custom-form-field-control.md#ngcontrol
*/
private provideValueAccessor;
private setupValidator;
private monitorFocus;
/**
* Syncs touched and dirty states between inner controls and the forwarded ngControl
* @param innerControls controls that need to be synced
*/
private syncOuterAndInnerControls;
static ɵfac: i0.ɵɵFactoryDeclaration, never>;
static ɵdir: i0.ɵɵDirectiveDeclaration, never, never, { "disabled": "disabled"; }, {}, never, never, false, never>;
}