;
const childDescribedBy = typeof child.props["aria-describedby"] === "string" ? child.props["aria-describedby"] : undefined;
// eslint-disable-next-line react-x/no-clone-element -- removes Radix Slot while preserving child element semantics
return React.cloneElement(child, {
...props,
ref: composeRefs(ref, child.props.ref),
id: formItemId,
"aria-describedby": mergeAriaDescribedBy(childDescribedBy, describedBy),
"aria-invalid": Boolean(error),
});
}
return (
}
id={formItemId}
aria-describedby={describedBy}
aria-invalid={Boolean(error)}
{...props}>
{children}
);
},
);
FormControl.displayName = "FormControl";
/**
* Renders helper text that describes the current form control.
*
* @remarks
* - Renders a `` element
* - Built on the shared form field metadata hook
*
* @example
* ```tsx
* We'll never share your email.
* ```
*
* @see {@link https://developer.mozilla.org/docs/Web/HTML/Element/p | HTML paragraph element}
*/
const FormDescription = React.forwardRef>(({className, ...props}, ref) => {
const {formDescriptionId} = useFormField();
return (
);
});
FormDescription.displayName = "FormDescription";
/**
* Renders the validation message or fallback message for the current form control.
*
* @remarks
* - Renders a `` element when content is available
* - Built on the shared form field metadata hook
*
* @example
* ```tsx
*
* ```
*
* @see {@link https://developer.mozilla.org/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-invalid | ARIA invalid state}
*/
const FormMessage = React.forwardRef>(
({className, children, ...props}, ref) => {
const {error, formMessageId} = useFormField();
const body = error ? String(error.message ?? "") : children;
if (!body) {
return null;
}
return (
{body}
);
},
);
FormMessage.displayName = "FormMessage";
FormField.displayName = "FormField";
export {
Controller,
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
useController,
useFieldArray,
useForm,
useFormContext,
useFormField,
useFormState,
useWatch,
};
export type {
Control,
ControllerFieldState,
ControllerProps,
ControllerRenderProps,
DefaultValues,
FieldError,
FieldErrors,
FieldPath,
FieldValues,
FormControlProps,
Path,
RegisterOptions,
Resolver,
SubmitHandler,
UseControllerReturn,
UseFieldArrayReturn,
UseFormReturn,
};