@libs-ui/components-buttons-select-color 0.2.355-9 → 0.2.356-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +392 -83
  2. package/package.json +4 -4
package/README.md CHANGED
@@ -1,148 +1,457 @@
1
- # Buttons Select Color
1
+ # @libs-ui/components-buttons-select-color
2
2
 
3
- ## Giới thiệu
3
+ > Component Button Select Color với color picker tích hợp, hỗ trợ chế độ apply ngay hoặc apply sau.
4
4
 
5
- `select-color` một component nút kết hợp bộ chọn màu (Color Picker) cho Angular. Cho phép người dùng chọn màu sắc từ popover, hỗ trợ cấu hình tùy chỉnh, áp dụng ngay hoặc chờ xác nhận, và tùy chỉnh hiển thị nút.
5
+ ## Giới thiệu
6
6
 
7
- ## Tính năng
7
+ `LibsUiComponentsButtonsSelectColorComponent` 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.
8
8
 
9
- - Mở popover Color Picker khi click vào nút tùy chỉnh
10
- - Tùy chỉnh trigger button (nhãn, icon, kiểu, class)
11
- - Hỗ trợ cấu hình `customOptions` cho Color Picker
12
- - Hỗ trợ `applyNow`: tự động emit khi chọn màu nếu `true`
13
- - Hỗ trợ `externalContent`: sử dụng nội dung bên ngoài làm trigger
14
- - Tùy chọn hướng hiển thị `direction` và `zIndex` của popover
15
- - Phát sự kiện `outColorChange` và `outColorChangeMultipleType` khi màu thay đổi
9
+ ### Tính năng
16
10
 
17
- ## Cài đặt
11
+ - 2 chế độ: Apply ngay hoặc Apply sau
12
+ - ✅ Color picker với đầy đủ định dạng (HEX, RGB, RGBA, HSL, HSLA)
13
+ - ✅ Tùy chỉnh button trigger
14
+ - ✅ Hỗ trợ external content (custom trigger)
15
+ - ✅ Tích hợp popover với nhiều tùy chọn vị trí
16
+ - ✅ Emit multiple color formats cùng lúc
17
+ - ✅ Tùy chỉnh color picker options
18
+ - ✅ Angular Signals cho tính phản hồi cao
19
+ - ✅ OnPush Change Detection tối ưu hiệu năng
20
+ - ✅ Auto cleanup khi destroy component
18
21
 
19
- ### Yêu cầu
22
+ ## Khi nào sử dụng
20
23
 
21
- - Angular 18.0.0 trở lên
22
- - Tailwind CSS 3.3.0 trở lên
24
+ - Khi cần cho phép user chọn màu sắc
25
+ - Khi cần color picker với nhiều định dạng màu
26
+ - Khi cần preview màu trước khi apply (applyNow = false)
27
+ - Phù hợp cho theme customization, design tools, color settings
23
28
 
24
- ### Hướng dẫn
25
-
26
- Để cài đặt component `select-color`, sử dụng npm hoặc yarn:
29
+ ## Cài đặt
27
30
 
28
31
  ```bash
32
+ # npm
29
33
  npm install @libs-ui/components-buttons-select-color
30
- ```
31
-
32
- hoặc
33
34
 
34
- ```bash
35
+ # yarn
35
36
  yarn add @libs-ui/components-buttons-select-color
36
37
  ```
37
38
 
38
- ## Sử dụng
39
-
40
- ### Cách 1: Import inline template
39
+ ## Import
41
40
 
42
41
  ```typescript
43
- import { Component } from '@angular/core';
44
42
  import { LibsUiComponentsButtonsSelectColorComponent } from '@libs-ui/components-buttons-select-color';
43
+ import { IPickerCustomOptions, IOutputColorChangeMultipleType } from '@libs-ui/components-color-picker';
44
+ import { IButton } from '@libs-ui/components-buttons-button';
45
45
 
46
46
  @Component({
47
- selector: 'app-example',
48
47
  standalone: true,
49
48
  imports: [LibsUiComponentsButtonsSelectColorComponent],
50
- template: `
51
- <libs_ui-components-buttons-select_color
52
- [button]="{ label: 'Chọn màu', type: 'button-primary' }"
53
- [customOptions]="{ /* cấu hình picker */ }"
54
- [applyNow]="false"
55
- (outColorChange)="onColorChange($event)"></libs_ui-components-buttons-select_color>
56
- `,
49
+ // ...
57
50
  })
58
- export class ExampleComponent {
59
- onColorChange(color: string) {
60
- console.log('Màu đã chọn:', color);
61
- }
51
+ export class YourComponent {}
52
+ ```
53
+
54
+ ## Ví dụ
55
+
56
+ ### Basic - Apply Ngay
57
+
58
+ ```html
59
+ <libs_ui-components-buttons-select_color
60
+ [button]="{ label: 'Select Color' }"
61
+ [applyNow]="true"
62
+ (outColorChange)="handleColorChange($event)" />
63
+ ```
64
+
65
+ ```typescript
66
+ handleColorChange(color: string) {
67
+ console.log('Selected color:', color);
62
68
  }
63
69
  ```
64
70
 
65
- ### Cách 2: Sử dụng file HTML riêng biệt
71
+ ### With Apply Button
66
72
 
67
73
  ```html
68
- <!-- example.component.html -->
69
74
  <libs_ui-components-buttons-select_color
70
- [button]="{ label: 'Chọn màu', classIconLeft: 'text-red-500', type: 'button-outline' }"
71
- [direction]="'top'"
72
- [externalContent]="false"
73
- [zIndex]="1500"
74
- (outColorChangeMultipleType)="onMultiColorChange($event)"></libs_ui-components-buttons-select_color>
75
+ [button]="{ label: 'Choose Color' }"
76
+ [applyNow]="false"
77
+ (outColorChange)="handleColorChange($event)"
78
+ (outColorChangeMultipleType)="handleMultipleTypes($event)" />
75
79
  ```
76
80
 
77
81
  ```typescript
78
- // example.component.ts
79
- import { Component } from '@angular/core';
80
- import { LibsUiComponentsButtonsSelectColorComponent } from '@libs-ui/components-buttons-select-color';
82
+ handleColorChange(color: string) {
83
+ console.log('Applied color:', color);
84
+ }
81
85
 
82
- @Component({
83
- selector: 'app-example',
84
- standalone: true,
85
- imports: [LibsUiComponentsButtonsSelectColorComponent],
86
- templateUrl: './example.component.html',
87
- })
88
- export class ExampleComponent {}
86
+ handleMultipleTypes(colors: IOutputColorChangeMultipleType) {
87
+ console.log('HEX:', colors.hex);
88
+ console.log('RGB:', colors.rgb);
89
+ console.log('RGBA:', colors.rgba);
90
+ console.log('HSL:', colors.hsl);
91
+ console.log('HSLA:', colors.hsla);
92
+ console.log('Alpha:', colors.alpha);
93
+ }
94
+ ```
95
+
96
+ ### Custom Button Style
97
+
98
+ ```html
99
+ <libs_ui-components-buttons-select_color
100
+ [button]="{
101
+ label: 'Pick Color',
102
+ type: 'button-secondary',
103
+ classIconLeft: 'libs-ui-icon-color-palette'
104
+ }"
105
+ [applyNow]="true"
106
+ (outColorChange)="handleColorChange($event)" />
107
+ ```
108
+
109
+ ### Custom Color Picker Options
110
+
111
+ ```html
112
+ <libs_ui-components-buttons-select_color
113
+ [button]="{ label: 'Select Color' }"
114
+ [customOptions]="{
115
+ color: '#ff5733',
116
+ showAlpha: true,
117
+ showHex: true,
118
+ showRgb: true,
119
+ showHsl: false,
120
+ format: 'hex'
121
+ }"
122
+ [applyNow]="true"
123
+ (outColorChange)="handleColorChange($event)" />
124
+ ```
125
+
126
+ ```typescript
127
+ customOptions: IPickerCustomOptions = {
128
+ color: '#ff5733',
129
+ showAlpha: true,
130
+ showHex: true,
131
+ showRgb: true,
132
+ showHsl: false,
133
+ format: 'hex',
134
+ };
135
+ ```
136
+
137
+ ### External Content (Custom Trigger)
138
+
139
+ ```html
140
+ <libs_ui-components-buttons-select_color
141
+ [externalContent]="true"
142
+ [applyNow]="true"
143
+ (outColorChange)="handleColorChange($event)">
144
+ <div class="libs-ui-buttons-select-color">
145
+ <div
146
+ class="w-10 h-10 rounded border-2 border-gray-300 cursor-pointer"
147
+ [style.background-color]="selectedColor"></div>
148
+ </div>
149
+ </libs_ui-components-buttons-select_color>
150
+ ```
151
+
152
+ ```typescript
153
+ selectedColor = '#3b82f6';
154
+
155
+ handleColorChange(color: string) {
156
+ this.selectedColor = color;
157
+ }
158
+ ```
159
+
160
+ ### Different Popover Directions
161
+
162
+ ```html
163
+ <!-- Bottom (default) -->
164
+ <libs_ui-components-buttons-select_color
165
+ [button]="{ label: 'Bottom' }"
166
+ [direction]="'bottom'"
167
+ [applyNow]="true" />
168
+
169
+ <!-- Top -->
170
+ <libs_ui-components-buttons-select_color
171
+ [button]="{ label: 'Top' }"
172
+ [direction]="'top'"
173
+ [applyNow]="true" />
174
+
175
+ <!-- Left -->
176
+ <libs_ui-components-buttons-select_color
177
+ [button]="{ label: 'Left' }"
178
+ [direction]="'left'"
179
+ [applyNow]="true" />
180
+
181
+ <!-- Right -->
182
+ <libs_ui-components-buttons-select_color
183
+ [button]="{ label: 'Right' }"
184
+ [direction]="'right'"
185
+ [applyNow]="true" />
186
+ ```
187
+
188
+ ### Icon Only Button
189
+
190
+ ```html
191
+ <libs_ui-components-buttons-select_color
192
+ [button]="{
193
+ classIconLeft: 'libs-ui-icon-color-palette',
194
+ iconOnlyType: true
195
+ }"
196
+ [applyNow]="true"
197
+ (outColorChange)="handleColorChange($event)" />
198
+ ```
199
+
200
+ ### With Custom Z-Index
201
+
202
+ ```html
203
+ <libs_ui-components-buttons-select_color
204
+ [button]="{ label: 'Select Color' }"
205
+ [(zIndex)]="customZIndex"
206
+ [applyNow]="true"
207
+ (outColorChange)="handleColorChange($event)" />
208
+ ```
209
+
210
+ ```typescript
211
+ customZIndex = 2000;
89
212
  ```
90
213
 
91
- ## Công nghệ sử dụng
214
+ ## API
215
+
216
+ ### libs_ui-components-buttons-select_color
92
217
 
93
- - **Angular 18**: standalone components, signals, control flow
94
- - **Tailwind CSS**: quản lý style, tiện lợi để xây dựng demo
218
+ #### Inputs
95
219
 
96
- ## API Reference
220
+ | Property | Type | Default | Description |
221
+ | ------------------- | ------------------------ | ----------- | ------------------------------------------------- |
222
+ | `[applyNow]` | `boolean` | `false` | Nếu true: chọn xong tự emit; false: cần bấm Apply |
223
+ | `[button]` | `IButton` | `undefined` | Cấu hình button trigger |
224
+ | `[customOptions]` | `IPickerCustomOptions` | `undefined` | Tùy chỉnh color picker options |
225
+ | `[direction]` | `TYPE_POPOVER_DIRECTION` | `'bottom'` | Hướng hiển thị popover |
226
+ | `[externalContent]` | `boolean` | `false` | Sử dụng custom content thay vì button mặc định |
227
+ | `[(zIndex)]` | `number` | `1200` | Z-index của popover (two-way binding) |
97
228
 
98
- ### Inputs
229
+ #### Outputs
99
230
 
100
- | Tên | Kiểu dữ liệu | Mặc định | Mô tả |
101
- | --------------- | ------------------------ | ---------- | ----------------------------------------------------------- |
102
- | button | `IButton` | - | Cấu hình trigger button (label, icon, class, popover, ...). |
103
- | customOptions | `IPickerCustomOptions` | - | Tùy chọn cấu hình cho Color Picker. |
104
- | applyNow | `boolean` | `false` | Nếu `true`, emit `outColorChange` ngay khi chọn màu. |
105
- | externalContent | `boolean` | `false` | Sử dụng nội dung bên ngoài làm trigger. |
106
- | direction | `TYPE_POPOVER_DIRECTION` | `'bottom'` | Hướng hiển thị của popover. |
107
- | zIndex | `number` | `1200` | Z-index của popover. |
231
+ | Property | Type | Description |
232
+ | ------------------------------ | -------------------------------- | -------------------------------------------- |
233
+ | `(outColorChange)` | `string` | Emit màu đã chọn (format theo customOptions) |
234
+ | `(outColorChangeMultipleType)` | `IOutputColorChangeMultipleType` | Emit tất cả các định dạng màu cùng lúc |
108
235
 
109
- ### Outputs
236
+ #### Content Projection
110
237
 
111
- | Tên | Kiểu dữ liệu | Mô tả |
112
- | -------------------------- | -------------------------------- | ------------------------------------------- |
113
- | outColorChange | `string` | Sự kiện emit màu khi chọn (dạng hex). |
114
- | outColorChangeMultipleType | `IOutputColorChangeMultipleType` | Sự kiện emit nhiều định dạng màu khác nhau. |
238
+ | Selector | Description |
239
+ | ---------------------------------- | ------------------------------------------------- |
240
+ | `div.libs-ui-buttons-select-color` | Custom trigger content (khi externalContent=true) |
115
241
 
116
- ### Interfaces
242
+ ## Types & Interfaces
117
243
 
118
- #### IPickerCustomOptions
244
+ ### IButton Interface
245
+
246
+ ```typescript
247
+ export interface IButton {
248
+ key?: string;
249
+ type?: TYPE_BUTTON;
250
+ sizeButton?: TYPE_SIZE_BUTTON;
251
+ iconOnlyType?: boolean;
252
+ label?: string;
253
+ disable?: boolean;
254
+ classInclude?: string;
255
+ classIconLeft?: string;
256
+ classIconRight?: string;
257
+ classLabel?: string;
258
+ popover?: IPopover;
259
+ ignoreStopPropagationEvent?: boolean;
260
+ zIndex?: number;
261
+ isPending?: boolean;
262
+ action?: (data?: any) => Promise<void>;
263
+ styleIconLeft?: Record<string, any>;
264
+ styleButton?: Record<string, any>;
265
+ buttonCustom?: IColorButton;
266
+ }
267
+ ```
268
+
269
+ ### IPickerCustomOptions Interface
119
270
 
120
271
  ```typescript
121
272
  export interface IPickerCustomOptions {
122
- slBarSize?: number[];
123
- hueBarSize?: number[];
124
- alphaBarSize?: number[];
273
+ /** Kích thước saturation/lightness bar [width, height] */
274
+ slBarSize?: Array<number>;
275
+
276
+ /** Kích thước hue bar [width, height] */
277
+ hueBarSize?: Array<number>;
278
+
279
+ /** Kích thước alpha bar [width, height] */
280
+ alphaBarSize?: Array<number>;
281
+
282
+ /** Hiển thị HSL input */
125
283
  showHsl?: boolean;
284
+
285
+ /** Hiển thị RGB input */
126
286
  showRgb?: boolean;
287
+
288
+ /** Hiển thị HEX input */
127
289
  showHex?: boolean;
290
+
291
+ /** Hiển thị Alpha slider */
128
292
  showAlpha?: boolean;
129
- color?: string | number[];
293
+
294
+ /** Màu khởi tạo (HEX string hoặc RGB array) */
295
+ color?: string | Array<number>;
296
+
297
+ /** Format output mặc định */
130
298
  format?: 'rgb' | 'rgba' | 'hsl' | 'hsla' | 'hex' | 'color';
131
299
  }
132
300
  ```
133
301
 
134
- tả: Tùy chọn cấu hình cho Color Picker.
135
-
136
- #### IOutputColorChangeMultipleType
302
+ ### IOutputColorChangeMultipleType Interface
137
303
 
138
304
  ```typescript
139
305
  export interface IOutputColorChangeMultipleType {
306
+ /** Màu dạng RGBA string: "rgba(255, 0, 0, 1)" */
140
307
  rgba: string;
308
+
309
+ /** Màu dạng RGB string: "rgb(255, 0, 0)" */
141
310
  rgb: string;
311
+
312
+ /** Màu dạng HEX string: "#ff0000" */
142
313
  hex: string;
314
+
315
+ /** Màu dạng HSL string: "hsl(0, 100%, 50%)" */
143
316
  hsl: string;
317
+
318
+ /** Màu dạng HSLA string: "hsla(0, 100%, 50%, 1)" */
144
319
  hsla: string;
320
+
321
+ /** Giá trị alpha (0-1) */
322
+ alpha: number;
145
323
  }
146
324
  ```
147
325
 
148
- tả: Đối tượng chứa nhiều định dạng giá trị màu khi chọn.
326
+ ### TYPE_POPOVER_DIRECTION
327
+
328
+ ```typescript
329
+ export type TYPE_POPOVER_DIRECTION = 'top' | 'bottom' | 'left' | 'right';
330
+ ```
331
+
332
+ ## Behavior
333
+
334
+ ### Apply Now Mode (applyNow = true)
335
+
336
+ - Khi chọn màu, component tự động emit `outColorChange` và `outColorChangeMultipleType`
337
+ - Không hiển thị Cancel/Apply buttons
338
+ - Popover vẫn mở sau khi chọn màu (user có thể tiếp tục điều chỉnh)
339
+
340
+ ### Apply Later Mode (applyNow = false)
341
+
342
+ - Khi chọn màu, component lưu tạm thời màu đã chọn
343
+ - Hiển thị Cancel và Apply buttons
344
+ - Click Cancel: đóng popover, không emit event
345
+ - Click Apply: emit `outColorChange` và `outColorChangeMultipleType`, sau đó đóng popover
346
+
347
+ ### Popover Management
348
+
349
+ - Component tự động cleanup popover khi destroy (ngOnDestroy)
350
+ - Popover có thể được đóng bằng cách click outside (click-toggle mode)
351
+ - Z-index có thể được điều chỉnh để tránh conflicts
352
+
353
+ ## Công nghệ
354
+
355
+ | Technology | Version | Purpose |
356
+ | --------------- | ------- | ---------------- |
357
+ | Angular | 18+ | Framework |
358
+ | Angular Signals | - | State management |
359
+ | TailwindCSS | 3.x | Styling |
360
+ | OnPush | - | Change Detection |
361
+
362
+ ## Demo
363
+
364
+ ```bash
365
+ npx nx serve core-ui
366
+ ```
367
+
368
+ Truy cập: `http://localhost:4500/buttons/select-color`
369
+
370
+ ## Unit Tests
371
+
372
+ ```bash
373
+ # Chạy tests
374
+ npx nx test buttons-select-color
375
+
376
+ # Coverage
377
+ npx nx test buttons-select-color --coverage
378
+
379
+ # Watch mode
380
+ npx nx test buttons-select-color --watch
381
+ ```
382
+
383
+ ## Dependencies
384
+
385
+ - `@angular/core`: >=18.0.0
386
+ - `@libs-ui/components-buttons-button`: 0.2.355-14
387
+ - `@libs-ui/components-color-picker`: 0.2.355-14
388
+ - `@libs-ui/components-popover`: 0.2.355-14
389
+ - `@ngx-translate/core`: ^15.0.0
390
+
391
+ ## Important Notes
392
+
393
+ ### ⚠️ External Content Selector
394
+
395
+ Khi sử dụng `[externalContent]="true"`, content projection PHẢI có class `libs-ui-buttons-select-color`:
396
+
397
+ ```html
398
+ <libs_ui-components-buttons-select_color [externalContent]="true">
399
+ <div class="libs-ui-buttons-select-color">
400
+ <!-- Your custom trigger here -->
401
+ </div>
402
+ </libs_ui-components-buttons-select_color>
403
+ ```
404
+
405
+ ### ⚠️ Color Format
406
+
407
+ - `outColorChange` emit màu theo format được chỉ định trong `customOptions.format`
408
+ - Nếu không chỉ định format, mặc định là format của màu input
409
+ - `outColorChangeMultipleType` luôn emit tất cả các formats
410
+
411
+ ### ⚠️ Z-Index Management
412
+
413
+ - Default z-index là 1200
414
+ - Nếu có conflicts với modals/dialogs khác, tăng z-index
415
+ - Z-index hỗ trợ two-way binding: `[(zIndex)]="myZIndex"`
416
+
417
+ ### ⚠️ Memory Management
418
+
419
+ Component tự động cleanup popover trong `ngOnDestroy`. Không cần manual cleanup.
420
+
421
+ ## Best Practices
422
+
423
+ 1. **Sử dụng applyNow cho simple use cases**: Nếu không cần preview, dùng `applyNow="true"` để UX tốt hơn
424
+ 2. **Handle multiple formats**: Sử dụng `outColorChangeMultipleType` khi cần lưu nhiều formats
425
+ 3. **Custom trigger cho special cases**: Dùng `externalContent` khi cần custom UI (color swatch, preview box...)
426
+ 4. **Set initial color**: Luôn set `customOptions.color` để có màu khởi tạo
427
+ 5. **Responsive z-index**: Điều chỉnh z-index phù hợp với layout hierarchy
428
+
429
+ ## Troubleshooting
430
+
431
+ ### Color picker không hiển thị
432
+
433
+ - Kiểm tra z-index có bị overlap bởi elements khác không
434
+ - Verify `@libs-ui/components-color-picker` đã được install
435
+ - Check console errors
436
+
437
+ ### External content không hoạt động
438
+
439
+ - Đảm bảo có class `libs-ui-buttons-select-color` trên wrapper div
440
+ - Verify `[externalContent]="true"` được set
441
+ - Check content projection syntax
442
+
443
+ ### Màu không đúng format
444
+
445
+ - Kiểm tra `customOptions.format` setting
446
+ - Verify input color format hợp lệ
447
+ - Use `outColorChangeMultipleType` để có tất cả formats
448
+
449
+ ### Popover không đóng
450
+
451
+ - Component tự động cleanup trong ngOnDestroy
452
+ - Nếu cần đóng manual, có thể trigger click outside
453
+ - Check không có errors trong console
454
+
455
+ ## License
456
+
457
+ MIT
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@libs-ui/components-buttons-select-color",
3
- "version": "0.2.355-9",
3
+ "version": "0.2.356-1",
4
4
  "peerDependencies": {
5
5
  "@angular/core": ">=18.0.0",
6
- "@libs-ui/components-buttons-button": "0.2.355-9",
7
- "@libs-ui/components-color-picker": "0.2.355-9",
8
- "@libs-ui/components-popover": "0.2.355-9",
6
+ "@libs-ui/components-buttons-button": "0.2.356-1",
7
+ "@libs-ui/components-color-picker": "0.2.356-1",
8
+ "@libs-ui/components-popover": "0.2.356-1",
9
9
  "@ngx-translate/core": "^15.0.0"
10
10
  },
11
11
  "sideEffects": false,