FSAI Design System
Components

Avatar

Shared identity primitive for people, entities, rows, chat, and panel headers.

Overview

Avatar is the shared identity primitive used across @fsai/shared-ui.

It is commonly used for:

  • people with a profile image or initials
  • entities that need an icon-based identity treatment
  • dense table and list rows
  • chat and activity surfaces
  • clickable image pickers or editable group avatars

The primitive supports a simple fallback chain:

  1. image
  2. icon
  3. initials

Use the modern props when writing new code:

  • imageSrc
  • icon
  • name
  • initials
  • tooltip

The older user, fallbackIcon, and withTooltip props are still common in the repo, but they are legacy compatibility props rather than the preferred API.

Basic Usage

import { Avatar } from '@fsai/shared-ui';

<Avatar
  imageSrc={contact.profilePictureUrl}
  name={contact.fullName}
  tooltip
/>

If imageSrc is missing or the image fails to load, Avatar falls back to icon and then to initials derived from name.

Icon Or Entity Avatar

Use an icon when the subject is not really a person, or when the panel or row needs a stable identity treatment without depending on uploaded images.

<Avatar icon="LocationPin" color="blue" tooltip="Location" />

This is common in panel headers for locations, contacts, and other entities.

Dense Row Avatar

In tables and dense lists, Avatar is often size-controlled with className instead of relying only on the built-in size variants.

<Avatar
  className="h-6 w-6 mr-2.5"
  imageSrc={item.thumbnailAssetUrl}
  name={item.name}
  color="blue"
/>

This mirrors the location-name cell pattern used in the locations table utilities.

Clickable Editable Avatar

Avatar can also be used as a lightweight clickable target for image selection or replacement.

<Avatar
  imageSrc={groupChatImagePreview}
  name="Group Chat"
  icon="CameraSolid"
  onClick={() => fileInputRef.current?.click()}
  className="w-12 h-12 hover:opacity-80 transition-opacity bg-gray-bg-surface"
/>

This is the pattern used in ChatOverview.components.tsx for a group-chat image picker.

Panel Header Usage

When the avatar appears in a large panel header, prefer Panel.Header.Avatar instead of raw Avatar.

Panel.Header.Avatar is the shared panel wrapper around Avatar and gives panel headers a consistent large treatment. Use raw Avatar directly for rows, chat, inline controls, and other non-header contexts.

Loading State

Set isLoading when the surrounding UI is skeletonized.

<Avatar name="Location" icon="LocationPin" color="blue" isLoading={isLoading} />

This renders a Skeleton with matching size and corner radius instead of the normal avatar content.

Props

PropTypeDefaultDescription
imageSrcstring | nullImage source to render first.
iconIconNameIcon fallback or icon-only avatar content.
namestring | nullDisplay name used for initials and tooltip fallback.
initialsstring | nullExplicit initials override.
tooltipstring | booleantrue shows the resolved name; a string shows custom tooltip content.
isLoadingbooleanfalseRenders the skeleton state.
onClick() => voidMakes the avatar clickable and adds pointer styling.
color'gray' | 'blue' | 'purple' | 'yellow' | 'blue-gradient''gray'Avatar color treatment.
size'xs' | 'sm' | 'md' | 'lg''md'Built-in size variant.
rounded'sm' | 'md' | 'full''md'Corner radius variant.
classNamestringAdditional classes, often used for exact sizing in dense layouts.
styleCSSPropertiesInline style overrides.

Legacy Compatibility Props

PropStatusNotes
userlegacyOlder convenience shape with firstName, lastName, and profilePicture. Still common across the repo.
fallbackIconlegacyUse icon instead.
withTooltiplegacyUse tooltip instead.

Fallback And Tooltip Behavior

  • image rendering is attempted first
  • if the image errors, the avatar falls back to icon or initials
  • initials come from initials first, otherwise from name
  • when name has two words, initials use the first letter of each of the first two words
  • when name has one word, initials use a single letter
  • a tooltip only appears when tooltip is true or a string; passing only name does not automatically enable it

Common Usage Patterns

PatternPathNotes
Panel-header entity avatarfsai/apps/applicant-portal/src/components/LocationPanel/LocationPanel.tsxUses Panel.Header.Avatar with icon, color, and isLoading for a location entity.
Panel-header contact avatarfsai/apps/brand-dashboard/src/components/ContactPanel/ContactPanel.tsxUses Panel.Header.Avatar with a generic user icon for contact details.
Dense table/list avatarfsai/apps/brand-dashboard/src/modules/locations/utils/index.tsxUses a small avatar in the location name cell with image plus derived initials fallback.
Editable group avatarfsai/apps/brand-dashboard/src/pages/Home/ChatOverview/ChatOverview.components.tsxUses a clickable avatar with image preview and camera fallback icon.
Mobile message avatarfsai/apps/mobile-dashboard/src/components/Message/Message.tsxSimilar concept, but this is a separate mobile implementation, not the shared web primitive.

Important Conventions

  • Prefer imageSrc, icon, name, and tooltip in new web code.
  • Keep the legacy user prop in mind when reading existing code; it is still widely used.
  • Prefer Panel.Header.Avatar over raw Avatar inside panel headers.
  • In dense tables and lists, it is normal to size the avatar with className such as h-6 w-6 or w-5 h-5.
  • Avatar does not include built-in status dots, role badges, or presence indicators. Compose those outside the primitive when needed.
  • For non-person entities, icon-only or image-plus-name usage is often clearer than pretending everything is a user.
  • The mobile dashboard has its own Avatar component with a different API. Do not assume the web and mobile props are interchangeable.

Guidelines

  • Do use Avatar for identity treatment in lists, rows, chat, and small interactive surfaces
  • Do use Panel.Header.Avatar for large panel headers
  • Do pass tooltip when hover disclosure is actually useful
  • Do expect image failure and rely on the fallback chain
  • Don't build status or role indicators into the primitive itself
  • Don't assume the mobile Avatar API matches the shared web component
  • Don't introduce new user-based usages when imageSrc, icon, and name express the same thing more clearly

On this page