@libs-ui/icons
v0.2.357-9
Published
> Bộ SVG icon components và pipe lazy-load dùng trong hệ sinh thái libs-ui.
Readme
@libs-ui/icons
Bộ SVG icon components và pipe lazy-load dùng trong hệ sinh thái libs-ui.
Giới thiệu
@libs-ui/icons cung cấp tập hợp các SVG icon được đóng gói thành Angular Standalone Component, hỗ trợ tùy biến kích thước và màu sắc thông qua Signal API. Thư viện còn bao gồm pipe LibsUiIconsGetIconComponentPipe để lazy-load icon component theo key string, phù hợp cho các trường hợp render icon động tại runtime mà không cần import tĩnh từng component.
Tính năng
- ✅ 13 icon component SVG sẵn dùng (file types, AI, trạng thái rỗng, reload, v.v.)
- ✅ Tùy biến
sizevàcolorthông qua Signalinput() - ✅ Hỗ trợ trạng thái
activevới màu riêng (colorActive) - ✅ Pipe lazy-load icon theo key string — không import tĩnh toàn bộ bundle
- ✅ Mọi component đều Standalone +
ChangeDetectionStrategy.OnPush - ✅ Abstract base class
LibsUiIconsComponentAbstractđể mở rộng icon mới nhất quán
Khi nào sử dụng
- Hiển thị icon định dạng file (PDF, Word, Excel, PPTX, JSON, XML) trong danh sách tài liệu hoặc upload preview
- Hiển thị trạng thái rỗng (
no-data,no-result) trong bảng dữ liệu hoặc màn hình list - Sử dụng icon AI (
ai,ai-interaction,sparkles-ai-solid) trong các tính năng trí tuệ nhân tạo - Render icon động theo key từ API/config mà không biết trước loại icon khi build
- Tích hợp icon
reload,send-solid,stop-solidvào các nút hành động
Cài đặt
npm install @libs-ui/iconsImport
// Import từng icon component cụ thể
import { LibsUiIconsAiComponent } from '@libs-ui/icons';
import { LibsUiIconsPdfComponent } from '@libs-ui/icons';
import { LibsUiIconsNoDataComponent } from '@libs-ui/icons';
import { LibsUiIconsReloadComponent } from '@libs-ui/icons';
import { LibsUiIconsSendSolidComponent } from '@libs-ui/icons';
import { LibsUiIconsStopSolidComponent } from '@libs-ui/icons';
import { LibsUiIconsSparklesAiSolidComponent } from '@libs-ui/icons';
import { LibsUiIconsAiInteractionComponent } from '@libs-ui/icons';
import { LibsUiIconsNoResultComponent } from '@libs-ui/icons';
import { LibsUiIconsWordComponent } from '@libs-ui/icons';
import { LibsUiIconsXlsxComponent } from '@libs-ui/icons';
import { LibsUiIconsPptxComponent } from '@libs-ui/icons';
import { LibsIconsJsonComponent } from '@libs-ui/icons';
import { LibsUiIconsXmlComponent } from '@libs-ui/icons';
import { LibsIconsImageDefaultComponent } from '@libs-ui/icons';
// Import pipe lazy-load
import { LibsUiIconsGetIconComponentPipe } from '@libs-ui/icons';
// Import abstract base class (khi tạo icon mới)
import { LibsUiIconsComponentAbstract } from '@libs-ui/icons';Ví dụ sử dụng
Ví dụ 1 — Icon cơ bản với size và color tùy chỉnh
import { Component } from '@angular/core';
import { ChangeDetectionStrategy } from '@angular/core';
import { LibsUiIconsPdfComponent } from '@libs-ui/icons';
import { LibsUiIconsWordComponent } from '@libs-ui/icons';
import { LibsUiIconsXlsxComponent } from '@libs-ui/icons';
@Component({
selector: 'app-file-icon-demo',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [LibsUiIconsPdfComponent, LibsUiIconsWordComponent, LibsUiIconsXlsxComponent],
template: `
<!-- PDF icon — size 24, màu mặc định -->
<libs_ui-icons-pdf [size]="24" />
<!-- Word icon — size 32 (mặc định) -->
<libs_ui-icons-word />
<!-- Excel icon — size 40, màu tùy chỉnh -->
<libs_ui-icons-xlsx [size]="40" [color]="'#217346'" />
`,
})
export class FileIconDemoComponent {}Ví dụ 2 — Icon trạng thái rỗng
import { Component } from '@angular/core';
import { ChangeDetectionStrategy } from '@angular/core';
import { LibsUiIconsNoDataComponent } from '@libs-ui/icons';
import { LibsUiIconsNoResultComponent } from '@libs-ui/icons';
@Component({
selector: 'app-empty-state-demo',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [LibsUiIconsNoDataComponent, LibsUiIconsNoResultComponent],
template: `
<!-- Khi không có dữ liệu nào -->
<div class="flex flex-col items-center gap-2">
<libs_ui-icons-no_data [size]="65" />
<span class="libs-ui-font-h5r">Chưa có dữ liệu</span>
</div>
<!-- Khi tìm kiếm không có kết quả -->
<div class="flex flex-col items-center gap-2">
<libs_ui-icons-no_result [size]="65" />
<span class="libs-ui-font-h5r">Không tìm thấy kết quả</span>
</div>
`,
})
export class EmptyStateDemoComponent {}Ví dụ 3 — Icon AI với trạng thái active
import { Component, signal } from '@angular/core';
import { ChangeDetectionStrategy } from '@angular/core';
import { LibsUiIconsAiComponent } from '@libs-ui/icons';
import { LibsUiIconsSparklesAiSolidComponent } from '@libs-ui/icons';
import { LibsUiIconsSendSolidComponent } from '@libs-ui/icons';
import { LibsUiIconsStopSolidComponent } from '@libs-ui/icons';
@Component({
selector: 'app-ai-icon-demo',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
LibsUiIconsAiComponent,
LibsUiIconsSparklesAiSolidComponent,
LibsUiIconsSendSolidComponent,
LibsUiIconsStopSolidComponent,
],
template: `
<!-- AI icon gradient — size 32 (mặc định) -->
<libs_ui-icons-ai [size]="32" />
<!-- Sparkles AI solid — màu xanh mặc định #226FF5 -->
<libs_ui-icons-sparkles_ai_solid [size]="24" />
<!-- Send solid — active state đổi màu -->
<libs_ui-icons-send_solid
[size]="24"
[color]="'#226FF5'"
[colorActive]="'#0050CC'"
[active]="isActive()" />
<!-- Stop solid — dừng stream AI -->
<libs_ui-icons-stop_solid [size]="24" [color]="'#226FF5'" />
`,
})
export class AiIconDemoComponent {
protected isActive = signal(false);
}Ví dụ 4 — Lazy-load icon bằng pipe (render động)
import { Component, signal } from '@angular/core';
import { AsyncPipe, NgComponentOutlet } from '@angular/common';
import { ChangeDetectionStrategy } from '@angular/core';
import { LibsUiIconsGetIconComponentPipe } from '@libs-ui/icons';
@Component({
selector: 'app-dynamic-icon-demo',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [AsyncPipe, NgComponentOutlet, LibsUiIconsGetIconComponentPipe],
template: `
<!-- Lazy-load icon theo key động -->
@for (file of files(); track file.id) {
<ng-container
*ngComponentOutlet="file.type | LibsUiIconsGetIconComponentPipe | async" />
}
`,
})
export class DynamicIconDemoComponent {
protected files = signal([
{ id: '1', name: 'report.pdf', type: 'pdf' },
{ id: '2', name: 'data.xlsx', type: 'xlsx' },
{ id: '3', name: 'doc.docx', type: 'word' },
{ id: '4', name: 'data.json', type: 'json' },
]);
}Ví dụ 5 — Icon reload và ai-interaction
import { Component } from '@angular/core';
import { ChangeDetectionStrategy } from '@angular/core';
import { LibsUiIconsReloadComponent } from '@libs-ui/icons';
import { LibsUiIconsAiInteractionComponent } from '@libs-ui/icons';
@Component({
selector: 'app-action-icon-demo',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [LibsUiIconsReloadComponent, LibsUiIconsAiInteractionComponent],
template: `
<!-- Reload icon — màu xám mặc định #6A7383 -->
<button (click)="handlerReload($event)" class="p-2 hover:bg-gray-100 rounded">
<libs_ui-icons-reload [size]="20" />
</button>
<!-- AI Interaction icon — size 32 mặc định -->
<libs_ui-icons-ai-interaction [size]="28" />
`,
})
export class ActionIconDemoComponent {
protected handlerReload(event: Event): void {
event.stopPropagation();
// xử lý reload
}
}@Input() — Shared (tất cả icon components)
Tất cả icon component đều kế thừa LibsUiIconsComponentAbstract và có chung các input sau:
| Input | Type | Default | Mô tả | Ví dụ |
|---|---|---|---|---|
| size | number | 16 (xem bảng riêng) | Kích thước icon theo px (áp dụng cho cả width và height của SVG) | [size]="24" |
| color | string | '#e6e7ea' (xem bảng riêng) | Màu fill mặc định của icon khi không active | [color]="'#333333'" |
| colorActive | string | '#9CA2AD' | Màu fill của icon khi active là true | [colorActive]="'#0050CC'" |
| active | boolean | undefined | Khi true, icon hiển thị với màu colorActive thay vì color | [active]="isSelected()" |
Default size và color theo từng component
| Component | Selector | Default size | Default color |
|---|---|---|---|
| LibsUiIconsAiComponent | libs_ui-icons-ai | 32 | #e6e7ea (gradient SVG) |
| LibsUiIconsAiInteractionComponent | libs_ui-icons-ai-interaction | 32 | #e6e7ea |
| LibsIconsImageDefaultComponent | libs_ui-icons-image_default | 64 | #e6e7ea |
| LibsIconsJsonComponent | libs_ui-icons-json | 32 | #e6e7ea |
| LibsUiIconsNoDataComponent | libs_ui-icons-no_data | 16* | #e6e7ea |
| LibsUiIconsNoResultComponent | libs_ui-icons-no_result | 16* | #e6e7ea |
| LibsUiIconsPdfComponent | libs_ui-icons-pdf | 32 | #e6e7ea |
| LibsUiIconsPptxComponent | libs_ui-icons-pptx | 32 | #e6e7ea |
| LibsUiIconsReloadComponent | libs_ui-icons-reload | 32 | #6A7383 |
| LibsUiIconsSendSolidComponent | libs_ui-icons-send_solid | 32 | #226FF5 |
| LibsUiIconsSparklesAiSolidComponent | libs_ui-icons-sparkles_ai_solid | 32 | #226FF5 |
| LibsUiIconsStopSolidComponent | libs_ui-icons-stop_solid | 32 | #226FF5 |
| LibsUiIconsWordComponent | libs_ui-icons-word | 32 | #e6e7ea |
| LibsUiIconsXlsxComponent | libs_ui-icons-xlsx | 32 | #e6e7ea |
| LibsUiIconsXmlComponent | libs_ui-icons-xml | 32 | #e6e7ea |
* no-data/no-result khai báo input(16, { transform: (v) => v ?? 65 }) — theo cơ chế input() của Angular, transform chỉ chạy khi có giá trị được binding từ template (kể cả undefined), KHÔNG áp dụng cho giá trị khởi tạo khi hoàn toàn không binding [size]. Do đó nếu bỏ trống [size] hoàn toàn, giá trị thực tế là 16; chỉ khi binding rõ [size]="undefined" mới ra 65. Luôn truyền [size] tường minh (ví dụ [size]="65") để tránh phụ thuộc vào chi tiết này.
Pipe — LibsUiIconsGetIconComponentPipe
Pipe async lazy-load icon component theo key string. Trả về Promise<Type<any> | null>, dùng kết hợp với AsyncPipe và NgComponentOutlet.
| Tham số | Type | Bắt buộc | Mô tả | Ví dụ |
|---|---|---|---|---|
| key | string \| undefined | Không | Key định danh icon. Xem bảng key hợp lệ bên dưới | 'pdf' |
Key hợp lệ
| Key | Component được lazy-load |
|---|---|
| 'no-data' | LibsUiIconsNoDataComponent |
| 'no-result' | LibsUiIconsNoResultComponent |
| 'json' | LibsIconsJsonComponent |
| 'pdf' | LibsUiIconsPdfComponent |
| 'pptx' | LibsUiIconsPptxComponent |
| 'word' | LibsUiIconsWordComponent |
| 'xlsx' | LibsUiIconsXlsxComponent |
| 'xml' | LibsUiIconsXmlComponent |
| 'image-default' | LibsIconsImageDefaultComponent |
| 'ai' | LibsUiIconsAiComponent |
| 'ai-interaction' | LibsUiIconsAiInteractionComponent |
| 'reload' | LibsUiIconsReloadComponent |
| 'send-solid' | LibsUiIconsSendSolidComponent |
| 'sparkles-ai-solid' | LibsUiIconsSparklesAiSolidComponent |
| 'stop-solid' | LibsUiIconsStopSolidComponent |
| Bất kỳ key khác | null (không render) |
Sử dụng pipe trong template
<!-- Kết hợp async pipe + NgComponentOutlet -->
<ng-container
*ngComponentOutlet="'pdf' | LibsUiIconsGetIconComponentPipe | async" />Sử dụng pipe trong TypeScript (standalone)
import { LibsUiIconsGetIconComponentPipe } from '@libs-ui/icons';
const pipe = new LibsUiIconsGetIconComponentPipe();
const component = await pipe.transform('pdf');
// component = LibsUiIconsPdfComponent class (có thể dùng với dynamic component)
const nullResult = await pipe.transform('unknown-key');
// nullResult = nullAbstract Base Class — LibsUiIconsComponentAbstract
Dùng khi tạo icon component mới trong dự án, kế thừa để có sẵn các input size, color, colorActive, active và computed colorBind.
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
import { LibsUiIconsComponentAbstract } from '@libs-ui/icons';
@Component({
selector: 'app-custom-icon',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<svg [attr.width]="size()" [attr.height]="size()" viewBox="0 0 24 24" fill="none">
<circle cx="12" cy="12" r="10" [attr.fill]="colorBind()" />
</svg>
`,
})
export class CustomIconComponent extends LibsUiIconsComponentAbstract {
// Override default size nếu cần
override readonly size = input<number, number | undefined>(24, { transform: (value) => value ?? 24 });
}API của LibsUiIconsComponentAbstract
| Thành phần | Loại | Mô tả |
|---|---|---|
| size | input<number> (default: 16) | Kích thước px |
| color | input<string> (default: '#e6e7ea') | Màu mặc định |
| colorActive | input<string> (default: '#9CA2AD') | Màu khi active |
| active | input<boolean> | Trạng thái active |
| colorBind | computed (protected) | Trả về colorActive() khi active() là true, ngược lại trả về color() |
Lưu ý quan trọng
⚠️ Selector dùng dấu gạch dưới (_) cho dấu gạch ngang trong tên folder: Các selector như libs_ui-icons-no_data, libs_ui-icons-send_solid dùng _ để thay thế - trong tên folder theo quy ước selector của libs-ui. Cần viết đúng selector khi dùng trong template.
⚠️ Pipe là async: LibsUiIconsGetIconComponentPipe trả về Promise, bắt buộc kết hợp với | async trong template và import AsyncPipe vào imports[] của component.
⚠️ Icon AI (libs_ui-icons-ai) dùng SVG gradient: Màu của icon AI được định nghĩa trực tiếp trong SVG path qua linearGradient, input color không ảnh hưởng đến màu gradient này.
⚠️ colorActive default là '#9CA2AD': Trong abstract base, giá trị mặc định của colorActive khi không truyền vào là '#9CA2AD' (xám). Không có icon component nào trong lib hiện override giá trị này — tất cả 15 icon dùng chung default colorActive từ abstract (chỉ size và color được override riêng, ví dụ: reload dùng color: '#6A7383', send-solid/sparkles-ai-solid/stop-solid dùng color: '#226FF5'). Kiểm tra bảng default ở trên trước khi dùng.
⚠️ Không có @Output(): Tất cả icon component chỉ là SVG display thuần, không emit event. Nếu cần xử lý click, bọc bên ngoài bằng <button> hoặc element có (click) handler.
