57 lines
1.7 KiB
TypeScript
57 lines
1.7 KiB
TypeScript
import { type ChangeEvent, type Dispatch, type SetStateAction, type TextareaHTMLAttributes } from "react";
|
|
import type { CreateRecipeFormDirtyEntries } from "../../pages/Create";
|
|
|
|
interface RecipeCreateFormInputProps
|
|
extends Omit<
|
|
TextareaHTMLAttributes<HTMLTextAreaElement>,
|
|
"value" | "onChange" | "name" | "type" | "placeholder" | "required"
|
|
> {
|
|
label: string;
|
|
name: string;
|
|
desc: string;
|
|
placeholder: string;
|
|
required?: boolean;
|
|
valid: boolean;
|
|
value: string;
|
|
setValue: Dispatch<SetStateAction<string>>;
|
|
setDirty: Dispatch<SetStateAction<CreateRecipeFormDirtyEntries>>;
|
|
error: string;
|
|
parentClasses?: string;
|
|
classes: string;
|
|
};
|
|
|
|
export default function RecipeCreateFormTextArea({ label, name, desc, placeholder, required = false, valid, value, setDirty, setValue, error, parentClasses = "", classes, ...inputProps }: RecipeCreateFormInputProps) {
|
|
const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
|
|
setDirty(prev => ({ ...prev, [name]: true }));
|
|
setValue(e.target.value);
|
|
}
|
|
|
|
return (
|
|
<div className={`flex flex-col ${parentClasses}`}>
|
|
<label htmlFor={name} className="text-sm">
|
|
{label}
|
|
{required && <span className="text-red-500">*</span>}
|
|
</label>
|
|
<p className="text-xs pt-1 pb-2 text-gray-700">
|
|
{desc}
|
|
</p>
|
|
<textarea
|
|
className={`${!valid ? "border-red-500" : ""} ${classes}`}
|
|
name={name}
|
|
value={value}
|
|
onChange={handleChange}
|
|
required={required}
|
|
placeholder={placeholder}
|
|
{...inputProps}
|
|
/>
|
|
{!valid && (
|
|
<p className="text-xs text-red-500 my-1">
|
|
{error}
|
|
</p>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
|