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

v0.2.357-4

Published

> Component chuyển đổi trạng thái Bật/Tắt (Toggle Switch) với hỗ trợ two-way binding Signal và xử lý async kèm cơ chế revert.

Readme

@libs-ui/components-switch

Component chuyển đổi trạng thái Bật/Tắt (Toggle Switch) với hỗ trợ two-way binding Signal và xử lý async kèm cơ chế revert.

Giới thiệu

LibsUiComponentsSwitchComponent là một standalone Angular component cung cấp giao diện Switch Button (Toggle). Component hỗ trợ 2 kích thước (defaultlarge), trạng thái disabled, và sử dụng Signal Model cho two-way binding. Khi toggle, component tự động cập nhật state trước khi emit event, đồng thời cung cấp hàm revert() để hoàn tác nếu cần (ví dụ: API call thất bại).

Tính năng

  • ✅ Two-way binding với Angular Signal Model ([(active)])
  • ✅ 2 kích thước: defaultlarge
  • ✅ Trạng thái disabled (vô hiệu hóa tương tác)
  • ✅ Event output (outSwitch) kèm hàm revert() để hoàn tác state
  • ✅ Hỗ trợ xử lý async (chờ API response rồi quyết định giữ hay revert)
  • ✅ Standalone component với ChangeDetectionStrategy.OnPush

Khi nào sử dụng

  • Khi người dùng cần bật/tắt một tính năng và hành động có hiệu lực ngay lập tức.
  • Thay thế cho Checkbox trong các màn hình cài đặt hệ thống, quản lý cấu hình.
  • Khi cần xác nhận toggle qua API trước khi chính thức cập nhật state (dùng revert() nếu API lỗi).

Cài đặt

npm install @libs-ui/components-switch

Import

import { LibsUiComponentsSwitchComponent } from '@libs-ui/components-switch';

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

Nếu cần dùng interface trong TypeScript:

import { LibsUiComponentsSwitchComponent, ISwitchEvent } from '@libs-ui/components-switch';

Ví dụ sử dụng

1. Basic — Two-way binding cơ bản

<!-- template.html -->
<div class="flex items-center gap-3">
  <libs_ui-components-switch [(active)]="isActive" />
  <span class="text-sm text-gray-700">
    Status: {{ isActive() ? 'ON' : 'OFF' }}
  </span>
</div>
// component.ts
import { Component, signal } from '@angular/core';
import { LibsUiComponentsSwitchComponent } from '@libs-ui/components-switch';

@Component({
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [LibsUiComponentsSwitchComponent],
  templateUrl: './my.component.html',
})
export class MyComponent {
  protected isActive = signal(false);
}

2. Sizes — Kích thước Default và Large

<!-- template.html -->
<div class="flex items-end gap-8">
  <div class="flex flex-col items-center gap-2">
    <span class="text-xs text-gray-500">Default</span>
    <libs_ui-components-switch size="default" [(active)]="isActiveDefault" />
  </div>

  <div class="flex flex-col items-center gap-2">
    <span class="text-xs text-gray-500">Large</span>
    <libs_ui-components-switch size="large" [(active)]="isActiveLarge" />
  </div>
</div>
// component.ts
protected isActiveDefault = signal(false);
protected isActiveLarge = signal(true);

3. Disabled State — Vô hiệu hóa tương tác

<!-- template.html -->
<div class="flex gap-8">
  <!-- Disabled & đang bật -->
  <div class="flex flex-col items-center gap-2">
    <span class="text-xs text-gray-500">Disabled (ON)</span>
    <libs_ui-components-switch [disable]="true" [active]="true" />
  </div>

  <!-- Disabled & đang tắt -->
  <div class="flex flex-col items-center gap-2">
    <span class="text-xs text-gray-500">Disabled (OFF)</span>
    <libs_ui-components-switch [disable]="true" [active]="false" />
  </div>
</div>

4. Async Handling — Xử lý API và revert nếu lỗi

<!-- template.html -->
<div class="flex items-center gap-4">
  <libs_ui-components-switch
    [(active)]="isActiveAsync"
    [disable]="isProcessing()"
    (outSwitch)="handlerAsyncSwitch($event)" />

  @if (isProcessing()) {
    <span class="text-sm text-blue-500">Đang xử lý...</span>
  }
</div>
// component.ts
import { Component, signal, ChangeDetectionStrategy } from '@angular/core';
import { LibsUiComponentsSwitchComponent, ISwitchEvent } from '@libs-ui/components-switch';

@Component({
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [LibsUiComponentsSwitchComponent],
  templateUrl: './my.component.html',
})
export class MyComponent {
  protected isActiveAsync = signal(false);
  protected isProcessing = signal(false);

  protected async handlerAsyncSwitch(event: ISwitchEvent): Promise<void> {
    event.stopPropagation?.();
    this.isProcessing.set(true);

    try {
      // Gọi API — ví dụ: lưu cài đặt thông báo
      await this.settingsService.updateNotification(event.active).toPromise();
      // Thành công: state giữ nguyên như đã toggle
    } catch {
      // Thất bại: revert lại state ban đầu
      await event.revert();
    } finally {
      this.isProcessing.set(false);
    }
  }
}

5. Lắng nghe sự kiện không dùng two-way binding

<!-- template.html -->
<libs_ui-components-switch
  [active]="isFeatureEnabled()"
  (outSwitch)="handlerFeatureToggle($event)" />
// component.ts
protected isFeatureEnabled = signal(false);

protected handlerFeatureToggle(event: ISwitchEvent): void {
  event.stopPropagation?.();
  console.log('Trạng thái mới:', event.active);
  // Tự quản lý state ngoài, không dùng [(active)] two-way binding
  this.isFeatureEnabled.set(event.active);
}

@Input()

| Input | Type | Default | Mô tả | Ví dụ | |---|---|---|---|---| | [(active)] / [active] | boolean (Signal Model) | false | Trạng thái bật/tắt của switch. Hỗ trợ two-way binding với [(active)] hoặc one-way với [active]. | [(active)]="isActive" | | [size] | 'default' \| 'large' | 'default' | Kích thước hiển thị của switch. | size="large" | | [disable] | boolean | undefined (falsy) | Vô hiệu hóa switch — người dùng không thể click khi true. Thường dùng khi đang chờ API response. | [disable]="isProcessing()" |

@Output()

| Output | Type | Mô tả | Handler TS | Binding HTML | |---|---|---|---|---| | (outSwitch) | ISwitchEvent | Emit sau khi state đã được toggle. Cung cấp active (trạng thái mới) và revert() để hoàn tác về trạng thái trước đó. | protected handlerSwitch(event: ISwitchEvent): void { event.stopPropagation?.(); ... } | (outSwitch)="handlerSwitch($event)" |

Types & Interfaces

import { ISwitchEvent, ISwitch } from '@libs-ui/components-switch';
/**
 * Event emit khi người dùng click vào switch.
 * State đã được toggle trước khi event này được emit.
 */
export interface ISwitchEvent {
  /** Trạng thái mới sau khi toggle (true = ON, false = OFF) */
  active: boolean;
  /** Hàm async để hoàn tác state về trước khi toggle — dùng khi API call thất bại */
  revert: () => Promise<void>;
}

/**
 * Interface mô tả cấu hình của Switch component.
 * Có thể dùng làm type cho object config truyền vào.
 */
export interface ISwitch {
  disable?: boolean;
  active?: boolean;
  action?: (event: ISwitchEvent) => Promise<void>;
}

Lưu ý quan trọng

⚠️ State toggle trước khi emit event: Component tự động toggle active state trước khi phát event (outSwitch). Điều này có nghĩa là event.active trong handler đã là giá trị MỚI. Nếu muốn giữ nguyên state (chờ API xác nhận), hãy gọi await event.revert() trong khối catch.

⚠️ Dùng [disable] khi đang xử lý async: Để tránh user click nhiều lần trong khi API đang chạy, truyền [disable]="isProcessing()" vào component. Điều này khóa switch cho đến khi xử lý xong.

⚠️ [(active)] vs [active]: Dùng [(active)] (two-way binding với Signal Model) khi muốn component tự quản lý state. Dùng [active] (one-way) kết hợp với (outSwitch) khi cần kiểm soát state thủ công từ bên ngoài.

⚠️ Không truyền hàm vào template: Tuân thủ convention dự án, tất cả logic xử lý event phải nằm trong handler method của component, không viết inline trên HTML.

Demo

npx nx serve core-ui

Truy cập: http://localhost:4500/components/switch