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 66 | 1x 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;
|