Reactive-Resume/apps/client/components/shared/ArrayInput.tsx

71 lines
2.0 KiB
TypeScript

import { Add, Delete } from '@mui/icons-material';
import { IconButton, InputAdornment, TextField } from '@mui/material';
import get from 'lodash/get';
import { useEffect, useState } from 'react';
import { FieldError } from 'react-hook-form';
import styles from './ArrayInput.module.scss';
type Props = {
value: string[];
label: string;
onChange: (event: any) => void;
errors: FieldError | FieldError[];
className?: string;
};
const ArrayInput: React.FC<Props> = ({ value, label, onChange, errors, className }) => {
const [items, setItems] = useState<string[]>(value);
const onAdd = () => setItems([...items, '']);
const onDelete = (index: number) => setItems(items.filter((_, idx) => idx !== index));
const handleChange = (event: React.ChangeEvent<HTMLInputElement>, index: number) => {
const tempItems = [...items];
tempItems[index] = event.target.value;
setItems(tempItems);
};
useEffect(() => {
onChange(items);
}, [onChange, items]);
return (
<div className={className}>
<header className={styles.header}>
<h3 className={styles.label}>
{label} <small>({items.length})</small>
</h3>
<IconButton onClick={onAdd}>
<Add />
</IconButton>
</header>
<div className={styles.inputGrid}>
{items.map((value, index) => (
<TextField
key={index}
value={value}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => handleChange(event, index)}
error={!!get(errors, index, false)}
helperText={get(errors, `${index}.message`, '')}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton edge="end" onClick={() => onDelete(index)} className={styles.delete}>
<Delete />
</IconButton>
</InputAdornment>
),
}}
/>
))}
</div>
</div>
);
};
export default ArrayInput;