@libs-ui/components-buttons-dropdown 0.2.355-9 → 0.2.356-0

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 +267 -99
  2. package/package.json +5 -5
package/README.md CHANGED
@@ -1,146 +1,252 @@
1
- # Button Dropdown
1
+ # @libs-ui/components-buttons-dropdown
2
+
3
+ > Component Dropdown Button với menu tùy chọn, hỗ trợ chế độ apply ngay hoặc apply sau.
2
4
 
3
5
  ## Giới thiệu
4
6
 
5
- `@libs-ui/components-buttons-dropdown` là một component Dropdown Button dùng cho Angular, cho phép hiển thị danh sách các tùy chọn khi nhấn vào button, hỗ trợ custom templates, binding lựa chọn nhiều tùy chỉnh linh hoạt.
7
+ `LibsUiComponentsButtonsDropdownComponent` là một standalone Angular component được thiết kế để hiển thị button với dropdown menu. Component hỗ trợ 2 chế độ: apply ngay (applyNow) khi chọn item hoặc chọn trước rồi bấm nút Apply.
8
+
9
+ ### Tính năng
10
+
11
+ - ✅ 2 chế độ: Apply ngay hoặc Apply sau
12
+ - ✅ Tùy chỉnh field hiển thị và key field
13
+ - ✅ Two-way binding cho item được chọn
14
+ - ✅ Tích hợp popover với nhiều tùy chọn vị trí
15
+ - ✅ Hỗ trợ icon cho từng item
16
+ - ✅ Hỗ trợ custom template cho item
17
+ - ✅ Disable state cho button và từng item
18
+ - ✅ Angular Signals cho tính phản hồi cao
19
+ - ✅ OnPush Change Detection tối ưu hiệu năng
6
20
 
7
- ## Tính năng
21
+ ## Khi nào sử dụng
8
22
 
9
- - Hiển thị danh sách items dưới dạng popover khi click (hoặc hover)
10
- - Hỗ trợ custom label key cho items
11
- - Two-way binding giá trị chọn (`keySelected`)
12
- - Tuỳ chọn auto apply (`applyNow`) hoặc yêu cầu click nút Áp dụng
13
- - Hỗ trợ vô hiệu hóa và tuỳ chỉnh kích thước, kiểu button
14
- - Cấu hình popover (kích thước, vị trí, z-index, direction)
15
- - Hỗ trợ custom CSS classes cho container và items
23
+ - Khi cần hiển thị danh sách tùy chọn trong dropdown menu
24
+ - Khi cần cho phép user chọn một item từ danh sách
25
+ - Khi cần chế độ preview trước khi apply (applyNow = false)
26
+ - Phù hợp cho filter buttons, action menus, selection dropdowns
16
27
 
17
28
  ## Cài đặt
18
29
 
19
30
  ```bash
31
+ # npm
20
32
  npm install @libs-ui/components-buttons-dropdown
21
- ```
22
-
23
- hoặc
24
33
 
25
- ```bash
34
+ # yarn
26
35
  yarn add @libs-ui/components-buttons-dropdown
27
36
  ```
28
37
 
29
- ## Sử dụng
30
-
31
- ### Inline Template
38
+ ## Import
32
39
 
33
40
  ```typescript
34
- import { Component } from '@angular/core';
35
- import { LibsUiComponentsButtonsDropdownComponent } from '@libs-ui/components-buttons-dropdown';
41
+ import { LibsUiComponentsButtonsDropdownComponent, IButtonDropdown, IPopupConfigButtonDropdown } from '@libs-ui/components-buttons-dropdown';
36
42
 
37
43
  @Component({
38
- selector: 'app-example',
39
44
  standalone: true,
40
45
  imports: [LibsUiComponentsButtonsDropdownComponent],
41
- template: `
42
- <libs_ui-components-buttons-dropdown
43
- [label]="'Chọn mục'"
44
- [items]="items"
45
- [(keySelected)]="selectedKey"
46
- (outSelectItem)="onSelect($event)"></libs_ui-components-buttons-dropdown>
47
- `,
46
+ // ...
48
47
  })
49
- export class ExampleComponent {
50
- items = [
51
- { id: '1', label: 'Option 1' },
52
- { id: '2', label: 'Option 2' },
53
- { id: '3', label: 'Option 3' },
54
- ];
55
- selectedKey = '1';
56
- onSelect(item: any) {
57
- console.log('Selected:', item);
58
- }
59
- }
48
+ export class YourComponent {}
60
49
  ```
61
50
 
62
- ### File HTML riêng
51
+ ## dụ
52
+
53
+ ### Basic - Apply Ngay
54
+
55
+ ```html
56
+ <libs_ui-components-buttons-dropdown
57
+ label="Select Option"
58
+ [items]="options"
59
+ [applyNow]="true"
60
+ (outSelectItem)="handleSelect($event)" />
61
+ ```
63
62
 
64
63
  ```typescript
65
- import { Component } from '@angular/core';
66
- import { LibsUiComponentsButtonsDropdownComponent } from '@libs-ui/components-buttons-dropdown';
64
+ options = [
65
+ { key: '1', label: 'Option 1' },
66
+ { key: '2', label: 'Option 2' },
67
+ { key: '3', label: 'Option 3' }
68
+ ];
67
69
 
68
- @Component({
69
- selector: 'app-example',
70
- standalone: true,
71
- imports: [LibsUiComponentsButtonsDropdownComponent],
72
- templateUrl: './example.component.html',
73
- })
74
- export class ExampleComponent {
75
- items = [
76
- /* ... */
77
- ];
78
- selectedKey = '';
79
- onSelect(item: any) {}
70
+ handleSelect(item: any) {
71
+ console.log('Selected:', item);
80
72
  }
81
73
  ```
82
74
 
75
+ ### With Apply Button
76
+
83
77
  ```html
84
78
  <libs_ui-components-buttons-dropdown
85
- [label]="'Chọn mục'"
86
- [items]="items"
79
+ label="Select Option"
80
+ [items]="options"
81
+ [applyNow]="false"
87
82
  [(keySelected)]="selectedKey"
88
- (outSelectItem)="onSelect($event)"></libs_ui-components-buttons-dropdown>
89
- ```
90
-
91
- ## API Reference
92
-
93
- ### Inputs
94
-
95
- | Tên | Kiểu | Mặc định | Mô tả |
96
- | ---------------------------------------- | ---------------------------- | ---------------------------------------- | ---------------------------------------------------------------- |
97
- | label | `string` | `''` | Text hiển thị trên nút (ví dụ: "Chọn mục"). |
98
- | items | `Array<any>` | required | Danh sách các mục sẽ hiển thị trong menu. |
99
- | fieldDisplay | `string` | `label` | Trường của mục để hiển thị nội dung. |
100
- | keyField | `string` | `id` | Trường của mục dùng làm giá trị key. |
101
- | keySelected | `string` | undefined | Giá trị key đang được chọn (hỗ trợ two-way binding). |
102
- | applyNow | `boolean` | `false` | Nếu true: chọn xong tự emit sự kiện; false: cần bấm nút Áp dụng. |
103
- | showBorderBottom | `boolean` | `false` | Hiện đường kẻ dưới menu khi mở. |
104
- | disable | `boolean` | `false` | Khóa dropdown, không cho chọn mục. |
105
- | sizeButton | `TYPE_SIZE_BUTTON` | `medium` | Kích thước nút (.small/.medium/.large). |
106
- | typeButton | `TYPE_BUTTON` | `button-primary` | Kiểu style của nút (primary, secondary,...). |
107
- | classLabel | `string` | `''` | Class CSS thêm cho nhãn (text). |
108
- | classInclude | `string` | `''` | Class CSS thêm cho phần container chính. |
109
- | classIncludeContainer | `string` | undefined | Class CSS thêm cho phần container nội dung. |
110
- | fieldClass | `string` | `class` | Trường trong mục chứa class CSS khi cần. |
111
- | classIconLeft | `string` | `''` | Class CSS thêm cho icon bên trái. |
112
- | classIconRight | `string` | `libs-ui-icon-move-right rotate-[90deg]` | Class CSS thêm cho icon bên phải. |
113
- | iconOnlyType | `boolean` | `false` | Chỉ hiện icon, không hiển thị nhãn. |
114
- | popupConfig | `IPopupConfigButtonDropdown` | default cấu hình popover | Cấu hình chi tiết cho popover (vị trí, kích thước). |
115
- | ignoreHiddenPopoverContentWhenMouseLeave | `boolean` | `true` | Giữ popover mở khi chuột rời khỏi nội dung. |
116
- | modePopover | `TYPE_POPOVER_MODE` | `click-toggle` | Cách hiển thị popover (click, hover,...). |
117
-
118
- ### Outputs
119
-
120
- | Tên | Kiểu | Mô tả |
121
- | ------------------- | ------------------------------------------------- | --------------------------------------------------------- |
122
- | outSelectItem | `(item: any) => void` | Trả về mục (item) bạn vừa chọn. |
123
- | outHover | `(isHover: boolean) => void` | Phát ra khi rê chuột lên/xuống trên một mục. |
124
- | outApply | `(item: any) => void` | Phát ra khi bạn bấm nút Áp dụng (với applyNow=false). |
125
- | outPopoverEvent | `(event: TYPE_POPOVER_EVENT) => void` | Phát ra các sự kiện của popover (show, hide, click, ...). |
126
- | outFunctionsControl | `(control: IPopoverFunctionControlEvent) => void` | Cung cấp control API để điều khiển popover. |
127
- | outIconEvent | `(event: MouseEvent) => void` | Phát ra khi bạn nhấn vào icon. |
128
-
129
- ### Interfaces
83
+ (outApply)="handleApply($event)" />
84
+ ```
130
85
 
131
86
  ```typescript
87
+ selectedKey = '1';
88
+
89
+ handleApply(item: any) {
90
+ console.log('Applied:', item);
91
+ }
92
+ ```
93
+
94
+ ### Custom Field Names
95
+
96
+ ```html
97
+ <libs_ui-components-buttons-dropdown
98
+ label="Select User"
99
+ [items]="users"
100
+ fieldDisplay="name"
101
+ keyField="id"
102
+ [applyNow]="true"
103
+ (outSelectItem)="handleSelect($event)" />
104
+ ```
105
+
106
+ ```typescript
107
+ users = [
108
+ { id: 'u1', name: 'John Doe' },
109
+ { id: 'u2', name: 'Jane Smith' },
110
+ { id: 'u3', name: 'Bob Johnson' },
111
+ ];
112
+ ```
113
+
114
+ ### With Icons
115
+
116
+ ```html
117
+ <libs_ui-components-buttons-dropdown
118
+ label="Actions"
119
+ [items]="actions"
120
+ fieldClassIconLeft="iconClass"
121
+ [applyNow]="true"
122
+ (outSelectItem)="handleAction($event)" />
123
+ ```
124
+
125
+ ```typescript
126
+ actions = [
127
+ { key: 'edit', label: 'Edit', iconClass: 'libs-ui-icon-edit' },
128
+ { key: 'delete', label: 'Delete', iconClass: 'libs-ui-icon-delete' },
129
+ { key: 'share', label: 'Share', iconClass: 'libs-ui-icon-share' },
130
+ ];
131
+ ```
132
+
133
+ ### Custom Popup Config
134
+
135
+ ```html
136
+ <libs_ui-components-buttons-dropdown
137
+ label="Options"
138
+ [items]="options"
139
+ [popupConfig]="{
140
+ width: 300,
141
+ maxHeight: 200,
142
+ direction: 'bottom',
143
+ zIndex: 1500
144
+ }"
145
+ [applyNow]="true" />
146
+ ```
147
+
148
+ ### Different Button Types
149
+
150
+ ```html
151
+ <!-- Primary -->
152
+ <libs_ui-components-buttons-dropdown
153
+ label="Primary"
154
+ [items]="options"
155
+ typeButton="button-primary"
156
+ [applyNow]="true" />
157
+
158
+ <!-- Secondary -->
159
+ <libs_ui-components-buttons-dropdown
160
+ label="Secondary"
161
+ [items]="options"
162
+ typeButton="button-secondary"
163
+ [applyNow]="true" />
164
+
165
+ <!-- Outline -->
166
+ <libs_ui-components-buttons-dropdown
167
+ label="Outline"
168
+ [items]="options"
169
+ typeButton="button-outline"
170
+ [applyNow]="true" />
171
+ ```
172
+
173
+ ## API
174
+
175
+ ### libs_ui-components-buttons-dropdown
176
+
177
+ #### Inputs
178
+
179
+ | Property | Type | Default | Description |
180
+ | -------------------------------------------- | ---------------------------- | ------------------------------------------ | ------------------------------------------------- |
181
+ | `[applyNow]` | `boolean` | `false` | Nếu true: chọn xong tự emit; false: cần bấm Apply |
182
+ | `[classIconLeft]` | `string` | `''` | Class icon bên trái button |
183
+ | `[classIconRight]` | `string` | `'libs-ui-icon-move-right rotate-[90deg]'` | Class icon bên phải button |
184
+ | `[classInclude]` | `string` | `''` | Class CSS bổ sung cho button |
185
+ | `[classIncludeContainer]` | `string` | `undefined` | Class CSS cho container |
186
+ | `[classLabel]` | `string` | `''` | Class CSS cho label |
187
+ | `[disable]` | `boolean` | `false` | Disable button |
188
+ | `[fieldClass]` | `string` | `'class'` | Tên field chứa class của item |
189
+ | `[fieldClassIconLeft]` | `string` | `'classIconLeft'` | Tên field chứa icon class của item |
190
+ | `[fieldDisplay]` | `string` | `'label'` | Tên field hiển thị của item |
191
+ | `[iconOnlyType]` | `boolean` | `false` | Chỉ hiển thị icon, ẩn label |
192
+ | `[ignoreHiddenPopoverContentWhenMouseLeave]` | `boolean` | `true` | Giữ popover mở khi chuột rời |
193
+ | `[items]` | `Array<any>` | required | Danh sách items hiển thị |
194
+ | `[keyField]` | `string` | `'key'` | Tên field làm key của item |
195
+ | `[(keySelected)]` | `string` | `undefined` | Key của item được chọn (two-way binding) |
196
+ | `[label]` | `string` | `undefined` | Label của button |
197
+ | `[modePopover]` | `TYPE_POPOVER_MODE` | `'click-toggle'` | Chế độ hiển thị popover |
198
+ | `[popupConfig]` | `IPopupConfigButtonDropdown` | `{...}` | Cấu hình popup (width, height, direction...) |
199
+ | `[showBorderBottom]` | `boolean` | `false` | Hiển thị border dưới items |
200
+ | `[sizeButton]` | `TYPE_SIZE_BUTTON` | `'medium'` | Kích thước button |
201
+ | `[typeButton]` | `TYPE_BUTTON` | `'button-primary'` | Kiểu button |
202
+
203
+ #### Outputs
204
+
205
+ | Property | Type | Description |
206
+ | ----------------------- | ------------------------------ | ------------------------------------------ |
207
+ | `(outApply)` | `any` | Emit khi bấm Apply (chế độ applyNow=false) |
208
+ | `(outFunctionsControl)` | `IPopoverFunctionControlEvent` | Emit functions điều khiển popover |
209
+ | `(outHover)` | `boolean` | Emit khi hover state thay đổi |
210
+ | `(outIconEvent)` | `MouseEvent` | Emit khi click icon |
211
+ | `(outPopoverEvent)` | `TYPE_POPOVER_EVENT` | Emit events từ popover |
212
+ | `(outSelectItem)` | `any` | Emit khi chọn item |
213
+
214
+ #### Public Methods
215
+
216
+ | Method | Description |
217
+ | ------------------ | --------------------------------------- |
218
+ | `FunctionsControl` | Getter để lấy popover control functions |
219
+
220
+ ## Types & Interfaces
221
+
222
+ ```typescript
223
+ /**
224
+ * Interface cho Dropdown Button component
225
+ */
132
226
  export interface IButtonDropdown extends IButton {
227
+ /** Danh sách các mục sẽ hiển thị trong menu */
133
228
  items: any[];
229
+ /** Tên trường dùng để hiển thị nội dung của mỗi mục */
134
230
  fieldDisplay?: string;
231
+ /** Tên trường dùng làm giá trị key của mỗi mục */
135
232
  keyField?: string;
233
+ /** Giá trị key đang được chọn (hỗ trợ two-way binding) */
136
234
  keySelected?: string;
235
+ /** Nếu true: chọn xong tự emit sự kiện; false: cần bấm nút Áp dụng */
137
236
  applyNow?: boolean;
237
+ /** Hiển thị đường kẻ dưới menu khi mở */
138
238
  showBorderBottom?: boolean;
239
+ /** Cấu hình chi tiết cho popover (vị trí, kích thước) */
139
240
  popupConfig?: IPopupConfigButtonDropdown;
241
+ /** Giữ popover mở khi chuột rời khỏi nội dung */
140
242
  ignoreHiddenPopoverContentWhenMouseLeave?: boolean;
243
+ /** Cách hiển thị popover (click, hover,...) */
141
244
  modePopover?: TYPE_POPOVER_MODE;
142
245
  }
143
246
 
247
+ /**
248
+ * Cấu hình cho Dropdown popover
249
+ */
144
250
  export interface IPopupConfigButtonDropdown {
145
251
  width?: number;
146
252
  maxWidth?: number;
@@ -155,7 +261,69 @@ export interface IPopupConfigButtonDropdown {
155
261
  };
156
262
  classInclude?: string;
157
263
  }
264
+ ```
265
+
266
+ ## Item Structure
267
+
268
+ Mỗi item trong array `items` có thể có các thuộc tính:
269
+
270
+ ```typescript
271
+ interface DropdownItem {
272
+ // Required fields (tùy theo fieldDisplay và keyField)
273
+ [fieldDisplay]: string; // Mặc định: 'label'
274
+ [keyField]: string; // Mặc định: 'key'
275
+
276
+ // Optional fields
277
+ class?: string; // Class cho item
278
+ classIconLeft?: string; // Icon class
279
+ classInclude?: string; // Class bổ sung
280
+ classRow?: string; // Class cho row
281
+ disable?: boolean; // Disable item
282
+ ignoreFlex?: boolean; // Không dùng flex layout
283
+ showPopover?: boolean; // Hiển thị popover cho item
284
+ popoverContent?: string; // Nội dung popover
285
+ subTemplate?: TemplateRef; // Custom template
286
+ buttonTemplateConfig?: {
287
+ // Config cho button trong item
288
+ icon?: string;
289
+ iconLeft?: string;
290
+ label?: string;
291
+ type?: TYPE_BUTTON;
292
+ action: (item: any, items: any[]) => void;
293
+ };
294
+ }
295
+ ```
296
+
297
+ ## Công nghệ
298
+
299
+ | Technology | Version | Purpose |
300
+ | --------------- | ------- | ---------------- |
301
+ | Angular | 18+ | Framework |
302
+ | Angular Signals | - | State management |
303
+ | TailwindCSS | 3.x | Styling |
304
+ | OnPush | - | Change Detection |
305
+
306
+ ## Demo
158
307
 
159
- export type TYPE_POPOVER_DIRECTION = 'top' | 'right' | 'bottom' | 'left';
160
- export type TYPE_POPOVER_MODE = 'hover' | 'click' | 'click-toggle' | 'click_open_and_click_panel_content_hidden';
308
+ ```bash
309
+ npx nx serve core-ui
310
+ ```
311
+
312
+ Truy cập: `http://localhost:4500/buttons/dropdown`
313
+
314
+ ## Unit Tests
315
+
316
+ ```bash
317
+ # Chạy tests
318
+ npx nx test components-buttons-dropdown
319
+
320
+ # Coverage
321
+ npx nx test components-buttons-dropdown --coverage
322
+
323
+ # Watch mode
324
+ npx nx test components-buttons-dropdown --watch
161
325
  ```
326
+
327
+ ## License
328
+
329
+ MIT
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@libs-ui/components-buttons-dropdown",
3
- "version": "0.2.355-9",
3
+ "version": "0.2.356-0",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=18.0.0",
6
6
  "@angular/core": ">=18.0.0",
7
- "@libs-ui/components-buttons-button": "0.2.355-9",
8
- "@libs-ui/components-popover": "0.2.355-9",
9
- "@libs-ui/utils": "0.2.355-9",
7
+ "@libs-ui/components-buttons-button": "0.2.356-0",
8
+ "@libs-ui/components-popover": "0.2.356-0",
9
+ "@libs-ui/utils": "0.2.356-0",
10
10
  "@ngx-translate/core": "^15.0.0",
11
- "@libs-ui/interfaces-types": "0.2.355-9"
11
+ "@libs-ui/interfaces-types": "0.2.356-0"
12
12
  },
13
13
  "sideEffects": false,
14
14
  "module": "fesm2022/libs-ui-components-buttons-dropdown.mjs",