import { cn } from "@/lib/utils"; import { HTMLInputAutoCompleteAttribute, type HTMLInputTypeAttribute, useId, } from "react"; import { type FieldErrors, type FieldValues, type Path, type UseFormRegister, type UseFormRegisterReturn, } from "react-hook-form"; type InputGroupProps = { name: Path; label: string; type: HTMLInputTypeAttribute; placeholder: string; className?: string; fileStyleVariant?: "style1" | "style2"; required?: boolean; disabled?: boolean; active?: boolean; handleChange?: (e: React.ChangeEvent) => void; value?: string; icon?: React.ReactNode; iconPosition?: "left" | "right"; height?: "sm" | "default"; autoComplete?: HTMLInputAutoCompleteAttribute; defaultValue?: string; register?: UseFormRegister; errors?: FieldErrors; } & Partial; const InputGroup = ({ className, label, type, placeholder, required, disabled, active, handleChange, icon, name, register, errors, autoComplete, onChange, onBlur, ref, ...props }: InputGroupProps): React.ReactElement => { const id = useId(); const error = errors && errors[name]; return ( {label} {required && *} { onChange?.(e); handleChange?.(e); }} onBlur={onBlur} {...(!onChange && props.value !== undefined && { value: props.value })} {...(!onChange && props.defaultValue !== undefined && { defaultValue: props.defaultValue, })} className={cn( "w-full rounded-lg border-[1.5px] border-stroke bg-transparent outline-none transition focus:border-primary disabled:cursor-default disabled:bg-gray-2 data-[active=true]:border-primary dark:border-dark-3 dark:bg-dark-2 dark:focus:border-primary dark:disabled:bg-dark dark:data-[active=true]:border-primary", // Add error styles conditionally error && "border-red focus:border-red dark:border-red", type === "file" ? getFileStyles(props.fileStyleVariant!) : "px-5.5 py-3 text-dark placeholder:text-dark-6 dark:text-white", props.iconPosition === "left" && "pl-12.5", props.height === "sm" && "py-2.5", )} disabled={disabled} data-active={active} /> {icon} {error && ( {error.message as string} )} ); }; export default InputGroup; function getFileStyles(variant: "style1" | "style2") { switch (variant) { case "style1": return `file:mr-5 file:border-collapse file:cursor-pointer file:border-0 file:border-r file:border-solid file:border-stroke file:bg-[#E2E8F0] file:px-6.5 file:py-[13px] file:text-body-sm file:font-medium file:text-dark-5 file:hover:bg-primary file:hover:bg-opacity-10 dark:file:border-dark-3 dark:file:bg-white/30 dark:file:text-white`; default: return `file:mr-4 file:rounded file:border-[0.5px] file:border-stroke file:bg-stroke file:px-2.5 file:py-1 file:text-body-xs file:font-medium file:text-dark-5 file:focus:border-primary dark:file:border-dark-3 dark:file:bg-white/30 dark:file:text-white px-3 py-[9px]`; } }
{error.message as string}