react-browser-form
Version:
<div align="center"> <a href="https://deniskabana.github.io/react-browser-form/introduction" title="React Browser Form - Form management in React made simple for browsers."> <img src="https://raw.githubusercontent.com/deniskabana/react-browser-form/
284 lines (283 loc) • 15.9 kB
TypeScript
/// <reference types="react" />
/** An options object to configure how you use this form.
* - [Options API](https://deniskabana.github.io/react-browser-form/documentation/options-api)
*/
export interface BrowserFormOptionsInput<Schema> {
/**
* Form DOM name attribute - **must be unique**. Used to access inputs through `document.forms`, to read all events and hydrate the form data and the DOM inputs.
* - [Options API](https://deniskabana.github.io/react-browser-form/documentation/options-api)
*/
name: string;
/**
* Default values need to match your schema. **Do not change these - it will result in incorrect behavior.**
* - [Options API](https://deniskabana.github.io/react-browser-form/documentation/options-api)
*/
defaultValues: Schema & {
[key: string]: any;
};
/**
* A callback for when the form is submitted. **Will not trigger if there are errors during validation!**
* - [Options API](https://deniskabana.github.io/react-browser-form/documentation/options-api)
*/
onSubmit?: (data: Schema) => void;
/**
* This method is useful when using `onChange` mode, live fields, setting or resetting values, etc.
* - [Options API](https://deniskabana.github.io/react-browser-form/documentation/options-api)
*/
onChange?: (data: Schema) => void;
/**
* A dead-simple validation with a validator schema that has access to single field and all form data. Throw `ValidationError` with an error message if field validation fails.
* - [Options API](https://deniskabana.github.io/react-browser-form/documentation/options-api)
* - [Documentation](https://deniskabana.github.io/react-browser-form/documentation/validation-and-transformation)
* - [Examples](https://deniskabana.github.io/react-browser-form/examples/validation)
*/
validationSchema?: ValidationSchema<Schema>;
/**
* A dead-simple type and value transformation schema. Useful when you need easy data processing, input masking or just recast types.
* - [Options API](https://deniskabana.github.io/react-browser-form/documentation/options-api)
* - [Documentation](https://deniskabana.github.io/react-browser-form/documentation/validation-and-transformation)
* - [Example](https://deniskabana.github.io/react-browser-form/examples/advanced/value-transformation)
*/
transformationSchema?: TransformationSchema<Schema>;
/**
* Whether to perform validation right after mounting the form - before the first render.
* - [Options API](https://deniskabana.github.io/react-browser-form/documentation/options-api)
*/
validateAfterInit?: boolean;
/**
* Options:
* - `onSubmitUnlessError`: Hydrate and validate upon form submit event. Inputs with errors re-validate on input change until the error is resolved.
* - `onSubmit`: Hydrate and validate upon form submit event. The fastest option if not validating, reliant on browser handling and keeping inputs mounted.
* - `onBlurUnlessError`: Hydrate and validate the form on every input blur. Inputs with errors re-validate on input change until the error is resolved.
* - `onBlur`: Hydrate and validate the form on every input blur. Recommended for forms with more complex validation logic.
* - `onChange`: The React way of handling forms. - the slowest method. Only good for live data handling. It is recommended to use live fields instead.
*
* Further reading:
* - [Options API](https://deniskabana.github.io/react-browser-form/documentation/options-api)
* - [Example](https://deniskabana.github.io/react-browser-form/examples/basic/form-modes)
*
* @default "onSubmitUnlessError"
*/
mode?: "onSubmitUnlessError" | "onSubmit" | "onBlurUnlessError" | "onBlur" | "onChange";
/**
* A revalidation strategy for inputs with errors. To be used with any *unlessError mode. Choose `onBlur` if your validation is demanding.
* - [Options API](https://deniskabana.github.io/react-browser-form/documentation/options-api)
* - [Example](https://deniskabana.github.io/react-browser-form/examples/validation/revalidation-strategies)
*
* @default "onChange"
*/
revalidationStrategy?: "onChange" | "onBlur";
/**
* A subset of fields that will trigger update and validation of specified fields on every input change. Useful for conditional operations within forms, dependent fields, etc.
* - [Options API](https://deniskabana.github.io/react-browser-form/documentation/options-api)
* - [Example](https://deniskabana.github.io/react-browser-form/examples/advanced/live-fields)
*/
liveFields?: (keyof Schema)[];
/** **DO NOT USE IN PRODUCTION**. UNDOCUMENTED ON PURPOSE. This is meant for tests, library development and docs. */
debug?: boolean;
}
export declare type BrowserFormOptions<Schema> = Required<BrowserFormOptionsInput<Schema>>;
/** An object returned after initialization.
* - [Return types API](https://deniskabana.github.io/react-browser-form/documentation/return-types-api)
*/
export interface BrowserFormReturnType<Schema> {
/**
* Props that will attach to DOM form node - `<form {...formProps} />`. This is necessary for React Browser Form to function as it uses the built-in browser form management mechanisms an React events.
* - [Return types API](https://deniskabana.github.io/react-browser-form/documentation/return-types-api)
*/
formProps: FormComponentProps<Schema>;
/**
* **Optional but recommended.** Names object prevents errors during development. You can pass name as a string to inputs optionally, but you will lose out on compile-time errors.
* - [Return types API](https://deniskabana.github.io/react-browser-form/documentation/return-types-api)
*/
names: Record<keyof Schema, string>;
/**
* Errors object that keeps tracks of errors and their count.
* - [Return types API](https://deniskabana.github.io/react-browser-form/documentation/return-types-api)
*
* @example { count: 1, errors: { password: "Error message" } }
*/
errorData: ErrorsObject<Schema>;
/**
* Whether the form has been touched by the user. No deep comparisons happen internally. Reset will clear this value.
* - [Return types API](https://deniskabana.github.io/react-browser-form/documentation/return-types-api)
*/
isDirty: boolean;
/**
* An array of strings referencing the names of inputs considered "dirty". Reset will clear this value.
* - [Return types API](https://deniskabana.github.io/react-browser-form/documentation/return-types-api)
*/
dirtyFields: Array<keyof Schema>;
/**
* Lets you programatically submit the form. Useful when using non-standard or controlled inputs.
* - [Return types API](https://deniskabana.github.io/react-browser-form/documentation/return-types-api)
* - [Example](https://deniskabana.github.io/react-browser-form/examples/basic/form-methods)
*/
submit: SubmitMethod;
/**
* Programatically reset the form. If no values are provided, `defaultValues` are used. If values are provided, they need to cover the entire Schema. Triggers the `onChange` event and validation and reset dirty fields.
* - [Return types API](https://deniskabana.github.io/react-browser-form/documentation/return-types-api)
* - [Example](https://deniskabana.github.io/react-browser-form/examples/basic/form-methods)
*/
reset: ResetMethod<Schema>;
/**
* Allows to set a subset of values programmatically (this gets merged with the current form state). It will trigger an `onChange` event and validation.
* **Setting the values programatically does change the dirty status of both the fields and the whole form.**
* - [Return types API](https://deniskabana.github.io/react-browser-form/documentation/return-types-api)
* - [Example](https://deniskabana.github.io/react-browser-form/examples/basic/form-methods)
*/
setValues: SetValuesMethod<Schema>;
}
/**
* Lets you programatically submit the form. Useful when using non-standard or controlled inputs.
* - [Return types API](https://deniskabana.github.io/react-browser-form/documentation/return-types-api)
* - [Example](https://deniskabana.github.io/react-browser-form/examples/basic/form-methods)
*/
export declare type SubmitMethod = VoidFunction;
/**
* Programatically reset the form. If no values are provided, `defaultValues` are used. If values are provided, they need to cover the entire Schema. Triggers the `onChange` event and validation.
* - [Return types API](https://deniskabana.github.io/react-browser-form/documentation/return-types-api)
* - [Example](https://deniskabana.github.io/react-browser-form/examples/basic/form-methods)
*/
export declare type ResetMethod<Schema> = (values?: Schema) => void;
/**
* Allows to set a subset of values programmatically (this gets merged with the current form state). It will trigger an `onChange` event and validation.
* - [Return types API](https://deniskabana.github.io/react-browser-form/documentation/return-types-api)
* - [Example](https://deniskabana.github.io/react-browser-form/examples/basic/form-methods)
*/
export declare type SetValuesMethod<Schema> = (values: Partial<Schema>) => void;
export declare type TransformationFn<Schema, Key extends keyof Schema> = (fieldData: unknown, formState?: Schema) => Schema[Key];
/**
* A dead-simple type and value transformation schema. Useful when you need easy data processing, input masking or just recast types.
* - [Options API](https://deniskabana.github.io/react-browser-form/documentation/options-api)
* - [Documentation](https://deniskabana.github.io/react-browser-form/documentation/validation-and-transformation)
* - [Example](https://deniskabana.github.io/react-browser-form/examples/advanced/value-transformation)
*/
export interface TransformationSchema<Schema> {
/** By default a transformation based on input[type] is applied, managing the correct types for primitive types. */
disableDefaultTransformation?: boolean;
/** Singular fields to transform. Can not use `transformAllData` if `fields` is used. Provide the name of the primitive type or your own transform function. */
fields?: {
[Field in keyof Schema]?: TransformationFn<Schema, Field> | "number" | "string" | "boolean";
};
}
export interface DirtyFieldsManager<Schema> {
isDirty: boolean;
setIsDirty: React.Dispatch<React.SetStateAction<boolean>>;
dirtyFields: Array<keyof Schema>;
setDirtyFields: (fields: Array<keyof Schema>) => void;
resetDirtyState: () => void;
}
export interface ErrorManager<Schema> {
errorData: ErrorsObject<Schema>;
setErrors: (errors: Partial<Record<keyof Schema, string>>) => void;
}
/**
* Errors object that keeps tracks of errors and their count.
* - [Return types API](https://deniskabana.github.io/react-browser-form/documentation/return-types-api)
*
* @example { count: 1, errors: { password: "Error message" } }
*/
export interface ErrorsObject<Schema> {
count: number;
/** Contains an object that ties field name to a custom error message (if any). */
errors: Partial<Record<keyof Schema, string>>;
}
/**
* A validation function that receives all the latest form data.
* @param fieldData Data of the field that the validation function is tied to.
* @param formState **Optional.** The whole form state object. Use if any of your data are tied together.
* @throws `ValidationError` if the validation failed.
*/
export declare type ValidationFn<Schema, Key extends keyof Schema> = (fieldData: Schema[Key], formState: Schema) => void;
export declare type ValidationValidatorsFields<Schema> = {
[Field in keyof Schema]?: ValidationFn<Schema, Field> | Array<ValidationFn<Schema, Field>>;
};
export declare type ValidationRequiredFields<Schema> = {
fields: (keyof Schema)[];
message?: string;
};
/**
* A dead-simple validation with a validator schema that has access to single field and all form data. Throw `ValidationError` with an error message if field validation fails.
* - [Options API](https://deniskabana.github.io/react-browser-form/documentation/options-api)
* - [Documentation](https://deniskabana.github.io/react-browser-form/documentation/validation-and-transformation)
* - [Examples](https://deniskabana.github.io/react-browser-form/examples/validation)
*/
export declare type ValidationSchema<Schema> = {
validators?: ValidationValidatorsFields<Schema>;
required: ValidationRequiredFields<Schema>;
} | {
validators: ValidationValidatorsFields<Schema>;
required?: ValidationRequiredFields<Schema>;
};
export interface FieldsData<Schema> {
names: Record<keyof Schema, string>;
required: (keyof Schema)[];
validated: (keyof Schema)[];
}
/**
* Props that will attach to DOM form node - `<form {...formProps} />`. This is necessary for React Browser Form to function as it uses the built-in browser form management mechanisms an React events.
* - [Return types API](https://deniskabana.github.io/react-browser-form/documentation/return-types-api)
*/
export declare type FormComponentProps<Schema> = FormEventHandlers<Schema>[EventSource.Form] & {
name: BrowserFormOptions<Schema>["name"];
};
export interface UserCallbacks<Schema> {
onSubmit: (data: Schema) => void;
onChange: (data: Schema) => void;
}
export declare enum EventSource {
User = "User",
Form = "Form"
}
export declare enum EventType {
/** Submit event */
Submit = "Submit",
/** Any type of reset or clear action */
Reset = "Reset",
/** `EventType.Change` gets called for all listeners - `onChange`, `onBlur` and `onSubmit` */
Change = "Change",
/** `EventType.Blur` when a form input is blurred (loses focus) */
Blur = "Blur",
/** A special type of event triggered programmatically during init phase. Under the hood it just calls `reset()` without calling `onChange()` or hydrating */
FormInit = "FormInit"
}
export declare type FormEventHandler = (event: React.FormEvent<HTMLFormElement>) => void;
export declare type UserEventHandler<Schema> = (value?: Partial<Schema>) => void;
export interface FormEventHandlers<Schema> {
[EventSource.User]: {
setValues: UserEventHandler<Schema>;
submit: UserEventHandler<Schema>;
reset: UserEventHandler<Schema>;
};
[EventSource.Form]: {
onChange: FormEventHandler;
onSubmit: FormEventHandler;
onBlur: FormEventHandler;
onReset: FormEventHandler;
};
}
export interface DataFlowEvent<Schema> {
source: EventSource;
type: EventType;
value?: Partial<Schema>;
nativeEvent?: React.FormEvent<HTMLFormElement>;
}
export interface DataFlowState<Schema> {
hasErrors: boolean;
event: DataFlowEvent<Schema>;
options: BrowserFormOptions<Schema>;
changedData: Partial<Schema>;
changeReason: string;
formState: Schema;
fieldsData: FieldsData<Schema>;
callbacks: UserCallbacks<Schema>;
errorData: ErrorsObject<Schema>;
setErrors: ErrorManager<Schema>["setErrors"];
isDirty: boolean;
setIsDirty: React.Dispatch<React.SetStateAction<boolean>>;
setDirtyFields: DirtyFieldsManager<Schema>["setDirtyFields"];
resetDirtyState: DirtyFieldsManager<Schema>["resetDirtyState"];
}
export declare type DataFlowFn<Schema> = (dataFlowState: DataFlowState<Schema>) => void;
export declare type HandleDataFlow<Schema> = (event: DataFlowEvent<Schema>) => void;