import { Type } from '@angular/core'; import { AbstractControl, AsyncValidatorFn, FormArray, FormControl, FormGroup, ValidatorFn } from '@angular/forms'; import { DeepPropsObject, Immutable, Maybe, NotNull } from '@fretve/global-types'; import { Observable } from 'rxjs'; import { DeepPartial } from 'ts-essentials'; export declare type GetControlFieldReturnValue = T extends ControlFieldComponent<(infer V), any> ? V : never; export declare type GetViewOptionsFromComponent = T extends null ? {} : T extends Type> ? Q : Else; export declare type GetValueTypeFromControl = T extends AbstractDynamicControl ? V : never; export declare type GetViewOptionsFromControl = T extends AbstractDynamicControl ? GetViewOptionsFromComponent : never; /** Represents a function that converts an error to a readable error message */ export declare type ErrorDisplayFn = (err: unknown) => string; /** Represents a map of controls that should be disabled */ export declare type DisabledControls = { [P in keyof NotNull]: boolean; }; /** Represents a map of controls with callbacks that are called on form value changes. Return true on callback to hide control. */ export declare type HideOnValueChanges = { [P in keyof NotNull]: (val: TForm) => boolean; }; /** Represents an async validator that reacts to an observer of state T */ export declare type AsyncStateValidator = ((state$: Observable) => AsyncValidatorFn); export declare type FormControlType = TControl extends DynamicControlArray ? FormArray : TControl extends DynamicControlGroup ? FormGroup : TControl extends DynamicControlField ? (GenericAbstractControl & FormControl) : FormControl; /** Represents a selector for a slice of form and state */ export interface FormStateSelector extends ReactiveSelector { setter: FormStateSelectorFn, Partial, TReturnValue>; selectorType: "regular"; onlyOnce?: boolean; ɵform?: TForm; ɵstate?: TInputState; } /** Represents a selector for an observable slice of form and state */ export interface FormStateObserverSelector extends ReactiveSelector { setter: FormStateSelectorFn>, Observable>, Observable>; selectorType: "observer"; ɵform?: TForm; ɵstate?: TInputState; } /** Represents a selector for async validators */ export interface AsyncValidatorSelector extends ReactiveSelector { setter: FormStateSelectorFn>, Observable>, AsyncValidatorFn>; selectorType: "asyncValidator"; ɵform?: TForm; ɵstate?: TInputState; } /** Represents a generic reactive selector */ export interface ReactiveSelector { stateSlice: TStateSlice[]; formSlice: TFormSlice[]; setter: FormStateSelectorFn; baseFormPath?: string; } /** Represents the selector function of form state {@link FormStateSetter} */ export declare type FormStateSelectorFn = (form: TForm, state: TInputState) => TReturnValue; /** A union of eligible form state selectors */ export declare type AllowedFormStateSelector = FormStateSelector, Partial, TValueType, string, keyof TInputState> | FormStateObserverSelector, Partial, TValueType, string, keyof TInputState> | TValueType; /** Returns an object where all properties allow a form state selectors with respective return values */ export declare type AllowFormStateSelectors = { [P in keyof TObject]: P extends `${any}$` ? FormStateSelector, Partial, TObject[P], string, keyof TInputState> | FormStateObserverSelector, Partial, TObject[P], string, keyof TInputState> | TObject[P] : NotNull extends AsyncValidatorFn[] ? (AsyncValidatorSelector, Partial, string, keyof TInputState> | AsyncValidatorFn)[] : TObject[P]; }; /** Returns an object with no form state selectors */ export declare type RemoveFormStateSelectors = { [P in keyof TObject]: Exclude>; }; /** Represents a generic form state selector */ export declare type GenericFormStateSelector = FormStateSelector; /** Represents a generic form state selector */ export declare type GenericFormStateObserverSelector = FormStateObserverSelector; /** Represents a map of properties from TForm with an associated control schema */ export declare type DynamicControlMap = { [P in keyof TForm]: AbstractDynamicControl>>, any>; }; export interface DynamicControlGroup, TGroupComponent extends Maybe>>> extends AbstractDynamicControl, AllowFormStateSelectors { /** The form controls that make up the group */ controls: TControls; } export interface DynamicControlArray, TControlComponent extends Type> | undefined = undefined> extends AbstractDynamicControl, AllowFormStateSelectors { /** The template control used for each entry */ controlTemplate: TInputState extends ControlState ? TTemplate : never; } declare type ControlState = T extends AbstractDynamicControl ? S : never; export interface DynamicControlField> | undefined = undefined> extends AbstractDynamicControl, AllowFormStateSelectors { } export interface AbstractDynamicControl>> = undefined, TViewOptionDefault extends object = never> { /** The control component that should be rendered. * @remarks * For arrays and groups; a value of undefined indicates the use of default component. * For groups; a value of null indicates no component */ viewComponent?: TControlComponent; /** The control component view options */ viewOptions: AllowFormStateSelectors, TForm, TInputState>; ɵvalueType?: TValueType; } /** Represents configuration options for a dynamic control field */ export interface DynamicControlFieldOptions extends ControlOptions { /** Set to true if control is required. */ required$?: boolean; } /** Represents configuration options for a dynamic control array */ export interface DynamicControlArrayOptions extends ControlOptions { } /** Represents configuration options for a dynamic control group */ export interface DynamicControlGroupOptions extends ControlOptions { } /** Represents configuration options for all controls */ export interface ControlOptions { /** Set to true to require a value before the form can be submitted. Default is false. */ disabled$?: boolean; /** Validators for the control*/ validators$?: ValidatorFn[]; /** Async validators for the control*/ asyncValidators?: AsyncValidatorFn[]; /** A custom class added to the anchor tag of the control component */ controlClass$?: string; /** Clears the control value if true. Ignores initial value. */ clearValue$?: boolean; } /** Represents a control field component that displays a field used to set the control value. */ export interface ControlFieldComponent extends ControlComponent { /** The control accociated with the component */ formControl: GenericAbstractControl; /** Selector for the required status of the control. Use with {@link FormStateResolver} to retrieve observable value. */ requiredSelector?: Immutable>; /** Resolve an observable for viewOptions values */ resolveOptions$(): Observable>; } /** Represents a control group component used to display a group of controls. */ export interface ControlGroupComponent extends ControlComponent { /** The form group control accociated with the component */ formControl: FormGroup; /** The controls of the form group */ controls: Immutable>; } /** Represents a control array component used to display an array of controls. */ export interface ControlArrayComponent extends ControlComponent { /** The form array control accociated with the component */ formControl: FormArray; /** The control template for creating entries in the form array */ controlTemplate: Immutable>; } export interface ControlComponent extends OnControlInit { /** The control associated with this component */ formControl: GenericAbstractControl; /** Selectors for viewOptions values. Use with {@link FormStateResolver} to retrieve observable values. */ viewOptionSelectors: Immutable>; ɵviewOptions?: TViewOptions; } /** Represents a life cycle hook that runs when the control is initalized. */ export interface OnControlInit { onControlInit?: () => void; } /** Represents an AbstractControl with generic value type */ export interface GenericAbstractControl extends Omit { readonly valueChanges: Observable; reset(value?: T): void; readonly value: T; setValue(value: T, options?: Object): void; patchValue(value: T, options?: Object): void; } /** Represents component options for a default control group component configured with {@link DynamicFormDefaultOptions} * @remarks Use declaration merging to populate interface with options. */ export interface DefaultControlGroupComponentOptions { } /** Represents component options for a default control array component configured with {@link DynamicFormDefaultOptions} * @remarks Use declaration merging to populate interface with options. */ export interface DefaultControlArrayComponentOptions { } /** Represents a custom html attribute for a given control */ export interface CustomAttribute = AbstractDynamicControl> { attribute: string; value: (name: string, config: TControl) => string; } /** Represents default configuration options for all dynamic forms in module scope. * @remarks Supplied with injection token {@link DYNAMIC_FORM_DEFAULT_OPTIONS} */ export interface DynamicFormDefaultOptions { arrayViewComponent?: Type>; groupViewComponent?: Type>; groupClass?: string; arrayClass?: string; fieldClass?: string; controlAttributes?: CustomAttribute[]; } export {};