Skip to main content

Task 10: Implement Email Input with Validation

Role

Frontend

Overview

Implement a robust email input field with real-time validation, error messaging, and user-friendly feedback to ensure users enter valid email addresses before attempting authentication.

Objectives

  • Create a controlled email input component
  • Implement real-time email format validation
  • Display clear error messages for invalid input
  • Provide visual feedback (success/error states)
  • Ensure accessibility standards are met

Technical Requirements

Input Component Specifications

interface EmailInputProps {
value: string;
onChange: (value: string) => void;
onBlur?: () => void;
error?: string;
disabled?: boolean;
placeholder?: string;
}

Validation Rules

  1. Required Field: Email cannot be empty
  2. Format Validation: Must match valid email pattern
  3. Domain Validation: Must include '@' and valid domain
  4. Length Limits:
    • Minimum: 5 characters
    • Maximum: 254 characters (RFC 5321)

Email Regex Pattern

const EMAIL_REGEX = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;

function validateEmail(email: string): boolean {
if (!email) return false;
if (email.length < 5 || email.length > 254) return false;
return EMAIL_REGEX.test(email);
}

Implementation Steps

1. Create Email Input Component

import React, { useState } from "react";

export function EmailInput({
value,
onChange,
onBlur,
error,
disabled,
}: EmailInputProps) {
const [touched, setTouched] = useState(false);

const handleBlur = () => {
setTouched(true);
onBlur?.();
};

return (
<div className="email-input-container">
<label htmlFor="email" className="input-label">
Email address
</label>
<input
id="email"
type="email"
value={value}
onChange={(e) => onChange(e.target.value)}
onBlur={handleBlur}
disabled={disabled}
placeholder="client01@micdots.com"
aria-invalid={touched && !!error}
aria-describedby={error ? "email-error" : undefined}
className={`email-input ${error && touched ? "error" : ""}`}
/>
{touched && error && (
<span id="email-error" className="error-message" role="alert">
{error}
</span>
)}
</div>
);
}

2. Validation Logic

export function getEmailError(email: string): string | undefined {
if (!email) {
return "Email is required";
}

if (email.length < 5) {
return "Email is too short";
}

if (email.length > 254) {
return "Email is too long";
}

if (!EMAIL_REGEX.test(email)) {
return "Please enter a valid email address";
}

return undefined;
}

3. Visual States

/* Default State */
.email-input {
width: 100%;
height: 48px;
padding: 0 16px;
background: #1a1f2e;
border: 1px solid #3a4057;
border-radius: 8px;
color: #ffffff;
font-size: 15px;
transition: border-color 0.2s;
}

/* Focus State */
.email-input:focus {
outline: none;
border-color: #4d7cfe;
box-shadow: 0 0 0 3px rgba(77, 124, 254, 0.1);
}

/* Error State */
.email-input.error {
border-color: #ef4444;
}

/* Error Message */
.error-message {
display: block;
margin-top: 8px;
color: #ef4444;
font-size: 13px;
}

Error Messages

ScenarioError Message
Empty field"Email is required"
Too short"Email is too short"
Too long"Email is too long"
Invalid format"Please enter a valid email address"
Missing @"Email must include @"
Invalid domain"Please enter a valid email domain"

Acceptance Criteria

  • Email input field renders correctly
  • Real-time validation on blur event
  • Error messages display for invalid input
  • Success state shows for valid email
  • Keyboard navigation works (Tab, Enter)
  • Screen reader announces errors correctly
  • Copy/paste functionality works
  • Auto-complete is enabled
  • Validation works for edge cases:
    • Multiple @ symbols
    • Special characters
    • Unicode characters
    • Whitespace handling
  • Component is accessible (WCAG 2.1 AA)

Testing Checklist

Unit Tests

describe("EmailInput", () => {
test("validates correct email format", () => {
expect(validateEmail("user@example.com")).toBe(true);
});

test("rejects invalid email format", () => {
expect(validateEmail("invalid-email")).toBe(false);
});

test("shows error message on invalid input", () => {
// Test implementation
});
});

Manual Testing

  • Test with valid emails (various formats)
  • Test with invalid emails (missing @, no domain)
  • Test edge cases (very long emails, special chars)
  • Test copy/paste behavior
  • Test screen reader experience
  • Test keyboard navigation

Estimated Time

4 hours

Dependencies

  • Task 08: Set up login page route (must be completed first)
  • Task 09: Create Login component structure (must be completed first)
  • Task 11: Implement Password Input with Toggle (Coming Soon)
  • Task 12: Add Client-Side Form Validation (Coming Soon)
  • Task 14: Add Error Message Display (Coming Soon)
  • Task 17: Add Accessibility Features (Coming Soon)

External Resources