UNPKG

@react-md/form

Version:

This package is for creating all the different form input types.

208 lines (207 loc) 8.12 kB
import type { Dispatch, HTMLAttributes, ReactNode, SetStateAction } from "react"; import type { FormMessageInputLengthCounterProps, FormMessageProps } from "../FormMessage"; import type { GetErrorIcon } from "./getErrorIcon"; import type { ChangeValidationBehavior, GetErrorMessage, TextConstraints } from "./getErrorMessage"; import type { IsErrored } from "./isErrored"; import type { TextFieldProps } from "./TextField"; /** * @remarks \@since 2.5.0 */ export declare type TextFieldChangeHandlers = Pick<HTMLAttributes<HTMLInputElement | HTMLTextAreaElement>, "onBlur" | "onChange">; /** * A function that reports the error state changing. A good use-case for this is * to keep track of all the errors within your form and keep a submit button * disabled until they have been resolved. * * Example: * * ```ts * const [errors, setErrors] = useState<Record<string, boolean | undefined>>({}); * const onErrorChange: ErrorChangeHandler = (id, error) => * setErrors((prevErrors) => ({ ...prevErrors, [id]: error })); * * const invalid = Object.values(errors).some(Boolean); * * // form implementation is left as an exercise for the reader * <Button type="submit" disabled={invalid} onClick={submitForm}>Submit</Button> * ``` * * @remarks \@since 2.5.0 */ export declare type ErrorChangeHandler = (id: string, error: boolean) => void; /** * @remarks \@since 2.5.0 */ export interface TextFieldHookOptions extends TextConstraints, TextFieldChangeHandlers, Pick<TextFieldProps, "id" | "theme"> { /** * Boolean if the `FormMessage` should also display a counter for the * remaining letters allowed based on the `maxLength`. * * This will still be considered false if the `maxLength` value is not * provided. */ counter?: boolean; /** * The default value to use for the `TextField` or `TextArea` one initial * render. If you want to manually change the value to something else after * the initial render, either change the `key` for the component containing * this hook, or use the `setState` function returned from this hook. */ defaultValue?: string | (() => string); /** * An optional help text to display in the `FormMessage` component when there * is not an error. */ helpText?: ReactNode; /** * A function used to determine if the `TextField` or `TextArea` is an in * errored state. See {@link defaultIsErrored} for the default implementation * details. */ isErrored?: IsErrored; /** * An optional error icon used in the {@link getErrorIcon} option. */ errorIcon?: ReactNode; /** * A function used to get the error icon to display at the right of the * `TextField` or `TextArea`. The default behavior will only show an icon when * the `error` state is `true` and an `errorIcon` option has been provided. */ getErrorIcon?: GetErrorIcon; /** * A function to get and display an error message based on the `TextField` or * `TextArea` validity. See {@link defaultGetErrorMessage} for the default * implementation details. */ getErrorMessage?: GetErrorMessage; /** * An optional function that will be called whenever the `error` state is * changed. This can be used for more complex forms to `disable` the Submit * button or anything else if any field has an error. */ onErrorChange?: ErrorChangeHandler; /** * Describes the validation behavior that should be done when the value within * the `TextField` changes. This can either be: * * - a boolean * - the string `"recommended"` * - a single key of the ValidityState that should trigger the validation * - a list of keys of the ValidityState that should trigger the validation */ validateOnChange?: ChangeValidationBehavior; /** * Boolean if the `TextField` or `TextArea` will **not** be rendered along * with a `FormMessage` component. This will prevent the `aria-describedby` * prop from being returned when set to `true`. */ disableMessage?: boolean; /** * Boolean if the `maxLength` prop should not be passed to the `TextField` * component since it will prevent any additional characters from being * entered in the text field which might feel like weird behavior to some * users. This should really only be used when the `counter` option is also * enabled and rendering along with a `FormMessage` component. */ disableMaxLength?: boolean; } /** * All the props that will be generated and return from the `useTextField` hook * that should be passed to a `FormMessage` component. * * @remarks \@since 2.5.0 */ export interface ProvidedFormMessageProps extends Pick<FormMessageProps, "id" | "theme" | "children">, Required<Pick<TextFieldProps, "error">>, Partial<Pick<FormMessageInputLengthCounterProps, "length" | "maxLength">> { } /** * All the props that will be generated and returned by the `useTextField` hook * that should be passed to a `TextField` component. * * @remarks \@since 2.5.0 */ export interface ProvidedTextFieldProps extends TextConstraints, Required<TextFieldChangeHandlers>, Required<Pick<TextFieldProps, "id" | "value" | "error">>, Pick<TextFieldProps, "aria-describedby" | "theme" | "rightChildren"> { } /** * @remarks \@since 2.5.0 */ export interface ProvidedTextFieldMessageProps extends ProvidedTextFieldProps { /** * These props will be defined as long as the `disableMessage` prop is not * `true` from the `useTextField` hook. */ messageProps: ProvidedFormMessageProps; } /** * @remarks \@since 2.5.0 */ export interface TextFieldHookState { /** * The current value for the `TextField` or `TextArea`. */ value: string; /** * Boolean if the `TextField` or `TextArea` are in an errored state. * * Note: This can be `true` while the `errorMessage` is an empty string since * it's sometimes useful to show there's an error while the user is typing * without reporting the full error message. */ error: boolean; /** * The current error message that will be an empty string when there are no * errors for the `TextField` or `TextArea` component or the message is hidden * during change events. */ errorMessage: string; } /** * @remarks \@since 2.5.0 */ export interface TextFieldHookControls { /** * Resets the state back to: * ```ts * { * value: "", * error: false, * errorMessage: "", * } * ``` */ reset(): void; setState: Dispatch<SetStateAction<TextFieldHookState>>; } /** * @remarks \@since 2.5.0 */ export declare type TextFieldHookReturnType = [ string, ProvidedTextFieldProps | ProvidedTextFieldMessageProps, TextFieldHookControls ]; /** * This hook is used to control the `value` for a `TextField` or `TextArea` * component along with some simple validation checks using the browser validity * api/constraint validation. This also provides props that can be passed to the * `FormMessage` component to display error messages or help text. * * Note: Even though this hook exists, it is highly recommended to use a form * helper library like [react-hook-form](https://react-hook-form.com/) for more * complex forms * * @see https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation * @param options - All the options used to control the functionality of this * hook. * @returns @see {@link TextFieldHookReturnType} * @remarks \@since 2.5.0 */ export declare function useTextField(options: TextFieldHookOptions & { disableMessage: true; }): [string, ProvidedTextFieldProps, TextFieldHookControls]; export declare function useTextField(options: TextFieldHookOptions & { disableMessage: false; }): [string, ProvidedTextFieldMessageProps, TextFieldHookControls]; export declare function useTextField(options: TextFieldHookOptions & { disableMessage?: boolean; }): [string, ProvidedTextFieldMessageProps, TextFieldHookControls];