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

v0.2.357-4

Published

> Component hiển thị hiệu ứng loading (spinner) với animation xoay mượt mà, hỗ trợ nhiều kích thước và chế độ màu sắc.

Downloads

4,287

Readme

@libs-ui/components-spinner

Component hiển thị hiệu ứng loading (spinner) với animation xoay mượt mà, hỗ trợ nhiều kích thước và chế độ màu sắc.

Giới thiệu

LibsUiComponentsSpinnerComponent là một standalone Angular component hiển thị spinner loading dựa trên CSS conic-gradientmask. Component hỗ trợ 4 kích thước chuẩn, 2 màu sắc (xanh và trắng), và 2 chế độ vị trí: normal flow và absolute (tự căn giữa container cha). Phù hợp để thể hiện trạng thái loading cục bộ (trong button, card) hoặc loading overlay toàn vùng.

Tính năng

  • ✅ Animation xoay mượt mà dùng CSS conic-gradient — không cần SVG icon hay ảnh ngoài
  • ✅ 4 kích thước chuẩn: large (64px), medium (20px), small (16px), smaller (12px)
  • ✅ 2 chế độ màu: xanh (blue) và trắng (white)
  • ✅ 2 chế độ vị trí: normal flow và absolute (tự căn giữa tuyệt đối)
  • ✅ Standalone component, OnPush, không phụ thuộc thư viện ngoài

Khi nào sử dụng

  • Khi đang tải dữ liệu cục bộ trong button, card, hoặc input để thay cho text "Loading..."
  • Khi cần overlay loading trên một vùng content (container, modal, section)
  • Khi cần loading toàn trang hoặc toàn modal với chế độ spin-absolute-*
  • Khi muốn biểu thị trạng thái xử lý (submit form, sync dữ liệu) ở button nhỏ với size="smaller"

Cài đặt

npm install @libs-ui/components-spinner

Import

import { LibsUiComponentsSpinnerComponent } from '@libs-ui/components-spinner';

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

Export type đi kèm:

import { TYPE_SPINNER } from '@libs-ui/components-spinner';

Ví dụ sử dụng

1. Spinner mặc định (medium, absolute blue)

<div class="relative w-full h-[200px]">
  <libs_ui-components-spinner />
</div>

Container cha cần position: relative khi dùng type mặc định spin-absolute-blue.

2. Spinner inline trong button

import { LibsUiComponentsSpinnerComponent } from '@libs-ui/components-spinner';
import { Component, signal } from '@angular/core';

@Component({
  standalone: true,
  imports: [LibsUiComponentsSpinnerComponent],
  template: `
    <button
      class="px-4 py-2 rounded-md bg-blue-600 text-white flex items-center gap-2"
      (click)="handlerSave($event)">
      @if (isSaving()) {
        <libs_ui-components-spinner
          type="spin-white"
          size="small" />
      }
      <span>{{ isSaving() ? 'Đang lưu...' : 'Lưu' }}</span>
    </button>
  `,
})
export class SaveButtonComponent {
  protected isSaving = signal(false);

  protected handlerSave(event: Event): void {
    event.stopPropagation();
    this.isSaving.set(true);
    // gọi API, rồi set false khi xong
  }
}

3. Spinner overlay trên vùng content

import { LibsUiComponentsSpinnerComponent } from '@libs-ui/components-spinner';
import { Component, signal } from '@angular/core';

@Component({
  standalone: true,
  imports: [LibsUiComponentsSpinnerComponent],
  template: `
    <div class="relative w-full min-h-[300px] border rounded-lg">
      <!-- Nội dung chính -->
      <div class="p-6">
        <h2 class="text-lg font-semibold">Danh sách sản phẩm</h2>
        <p class="text-gray-500 mt-2">Nội dung sẽ hiển thị ở đây...</p>
      </div>

      <!-- Overlay loading khi đang tải -->
      @if (isLoading()) {
        <div class="absolute inset-0 bg-white/70 rounded-lg">
          <libs_ui-components-spinner
            type="spin-absolute-blue"
            size="large" />
        </div>
      }
    </div>
  `,
})
export class ProductListComponent {
  protected isLoading = signal(true);
}

4. So sánh các kích thước

<!-- large: 64px — dùng cho overlay toàn vùng lớn -->
<libs_ui-components-spinner type="spin-blue" size="large" />

<!-- medium: 20px — kích thước mặc định, dùng cho card, section -->
<libs_ui-components-spinner type="spin-blue" size="medium" />

<!-- small: 16px — dùng trong button tiêu chuẩn -->
<libs_ui-components-spinner type="spin-blue" size="small" />

<!-- smaller: 12px — dùng trong button nhỏ, icon compact -->
<libs_ui-components-spinner type="spin-white" size="smaller" />

5. Spinner màu trắng trên nền tối

<div class="bg-blue-600 rounded-lg p-6 flex items-center gap-3">
  <libs_ui-components-spinner
    type="spin-white"
    size="medium" />
  <span class="text-white font-medium">Đang xử lý...</span>
</div>

@Input()

| Input | Type | Default | Mô tả | Ví dụ | |---|---|---|---|---| | [type] | TYPE_SPINNER | 'spin-absolute-blue' | Chế độ hiển thị — xác định màu sắc và kiểu vị trí của spinner | type="spin-blue" | | [size] | 'large' \| 'medium' \| 'small' \| 'smaller' | 'medium' | Kích thước spinner: large=64px, medium=20px, small=16px, smaller=12px | size="large" |

Types & Interfaces

import { TYPE_SPINNER } from '@libs-ui/components-spinner';

type TYPE_SPINNER =
  | 'spin-absolute-blue'   // position: absolute, căn giữa container cha — màu xanh
  | 'spin-absolute-white'  // position: absolute, căn giữa container cha — màu trắng
  | 'spin-blue'            // normal flow (position: relative) — màu xanh
  | 'spin-white';          // normal flow (position: relative) — màu trắng

Bảng đối chiếu type

| type | Màu sắc | Vị trí | Dùng khi | |---|---|---|---| | spin-absolute-blue | Xanh | position: absolute, căn giữa | Overlay loading trên container cha có relative | | spin-absolute-white | Trắng | position: absolute, căn giữa | Overlay loading trên nền tối có relative | | spin-blue | Xanh | Normal flow | Inline trong button, card trên nền sáng | | spin-white | Trắng | Normal flow | Inline trong button, card trên nền tối/màu |

Lưu ý quan trọng

⚠️ Reactivity của size: Kích thước (width, height) được tính một lần duy nhất tại ngOnInit. Thay đổi input size sau khi component đã render sẽ không cập nhật kích thước spinner. Nếu cần thay đổi size động, dùng @if để destroy và re-create component:

<!-- Cách xử lý thay đổi size động -->
@if (showSpinner()) {
  <libs_ui-components-spinner [type]="spinnerType()" [size]="spinnerSize()" />
}

⚠️ Container cha với spin-absolute-*: Khi dùng type="spin-absolute-blue" hoặc type="spin-absolute-white", component tự áp dụng position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%). Bắt buộc container cha phải có position: relative để spinner căn giữa chính xác:

<!-- ✅ ĐÚNG — container có position: relative -->
<div class="relative w-full h-[200px]">
  <libs_ui-components-spinner type="spin-absolute-blue" size="large" />
</div>

<!-- ❌ SAI — thiếu relative, spinner có thể bị offset sai -->
<div class="w-full h-[200px]">
  <libs_ui-components-spinner type="spin-absolute-blue" size="large" />
</div>

⚠️ Giá trị null/undefined cho input: Cả typesize đều có transform guard — nếu truyền vào null hay undefined, component tự fallback về giá trị mặc định ('spin-absolute-blue''medium').

Demo

npx nx serve core-ui

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