Skip to content

Avatar

Render a person, agent, or any named entity. Avatar resolves an image when one is available, falls back to initials derived from the name, and finally to a generic user glyph. AvatarGroup overlaps multiple avatars and collapses overflow into a +N indicator.

Reach for Avatar to represent identities — collaborators, comment authors, agent attributions. For decorative imagery (thumbnails, hero photos) use a plain <img>; an avatar isn’t the right semantic.

Live Preview

Import

import { Avatar, AvatarGroup } from 'entangle-ui';

Usage

<Avatar src="/users/alice.png" name="Alice Wong" />
<Avatar name="Sebastian Kowalski" status="online" />
<Avatar name="Bot" color="primary" shape="rounded" />

When src is provided the avatar attempts to load it; the underlying initials remain in place as a backdrop until the image paints (or fails). If it fails, the initials become the visible content.

Sizes

Six fixed sizes from xs (toolbar / chip) through xxl (profile header).

Sizes

SizeDiameterUse case
xs16pxInline next to dense rows
sm20pxCompact lists / chat bubbles
md24pxDefault
lg32pxSide panels, comments
xl40pxCards, member rows
xxl56pxProfile pages / detail headers
<Avatar size="xs" name="Alice" />
<Avatar size="xxl" name="Alice" />

Shapes

Shapes

ShapeBorder radiusWhen to use
circle50%Default — people / personal context
square0Logos, machine identifiers
roundedborderRadius.mdSoft fallback between the two
<Avatar shape="circle" />
<Avatar shape="square" />
<Avatar shape="rounded" />

Initials

Without a src, the avatar derives initials from name. A single word produces its first two characters; multi-word names produce the first character of the first and last word. With color="auto" (default) the background colour is hashed deterministically from the name — same name, same colour, every render.

Initials

<Avatar name="Sebastian Kowalski" /> {/* "SK" */}
<Avatar name="Alice" /> {/* "AL" */}
<Avatar name="Mary Anne Smith" /> {/* "MS" */}
<Avatar name="Sebastian" initials="SK" /> {/* explicit override */}

To force a specific accent, pass color="primary" (or success, warning, error, info, neutral). Any other string is treated as a raw CSS colour.

<Avatar name="Bot" color="primary" />
<Avatar name="Bot" color="#9b59b6" />

Icon fallback

When neither src nor name/initials resolves, a generic user glyph renders. Override it with fallbackIcon.

Icon fallback

<Avatar />
<Avatar fallbackIcon={<RobotIcon />} />

Statuses

Add a presence indicator in the bottom-right corner via the status prop.

Statuses

StatusColour token
onlinecolors.accent.success
awaycolors.accent.warning
busycolors.accent.error
offlinecolors.text.muted
<Avatar name="Alice" status="online" />
<Avatar name="Bob" status="away" />
<Avatar name="Carol" status="busy" />
<Avatar name="Dave" status="offline" />

Fallback chain

The component renders both the image and the fallback in the same DOM, with the image positioned over the fallback. As soon as the image loads it paints over the initials; if it errors, the image is hidden via data-loaded="false" and the initials become visible without a layout shift.

Broken image

In order:

  1. Imagesrc provided and loads successfully
  2. Initials — derived from name (or set explicitly via initials)
  3. IconfallbackIcon if provided, otherwise a generic user glyph

Image source recommendations

  • Square aspect ratio. The <img> is rendered with object-fit: cover, so non-square sources crop to centre.
  • Render at 2× the avatar’s pixel size for crisp results on HiDPI displays — for a 32px avatar, a 64×64 source.
  • Prefer modern formats (WebP / AVIF). Avatars sit in a container with overflow: hidden, so transparency is preserved when the format supports it.
  • For user-uploaded images, consider running them through a face-aware crop service (Unsplash, Cloudinary, your own pipeline) before passing the URL to <Avatar>.

Clickable

Provide onClick to make the avatar interactive — focusable, with a hover affordance and Enter/Space activation.

Clickable

<Avatar
src="/users/alice.png"
name="Alice"
onClick={() => openProfile('alice')}
/>

AvatarGroup

Display multiple avatars as an overlapping cluster.

AvatarGroup

<AvatarGroup max={4}>
<Avatar src="/users/alice.png" name="Alice" />
<Avatar name="Bob" />
<Avatar name="Carol" />
<Avatar name="Dave" />
<Avatar name="Eve" />
</AvatarGroup>

size and bordered propagate to every child — the group always wins so the cluster reads uniformly. The default bordered={true} adds a 2px ring matching the surrounding background; the leftmost avatar stacks on top via descending z-index.

AvatarGroup overflow

When the number of children exceeds max, the remainder collapses into a +N indicator. Hover it to reveal the names of the hidden avatars.

AvatarGroup overflow

<AvatarGroup max={4}>{/* 12 avatars — 4 visible, "+8" overflow */}</AvatarGroup>

Disable the tooltip with showOverflowTooltip={false} when the names aren’t useful in context (e.g. when none of the avatars carry a name prop).

Group sizes

Group sizes

Editor example

A collaborators row in a project header.

Editor example

Accessibility

  • The accessible name resolves in this order: aria-labelnamealt. Always supply at least one of these.
  • The image’s alt attribute defaults to name (then the empty string), so when an image fails the underlying initials read with the supplied name.
  • The status dot has its own aria-label ("Status: Online" etc.) so a screen reader reaches it independently of the avatar’s name.
  • When onClick is provided, the avatar gets role="button" and tabIndex={0}, and Enter / Space trigger the handler.
  • The fallback glyph is marked aria-hidden="true" once an image successfully loads so it doesn’t double-announce.

API Reference

Avatar

Prop Type Default Description
src string Image source URL. Falls back to initials, then to an icon, on error.
alt string Image alt text and accessible name fallback.
name string Display name. Drives initials and the auto color hash.
initials string Manual initials override. Truncated to two characters and uppercased.
fallbackIcon ReactNode Icon shown when neither image nor initials resolve.
size 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' 'md' Diameter (16 / 20 / 24 / 32 / 40 / 56 px).
shape 'circle' | 'square' | 'rounded' 'circle' Border radius treatment.
color 'auto' | 'neutral' | 'primary' | 'success' | 'warning' | 'error' | 'info' | string 'auto' Background colour for the initials / icon surface.
status 'online' | 'away' | 'busy' | 'offline' Optional presence indicator in the bottom-right corner.
onClick (event) => void When provided, the avatar becomes a focusable button with Enter/Space activation.
bordered boolean false Render a 2px ring matching the surrounding background.
className string Additional CSS class names.
style CSSProperties Inline styles.
testId string Test identifier for automated testing.
ref Ref<HTMLSpanElement> Ref to the avatar root element.

AvatarGroup

Prop Type Default Description
max number 4 Maximum number of visible avatars before the +N indicator appears.
spacing number | string -8 Spacing between avatars. Negative values overlap. Numbers are pixels.
size 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' 'md' Size applied to every child avatar.
bordered boolean true Force a border on every child, separating overlapping avatars.
showOverflowTooltip boolean true Show a tooltip listing hidden avatar names when the +N indicator is visible.
children * ReactNode Avatar children.
className string Additional CSS class names.
style CSSProperties Inline styles.
testId string Test identifier for automated testing.
ref Ref<HTMLDivElement> Ref to the group root element.