Avatar
An avatar is a thumbnail representation of an entity, such as a user or an organization.
import { Avatar } from 'cwl-ui'
export function Default() {
return (
<div>
<Avatar src="https://images.unsplash.com/photo-1560800452-f2d475982b96?w=250&h=250&auto=format&fit=crop" />
</div>
)
}
Component API
Prop | Default | Description |
---|---|---|
Initials | undefined | The color of the badge. |
src | undefined | Represents the image source displayed in the Avatar. |
alt | undefined | Represents the alternative text for the image displayed in the Avatar. |
className | undefined | Represents the className of the Avatar. |
size | sm | Represents the size of the Avatar. |
notification | undefined | An optional prop to apply a notification to the Avatar. |
status | undefined | An optional prop to apply a custom status to the Avatar. |
This is a custom Avatar component that does not use react-aria-components like other components in this library.
Examples
Sizes
Pass a size
prop to the Avatar to change the size of the Avatar.
import { Avatar } from 'cwl-ui'
export function Default() {
return (
<div className="space-x-4">
<Avatar
size="sm"
src="https://images.unsplash.com/photo-1560800452-f2d475982b96?w=250&h=250&auto=format&fit=crop"
/>
<Avatar
size="md"
src="https://images.unsplash.com/photo-1560800452-f2d475982b96?w=250&h=250&auto=format&fit=crop"
/>
<Avatar
size="lg"
src="https://images.unsplash.com/photo-1560800452-f2d475982b96?w=250&h=250&auto=format&fit=crop"
/>
</div>
)
}
Notification Avatar
Pass a notification
prop to the Avatar to apply a notification.
import { Avatar } from 'cwl-ui'
export function Default() {
return (
<div className="space-x-4">
<Avatar
size="sm"
notification="green"
src="https://images.unsplash.com/photo-1560800452-f2d475982b96?w=250&h=250&auto=format&fit=crop"
/>
<Avatar
size="md"
notification="yellow"
src="https://images.unsplash.com/photo-1560800452-f2d475982b96?w=250&h=250&auto=format&fit=crop"
/>
<Avatar
size="lg"
notification="red"
src="https://images.unsplash.com/photo-1560800452-f2d475982b96?w=250&h=250&auto=format&fit=crop"
/>
</div>
)
}
Status
Pass a status
prop to the Avatar to apply a custom status to the Avatar.
import { Avatar } from 'cwl-ui'
export function Default() {
return (
<div className="space-x-4">
<Avatar
size="sm"
status="green"
src="https://images.unsplash.com/photo-1560800452-f2d475982b96?w=250&h=250&auto=format&fit=crop"
/>
<Avatar
size="md"
status="yellow"
src="https://images.unsplash.com/photo-1560800452-f2d475982b96?w=250&h=250&auto=format&fit=crop"
/>
<Avatar
size="lg"
status="red"
src="https://images.unsplash.com/photo-1560800452-f2d475982b96?w=250&h=250&auto=format&fit=crop"
/>
</div>
)
}
Status and Notification
If you want to apply both a status and a notification to the Avatar, you can pass both props.
import { Avatar } from 'cwl-ui'
export function Default() {
return (
<div>
<Avatar
size="lg"
status="green"
notification="red"
initials="CL"
src="https://images.unsplash.com/photo-1560800452-f2d475982b96?w=250&h=250&auto=format&fit=crop"
/>
</div>
)
}
Custom Avatar
If you need finer grained control on how you want to display the Avatar, you can pass children as props instead.
import { Avatar } from 'cwl-ui'
export function Custom() {
return (
<div>
<Avatar src="https://images.unsplash.com/photo-1560800452-f2d475982b96?w=250&h=250&auto=format&fit=crop">
<Avatar.Notification status="yellow" className="absolute left-0 bottom-0" />
</Avatar>
</div>
)
}
Installation
To install, copy the code below and paste into your project.
import * as React from 'react'
import { cn, getInitials } from './lib/utils'
type Variants = 'gray' | 'green' | 'yellow' | 'red'
interface AvatarProps extends React.HTMLAttributes<HTMLSpanElement> {
/**
* Represents the initials displayed on the Avatar.
* - Supports single characters, two characters, or full words.
* - For full words, initials will be derived from
* the first letter of the first and last word.
*/
initials?: string
/**
* Represents the image source displayed on the Avatar.
*/
src?: string
/**
* Represents the alternate text for the image displayed on the Avatar.
*/
alt?: string
/**
* Represents the class name of the Avatar.
*/
className?: string
/**
* Represents the size of the Avatar.
*/
size?: 'sm' | 'md' | 'lg'
/**
* An optional prop to apply a notification to the Avatar.
*/
notification?: Variants
/**
* An optional prop to apply a status to the Avatar.
*/
status?: Variants
}
const AvatarRoot = React.forwardRef<HTMLSpanElement, AvatarProps>(
(
{ children, initials, alt, className, size = 'sm', src, notification, status, ...props },
ref,
) => {
return (
<span
className={cn(className, 'relative inline-grid rounded-full', {
'w-8 h-8 [--notification-size:8px]': size === 'sm',
'w-12 h-12 [--notification-size:12px]': size === 'md',
'w-16 h-16 [--notification-size:16px]': size === 'lg',
})}
data-slot="avatar"
ref={ref}
{...props}
>
{initials && (
<svg
className="select-none fill-current text-[48px] font-medium uppercase"
viewBox="0 0 100 100"
aria-hidden={alt ? undefined : 'true'}
>
{alt && <title>{alt}</title>}
<text
x="50%"
y="50%"
alignmentBaseline="middle"
dominantBaseline="middle"
textAnchor="middle"
dy=".125em"
>
{getInitials(initials)}
</text>
</svg>
)}
{src && (
// eslint-disable-next-line @next/next/no-img-element
<img
className="aspect-square h-full w-full rounded-full object-cover object-center"
src={src}
alt={alt}
/>
)}
{notification && <Notification status={notification} />}
{status && <Status status={status} />}
{children}
</span>
)
},
)
const Status = React.forwardRef<
HTMLSpanElement,
React.ComponentPropsWithoutRef<'span'> & Pick<AvatarProps, 'status'>
>(({ status }, ref) => {
return (
<span
ref={ref}
className={cn(
'absolute right-0 top-0 h-[--notification-size] w-[--notification-size] rounded-full ring-2 ring-white',
{
'bg-gray-500': status === 'gray',
'bg-green-500': status === 'green',
'bg-yellow-500': status === 'yellow',
'bg-red-500': status === 'red',
},
)}
/>
)
})
const Notification = React.forwardRef<
HTMLSpanElement,
React.ComponentPropsWithoutRef<'span'> & Pick<AvatarProps, 'status'>
>(({ status, className }, ref) => {
return (
<span
ref={ref}
className={cn(
'absolute bottom-0 right-0 h-[--notification-size] w-[--notification-size] rounded-full ring-2 ring-white',
{
'bg-gray-500': status === 'gray',
'bg-green-500': status === 'green',
'bg-yellow-500': status === 'yellow',
'bg-red-500': status === 'red',
},
className,
)}
/>
)
})
AvatarRoot.displayName = 'AvatarRoot'
Status.displayName = 'AvatarStatus'
Notification.displayName = 'AvatarNotification'
export const Avatar = Object.assign(AvatarRoot, {
Status,
Notification,
})