UNPKG

mobx-form

Version:
261 lines (260 loc) 9.05 kB
import type { DebouncedFunc } from "lodash"; export type Descriptors<T> = { [P in keyof T]: FieldDescriptor<T[P], T>; }; export type FormModelArgs<T> = { descriptors: Partial<Descriptors<T>>; initialState?: Partial<T>; options?: ThrowIfMissingFieldType; }; export type ResultObj = { error: string; }; export type ErrorLike = { message: string; } | Error; export type ValidatorResult = boolean | ResultObj | void; export type ValidateFnArgs<T, K> = { field: Field<T, K>; fields: FormModel<K>["fields"]; model: FormModel<K>; value: Field<T, K>["value"]; }; export type ValidateFn<T, K> = (args: ValidateFnArgs<T, K>) => Promise<ValidatorResult> | ValidatorResult; export type ResetInteractedFlagType = { resetInteractedFlag?: boolean; }; export type ThrowIfMissingFieldType = { throwIfMissingField?: boolean; }; export interface FieldDescriptor<T, K> { waitForBlur?: boolean; disabled?: boolean; errorMessage?: string; validator?: ValidateFn<T, K> | ValidateFn<T, K>[]; hasValue?: (value: T) => boolean; value?: T; required?: boolean | string; autoValidate?: boolean; validationDebounceThreshold?: number; clearErrorOnValueChange?: boolean; meta?: Record<string, any>; } export type CommitType = { commit?: boolean; }; export type ForceType = { force?: boolean; }; export type SetValueFnArgs = ResetInteractedFlagType & CommitType; /** * Field class provides abstract the validation of a single field */ export declare class Field<T, K> { _name: string; meta?: Record<string, any>; _model: FormModel<K>; _waitForBlur?: boolean | undefined; _disabled?: boolean | undefined; _required?: boolean | string; _validatedOnce: boolean; _clearErrorOnValueChange?: boolean | undefined; _hasValueFn?: (value: T) => boolean; get name(): string; get model(): FormModel<K>; get validatedAtLeastOnce(): boolean; get waitForBlur(): boolean; get disabled(): boolean; get required(): boolean; resetInteractedFlag(): void; markAsInteracted(): void; resetValidatedOnce(): void; get hasValue(): boolean; _validationTs: number; /** * flag to know if a validation is in progress on this field */ _validating: boolean; /** * field to store the initial value set on this field * */ _initialValue?: T; /** * the value of the field * */ _value?: T; /** * whether the user interacted with the field * this means if there is any value set on the field * either setting it using the `setValue` or using * the setter `value`. This is useful to know if * the user has interacted with teh form in any way */ _interacted: boolean; /** * whether the field was blurred at least once * usually validators should only start being applied * after the first blur, otherwise they become * too invasive. This flag be used to keep track of * the fact that the user already blurred of a field */ _blurredOnce: boolean; get blurred(): boolean; /** the raw error in caes validator throws a real error */ rawError?: ErrorLike; /** * the error message associated with this field. * This is used to indicate what error happened during * the validation process */ get errorMessage(): string | undefined; /** * whether the validation should be launch after a * new value is set in the field. This is usually associated * to forms that set the value on the fields after each * onChange event */ _autoValidate: boolean; get autoValidate(): boolean; /** * used to keep track of the original message */ _originalErrorMessage?: string; /** * whether the field is valid or not */ get valid(): boolean; /** * whether the user has interacted or not with the field */ get interacted(): boolean; /** * get the value set on the field */ get value(): T | undefined; _setValueOnly: (val?: T) => void; _setValue: (val?: T) => void; /** * setter for the value of the field */ set value(val: T); setValue: (value?: T, { resetInteractedFlag, commit }?: SetValueFnArgs) => void; /** * Restore the initial value of the field */ restoreInitialValue: ({ resetInteractedFlag, commit }?: SetValueFnArgs) => void; get dirty(): boolean; commit(): void; /** * clear the valid state of the field by * removing the errorMessage string. A field is * considered valid if the errorMessage is not empty */ resetError(): void; clearValidation(): void; /** * mark the field as already blurred so validation can * start to be applied to the field. */ markBlurredAndValidate: () => void; _validateFn?: ValidateFn<T, K> | Array<ValidateFn<T, K>>; _doValidate: () => Promise<ValidatorResult | undefined>; setDisabled(disabled: boolean): void; validate: (opts?: ForceType) => Promise<void>; get originalErrorMessage(): string; setValidating: (validating: boolean) => void; get validating(): boolean; /** * validate the field. If force is true the validation will be perform * even if the field was not initially interacted or blurred * */ _validate: ({ force }?: ForceType) => Promise<void>; setRequired: (val: boolean | string) => void; setErrorMessage: (msg?: string) => void; setError: (error: ErrorLike) => void; get error(): string | undefined; _debouncedValidation?: DebouncedFunc<Field<T, K>["_validate"]>; constructor(model: FormModel<K>, value: T, validatorDescriptor: FieldDescriptor<T, K>, fieldName: string); } /** * a helper class to generate a dynamic form * provided some keys and validators descriptors * * @export * @class FormModel */ export declare class FormModel<K> { get validatedAtLeastOnce(): boolean; get dataIsReady(): boolean; get requiredFields(): (keyof K)[]; get requiredAreFilled(): boolean; fields: { [P in keyof K]: Field<K[P], K>; }; _validating: boolean; get valid(): boolean; /** * whether or not the form has been "interacted", meaning that at * least a value has set on any of the fields after the model * has been created */ get interacted(): boolean; /** * Restore the initial values set at the creation time of the model * */ restoreInitialValues(opts?: SetValueFnArgs): void; commit(): void; get dirty(): boolean; /** * Set multiple values to more than one field a time using an object * where each key is the name of a field. The value will be set to each * field and from that point on the values set are considered the new * initial values. Validation and interacted flags are also reset if the second argument is true * */ updateFrom(obj: Partial<K>, { resetInteractedFlag, ...opts }?: SetValueFnArgs & ThrowIfMissingFieldType): void; /** * return the array of errors found. The array is an Array<String> * */ get summary(): string[]; setValidating: (validating: boolean) => void; get validating(): boolean; /** * Manually perform the form validation * */ validate: () => Promise<void>; /** * Update the value of the field identified by the provided name. * Optionally if reset is set to true, interacted and * errorMessage are cleared in the Field. * */ updateField: (name: keyof K, value?: K[keyof K], opts?: SetValueFnArgs & ThrowIfMissingFieldType) => void; /** * return the data as plain Javascript object (mobx magic removed from the fields) * */ get serializedData(): K; /** * Creates an instance of FormModel. * initialState => an object which keys are the names of the fields and the values the initial values for the form. * validators => an object which keys are the names of the fields and the values are the descriptors for the validators */ constructor(args: FormModelArgs<K>); _getField(name: keyof K, { throwIfMissingField }?: ThrowIfMissingFieldType): { [P in keyof K]: Field<K[P], K>; }[keyof K]; _eachField(cb: (field: Field<K[keyof K], K>) => void): void; get _fieldKeys(): (keyof K)[]; resetInteractedFlag(): void; disableFields: (fieldKeys: (keyof K)[]) => void; _createField({ name, descriptor, }: { name: keyof K; descriptor: FieldDescriptor<K[keyof K], K>; }): void; addFields: (fieldsDescriptor: Partial<Descriptors<K>>) => void; enableFields(fieldKeys: (keyof K)[]): void; resetValidatedOnce(): void; } /** * return an instance of a FormModel refer to the constructor * */ export declare const createModel: <T>(args: FormModelArgs<T>) => FormModel<T>; export declare const createModelFromState: <T>(initialState?: Partial<T>, validators?: Descriptors<T>, options?: ThrowIfMissingFieldType) => FormModel<T>;