This is my attempt for building an <Avatar>
parent component with <Avatar.Image>
and <Avatar.Fallback>
child components.
Firstly, I built the <Avatar.Image>
component to display the image of our avatar.
import React, { useState } from 'react';
import Image from 'next/image';
function AvatarImage({ src, alt, className, ...props }) {
const [imageSuccessfullyLoaded, setImageSuccessfullyLoaded] = useState(true);
return (
<div>
{imageSuccessfullyLoaded && (
<Image
src={src}
alt={alt}
placeholder="empty"
onError={() => {
setImageSuccessfullyLoaded(false);
}}
fill
{...props}
/>
)}
</div>
);
}
export default AvatarImage;
Once the AvatarImage
component fails to load, I let the AvatarFallback
component fill the background.
import React from 'react';
import classNames from 'classnames';
function AvatarFallback({ children, className }) {
return (
<div
className={classNames(
'text-lg font-medium text-neutral-600 dark:text-neutral-200',
className
)}
>
{children}
</div>
);
}
export default AvatarFallback;
The parent component is named Avatar
import React from 'react';
import classNames from 'classnames';
import AvatarImage from './AvatarImage/AvatarImage';
import AvatarFallback from './AvatarFallback/AvatarFallback';
function Avatar({ className, children }) {
return (
<div
className={classNames(
'relative flex items-center justify-center overflow-hidden rounded-full bg-neutral-200 dark:bg-neutral-600',
className
)}
>
{children}
</div>
);
}
Avatar.Image = AvatarImage;
Avatar.Fallback = AvatarFallback;
export default Avatar;
Below is an example of how I use it:
(don't forget to change ${videoId}
)
<Avatar>
<Avatar.Image src="https://i.ytimg.com/vi/${videoId}/maxresdefault.jpg" alt="Avatar image" />
<Avatar.Fallback>
<Image
src="https://i.ytimg.com/vi/${videoId}/hqdefault.jpg"
fill
alt="Avatar image"
/>
</Avatar.Fallback>
</Avatar>