Avatar

A circular avatar with image, fallback, status badge and group support.

import { … } from '@inlaylab/ivorie/avatar'
ALGH
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_AVATAR_IMPORTS } from '@inlaylab/ivorie/avatar';

@Component({
  selector: 'demo-avatar',
  imports: [IV_AVATAR_IMPORTS],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <div class="flex items-center gap-4">
      <iv-avatar>
        <iv-avatar-image src="avatar.svg" alt="Ada Lovelace" />
        <iv-avatar-fallback>AL</iv-avatar-fallback>
      </iv-avatar>
      <iv-avatar>
        <iv-avatar-fallback>GH</iv-avatar-fallback>
      </iv-avatar>
    </div>
  `,
})
export default class AvatarDemo {}

Installation

CLInpm
npx ivorie add avatar

The fallback shows until the image has loaded. It stays if the image fails.

Usage

import { IV_AVATAR_IMPORTS } from '@inlaylab/ivorie/avatar';
<iv-avatar>
  <iv-avatar-image src="/me.png" alt="Ada Lovelace"></iv-avatar-image>
  <iv-avatar-fallback>AL</iv-avatar-fallback>
</iv-avatar>

Examples

Sizes

SDL
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_AVATAR_IMPORTS } from '@inlaylab/ivorie/avatar';

@Component({
  selector: 'demo-avatar-sizes',
  imports: [IV_AVATAR_IMPORTS],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <div class="flex items-center gap-4">
      <iv-avatar size="sm">
        <iv-avatar-image src="avatar.svg" alt="Small" />
        <iv-avatar-fallback>S</iv-avatar-fallback>
      </iv-avatar>
      <iv-avatar>
        <iv-avatar-image src="avatar.svg" alt="Default" />
        <iv-avatar-fallback>D</iv-avatar-fallback>
      </iv-avatar>
      <iv-avatar size="lg">
        <iv-avatar-image src="avatar.svg" alt="Large" />
        <iv-avatar-fallback>L</iv-avatar-fallback>
      </iv-avatar>
    </div>
  `,
})
export default class AvatarSizesDemo {}

Badge

AL
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_AVATAR_IMPORTS } from '@inlaylab/ivorie/avatar';

@Component({
  selector: 'demo-avatar-badge',
  imports: [IV_AVATAR_IMPORTS],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <iv-avatar>
      <iv-avatar-image src="avatar.svg" alt="Ada Lovelace" />
      <iv-avatar-fallback>AL</iv-avatar-fallback>
      <iv-avatar-badge class="bg-primary ring-background" />
    </iv-avatar>
  `,
})
export default class AvatarBadgeDemo {}

Group

AGL+3
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_AVATAR_IMPORTS } from '@inlaylab/ivorie/avatar';

@Component({
  selector: 'demo-avatar-group',
  imports: [IV_AVATAR_IMPORTS],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <iv-avatar-group>
      <iv-avatar>
        <iv-avatar-image src="avatar.svg" alt="Ada" />
        <iv-avatar-fallback>A</iv-avatar-fallback>
      </iv-avatar>
      <iv-avatar>
        <iv-avatar-image src="avatar.svg" alt="Grace" />
        <iv-avatar-fallback>G</iv-avatar-fallback>
      </iv-avatar>
      <iv-avatar>
        <iv-avatar-image src="avatar.svg" alt="Linus" />
        <iv-avatar-fallback>L</iv-avatar-fallback>
      </iv-avatar>
      <iv-avatar-group-count>+3</iv-avatar-group-count>
    </iv-avatar-group>
  `,
})
export default class AvatarGroupDemo {}

API

Every part also accepts class.

iv-avatar

Name Type Default Description
size 'default' | 'sm' | 'lg' 'default' Avatar size. Children (badge, fallback text) scale with it.

iv-avatar-image

Name Type Default Description
src string required Image URL.
alt string '' Alternative text.

iv-avatar-fallback

No inputs besides class. Hidden once the image has loaded.

iv-avatar-badge

No inputs besides class. Status dot at the bottom right. At sm size, svg children are hidden.

iv-avatar-group

No inputs besides class. Overlaps its avatars with a background ring.

iv-avatar-group-count

No inputs besides class. An overflow chip such as +3.

Accessibility

Give the image a meaningful alt. For a person, use their name. The fallback text is the visible stand-in, so keep it short, for example initials.

Notes

With SSR the image may finish loading before hydration. The image checks its state once after first render, so the fallback still resolves correctly.