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-list

v0.2.356-5

Published

> Component mạnh mẽ hỗ trợ hiển thị danh sách với nhiều định dạng: Text, Radio, Checkbox, Tag và Group/Tree. Kèm sub-component hiển thị giao diện No-Data linh hoạt.

Readme

@libs-ui/components-list

Component mạnh mẽ hỗ trợ hiển thị danh sách với nhiều định dạng: Text, Radio, Checkbox, Tag và Group/Tree. Kèm sub-component hiển thị giao diện No-Data linh hoạt.

Version: 0.2.356-3 | Package: @libs-ui/components-list

Giới thiệu

LibsUiComponentsListComponent là một standalone Angular component được thiết kế để xử lý các bài toán hiển thị danh sách phức tạp. Component này không chỉ hiển thị dữ liệu mà còn tích hợp sâu với các dịch vụ lấy dữ liệu (HTTP), tìm kiếm và quản lý trạng thái chọn item.

Tính năng

  • Đa dạng Template: Hỗ trợ 5 loại hiển thị: text, radio, checkbox, tag, group.
  • Cấu trúc Cây (Group/Tree): Hiển thị phân cấp không giới hạn level với logic quan hệ cha-con tinh tế.
  • Tìm kiếm Thông minh: Hỗ trợ cả tìm kiếm Online (server-side) và Offline (client-side).
  • Tích hợp HTTP: Tự động load dữ liệu thông qua cấu hình httpRequestData.
  • Virtual Scroll: Tối ưu render danh sách lớn.
  • OnPush Change Detection: Tối ưu hiệu năng render.
  • Standalone Component: Dễ dàng import và sử dụng.
  • Angular Signals: State management hiện đại và reactive.
  • Custom Row/Column: Tùy biến layout từng item qua cấu hình rows/cols.

Khi nào sử dụng

  • Khi cần hiển thị danh sách các tùy chọn cho người dùng chọn một hoặc nhiều.
  • Khi xây dựng các bộ lọc (filters) có cấu trúc phân cấp phức tạp.
  • Khi danh sách có kích thước lớn và cần tối ưu hiệu năng render (Virtual Scroll).
  • Khi muốn đồng bộ hóa việc tìm kiếm và hiển thị dữ liệu từ API một cách tự động.

⚠️ Important Notes

  • Config Type: Phải luôn cung cấp type và signal config tương ứng (ví dụ: configTemplateText cho type text).
  • Performance: Virtual scroll được bật mặc định cho danh sách lớn. Tắt bằng cách set notUseVirtualScroll: true trong config.
  • Signals: Các cấu hình bên trong config (như httpRequestData) phải là WritableSignal để component có thể reactive.
  • keysDisableItem + configCheckboxCheckAll: Không dùng keysDisableItem kết hợp với template checkbox có configCheckboxCheckAll.

Cài đặt

# npm
npm install @libs-ui/components-list

# yarn
yarn add @libs-ui/components-list

Import

// Component chính
import { LibsUiComponentsListComponent } from '@libs-ui/components-list';

// Sub-component No-Data (khi cần dùng riêng)
import { LibsUiComponentsListTemplatesNoDataComponent } from '@libs-ui/components-list';

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

Ví dụ

Basic (Text – Single Select)

<libs_ui-components-list
  [config]="configText()"
  [keySelected]="keySelected()"
  (outSelectKey)="onSelect($event)"
  (outFunctionsControl)="onFunctionsControl($event)"></libs_ui-components-list>
configText = signal<IListConfigItem>({
  type: 'text',
  httpRequestData: signal<IHttpRequestConfig>({
    objectInstance: returnListObject(myData),
    argumentsValue: [],
    functionName: 'list',
  }),
  configTemplateText: signal({
    fieldKey: 'id',
    getValue: (item) => item.name || item.label,
  }),
});

Checkbox (Multi-select)

<libs_ui-components-list
  [config]="configCheckbox()"
  [multiKeySelected]="multiKeySelected()"
  (outSelectMultiKey)="onMultiSelect($event)"></libs_ui-components-list>
configCheckbox = signal<IListConfigItem>({
  type: 'checkbox',
  configTemplateCheckbox: signal({
    fieldKey: 'id',
    getValue: (item) => item.name,
  }),
});

Tag + Search

<libs_ui-components-list
  [config]="configTag()"
  [searchConfig]="{ placeholder: 'Tìm theo tên...' }"></libs_ui-components-list>
configTag = signal<IListConfigItem>({
  type: 'tag',
  configTemplateTag: signal({ fieldKey: 'id', getValue: (item) => item.name }),
});

Group / Tree

import { buildListGroupConfig } from '@libs-ui/components-list';

configGroup = signal<IListConfigItem>({
  type: 'group',
  configTemplateGroup: buildListGroupConfig('group_tree_checkbox_1'),
});

Custom Row & Column

configCustomRow = signal<IListConfigItem>({
  type: 'text',
  configTemplateText: signal({
    fieldKey: 'id',
    rows: signal([
      signal({
        classRow: 'flex flex-col',
        cols: signal([signal({ getValue: (data) => of(`<b>${data.item.name}</b>`) }), signal({ getValue: (data) => of(data.item.subTitle) })]),
      }),
      signal({ getValue: (data) => of(data.item.desc) }),
    ]),
  }),
});

No-Data (Default)

<libs_ui-components-list-templates-no_data
  [config]="configEmpty()"
  [keySearch]="''"
  [loading]="false"
  [enableNoData]="true"></libs_ui-components-list-templates-no_data>

No-Data (Custom trước khi search)

<ng-template #tplNoData>
  <div class="flex flex-col items-center p-4">
    <span>Vui lòng nhập thông tin để tìm kiếm.</span>
  </div>
</ng-template>

<libs_ui-components-list-templates-no_data
  [config]="configEmpty()"
  [keySearch]="''"
  [loading]="false"
  [enableNoData]="true"
  [templateRefNotSearchNoData]="tplNoData"></libs_ui-components-list-templates-no_data>

No-Result (Custom sau khi search)

<ng-template
  #tplNoResult
  let-keySearch="keySearch">
  <div>
    Không có kết quả cho:
    <b>{{ keySearch }}</b>
  </div>
</ng-template>

<libs_ui-components-list-templates-no_data
  [config]="configEmpty()"
  [keySearch]="searchKeyword"
  [loading]="false"
  [enableNoData]="true"
  [templateRefSearchNoData]="tplNoResult"></libs_ui-components-list-templates-no_data>

API

libs_ui-components-list

Inputs

| Property | Type | Default | Description | | ------------------------------------------------- | -------------------------------- | -------------- | -------------------------------------------------------------------------- | | autoSelectedFirstItemCallOutsideBefore | boolean | false | Tự động chọn item đầu tiên nếu chưa có item nào được chọn. | | backgroundListCustom | string | bg-[#ffffff] | Màu nền tùy chỉnh cho danh sách. | | buttonsOther | IButton[] | undefined | Danh sách các nút bấm khác hiển thị cuối danh sách. | | clickExactly | boolean | undefined | Chỉ kích hoạt chọn khi click chính xác vào item. | | config | IListConfigItem | REQUIRED | Cấu hình chính (loại template, logic lấy dữ liệu...). | | disable | boolean | false | Vô hiệu hóa toàn bộ component. | | disableLabel | boolean | false | Vô hiệu hóa nhãn (label). | | dividerClassInclude | string | undefined | Class CSS bổ sung cho đường kẻ phân cách. | | dropdownTabKeyActive | string | undefined | Key của tab đang active trong dropdown. | | focusInputSearch | boolean | undefined | Tự động focus vào ô tìm kiếm khi dữ liệu load xong. | | functionGetItemsAutoAddList | () => Array<any> | undefined | Hàm lấy danh sách item tự động thêm vào list. | | hasButtonUnSelectOption | boolean | undefined | Hiển thị nút bỏ chọn tất cả. | | hasDivider | boolean | true | Hiển thị gạch phân cách giữa các phần. | | hiddenInputSearch | boolean | false | Ẩn/hiện thanh tìm kiếm. | | ignoreClassDisableDefaultWhenUseKeysDisableItem | boolean | undefined | Bỏ class disable mặc định khi dùng keysDisableItem. | | isSearchOnline | boolean | false | Bật tìm kiếm từ Server (call API). | | keySearch | string | undefined | Giá trị tìm kiếm khởi tạo. | | keySelected | any | undefined | Key đang chọn (single select). | | keysDisableItem | Array<any> | undefined | Danh sách các keys bị vô hiệu hóa. | | keysHiddenItem | Array<any> | undefined | Danh sách các keys bị ẩn đi. | | labelConfig | ILabel | undefined | Cấu hình label tiêu đề cho danh sách. | | loadingIconSize | 'large' \| 'medium' \| 'small' | undefined | Kích thước icon loading. | | maxItemShow | number | undefined | Số lượng item tối đa hiển thị trước khi scroll. | | multiKeySelected | Array<any> | [] | Danh sách keys đang chọn (multi select). | | paddingLeftItem | boolean | undefined | Thêm padding bên trái cho item. | | resetKeyWhenSelectAllKeyDropdown | boolean | undefined | Reset key khi chọn tất cả trong dropdown. | | searchConfig | IInputSearchConfig | {} | Cấu hình chi tiết cho ô tìm kiếm. | | searchPadding | boolean | undefined | Thêm padding cho thanh tìm kiếm. | | showValidateBottom | boolean | undefined | Hiển thị thông báo validate ở phía dưới. | | skipFocusInputWhenKeySearchStoreUndefined | boolean | undefined | Bỏ qua focus input nếu keySearchStore là undefined. | | templateRefSearchNoData | TemplateRef | undefined | Template hiển thị khi tìm kiếm không có kết quả. | | templateRefNotSearchNoData | TemplateRef | undefined | Template hiển thị khi không trong trạng thái tìm kiếm và không có dữ liệu. | | validRequired | IValidRequired | undefined | Cấu hình bắt buộc phải chọn item. | | zIndex | number | undefined | Z-index cho danh sách. |

Outputs

| Property | Type | Description | | --------------------------------- | ----------------------------------------- | -------------------------------------------------------- | | (outChangeView) | Array<any> | Phát ra khi danh sách hiển thị thay đổi (ví dụ sau lọc). | | (outChangStageFlagMousePopover) | IFlagMouse | Phát ra trạng thái hover chuột cho popover. | | (outClickButtonOther) | IButton | Phát ra khi click vào các nút bấm bổ sung. | | (outFieldKey) | string | Phát ra key của trường dữ liệu được chọn. | | (outFunctionsControl) | IListFunctionControlEvent | Cung cấp các method điều khiển từ bên ngoài. | | (outKeySearch) | string | Phát ra khi keyword tìm kiếm thay đổi. | | (outLoadItemsComplete) | { items: Array<any>, paging?: IPaging } | Phát ra khi việc tải dữ liệu hoàn tất. | | (outLoading) | boolean | Trạng thái đang tải dữ liệu. | | (outSelectKey) | IListDataEmitKey | Phát ra khi chọn 1 item (Single Select). | | (outSelectMultiKey) | IListDataEmitMultiKey | Phát ra khi chọn nhiều item (Multi Select). | | (outUnSelectMultiKey) | Array<unknown> | Phát ra danh sách các keys bị bỏ chọn. |

Methods (via outFunctionsControl)

| Method | Parameters | Description | | -------------------- | -------------------------- | ----------------------------------------------------------- | | checkIsValid() | - | Kiểm tra tính hợp lệ của lựa chọn (nếu có validRequired). | | getRectListView() | - | Lấy kích thước và vị trí của list view container. | | refresh() | - | Làm mới danh sách và tải lại dữ liệu từ đầu. | | removeItems() | keys: Array<any> | Xóa các item cụ thể khỏi danh sách theo keys. | | resetKeySelected() | - | Xóa sạch toàn bộ các item đang được chọn. | | updateData() | data: IDataUpdateToStore | Cập nhật dữ liệu cụ thể vào store của list. |

libs_ui-components-list-templates-no_data

Sub-component hiển thị giao diện trạng thái No-Data, có thể dùng độc lập hoặc tích hợp qua [templateRefSearchNoData] / [templateRefNotSearchNoData].

Inputs

| Property | Type | Default | Description | | ---------------------------- | ----------------- | ------------ | ------------------------------------------------------------------------------ | | config | IListConfigItem | REQUIRED | Cấu hình list (dùng để lấy textNoData). | | keySearch | string | '' | Keyword đang search. Nếu rỗng → hiển thị no-data; nếu có → hiển thị no-result. | | loading | boolean | false | Đang tải dữ liệu — khi true sẽ không hiển thị no-data. | | enableNoData | boolean | false | Bật/tắt hiển thị trạng thái no-data. | | templateRefNotSearchNoData | TemplateRef | undefined | Template tùy chỉnh khi chưa tìm kiếm (keySearch rỗng). | | templateRefSearchNoData | TemplateRef | undefined | Template tùy chỉnh khi tìm kiếm không có kết quả. |

Types & Interfaces

export type TYPE_TEMPLATE = 'checkbox' | 'group' | 'radio' | 'text' | 'tag';

export interface IListConfigItem {
  type: TYPE_TEMPLATE;
  httpRequestData?: WritableSignal<IHttpRequestConfig>;
  configTemplateText?: WritableSignal<IListConfigItemText>;
  configTemplateRadio?: WritableSignal<IListConfigItemRadio>;
  configTemplateCheckbox?: WritableSignal<IListConfigItemCheckbox>;
  configTemplateGroup?: WritableSignal<IListConfigItemGroup>;
  configTemplateTag?: WritableSignal<IListConfigItemTag>;
  textNoData?: string;
  autoSelectFirstItem?: boolean;
  sort?: (items: Array<any>) => void;
  // ...
}

export interface IListDataEmitKey {
  key: unknown;
  item: any;
  isClickManual: boolean;
}

export interface IListDataEmitMultiKey {
  keys: Array<unknown>;
  mapKeys: Array<IListDataEmitKey>;
  isClickManual: boolean;
}

export interface IListFunctionControlEvent {
  checkIsValid: () => Promise<boolean>;
  refresh: () => Promise<void>;
  resetKeySelected: () => Promise<void>;
  getRectListView: () => Promise<IBoundingClientRect>;
  removeItems: (keys: Array<string>) => Promise<void>;
  updateData: (data: IDataUpdateToStore) => Promise<void>;
}

export interface IDataUpdateToStore {
  newData: WritableSignal<Array<WritableSignal<any>>>;
  functionCustomAddDataToStore: (newData: WritableSignal<Array<WritableSignal<any>>>, store: WritableSignal<Array<WritableSignal<any>>>) => void;
}

Demo

Công nghệ

| Technology | Purpose | | ----------------- | ----------------------------- | | Angular 18+ | Framework chính | | Angular Signals | Quản lý state reactive | | TailwindCSS | Styling hệ thống | | Dynamic Component | Khởi tạo template linh hoạt | | Virtual Scroll | Render danh sách lớn hiệu quả |

License

MIT