@libs-ui/components-buttons-select-color
v0.2.355-15
Published
> Component Button Select Color với color picker tích hợp, hỗ trợ chế độ apply ngay hoặc apply sau.
Readme
@libs-ui/components-buttons-select-color
Component Button Select Color với color picker tích hợp, hỗ trợ chế độ apply ngay hoặc apply sau.
Giới thiệu
LibsUiComponentsButtonsSelectColorComponent là một standalone Angular component được thiết kế để hiển thị button với color picker popover. Component hỗ trợ 2 chế độ: apply ngay (applyNow) khi chọn màu hoặc chọn trước rồi bấm nút Apply.
Tính năng
- ✅ 2 chế độ: Apply ngay hoặc Apply sau
- ✅ Color picker với đầy đủ định dạng (HEX, RGB, RGBA, HSL, HSLA)
- ✅ Tùy chỉnh button trigger
- ✅ Hỗ trợ external content (custom trigger)
- ✅ Tích hợp popover với nhiều tùy chọn vị trí
- ✅ Emit multiple color formats cùng lúc
- ✅ Tùy chỉnh color picker options
- ✅ Angular Signals cho tính phản hồi cao
- ✅ OnPush Change Detection tối ưu hiệu năng
- ✅ Auto cleanup khi destroy component
Khi nào sử dụng
- Khi cần cho phép user chọn màu sắc
- Khi cần color picker với nhiều định dạng màu
- Khi cần preview màu trước khi apply (applyNow = false)
- Phù hợp cho theme customization, design tools, color settings
Cài đặt
# npm
npm install @libs-ui/components-buttons-select-color
# yarn
yarn add @libs-ui/components-buttons-select-colorImport
import { LibsUiComponentsButtonsSelectColorComponent } from '@libs-ui/components-buttons-select-color';
import { IPickerCustomOptions, IOutputColorChangeMultipleType } from '@libs-ui/components-color-picker';
import { IButton } from '@libs-ui/components-buttons-button';
@Component({
standalone: true,
imports: [LibsUiComponentsButtonsSelectColorComponent],
// ...
})
export class YourComponent {}Ví dụ
Basic - Apply Ngay
<libs_ui-components-buttons-select_color
[button]="{ label: 'Select Color' }"
[applyNow]="true"
(outColorChange)="handleColorChange($event)" />handleColorChange(color: string) {
console.log('Selected color:', color);
}With Apply Button
<libs_ui-components-buttons-select_color
[button]="{ label: 'Choose Color' }"
[applyNow]="false"
(outColorChange)="handleColorChange($event)"
(outColorChangeMultipleType)="handleMultipleTypes($event)" />handleColorChange(color: string) {
console.log('Applied color:', color);
}
handleMultipleTypes(colors: IOutputColorChangeMultipleType) {
console.log('HEX:', colors.hex);
console.log('RGB:', colors.rgb);
console.log('RGBA:', colors.rgba);
console.log('HSL:', colors.hsl);
console.log('HSLA:', colors.hsla);
console.log('Alpha:', colors.alpha);
}Custom Button Style
<libs_ui-components-buttons-select_color
[button]="{
label: 'Pick Color',
type: 'button-secondary',
classIconLeft: 'libs-ui-icon-color-palette'
}"
[applyNow]="true"
(outColorChange)="handleColorChange($event)" />Custom Color Picker Options
<libs_ui-components-buttons-select_color
[button]="{ label: 'Select Color' }"
[customOptions]="{
color: '#ff5733',
showAlpha: true,
showHex: true,
showRgb: true,
showHsl: false,
format: 'hex'
}"
[applyNow]="true"
(outColorChange)="handleColorChange($event)" />customOptions: IPickerCustomOptions = {
color: '#ff5733',
showAlpha: true,
showHex: true,
showRgb: true,
showHsl: false,
format: 'hex',
};External Content (Custom Trigger)
<libs_ui-components-buttons-select_color
[externalContent]="true"
[applyNow]="true"
(outColorChange)="handleColorChange($event)">
<div class="libs-ui-buttons-select-color">
<div
class="w-10 h-10 rounded border-2 border-gray-300 cursor-pointer"
[style.background-color]="selectedColor"></div>
</div>
</libs_ui-components-buttons-select_color>selectedColor = '#3b82f6';
handleColorChange(color: string) {
this.selectedColor = color;
}Different Popover Directions
<!-- Bottom (default) -->
<libs_ui-components-buttons-select_color
[button]="{ label: 'Bottom' }"
[direction]="'bottom'"
[applyNow]="true" />
<!-- Top -->
<libs_ui-components-buttons-select_color
[button]="{ label: 'Top' }"
[direction]="'top'"
[applyNow]="true" />
<!-- Left -->
<libs_ui-components-buttons-select_color
[button]="{ label: 'Left' }"
[direction]="'left'"
[applyNow]="true" />
<!-- Right -->
<libs_ui-components-buttons-select_color
[button]="{ label: 'Right' }"
[direction]="'right'"
[applyNow]="true" />Icon Only Button
<libs_ui-components-buttons-select_color
[button]="{
classIconLeft: 'libs-ui-icon-color-palette',
iconOnlyType: true
}"
[applyNow]="true"
(outColorChange)="handleColorChange($event)" />With Custom Z-Index
<libs_ui-components-buttons-select_color
[button]="{ label: 'Select Color' }"
[(zIndex)]="customZIndex"
[applyNow]="true"
(outColorChange)="handleColorChange($event)" />customZIndex = 2000;API
libs_ui-components-buttons-select_color
Inputs
| Property | Type | Default | Description |
| ------------------- | ------------------------ | ----------- | ------------------------------------------------- |
| [applyNow] | boolean | false | Nếu true: chọn xong tự emit; false: cần bấm Apply |
| [button] | IButton | undefined | Cấu hình button trigger |
| [customOptions] | IPickerCustomOptions | undefined | Tùy chỉnh color picker options |
| [direction] | TYPE_POPOVER_DIRECTION | 'bottom' | Hướng hiển thị popover |
| [externalContent] | boolean | false | Sử dụng custom content thay vì button mặc định |
| [(zIndex)] | number | 1200 | Z-index của popover (two-way binding) |
Outputs
| Property | Type | Description |
| ------------------------------ | -------------------------------- | -------------------------------------------- |
| (outColorChange) | string | Emit màu đã chọn (format theo customOptions) |
| (outColorChangeMultipleType) | IOutputColorChangeMultipleType | Emit tất cả các định dạng màu cùng lúc |
Content Projection
| Selector | Description |
| ---------------------------------- | ------------------------------------------------- |
| div.libs-ui-buttons-select-color | Custom trigger content (khi externalContent=true) |
Types & Interfaces
IButton Interface
export interface IButton {
key?: string;
type?: TYPE_BUTTON;
sizeButton?: TYPE_SIZE_BUTTON;
iconOnlyType?: boolean;
label?: string;
disable?: boolean;
classInclude?: string;
classIconLeft?: string;
classIconRight?: string;
classLabel?: string;
popover?: IPopover;
ignoreStopPropagationEvent?: boolean;
zIndex?: number;
isPending?: boolean;
action?: (data?: any) => Promise<void>;
styleIconLeft?: Record<string, any>;
styleButton?: Record<string, any>;
buttonCustom?: IColorButton;
}IPickerCustomOptions Interface
export interface IPickerCustomOptions {
/** Kích thước saturation/lightness bar [width, height] */
slBarSize?: Array<number>;
/** Kích thước hue bar [width, height] */
hueBarSize?: Array<number>;
/** Kích thước alpha bar [width, height] */
alphaBarSize?: Array<number>;
/** Hiển thị HSL input */
showHsl?: boolean;
/** Hiển thị RGB input */
showRgb?: boolean;
/** Hiển thị HEX input */
showHex?: boolean;
/** Hiển thị Alpha slider */
showAlpha?: boolean;
/** Màu khởi tạo (HEX string hoặc RGB array) */
color?: string | Array<number>;
/** Format output mặc định */
format?: 'rgb' | 'rgba' | 'hsl' | 'hsla' | 'hex' | 'color';
}IOutputColorChangeMultipleType Interface
export interface IOutputColorChangeMultipleType {
/** Màu dạng RGBA string: "rgba(255, 0, 0, 1)" */
rgba: string;
/** Màu dạng RGB string: "rgb(255, 0, 0)" */
rgb: string;
/** Màu dạng HEX string: "#ff0000" */
hex: string;
/** Màu dạng HSL string: "hsl(0, 100%, 50%)" */
hsl: string;
/** Màu dạng HSLA string: "hsla(0, 100%, 50%, 1)" */
hsla: string;
/** Giá trị alpha (0-1) */
alpha: number;
}TYPE_POPOVER_DIRECTION
export type TYPE_POPOVER_DIRECTION = 'top' | 'bottom' | 'left' | 'right';Behavior
Apply Now Mode (applyNow = true)
- Khi chọn màu, component tự động emit
outColorChangevàoutColorChangeMultipleType - Không hiển thị Cancel/Apply buttons
- Popover vẫn mở sau khi chọn màu (user có thể tiếp tục điều chỉnh)
Apply Later Mode (applyNow = false)
- Khi chọn màu, component lưu tạm thời màu đã chọn
- Hiển thị Cancel và Apply buttons
- Click Cancel: đóng popover, không emit event
- Click Apply: emit
outColorChangevàoutColorChangeMultipleType, sau đó đóng popover
Popover Management
- Component tự động cleanup popover khi destroy (ngOnDestroy)
- Popover có thể được đóng bằng cách click outside (click-toggle mode)
- Z-index có thể được điều chỉnh để tránh conflicts
Công nghệ
| Technology | Version | Purpose | | --------------- | ------- | ---------------- | | Angular | 18+ | Framework | | Angular Signals | - | State management | | TailwindCSS | 3.x | Styling | | OnPush | - | Change Detection |
Demo
npx nx serve core-uiTruy cập: http://localhost:4500/buttons/select-color
Unit Tests
# Chạy tests
npx nx test buttons-select-color
# Coverage
npx nx test buttons-select-color --coverage
# Watch mode
npx nx test buttons-select-color --watchDependencies
@angular/core: >=18.0.0@libs-ui/components-buttons-button: 0.2.355-14@libs-ui/components-color-picker: 0.2.355-14@libs-ui/components-popover: 0.2.355-14@ngx-translate/core: ^15.0.0
Important Notes
⚠️ External Content Selector
Khi sử dụng [externalContent]="true", content projection PHẢI có class libs-ui-buttons-select-color:
<libs_ui-components-buttons-select_color [externalContent]="true">
<div class="libs-ui-buttons-select-color">
<!-- Your custom trigger here -->
</div>
</libs_ui-components-buttons-select_color>⚠️ Color Format
outColorChangeemit màu theo format được chỉ định trongcustomOptions.format- Nếu không chỉ định format, mặc định là format của màu input
outColorChangeMultipleTypeluôn emit tất cả các formats
⚠️ Z-Index Management
- Default z-index là 1200
- Nếu có conflicts với modals/dialogs khác, tăng z-index
- Z-index hỗ trợ two-way binding:
[(zIndex)]="myZIndex"
⚠️ Memory Management
Component tự động cleanup popover trong ngOnDestroy. Không cần manual cleanup.
Best Practices
- Sử dụng applyNow cho simple use cases: Nếu không cần preview, dùng
applyNow="true"để UX tốt hơn - Handle multiple formats: Sử dụng
outColorChangeMultipleTypekhi cần lưu nhiều formats - Custom trigger cho special cases: Dùng
externalContentkhi cần custom UI (color swatch, preview box...) - Set initial color: Luôn set
customOptions.colorđể có màu khởi tạo - Responsive z-index: Điều chỉnh z-index phù hợp với layout hierarchy
Troubleshooting
Color picker không hiển thị
- Kiểm tra z-index có bị overlap bởi elements khác không
- Verify
@libs-ui/components-color-pickerđã được install - Check console errors
External content không hoạt động
- Đảm bảo có class
libs-ui-buttons-select-colortrên wrapper div - Verify
[externalContent]="true"được set - Check content projection syntax
Màu không đúng format
- Kiểm tra
customOptions.formatsetting - Verify input color format hợp lệ
- Use
outColorChangeMultipleTypeđể có tất cả formats
Popover không đóng
- Component tự động cleanup trong ngOnDestroy
- Nếu cần đóng manual, có thể trigger click outside
- Check không có errors trong console
License
MIT
