| import React from 'react'; |
| import type { ControllerRenderProps, FieldValues, FieldPath } from 'react-hook-form'; |
| import { Label } from './Label'; |
| import { Input } from './Input'; |
| import { cn } from '~/utils'; |
|
|
| export default function FormInput< |
| TFieldValues extends FieldValues = FieldValues, |
| TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, |
| >({ |
| field, |
| label, |
| labelClass, |
| inputClass, |
| containerClass, |
| labelAdjacent, |
| placeholder = '', |
| type = 'string', |
| }: { |
| field: ControllerRenderProps<TFieldValues, TName>; |
| label: string; |
| labelClass?: string; |
| inputClass?: string; |
| placeholder?: string; |
| containerClass?: string; |
| type?: 'string' | 'number'; |
| labelAdjacent?: React.ReactNode; |
| }) { |
| const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { |
| const value = e.target.value; |
|
|
| if (type !== 'number') { |
| field.onChange(value); |
| return; |
| } |
|
|
| if (value === '') { |
| field.onChange(value); |
| } else if (!isNaN(Number(value))) { |
| field.onChange(Number(value)); |
| } |
| }; |
|
|
| return ( |
| <div className={cn('flex w-full flex-col items-center gap-2', containerClass)}> |
| <div className="flex w-full items-center justify-start gap-2"> |
| <Label |
| htmlFor={`${field.name}-input`} |
| className={cn('text-left text-sm font-semibold text-text-primary', labelClass)} |
| > |
| {label} |
| </Label> |
| {labelAdjacent} |
| </div> |
| <Input |
| id={`${field.name}-input`} |
| value={field.value ?? ''} |
| onChange={handleChange} |
| placeholder={placeholder} |
| className={cn( |
| 'flex h-10 max-h-10 w-full resize-none border-none bg-surface-secondary px-3 py-2', |
| inputClass, |
| )} |
| /> |
| </div> |
| ); |
| } |
|
|