import React, { forwardRef, useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { AlertCircle, Eye, EyeOff } from 'lucide-react'; import PropTypes from 'prop-types'; const Input = forwardRef(({ label, type = 'text', placeholder, value, onChange, onBlur, onFocus, error, helperText, required = false, disabled = false, size = 'md', icon, iconPosition = 'left', className = '', ...props }, ref) => { const [focused, setFocused] = useState(false); const [showPassword, setShowPassword] = useState(false); const inputType = type === 'password' && showPassword ? 'text' : type; const baseClasses = 'w-full rounded-lg border transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-1 text-base sm:text-sm md:text-base'; const sizes = { sm: 'px-3 py-2 text-sm min-h-[40px]', md: 'px-4 py-3 text-base min-h-[48px] sm:py-2.5 sm:min-h-[44px]', lg: 'px-5 py-4 text-lg min-h-[52px] sm:py-3 sm:min-h-[48px]', }; const stateClasses = error ? 'border-error-300 focus:border-error-500 focus:ring-error-500/20' : focused ? 'border-primary-300 focus:border-primary-500 focus:ring-primary-500/20' : 'border-neutral-300 hover:border-neutral-400'; const disabledClasses = disabled ? 'bg-base-200 text-neutral-500 cursor-not-allowed' : 'bg-base-100 text-neutral-900 dark:text-neutral-100'; const iconClasses = icon ? (iconPosition === 'left' ? 'pl-10' : 'pr-10') : ''; const passwordToggleClasses = type === 'password' ? 'pr-10' : ''; const inputClasses = ` ${baseClasses} ${sizes[size]} ${stateClasses} ${disabledClasses} ${iconClasses} ${passwordToggleClasses} ${className} `.trim(); const handleFocus = (e) => { setFocused(true); onFocus?.(e); }; const handleBlur = (e) => { setFocused(false); onBlur?.(e); }; return (
{label && ( {label} {required && *} )}
{icon && (
{icon}
)} {type === 'password' && ( )}
{(error || helperText) && ( {error && } {error || helperText} )}
); }); Input.displayName = 'Input'; Input.propTypes = { label: PropTypes.string, type: PropTypes.string, placeholder: PropTypes.string, value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), onChange: PropTypes.func, onBlur: PropTypes.func, onFocus: PropTypes.func, error: PropTypes.string, helperText: PropTypes.string, required: PropTypes.bool, disabled: PropTypes.bool, size: PropTypes.oneOf(['sm', 'md', 'lg']), icon: PropTypes.node, iconPosition: PropTypes.oneOf(['left', 'right']), className: PropTypes.string, }; export default Input;