@libs-ui/components-dropdown
v0.2.356-0
Published
> Component dropdown đa năng hỗ trợ nhiều chế độ hiển thị: text, radio, checkbox, group. Tích hợp sẵn tìm kiếm, validation, popover, tabs và điều khiển từ bên ngoài.
Readme
@libs-ui/components-dropdown
Component dropdown đa năng hỗ trợ nhiều chế độ hiển thị: text, radio, checkbox, group. Tích hợp sẵn tìm kiếm, validation, popover, tabs và điều khiển từ bên ngoài.
Version: 0.2.355-14
Giới thiệu
LibsUiComponentsDropdownComponent là một standalone Angular component cung cấp dropdown selection với nhiều chế độ hiển thị và tính năng nâng cao.
Tính năng
- ✅ Nhiều chế độ hiển thị: text, radio, checkbox, group
- ✅ Tìm kiếm online/offline tích hợp sẵn
- ✅ Validation (required, max items selected)
- ✅ Điều khiển từ bên ngoài qua
IDropdownFunctionControlEvent - ✅ Hỗ trợ tabs để phân loại dữ liệu
- ✅ Tự động load dữ liệu từ API (httpRequestData)
- ✅ Auto-select first item / all items
- ✅ Hiển thị avatar, icon, image cho item
- ✅ Custom content qua ng-content
- ✅ OnPush Change Detection
- ✅ Angular Signals
Khi nào sử dụng
- Chọn một hoặc nhiều giá trị từ danh sách dữ liệu
- Dropdown với tìm kiếm online/offline
- Chọn dữ liệu dạng nhóm (group), cây (tree), JSON tree
- Cần validation (required, max items)
- Cần điều khiển dropdown từ component cha (reset, refresh, check valid)
- Hiển thị dropdown với tabs để phân loại dữ liệu
- Dropdown với custom content (ng-content)
Lưu ý quan trọng
- ⚠️ Bắt buộc
[listConfig]: Phải cung cấp[listConfig]để dropdown hiển thị danh sách. - ⚠️ Chế độ chọn: Sử dụng
[listKeySelected]cho chọn đơn (text/radio),[listMultiKeySelected]cho chọn nhiều (checkbox/group). - ⚠️ Auto-load API: Khi dùng
httpRequestDatatronglistConfig, dropdown tự động gọi API để load dữ liệu. - ⚠️ FunctionControl: Output
outFunctionsControlemitIDropdownFunctionControlEventđể điều khiển dropdown từ bên ngoài.
Cài đặt
# npm
npm install @libs-ui/components-dropdown
# yarn
yarn add @libs-ui/components-dropdownImport
import {
LibsUiComponentsDropdownComponent,
IDropdownFunctionControlEvent,
IEmitSelectKey,
IEmitMultiKey,
IPopoverCustomConfig,
IDropdownTabsItem,
IValidMaxItemSelected,
IDropdown,
} from '@libs-ui/components-dropdown';
@Component({
standalone: true,
imports: [LibsUiComponentsDropdownComponent],
// ...
})
export class YourComponent {}Ví dụ
Basic - Text
<libs_ui-components-dropdown
[labelConfig]="{ labelLeft: 'Chọn item', required: true }"
[listConfig]="listConfig"
[listSearchConfig]="{ noBorder: true }"
[listMaxItemShow]="5"
[convertItemSelected]="convertItemSelected"
(outSelectKey)="onSelectKey($event)"
/>listConfig: IListConfigItem = {
type: 'text',
httpRequestData: signal<IHttpRequestConfig>({
objectInstance: getConfigListDataDemo(),
functionName: 'list',
argumentsValue: [new UtilsHttpParamsRequest({ fromObject: { page: 1, per_page: 20 } })],
}),
configTemplateText: signal({
fieldKey: 'id',
notUseVirtualScroll: true,
getValue: (item) => escapeHtml(item.name),
}),
};Checkbox
<libs_ui-components-dropdown
[labelConfig]="{ labelLeft: 'Chọn nhiều (checkbox)', required: true }"
[listConfig]="checkboxConfig"
[listMaxItemShow]="5"
[convertItemSelected]="convertItemSelected"
(outSelectMultiKey)="onSelectMultiKey($event)"
/>Radio
<libs_ui-components-dropdown
[labelConfig]="{ labelLeft: 'Chọn item (radio)', required: true }"
[listConfig]="radioConfig"
[listMaxItemShow]="5"
[convertItemSelected]="convertItemSelected"
(outSelectKey)="onSelectKey($event)"
/>Interactive - Controls
<libs_ui-components-dropdown
[labelConfig]="{ labelLeft: 'Interactive', required: true }"
[listConfig]="listConfig"
[listMaxItemShow]="5"
[validRequired]="{}"
(outFunctionsControl)="onFunctionControl($event)"
/>dropdownControl: IDropdownFunctionControlEvent | undefined;
onFunctionControl(event: IDropdownFunctionControlEvent) {
this.dropdownControl = event;
}
async resetDropdown() {
await this.dropdownControl?.reset();
}
async checkValid() {
const isValid = await this.dropdownControl?.checkIsValid();
console.log('Valid:', isValid);
}
async refreshList() {
await this.dropdownControl?.refreshList();
}States
<!-- Disable -->
<libs_ui-components-dropdown
[labelConfig]="{ labelLeft: 'Disable' }"
[disable]="true"
[listConfig]="listConfig"
/>
<!-- Readonly -->
<libs_ui-components-dropdown
[labelConfig]="{ labelLeft: 'Readonly' }"
[readonly]="true"
[listConfig]="listConfig"
/>API
libs_ui-components-dropdown
Inputs
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| [allowSelectItemMultiple] | boolean | undefined | Cho phép chọn lại item đã chọn |
| [changeValidUndefinedResetError] | boolean | undefined | Reset error khi valid undefined |
| [classAvatarInclude] | string | 'mr-[8px]' | Class CSS cho avatar |
| [classInclude] | string | undefined | Class CSS bổ sung cho container |
| [classIncludeContent] | string | undefined | Class CSS cho content wrapper |
| [classIncludeIcon] | string | 'ml-[8px]' | Class CSS cho icon mũi tên |
| [classIncludeTextDisplayWhenNoSelect] | string | 'libs-ui-font-h5r' | Class CSS cho text placeholder |
| [convertItemSelected] | (item, translate?) => void | defaultConvert | Hàm convert item sau khi chọn để hiển thị label |
| [disable] | boolean | undefined | Vô hiệu hóa dropdown |
| [disableLabel] | boolean | undefined | Vô hiệu hóa label |
| [fieldGetColorAvatar] | string | undefined | Field lấy color cho avatar |
| [fieldGetIcon] | string | undefined | Field lấy icon class từ item |
| [fieldGetImage] | string | undefined | Field lấy URL ảnh từ item |
| [fieldGetLabel] | string | undefined | Field lấy label từ item |
| [fieldGetTextAvatar] | string | 'username' | Field lấy text cho avatar |
| [fieldLabel] | string | 'labelDisplay' | Field lưu label hiển thị trên dropdown |
| [flagMouse] | IFlagMouse (model) | { isMouseEnter: false, isMouseEnterContent: false } | Trạng thái mouse |
| [flagMouseContent] | IFlagMouse (model) | undefined | Trạng thái mouse content |
| [focusInputSearch] | boolean | true | Tự động focus input tìm kiếm khi mở |
| [getLastTextAfterSpace] | boolean | undefined | Lấy text cuối sau dấu cách |
| [getPopoverItemSelected] | (item, translate?) => Promise<IPopover> | undefined | Hàm lấy popover config cho item đã chọn |
| [hasContentUnitRight] | boolean | undefined | Có content bên phải unit |
| [httpRequestDetailItemById] | IHttpRequestConfig | undefined | Config HTTP request để lấy chi tiết item theo key |
| [ignoreBorderBottom] | boolean | undefined | Bỏ border bottom |
| [ignoreStopPropagationEvent] | boolean | false | Bỏ qua stopPropagation |
| [imageSize] | TYPE_SIZE_AVATAR_CONFIG | 16 | Kích thước avatar |
| [isNgContent] | boolean | undefined | Sử dụng ng-content thay vì giao diện mặc định |
| [isSearchOnline] | boolean | false | Tìm kiếm online (gọi API) |
| [labelConfig] | ILabel | undefined | Cấu hình label phía trên dropdown |
| [labelPopoverConfig] | IPopoverOverlay | undefined | Config popover cho label |
| [labelPopoverFullWidth] | boolean | true | Popover label full width |
| [lengthKeys] | number (model) | 0 | Số lượng keys đã chọn |
| [linkImageError] | string | undefined | Link ảnh khi lỗi |
| [listBackgroundCustom] | string | undefined | Background custom cho list |
| [listButtonsOther] | Array<IButton> | undefined | Các button khác trong list |
| [listClickExactly] | boolean | undefined | Click chính xác item |
| [listConfig] | IListConfigItem | undefined | Cấu hình danh sách (type, httpRequestData, template config) |
| [listConfigHasDivider] | boolean | true | Hiển thị divider trong list |
| [listDividerClassInclude] | string | undefined | Class CSS cho divider |
| [listHasButtonUnSelectOption] | boolean | undefined | Hiển thị nút bỏ chọn |
| [listHiddenInputSearch] | boolean | undefined | Ẩn input tìm kiếm |
| [listIgnoreClassDisableDefaultWhenUseKeysDisableItem] | boolean | undefined | Bỏ class disable mặc định khi dùng keysDisable |
| [listKeysDisable] | Array<string> | undefined | Danh sách keys bị disable |
| [listKeysHidden] | Array<string> | undefined | Danh sách keys bị ẩn |
| [listKeySearch] | string | undefined | Key tìm kiếm |
| [listKeySelected] | unknown (model) | undefined | Key item đang được chọn (single select) |
| [listMaxItemShow] | number | 5 | Số item tối đa hiển thị |
| [listMultiKeySelected] | Array<unknown> (model) | undefined | Danh sách keys đang được chọn (multi select) |
| [listSearchConfig] | IInputSearchConfig | { noBorder: true } | Cấu hình input tìm kiếm |
| [listSearchNoDataTemplateRef] | TemplateRef<unknown> | undefined | Template khi không có dữ liệu tìm kiếm |
| [listSearchPadding] | boolean | undefined | Padding cho search |
| [onlyEmitDataWhenReset] | boolean | undefined | Chỉ emit sự kiện khi reset |
| [popoverCustomConfig] | IPopoverCustomConfig | undefined | Cấu hình popover overlay |
| [popoverElementRefCustom] | HTMLElement | undefined | Element ref custom cho popover |
| [readonly] | boolean | undefined | Chế độ chỉ đọc |
| [resetKeyWhenSelectAllKey] | boolean | undefined | Reset key khi select all |
| [showBorderError] | boolean (model) | undefined | Hiển thị border error |
| [showError] | boolean | true | Hiển thị error message |
| [tabKeyActive] | string (model) | undefined | Key tab đang active |
| [tabsConfig] | Array<IDropdownTabsItem> | undefined | Cấu hình tabs cho dropdown |
| [textDisplayWhenMultiSelect] | string | 'i18n_selecting_options' | Text hiển thị khi chọn nhiều |
| [textDisplayWhenNoSelect] | string | 'i18n_select_information' | Text hiển thị khi chưa chọn |
| [typeShape] | TYPE_SHAPE_AVATAR | 'circle' | Hình dạng avatar |
| [useXssFilter] | boolean | false | Bật XSS filter |
| [validMaxItemSelected] | IValidMaxItemSelected | undefined | Validation số item chọn tối đa |
| [validRequired] | IMessageTranslate | undefined | Validation required |
| [zIndex] | number | undefined | z-index cho popover |
Outputs
| Property | Type | Description |
|----------|------|-------------|
| (outChangStageFlagMouse) | IFlagMouse | Emit khi trạng thái mouse thay đổi |
| (outChangeTabKeyActive) | string \| undefined | Emit khi tab active thay đổi |
| (outClickButtonOther) | IButton | Emit khi click button khác trong list |
| (outDataChange) | Array<unknown> | Emit khi dữ liệu list thay đổi |
| (outFunctionsControl) | IDropdownFunctionControlEvent | Emit functions để điều khiển dropdown |
| (outSelectKey) | IEmitSelectKey \| undefined | Emit khi chọn item (single select) |
| (outSelectMultiKey) | IEmitMultiKey \| undefined | Emit khi chọn items (multi select) |
| (outShowList) | boolean | Emit khi show/hide list |
| (outValidEvent) | boolean | Emit kết quả validation |
FunctionControl Methods
| Method | Description |
|--------|-------------|
| checkIsValid() | Kiểm tra validation và trả về boolean |
| getDisable() | Lấy trạng thái disable |
| refreshList() | Refresh lại danh sách dữ liệu |
| removeList() | Đóng popup danh sách |
| reset() | Reset dropdown về trạng thái ban đầu |
| resetError() | Xóa error hiện tại |
| setError(message) | Đặt error message |
| setItemSelectedByKey(id) | Chọn item theo key (gọi API nếu có httpRequestDetailItemById) |
| updateLabelItemSelected(label) | Cập nhật label của item đã chọn |
Types & Interfaces
interface IEmitSelectKey {
key?: unknown;
item?: any;
isClickManual?: boolean;
tabKeyActive?: string;
}
interface IEmitMultiKey {
keys?: Array<unknown>;
mapKeys?: Array<IEmitSelectKey>;
isClickManual?: boolean;
tabKeyActive?: string;
}
interface IPopoverCustomConfig {
widthByParent?: boolean;
parentBorderWidth?: number;
maxHeight?: number;
maxWidth?: number;
direction?: TYPE_POPOVER_DIRECTION;
ignoreArrow?: boolean;
classInclude?: string;
disable?: boolean;
clickExactly?: boolean;
paddingLeftItem?: boolean;
timerDestroy?: number;
position?: { mode: TYPE_POPOVER_POSITION_MODE; distance: number };
animationConfig?: { time?: number; distance?: number };
width?: number;
classIncludeOverlayBody?: string;
}
interface IDropdownTabsItem {
key: string;
name: string;
httpRequestData?: IHttpRequestConfig;
}
interface IValidMaxItemSelected extends IMessageTranslate {
value: number;
}
interface IDropdown {
listConfig: IListConfigItem;
listBackgroundListCustom?: string;
listMaxItemShow?: number;
classIncludePopup?: string;
paddingLeftItem?: boolean;
clickExactly?: boolean;
zIndex?: number;
popoverCustomConfig?: IPopoverCustomConfig;
disable?: boolean;
}
interface IDropdownFunctionControlEvent {
checkIsValid: () => Promise<boolean>;
resetError: () => Promise<void>;
setError?: (message: string) => Promise<void>;
removeList: () => Promise<void>;
updateLabelItemSelected: (label: string) => Promise<void>;
reset: () => Promise<void>;
refreshList: () => Promise<void>;
setItemSelectedByKey: (id: unknown) => Promise<void>;
getDisable: () => Promise<boolean>;
}| Type | Mô tả |
|------|--------|
| IEmitSelectKey | Dữ liệu emit khi chọn 1 item (single select) |
| IEmitMultiKey | Dữ liệu emit khi chọn nhiều items (multi select) |
| IPopoverCustomConfig | Cấu hình tùy chỉnh popover overlay |
| IDropdownTabsItem | Cấu hình cho từng tab trong dropdown |
| IValidMaxItemSelected | Cấu hình validation giới hạn số item được chọn |
| IDropdown | Interface cấu hình dropdown |
| IDropdownFunctionControlEvent | Interface chứa các methods để điều khiển dropdown từ component cha |
Dependencies
| Package | Version | Mục đích |
|---------|---------|----------|
| @libs-ui/components-avatar | 0.2.355-14 | Hiển thị avatar trong dropdown |
| @libs-ui/components-buttons-button | 0.2.355-14 | Button interface |
| @libs-ui/components-inputs-search | 0.2.355-14 | Input tìm kiếm |
| @libs-ui/components-inputs-valid | 0.2.355-14 | Validation input |
| @libs-ui/components-label | 0.2.355-14 | Label component |
| @libs-ui/components-list | 0.2.355-14 | Danh sách hiển thị |
| @libs-ui/components-popover | 0.2.355-14 | Popover overlay |
| @libs-ui/pipes-security-trust | 0.2.355-14 | Security trust pipe |
| @libs-ui/services-http-request | 0.2.355-14 | HTTP request service |
| @libs-ui/utils | 0.2.355-14 | Utilities |
| @ngx-translate/core | ^15.0.0 | Đa ngôn ngữ |
Công nghệ
| Technology | Version | Purpose | |------------|---------|---------| | Angular | 18+ | Framework | | Angular Signals | - | State management | | TailwindCSS | 3.x | Styling | | OnPush | - | Change Detection |
Demo
npx nx serve core-uiTruy cập: http://localhost:4500/dropdown
Unit Tests
# Chạy tests
npx nx test components-dropdown
# Coverage
npx nx test components-dropdown --coverage
# Watch mode
npx nx test components-dropdown --watchLicense
MIT
