Avatar
- Needs review
- WCAG 2.2 evidence
- RTL
A person or organisation shown as a photo, initials or an icon. Fallback order: photo, then initials, then the person icon. Accessibility: a named avatar is an image (<img alt> or role="img" with aria-label), so the name survives a
failed photo (WCAG 1.1.1, 4.1.2); a decorative one is hidden. The presence slot sits outside the image, so its
status text is announced (1.3.1). Consumer duties: pass the real name; show availability as visible text where it
matters, because the presence colours alone do not meet 1.4.1; make the avatar a link or button by wrapping it. Presentational: renders in React Server Components. Only the photo's load-failure handling is a client island
(AvatarImage).
import { Avatar } from "@nexera-ui/react";- 5
- examples
- 7
- props
- 3
- live controls
- 1
- platform
- 3
- WCAG criteria
- 32
- blocks use it
Try every prop. Copy the code.
Change the props and the code updates. Check light and dark, LTR and RTL, and phone width.
import { Avatar } from "@nexera-ui/react";
<Avatar />Examples 4
The same examples as Storybook, rendered live. Open Code to copy one.
With presence
Figma Show status: a Presence in the presence slot, resized to 8, 10, 12 or 14 px. Its status text is announced after the name; the visible status line keeps it readable without colour (WCAG 1.4.1).
import { Avatar, Presence } from "@nexera-ui/react";
const sizes = ["xs", "sm", "md", "lg", "xl", "2xl"] as const;
const statuses = ["online", "away", "busy", "offline"] as const;
export function WithPresence() {
return (
<ul className="m-0 flex list-none flex-col gap-4 p-0">
{sizes.map((size, index) => {
const status = statuses[index % statuses.length] ?? "online";
return (
<li key={size} className="flex items-center gap-3">
<Avatar
initials="AK"
size={size}
isDecorative
presence={<Presence status={status} isDecorative />}
/>
<span className="flex flex-col">
<span className="text-body-strong text-primary">Ayesha Khan</span>
<span className="text-body-small text-secondary capitalize">{status}</span>
</span>
</li>
);
})}
</ul>
);
}
Photo fallback
Fallback order: photo, then initials, then the person icon (missing src or an image that fails to load).
import { Avatar } from "@nexera-ui/react";
const SAMPLE_PHOTO = `data:image/svg+xml,${encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect width="40" height="40" fill="steelblue"/>' +
'<circle cx="20" cy="15" r="7.6" fill="white" fill-opacity="0.92"/>' +
'<ellipse cx="20" cy="38" rx="15.6" ry="12" fill="white" fill-opacity="0.92"/></svg>',
)}`;
const BROKEN_PHOTO = "data:image/png;base64,broken";
export function PhotoFallback() {
return (
<div className="flex flex-wrap items-center gap-6">
<Avatar type="photo" src={SAMPLE_PHOTO} initials="AK" size="xl" label="Ayesha Khan" />
<Avatar type="photo" src={BROKEN_PHOTO} initials="AK" size="xl" label="Ayesha Khan" />
<Avatar type="photo" src={BROKEN_PHOTO} size="xl" label="Ayesha Khan" />
<Avatar type="photo" src={null} initials="BK" size="xl" label="Bilal Khan" />
</div>
);
}
With visible name
Next to a visible name the avatar is decorative (isDecorative): screen readers hear the name once.
import { Avatar } from "@nexera-ui/react";
const SAMPLE_PHOTO = `data:image/svg+xml,${encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect width="40" height="40" fill="steelblue"/>' +
'<circle cx="20" cy="15" r="7.6" fill="white" fill-opacity="0.92"/>' +
'<ellipse cx="20" cy="38" rx="15.6" ry="12" fill="white" fill-opacity="0.92"/></svg>',
)}`;
export function WithVisibleName() {
return (
<p className="text-body-default text-primary m-0 flex items-center gap-2">
<Avatar isDecorative type="photo" src={SAMPLE_PHOTO} size="sm" />
Ayesha Khan approved your leave request.
</p>
);
}
Right to left
Right-to-left: the presence dot moves to the bottom-left corner (inline end).
import { Avatar, Presence } from "@nexera-ui/react";
const SAMPLE_PHOTO = `data:image/svg+xml,${encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect width="40" height="40" fill="steelblue"/>' +
'<circle cx="20" cy="15" r="7.6" fill="white" fill-opacity="0.92"/>' +
'<ellipse cx="20" cy="38" rx="15.6" ry="12" fill="white" fill-opacity="0.92"/></svg>',
)}`;
export function RightToLeft() {
return (
<div dir="rtl" lang="ar" className="flex items-center gap-4">
<Avatar initials="أخ" size="lg" label="أيشة خان" presence={<Presence label="متصل" />} />
<Avatar
type="photo"
src={SAMPLE_PHOTO}
size="xl"
label="أيشة خان"
presence={<Presence status="away" label="بعيد" />}
/>
</div>
);
}
Props 7
Press "Try it" on a card to load that prop into the playground.
7 props shown
sizeNexera"xs" | "sm" | "md" | "lg" | "xl" | "2xl"Box size: 20, 24, 32, 40, 56 or 72 px. xs replaces the Select-page Avatar.
labelNexerastringAccessible name: the person's or company's name, for example "Ayesha Khan" (WCAG 1.1.1). It becomes the photo's
alt, and stays the name when the photo falls back to initials or the icon.
Not allowed on a decorative avatar.
isDecorativeNexerabooleanHide the avatar from assistive technology.
The avatar repeats a name that is visible next to it, so it is hidden from assistive technology (aria-hidden,
empty alt). A presence dot stays readable.
typeNexera"initials" | "photo" | "icon" | "company"What the avatar shows: initials on a brand tint, a photo, a person icon, or a company letter on
a rounded square.
A photo.
A generic person, for someone without a photo or initials.
An organisation: a rounded square in the brand colour.
initialsNexerastringOne or two letters. Empty initials show the person icon. Fallback letters when the photo is missing or fails to load. Not used by the icon type. Usually the first letter of the company name.
srcNexerastring | nullOnly with type="photo".
Image URL. When it is missing or fails to load, the avatar shows initials, or the person icon without them.
presenceNexeraReactNodeAvailability dot at the bottom inline-end corner, sized for the
avatar: pass a <Presence status="online" />. It stays outside the image so its status text is read.
Availability dot: pass a <Presence />.
Figma has no presence on a company avatar.
* Required. React Aria props shown are the ones most apps use; the component accepts the rest of its React Aria props too.
Accessible by default.
Built on React Aria, and covered by the WCAG 2.2 evidence generated on every build.
WCAG 2.2 evidence
3 direct · 0 supporting- 1.1.1Non-text ContentLevel A · tested directly
- 1.3.1Info and RelationshipsLevel A · tested directly
- 4.1.2Name, Role, ValueLevel A · tested directly
Fits any width.
Nexera components respond to the space they are given. Drag the corner of the frame, or pick a width.
Styling hooks
Pass className to add Tailwind classes (merged last). State is exposed as data attributes, so you can style it with variants like data-pressed:.
<Avatar className="shadow-sm" />Used in blocks
- Session expiredSign in and account
- Choose a workspaceSign in and account
- Profile setupOnboarding
- Invite your teamOnboarding
- Sidebar app shellApp shells and navigation
- Top bar with tabsApp shells and navigation
- Mobile app shellApp shells and navigation
- Bulk actionsLists, tables and records
- Filter barLists, tables and records
- People directoryLists, tables and records
- Record details drawerLists, tables and records
- Activity feedLists, tables and records
- Add a personForms and data entry
- Search with suggestionsForms and data entry
- Team members and rolesSettings and preferences
- ChatMessaging and collaboration
- InboxMessaging and collaboration
- Helpdesk assistantMessaging and collaboration
- Comment threadMessaging and collaboration
- Day separators and system notesMessaging and collaboration
- Team availabilityScheduling and calendar
- Book a meetingScheduling and calendar
- Event detailsScheduling and calendar
- Leave approvalScheduling and calendar
- PayslipCommerce and payments
- Reviews and ratingsCommerce and payments
- Candidate shortlistWork and projects
- Team mapMaps and places
- People nearbyMaps and places
- ToastsStates and system messages
- Tab bar appMobile patterns
- Pull to refresh feedMobile patterns
Related components
- AccordionItemOne collapsible section of an FAQ or settings page.
- AreaChartA stacked area chart: layers piled up over time with the title, range switch, actions and legend of the card.
- AvailabilityRowOne person's availability across a window of the day: an avatar with initials and the name, and a timeline with the busy periods drawn as bars.
- AvatarGroupA row of overlapping avatars with a "+N" chip for the rest.
- AvatarLabelAn avatar with a name and an optional subtitle beside it, for a person in a list, a header or a mention.
- BadgeShort status or category label: `Tone` x `Variant` x `Size`, with an optional dot, leading icon and remove button.
- BadgeGroupA pill that pairs a small badge with a short message, for an announcement or a status line.
- BadgeOverflowThe "+N" pill that stands in for the badges a row has no room for.