@kform/react
Version:
React integration for KForm.
214 lines (213 loc) • 10.1 kB
TypeScript
import { AutoValidationStatus, FormManager, LocatedValidationWarning, Schema, SchemaKt, SealedLocatedValidationIssue, ValidationMode } from "@kform/core";
import { DistributedOmit, MaybePromise } from "../utils/typeUtils";
import { Controller, ControllerOptions, ControllerState } from "./useController";
/** Default message passed when preventing the "before unload" event. */
export declare const DEFAULT_CONFIRM_UNLOAD_MESSAGE = "Are you sure you want to leave?";
/**
* Type of external issues accepted by the form manager's `addExternalIssues`
* method.
*/
type ExternalValidationIssues = Parameters<FormManager["addExternalIssues"]>[0];
/** An object which is event-like. */
type EventLike = Pick<Event, "preventDefault" | "defaultPrevented">;
/** Options available to the {@link useForm} hook. */
export type FormOptions<T = unknown, TSubmitResult = unknown> = DistributedOmit<ControllerOptions<T, FormControllerState<T>>, "formManager"> & FormOwnOptions<T, TSubmitResult>;
/** Own options available to the {@link useForm} hook. */
export interface FormOwnOptions<T = unknown, TSubmitResult = unknown> extends SubmitOptions<T, TSubmitResult> {
/** Initial form value. */
initialValue?: T;
/**
* External contexts available to validations. This value may change over time
* and will not cause a new form manager to be instantiated.
*/
externalContexts?: Record<string, unknown>;
/**
* Form manager's validation mode. This value may change over time and will
* not cause a new form manager to be instantiated.
*/
validationMode?: ValidationMode;
/**
* Whether to display a confirmation that the page should be unloaded when the
* form is dirty.
*
* @default true
*/
confirmUnloadWhenDirty?: boolean;
/**
* Message to provide when confirming a page unload due to the dirty status of
* the form.
*
* Note that most recent browsers will not honour this string and will instead
* display a predefined message (see:
* https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event#compatibility_notes).
*/
confirmUnloadMessage?: string;
/**
* Function called during reset, before actually resetting the form. Calling
* [preventDefault()]{@link event.preventDefault} on the event will prevent the
* reset from occurring.
*
* @param event Original `onReset` event.
*/
onReset?: (event?: EventLike) => MaybePromise<void>;
}
/**
* Controller used to read and control the root form value, exposing properties
* that should be set on a {@link HTMLFormElement <form>} element.
*/
export type FormController<T = unknown, TSubmitResult = unknown> = Controller<T, FormControllerState<T>> & FormOwnController<T, TSubmitResult>;
/** Form's own controller. */
export interface FormOwnController<T = unknown, TSubmitResult = unknown> {
/**
* Function used to submit the form.
*
* @param event Event which caused the submission.
* @param options Options used when submitting the form.
*/
readonly submit: (<TOptionsSubmitResult = TSubmitResult>(event: EventLike, options?: SubmitOptions<T, TOptionsSubmitResult>) => Promise<void>) & (<TOptionsSubmitResult = TSubmitResult>(options?: SubmitOptions<T, TOptionsSubmitResult>) => Promise<void>);
/** Hook returning the status of the form's automatic validations. */
readonly useAutoValidationStatus: () => AutoValidationStatus;
/** Hook returning whether the form is currently being submitted. */
readonly useSubmitting: () => boolean;
/** Hook returning whether the form is currently being reset. */
readonly useResetting: () => boolean;
/** Properties to set on a {@link HTMLFormElement <form>} element. */
readonly formProps: FormElementProps;
}
/** Options available when submitting a value. */
export interface SubmitOptions<T = unknown, TSubmitResult = unknown> {
/**
* Function called during submission when the form value to submit is locally
* valid (no validation errors were found), or always when `validateOnSubmit`
* is set to `false`.
*
* This function may (possibly asynchronously) return two types of values, or
* throw an error:
*
* - Function returns external validation issues: the submission is considered
* invalid (even if all returned issues are warnings). Returned issues that
* aren't already in the form manager are added to it via
* {@link FormManager.addExternalIssues}. `onInvalidSubmit` is subsequently
* called with the returned issues.
* - Function returns any other value: the submission is considered successful.
* `onSuccessfulSubmit` will be called with the returned value after setting
* the form as pristine (unless `setPristineOnSuccessfulSubmit` is set to
* `false`).
* - Function throws: the submission is considered to have failed.
* `onFailedSubmit` will be called with the thrown error.
*
* @param value Form value to submit.
* @param warnings List of form warnings. `undefined` when `validateOnSubmit`
* is set to `false`.
* @param event Original event (with the default behaviour already prevented).
* @returns External validation issues, or any other value (including
* `undefined`) to indicate success; or a promise which resolves to such
* values.
*/
onSubmit?: (value: T, warnings?: LocatedValidationWarning[], event?: EventLike) => MaybePromise<ExternalValidationIssues | TSubmitResult>;
/**
* Function called during submission when the form value to submit is locally
* invalid (validation errors were found), or after `onSubmit` if it returns
* external validation issues.
*
* @param issues List of form issues.
* @param event Original event (with the default behaviour already prevented).
*/
onInvalidSubmit?: (issues: SealedLocatedValidationIssue[], event?: EventLike) => void;
/**
* Function called after a successful submission with the result of
* `onSubmit`, when this result isn't external validation issues.
*
* Unless `setPristineOnSuccessfulSubmit` is set to `false`, the form will be
* pristine by the time this function runs, meaning that redirections that
* cause the form to be closed should happen within this function (so that the
* form unload confirmation isn't triggered).
*
* @param submitResult Result of calling `onSubmit`, when such value isn't
* external validation issues.
* @param event Original event (with the default behaviour already prevented).
*/
onSuccessfulSubmit?: (submitResult: TSubmitResult, event?: EventLike) => void;
/**
* Function called after a submission which resulted in an error.
*
* @param error Error that occurred during the submission.
* @param event Original event (with the default behaviour already prevented).
*/
onFailedSubmit?: (error: unknown, event?: EventLike) => void;
/**
* Whether to set the whole form as touched before submitting.
*
* @default true
*/
setTouchedOnSubmit?: boolean;
/**
* Whether to validate the form before submitting.
*
* When set to `false`, `onSubmit` is always called and `onInvalidSubmit` is
* only called if `onSubmit` returns external validation issues.
*
* @default true
*/
validateOnSubmit?: boolean;
/**
* Whether to set the whole form as pristine after a successful submission,
* but before invoking `onSuccessfulSubmit`.
*
* @default true
*/
setPristineOnSuccessfulSubmit?: boolean;
/**
* Whether to convert table row indices into ids when processing external
* issues returned by the `onSubmit` function.
*
* @default false
*/
convertExternalIssuesTableRowIndicesToIds?: boolean;
}
/**
* Properties to provide to a form element to integrate it with the form
* manager.
*/
export interface FormElementProps {
/** Disable native HTML validations. */
readonly noValidate: true;
/**
* Function to run whenever the form is to be submitted. This function calls
* the provided `onSubmit` option with the root value and the original form
* element event, while preventing the default event behaviour.
*/
readonly onSubmit: (event?: EventLike) => Promise<void>;
/**
* Function to run whenever the form is to be reset. This function resets the
* whole form, while preventing the default event behaviour.
*/
readonly onReset: (event?: EventLike) => Promise<void>;
}
/** Form controller's state. */
export type FormControllerState<T = unknown> = ControllerState<T> & FormControllerOwnState;
/** Form controller's own state. */
export interface FormControllerOwnState {
/** Status of the automatic validations. */
readonly autoValidationStatus: AutoValidationStatus;
/** Whether the root value is currently being submitted. */
readonly submitting: boolean;
/** Whether the root value is currently being reset. */
readonly resetting: boolean;
}
/**
* Hook used to create a new form managed by a form manager given its
* {@link schema}. It provides access to the form controller, as well as
* properties for integration with a {@link HTMLFormElement <form>} element.
*
* The provided external contexts and validation mode may change over time and
* will not cause a new form manager to be instantiated.
*
* @param schema Schema of the form.
* @param options Available options.
* @returns A controller used to read and control the root form value, exposing
* properties that should be set on a {@link HTMLFormElement <form>} element.
*/
export declare function useForm<T = unknown, TSubmitResult = unknown>(schema: Schema<T> | SchemaKt, options?: undefined): FormController<T, TSubmitResult>;
export declare function useForm<T = unknown, TSubmitResult = unknown>(schema: Schema<T> | SchemaKt, options: FormOptions<T, TSubmitResult>): FormController<T, TSubmitResult>;
export {};