Exercise 1: Component Composition
Objective
Practice building reusable components using composition patterns.
Task
Build a card component system with proper composition.
Requirements
1. Create a Card Component System
// Create these components:
// - Card (container)
// - Card.Header
// - Card.Body
// - Card.Footer
// - Card.Image
// Example usage:
<Card>
<Card.Image src='...' alt='...' />
<Card.Header>
<h2>Title</h2>
</Card.Header>
<Card.Body>
<p>Content goes here</p>
</Card.Body>
<Card.Footer>
<button>Action</button>
</Card.Footer>
</Card>
2. Features
- Support variants:
default,bordered,elevated - Support sizes:
sm,md,lg - Optional image at top
- Flexible content areas
- TypeScript types
3. Implementation Guidelines
Card.tsx
interface CardProps {
variant?: 'default' | 'bordered' | 'elevated';
size?: 'sm' | 'md' | 'lg';
children: React.ReactNode;
className?: string;
}
// Implement Card and sub-components
Solution Structure
src/
├── components/
│ └── Card/
│ ├── Card.tsx
│ ├── Card.module.css
│ └── index.ts
└── App.tsx
Testing Your Solution
Create example usage in App.tsx:
function App() {
return (
<div className='app'>
<Card variant='elevated' size='md'>
<Card.Image src='/profile.jpg' alt='Profile' />
<Card.Header>
<h2>John Doe</h2>
<p>Software Developer</p>
</Card.Header>
<Card.Body>
<p>Passionate about building great user experiences...</p>
</Card.Body>
<Card.Footer>
<button>View Profile</button>
<button>Message</button>
</Card.Footer>
</Card>
</div>
);
}
Bonus Challenges
- Add hover effects
- Make the card clickable (entire card as link)
- Add a loading state with skeleton
- Support horizontal layout
- Add close button functionality
Hints
- Use Context API for sharing variant/size with sub-components
- Use CSS modules or styled-components for styling
- Export sub-components as properties:
Card.Header,Card.Body, etc.
Time Estimate
2-3 hours