UNPKG

@kform/react

Version:

React integration for KForm.

235 lines (234 loc) 10.2 kB
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 {};