11
22
33``` angular-ts title="avatar.component.ts" expandable="true" expandableTitle="Expand" copyButton showLineNumbers
4- import { ChangeDetectionStrategy, Component, computed, input, signal, ViewEncapsulation } from '@angular/core';
5-
6- import { avatarVariants, imageVariants, type ZardImageVariants, type ZardAvatarVariants } from './avatar.variants';
4+ import { NgOptimizedImage } from '@angular/common';
5+ import {
6+ booleanAttribute,
7+ ChangeDetectionStrategy,
8+ Component,
9+ computed,
10+ effect,
11+ input,
12+ signal,
13+ ViewEncapsulation,
14+ } from '@angular/core';
15+ import type { SafeUrl } from '@angular/platform-browser';
716
817import { mergeClasses } from '@/shared/utils/merge-classes';
918
19+ import { avatarVariants, imageVariants, type ZardAvatarVariants, type ZardImageVariants } from './avatar.variants';
20+
1021export type ZardAvatarStatus = 'online' | 'offline' | 'doNotDisturb' | 'away';
1122
1223@Component({
1324 selector: 'z-avatar, [z-avatar]',
14- standalone: true ,
25+ imports: [NgOptimizedImage] ,
1526 template: `
1627 @if (zFallback() && (!zSrc() || !imageLoaded())) {
1728 <span class="absolute z-0 m-auto text-base">{{ zFallback() }}</span>
1829 }
1930
2031 @if (zSrc() && !imageError()) {
2132 <img
22- [src]="zSrc()"
33+ fill
34+ sizes="100%"
2335 [alt]="zAlt()"
2436 [class]="imgClasses()"
25- [hidden ]="!imageLoaded ()"
26- (load)="onImageLoad ()"
37+ [ngSrc ]="zSrc ()"
38+ [priority]="zPriority ()"
2739 (error)="onImageError()"
40+ (load)="onImageLoad()"
2841 />
2942 }
3043
@@ -41,7 +54,7 @@ export type ZardAvatarStatus = 'online' | 'offline' | 'doNotDisturb' | 'away';
4154 stroke-width="2"
4255 stroke-linecap="round"
4356 stroke-linejoin="round"
44- class="absolute -right-[5px] -bottom-[5px] z-20 h-5 w-5 text-green-500"
57+ class="absolute -right-1.25 -bottom-1.25 z-20 h-5 w-5 text-green-500"
4558 >
4659 <circle cx="12" cy="12" r="10" fill="currentColor" />
4760 </svg>
@@ -57,7 +70,7 @@ export type ZardAvatarStatus = 'online' | 'offline' | 'doNotDisturb' | 'away';
5770 stroke-width="2"
5871 stroke-linecap="round"
5972 stroke-linejoin="round"
60- class="absolute -right-[5px] -bottom-[5px] z-20 h-5 w-5 text-red-500"
73+ class="absolute -right-1.25 -bottom-1.25 z-20 h-5 w-5 text-red-500"
6174 >
6275 <circle cx="12" cy="12" r="10" fill="currentColor" />
6376 </svg>
@@ -73,7 +86,7 @@ export type ZardAvatarStatus = 'online' | 'offline' | 'doNotDisturb' | 'away';
7386 stroke-width="2"
7487 stroke-linecap="round"
7588 stroke-linejoin="round"
76- class="absolute -right-[5px] -bottom-[5px] z-20 h-5 w-5 text-red-500"
89+ class="absolute -right-1.25 -bottom-1.25 z-20 h-5 w-5 text-red-500"
7790 >
7891 <circle cx="12" cy="12" r="10" />
7992 <path d="M8 12h8" fill="currentColor" />
@@ -90,7 +103,7 @@ export type ZardAvatarStatus = 'online' | 'offline' | 'doNotDisturb' | 'away';
90103 stroke-width="2"
91104 stroke-linecap="round"
92105 stroke-linejoin="round"
93- class="absolute -right-[5px] -bottom-[5px] z-20 h-5 w-5 rotate-y-180 text-yellow-400"
106+ class="absolute -right-1.25 -bottom-1.25 z-20 h-5 w-5 rotate-y-180 text-yellow-400"
94107 >
95108 <path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" fill="currentColor" />
96109 </svg>
@@ -110,17 +123,26 @@ export type ZardAvatarStatus = 'online' | 'offline' | 'doNotDisturb' | 'away';
110123 exportAs: 'zAvatar',
111124})
112125export class ZardAvatarComponent {
113- readonly zStatus = input<ZardAvatarStatus>();
114- readonly zShape = input<ZardImageVariants['zShape']>('circle');
115- readonly zSize = input<ZardAvatarVariants['zSize'] | number>('default');
116- readonly zSrc = input<string>();
126+ readonly class = input<string>('');
117127 readonly zAlt = input<string>('');
118128 readonly zFallback = input<string>('');
129+ readonly zPriority = input(false, { transform: booleanAttribute });
130+ readonly zShape = input<ZardImageVariants['zShape']>('circle');
131+ readonly zSize = input<ZardAvatarVariants['zSize'] | number>('default');
132+ readonly zSrc = input<string | SafeUrl>('');
133+ readonly zStatus = input<ZardAvatarStatus>();
119134
120- readonly class = input<string>('');
135+ readonly imageError = signal(false);
136+ readonly imageLoaded = signal(false);
121137
122- protected readonly imageError = signal(false);
123- protected readonly imageLoaded = signal(false);
138+ constructor() {
139+ effect(() => {
140+ // Reset image state when zSrc changes
141+ this.zSrc();
142+ this.imageError.set(false);
143+ this.imageLoaded.set(false);
144+ });
145+ }
124146
125147 protected readonly containerClasses = computed(() => {
126148 const size = this.zSize();
0 commit comments