Skip to content

Avatar ​

A generic, accessible avatar chip. It renders an image when you give it one, and gracefully falls back to name-derived initials (on a deterministic colour) or a custom node when the image is missing or fails to load β€” so a list never shows a broken-image icon.

πŸ§ͺ Try every prop live in the Storybook.

Usage ​

tsx
import { Avatar } from '@whereq/react'

;<Avatar src="/users/ada.jpg" name="Ada Lovelace" />

Initials fallback (no src, or the image 404s) β€” the background colour is derived deterministically from name:

tsx
<Avatar name="Grace Hopper" /> // β†’ "GH" on a stable colour

Head-crop a portrait so the face fills the circle, with a ring:

tsx
<Avatar src="/mascot.png" name="Q" position="top" ring="#e4e8ee" ringWidth={2} />

Shapes and a presence dot:

tsx
<Avatar name="Ada" shape="rounded" />
<Avatar src="/ada.jpg" name="Ada" status="online" />

AvatarGroup ​

Overlap several avatars and collapse the overflow into a +N chip. Size, shape and the separator ring are set once on the group and applied to every child.

tsx
import { Avatar, AvatarGroup } from '@whereq/react'

;<AvatarGroup size={32} max={3}>
  <Avatar src="/a.jpg" name="Ada" />
  <Avatar src="/b.jpg" name="Ben" />
  <Avatar name="Cai" />
  <Avatar name="Dee" />
</AvatarGroup>

Props ​

<Avatar> extends React.HTMLAttributes<HTMLSpanElement> (minus color) β€” className, style, ref and any other span prop pass through.

PropTypeDefaultDescription
srcstringβ€”Image URL. Falls back to initials if missing / errors.
namestringβ€”Drives auto-initials, the colour and the a11y label.
initialsstringfrom nameExplicit initials override.
fallbackReactNodeβ€”Shown when there's no image and no initials (an icon).
sizenumber40Diameter in px.
shape'circle' | 'rounded' | 'square''circle'Outline shape.
bgstringfrom nameChip background (behind transparent art / initials).
colorstring'#fff'Initials colour.
ringstringβ€”Inset ring colour.
ringWidthnumber1Ring width in px.
fitCSSProperties['objectFit']'cover'Image object-fit.
positionCSSProperties['objectPosition']'center'Image object-position β€” use 'top' to head-crop.
status'online' | 'offline' | 'busy' | 'away'β€”Presence dot in the corner.
statusColorsPartial<Record<AvatarStatus, string>>presetPer-status dot colour overrides.
statusRingstring'#fff'Separator ring around the status dot.
altstringnameImage alt text.

<AvatarGroup> props ​

Extends React.HTMLAttributes<HTMLDivElement>.

PropTypeDefaultDescription
sizenumber40Diameter applied to every child.
maxnumberβ€”Show this many, then a +N chip.
spacingnumbersize * 0.35Overlap between adjacent avatars in px.
ringstring'#fff'Separator ring around each avatar.
ringWidthnumber2Ring width in px.
shape'circle' | 'rounded' | 'square''circle'Outline shape applied to every child.

Helpers ​

The pure functions behind the component are exported for reuse:

ts
import { initialsFromName, colorFromName } from '@whereq/react'

initialsFromName('Ada Lovelace') // 'AL'
initialsFromName('张伟') // '张伟'
colorFromName('Ada Lovelace') // a stable palette hex

Notes ​

  • Accessibility β€” when an image is shown, the <img> carries the alt; otherwise the wrapper is exposed as role="img" with aria-label={name}, and the initials are aria-hidden.
  • SSR-safe β€” the component is pure inline styles with no stylesheet injection or DOM access, so it renders identically on the server and hydrates cleanly.
  • Image errors β€” a failed load flips to the initials/fallback, and the state resets automatically when src changes (safe for reused list rows).

Released under the MIT License.