/// /// import * as react from 'react'; import { FormEvent, ReactElement, ReactNode, FC, ComponentClass, FormHTMLAttributes, Ref } from 'react'; import { EventEmitter } from 'events'; /** * */ declare enum PathNodeType { OBJECT_KEY = 0, ARRAY_INDEX = 1 } /** * */ declare type PathNode = [PathNodeType.OBJECT_KEY, string] | [PathNodeType.ARRAY_INDEX, number]; /** * */ declare type UnparsedPathNode = PathNode | string; /** * */ declare type UnparsedPath = Path | PathNode[] | UnparsedPathNode[] | string | null | undefined; /** * */ declare class Path { static readonly ROOT: Path; readonly nodes: PathNode[]; constructor(nodes: PathNode[]); /** * True if this path is root (contains no nodes). */ get isRoot(): boolean; /** * Returns a string */ get pathString(): string; /** * * @param other */ parentOf(other: Path): boolean; /** * * @param other */ equals(other: Path): boolean; /** * * @param nodes */ add(...nodes: PathNode[]): Path; /** * * @param other */ concat(other: Path): Path; /** * * @param start * @param end */ slice(start?: number, end?: number): Path; /** * */ toString(): string; /** * * @param path */ static parse(path: UnparsedPath): Path; } declare class Change { readonly path: Path; readonly value: any; constructor(path: Path, value: any); static subChanges(changes: Change[], path: Path): Change[]; } declare type ValidationError = string; declare type FieldError = [Path, ValidationError[]]; interface ValidationResult { valid: boolean; value: ValueType; errors: FieldError[]; path: Path; } interface IValidator { validateSubmission(values: Values): Promise>; validateChange(path: Path, value: FieldType, values: Values): Promise>; validateOnBlur(path: Path, value: FieldType, values: Values): Promise>; } declare const CHANGE_EVENT: "change"; declare const ERROR_EVENT: "formerror"; declare const FOCUS_EVENT: "focus"; declare const BLUR_EVENT: "blur"; declare const DO_SUBMIT_EVENT: "dosubmit"; declare const SUBMITTING_EVENT: "submitting"; declare type FormoramaEvents = { [CHANGE_EVENT]: [changes: Change[]]; [ERROR_EVENT]: [errors: FieldError[]]; [FOCUS_EVENT]: [focusedPath: Path]; [BLUR_EVENT]: [oldFocus: Path]; [DO_SUBMIT_EVENT]: [event?: FormEvent]; [SUBMITTING_EVENT]: [submitting: boolean]; }; declare type FormEventListener = FormoramaEvents> = (...args: Events[Event]) => void; declare type ArrayItem = T extends Array ? S : never; declare type NullableValues> = { [K in keyof T]?: NullableField; }; declare type NullableField = T extends Record ? NullableValues | null : T | null; declare type ErrorObject = { [K in keyof T]?: ErrorField; } & ({ [key: string]: ErrorField; } | {}); declare type ErrorField = T extends Record ? ErrorObject | string | null : string | null; interface SubFormProps { children?: ReactNode; name: string; } declare function SubForm({ children, name }: SubFormProps): ReactElement; interface ArrayFormItemProps { children?: ReactNode; index: number; } declare function ArrayFormItem({ children, index }: ArrayFormItemProps): ReactElement; interface ArrayFormItemsChildrenParams { values: Values; index: number; remove(): void; } declare type Component = FC | ComponentClass | string; declare type ArrayFormItemsRenderOptions = { component?: Component>; } | { children?(props: ArrayFormItemsChildrenParams): ReactNode; } | { renderItem?(props: ArrayFormItemsChildrenParams): ReactNode; }; interface ArrayFormItemsProps { keyExtractor?(values: ArrayItem, index: number): any; getKey?(values: ArrayItem, index: number): any; } declare function ArrayFormItems({ getKey, keyExtractor: _keyExtractor, ...props }: ArrayFormItemsProps & ArrayFormItemsRenderOptions>): ReactElement; declare class FormErrors { static readonly EMPTY: FormErrors; private readonly errors; constructor(errors: FieldError[]); get(path: Path): ValidationError[]; subErrors(path: Path): FormErrors; compare(nextErrors: FormErrors): FieldError[]; applyValidationResults(results: ValidationResult[]): FormErrors; set(path: Path, errors: ValidationError[]): FormErrors; private static errorsEqual; private static changeError; private static applyResult; } interface NormalFormControllerParams { maxListeners?: number; } interface FormControllerParamsWithLegacyValidate extends NormalFormControllerParams { validate(values: Values): any | Promise; } interface FormControllerParamsWithValidator extends NormalFormControllerParams { validator: IValidator; } declare type FormControllerParams = NormalFormControllerParams | FormControllerParamsWithLegacyValidate | FormControllerParamsWithValidator; declare class FormController extends EventEmitter { private values; private touched; private validator; constructor(params?: FormControllerParams); private _errors; set errors(errors: FormErrors); set params(params: FormControllerParams); private _submitting; get submitting(): boolean; set submitting(submitting: boolean); private _focusing; private get focusing(); private set focusing(value); change(path: Path, value: any): Promise; changeErrors(path: Path, errors: ValidationError[]): void; modify(modifier: (values: T) => T, path?: Path): void; focus(path: Path): void; blur(path: Path): void; submit(): void; getValue(path: Path): T; getErrors(path: Path): ValidationError[]; hasTouched(path: Path): boolean; isFocusing(path: Path | null): boolean; validateSubmission(): Promise; private validateChanges; private validateBlur; } interface FormMethods { change(uPath: UnparsedPath, value: T): void; getValue(uPath: UnparsedPath): T; getError(uPath: UnparsedPath): any; hasTouched(uPath: UnparsedPath): boolean; isFocusing(uPath: UnparsedPath): boolean; modify(modifier: (values: NullableField) => NullableField, uPath?: UnparsedPath): void; submit(): void; } interface FormContextValue { controller: FormController; path: Path; } declare const FormContext: react.Context>; declare const FormConsumer: react.Consumer>; interface UseForm extends FormMethods { ctx: FormContextValue; } declare function useForm(params?: FormControllerParams): UseForm; interface ErrorExtraResult { values: Values; event?: FormEvent; } interface SubmitExtraResult { event?: FormEvent; } interface FormTagProps extends Omit, "onSubmit" | "onError" | "form"> { noFormTag?: false; formRef?: Ref; } interface NoFormTagProps { noFormTag: true; } declare type FormProps = { form: UseForm; onSubmit?: (values: Values, extra: SubmitExtraResult) => Promise | void; onError?: (errors: any, extra: ErrorExtraResult) => Promise | void; children?: ReactNode; } & (FormTagProps | NoFormTagProps); declare function Form({ children, form, onSubmit, onError, ...props }: FormProps): ReactElement; declare class ImmutableValuesTree { static readonly EMPTY_OBJECT: ImmutableValuesTree<{}>; static readonly EMPTY_ARRAY: ImmutableValuesTree<[]>; readonly raw: T; constructor(values: T); /** * * @param path */ get(path: Path): any; /** * * @param path */ has(path: Path): boolean; /** * * @param path */ follow(path: Path): ImmutableValuesTree; /** * * @param path * @param value */ set(path: Path, value: any): ImmutableValuesTree; /** * */ entries(): [Path, any][]; /** * * @param other */ compare(other: ImmutableValuesTree): [Path, any][]; /** * */ clean(): ImmutableValuesTree; /** * * @param entries * @param tree */ static fromEntries(entries: [Path, any][], tree?: ImmutableValuesTree): ImmutableValuesTree; private static getValue; private static setValue; private static isArray; private static isObject; private static getEntries; private static clean; private static cleanFilter; } declare class SubmissionError implements Error { readonly message = "An error occurred while during the form submission"; readonly name: string; readonly errors: ImmutableValuesTree; constructor(errors: any); } declare function useFormContext(path?: UnparsedPath): UseForm; interface ChangeListeners { onChange(eventOrValue: any): void; } interface FocusListeners { onFocus(event: any): void; onBlur(event: any): void; } interface UseInput { value: ValueType; error: ValidationError | null; errors: ValidationError[]; focused: boolean; touched: boolean; submitting: boolean; listeners: ChangeListeners & FocusListeners; changeListeners: ChangeListeners; focusListeners: FocusListeners; handleChange(eventOrValue: any): void; handleError(error: any): void; handleFocus(): void; handleBlur(): void; } declare function useInput(name: string, defaultValue: ValueType): UseInput; declare type NullableArray = T extends unknown[] ? { [K in keyof T]: T[K] | null; } : never; declare function useInputValue(fields: { [K in keyof Values]: UnparsedPath; }, form?: UseForm, uPath?: UnparsedPath): NullableArray; declare function useSubmitting(form?: UseForm): boolean; declare class FormValues { readonly values: ImmutableValuesTree; constructor(values: Values); change(path: Path, value: any): Change[]; compare(otherValues: FormValues): Change[]; apply(changes: Change[]): FormValues; get(path: Path): T; } declare const events: { CHANGE_EVENT: "change"; ERROR_EVENT: "formerror"; FOCUS_EVENT: "focus"; BLUR_EVENT: "blur"; DO_SUBMIT_EVENT: "dosubmit"; SUBMITTING_EVENT: "submitting"; }; export { SubForm as ArrayForm, ArrayFormItem, ArrayFormItems, Change, ErrorField, ErrorObject, Form, FormConsumer, FormContext, FormController, FormControllerParams, FormErrors, FormEventListener, FormValues, FormoramaEvents, IValidator, ImmutableValuesTree, NullableField, NullableValues, Path, SubForm, SubmissionError, UseForm, UseInput, ValidationResult, events, useForm, useFormContext, useInput, useInputValue, useSubmitting };