@react-md/form
Version:
This package is for creating all the different form input types.
208 lines (207 loc) • 8.12 kB
TypeScript
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];