Run the CLI
Use the CLI to add the component to your project.
npx @ngzard/ui@latest add avatarAn image element with a fallback for representing the user.



import { Component } from '@angular/core';
import { ZardAvatarGroupComponent } from '../avatar-group.component';
import { ZardAvatarComponent } from '../avatar.component';
@Component({
selector: 'z-demo-avatar-basic',
imports: [ZardAvatarComponent, ZardAvatarGroupComponent],
standalone: true,
template: `
<z-avatar zSrc="/images/avatar/imgs/avatar_image.jpg" zFallback="ZA" [zSize]="32" />
<z-avatar zSrc="error-image.png" zFallback="ZA" zSize="sm" />
<z-avatar-group>
<z-avatar zSrc="/images/avatar/imgs/avatar_image.jpg" zFallback="JD" zSize="sm" />
<z-avatar zSrc="https://github.com/srizzon.png" zFallback="SA" zSize="sm" />
<z-avatar zSrc="https://github.com/Luizgomess.png" zFallback="LU" zSize="sm" />
</z-avatar-group>
`,
})
export class ZardDemoAvatarBasicComponent {}
Use the CLI to add the component to your project.
npx @ngzard/ui@latest add avatarpnpm dlx @ngzard/ui@latest add avataryarn dlx @ngzard/ui@latest add avatarbunx @ngzard/ui@latest add avatarCreate the component directory structure and add the following files to your project.
import { ChangeDetectionStrategy, Component, computed, input, signal, ViewEncapsulation } from '@angular/core';
import { avatarVariants, imageVariants, type ZardImageVariants, type ZardAvatarVariants } from './avatar.variants';
import { mergeClasses } from '../../shared/utils/utils';
export type ZardAvatarStatus = 'online' | 'offline' | 'doNotDisturb' | 'away';
@Component({
selector: 'z-avatar, [z-avatar]',
standalone: true,
template: `
@if (zFallback() && (!zSrc() || !imageLoaded())) {
<span class="absolute z-0 m-auto text-base">{{ zFallback() }}</span>
}
@if (zSrc() && !imageError()) {
<img
[src]="zSrc()"
[alt]="zAlt()"
[class]="imgClasses()"
[hidden]="!imageLoaded()"
(load)="onImageLoad()"
(error)="onImageError()"
/>
}
@if (zStatus()) {
@switch (zStatus()) {
@case ('online') {
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="currentColor"
stroke="white"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="absolute -right-[5px] -bottom-[5px] z-20 h-5 w-5 text-green-500"
>
<circle cx="12" cy="12" r="10" fill="currentColor" />
</svg>
}
@case ('offline') {
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="currentColor"
stroke="white"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="absolute -right-[5px] -bottom-[5px] z-20 h-5 w-5 text-red-500"
>
<circle cx="12" cy="12" r="10" fill="currentColor" />
</svg>
}
@case ('doNotDisturb') {
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="currentColor"
stroke="white"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="absolute -right-[5px] -bottom-[5px] z-20 h-5 w-5 text-red-500"
>
<circle cx="12" cy="12" r="10" />
<path d="M8 12h8" fill="currentColor" />
</svg>
}
@case ('away') {
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="currentColor"
stroke="white"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="absolute -right-[5px] -bottom-[5px] z-20 h-5 w-5 rotate-y-180 text-yellow-400"
>
<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" fill="currentColor" />
</svg>
}
}
}
`,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
'[class]': 'containerClasses()',
'[style.width]': 'customSize()',
'[style.height]': 'customSize()',
'[attr.data-slot]': '"avatar"',
'[attr.data-status]': 'zStatus() ?? null',
},
exportAs: 'zAvatar',
})
export class ZardAvatarComponent {
readonly zStatus = input<ZardAvatarStatus>();
readonly zShape = input<ZardImageVariants['zShape']>('circle');
readonly zSize = input<ZardAvatarVariants['zSize'] | number>('default');
readonly zSrc = input<string>();
readonly zAlt = input<string>('');
readonly zFallback = input<string>('');
readonly class = input<string>('');
protected readonly imageError = signal(false);
protected readonly imageLoaded = signal(false);
protected readonly containerClasses = computed(() => {
const size = this.zSize();
const zSize = typeof size === 'number' ? undefined : (size as ZardAvatarVariants['zSize']);
return mergeClasses(avatarVariants({ zShape: this.zShape(), zSize }), this.class());
});
protected readonly customSize = computed(() => {
const size = this.zSize();
return typeof size === 'number' ? `${size}px` : null;
});
protected readonly imgClasses = computed(() => mergeClasses(imageVariants({ zShape: this.zShape() })));
protected onImageLoad(): void {
this.imageLoaded.set(true);
this.imageError.set(false);
}
protected onImageError(): void {
this.imageError.set(true);
this.imageLoaded.set(false);
}
}
import { cva, type VariantProps } from 'class-variance-authority';
export const avatarVariants = cva(
'relative flex flex-row items-center justify-center box-content cursor-default bg-muted',
{
variants: {
zSize: {
sm: 'size-8',
default: 'size-10',
md: 'size-12',
lg: 'size-14',
xl: 'size-16',
},
zShape: {
circle: 'rounded-full',
rounded: 'rounded-md',
square: 'rounded-none',
},
},
defaultVariants: {
zSize: 'default',
zShape: 'circle',
},
},
);
export const imageVariants = cva('relative object-cover object-center w-full h-full z-10', {
variants: {
zShape: {
circle: 'rounded-full',
rounded: 'rounded-md',
square: 'rounded-none',
},
},
defaultVariants: {
zShape: 'circle',
},
});
export const avatarGroupVariants = cva('flex items-center [&_img]:ring-2 [&_img]:ring-background', {
variants: {
zOrientation: {
horizontal: 'flex-row -space-x-3',
vertical: 'flex-col -space-y-3',
},
},
defaultVariants: {
zOrientation: 'horizontal',
},
});
export type ZardAvatarVariants = VariantProps<typeof avatarVariants>;
export type ZardImageVariants = VariantProps<typeof imageVariants>;
export type ZardAvatarGroupVariants = VariantProps<typeof avatarGroupVariants>;
import { ChangeDetectionStrategy, Component, computed, input, ViewEncapsulation } from '@angular/core';
import type { ClassValue } from 'clsx';
import { avatarGroupVariants, ZardAvatarGroupVariants } from './avatar.variants';
import { mergeClasses } from '../../shared/utils/utils';
@Component({
selector: 'z-avatar-group',
standalone: true,
template: `<ng-content />`,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
'[class]': 'classes()',
},
exportAs: 'zAvatarGroup',
})
export class ZardAvatarGroupComponent {
readonly zOrientation = input<ZardAvatarGroupVariants['zOrientation']>('horizontal');
readonly class = input<ClassValue>('');
protected readonly classes = computed(() =>
mergeClasses(avatarGroupVariants({ zOrientation: this.zOrientation() }), this.class()),
);
}



import { Component } from '@angular/core';
import { ZardAvatarGroupComponent } from '../avatar-group.component';
import { ZardAvatarComponent } from '../avatar.component';
@Component({
selector: 'z-demo-avatar-basic',
imports: [ZardAvatarComponent, ZardAvatarGroupComponent],
standalone: true,
template: `
<z-avatar zSrc="/images/avatar/imgs/avatar_image.jpg" zFallback="ZA" [zSize]="32" />
<z-avatar zSrc="error-image.png" zFallback="ZA" zSize="sm" />
<z-avatar-group>
<z-avatar zSrc="/images/avatar/imgs/avatar_image.jpg" zFallback="JD" zSize="sm" />
<z-avatar zSrc="https://github.com/srizzon.png" zFallback="SA" zSize="sm" />
<z-avatar zSrc="https://github.com/Luizgomess.png" zFallback="LU" zSize="sm" />
</z-avatar-group>
`,
})
export class ZardDemoAvatarBasicComponent {}
import { Component } from '@angular/core';
import { ZardAvatarComponent } from '../avatar.component';
@Component({
selector: 'z-demo-avatar-status',
imports: [ZardAvatarComponent],
standalone: true,
template: `
<z-avatar zSrc="/images/avatar/imgs/avatar_image.jpg" zAlt="Image" />
<z-avatar zStatus="online" zSrc="/images/avatar/imgs/avatar_image.jpg" zAlt="Image" />
<z-avatar zStatus="offline" zSrc="/images/avatar/imgs/avatar_image.jpg" zAlt="Image" />
<z-avatar zStatus="doNotDisturb" zSrc="/images/avatar/imgs/avatar_image.jpg" zAlt="Image" />
<z-avatar zStatus="away" zSrc="/images/avatar/imgs/avatar_image.jpg" zAlt="Image" />
`,
})
export class ZardDemoAvatarStatusComponent {}