Implement a Versatile Avatar Component in React
This challenge focuses on building a reusable and flexible Avatar component in React using TypeScript. A well-designed Avatar component is crucial for user interfaces, allowing for consistent display of user identities, whether through images, initials, or placeholders.
Problem Description
You are tasked with creating a React component named Avatar that can display a user's avatar in various ways. The component should be configurable to handle different avatar sources and provide fallback mechanisms.
Key Requirements:
- Image Display: The component should accept an
imageUrlprop to display an image. - Initials Display: If no
imageUrlis provided, it should display the user's initials. The initials should be derived from anameprop. - Fallback: If both
imageUrlandnameare missing, or if theimageUrlfails to load, a default fallback placeholder should be displayed. - Size Control: The component should allow control over its size using a
sizeprop (e.g., 'small', 'medium', 'large'). - Styling: The component should be styled to appear as a circular image/placeholder.
- Accessibility: Ensure the component is accessible, especially when displaying images.
Expected Behavior:
- If
imageUrlis provided and the image loads successfully, display the image. - If
imageUrlis not provided or fails to load, andnameis provided, display the first two uppercase letters of thename. - If neither
imageUrlnornameis provided, or ifnameis an empty string, display a generic fallback icon. - The
sizeprop should adjust the dimensions of the avatar container and the content within it.
Edge Cases to Consider:
nameprop is an empty string or contains only whitespace.imageUrlis an invalid URL or points to a broken image.sizeprop is not one of the predefined options (handle gracefully).- The
alttext for the image should be meaningful.
Examples
Example 1: Image Avatar
Input:
<Avatar imageUrl="https://example.com/user-avatar.jpg" name="John Doe" size="medium" />
Output:
(A medium-sized circular element displaying the image from the URL)
Explanation: The imageUrl is provided and valid, so the image is displayed. The name and size props are also used for context and styling.
Example 2: Initials Avatar
Input:
<Avatar name="Jane Smith" size="large" />
Output:
(A large-sized circular element displaying "JS")
Explanation: No imageUrl is provided, so the component falls back to displaying initials derived from the name "Jane Smith".
Example 3: Fallback Avatar
Input:
<Avatar size="small" />
Output:
(A small-sized circular element displaying a default placeholder icon)
Explanation: Neither imageUrl nor name is provided, so the component displays the default fallback.
Example 4: Broken Image Fallback
Input:
<Avatar imageUrl="https://example.com/non-existent.jpg" name="Peter Jones" size="medium" />
Output:
(A medium-sized circular element displaying "PJ" or a fallback icon if the image fails to load)
Explanation: The imageUrl is provided but invalid, so the component falls back to displaying initials or a generic placeholder.
Constraints
- The
Avatarcomponent should be a functional component. - The
imageUrl,name, andsizeprops should be typed using TypeScript interfaces. - The
sizeprop should accept a limited set of string values:'small','medium','large'. - The fallback initials should be derived from the first two characters of the
nameprop, converted to uppercase. - The fallback icon should be a simple SVG or font icon.
- The component should be performant for typical usage.
Notes
- Consider using the
useStateanduseEffecthooks to handle image loading states if you need finer control over the fallback for broken images. - For styling, you can use CSS Modules, styled-components, or a CSS-in-JS solution of your choice. Ensure the styling makes the component easily integrable into other parts of an application.
- Think about how you would handle names with only one character or names with special characters.
- For accessibility, ensure the
altattribute for images is set appropriately, e.g., using thenameprop.