@libs-ui/components-badge
v0.2.357-4
Published
> Component hiển thị số lượng/đếm (badge) với nhiều chế độ định dạng cho Angular.
Downloads
4,381
Readme
@libs-ui/components-badge
Component hiển thị số lượng/đếm (badge) với nhiều chế độ định dạng cho Angular.
Giới thiệu
LibsUiComponentsBadgeComponent là một Angular standalone component dùng để hiển thị số lượng dạng badge (ví dụ: tin nhắn chưa đọc, thông báo mới, số items trong giỏ hàng). Component hỗ trợ 5 chế độ định dạng số khác nhau, tích hợp sẵn popover tooltip, và sử dụng Angular Signals với ChangeDetectionStrategy.OnPush để đảm bảo hiệu năng cao.
Tính năng
- ✅ 5 chế độ hiển thị số:
x,0x,x+,+x,k - ✅ Rút gọn số lớn tự động (1K, 1.5K, 1M, 1.5M) với mode
k - ✅ Hiển thị dạng "99+" khi vượt giới hạn với mode
x+ - ✅ Trạng thái active thay đổi màu sắc badge
- ✅ Tích hợp Popover tooltip khi hover
- ✅ Bỏ margin-left mặc định với
ignoreMarginDefault - ✅ Class CSS tùy chỉnh qua
classCircle - ✅ OnPush Change Detection cho hiệu năng cao
- ✅ Angular Signals — reactive state với
computed() - ✅ Standalone Component, không cần NgModule
Khi nào sử dụng
- Hiển thị số lượng tin nhắn chưa đọc, thông báo mới trên icon/tab
- Đếm số items trong giỏ hàng hoặc danh sách chọn
- Hiển thị số liệu thống kê dạng compact (1K, 1.5M) trong bảng hoặc card
- Đánh dấu trạng thái active/inactive cho một mục trong sidebar/menu
- Hiển thị số thứ tự hoặc đếm bước có padding số 0 (01, 02...)
Cài đặt
npm install @libs-ui/components-badgeImport
import { LibsUiComponentsBadgeComponent } from '@libs-ui/components-badge';
import { TYPE_BADGE_MODE } from '@libs-ui/components-badge';
import { IBadge } from '@libs-ui/components-badge';Ví dụ sử dụng
Basic — hiển thị số đơn giản
import { Component } from '@angular/core';
import { LibsUiComponentsBadgeComponent } from '@libs-ui/components-badge';
@Component({
selector: 'app-basic-example',
standalone: true,
imports: [LibsUiComponentsBadgeComponent],
template: `
<div class="flex items-center gap-2">
<span>Tin nhắn</span>
<libs_ui-components-badge [count]="5" />
</div>
`,
})
export class BasicExampleComponent {}Mode 0x — padding số 0 cho count < 10
import { Component, signal } from '@angular/core';
import { LibsUiComponentsBadgeComponent } from '@libs-ui/components-badge';
@Component({
selector: 'app-mode-example',
standalone: true,
imports: [LibsUiComponentsBadgeComponent],
template: `
<!-- Mode 'x': Số thường, không padding -->
<libs_ui-components-badge [count]="5" mode="x" />
<!-- Output: 5 -->
<!-- Mode '0x': Padding số 0 nếu < 10 -->
<libs_ui-components-badge [count]="5" mode="0x" />
<!-- Output: 05 -->
<!-- Mode 'x+': Hiển thị maxCount+ khi vượt giới hạn -->
<libs_ui-components-badge [count]="150" mode="x+" [maxCount]="99" />
<!-- Output: 99+ -->
<!-- Mode '+x': Thêm dấu + phía trước -->
<libs_ui-components-badge [count]="5" mode="+x" />
<!-- Output: +05 -->
<!-- Mode 'k': Rút gọn hàng nghìn/triệu -->
<libs_ui-components-badge [count]="1500" mode="k" />
<!-- Output: 1.5K -->
`,
})
export class ModeExampleComponent {}Active state — đổi màu badge
import { Component, signal } from '@angular/core';
import { LibsUiComponentsBadgeComponent } from '@libs-ui/components-badge';
@Component({
selector: 'app-active-example',
standalone: true,
imports: [LibsUiComponentsBadgeComponent],
template: `
<!-- Badge bình thường (nền xám) -->
<libs_ui-components-badge [count]="5" />
<!-- Badge active (nền xanh) -->
<libs_ui-components-badge [count]="5" [active]="true" />
<!-- Kết hợp với signal -->
<libs_ui-components-badge [count]="unreadCount()" [active]="hasUnread()" />
`,
})
export class ActiveExampleComponent {
protected readonly unreadCount = signal(3);
protected readonly hasUnread = signal(true);
}Nâng cao — dùng trong notification icon
import { Component, signal } from '@angular/core';
import { LibsUiComponentsBadgeComponent } from '@libs-ui/components-badge';
@Component({
selector: 'app-notification-example',
standalone: true,
imports: [LibsUiComponentsBadgeComponent],
template: `
<!-- Badge trong icon thông báo, bỏ margin mặc định -->
<button class="relative p-2" (click)="handlerOpenNotifications($event)">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 22c1.1 0 2-.9 2-2h-4c0 1.1.9 2 2 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/>
</svg>
<libs_ui-components-badge
[count]="notificationCount()"
mode="x+"
[maxCount]="99"
[active]="true"
[ignoreMarginDefault]="true"
/>
</button>
<!-- Badge rút gọn cho bảng thống kê -->
<div class="flex items-center gap-2">
<span class="libs-ui-font-h6r">Lượt xem</span>
<libs_ui-components-badge [count]="viewCount()" mode="k" />
</div>
`,
})
export class NotificationExampleComponent {
protected readonly notificationCount = signal(5);
protected readonly viewCount = signal(12500);
protected handlerOpenNotifications(event: Event): void {
event.stopPropagation();
// handle open notifications
}
}@Input()
| Input | Type | Default | Mô tả | Ví dụ |
|---|---|---|---|---|
| [count] | number | 0 | Số lượng hiển thị trên badge. Nhận null được transform về 0. | [count]="unreadCount()" |
| [mode] | TYPE_BADGE_MODE | undefined | Chế độ định dạng số. Xem bảng mode bên dưới để biết chi tiết từng giá trị. | mode="0x" |
| [maxCount] | number | Number.MAX_SAFE_INTEGER | Giới hạn tối đa — khi count > maxCount và mode='x+' thì hiển thị "maxCount+". | [maxCount]="99" |
| [active] | boolean | false | Trạng thái active — đổi màu badge sang màu xanh (primary). | [active]="hasUnread()" |
| [classCircle] | string | 'libs-ui-font-h6r' | Class CSS tùy chỉnh cho phần tử badge. Dùng để override typography. | classCircle="libs-ui-font-h5r" |
| [ignoreMarginDefault] | boolean | false | Bỏ margin-left: 8px mặc định của badge. Dùng khi cần định vị badge tùy ý (ví dụ: absolute). | [ignoreMarginDefault]="true" |
| [popoverConfig] | IPopoverOverlay | undefined | Cấu hình popover tooltip khi hover vào badge. Nếu không truyền, tooltip mặc định hiển thị giá trị countDisplay. | [popoverConfig]="tooltipConfig" |
| [ignoreStopPropagationEvent] | boolean | true | Bỏ qua stopPropagation khi click vào badge. Mặc định true — sự kiện click sẽ lan lên component cha. | [ignoreStopPropagationEvent]="false" |
Bảng chế độ hiển thị (TYPE_BADGE_MODE)
| Mode | count = 0 | count = 5 | count = 9 | count = 15 | count = 100 | count > maxCount |
|---|---|---|---|---|---|---|
| undefined (default) | 00 | 05 | 09 | 15 | 100 | — |
| 'x' | 0 | 5 | 9 | 15 | 100 | — |
| '0x' | 00 | 05 | 09 | 15 | 100 | — |
| 'x+' | 00 | 05 | 09 | 15 | 100 | 99+ |
| '+x' | +00 | +05 | +09 | +15 | +100 | — |
| 'k' | — | — | — | — | — | 1K, 1.5K, 1M |
Lưu ý mode
k: Chỉ rút gọn khicount > 999. Dưới 1000 thì hiển thị như số thường.
Types & Interfaces
import { TYPE_BADGE_MODE } from '@libs-ui/components-badge';
import { IBadge } from '@libs-ui/components-badge';/**
* Các chế độ hiển thị số trên Badge
* - 'x' : Số thường (0, 5, 15, 100)
* - '0x' : Padding số 0 nếu < 10 (00, 05, 15, 100)
* - 'x+' : Hiển thị "maxCount+" khi vượt giới hạn (99+, 999+)
* - '+x' : Thêm dấu + phía trước (+00, +05, +15)
* - 'k' : Rút gọn hàng nghìn/triệu (1K, 1.5K, 1M, 1.5M)
*/
type TYPE_BADGE_MODE = 'x' | 'x+' | '+x' | 'k' | '0x';
/**
* Interface cấu hình cho Badge — dùng khi cần type cho object config
*/
interface IBadge {
mode?: TYPE_BADGE_MODE;
count?: number;
maxCount?: number;
classCircle?: string;
}Ví dụ dùng IBadge để truyền config
import { Component } from '@angular/core';
import { LibsUiComponentsBadgeComponent, IBadge } from '@libs-ui/components-badge';
@Component({
selector: 'app-config-example',
standalone: true,
imports: [LibsUiComponentsBadgeComponent],
template: `
<libs_ui-components-badge
[count]="badgeConfig.count ?? 0"
[mode]="badgeConfig.mode"
[maxCount]="badgeConfig.maxCount"
[classCircle]="badgeConfig.classCircle ?? 'libs-ui-font-h6r'"
/>
`,
})
export class ConfigExampleComponent {
readonly badgeConfig: IBadge = {
mode: 'x+',
count: 150,
maxCount: 99,
classCircle: 'libs-ui-font-h6r',
};
}Styling
Badge có 2 trạng thái CSS được định nghĩa sẵn:
// Trạng thái bình thường — nền xám, chữ xám
.libs-ui-badge {
width: fit-content;
height: 20px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
color: #6a7383;
background: #e6e7ea;
margin-left: 8px;
padding: 2px 6px;
}
// Trạng thái active — nền xanh nhạt, chữ xanh primary
.libs-ui-badge-active {
color: var(--libs-ui-color-default, #226ff5);
background: var(--libs-ui-color-light-3, #f4f8ff);
}Override màu qua CSS variables:
:root {
--libs-ui-color-default: #226ff5; /* Màu chữ active */
--libs-ui-color-light-3: #f4f8ff; /* Màu nền active */
}Lưu ý quan trọng
⚠️ margin-left mặc định: Badge mặc định có margin-left: 8px. Khi đặt badge ở vị trí tuyệt đối (absolute positioning), truyền [ignoreMarginDefault]="true" để loại bỏ margin này.
⚠️ mode k chỉ rút gọn khi count > 999: Với count <= 999 và mode="k", badge hiển thị số thường. Nếu muốn luôn có padding số 0 với số nhỏ, dùng kết hợp mode 0x.
⚠️ maxCount chỉ có tác dụng với mode x+: Truyền [maxCount] mà không đặt mode="x+" sẽ không có hiệu lực.
⚠️ Selector dùng dấu gạch dưới: Selector của component là libs_ui-components-badge (có _ giữa libs_ui). Đây là quy chuẩn của dự án — không dùng libs-ui-components-badge sẽ không render được.
Demo
npx nx serve core-uiTruy cập: http://localhost:4500/components/badge
