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:
- image
- icon
- initials
Use the modern props when writing new code:
imageSrciconnameinitialstooltip
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
| Prop | Type | Default | Description |
|---|---|---|---|
imageSrc | string | null | — | Image source to render first. |
icon | IconName | — | Icon fallback or icon-only avatar content. |
name | string | null | — | Display name used for initials and tooltip fallback. |
initials | string | null | — | Explicit initials override. |
tooltip | string | boolean | — | true shows the resolved name; a string shows custom tooltip content. |
isLoading | boolean | false | Renders the skeleton state. |
onClick | () => void | — | Makes 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. |
className | string | — | Additional classes, often used for exact sizing in dense layouts. |
style | CSSProperties | — | Inline style overrides. |
Legacy Compatibility Props
| Prop | Status | Notes |
|---|---|---|
user | legacy | Older convenience shape with firstName, lastName, and profilePicture. Still common across the repo. |
fallbackIcon | legacy | Use icon instead. |
withTooltip | legacy | Use 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
initialsfirst, otherwise fromname - when
namehas two words, initials use the first letter of each of the first two words - when
namehas one word, initials use a single letter - a tooltip only appears when
tooltipistrueor a string; passing onlynamedoes not automatically enable it
Common Usage Patterns
| Pattern | Path | Notes |
|---|---|---|
| Panel-header entity avatar | fsai/apps/applicant-portal/src/components/LocationPanel/LocationPanel.tsx | Uses Panel.Header.Avatar with icon, color, and isLoading for a location entity. |
| Panel-header contact avatar | fsai/apps/brand-dashboard/src/components/ContactPanel/ContactPanel.tsx | Uses Panel.Header.Avatar with a generic user icon for contact details. |
| Dense table/list avatar | fsai/apps/brand-dashboard/src/modules/locations/utils/index.tsx | Uses a small avatar in the location name cell with image plus derived initials fallback. |
| Editable group avatar | fsai/apps/brand-dashboard/src/pages/Home/ChatOverview/ChatOverview.components.tsx | Uses a clickable avatar with image preview and camera fallback icon. |
| Mobile message avatar | fsai/apps/mobile-dashboard/src/components/Message/Message.tsx | Similar concept, but this is a separate mobile implementation, not the shared web primitive. |
Important Conventions
- Prefer
imageSrc,icon,name, andtooltipin new web code. - Keep the legacy
userprop in mind when reading existing code; it is still widely used. - Prefer
Panel.Header.Avatarover rawAvatarinside panel headers. - In dense tables and lists, it is normal to size the avatar with
classNamesuch ash-6 w-6orw-5 h-5. Avatardoes 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
Avatarcomponent with a different API. Do not assume the web and mobile props are interchangeable.
Guidelines
- Do use
Avatarfor identity treatment in lists, rows, chat, and small interactive surfaces - Do use
Panel.Header.Avatarfor large panel headers - Do pass
tooltipwhen 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
AvatarAPI matches the shared web component - Don't introduce new
user-based usages whenimageSrc,icon, andnameexpress the same thing more clearly