Files
aggios.app/front-end-dash.aggios.app/components/ui/Input.tsx

106 lines
3.9 KiB
TypeScript

"use client";
import { InputHTMLAttributes, forwardRef, useState } from "react";
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
helperText?: string;
leftIcon?: string;
rightIcon?: string;
onRightIconClick?: () => void;
}
const Input = forwardRef<HTMLInputElement, InputProps>(
(
{
label,
error,
helperText,
leftIcon,
rightIcon,
onRightIconClick,
className = "",
type,
...props
},
ref
) => {
const [showPassword, setShowPassword] = useState(false);
const isPassword = type === "password";
const inputType = isPassword ? (showPassword ? "text" : "password") : type;
return (
<div className="w-full">
{label && (
<label className="block text-[13px] font-semibold text-[#000000] dark:text-white mb-2">
{label}
{props.required && <span className="text-[#FF3A05] ml-1">*</span>}
</label>
)}
<div className="relative">
{leftIcon && (
<i
className={`${leftIcon} absolute left-3.5 top-1/2 -translate-y-1/2 text-[#7D7D7D] dark:text-gray-400 text-[20px]`}
/>
)}
<input
ref={ref}
type={inputType}
className={`
w-full px-3.5 py-3 text-[14px] font-normal
border rounded-md bg-white dark:bg-gray-700 dark:text-white
placeholder:text-[#7D7D7D] dark:placeholder:text-gray-400
transition-all
${leftIcon ? "pl-11" : ""}
${isPassword || rightIcon ? "pr-11" : ""}
${error
? "border-[#FF3A05]"
: "border-[#E5E5E5] dark:border-gray-600 focus:border-[#FF3A05]"
}
outline-none ring-0 focus:ring-0 shadow-none focus:shadow-none
disabled:bg-[#E5E5E5]/30 disabled:cursor-not-allowed
${className}
`}
{...props}
/>
{isPassword && (
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute right-3.5 top-1/2 -translate-y-1/2 text-[#7D7D7D] hover:text-[#000000] transition-colors cursor-pointer"
>
<i
className={`${showPassword ? "ri-eye-off-line" : "ri-eye-line"} text-[20px]`}
/>
</button>
)}
{!isPassword && rightIcon && (
<button
type="button"
onClick={onRightIconClick}
className="absolute right-3.5 top-1/2 -translate-y-1/2 text-[#7D7D7D] hover:text-[#000000] transition-colors cursor-pointer"
>
<i className={`${rightIcon} text-[20px]`} />
</button>
)}
</div>
{error && (
<p className="mt-1 text-[13px] text-[#FF3A05] flex items-center gap-1">
<i className="ri-error-warning-line" />
{error}
</p>
)}
{helperText && !error && (
<p className="mt-1 text-[13px] text-[#7D7D7D]">{helperText}</p>
)}
</div>
);
}
);
Input.displayName = "Input";
export default Input;