Morphos
Feedback

Avatar

An image with an automatic fallback when the image is loading or fails to load.

Interactive example

Open in Storybook

Installation

npm install @morphos/feedback
pnpm add @morphos/feedback
yarn add @morphos/feedback
bun add @morphos/feedback

Import

import { Avatar, AvatarImage, AvatarFallback } from '@morphos/feedback'

Usage

Avatar is the compound root — it owns the image-load status state machine. Construct it with @State() and pass the same instance to AvatarImage and AvatarFallback via the avatar prop.

@Component()
class MyComponent extends StatefulComponent {
  @State() avatar = new Avatar()

  render() {
    return (
      <Avatar>
        <AvatarImage avatar={this.avatar} src="/profile.jpg" alt="Alice Johnson" />
        <AvatarFallback avatar={this.avatar}>AJ</AvatarFallback>
      </Avatar>
    )
  }
}

Compound components

ComponentDescription
AvatarRoot — tracks image load status via a state machine
AvatarImageThe <img> element. Hidden until the image loads
AvatarFallbackShown when the image has not yet loaded or failed

Props — Avatar

PropTypeDefaultDescription
classstringCSS class on the root <span>
idstringid on the root element
childrenChildrenAvatarImage and AvatarFallback

Methods

MethodDescription
setImageStatus(status)Sets the image load status ("idle" | "loading" | "loaded" | "error"). Called internally by AvatarImage on mount/load/error, but can also be called directly for custom loading integrations.

imageLoaded and imageError are also available as readonly getters (boolean) derived from the current status, if you need to branch on load state outside of the built-in AvatarImage / AvatarFallback visibility logic.

Props — AvatarImage

PropTypeDefaultDescription
avatarAvatarThe root Avatar instance
srcstringImage URL
altstringAlternative text (required for accessibility)
classstringCSS class on the <img>

Props — AvatarFallback

PropTypeDefaultDescription
avatarAvatarThe root Avatar instance
childrenChildrenFallback content (initials, icon, etc.)
classstringCSS class on the fallback <span>
idstringid on the fallback element

data-* attributes

AttributeElementWhen present
data-statusAvatar rootAlways — value is "idle", "loading", "loaded", or "error"

Status state machine

idle → loading → loaded
                ↘ error

AvatarImage sets status to "loading" on mount, then "loaded" or "error" based on the image's onLoad / onError events.

Visibility

AvatarImage is hidden (hidden attribute) until status is "loaded". AvatarFallback is hidden once the image has loaded. Both use the native hidden attribute — no JS class toggling needed.

Styling example

.morphos-avatar {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  overflow: hidden;
  border-radius: var(--morphos-radius-full);
  background: var(--morphos-color-bg-subtle);
  color: var(--morphos-color-text-muted);
  font-size: 0.875rem;
  font-weight: 500;
}

.morphos-avatar-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.morphos-avatar-image[hidden] {
  display: none;
}

.morphos-avatar-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
}

.morphos-avatar-fallback[hidden] {
  display: none;
}

Apply class="morphos-avatar" to Avatar, class="morphos-avatar-image" to AvatarImage, and class="morphos-avatar-fallback" to AvatarFallback. You can also target [data-status="error"] or [data-status="loading"] on the root for state-specific styling not covered by the recipe.

Always provide a meaningful alt on AvatarImage. If the avatar is purely decorative, pass alt="" so screen readers skip it.

On this page