All files / frontend/src/components Input.tsx

87.5% Statements 42/48
86.66% Branches 13/15
100% Functions 0/0
87.5% Lines 42/48

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 661x 1x 1x                 1x 1x   5x 5x 5x   5x 5x 5x 4x 4x 4x 4x   5x 5x         5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 3x 3x 3x   5x         5x   5x 1x   1x   1x  
import React from 'react';
import classNames from 'classnames';
import './Input.css';
 
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
    label?: string;
    error?: string;
    helperText?: string;
    icon?: React.ReactNode;
}
 
const Input = React.forwardRef<HTMLInputElement, InputProps>(
    ({ label, error, helperText, icon, className, id, required, ...props }, ref) => {
        // Generate a unique ID if not provided
        const inputId = id || `input-${Math.random().toString(36).substr(2, 9)}`;
        const errorId = error ? `${inputId}-error` : undefined;
        const helperId = helperText ? `${inputId}-helper` : undefined;
 
        return (
            <div className="input-wrapper">
                {label && (
                    <label htmlFor={inputId} className="input-label">
                        {label}
                        {required && <span className="text-red-500 ml-1" aria-label="required">*</span>}
                    </label>
                )}
                <div className="input-container">
                    {icon && (
                        <div className="input-icon" aria-hidden="true">
                            {icon}
                        </div>
                    )}
                    <input
                        ref={ref}
                        id={inputId}
                        className={classNames(
                            'input-field',
                            { 'input-field-with-icon': !!icon },
                            { 'input-field-error': !!error },
                            className
                        )}
                        aria-invalid={error ? 'true' : 'false'}
                        aria-describedby={error ? errorId : helperId}
                        aria-required={required}
                        {...props}
                    />
                </div>
                {error && (
                    <p id={errorId} className="input-error-text" role="alert">
                        {error}
                    </p>
                )}
                {helperText && !error && (
                    <p id={helperId} className="input-helper-text">
                        {helperText}
                    </p>
                )}
            </div>
        );
    }
);
 
Input.displayName = 'Input';
 
export default Input;