Avatar
A person's image with initials as the fallback.
Example
Installation
pnpm dlx shadcn@latest add superzero11/uiset/avatarIt lands in components/ui/avatar.tsx, with UISet’s root (uiset). Wrap your app in <UISet> once, and every component takes its skin.
What UISet adds
The component is UI SDK’s own, with its parts, props and names, so everything below works as UI SDK documents it. UISet adds the look and checks it:
- Styles in five skins, each in light and dark, from CSS variables you can override.
- Text at 4.5:1 contrast and control edges and focus rings at 3:1, in every skin and theme, checked with axe in tests.
- Haptic cues on phones, and sound cues when you set
soundon<UISet>. - Examples that name every control, so agents can find it (see Agents below).
The API reference and accessibility notes below are UI SDK’s, from its docs for @ui-sdk/react (Apache-2.0). Avatar on ui-sdk.dev has more usage examples. Your coding agent can read the same page at node_modules/@ui-sdk/react/docs/components/avatar.md.
API Reference
Props and callbacks are the same as below, as React props.
Avatar
onLoadingStatusChange?(((status: AvatarLoadingStatus, details: ChangeDetails<AvatarLoadingStatusChangeReason>) => void)): Runs when the image's loading status changes:"loading"when it gets a source,"loaded","error", and"idle"when it leaves the page.details.reasonsays why, anddetails.eventis the image'sloadorerrorevent, or undefined when the status was known at once, like for a cached image.debug?(boolean): Logs every state change with its reason to the console, in development builds.
AvatarImage
The image. Renders a real img, so the browser can fetch it before hydration, and accepts its attributes, such as srcSet, crossOrigin and referrerPolicy.
AvatarFallback
delay?(number): How long to wait, in milliseconds, before showing the fallback, so a fast image appears without the fallback flashing first. Without one, the fallback shows at once, server markup included.
State
What render functions, state-based class names and slots receive. Every part gets the same state.
loadingStatus(AvatarLoadingStatus): Where the image is:"idle","loading","loaded"or"error".
Reasons
details.reason says why the status changed.
image-load(Event | undefined): An image loaded. No event when it was already in the browser's cache.image-error(Event | undefined): An image failed to load, or has no source. No event when that was known at once.src-change(none): An image got a new source, or left the page, so its status starts over.
Events
Callbacks get the new status first, then the details.
| Prop | On | Receives |
|---|---|---|
onLoadingStatusChange | Avatar | (status, details): the image's status, the reason and details.event |
Accessibility
Give the image meaningful alt text. Include the person's name in the fallback too, using visually hidden text if you only want to show initials.
When a visible name beside the avatar already identifies the person, use an empty alt and hide decorative fallback content from screen readers.
- An image that loads replaces the fallback.
- An image that fails keeps the fallback.
- An avatar without an image shows its fallback.
- A fallback with a delay waits before showing.
- The image's loading status is reported.
- Removing the image brings the fallback back.
- A new source shows its image once it loads.
- The image is fetched with its own referrer policy.
- A cached image doesn't flash the fallback when the avatar mounts again.
- A new source keeps showing the previous image until it loads.
- The image is fetched once, even when it can't be cached.
Runs in React, Vue and web components.
Agents
UI SDK’s agent bridge finds this component by its accessible name: give it a visible label or an aria-label, and an agent can read its state and call its actions without screenshots. Building with AI agents shows how to connect one.
This is agent.snapshot() for the example above, read live from this page. Change something in the example, then read it again: the values follow.
[
{
"ref": "c8",
"component": "avatar",
"actions": [],
"label": "Ada Lovelace"
},
{
"ref": "c9",
"component": "avatar",
"actions": [],
"label": "Grace Hopper"
}
]