# Frontend Horizontal Instructions
## Purpose
The Frontend horizontal defines the user interface components, user experience patterns, and client-side architecture for each vertical component. It ensures consistent, accessible, and performant user interfaces across the entire system.
## Content Requirements
### Required Sections
1. **Component Architecture**
- Component hierarchy and organization
- Reusable component library
- Design system implementation
- State management patterns
2. **User Interface Specifications**
- Layout and responsive design
- Visual design and styling
- Interaction patterns and animations
- Accessibility requirements (WCAG 2.1 AA)
3. **User Experience Flows**
- User journey mapping
- Navigation patterns
- Form design and validation
- Error handling and messaging
4. **Performance Optimization**
- Code splitting and lazy loading
- Asset optimization and caching
- Bundle size management
- Runtime performance monitoring
5. **Integration Patterns**
- API integration strategies
- Real-time data handling
- Authentication and authorization UI
- Third-party service integrations
### Documentation Format
```yaml
components:
UserRegistrationForm:
type: "form_component"
framework: "react"
dependencies: ["formik", "yup"]
props:
onSubmit:
type: "function"
required: true
description: "Callback function for form submission"
initialValues:
type: "object"
required: false
default: {}
description: "Initial form values"
state_management:
local_state: ["form_values", "validation_errors", "loading"]
global_state: ["user_session", "registration_status"]
accessibility:
keyboard_navigation: true
screen_reader_support: true
aria_labels: "Complete for all form elements"
focus_management: "Automatic focus on first error"
responsive_design:
breakpoints:
mobile: "320px - 767px"
tablet: "768px - 1023px"
desktop: "1024px+"
layout: "Single column on mobile, two column on desktop"
performance:
bundle_size: "< 50KB gzipped"
render_time: "< 100ms"
lazy_loading: true
```
## Validation Rules
### Quality Control
1. **User Experience Standards**
- All interactive elements must have hover/focus states
- Loading states must be provided for async operations
- Error messages must be clear and actionable
- Success feedback must be immediate and obvious
2. **Accessibility Compliance**
- WCAG 2.1 AA compliance mandatory
- Keyboard navigation support required
- Screen reader compatibility verified
- Color contrast ratios must meet standards
3. **Performance Requirements**
- First Contentful Paint < 1.5 seconds
- Largest Contentful Paint < 2.5 seconds
- Cumulative Layout Shift < 0.1
- First Input Delay < 100ms
4. **Code Quality**
- Component reusability > 80%
- Test coverage > 85%
- Bundle size budget compliance
- ESLint and TypeScript compliance
### Automated Checks
- Lighthouse performance audits
- Accessibility testing with axe-core
- Visual regression testing
- Bundle size analysis
- Component documentation validation
## Evolution Rules
### Across Verticals (Left to Right)
1. **Foundation → Core**
- Basic UI components evolve into rich interactive experiences
- Simple forms become complex multi-step workflows
- Static layouts become dynamic and personalized
2. **Core → Integration**
- Internal interfaces become external-facing portals
- Single-application UIs become federated experiences
- Synchronous interactions include real-time features
3. **Integration → Extension**
- Fixed UIs become customizable and themeable
- Standard interfaces support plugin architectures
- Monolithic frontends become micro-frontend capable
### UI Maturity Levels
- **Level 1**: Basic functional interface with minimal styling
- **Level 2**: Polished interface with design system consistency
- **Level 3**: Advanced UX with animations and micro-interactions
- **Level 4**: AI-enhanced interface with personalization
## Dependencies
### Upstream Dependencies
1. **Specs Horizontal**
- User experience requirements
- Functional specifications
- Accessibility requirements
- Performance requirements
2. **API Horizontal**
- Service interface contracts
- Authentication patterns
- Data schemas and types
- Error response formats
3. **Schema Horizontal**
- Data model definitions
- Validation rule specifications
- Type definitions for forms
### Downstream Dependencies
1. **Tests Horizontal**
- UI component testing strategies
- User interaction test scenarios
- Visual regression test baselines
2. **Backend Horizontal**
- API endpoint implementations
- Authentication service integration
- Real-time communication setup
## Best Practices
### Design System Implementation
1. **Component Library**
- Atomic design methodology (atoms, molecules, organisms)
- Consistent component API patterns
- Comprehensive component documentation
- Interactive component playground (Storybook)
2. **Design Tokens**
- Centralized design token management
- Consistent spacing, typography, and color systems
- Multi-theme support capability
- Design-developer handoff automation
3. **Accessibility-First Design**
- Semantic HTML structure
- Proper ARIA labeling
- Focus management strategies
- High contrast mode support
4. **Performance Optimization**
- Tree shaking and dead code elimination
- Image optimization and lazy loading
- Critical CSS extraction
- Service worker implementation
### Common Frontend Patterns
```typescript
// Component Pattern with TypeScript
interface UserCardProps {
user: User;
onEdit?: (user: User) => void;
onDelete?: (userId: string) => void;
showActions?: boolean;
}
const UserCard: React.FC<UserCardProps> = ({
user,
onEdit,
onDelete,
showActions = true
}) => {
const [isLoading, setIsLoading] = useState(false);
const { theme } = useTheme();
const handleEdit = useCallback(() => {
if (onEdit) {
onEdit(user);
}
}, [user, onEdit]);
const handleDelete = useCallback(async () => {
if (onDelete && window.confirm('Are you sure?')) {
setIsLoading(true);
try {
await onDelete(user.id);
} finally {
setIsLoading(false);
}
}
}, [user.id, onDelete]);
return (
<Card
className={`user-card ${theme}`}
role="article"
aria-labelledby={`user-${user.id}-name`}
>
<Avatar
src={user.avatar}
alt={`${user.name}'s profile picture`}
size="medium"
/>
<div className="user-info">
<h3 id={`user-${user.id}-name`}>{user.name}</h3>
<p className="user-email">{user.email}</p>
</div>
{showActions && (
<div className="user-actions">
<IconButton
icon="edit"
onClick={handleEdit}
aria-label={`Edit ${user.name}'s profile`}
disabled={isLoading}
/>
<IconButton
icon="delete"
onClick={handleDelete}
aria-label={`Delete ${user.name}'s profile`}
disabled={isLoading}
variant="danger"
/>
</div>
)}
{isLoading && (
<div className="loading-overlay" aria-live="polite">
<Spinner size="small" />
<span className="sr-only">Processing...</span>
</div>
)}
</Card>
);
};
// Custom Hook Pattern
const useUserRegistration = () => {
const [state, setState] = useState({
loading: false,
error: null,
success: false
});
const register = useCallback(async (userData: UserRegistrationData) => {
setState({ loading: true, error: null, success: false });
try {
const response = await api.users.register(userData);
setState({ loading: false, error: null, success: true });
return response;
} catch (error) {
setState({
loading: false,
error: error.message,
success: false
});
throw error;
}
}, []);
const reset = useCallback(() => {
setState({ loading: false, error: null, success: false });
}, []);
return {
...state,
register,
reset
};
};
// Form Handling Pattern
const UserRegistrationForm: React.FC = () => {
const { register, loading, error, success } = useUserRegistration();
const navigate = useNavigate();
const formik = useFormik({
initialValues: {
email: '',
password: '',
confirmPassword: '',
firstName: '',
lastName: '',
agreeToTerms: false
},
validationSchema: Yup.object({
email: Yup.string()
.email('Invalid email address')
.required('Email is required'),
password: Yup.string()
.min(8, 'Password must be at least 8 characters')
.matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/,
'Password must contain uppercase, lowercase, number, and special character')
.required('Password is required'),
confirmPassword: Yup.string()
.oneOf([Yup.ref('password')], 'Passwords must match')
.required('Confirm password is required'),
firstName: Yup.string()
.required('First name is required'),
lastName: Yup.string()
.required('Last name is required'),
agreeToTerms: Yup.boolean()
.oneOf([true], 'You must agree to the terms and conditions')
}),
onSubmit: async (values, { setSubmitting }) => {
try {
await register({
email: values.email,
password: values.password,
firstName: values.firstName,
lastName: values.lastName
});
navigate('/registration-success');
} catch (error) {
// Error handled by useUserRegistration hook
} finally {
setSubmitting(false);
}
}
});
return (
<Form onSubmit={formik.handleSubmit} noValidate>
<fieldset disabled={loading}>
<legend>Create Your Account</legend>
<div className="form-group">
<label htmlFor="email">Email Address *</label>
<input
id="email"
type="email"
{...formik.getFieldProps('email')}
aria-describedby={formik.errors.email ? 'email-error' : undefined}
aria-invalid={formik.errors.email && formik.touched.email}
/>
{formik.errors.email && formik.touched.email && (
<div id="email-error" className="field-error" role="alert">
{formik.errors.email}
</div>
)}
</div>
{/* Additional form fields... */}
<button
type="submit"
disabled={!formik.isValid || formik.isSubmitting || loading}
aria-describedby="submit-status"
>
{loading ? 'Creating Account...' : 'Create Account'}
</button>
<div id="submit-status" aria-live="polite">
{error && (
<div className="error-message" role="alert">
{error}
</div>
)}
{success && (
<div className="success-message" role="alert">
Account created successfully!
</div>
)}
</div>
</fieldset>
</Form>
);
};
```
## State Management Patterns
### Context + Reducer Pattern
```typescript
// User Context
interface UserState {
user: User | null;
loading: boolean;
error: string | null;
}
type UserAction =
| { type: 'LOGIN_START' }
| { type: 'LOGIN_SUCCESS'; payload: User }
| { type: 'LOGIN_ERROR'; payload: string }
| { type: 'LOGOUT' };
const userReducer = (state: UserState, action: UserAction): UserState => {
switch (action.type) {
case 'LOGIN_START':
return { ...state, loading: true, error: null };
case 'LOGIN_SUCCESS':
return { ...state, user: action.payload, loading: false, error: null };
case 'LOGIN_ERROR':
return { ...state, loading: false, error: action.payload };
case 'LOGOUT':
return { user: null, loading: false, error: null };
default:
return state;
}
};
const UserProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [state, dispatch] = useReducer(userReducer, {
user: null,
loading: false,
error: null
});
const login = useCallback(async (credentials: LoginCredentials) => {
dispatch({ type: 'LOGIN_START' });
try {
const user = await authAPI.login(credentials);
dispatch({ type: 'LOGIN_SUCCESS', payload: user });
} catch (error) {
dispatch({ type: 'LOGIN_ERROR', payload: error.message });
}
}, []);
const logout = useCallback(() => {
authAPI.logout();
dispatch({ type: 'LOGOUT' });
}, []);
return (
<UserContext.Provider value={{ ...state, login, logout }}>
{children}
</UserContext.Provider>
);
};
```
## Testing Strategies
### Component Testing
```typescript
// Unit Test Example
describe('UserCard Component', () => {
const mockUser: User = {
id: '1',
name: 'John Doe',
email: 'john@example.com',
avatar: '/avatars/john.jpg'
};
it('renders user information correctly', () => {
render(<UserCard user={mockUser} />);
expect(screen.getByRole('article')).toBeInTheDocument();
expect(screen.getByText('John Doe')).toBeInTheDocument();
expect(screen.getByText('john@example.com')).toBeInTheDocument();
});
it('calls onEdit when edit button is clicked', async () => {
const onEdit = jest.fn();
render(<UserCard user={mockUser} onEdit={onEdit} />);
const editButton = screen.getByRole('button', { name: /edit.*profile/i });
await user.click(editButton);
expect(onEdit).toHaveBeenCalledWith(mockUser);
});
it('meets accessibility requirements', async () => {
const { container } = render(<UserCard user={mockUser} />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
});
// Integration Test Example
describe('User Registration Flow', () => {
it('allows user to complete registration', async () => {
const mockRegister = jest.fn().mockResolvedValue({ success: true });
render(
<MemoryRouter>
<UserRegistrationForm />
</MemoryRouter>
);
// Fill form
await user.type(screen.getByLabelText(/email/i), 'test@example.com');
await user.type(screen.getByLabelText(/^password/i), 'SecurePass123!');
await user.type(screen.getByLabelText(/confirm password/i), 'SecurePass123!');
await user.type(screen.getByLabelText(/first name/i), 'John');
await user.type(screen.getByLabelText(/last name/i), 'Doe');
await user.click(screen.getByRole('checkbox', { name: /agree to terms/i }));
// Submit form
await user.click(screen.getByRole('button', { name: /create account/i }));
// Verify submission
expect(mockRegister).toHaveBeenCalledWith({
email: 'test@example.com',
password: 'SecurePass123!',
firstName: 'John',
lastName: 'Doe'
});
});
});
```
## Integration Guidelines
### API Integration
```typescript
// API Client Pattern
class APIClient {
private baseURL: string;
private token: string | null = null;
constructor(baseURL: string) {
this.baseURL = baseURL;
}
setAuthToken(token: string) {
this.token = token;
}
private async request<T>(
endpoint: string,
options: RequestInit = {}
): Promise<T> {
const url = `${this.baseURL}${endpoint}`;
const config: RequestInit = {
headers: {
'Content-Type': 'application/json',
...(this.token && { Authorization: `Bearer ${this.token}` }),
...options.headers
},
...options
};
const response = await fetch(url, config);
if (!response.ok) {
const error = await response.json().catch(() => ({
message: 'Unknown error occurred'
}));
throw new APIError(error.message, response.status);
}
return response.json();
}
// Resource methods
users = {
create: (data: CreateUserData) =>
this.request<User>('/users', {
method: 'POST',
body: JSON.stringify(data)
}),
getById: (id: string) =>
this.request<User>(`/users/${id}`),
update: (id: string, data: Partial<User>) =>
this.request<User>(`/users/${id}`, {
method: 'PUT',
body: JSON.stringify(data)
}),
delete: (id: string) =>
this.request<void>(`/users/${id}`, { method: 'DELETE' })
};
}
```
### Tools and Frameworks
- **Frameworks**: React, Vue.js, Angular, Svelte
- **State Management**: Redux Toolkit, Zustand, Valtio, Context API
- **Styling**: Styled Components, Emotion, Tailwind CSS, CSS Modules
- **Testing**: Jest, React Testing Library, Cypress, Playwright
- **Build Tools**: Vite, Webpack, Parcel, esbuild
- **Documentation**: Storybook, Docusaurus, Styleguidist
- **Performance**: Lighthouse, Web Vitals, Bundle Analyzer