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-checkbox-group

v0.2.357-4

Published

> Standalone Angular component quản lý nhóm các checkbox với two-way binding, validation bắt buộc chọn, layout linh hoạt và API điều khiển từ bên ngoài.

Readme

@libs-ui/components-checkbox-group

Standalone Angular component quản lý nhóm các checkbox với two-way binding, validation bắt buộc chọn, layout linh hoạt và API điều khiển từ bên ngoài.

Giới thiệu

LibsUiComponentsCheckboxGroupComponent là component độc lập cho phép hiển thị và quản lý một tập hợp các checkbox trong cùng một nhóm. Nó kế thừa đầy đủ khả năng của CheckboxSingleComponent cho mỗi item và bổ sung tính năng quản lý tập trung: theo dõi trạng thái chọn toàn nhóm, validation bắt buộc chọn, set trạng thái nhanh theo danh sách keys, và cấp phát API điều khiển cho component cha thông qua outFunctionsControl.

Tính năng

  • ✅ Two-way binding danh sách items qua model() — tự động đồng bộ khi trạng thái checkbox thay đổi
  • ✅ Set trạng thái checked/disabled hàng loạt bằng danh sách keys (keysChecked, keysDisable)
  • ✅ Layout dọc (mặc định) hoặc ngang (horizontal) với tùy chỉnh CSS linh hoạt
  • ✅ Validation bắt buộc chọn tích hợp (validRequired) với thông báo lỗi i18n
  • ✅ API điều khiển từ bên ngoài: checkIsValid(), reset(), resetError()
  • ✅ Hỗ trợ nội dung bổ sung cho từng item: subText, subTemplate
  • ✅ Hiển thị nhãn tổng quát (labelConfig) tích hợp component Label
  • ✅ Hỗ trợ viền bao quanh (modeBorder) và tùy chỉnh class CSS đầy đủ

Khi nào sử dụng

  • Quản lý danh sách lựa chọn nhiều giá trị (multi-select) trong form
  • Cần ràng buộc người dùng phải chọn ít nhất một giá trị trước khi submit
  • Cần hiển thị các checkbox theo hàng ngang để tiết kiệm diện tích màn hình
  • Cần điều khiển trạng thái toàn nhóm từ bên ngoài (reset, validate) thông qua API
  • Cần set sẵn trạng thái checked hoặc disabled cho một số items dựa vào dữ liệu từ API

Cài đặt

npm install @libs-ui/components-checkbox-group

Import

import {
  LibsUiComponentsCheckboxGroupComponent,
  ICheckboxGroupItem,
  ICheckboxGroupValidRequired,
  ICheckboxGroupFunctionControlEvent,
  ICheckboxItem,
} from '@libs-ui/components-checkbox-group';

Ví dụ sử dụng

1. Cơ bản — danh sách dọc với nhãn

import { Component, signal } from '@angular/core';
import {
  LibsUiComponentsCheckboxGroupComponent,
  ICheckboxGroupItem,
} from '@libs-ui/components-checkbox-group';
import { ICheckboxEvent } from '@libs-ui/components-checkbox-single';

@Component({
  selector: 'app-skills-form',
  standalone: true,
  imports: [LibsUiComponentsCheckboxGroupComponent],
  template: `
    <libs_ui-components-checkbox-group
      [(groups)]="skillOptions"
      [labelConfig]="{ labelLeft: 'Kỹ năng', required: true }"
      (outChange)="handlerSkillChange($event)"
    />
  `,
})
export class SkillsFormComponent {
  skillOptions = signal<ICheckboxGroupItem[]>([
    { item: { key: 'angular', label: 'Angular' } },
    { item: { key: 'react', label: 'React', checked: true } },
    { item: { key: 'vue', label: 'Vue.js' } },
    { item: { key: 'nodejs', label: 'Node.js' } },
  ]);

  handlerSkillChange(event: ICheckboxEvent): void {
    event.stopPropagation();
    console.log('Checked items:', event.allCheckboxChecked);
  }
}

2. Layout ngang — chọn thứ trong tuần

import { Component, signal } from '@angular/core';
import {
  LibsUiComponentsCheckboxGroupComponent,
  ICheckboxGroupItem,
} from '@libs-ui/components-checkbox-group';

@Component({
  selector: 'app-schedule-form',
  standalone: true,
  imports: [LibsUiComponentsCheckboxGroupComponent],
  template: `
    <libs_ui-components-checkbox-group
      [(groups)]="weekDays"
      [horizontal]="true"
      [labelConfig]="{ labelLeft: 'Lịch làm việc' }"
      [classItemWhenModeHorizontal]="'mr-[32px]'"
    />
  `,
})
export class ScheduleFormComponent {
  weekDays = signal<ICheckboxGroupItem[]>([
    { item: { key: 'mon', label: 'Thứ 2' } },
    { item: { key: 'tue', label: 'Thứ 3', checked: true } },
    { item: { key: 'wed', label: 'Thứ 4', checked: true } },
    { item: { key: 'thu', label: 'Thứ 5' } },
    { item: { key: 'fri', label: 'Thứ 6', checked: true } },
  ]);
}

3. Validation bắt buộc chọn

import { Component, signal } from '@angular/core';
import {
  LibsUiComponentsCheckboxGroupComponent,
  ICheckboxGroupItem,
} from '@libs-ui/components-checkbox-group';

@Component({
  selector: 'app-required-form',
  standalone: true,
  imports: [LibsUiComponentsCheckboxGroupComponent],
  template: `
    <libs_ui-components-checkbox-group
      [(groups)]="categories"
      [labelConfig]="{ labelLeft: 'Danh mục quan tâm', required: true }"
      [validRequired]="{
        message: 'Vui lòng chọn ít nhất một danh mục',
        hasBorderErrorCheckbox: true
      }"
      [showValidateBottom]="true"
    />
  `,
})
export class RequiredFormComponent {
  categories = signal<ICheckboxGroupItem[]>([
    { item: { key: 'tech', label: 'Công nghệ' } },
    { item: { key: 'finance', label: 'Tài chính' } },
    { item: { key: 'health', label: 'Sức khỏe' } },
  ]);
}

4. Điều khiển từ bên ngoài qua API

import { Component, signal } from '@angular/core';
import {
  LibsUiComponentsCheckboxGroupComponent,
  ICheckboxGroupItem,
  ICheckboxGroupFunctionControlEvent,
} from '@libs-ui/components-checkbox-group';

@Component({
  selector: 'app-form-with-api',
  standalone: true,
  imports: [LibsUiComponentsCheckboxGroupComponent],
  template: `
    <div class="flex gap-2 mb-4">
      <button (click)="handlerReset()">Reset</button>
      <button (click)="handlerValidate()">Validate</button>
    </div>

    <libs_ui-components-checkbox-group
      [(groups)]="items"
      [validRequired]="{ message: 'Bạn chưa chọn mục nào' }"
      [showValidateBottom]="true"
      (outFunctionsControl)="handlerFunctionsControl($event)"
    />
  `,
})
export class FormWithApiComponent {
  items = signal<ICheckboxGroupItem[]>([
    { item: { key: 'item1', label: 'Mục 1' } },
    { item: { key: 'item2', label: 'Mục 2' } },
    { item: { key: 'item3', label: 'Mục 3' } },
  ]);

  private checkboxControl: ICheckboxGroupFunctionControlEvent | null = null;

  handlerFunctionsControl(event: ICheckboxGroupFunctionControlEvent): void {
    event.stopPropagation();
    this.checkboxControl = event;
  }

  handlerReset(): void {
    this.checkboxControl?.reset();
  }

  handlerValidate(): void {
    this.checkboxControl?.checkIsValid();
  }
}

5. Set checked/disabled theo keys từ API

import { Component, signal } from '@angular/core';
import {
  LibsUiComponentsCheckboxGroupComponent,
  ICheckboxGroupItem,
} from '@libs-ui/components-checkbox-group';

@Component({
  selector: 'app-keys-control',
  standalone: true,
  imports: [LibsUiComponentsCheckboxGroupComponent],
  template: `
    <libs_ui-components-checkbox-group
      [(groups)]="permissions"
      [fieldKey]="'id'"
      [keysChecked]="checkedKeys()"
      [keysDisable]="disabledKeys()"
      [labelConfig]="{ labelLeft: 'Quyền truy cập' }"
    />
  `,
})
export class KeysControlComponent {
  permissions = signal<ICheckboxGroupItem[]>([
    { item: { id: 'read', label: 'Xem' } },
    { item: { id: 'write', label: 'Chỉnh sửa' } },
    { item: { id: 'delete', label: 'Xóa' } },
    { item: { id: 'admin', label: 'Quản trị' } },
  ]);

  // Keys sẽ được check sẵn khi component khởi tạo hoặc khi giá trị thay đổi
  checkedKeys = signal<string[]>(['read', 'write']);

  // Keys sẽ bị vô hiệu hóa
  disabledKeys = signal<string[]>(['admin']);
}

6. Item với nội dung bổ sung (subText / subTemplate)

import { Component, signal } from '@angular/core';
import {
  LibsUiComponentsCheckboxGroupComponent,
  ICheckboxGroupItem,
} from '@libs-ui/components-checkbox-group';

@Component({
  selector: 'app-subtext-example',
  standalone: true,
  imports: [LibsUiComponentsCheckboxGroupComponent],
  template: `
    <libs_ui-components-checkbox-group
      [(groups)]="planOptions"
      [labelConfig]="{ labelLeft: 'Chọn gói dịch vụ' }"
    />
  `,
})
export class SubtextExampleComponent {
  planOptions = signal<ICheckboxGroupItem[]>([
    {
      item: { key: 'basic', label: 'Gói Cơ bản' },
      subText: 'Bao gồm 5GB lưu trữ và hỗ trợ email.',
      classIncludeSubText: 'text-gray-500 pl-[24px] mt-[4px]',
    },
    {
      item: { key: 'pro', label: 'Gói Pro', checked: true },
      subText: 'Bao gồm 50GB lưu trữ, hỗ trợ 24/7 và API access.',
      classIncludeSubText: 'text-gray-500 pl-[24px] mt-[4px]',
    },
  ]);
}

@Input()

| Input | Type | Default | Mô tả | Ví dụ | |---|---|---|---|---| | [(groups)] | ICheckboxGroupItem[] | bắt buộc | Danh sách items trong nhóm, hỗ trợ two-way binding để đồng bộ trạng thái checked | [(groups)]="skillOptions" | | [classGroupWhenModeHorizontal] | string | 'flex' | Class CSS cho wrapper nhóm khi ở chế độ nằm ngang | [classGroupWhenModeHorizontal]="'flex flex-wrap'" | | [classInclude] | string | undefined | Class CSS bổ sung cho container checkbox của mỗi item | [classInclude]="'border rounded'" | | [classItemWhenModeHorizontal] | string | 'mr-[24px]' | Class CSS cho mỗi item khi ở chế độ nằm ngang | [classItemWhenModeHorizontal]="'mr-[32px]'" | | [classLabelInclude] | string | undefined | Class CSS bổ sung cho nhãn của mỗi checkbox | [classLabelInclude]="'libs-ui-font-h5m'" | | [clickExactly] | boolean | true | Nếu true, chỉ click vào ô checkbox/nhãn mới đổi trạng thái; nếu false, click vào vùng bao quanh cũng trigger | [clickExactly]="false" | | [disable] | boolean | false | Vô hiệu hóa tương tác cho toàn bộ nhóm checkbox | [disable]="isFormLocked()" | | [fieldKey] | string | 'key' | Tên trường dùng làm khóa định danh trong object item (dùng khi item data có field tên khác key) | [fieldKey]="'id'" | | [horizontal] | boolean | false | Nếu true, hiển thị các item theo hàng ngang thay vì hàng dọc | [horizontal]="true" | | [keysChecked] | string[] | undefined | Danh sách giá trị của fieldKey cần được set trạng thái checked khi khởi tạo hoặc khi thay đổi | [keysChecked]="selectedIds()" | | [keysDisable] | string[] | undefined | Danh sách giá trị của fieldKey cần được vô hiệu hóa | [keysDisable]="lockedIds()" | | [labelConfig] | ILabel | undefined | Cấu hình cho component Label hiển thị phía trên nhóm (nhãn, required, mô tả, nút...) | [labelConfig]="{ labelLeft: 'Kỹ năng', required: true }" | | [modeBorder] | boolean | undefined | Hiển thị viền bao quanh từng checkbox item | [modeBorder]="true" | | [showValidateBottom] | boolean | undefined | Nếu true, hiển thị thông báo lỗi validation ở phía dưới nhóm; nếu false (mặc định), hiển thị ở phía trên | [showValidateBottom]="true" | | [validRequired] | ICheckboxGroupValidRequired | undefined | Cấu hình validation bắt buộc chọn ít nhất một item. Khi set, component sẽ tự validate khi checkbox thay đổi | [validRequired]="{ message: 'Vui lòng chọn ít nhất một mục' }" |

@Output()

| Output | Type | Mô tả | Handler TS | Binding HTML | |---|---|---|---|---| | (outChange) | ICheckboxEvent | Phát ra khi bất kỳ checkbox nào trong nhóm thay đổi trạng thái. event.allCheckboxChecked chứa danh sách tất cả items đang được chọn | handlerChange(event: ICheckboxEvent): void { event.stopPropagation(); const selected = event.allCheckboxChecked; } | (outChange)="handlerChange($event)" | | (outFunctionsControl) | ICheckboxGroupFunctionControlEvent | Phát ra object chứa các hàm điều khiển component. Được emit một lần trong ngOnInit. Lưu lại để gọi checkIsValid(), reset(), resetError() từ bên ngoài | handlerFunctionsControl(event: ICheckboxGroupFunctionControlEvent): void { event.stopPropagation(); this.checkboxControl = event; } | (outFunctionsControl)="handlerFunctionsControl($event)" |

Types & Interfaces

import {
  ICheckboxGroupItem,
  ICheckboxGroupValidRequired,
  ICheckboxGroupFunctionControlEvent,
  ICheckboxItem,
} from '@libs-ui/components-checkbox-group';

ICheckboxGroupItem

Cấu hình cho mỗi phần tử trong nhóm checkbox.

interface ICheckboxGroupItem {
  /** Cấu hình chi tiết của checkbox item */
  item: ICheckboxItem;
  /** Văn bản bổ sung hiển thị bên dưới item khi item đang được chọn */
  subText?: string;
  /** Class CSS bổ sung cho phần subText */
  classIncludeSubText?: string;
  /** Template tùy chỉnh hiển thị khi item được chọn */
  subTemplate?: TemplateRef<any>;
  /** Trạng thái vô hiệu hóa tự động khi key nằm trong keysDisable (tự set bởi component) */
  disableByKeys?: boolean;
}

ICheckboxItem

Cấu hình chi tiết cho một checkbox đơn lẻ bên trong nhóm.

interface ICheckboxItem {
  /** Khóa định danh duy nhất (dùng với fieldKey='key' mặc định) */
  key?: string;
  /** Trạng thái chọn của checkbox */
  checked?: boolean;
  /** Nhãn văn bản hiển thị cạnh checkbox */
  label?: string;
  /** Class CSS bổ sung cho nhãn */
  classLabelInclude?: string;
  /** Trạng thái vô hiệu hóa của checkbox */
  disable?: boolean;
  /** Vô hiệu hóa tương tác click trên nhãn nhưng vẫn cho click ô checkbox */
  disableLabel?: boolean;
  /** Class CSS bổ sung cho wrapper của item */
  classIncludeWrapper?: string;
  /** Class CSS bổ sung cho ô checkbox */
  classInclude?: string;
  /** Nếu true, chỉ click vào checkbox/label mới trigger (override giá trị clickExactly của group) */
  clickExactly?: boolean;
  /** Cấu hình popover khi di chuột vào nhãn */
  popover?: IPopover;
  /** Loại nội dung popover ('text' | 'component') */
  typeLabelPopover?: TYPE_POPOVER_TYPE;
  /** Ẩn popover khi di chuột vào nhãn */
  ignoreShowPopoverLabel?: boolean;
  /** Cấu hình Avatar hiển thị cạnh checkbox */
  avatarConfig?: IAvatarConfig;
  /** URL hình ảnh hiển thị cạnh checkbox */
  linkImage?: string;
  /** URL hình ảnh dự phòng khi load lỗi */
  linkImageError?: string;
  /** Class CSS bổ sung cho phần hình ảnh */
  classImageInclude?: string;
  /** Cấu hình bullet (chấm tròn màu) */
  bullet?: ICheckboxBullet;
  /** Mô tả chi tiết hiển thị dưới nhãn */
  description?: ICheckboxItemDescription;
  /** Callback xử lý sự kiện từ popover */
  outEventPopover?: (event: TYPE_POPOVER_EVENT) => void;
  /** Các thuộc tính mở rộng — dùng khi fieldKey trỏ đến field khác 'key' */
  [key: string]: any;
}

ICheckboxGroupValidRequired

Cấu hình cho tính năng validation bắt buộc chọn.

interface ICheckboxGroupValidRequired {
  /** Thông báo lỗi khi không có item nào được chọn. Hỗ trợ i18n key. */
  message?: string;
  /** Nếu true, hiển thị viền đỏ trên các ô checkbox khi có lỗi validation */
  hasBorderErrorCheckbox?: boolean;
  /** Tham số nội suy cho thông báo lỗi i18n (dùng với TranslateModule) */
  interpolateParams?: any;
}

ICheckboxGroupFunctionControlEvent

API điều khiển component từ bên ngoài, nhận được qua (outFunctionsControl).

interface ICheckboxGroupFunctionControlEvent {
  /** Kích hoạt validation, trả về true nếu có ít nhất một item được chọn */
  checkIsValid: () => Promise<boolean>;
  /** Xóa trạng thái hiển thị lỗi validation */
  resetError: () => Promise<void>;
  /** Reset toàn bộ nhóm về trạng thái chưa chọn và xóa lỗi */
  reset: () => Promise<void>;
}

Lưu ý quan trọng

⚠️ groups là model bắt buộc: Input [(groups)]model.required() — component sẽ báo lỗi runtime nếu không truyền vào. Luôn khởi tạo với mảng hợp lệ (có thể rỗng []).

⚠️ subTextsubTemplate chỉ hiển thị khi item được chọn: Nội dung bổ sung (subText, subTemplate) chỉ render khi group.item.checked === true. Đây là behavior có chủ đích để hiển thị thông tin chi tiết khi người dùng chọn một option.

⚠️ outFunctionsControl emit một lần duy nhất trong ngOnInit: Lưu giá trị nhận được từ output này vào biến class để sử dụng sau. Không cần subscribe lại.

⚠️ keysCheckedkeysDisable phản ứng reactively: Khi thay đổi giá trị của keysChecked() hoặc keysDisable(), component tự động cập nhật trạng thái checked/disabled của các items tương ứng. Sử dụng signal cho hai input này để tận dụng tính năng này.

⚠️ fieldKey phải khớp với tên trường trong item: Khi dùng fieldKey khác 'key' (ví dụ 'id'), object trong ICheckboxItem phải có trường đó (ví dụ item.id). Vì ICheckboxItem[key: string]: any, bạn có thể thêm bất kỳ trường nào.

⚠️ disable cấp group override disable cấp item: Khi [disable]="true" trên group, toàn bộ nhóm bị khóa kể cả khi item có disable: false. keysDisable hoạt động độc lập và không bị override bởi disable của group.

Demo

npx nx serve core-ui

Truy cập: http://localhost:4500/components/checkbox/group

File demo: apps/core-ui/src/app/components/checkbox/group/group.component.ts