import * as LabelPrimitive from '@radix-ui/react-label'
import { Slot } from '@radix-ui/react-slot'
import * as React from 'react'
import { Label } from '@/components/ui/label'
import { cn } from '@/lib/utils'
const Form = FormProvider
type FormFieldContextValue<
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
const FormFieldContext = React.createContext<FormFieldContextValue>(
{} as FormFieldContextValue,
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
}: ControllerProps<TFieldValues, TName>) => {
<FormFieldContext.Provider value={{ name: props.name }}>
<Controller {...props} />
</FormFieldContext.Provider>
const useFormField = () => {
const fieldContext = React.useContext(FormFieldContext)
const itemContext = React.useContext(FormItemContext)
const { getFieldState, formState } = useFormContext()
const fieldState = getFieldState(fieldContext.name, formState)
throw new Error('useFormField should be used within <FormField>')
const { id } = itemContext
formItemId: `${id}-form-item`,
formDescriptionId: `${id}-form-item-description`,
formMessageId: `${id}-form-item-message`,
type FormItemContextValue = {
const FormItemContext = React.createContext<FormItemContextValue>(
{} as FormItemContextValue,
const FormItem = React.forwardRef<
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => {
<FormItemContext.Provider value={{ id }}>
<div ref={ref} className={cn('space-y-2', className)} {...props} />
</FormItemContext.Provider>
FormItem.displayName = 'FormItem'
const FormLabel = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
>(({ className, ...props }, ref) => {
const { error, formItemId } = useFormField()
className={cn(error && 'text-red-500 font-base', className)}
FormLabel.displayName = 'FormLabel'
const FormControl = React.forwardRef<
React.ElementRef<typeof Slot>,
React.ComponentPropsWithoutRef<typeof Slot>
>(({ ...props }, ref) => {
const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
: `${formDescriptionId} ${formMessageId}`
FormControl.displayName = 'FormControl'
const FormDescription = React.forwardRef<
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => {
const { formDescriptionId } = useFormField()
'text-sm font-base text-text dark:text-darkText',
FormDescription.displayName = 'FormDescription'
const FormMessage = React.forwardRef<
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, children, ...props }, ref) => {
const { error, formMessageId } = useFormField()
const body = error ? String(error?.message) : children
className={cn('text-sm font-base text-red-500', className)}
FormMessage.displayName = 'FormMessage'