making login page beautiful
This commit is contained in:
99
src/components/FormField.tsx
Normal file
99
src/components/FormField.tsx
Normal file
@ -0,0 +1,99 @@
|
||||
import React, { useState } from 'react';
|
||||
import './FormField.css';
|
||||
|
||||
|
||||
interface FormFieldProperties {
|
||||
type?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search';
|
||||
placeholder?: string;
|
||||
value: string;
|
||||
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
required?: boolean;
|
||||
errorMessage?: string;
|
||||
showError?: boolean;
|
||||
onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;
|
||||
onFocus?: (e: React.FocusEvent<HTMLInputElement>) => void;
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
autoComplete?: string;
|
||||
customValidator?: (value: string) => string | null;
|
||||
showErrorInitially?: boolean;
|
||||
icon?: React.ComponentType<React.SVGProps<SVGSVGElement>>;
|
||||
}
|
||||
|
||||
|
||||
const FormField: React.FC<FormFieldProperties> = ({
|
||||
type = 'text',
|
||||
placeholder,
|
||||
value,
|
||||
onChange,
|
||||
required = false,
|
||||
errorMessage = 'Please fill out this field',
|
||||
showError = false,
|
||||
onBlur,
|
||||
onFocus,
|
||||
className = '',
|
||||
disabled = false,
|
||||
autoComplete = 'off',
|
||||
customValidator,
|
||||
showErrorInitially = false,
|
||||
icon: Icon,
|
||||
}) => {
|
||||
const [touched, setTouched] = useState<boolean>(showErrorInitially);
|
||||
const [customError, setCustomError] = useState<string>('');
|
||||
|
||||
const validateField = (value: string): string => {
|
||||
if (required && !value) {
|
||||
return errorMessage;
|
||||
}
|
||||
if (customValidator) {
|
||||
const customValidation = customValidator(value);
|
||||
if (customValidation) {
|
||||
return customValidation;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
const shouldShowError = showError || (touched && validateField(value));
|
||||
|
||||
const handleBlur = (e: React.FocusEvent<HTMLInputElement>): void => {
|
||||
setTouched(true);
|
||||
const error = validateField(value);
|
||||
setCustomError(error);
|
||||
onBlur?.(e);
|
||||
};
|
||||
|
||||
const handleFocus = (e: React.FocusEvent<HTMLInputElement>): void => {
|
||||
setCustomError('');
|
||||
onFocus?.(e);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`form-field ${className}`}>
|
||||
{Icon && (
|
||||
<div className="field-icon">
|
||||
<Icon />
|
||||
</div>
|
||||
)}
|
||||
<input
|
||||
type={type}
|
||||
placeholder={placeholder}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
onBlur={handleBlur}
|
||||
onFocus={handleFocus}
|
||||
required={required}
|
||||
disabled={disabled}
|
||||
autoComplete={autoComplete}
|
||||
className={shouldShowError ? 'error' : ''}
|
||||
/>
|
||||
{shouldShowError && (
|
||||
<div className="error-message">
|
||||
{customError || errorMessage}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FormField;
|
||||
Reference in New Issue
Block a user