FormTextareaArray.tsx
1 import { 2 Box, 3 FormControl, 4 FormErrorMessage, 5 FormLabel, 6 FormHelperText, 7 Textarea, 8 FormControlProps, 9 } from '@chakra-ui/react'; 10 import { Controller, UseFormReturn, FieldError } from 'react-hook-form'; 11 12 interface FormTextareaArrayProps { 13 name: string; 14 label: string; 15 defaultValue?: number; 16 description?: string; 17 hint?: string; 18 // @todo: fix type 19 control: UseFormReturn['control'] | any; 20 controlVariant?: FormControlProps['variant']; 21 } 22 23 function formatErrors(errors: FieldError[]): string | null { 24 if (!errors || !errors.length) return null; 25 const unique = errors.reduce((acc, curr) => { 26 if (!curr.message) return acc; 27 if (!acc[curr.message]) acc[curr.message] = 1; 28 else acc[curr.message] += 1; 29 return acc; 30 }, {} as { [key: string]: number }); 31 const str = Object.entries(unique).reduce((acc, [message, count], i) => { 32 if (i === 0) return `${message} (${count})`; 33 return acc + '\n' + `${message} (${count})`; 34 }, ''); 35 return str; 36 } 37 38 const FormTextareaArray = ({ 39 name, 40 label, 41 hint, 42 control, 43 controlVariant, 44 }: FormTextareaArrayProps) => { 45 return ( 46 <Box maxW={680} mb={10}> 47 <Controller 48 control={control} 49 name={name} 50 render={({ 51 field: { onChange, onBlur, value, name, ref }, 52 fieldState: { error }, 53 }) => { 54 return ( 55 <FormControl mt={2} isInvalid={!!error} variant={controlVariant}> 56 <FormLabel htmlFor={name}>{label}</FormLabel> 57 <FormHelperText>{hint}</FormHelperText> 58 <Box 59 display="flex" 60 flexDirection="row" 61 mt={3} 62 alignItems="center" 63 > 64 <Textarea 65 size="md" 66 colorScheme="green" 67 onBlur={onBlur} 68 onChange={(e) => { 69 onBlur(); 70 onChange(e.target.value.split('\n')); 71 }} 72 ref={ref} 73 value={Array.isArray(value) ? value.join('\n') : []} 74 name={name} 75 /> 76 </Box> 77 <FormErrorMessage whiteSpace="pre-line"> 78 {error?.message 79 ? error.message 80 : (error as unknown as FieldError[])?.length 81 ? formatErrors(error as unknown as FieldError[]) 82 : null} 83 </FormErrorMessage> 84 </FormControl> 85 ); 86 }} 87 /> 88 </Box> 89 ); 90 }; 91 92 export default FormTextareaArray;