import * as LabelPrimitive from "@radix-ui/react-label"; import { Slot } from "@radix-ui/react-slot"; import * as React from "react"; import { Controller, FormProvider, useFormContext, useFormState, type ControllerProps, type FieldPath, type FieldValues, } from "react-hook-form"; import { Label } from "~/components/ui/label"; import { cn } from "~/lib/utils"; const Form = FormProvider; type FormFieldContextValue< TFieldValues extends FieldValues = FieldValues, TName extends FieldPath = FieldPath, > = { name: TName; }; const FormFieldContext = React.createContext( {} as FormFieldContextValue, ); const FormField = < TFieldValues extends FieldValues = FieldValues, TName extends FieldPath = FieldPath, >({ ...props }: ControllerProps) => { return ( ); }; const useFormField = () => { const fieldContext = React.useContext(FormFieldContext); const itemContext = React.useContext(FormItemContext); const { getFieldState } = useFormContext(); const formState = useFormState({ name: fieldContext.name }); const fieldState = getFieldState(fieldContext.name, formState); if (!fieldContext) { throw new Error("useFormField should be used within "); } const { id } = itemContext; return { id, name: fieldContext.name, formItemId: `${id}-form-item`, formDescriptionId: `${id}-form-item-description`, formMessageId: `${id}-form-item-message`, ...fieldState, }; }; type FormItemContextValue = { id: string; }; const FormItemContext = React.createContext( {} as FormItemContextValue, ); function FormItem({ className, ...props }: React.ComponentProps<"div">) { const id = React.useId(); return (
); } function FormLabel({ className, required, ...props }: React.ComponentProps & { required?: boolean }) { const { error, formItemId } = useFormField(); return (
); } function FormControl({ ...props }: React.ComponentProps) { const { error, formItemId, formDescriptionId, formMessageId } = useFormField(); return ( ); } function FormDescription({ className, ...props }: React.ComponentProps<"p">) { const { formDescriptionId } = useFormField(); return (

); } function FormMessage({ className, ...props }: React.ComponentProps<"p">) { const { error, formMessageId } = useFormField(); const body = error ? String(error?.message ?? "") : props.children; if (!body) { return null; } return (

{body}

); } export { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useFormField, };