npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@libs-ui/components-avatar

v0.2.357-35

Published

> Component hiển thị avatar (ảnh đại diện) với cơ chế fallback thông minh sang text/icon khi ảnh lỗi hoặc không có.

Readme

@libs-ui/components-avatar

Component hiển thị avatar (ảnh đại diện) với cơ chế fallback thông minh sang text/icon khi ảnh lỗi hoặc không có.

Giới thiệu

LibsUiComponentsAvatarComponent là standalone Angular component dùng để hiển thị ảnh đại diện người dùng. Component hỗ trợ nhiều kích thước và hình dạng, tự động fallback sang text với màu nền được generate từ ID khi ảnh không tải được, và tích hợp gallery viewer để xem ảnh phóng to khi click.

Tính năng

  • Hiển thị ảnh avatar từ URL với xử lý lỗi tự động
  • Fallback thông minh theo chuỗi: linkAvatar → linkAvatarError → text + màu nền từ idGenColor
  • Hỗ trợ 6 kích thước: 16, 24, 32, 40, 48, 64px
  • Hỗ trợ 2 hình dạng: circle (mặc định) và rectangle
  • Tự động generate màu nền nhất quán từ ID (hash color — cùng ID luôn ra cùng màu)
  • Font size của text fallback tự động điều chỉnh theo kích thước avatar
  • Preview ảnh phóng to khi click (tích hợp LibsUiComponentsGalleryViewerComponent)
  • Angular Signals + Standalone Component

Khi nào sử dụng

  • Hiển thị ảnh đại diện người dùng trong danh sách, comment, profile
  • Hiển thị avatar có fallback khi ảnh không tải được hoặc chưa có ảnh
  • Cần hiển thị avatar với nhiều kích thước khác nhau trong cùng giao diện
  • Cần cho phép người dùng xem ảnh phóng to khi click vào avatar

Cài đặt

npm install @libs-ui/components-avatar

Import

import {
  LibsUiComponentsAvatarComponent,
  IAvatarConfig,
  TYPE_SHAPE_AVATAR,
  TYPE_SIZE_AVATAR_CONFIG,
} from '@libs-ui/components-avatar';

@Component({
  standalone: true,
  imports: [LibsUiComponentsAvatarComponent],
  // ...
})
export class MyComponent {}

Ví dụ sử dụng

1. Avatar cơ bản với ảnh

<libs_ui-components-avatar
  [linkAvatar]="'https://example.com/user-123.jpg'"
  [size]="40" />

2. Avatar với fallback text (khi ảnh lỗi)

Khi linkAvatar lỗi và không có linkAvatarError, component sẽ hiển thị ký tự đầu của textAvatar trên nền màu được generate từ idGenColor.

<libs_ui-components-avatar
  [linkAvatar]="'https://example.com/user-123.jpg'"
  [textAvatar]="'Nguyễn Văn An'"
  [idGenColor]="'user-123'"
  [size]="40"
  (outAvatarError)="handlerAvatarError()" />
handlerAvatarError(): void {
  // Ảnh không tải được, component đã tự hiển thị text fallback
  console.log('Avatar fallback to text');
}

3. Avatar với ảnh dự phòng và text cuối cùng

<!-- getLastTextAfterSpace PHẢI được truyền TRƯỚC textAvatar -->
<libs_ui-components-avatar
  [linkAvatar]="'https://example.com/user-456.jpg'"
  [linkAvatarError]="'https://example.com/default-avatar.png'"
  [getLastTextAfterSpace]="true"
  [textAvatar]="'Trần Thị Bích'"
  [idGenColor]="'user-456'"
  [size]="40" />

Khi getLastTextAfterSpace = true, text 'Trần Thị Bích' sẽ lấy ký tự đầu của từ cuối cùng → hiển thị B.

4. Avatar hình chữ nhật

<libs_ui-components-avatar
  [linkAvatar]="'https://example.com/company-logo.jpg'"
  [typeShape]="'rectangle'"
  [size]="48" />

5. Avatar có thể click để xem phóng to

<libs_ui-components-avatar
  [linkAvatar]="'https://example.com/user-photo.jpg'"
  [clickPreviewImage]="true"
  [zIndexPreviewImage]="1050"
  [size]="64"
  (outEventPreviewImage)="handlerPreviewImageEvent($event)" />
handlerPreviewImageEvent(state: 'open' | 'remove'): void {
  if (state === 'open') {
    console.log('Gallery viewer mở');
  } else {
    console.log('Gallery viewer đóng');
  }
}

6. Danh sách avatar người dùng

import { Component } from '@angular/core';
import { LibsUiComponentsAvatarComponent } from '@libs-ui/components-avatar';

interface User {
  id: string;
  name: string;
  avatarUrl: string;
}

@Component({
  standalone: true,
  imports: [LibsUiComponentsAvatarComponent],
  template: `
    <div class="flex items-center gap-2">
      @for (user of users; track user.id) {
        <libs_ui-components-avatar
          [linkAvatar]="user.avatarUrl"
          [textAvatar]="user.name"
          [idGenColor]="user.id"
          [classInclude]="''"
          [size]="32" />
      }
    </div>
  `,
})
export class UserListComponent {
  users: User[] = [
    { id: 'u1', name: 'Nguyen Van A', avatarUrl: 'https://example.com/u1.jpg' },
    { id: 'u2', name: 'Tran Thi B',   avatarUrl: 'https://example.com/u2.jpg' },
    { id: 'u3', name: 'Le Van C',     avatarUrl: 'https://example.com/u3.jpg' },
  ];
}

7. Tùy chỉnh class CSS

<libs_ui-components-avatar
  [linkAvatar]="'https://example.com/avatar.jpg'"
  [size]="40"
  [classInclude]="'mr-0'"
  [classImageInclude]="'opacity-90'"
  [textAvatarClassInclude]="'font-bold'"
  [containerTextAvatarClassInclude]="'border border-white'" />

@Input()

| Input | Type | Default | Mô tả | Ví dụ | |---|---|---|---|---| | [classInclude] | string \| undefined | 'mr-[8px]' | Class CSS tùy chỉnh cho thẻ container ngoài cùng | [classInclude]="'mr-0 mb-2'" | | [classImageInclude] | string \| undefined | '' | Class CSS tùy chỉnh cho thẻ <img> | [classImageInclude]="'opacity-80'" | | [clickPreviewImage] | boolean \| undefined | undefined | Bật tính năng click để xem ảnh phóng to qua gallery viewer | [clickPreviewImage]="true" | | [containerTextAvatarClassInclude] | string \| undefined | '' | Class CSS tùy chỉnh cho container bọc ngoài text fallback | [containerTextAvatarClassInclude]="'border-2'" | | [getLastTextAfterSpace] | boolean \| undefined | undefined | Lấy từ cuối cùng (sau khoảng trắng cuối) để hiển thị ký tự đầu. Phải truyền TRƯỚC textAvatar | [getLastTextAfterSpace]="true" | | [idGenColor] | string \| undefined | undefined | ID dùng để generate màu nền khi hiển thị text fallback. Cùng ID luôn ra cùng màu | [idGenColor]="'user-123'" | | [linkAvatar] | string \| undefined | undefined | URL ảnh avatar chính | [linkAvatar]="user.photoUrl" | | [linkAvatarError] | string \| undefined | undefined | URL ảnh dự phòng khi linkAvatar bị lỗi | [linkAvatarError]="'/assets/default.png'" | | [size] | TYPE_SIZE_AVATAR_CONFIG \| undefined | 32 | Kích thước (px) của avatar. Chỉ chấp nhận các giá trị: 16, 24, 32, 40, 48, 64 | [size]="40" | | [textAvatar] | string \| undefined | '' | Text dùng để hiển thị ký tự đầu khi fallback. Tự động loại bỏ unicode và ký tự đặc biệt | [textAvatar]="user.fullName" | | [textAvatarClassInclude] | string \| undefined | '' | Class CSS tùy chỉnh cho phần tử chứa ký tự text fallback | [textAvatarClassInclude]="'tracking-wide'" | | [typeShape] | TYPE_SHAPE_AVATAR \| undefined | 'circle' | Hình dạng của avatar: 'circle' (border-radius 50%) hoặc 'rectangle' (border-radius 4px) | [typeShape]="'rectangle'" | | [zIndexPreviewImage] | number \| undefined | undefined | Z-index cho gallery viewer khi xem ảnh phóng to. Cần set khi giao diện có overlay/modal | [zIndexPreviewImage]="1050" |

@Output()

| Output | Type | Mô tả | Handler TS | Binding HTML | |---|---|---|---|---| | (outAvatarError) | void | Phát ra khi tất cả nguồn ảnh đều thất bại (cả linkAvatar lẫn linkAvatarError) và component chuyển sang hiển thị text fallback | handlerAvatarError(): void { console.log('Avatar fallback'); } | (outAvatarError)="handlerAvatarError()" | | (outEventPreviewImage) | 'open' \| 'remove' | Phát ra khi gallery viewer được mở ('open') hoặc đóng ('remove') | handlerPreviewImageEvent(state: 'open' \| 'remove'): void { console.log(state); } | (outEventPreviewImage)="handlerPreviewImageEvent($event)" |

Types & Interfaces

import {
  IAvatarConfig,
  TYPE_SHAPE_AVATAR,
  TYPE_SIZE_AVATAR_CONFIG,
} from '@libs-ui/components-avatar';

// Kích thước được hỗ trợ (px)
// Font size text fallback tự động: 16/24 → h6s, 32 → h4s, 40 → h3s, 64 → h1s, mặc định → h4s
export type TYPE_SIZE_AVATAR_CONFIG = 16 | 24 | 32 | 40 | 48 | 64;

// Hình dạng avatar
// 'circle'    → border-radius: 50%
// 'rectangle' → border-radius: 4px
export type TYPE_SHAPE_AVATAR = 'circle' | 'rectangle';

// Interface config dùng khi cần truyền object config từ component cha
export interface IAvatarConfig {
  classImageInclude?: string;
  classInclude?: string;
  size?: TYPE_SIZE_AVATAR_CONFIG;
  linkAvatar?: string;
  linkAvatarError?: string;
  idGenColor?: string;
  textAvatar?: string;
  typeShape?: TYPE_SHAPE_AVATAR;
  getLastTextAfterSpace?: boolean;
}

Ví dụ dùng IAvatarConfig để truyền config từ component cha:

// parent.component.ts
import { IAvatarConfig } from '@libs-ui/components-avatar';

avatarConfig: IAvatarConfig = {
  linkAvatar: 'https://example.com/avatar.jpg',
  textAvatar: 'Nguyen Van An',
  idGenColor: 'user-001',
  size: 40,
  typeShape: 'circle',
};
<!-- parent.component.html -->
<libs_ui-components-avatar
  [linkAvatar]="avatarConfig.linkAvatar"
  [textAvatar]="avatarConfig.textAvatar"
  [idGenColor]="avatarConfig.idGenColor"
  [size]="avatarConfig.size"
  [typeShape]="avatarConfig.typeShape" />

Lưu ý quan trọng

⚠️ Thứ tự input getLastTextAfterSpace: Input [getLastTextAfterSpace] PHẢI được khai báo trong template TRƯỚC [textAvatar]. Nếu khai báo sau, transform của textAvatar sẽ chạy trước khi đọc được giá trị getLastTextAfterSpace, dẫn đến kết quả sai.

⚠️ Chuỗi fallback xử lý lỗi ảnh: Component xử lý lỗi theo thứ tự: linkAvatar → (lỗi) → linkAvatarError → (lỗi) → hiển thị text từ textAvatar với màu nền từ idGenColor. Nếu không cung cấp idGenColor và textAvatar, output (outAvatarError) sẽ phát ra ngay sau lần lỗi đầu tiên mà không hiển thị fallback.

⚠️ Màu nền nhất quán: Màu nền khi hiển thị text fallback được tính từ idGenColor qua hàm hash. Cùng một giá trị idGenColor luôn cho ra cùng một màu, đảm bảo nhất quán giao diện giữa các lần render.

⚠️ Preview image và lifecycle: Khi [clickPreviewImage]="true", component tự khởi tạo và quản lý vòng đời của LibsUiComponentsGalleryViewerComponent. Gallery viewer sẽ tự bị hủy khi avatar component bị destroy (xử lý trong ngOnDestroy).

⚠️ Transform text: textAvatar được tự động xử lý: loại bỏ unicode tiếng Việt (normalize), xóa ký tự đặc biệt (giữ lại chữ và số), trim khoảng trắng, rồi lấy ký tự đầu tiên. Nếu sau xử lý không còn ký tự nào, hiển thị —.