@libs-ui/components-label
v0.2.357-9
Published
> Component nhãn đa năng hỗ trợ tooltip, toggle switch, nút thao tác, bộ đếm ký tự và văn bản mô tả — dùng làm header cho các trường nhập liệu trong form.
Downloads
3,808
Readme
@libs-ui/components-label
Component nhãn đa năng hỗ trợ tooltip, toggle switch, nút thao tác, bộ đếm ký tự và văn bản mô tả — dùng làm header cho các trường nhập liệu trong form.
Giới thiệu
@libs-ui/components-label là component nhãn (label) linh hoạt dùng để trang trí tiêu đề cho các ô nhập liệu, form field hoặc nhóm nội dung. Nó hỗ trợ hiển thị nhãn trái/phải, đánh dấu bắt buộc (dấu sao đỏ), tooltip hướng dẫn, tích hợp toggle switch, thêm nút thao tác nhanh (trái/phải/mô tả), và bộ đếm ký tự theo giới hạn. Toàn bộ văn bản hỗ trợ đa ngôn ngữ qua TranslateModule.
Tính năng
- ✅ Hiển thị nhãn bên trái (
labelLeft) và nhãn bên phải (labelRight) đồng thời - ✅ Đánh dấu trường bắt buộc bằng dấu sao đỏ (
required) - ✅ Tooltip hướng dẫn tích hợp sẵn qua
popovervới icon tùy chỉnh - ✅ Tích hợp Toggle Switch (
hasToggle) với vị trí linh hoạt (trước hoặc sau nhãn) - ✅ Thêm mảng nút bấm (
IButton[]) ở vùng trái, phải hoặc vùng mô tả - ✅ Văn bản mô tả phụ (
description) hiển thị bên dưới nhãn chính - ✅ Bộ đếm ký tự (
count/limitLength) dùng cho textarea, rich text editor - ✅ Hỗ trợ đa ngôn ngữ qua
TranslateModule(i18n key) - ✅ Standalone component, OnPush, Angular Signals
Khi nào sử dụng
- Làm nhãn tiêu đề cho Input, Select, Textarea, DatePicker trong form
- Cần hiển thị tooltip hướng dẫn đính kèm nhãn (icon
?hover) - Cần thanh tiêu đề có nút thao tác nhanh (thêm mới, chỉnh sửa, cài đặt)
- Hiển thị cài đặt bật/tắt kèm mô tả chi tiết (Toggle + Description)
- Hiển thị bộ đếm ký tự còn lại cho ô nhập liệu có giới hạn độ dài
Cài đặt
npm install @libs-ui/components-labelImport
import { LibsUiComponentsLabelComponent } from '@libs-ui/components-label';
import { ILabel } from '@libs-ui/components-label';
@Component({
standalone: true,
imports: [LibsUiComponentsLabelComponent],
})
export class MyFormComponent {}Ví dụ sử dụng
1. Nhãn cơ bản với dấu bắt buộc và tooltip
<libs_ui-components-label
[labelLeft]="'Họ và tên'"
[required]="true"
[popover]="{ config: { content: 'Vui lòng nhập đầy đủ họ tên như trong giấy khai sinh.' } }">
</libs_ui-components-label>2. Nhãn tích hợp nút thao tác nhanh
import { Component } from '@angular/core';
import { LibsUiComponentsLabelComponent } from '@libs-ui/components-label';
import { IButton } from '@libs-ui/components-buttons-button';
@Component({
standalone: true,
imports: [LibsUiComponentsLabelComponent],
template: `
<libs_ui-components-label
[labelLeft]="'Danh sách thành viên'"
[buttonsRight]="buttonsRight"
(outClickButton)="handlerClickButton($event)">
</libs_ui-components-label>
`,
})
export class TeamSectionComponent {
protected buttonsRight: IButton[] = [
{ classIconLeft: 'libs-ui-icon-add', key: 'add', popover: { dataView: 'Thêm mới' } },
{ classIconLeft: 'libs-ui-icon-arrange', key: 'settings', popover: { dataView: 'Cài đặt' } },
];
protected handlerClickButton(button: IButton): void {
button.action?.(button);
}
}3. Nhãn tích hợp Toggle Switch và mô tả
import { Component, signal } from '@angular/core';
import { LibsUiComponentsLabelComponent } from '@libs-ui/components-label';
import { ISwitchEvent } from '@libs-ui/components-switch';
@Component({
standalone: true,
imports: [LibsUiComponentsLabelComponent],
template: `
<libs_ui-components-label
[labelLeft]="'Chế độ bảo mật 2 lớp'"
[hasToggle]="true"
[toggleActive]="securityEnabled()"
[description]="'Khi bật, ứng dụng yêu cầu xác thực OTP mỗi lần đăng nhập.'"
(outSwitchEvent)="handlerToggle($event)">
</libs_ui-components-label>
`,
})
export class SecuritySettingComponent {
protected securityEnabled = signal(false);
protected handlerToggle(event: ISwitchEvent): void {
this.securityEnabled.set(event.active);
}
}4. Nhãn với bộ đếm ký tự
import { Component, signal } from '@angular/core';
import { LibsUiComponentsLabelComponent } from '@libs-ui/components-label';
@Component({
standalone: true,
imports: [LibsUiComponentsLabelComponent],
template: `
<libs_ui-components-label
[labelLeft]="'Mô tả bản thân'"
[count]="charCount()"
[limitLength]="200">
</libs_ui-components-label>
<textarea (input)="handlerTextareaInput($event)" maxlength="200"></textarea>
`,
})
export class BioFieldComponent {
protected charCount = signal(0);
protected handlerTextareaInput(event: Event): void {
event.stopPropagation();
const target = event.target as HTMLTextAreaElement;
this.charCount.set(target.value.length);
}
}5. Nhãn trái/phải với toggle trước nhãn
<libs_ui-components-label
[labelLeft]="'Nhận thông báo email'"
[labelRight]="'Tùy chỉnh'"
[hasToggle]="true"
[labelLeftBehindToggleButton]="true"
[toggleActive]="true"
[toggleSize]="'large'"
(outSwitchEvent)="handlerToggle($event)"
(outLabelRightClick)="handlerLabelRightClick($event)">
</libs_ui-components-label>6. Sử dụng với interface ILabel (truyền config dạng object)
import { ILabel } from '@libs-ui/components-label';
import { IButton } from '@libs-ui/components-buttons-button';
const labelConfig: ILabel = {
labelLeft: 'Số điện thoại',
required: true,
description: 'Nhập số điện thoại có mã quốc gia, ví dụ: +84901234567',
buttonsRight: [
{ key: 'verify', label: 'Xác minh', type: 'button-link-primary' },
],
};<libs_ui-components-label
[labelLeft]="labelConfig.labelLeft"
[required]="labelConfig.required"
[description]="labelConfig.description"
[buttonsRight]="labelConfig.buttonsRight">
</libs_ui-components-label>@Input()
| Input | Type | Default | Mô tả | Ví dụ |
|---|---|---|---|---|
| buttonsDescription | IButton[] | [] | Danh sách nút bấm hiển thị vùng mô tả bên dưới nhãn | [buttonsDescription]="[{ key: 'add', label: 'Thêm' }]" |
| buttonsDescriptionContainerClass | string | 'flex libs-ui-label-description-button' | Class CSS container bọc ngoài nhóm nút mô tả | [buttonsDescriptionContainerClass]="'flex gap-2'" |
| buttonsLeft | IButton[] | [] | Danh sách nút bấm hiển thị vùng trái (sau nhãn left) | [buttonsLeft]="[{ classIconLeft: 'libs-ui-icon-add', key: 'add' }]" |
| buttonsRight | IButton[] | [] | Danh sách nút bấm hiển thị vùng phải | [buttonsRight]="[{ classIconLeft: 'libs-ui-icon-edit-line', key: 'edit' }]" |
| classInclude | string | 'libs-ui-label' | Class CSS bổ sung cho wrapper ngoài cùng của component | [classInclude]="'my-custom-label'" |
| count | number | 0 | Số ký tự hiện tại để hiển thị trên bộ đếm | [count]="charCount()" |
| description | string | undefined | Văn bản mô tả phụ hiển thị bên dưới nhãn chính (hỗ trợ i18n key) | [description]="'i18n_field_hint'" |
| descriptionClass | string | 'libs-ui-label-description libs-ui-font-h5r' | Class CSS bổ sung cho vùng mô tả | [descriptionClass]="'text-orange-500'" |
| disableButtonsDescription | boolean | undefined | Vô hiệu hóa tất cả nút trong vùng mô tả | [disableButtonsDescription]="isReadonly()" |
| disableButtonsLeft | boolean | undefined | Vô hiệu hóa tất cả nút bên trái | [disableButtonsLeft]="isReadonly()" |
| disableButtonsRight | boolean | undefined | Vô hiệu hóa tất cả nút bên phải | [disableButtonsRight]="isReadonly()" |
| hasToggle | boolean | undefined | Hiển thị toggle switch trong nhãn | [hasToggle]="true" |
| iconPopoverClass | string | 'libs-ui-icon-tooltip-outline' | Class CSS của icon tooltip (hiển thị khi có popover) | [iconPopoverClass]="'libs-ui-icon-tooltip-outline'" |
| labelLeft | string | undefined | Văn bản nhãn bên trái (hỗ trợ i18n key) | [labelLeft]="'i18n_field_name'" |
| labelLeftBehindToggleButton | boolean | undefined | Khi true, toggle switch hiển thị trước nhãn trái; khi false/undefined, toggle ở sau | [labelLeftBehindToggleButton]="true" |
| labelLeftClass | string | 'libs-ui-label-left-text libs-ui-font-h6m' | Class CSS bổ sung cho text nhãn trái | [labelLeftClass]="'text-blue-600'" |
| labelRight | string | undefined | Văn bản nhãn bên phải, có thể click (hỗ trợ i18n key) | [labelRight]="'Tùy chỉnh'" |
| labelRightClass | string | '' | Class CSS bổ sung cho text nhãn phải | [labelRightClass]="'text-blue-500 cursor-pointer'" |
| labelRightRequired | string | undefined | Text hiển thị bắt buộc vùng phải (thay thế dấu *) | [labelRightRequired]="'(Bắt buộc)'" |
| limitLength | number | 0 | Giới hạn ký tự tối đa — khi > 0 hiển thị dạng count/limitLength | [limitLength]="200" |
| onlyShowCount | boolean | undefined | Khi true, chỉ hiển thị số đếm hiện tại (không hiển thị giới hạn) | [onlyShowCount]="true" |
| popover | IPopover | undefined | Cấu hình tooltip hiển thị khi hover vào icon | [popover]="{ config: { content: 'Hướng dẫn nhập liệu' } }" |
| required | boolean | undefined | Hiển thị dấu sao đỏ * đánh dấu trường bắt buộc | [required]="true" |
| timerDestroyPopover | number | 0 | Thời gian (ms) sau đó popover tự đóng (0 = không tự đóng) | [timerDestroyPopover]="3000" |
| toggleActive | boolean | undefined | Trạng thái bật/tắt của toggle switch | [toggleActive]="isEnabled()" |
| toggleDisable | boolean | undefined | Vô hiệu hóa toggle switch | [toggleDisable]="isReadonly()" |
| toggleSize | 'default' \| 'large' | 'default' | Kích thước toggle switch | [toggleSize]="'large'" |
| zIndexPopover | number | 10 | z-index của popover (tăng khi bị che bởi các lớp khác) | [zIndexPopover]="100" |
@Output()
| Output | Type | Mô tả | Handler TS | Binding HTML |
|---|---|---|---|---|
| (outClickButton) | IButton | Phát ra khi click vào bất kỳ nút nào (trái, phải hoặc mô tả) trong component | handlerClickButton(button: IButton): void { button.action?.(button); } | (outClickButton)="handlerClickButton($event)" |
| (outLabelLeftClick) | MouseEvent | Phát ra khi click vào vùng nhãn trái | handlerLabelLeftClick(event: MouseEvent): void { event.stopPropagation(); } | (outLabelLeftClick)="handlerLabelLeftClick($event)" |
| (outLabelRightClick) | boolean | Phát ra true khi click vào nhãn phải | handlerLabelRightClick(clicked: boolean): void { } | (outLabelRightClick)="handlerLabelRightClick($event)" |
| (outSwitchEvent) | ISwitchEvent | Phát ra khi trạng thái toggle switch thay đổi | handlerToggle(event: ISwitchEvent): void { this.isEnabled.set(event.active); } | (outSwitchEvent)="handlerToggle($event)" |
Types & Interfaces
import { ILabel } from '@libs-ui/components-label';ILabel
Interface dùng để xây dựng object cấu hình cho component, thuận tiện khi cần truyền config từ TS thay vì bind từng input riêng lẻ.
import { ILabel } from '@libs-ui/components-label';
import { IButton } from '@libs-ui/components-buttons-button';
import { IPopover } from '@libs-ui/components-popover';
interface ILabel {
classInclude?: string;
labelLeft?: string;
labelLeftClass?: string;
labelLeftBehindToggleButton?: boolean;
popover?: IPopover;
iconPopoverClass?: string;
zIndexPopover?: number;
timerDestroyPopover?: number;
required?: boolean;
buttonsLeft?: IButton[];
disableButtonsLeft?: boolean;
buttonsRight?: IButton[];
disableButtonsRight?: boolean;
labelRight?: string;
labelRightClass?: string;
labelRightRequired?: string;
hasToggle?: boolean;
toggleActive?: boolean;
toggleDisable?: boolean;
toggleSize?: 'default' | 'large';
description?: string;
descriptionClass?: string;
buttonsDescription?: IButton[];
disableButtonsDescription?: boolean;
buttonsDescriptionContainerClass?: string;
onlyShowCount?: boolean;
limitLength?: number;
count?: number;
}ISwitchEvent (từ @libs-ui/components-switch)
import { ISwitchEvent } from '@libs-ui/components-switch';
// ISwitchEvent chứa ít nhất:
// { active: boolean }IButton (từ @libs-ui/components-buttons-button)
import { IButton } from '@libs-ui/components-buttons-button';
// Các field thường dùng:
// {
// key?: string;
// label?: string;
// type?: string; // 'button-link-primary' | 'button-primary' | ...
// classIconLeft?: string;
// classIconRight?: string;
// classInclude?: string;
// classLabel?: string;
// sizeButton?: string;
// disable?: boolean;
// popover?: object;
// action?: (button: IButton) => void;
// }Custom Description Slot
Component hỗ trợ ng-content projection với selector div.libs-ui-custom-description để inject nội dung tùy chỉnh bên dưới nhãn:
<libs_ui-components-label [labelLeft]="'Tệp đính kèm'">
<div class="libs-ui-custom-description">
<span class="text-gray-400 libs-ui-font-h7r">Hỗ trợ PDF, DOCX, tối đa 10MB</span>
</div>
</libs_ui-components-label>Lưu ý quan trọng
⚠️ Bộ đếm ký tự: Để bộ đếm hoạt động, cần truyền cả [count] và [limitLength]. Nếu chỉ muốn hiển thị số đếm mà không giới hạn, dùng [onlyShowCount]="true" kết hợp [count].
⚠️ Toggle switch và vị trí nhãn: Khi [labelLeftBehindToggleButton]="true", toggle xuất hiện ở bên trái nhãn. Khi false hoặc không truyền, toggle xuất hiện ở bên phải nhãn.
⚠️ Nhãn phải và giới hạn chiều rộng: Khi có labelRight, limitLength hoặc onlyShowCount, vùng nhãn trái (libs-ui-label-left) tự động co xuống maxWidth: 70% để dành chỗ cho vùng phải.
⚠️ i18n: Tất cả labelLeft, labelRight, description đều được pipe translate tự động — có thể truyền i18n key trực tiếp hoặc text thường.
⚠️ Custom description content: Chỉ nội dung trong <div class="libs-ui-custom-description"> mới được inject qua ng-content. Các tag khác sẽ bị bỏ qua.
