@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-gradient và mask. 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-spinnerImport
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: relativekhi dùng type mặc địnhspin-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ắngBả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ả type và size đề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' và 'medium').
Demo
npx nx serve core-uiTruy cập: http://localhost:4500/components/spinner
