import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { faUser } from '@fortawesome/free-solid-svg-icons'; import { BadgeComponent } from '../badge/badge.component'; export type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'; @Component({ selector: 'ui-avatar', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, FontAwesomeModule, BadgeComponent], template: `
@if (loading) {
} @else { @if (imageUrl && !imageError) { } @else {
@if (computedInitials) { } @else { }
} } @if (status) {
} @if (badge !== undefined && badge !== null) { {{ badge }} }
`, styleUrl: './avatar.component.scss' }) export class AvatarComponent { @Input() imageUrl?: string; @Input() name?: string; @Input() initials?: string; @Input() size: AvatarSize = 'md'; @Input() altText?: string; @Input() ariaLabel?: string; @Input() loading: boolean = false; @Input() status?: 'online' | 'offline' | 'away' | 'busy'; @Input() statusLabel?: string; @Input() badge?: string | number; @Input() badgeLabel?: string; faUser = faUser; imageError = false; onImageError(): void { this.imageError = true; } onImageLoad(): void { this.imageError = false; } // Auto-generate initials from name if not provided get computedInitials(): string { if (this.initials) { return this.initials.slice(0, 2).toUpperCase(); } if (this.name) { const nameParts = this.name.trim().split(/\s+/); if (nameParts.length >= 2) { return (nameParts[0][0] + nameParts[nameParts.length - 1][0]).toUpperCase(); } else if (nameParts[0]) { return nameParts[0].slice(0, 2).toUpperCase(); } } return ''; } }