forty-cdk
llms.txt

Primitives

Avatar

A user image with a graceful fallback across its loading lifecycle.

forty-cdk/avatar

Let the image load, then break its URL: data-status moves between loading, loaded and error, and the fallback only appears once the delay has passed without an image.

Ada Lovelace

It is headless and presentational: it tracks the load lifecycle of an <img> and lets you choose what to show while loading or after an error. There is no WAI-ARIA pattern for avatars, so the directive imposes no role of its own.

Anatomy

<span forAvatar #avatar="forAvatar">
  <img forAvatarImage [src]="src" [alt]="name" />
  <!-- rendered only when avatar.shouldShowFallback() is true -->
  <span forAvatarFallback>{{ initials }}</span>
</span>

Examples

Failed load

When the image errors, the directive flips shouldShowFallback() and the initials render in its place. An error shows the fallback at once, skipping the fallbackDelayMs wait.

Grace HopperGH

API

ForAvatar

PropertyTypeDescription
fallbackDelayMs
input
ms to wait before shouldShowFallback() flips to true while idle/loading.
Default: 0
status
Signal
Read-only current status.
Default: —
shouldShowFallback
Signal
true when the consumer should render the fallback. Drives @if.
Default: —
Data attributeValues
data-statusidle | loading | loaded | error

ForAvatarImage

PropertyTypeDescription
(loadStatusChange)
output
Output. Emits whenever the lifecycle transitions.
Default: —
Data attributeValues
data-statusidle | loading | loaded | error

ForAvatarFallback

Data attributeValues
data-statusidle | loading | loaded | error

Accessibility

The directive does not impose a role. Pair the avatar with visible name text or aria-label on the surrounding element when identity matters. Set alt="" on the <img> for purely decorative avatars next to a name, or provide a meaningful alt description if the avatar stands alone.

Styling

forty-cdk ships no styles: put your own class on each piece and key your CSS off the data-* attributes listed under API, not off the for* selectors (Styling forty-cdk explains why).

.avatar-image:not([data-status='loaded']) {
  display: none;
}
.avatar-fallback[data-status='error'] {
  color: #b00020;
}

Behavior notes

  • Cached images are detected on first render. If the browser already has the image cached, load/error may not fire. The directive checks <img>.complete and naturalWidth after the first render and reports loaded / error accordingly. A cached image that is complete but has zero intrinsic width (e.g. an SVG without explicit dimensions) is ambiguous, so the directive stays loading and confirms validity with img.decode() rather than pessimistically flagging error.
  • Multiple images per avatar are not supported. Each [forAvatar] expects exactly one [forAvatarImage]. If you need cascading sources (CDN → fallback URL → fallback content), swap src on a single image.
  • alt is consumer territory. Because <img> is the host element, the consumer keeps full control of alt. Set "" for purely decorative avatars next to a name, or describe the person if the avatar stands alone.
  • The image stays in the DOM. Hide it via CSS [data-status="loading"], [data-status="error"] { display: none } if your consumer-side styling needs it gone. The fallback uses @if, so it only mounts when needed.

Wrapping in a design system

Subclass the root and re-provide FOR_AVATAR_CONTEXT with useExisting pointing at the subclass, since Angular does not inherit a directive's providers; Wrapping non-form roots walks the pattern.