@kform/react
Version:
React integration for KForm.
235 lines (234 loc) • 10.2 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 {};