Files
2026-08-25 23:47:33 +05:30

64 lines
1.5 KiB
TypeScript

'use client'
import {
Controller,
type FieldValues,
type FieldPath,
type Control,
type ControllerRenderProps,
type FieldError,
} from 'react-hook-form'
import {
Field,
FieldLabel,
FieldDescription,
FieldError as FieldErrorDisplay,
} from '@/components/ui/field'
interface FormFieldProps<T extends FieldValues, TName extends FieldPath<T> = FieldPath<T>> {
control: Control<T>
name: TName
label?: string
description?: string
required?: boolean
render: (props: {
field: ControllerRenderProps<T, TName>
error?: FieldError
invalid: boolean
}) => React.ReactNode
}
export function FormField<T extends FieldValues, TName extends FieldPath<T> = FieldPath<T>>({
control,
name,
label,
description,
required,
render,
}: FormFieldProps<T>) {
return (
<Controller
control={control}
name={name}
render={({ field, fieldState }) => (
<Field data-invalid={fieldState.invalid || undefined}>
{label && (
<FieldLabel htmlFor={String(name)}>
{label}
{required && <span className="text-destructive"> *</span>}
</FieldLabel>
)}
{render({ field, error: fieldState.error, invalid: fieldState.invalid })}
{description && !fieldState.error && (
<FieldDescription>{description}</FieldDescription>
)}
{fieldState.error && (
<FieldErrorDisplay errors={[fieldState.error]} />
)}
</Field>
)}
/>
)
}