@libs-ui/components-inputs-color
v0.2.357-2
Published
> Component input chọn màu sắc (Color Picker) tích hợp palette mặc định, palette tùy chỉnh và điều chỉnh độ mờ (opacity).
Readme
@libs-ui/components-inputs-color
Component input chọn màu sắc (Color Picker) tích hợp palette mặc định, palette tùy chỉnh và điều chỉnh độ mờ (opacity).
Giới thiệu
LibsUiComponentsInputsColorComponent là một Standalone Angular component dùng để chọn màu sắc kết hợp điều chỉnh độ mờ. Component hiển thị dưới dạng một input thu gọn, khi click sẽ mở Popover chứa bảng màu mặc định, phần quản lý màu tùy chỉnh (tối đa 8 màu gần nhất), và một color picker nâng cao để thêm màu mới. Dữ liệu màu sắc và opacity được quản lý qua Angular model() cho phép two-way binding linh hoạt.
Tính năng
- ✅ Chọn màu từ palette mặc định (có thể cung cấp qua function hoặc dùng cache mặc định)
- ✅ Lưu và quản lý palette màu tùy chỉnh (tự động giới hạn 8 màu gần nhất)
- ✅ Điều chỉnh độ mờ (opacity) từ 0–100 trực tiếp trên input
- ✅ Two-way binding với
[(data)]qua Angularmodel() - ✅ Tích hợp Popover thông minh với
ignoreHiddenPopoverContentWhenMouseLeave - ✅ Hỗ trợ custom provider functions để lấy/lưu danh sách màu từ API
- ✅ Standalone Component, ChangeDetectionStrategy.OnPush
- ✅ Tự động cleanup popover khi component bị destroy
Khi nào sử dụng
- Khi cần cho phép người dùng chọn màu sắc trong form cấu hình giao diện, thiết kế chart, hoặc tùy biến theme.
- Khi cần tích hợp quản lý bảng màu cá nhân của người dùng (lưu/tải từ API).
- Khi cần điều chỉnh đồng thời cả màu sắc và độ trong suốt (opacity) của một phần tử.
- Khi cần một component compact — hiển thị ô màu + mã hex + input opacity trong một hàng duy nhất.
Cài đặt
npm install @libs-ui/components-inputs-colorImport
import { LibsUiComponentsInputsColorComponent } from '@libs-ui/components-inputs-color';
import { IColorPickerData } from '@libs-ui/components-inputs-color';
@Component({
standalone: true,
imports: [LibsUiComponentsInputsColorComponent],
// ...
})
export class YourComponent {}Ví dụ sử dụng
Ví dụ 1 — Cơ bản (Two-way binding)
import { Component, signal } from '@angular/core';
import { LibsUiComponentsInputsColorComponent, IColorPickerData } from '@libs-ui/components-inputs-color';
@Component({
selector: 'app-basic-color',
standalone: true,
imports: [LibsUiComponentsInputsColorComponent],
template: `
<libs_ui-components-inputs-color [(data)]="colorData" />
<p>Màu hiện tại: {{ colorData().color }} — Opacity: {{ colorData().opacity }}%</p>
`,
})
export class BasicColorComponent {
colorData = signal<IColorPickerData>({ color: '#3b82f6', opacity: 100 });
}Ví dụ 2 — Lắng nghe sự kiện thay đổi màu
import { Component, signal } from '@angular/core';
import { LibsUiComponentsInputsColorComponent, IColorPickerData } from '@libs-ui/components-inputs-color';
@Component({
selector: 'app-color-with-event',
standalone: true,
imports: [LibsUiComponentsInputsColorComponent],
template: `
<libs_ui-components-inputs-color
[(data)]="colorData"
(outColorChange)="handlerColorChange($event)"
/>
`,
})
export class ColorWithEventComponent {
colorData = signal<IColorPickerData>({ color: '#ef4444', opacity: 80 });
handlerColorChange(event: IColorPickerData): void {
event; // IColorPickerData không phải DOM Event, không cần stopPropagation
// Xử lý nghiệp vụ: lưu màu vào state, gọi API, v.v.
}
}Ví dụ 3 — Custom Provider (tích hợp API)
import { Component, signal } from '@angular/core';
import { LibsUiComponentsInputsColorComponent, IColorPickerData } from '@libs-ui/components-inputs-color';
@Component({
selector: 'app-color-custom-provider',
standalone: true,
imports: [LibsUiComponentsInputsColorComponent],
template: `
<libs_ui-components-inputs-color
[(data)]="colorData"
[functionGetListColorDefault]="getColorsDefault"
[functionGetListColorCustom]="getColorsCustom"
[functionSetListColorCustom]="saveColorsCustom"
(outColorChange)="handlerColorChange($event)"
/>
`,
})
export class ColorCustomProviderComponent {
colorData = signal<IColorPickerData>({ color: '#10b981', opacity: 100 });
getColorsDefault = async (): Promise<string[]> => {
// Ví dụ: gọi API hoặc trả về danh sách màu thương hiệu
return ['#ffffff', '#000000', '#ef4444', '#f97316', '#eab308', '#22c55e', '#3b82f6', '#8b5cf6'];
};
getColorsCustom = async (): Promise<string[]> => {
// Ví dụ: tải màu đã lưu của người dùng từ localStorage hoặc API
return JSON.parse(localStorage.getItem('user-colors') || '[]');
};
saveColorsCustom = async (colors: string[]): Promise<void> => {
// Ví dụ: lưu màu tùy chỉnh vào localStorage hoặc API
localStorage.setItem('user-colors', JSON.stringify(colors));
};
handlerColorChange(event: IColorPickerData): void {
// Cập nhật style preview hoặc notify component khác
}
}Ví dụ 4 — Tùy chỉnh Color Picker nâng cao
import { Component, signal } from '@angular/core';
import { LibsUiComponentsInputsColorComponent, IColorPickerData } from '@libs-ui/components-inputs-color';
import { IPickerCustomOptions } from '@libs-ui/components-color-picker';
@Component({
selector: 'app-color-advanced',
standalone: true,
imports: [LibsUiComponentsInputsColorComponent],
template: `
<libs_ui-components-inputs-color
[(data)]="colorData"
[customOptions]="pickerOptions"
[zIndex]="1300"
/>
`,
})
export class ColorAdvancedComponent {
colorData = signal<IColorPickerData>({ color: '#8b5cf6', opacity: 90 });
pickerOptions: IPickerCustomOptions = {
showHex: true,
showRgb: false,
showHsl: false,
showAlpha: true,
format: 'hex',
};
}@Input() / model()
| Input | Type | Default | Mô tả | Ví dụ |
|---|---|---|---|---|
| [(data)] | model<IColorPickerData> | { color: '', opacity: 100 } | Dữ liệu màu sắc (hex) và độ mờ (0–100). Hỗ trợ two-way binding. | [(data)]="colorData" |
| [(zIndex)] | model<number> | 1200 | Z-index của Popover bảng màu chính. Color picker nâng cao tự động dùng zIndex + 1. | [(zIndex)]="myZIndex" |
| [customOptions] | IPickerCustomOptions \| undefined | undefined | Tùy chỉnh giao diện color picker nâng cao (thanh hue, alpha, định dạng hiển thị). | [customOptions]="pickerOptions" |
| [functionGetListColorDefault] | (() => Promise<string[]>) \| undefined | undefined | Function async trả về mảng hex màu mặc định. Nếu không cung cấp, dùng cache nội bộ. | [functionGetListColorDefault]="getColors" |
| [functionGetListColorCustom] | (() => Promise<string[]>) \| undefined | undefined | Function async tải danh sách màu tùy chỉnh đã lưu của người dùng. | [functionGetListColorCustom]="loadCustom" |
| [functionSetListColorCustom] | ((colors: string[]) => Promise<void>) \| undefined | undefined | Function async lưu danh sách màu tùy chỉnh. Tự động giữ lại 8 màu gần nhất. | [functionSetListColorCustom]="saveCustom" |
@Output()
| Output | Type | Mô tả | Handler TS | Binding HTML |
|---|---|---|---|---|
| (outColorChange) | IColorPickerData | Emit khi người dùng chọn màu mới từ palette hoặc thay đổi opacity. | handlerColorChange(data: IColorPickerData): void { /* xử lý màu */ } | (outColorChange)="handlerColorChange($event)" |
Lưu ý:
outColorChangeemitIColorPickerData(không phải DOM Event), vì vậy không cần gọievent.stopPropagation()trong handler này. Tuy nhiên nếu handler được gắn vào DOM event khác, vẫn áp dụngstopPropagation()theo convention.
Types & Interfaces
import { IColorPickerData } from '@libs-ui/components-inputs-color';
import { IPickerCustomOptions } from '@libs-ui/components-color-picker';IColorPickerData
Dữ liệu màu sắc truyền vào/ra component. Là kiểu dữ liệu cho data model và outColorChange output.
export interface IColorPickerData {
/** Mã màu hex (ví dụ: '#3b82f6', '#ffffff') */
color: string;
/** Độ mờ từ 0 (trong suốt hoàn toàn) đến 100 (đục hoàn toàn) */
opacity: number;
}IPickerCustomOptions
Tùy chỉnh giao diện và tính năng cho color picker nâng cao (truyền qua [customOptions]).
export interface IPickerCustomOptions {
/** Kích thước thanh SL (Saturation-Lightness). Mặc định: [232, 150] */
slBarSize?: Array<number>;
/** Kích thước thanh Hue. Mặc định: [232, 12] */
hueBarSize?: Array<number>;
/** Kích thước thanh Alpha (opacity). Mặc định: [232, 12] */
alphaBarSize?: Array<number>;
/** Hiển thị input HSL. Mặc định: true */
showHsl?: boolean;
/** Hiển thị input RGB. Mặc định: true */
showRgb?: boolean;
/** Hiển thị input HEX. Mặc định: true */
showHex?: boolean;
/** Hiển thị thanh Alpha (opacity). Mặc định: true */
showAlpha?: boolean;
/** Màu khởi tạo ban đầu cho color picker */
color?: string | Array<number>;
/** Định dạng giá trị trả về */
format?: 'rgb' | 'rgba' | 'hsl' | 'hsla' | 'hex' | 'color';
}Lưu ý quan trọng
⚠️ Cache nội bộ khi không cung cấp provider functions: Nếu không truyền functionGetListColorDefault, functionGetListColorCustom hoặc functionSetListColorCustom, component sẽ tự động dùng UtilsCache với các key cố định nội bộ. Hành vi này có thể gây xung đột nếu nhiều instance dùng chung cache. Khuyến nghị luôn cung cấp đầy đủ 3 provider functions khi dùng trong production.
⚠️ Giới hạn màu tùy chỉnh: Khi người dùng thêm màu mới qua color picker nâng cao, component tự động giữ lại tối đa 8 màu gần nhất (LIFO — màu mới nhất ở đầu). Màu cũ hơn sẽ bị loại bỏ.
⚠️ Z-index tự động tăng: Popover color picker nâng cao (khi click "Thêm màu") tự động sử dụng zIndex + 1 so với Popover bảng màu chính. Nếu component nằm trong các lớp overlay khác (dialog, drawer), hãy truyền [zIndex] phù hợp để tránh bị che khuất.
⚠️ Cleanup tự động: Component tự gọi removePopoverOverlay() trong ngOnDestroy. Không cần xử lý cleanup popover thủ công từ component cha.
Demo
npx nx serve core-uiTruy cập: http://localhost:4500/components/inputs/color
