@libs-ui/components-buttons-dropdown 0.2.356-42 → 0.2.356-43
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.
package/README.md
CHANGED
|
@@ -1,44 +1,45 @@
|
|
|
1
1
|
# @libs-ui/components-buttons-dropdown
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Dropdown button với menu tùy chọn dạng popover, hỗ trợ hai chế độ: apply ngay khi chọn hoặc chọn trước rồi xác nhận sau.
|
|
4
4
|
|
|
5
5
|
## Giới thiệu
|
|
6
6
|
|
|
7
|
-
`LibsUiComponentsButtonsDropdownComponent` là một standalone Angular component
|
|
7
|
+
`LibsUiComponentsButtonsDropdownComponent` là một standalone Angular component kết hợp button và popover menu thành một khối tương tác hoàn chỉnh. Component cung cấp hai chế độ hoạt động: `applyNow = true` để emit ngay khi user chọn item, hoặc `applyNow = false` để tách biệt nút mở menu và nút xác nhận (Apply). Nội dung item được sanitize tự động qua `escapeHtml` để ngăn XSS.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Tính năng
|
|
10
10
|
|
|
11
|
-
- ✅
|
|
12
|
-
- ✅
|
|
13
|
-
- ✅
|
|
14
|
-
- ✅
|
|
15
|
-
- ✅
|
|
16
|
-
- ✅
|
|
17
|
-
- ✅
|
|
18
|
-
- ✅
|
|
19
|
-
- ✅
|
|
11
|
+
- ✅ Hai chế độ hoạt động: apply ngay (`applyNow = true`) hoặc chọn rồi xác nhận (`applyNow = false`)
|
|
12
|
+
- ✅ Two-way binding cho item đang được chọn qua `[(keySelected)]`
|
|
13
|
+
- ✅ Tùy chỉnh tên field hiển thị (`fieldDisplay`) và field key (`keyField`) — không cần format lại data
|
|
14
|
+
- ✅ Hỗ trợ icon bên trái cho từng item qua `fieldClassIconLeft`
|
|
15
|
+
- ✅ Custom sub-template cho item (`subTemplate`) và button lồng trong item (`buttonTemplateConfig`)
|
|
16
|
+
- ✅ Popover cấu hình linh hoạt: hướng mở, kích thước, z-index, animation
|
|
17
|
+
- ✅ Truy cập programmatic qua getter `FunctionsControl` để mở/đóng popup từ bên ngoài
|
|
18
|
+
- ✅ XSS-safe: giá trị `fieldDisplay` của mọi item tự động qua `escapeHtml`
|
|
19
|
+
- ✅ Hỗ trợ disable toàn bộ button hoặc từng item riêng lẻ
|
|
20
|
+
- ✅ Angular Signals + `ChangeDetectionStrategy.OnPush` — hiệu năng tối ưu
|
|
20
21
|
|
|
21
22
|
## Khi nào sử dụng
|
|
22
23
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
24
|
+
- Cần button gọi menu dropdown chọn một giá trị (filter, sort, action)
|
|
25
|
+
- Cần tách luồng "chọn trước — xác nhận sau" (ví dụ: chọn kỳ báo cáo rồi bấm Apply)
|
|
26
|
+
- Cần action menu với icon và label cho từng mục
|
|
27
|
+
- Cần dropdown lồng popover với vị trí và kích thước tùy chỉnh theo context giao diện
|
|
27
28
|
|
|
28
29
|
## Cài đặt
|
|
29
30
|
|
|
30
31
|
```bash
|
|
31
|
-
# npm
|
|
32
32
|
npm install @libs-ui/components-buttons-dropdown
|
|
33
|
-
|
|
34
|
-
# yarn
|
|
35
|
-
yarn add @libs-ui/components-buttons-dropdown
|
|
36
33
|
```
|
|
37
34
|
|
|
38
35
|
## Import
|
|
39
36
|
|
|
40
37
|
```typescript
|
|
41
|
-
import {
|
|
38
|
+
import {
|
|
39
|
+
LibsUiComponentsButtonsDropdownComponent,
|
|
40
|
+
IButtonDropdown,
|
|
41
|
+
IPopupConfigButtonDropdown,
|
|
42
|
+
} from '@libs-ui/components-buttons-dropdown';
|
|
42
43
|
|
|
43
44
|
@Component({
|
|
44
45
|
standalone: true,
|
|
@@ -48,260 +49,444 @@ import { LibsUiComponentsButtonsDropdownComponent, IButtonDropdown, IPopupConfig
|
|
|
48
49
|
export class YourComponent {}
|
|
49
50
|
```
|
|
50
51
|
|
|
51
|
-
## Ví dụ
|
|
52
|
+
## Ví dụ sử dụng
|
|
53
|
+
|
|
54
|
+
### 1. Apply ngay — chọn là emit
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// component.ts
|
|
58
|
+
import { Component } from '@angular/core';
|
|
59
|
+
import { LibsUiComponentsButtonsDropdownComponent } from '@libs-ui/components-buttons-dropdown';
|
|
52
60
|
|
|
53
|
-
|
|
61
|
+
@Component({
|
|
62
|
+
selector: 'app-example',
|
|
63
|
+
standalone: true,
|
|
64
|
+
imports: [LibsUiComponentsButtonsDropdownComponent],
|
|
65
|
+
templateUrl: './example.component.html',
|
|
66
|
+
})
|
|
67
|
+
export class ExampleComponent {
|
|
68
|
+
readonly statusOptions = [
|
|
69
|
+
{ key: 'active', label: 'Đang hoạt động' },
|
|
70
|
+
{ key: 'inactive', label: 'Ngừng hoạt động' },
|
|
71
|
+
{ key: 'pending', label: 'Chờ duyệt' },
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
handlerSelectStatus(event: Event, item: { key: string; label: string }): void {
|
|
75
|
+
event.stopPropagation();
|
|
76
|
+
console.log('Đã chọn:', item);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
54
80
|
|
|
55
81
|
```html
|
|
82
|
+
<!-- example.component.html -->
|
|
56
83
|
<libs_ui-components-buttons-dropdown
|
|
57
|
-
label="
|
|
58
|
-
[items]="
|
|
84
|
+
label="Trạng thái"
|
|
85
|
+
[items]="statusOptions"
|
|
59
86
|
[applyNow]="true"
|
|
60
|
-
(outSelectItem)="
|
|
87
|
+
(outSelectItem)="handlerSelectStatus($event, $event)" />
|
|
61
88
|
```
|
|
62
89
|
|
|
90
|
+
### 2. Chọn trước — xác nhận sau (applyNow = false)
|
|
91
|
+
|
|
63
92
|
```typescript
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
93
|
+
// component.ts
|
|
94
|
+
import { Component, signal } from '@angular/core';
|
|
95
|
+
import { LibsUiComponentsButtonsDropdownComponent } from '@libs-ui/components-buttons-dropdown';
|
|
96
|
+
|
|
97
|
+
@Component({
|
|
98
|
+
selector: 'app-filter',
|
|
99
|
+
standalone: true,
|
|
100
|
+
imports: [LibsUiComponentsButtonsDropdownComponent],
|
|
101
|
+
templateUrl: './filter.component.html',
|
|
102
|
+
})
|
|
103
|
+
export class FilterComponent {
|
|
104
|
+
protected selectedPeriodKey = signal<string>('q1');
|
|
105
|
+
|
|
106
|
+
readonly periodOptions = [
|
|
107
|
+
{ key: 'q1', label: 'Quý 1' },
|
|
108
|
+
{ key: 'q2', label: 'Quý 2' },
|
|
109
|
+
{ key: 'q3', label: 'Quý 3' },
|
|
110
|
+
{ key: 'q4', label: 'Quý 4' },
|
|
111
|
+
];
|
|
112
|
+
|
|
113
|
+
handlerApplyPeriod(event: Event, item: { key: string; label: string }): void {
|
|
114
|
+
event.stopPropagation();
|
|
115
|
+
console.log('Áp dụng kỳ:', item);
|
|
116
|
+
}
|
|
72
117
|
}
|
|
73
118
|
```
|
|
74
119
|
|
|
75
|
-
### With Apply Button
|
|
76
|
-
|
|
77
120
|
```html
|
|
121
|
+
<!-- filter.component.html -->
|
|
78
122
|
<libs_ui-components-buttons-dropdown
|
|
79
|
-
label="
|
|
80
|
-
[items]="
|
|
123
|
+
label="Chọn kỳ"
|
|
124
|
+
[items]="periodOptions"
|
|
81
125
|
[applyNow]="false"
|
|
82
|
-
[(keySelected)]="
|
|
83
|
-
(outApply)="
|
|
126
|
+
[(keySelected)]="selectedPeriodKey"
|
|
127
|
+
(outApply)="handlerApplyPeriod($event, $event)" />
|
|
84
128
|
```
|
|
85
129
|
|
|
130
|
+
### 3. Custom tên field — data không cần format lại
|
|
131
|
+
|
|
86
132
|
```typescript
|
|
87
|
-
|
|
133
|
+
// component.ts
|
|
134
|
+
import { Component } from '@angular/core';
|
|
135
|
+
import { LibsUiComponentsButtonsDropdownComponent } from '@libs-ui/components-buttons-dropdown';
|
|
88
136
|
|
|
89
|
-
|
|
90
|
-
|
|
137
|
+
@Component({
|
|
138
|
+
selector: 'app-user-picker',
|
|
139
|
+
standalone: true,
|
|
140
|
+
imports: [LibsUiComponentsButtonsDropdownComponent],
|
|
141
|
+
templateUrl: './user-picker.component.html',
|
|
142
|
+
})
|
|
143
|
+
export class UserPickerComponent {
|
|
144
|
+
readonly users = [
|
|
145
|
+
{ userId: 'u1', fullName: 'Nguyễn Văn An' },
|
|
146
|
+
{ userId: 'u2', fullName: 'Trần Thị Bình' },
|
|
147
|
+
{ userId: 'u3', fullName: 'Lê Quốc Cường' },
|
|
148
|
+
];
|
|
149
|
+
|
|
150
|
+
handlerSelectUser(event: Event, user: { userId: string; fullName: string }): void {
|
|
151
|
+
event.stopPropagation();
|
|
152
|
+
console.log('Người được chọn:', user.fullName);
|
|
153
|
+
}
|
|
91
154
|
}
|
|
92
155
|
```
|
|
93
156
|
|
|
94
|
-
### Custom Field Names
|
|
95
|
-
|
|
96
157
|
```html
|
|
158
|
+
<!-- user-picker.component.html -->
|
|
97
159
|
<libs_ui-components-buttons-dropdown
|
|
98
|
-
label="
|
|
160
|
+
label="Chọn người dùng"
|
|
99
161
|
[items]="users"
|
|
100
|
-
fieldDisplay="
|
|
101
|
-
keyField="
|
|
162
|
+
fieldDisplay="fullName"
|
|
163
|
+
keyField="userId"
|
|
102
164
|
[applyNow]="true"
|
|
103
|
-
(outSelectItem)="
|
|
165
|
+
(outSelectItem)="handlerSelectUser($event, $event)" />
|
|
104
166
|
```
|
|
105
167
|
|
|
168
|
+
### 4. Items có icon
|
|
169
|
+
|
|
106
170
|
```typescript
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
{ id: 'u3', name: 'Bob Johnson' },
|
|
111
|
-
];
|
|
112
|
-
```
|
|
171
|
+
// component.ts
|
|
172
|
+
import { Component } from '@angular/core';
|
|
173
|
+
import { LibsUiComponentsButtonsDropdownComponent } from '@libs-ui/components-buttons-dropdown';
|
|
113
174
|
|
|
114
|
-
|
|
175
|
+
@Component({
|
|
176
|
+
selector: 'app-action-menu',
|
|
177
|
+
standalone: true,
|
|
178
|
+
imports: [LibsUiComponentsButtonsDropdownComponent],
|
|
179
|
+
templateUrl: './action-menu.component.html',
|
|
180
|
+
})
|
|
181
|
+
export class ActionMenuComponent {
|
|
182
|
+
readonly actionItems = [
|
|
183
|
+
{ key: 'edit', label: 'Chỉnh sửa', classIconLeft: 'libs-ui-icon-edit' },
|
|
184
|
+
{ key: 'duplicate', label: 'Nhân bản', classIconLeft: 'libs-ui-icon-copy' },
|
|
185
|
+
{ key: 'delete', label: 'Xóa', classIconLeft: 'libs-ui-icon-delete' },
|
|
186
|
+
];
|
|
187
|
+
|
|
188
|
+
handlerSelectAction(event: Event, action: { key: string; label: string }): void {
|
|
189
|
+
event.stopPropagation();
|
|
190
|
+
console.log('Hành động:', action.key);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
```
|
|
115
194
|
|
|
116
195
|
```html
|
|
196
|
+
<!-- action-menu.component.html -->
|
|
117
197
|
<libs_ui-components-buttons-dropdown
|
|
118
|
-
label="
|
|
119
|
-
[items]="
|
|
120
|
-
fieldClassIconLeft="
|
|
198
|
+
label="Thao tác"
|
|
199
|
+
[items]="actionItems"
|
|
200
|
+
fieldClassIconLeft="classIconLeft"
|
|
121
201
|
[applyNow]="true"
|
|
122
|
-
(outSelectItem)="
|
|
202
|
+
(outSelectItem)="handlerSelectAction($event, $event)" />
|
|
123
203
|
```
|
|
124
204
|
|
|
205
|
+
### 5. Tùy chỉnh cấu hình popover
|
|
206
|
+
|
|
125
207
|
```typescript
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
208
|
+
// component.ts
|
|
209
|
+
import { Component } from '@angular/core';
|
|
210
|
+
import {
|
|
211
|
+
LibsUiComponentsButtonsDropdownComponent,
|
|
212
|
+
IPopupConfigButtonDropdown,
|
|
213
|
+
} from '@libs-ui/components-buttons-dropdown';
|
|
214
|
+
|
|
215
|
+
@Component({
|
|
216
|
+
selector: 'app-custom-popup',
|
|
217
|
+
standalone: true,
|
|
218
|
+
imports: [LibsUiComponentsButtonsDropdownComponent],
|
|
219
|
+
templateUrl: './custom-popup.component.html',
|
|
220
|
+
})
|
|
221
|
+
export class CustomPopupComponent {
|
|
222
|
+
readonly menuItems = [
|
|
223
|
+
{ key: '1', label: 'Mục 1' },
|
|
224
|
+
{ key: '2', label: 'Mục 2' },
|
|
225
|
+
{ key: '3', label: 'Mục 3' },
|
|
226
|
+
];
|
|
227
|
+
|
|
228
|
+
readonly popupConfig: IPopupConfigButtonDropdown = {
|
|
229
|
+
width: 280,
|
|
230
|
+
maxHeight: 200,
|
|
231
|
+
direction: 'bottom',
|
|
232
|
+
zIndex: 1500,
|
|
233
|
+
position: { mode: 'end', distance: 0 },
|
|
234
|
+
};
|
|
132
235
|
|
|
133
|
-
|
|
236
|
+
handlerSelectMenu(event: Event, item: { key: string }): void {
|
|
237
|
+
event.stopPropagation();
|
|
238
|
+
console.log('Chọn:', item.key);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
```
|
|
134
242
|
|
|
135
243
|
```html
|
|
244
|
+
<!-- custom-popup.component.html -->
|
|
136
245
|
<libs_ui-components-buttons-dropdown
|
|
137
|
-
label="
|
|
138
|
-
[items]="
|
|
139
|
-
[popupConfig]="
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
direction: 'bottom',
|
|
143
|
-
zIndex: 1500
|
|
144
|
-
}"
|
|
145
|
-
[applyNow]="true" />
|
|
246
|
+
label="Tùy chọn"
|
|
247
|
+
[items]="menuItems"
|
|
248
|
+
[popupConfig]="popupConfig"
|
|
249
|
+
[applyNow]="true"
|
|
250
|
+
(outSelectItem)="handlerSelectMenu($event, $event)" />
|
|
146
251
|
```
|
|
147
252
|
|
|
148
|
-
###
|
|
253
|
+
### 6. Các kiểu button (typeButton)
|
|
149
254
|
|
|
150
255
|
```html
|
|
151
|
-
|
|
152
|
-
<libs_ui-components-buttons-dropdown
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
256
|
+
<div class="flex gap-2">
|
|
257
|
+
<libs_ui-components-buttons-dropdown
|
|
258
|
+
label="Primary"
|
|
259
|
+
[items]="menuItems"
|
|
260
|
+
typeButton="button-primary"
|
|
261
|
+
[applyNow]="true" />
|
|
262
|
+
|
|
263
|
+
<libs_ui-components-buttons-dropdown
|
|
264
|
+
label="Secondary"
|
|
265
|
+
[items]="menuItems"
|
|
266
|
+
typeButton="button-secondary"
|
|
267
|
+
[applyNow]="true" />
|
|
268
|
+
|
|
269
|
+
<libs_ui-components-buttons-dropdown
|
|
270
|
+
label="Outline"
|
|
271
|
+
[items]="menuItems"
|
|
272
|
+
typeButton="button-outline"
|
|
273
|
+
[applyNow]="true" />
|
|
274
|
+
</div>
|
|
275
|
+
```
|
|
157
276
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
277
|
+
### 7. Truy cập programmatic qua FunctionsControl (ViewChild)
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
// parent.component.ts
|
|
281
|
+
import { Component, viewChild } from '@angular/core';
|
|
282
|
+
import { LibsUiComponentsButtonsDropdownComponent } from '@libs-ui/components-buttons-dropdown';
|
|
283
|
+
|
|
284
|
+
@Component({
|
|
285
|
+
selector: 'app-parent',
|
|
286
|
+
standalone: true,
|
|
287
|
+
imports: [LibsUiComponentsButtonsDropdownComponent],
|
|
288
|
+
templateUrl: './parent.component.html',
|
|
289
|
+
})
|
|
290
|
+
export class ParentComponent {
|
|
291
|
+
private readonly dropdownRef = viewChild<LibsUiComponentsButtonsDropdownComponent>('dropdownRef');
|
|
292
|
+
|
|
293
|
+
handlerOpenDropdown(event: Event): void {
|
|
294
|
+
event.stopPropagation();
|
|
295
|
+
this.dropdownRef()?.FunctionsControl?.show?.();
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
handlerCloseDropdown(event: Event): void {
|
|
299
|
+
event.stopPropagation();
|
|
300
|
+
this.dropdownRef()?.FunctionsControl?.hide?.();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
```
|
|
164
304
|
|
|
165
|
-
|
|
305
|
+
```html
|
|
306
|
+
<!-- parent.component.html -->
|
|
166
307
|
<libs_ui-components-buttons-dropdown
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
[applyNow]="true"
|
|
308
|
+
#dropdownRef
|
|
309
|
+
label="Menu"
|
|
310
|
+
[items]="menuItems"
|
|
311
|
+
[applyNow]="true"
|
|
312
|
+
(outFunctionsControl)="handlerFunctionsControl($event)" />
|
|
171
313
|
```
|
|
172
314
|
|
|
173
|
-
##
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
|
180
|
-
|
|
|
181
|
-
| `[
|
|
182
|
-
| `[
|
|
183
|
-
| `[
|
|
184
|
-
| `[
|
|
185
|
-
| `[
|
|
186
|
-
| `[
|
|
187
|
-
| `[
|
|
188
|
-
| `[
|
|
189
|
-
| `[
|
|
190
|
-
| `[
|
|
191
|
-
| `[
|
|
192
|
-
| `[
|
|
193
|
-
| `[
|
|
194
|
-
| `[
|
|
195
|
-
| `[
|
|
196
|
-
| `[
|
|
197
|
-
| `[
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
|
206
|
-
|
|
|
207
|
-
| `(
|
|
208
|
-
| `(
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
315
|
+
## @Input()
|
|
316
|
+
|
|
317
|
+
| Input | Type | Default | Mô tả | Ví dụ |
|
|
318
|
+
|---|---|---|---|---|
|
|
319
|
+
| `[applyNow]` | `boolean` | `false` | `true`: emit ngay khi chọn item; `false`: tách nút mở menu và nút Apply | `[applyNow]="true"` |
|
|
320
|
+
| `[classIconLeft]` | `string` | `''` | Class icon hiển thị bên trái label trên button chính | `classIconLeft="libs-ui-icon-filter"` |
|
|
321
|
+
| `[classIconRight]` | `string` | `'libs-ui-icon-move-right rotate-[90deg]'` | Class icon mũi tên bên phải trên nút toggle menu (chế độ `applyNow=false`) | `classIconRight="libs-ui-icon-chevron-down"` |
|
|
322
|
+
| `[classInclude]` | `string` | `''` | Class CSS bổ sung cho button | `classInclude="w-full"` |
|
|
323
|
+
| `[classIncludeContainer]` | `string` | `undefined` | Class CSS bổ sung cho div container bọc ngoài | `classIncludeContainer="flex-1"` |
|
|
324
|
+
| `[classLabel]` | `string` | `''` | Class CSS cho label text trên button | `classLabel="libs-ui-font-h5m"` |
|
|
325
|
+
| `[disable]` | `boolean` | `false` | Disable toàn bộ button | `[disable]="isLoading()"` |
|
|
326
|
+
| `[fieldClass]` | `string` | `'class'` | Tên field trong object item chứa class CSS của item đó | `fieldClass="cssClass"` |
|
|
327
|
+
| `[fieldClassIconLeft]` | `string` | `'classIconLeft'` | Tên field trong object item chứa class icon bên trái | `fieldClassIconLeft="iconClass"` |
|
|
328
|
+
| `[fieldDisplay]` | `string` | `'label'` | Tên field trong object item dùng để hiển thị text | `fieldDisplay="name"` |
|
|
329
|
+
| `[iconOnlyType]` | `boolean` | `false` | Chỉ hiển thị icon, ẩn label trên button | `[iconOnlyType]="true"` |
|
|
330
|
+
| `[ignoreHiddenPopoverContentWhenMouseLeave]` | `boolean` | `true` | Giữ popover mở khi chuột di ra ngoài vùng content | `[ignoreHiddenPopoverContentWhenMouseLeave]="false"` |
|
|
331
|
+
| `[items]` | `Array<any>` | **required** | Danh sách items hiển thị trong menu | `[items]="options"` |
|
|
332
|
+
| `[keyField]` | `string` | `'key'` | Tên field trong object item dùng làm giá trị key định danh | `keyField="id"` |
|
|
333
|
+
| `[(keySelected)]` | `string` | `undefined` | Key của item đang được chọn — hỗ trợ two-way binding | `[(keySelected)]="selectedKey"` |
|
|
334
|
+
| `[label]` | `string` | `undefined` | Label mặc định của button (khi chưa chọn item nào, hoặc ở chế độ `applyNow=true`) | `label="Chọn trạng thái"` |
|
|
335
|
+
| `[modePopover]` | `TYPE_POPOVER_MODE` | `'click-toggle'` | Chế độ kích hoạt popover | `modePopover="click-toggle"` |
|
|
336
|
+
| `[popupConfig]` | `IPopupConfigButtonDropdown` | `{ width: 205, maxWidth: 250, maxHeight: 140, zIndex: 1200, direction: 'top' }` | Cấu hình chi tiết cho popover (kích thước, vị trí, z-index) | `[popupConfig]="myConfig"` |
|
|
337
|
+
| `[showBorderBottom]` | `boolean` | `false` | Hiển thị đường kẻ phân cách dưới mỗi item trong menu | `[showBorderBottom]="true"` |
|
|
338
|
+
| `[sizeButton]` | `TYPE_SIZE_BUTTON` | `'medium'` | Kích thước button | `sizeButton="small"` |
|
|
339
|
+
| `[typeButton]` | `TYPE_BUTTON` | `'button-primary'` | Kiểu button (màu sắc, style) | `typeButton="button-secondary"` |
|
|
340
|
+
|
|
341
|
+
## @Output()
|
|
342
|
+
|
|
343
|
+
| Output | Type | Mô tả | Handler TS | Binding HTML |
|
|
344
|
+
|---|---|---|---|---|
|
|
345
|
+
| `(outApply)` | `any` | Emit item được chọn khi bấm nút Apply (chỉ ở chế độ `applyNow = false`) | `handlerApply(event: Event, item: any): void { event.stopPropagation(); console.log(item); }` | `(outApply)="handlerApply($event, $event)"` |
|
|
346
|
+
| `(outFunctionsControl)` | `IPopoverFunctionControlEvent` | Emit object chứa các hàm điều khiển popover (show, hide) ngay sau khi popover khởi tạo | `handlerFunctionsControl(event: Event, ctrl: IPopoverFunctionControlEvent): void { event.stopPropagation(); }` | `(outFunctionsControl)="handlerFunctionsControl($event, $event)"` |
|
|
347
|
+
| `(outHover)` | `boolean` | Emit `false` mỗi khi user vừa chọn xong một item | `handlerHover(event: Event, state: boolean): void { event.stopPropagation(); }` | `(outHover)="handlerHover($event, $event)"` |
|
|
348
|
+
| `(outIconEvent)` | `MouseEvent` | Emit MouseEvent khi click vào icon của button | `handlerIconClick(event: MouseEvent): void { event.stopPropagation(); }` | `(outIconEvent)="handlerIconClick($event)"` |
|
|
349
|
+
| `(outPopoverEvent)` | `TYPE_POPOVER_EVENT` | Emit các sự kiện lifecycle của popover (open, close, ...) | `handlerPopoverEvent(event: Event, evt: TYPE_POPOVER_EVENT): void { event.stopPropagation(); }` | `(outPopoverEvent)="handlerPopoverEvent($event, $event)"` |
|
|
350
|
+
| `(outSelectItem)` | `any` | Emit object item khi user click chọn một mục trong menu | `handlerSelectItem(event: Event, item: any): void { event.stopPropagation(); console.log(item); }` | `(outSelectItem)="handlerSelectItem($event, $event)"` |
|
|
351
|
+
|
|
352
|
+
## Public API — FunctionsControl
|
|
353
|
+
|
|
354
|
+
Truy cập qua `viewChild` để điều khiển popover từ component cha:
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
import { Component, viewChild } from '@angular/core';
|
|
358
|
+
import {
|
|
359
|
+
LibsUiComponentsButtonsDropdownComponent,
|
|
360
|
+
IButtonDropdown,
|
|
361
|
+
} from '@libs-ui/components-buttons-dropdown';
|
|
362
|
+
import { IPopoverFunctionControlEvent } from '@libs-ui/components-popover';
|
|
363
|
+
|
|
364
|
+
@Component({
|
|
365
|
+
selector: 'app-demo',
|
|
366
|
+
standalone: true,
|
|
367
|
+
imports: [LibsUiComponentsButtonsDropdownComponent],
|
|
368
|
+
template: `
|
|
369
|
+
<libs_ui-components-buttons-dropdown
|
|
370
|
+
#myDropdown
|
|
371
|
+
label="Menu"
|
|
372
|
+
[items]="items"
|
|
373
|
+
[applyNow]="true"
|
|
374
|
+
(outFunctionsControl)="handlerControl($event)" />
|
|
375
|
+
`,
|
|
376
|
+
})
|
|
377
|
+
export class DemoComponent {
|
|
378
|
+
private readonly dropdownRef = viewChild<LibsUiComponentsButtonsDropdownComponent>('myDropdown');
|
|
379
|
+
|
|
380
|
+
protected items = [
|
|
381
|
+
{ key: '1', label: 'Mục 1' },
|
|
382
|
+
{ key: '2', label: 'Mục 2' },
|
|
383
|
+
];
|
|
384
|
+
|
|
385
|
+
handlerControl(ctrl: IPopoverFunctionControlEvent): void {
|
|
386
|
+
// ctrl được lưu bên trong component — gọi show/hide từ bên ngoài
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Mở popup từ bên ngoài
|
|
390
|
+
openMenu(): void {
|
|
391
|
+
this.dropdownRef()?.FunctionsControl?.show?.();
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Đóng popup từ bên ngoài
|
|
395
|
+
closeMenu(): void {
|
|
396
|
+
this.dropdownRef()?.FunctionsControl?.hide?.();
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
| Getter | Return Type | Mô tả |
|
|
402
|
+
|---|---|---|
|
|
403
|
+
| `FunctionsControl` | `IPopoverFunctionControlEvent \| undefined` | Trả về object chứa các hàm điều khiển popover. `undefined` nếu popover chưa khởi tạo |
|
|
404
|
+
|
|
405
|
+
## Cấu trúc Item
|
|
406
|
+
|
|
407
|
+
Mỗi phần tử trong mảng `items` hỗ trợ các thuộc tính sau:
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
interface DropdownItem {
|
|
411
|
+
// Bắt buộc (tên field tùy theo fieldDisplay và keyField)
|
|
412
|
+
label: string; // field hiển thị — mặc định key là 'label'
|
|
413
|
+
key: string; // field key định danh — mặc định key là 'key'
|
|
414
|
+
|
|
415
|
+
// Tùy chọn — styling
|
|
416
|
+
class?: string; // Class CSS cho span hiển thị label của item (ghi đè 'libs-ui-font-h5r')
|
|
417
|
+
classIconLeft?: string; // Class icon hiển thị bên trái label item
|
|
418
|
+
classInclude?: string; // Class CSS bổ sung cho div wrapper của item
|
|
419
|
+
classRow?: string; // Class CSS cho div row ngoài cùng của item
|
|
420
|
+
|
|
421
|
+
// Tùy chọn — behavior
|
|
422
|
+
disable?: boolean; // Disable item (pointer-events-none + visual disabled)
|
|
423
|
+
ignoreFlex?: boolean; // Bỏ display:flex cho wrapper item
|
|
424
|
+
showPopover?: boolean; // Hiển thị tooltip/popover riêng cho item này
|
|
425
|
+
popoverContent?: string; // Nội dung tooltip khi showPopover = true
|
|
426
|
+
|
|
427
|
+
// Tùy chọn — advanced
|
|
428
|
+
subTemplate?: TemplateRef<unknown>; // Custom Angular template render bên trong item
|
|
429
|
+
buttonTemplateConfig?: { // Render thêm một button bên trong item
|
|
430
|
+
icon?: string; // Class icon bên phải button
|
|
431
|
+
iconLeft?: string; // Class icon bên trái button
|
|
432
|
+
label?: string; // Label của button
|
|
433
|
+
type?: TYPE_BUTTON; // Kiểu button
|
|
434
|
+
action: (item: DropdownItem, allItems: DropdownItem[]) => void; // Callback khi click
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
```
|
|
219
438
|
|
|
220
439
|
## Types & Interfaces
|
|
221
440
|
|
|
222
441
|
```typescript
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
442
|
+
import {
|
|
443
|
+
IButtonDropdown,
|
|
444
|
+
IPopupConfigButtonDropdown,
|
|
445
|
+
} from '@libs-ui/components-buttons-dropdown';
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
```typescript
|
|
449
|
+
// IButtonDropdown — kế thừa IButton, mô tả đầy đủ inputs của component
|
|
226
450
|
export interface IButtonDropdown extends IButton {
|
|
227
|
-
/** Danh sách các mục sẽ hiển thị trong menu */
|
|
228
451
|
items: any[];
|
|
229
|
-
/** Tên trường dùng để hiển thị nội dung của mỗi mục */
|
|
230
452
|
fieldDisplay?: string;
|
|
231
|
-
/** Tên trường dùng làm giá trị key của mỗi mục */
|
|
232
453
|
keyField?: string;
|
|
233
|
-
/** Giá trị key đang được chọn (hỗ trợ two-way binding) */
|
|
234
454
|
keySelected?: string;
|
|
235
|
-
/** Nếu true: chọn xong tự emit sự kiện; false: cần bấm nút Áp dụng */
|
|
236
455
|
applyNow?: boolean;
|
|
237
|
-
/** Hiển thị đường kẻ dưới menu khi mở */
|
|
238
456
|
showBorderBottom?: boolean;
|
|
239
|
-
/** Cấu hình chi tiết cho popover (vị trí, kích thước) */
|
|
240
457
|
popupConfig?: IPopupConfigButtonDropdown;
|
|
241
|
-
/** Giữ popover mở khi chuột rời khỏi nội dung */
|
|
242
458
|
ignoreHiddenPopoverContentWhenMouseLeave?: boolean;
|
|
243
|
-
/** Cách hiển thị popover (click, hover,...) */
|
|
244
459
|
modePopover?: TYPE_POPOVER_MODE;
|
|
245
460
|
}
|
|
246
461
|
|
|
247
|
-
|
|
248
|
-
* Cấu hình cho Dropdown popover
|
|
249
|
-
*/
|
|
462
|
+
// IPopupConfigButtonDropdown — cấu hình popover
|
|
250
463
|
export interface IPopupConfigButtonDropdown {
|
|
251
|
-
width?: number;
|
|
252
|
-
maxWidth?: number;
|
|
253
|
-
maxHeight?: number;
|
|
254
|
-
zIndex?: number;
|
|
255
|
-
direction?: TYPE_POPOVER_DIRECTION;
|
|
256
|
-
timeDestroy?: number;
|
|
257
|
-
widthByParent?: boolean;
|
|
464
|
+
width?: number; // Chiều rộng cố định (px)
|
|
465
|
+
maxWidth?: number; // Chiều rộng tối đa (px)
|
|
466
|
+
maxHeight?: number; // Chiều cao tối đa của danh sách (px)
|
|
467
|
+
zIndex?: number; // z-index của popover layer
|
|
468
|
+
direction?: TYPE_POPOVER_DIRECTION; // Hướng mở: 'top' | 'bottom' | 'left' | 'right'
|
|
469
|
+
timeDestroy?: number; // Thời gian (ms) trước khi DOM popover bị destroy sau khi đóng
|
|
470
|
+
widthByParent?: boolean; // Lấy chiều rộng theo parent element
|
|
258
471
|
position?: {
|
|
259
|
-
mode: 'start' | 'center' | 'end';
|
|
260
|
-
distance: number;
|
|
472
|
+
mode: 'start' | 'center' | 'end'; // Căn lề ngang của popup so với trigger
|
|
473
|
+
distance: number; // Khoảng lệch theo chiều ngang (px)
|
|
261
474
|
};
|
|
262
|
-
classInclude?: string;
|
|
475
|
+
classInclude?: string; // Class CSS bổ sung cho container popover
|
|
263
476
|
}
|
|
264
477
|
```
|
|
265
478
|
|
|
266
|
-
##
|
|
479
|
+
## Lưu ý quan trọng
|
|
267
480
|
|
|
268
|
-
|
|
481
|
+
⚠️ **`items` là required**: Input `[items]` bắt buộc phải truyền vào. Truyền mảng rỗng `[]` để hiển thị trạng thái "Không có dữ liệu".
|
|
269
482
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
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
|
-
```
|
|
483
|
+
⚠️ **`applyNow = false` yêu cầu `keyField`**: Khi dùng chế độ apply sau, component cần `keyField` để theo dõi item đang được chọn. Giá trị mặc định là `'key'` — đảm bảo mỗi item có field `key` hoặc truyền `keyField` phù hợp.
|
|
484
|
+
|
|
485
|
+
⚠️ **Label button thay đổi khi `applyNow = false`**: Ở chế độ `applyNow = false`, sau khi user chọn item, label trên button chính sẽ tự động cập nhật sang tên item được chọn (dựa theo `fieldDisplay`). Để label cố định, dùng `applyNow = true`.
|
|
296
486
|
|
|
297
|
-
|
|
487
|
+
⚠️ **XSS tự động**: Giá trị của field `fieldDisplay` trong từng item được tự động xử lý qua `escapeHtml` khi truyền vào component. Không cần escape thủ công trước khi truyền.
|
|
298
488
|
|
|
299
|
-
|
|
300
|
-
| --------------- | ------- | ---------------- |
|
|
301
|
-
| Angular | 18+ | Framework |
|
|
302
|
-
| Angular Signals | - | State management |
|
|
303
|
-
| TailwindCSS | 3.x | Styling |
|
|
304
|
-
| OnPush | - | Change Detection |
|
|
489
|
+
⚠️ **`FunctionsControl` có thể `undefined`**: Getter `FunctionsControl` trả về `undefined` nếu popover chưa được mount. Luôn kiểm tra `?.` trước khi gọi các method bên trong.
|
|
305
490
|
|
|
306
491
|
## Demo
|
|
307
492
|
|
|
@@ -310,20 +495,3 @@ npx nx serve core-ui
|
|
|
310
495
|
```
|
|
311
496
|
|
|
312
497
|
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
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
## License
|
|
328
|
-
|
|
329
|
-
MIT
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NgTemplateOutlet } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { signal, computed, input, model, output,
|
|
3
|
+
import { signal, computed, input, model, output, Component, ChangeDetectionStrategy } from '@angular/core';
|
|
4
4
|
import { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';
|
|
5
5
|
import { LibsUiComponentsPopoverComponent } from '@libs-ui/components-popover';
|
|
6
6
|
import { escapeHtml } from '@libs-ui/utils';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libs-ui-components-buttons-dropdown.mjs","sources":["../../../../../../libs-ui/components/buttons/dropdown/src/dropdown.component.ts","../../../../../../libs-ui/components/buttons/dropdown/src/dropdown.component.html","../../../../../../libs-ui/components/buttons/dropdown/src/libs-ui-components-buttons-dropdown.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, input, model, output, signal } from '@angular/core';\nimport { LibsUiComponentsButtonsButtonComponent, TYPE_BUTTON, TYPE_SIZE_BUTTON } from '@libs-ui/components-buttons-button';\nimport { IPopoverFunctionControlEvent, LibsUiComponentsPopoverComponent, TYPE_POPOVER_EVENT, TYPE_POPOVER_MODE } from '@libs-ui/components-popover';\nimport { escapeHtml } from '@libs-ui/utils';\nimport { TranslateModule } from '@ngx-translate/core';\nimport { IPopupConfigButtonDropdown } from './dropdown.interface';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'libs_ui-components-buttons-dropdown',\n templateUrl: './dropdown.component.html',\n styleUrl: './dropdown.component.scss',\n standalone: true,\n imports: [TranslateModule, NgTemplateOutlet, LibsUiComponentsButtonsButtonComponent, LibsUiComponentsPopoverComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class LibsUiComponentsButtonsDropdownComponent {\n // #region PROPERTY\n private readonly functionsControlPopover = signal<IPopoverFunctionControlEvent | undefined>(undefined);\n protected labelDisplay = computed(this.labelComputed.bind(this));\n\n // #region INPUT\n readonly label = input<string>();\n readonly fieldClass = input<string>('class'); // change color label item of items\n readonly fieldClassIconLeft = input<string>('classIconLeft'); // iconclass item of items\n readonly items = input.required<Array<any>, Array<any>>({ transform: (data) => data.map((item) => ({ ...item, [this.fieldDisplay()]: escapeHtml(item[this.fieldDisplay()]) })) }); // requried\n readonly fieldDisplay = input<string, string | undefined>('label', { transform: (value) => value ?? 'label' });\n readonly keyField = input<string, string | undefined>('key', { transform: (value) => value ?? 'key' });\n readonly keySelected = model<string>();\n readonly applyNow = input<boolean>(false); // if not applyNow: keyField is requried\n readonly showBorderBottom = input<boolean>(false);\n readonly disable = input<boolean>(false);\n readonly sizeButton = input<TYPE_SIZE_BUTTON>('medium');\n readonly classLabel = input<string>('');\n readonly iconOnlyType = input<boolean>(false);\n readonly classIconRight = input<string>('libs-ui-icon-move-right rotate-[90deg]');\n readonly classIconLeft = input<string>('');\n readonly typeButton = input<TYPE_BUTTON>('button-primary');\n readonly popupConfig = input<IPopupConfigButtonDropdown>({ width: 205, maxWidth: 250, maxHeight: 140, zIndex: 1200, direction: 'top' });\n readonly ignoreHiddenPopoverContentWhenMouseLeave = input<boolean>(true);\n readonly classInclude = input<string>('');\n readonly modePopover = input<TYPE_POPOVER_MODE>('click-toggle');\n readonly classIncludeContainer = input<string>();\n\n // #region OUTPUT\n readonly outSelectItem = output<any>();\n readonly outHover = output<boolean>();\n readonly outApply = output<any>(); // sử dụng cho bấm button left chế độ applyNow = false;\n readonly outPopoverEvent = output<TYPE_POPOVER_EVENT>();\n readonly outFunctionsControl = output<IPopoverFunctionControlEvent>();\n readonly outIconEvent = output<MouseEvent>();\n\n /* FUNCTIONS */\n protected async handlerApply() {\n if (!this.applyNow()) {\n this.outApply.emit(this.items().find((item) => item[this.keyField()] === this.keySelected()));\n }\n }\n\n protected async handlerSelectItem(event: Event, data: any) {\n event.stopPropagation();\n if (data.subTemplate) {\n return;\n }\n if (!this.applyNow()) {\n this.keySelected.set(data[this.keyField()]);\n }\n this.outSelectItem.emit(data);\n this.outHover.emit(false);\n }\n\n protected async handlerPopoverEvent(event: TYPE_POPOVER_EVENT) {\n this.outPopoverEvent.emit(event);\n }\n\n protected async handlerPopoverControlEvent(control: IPopoverFunctionControlEvent) {\n this.outFunctionsControl.emit(control);\n this.functionsControlPopover.set(control);\n }\n\n public get FunctionsControl(): IPopoverFunctionControlEvent | undefined {\n return this.functionsControlPopover();\n }\n\n protected async handlerClickButtonTemplate(event: Event, data: any, items: Array<any>) {\n event.stopPropagation();\n data.buttonTemplateConfig.action(data, items);\n }\n\n private labelComputed() {\n if (!this.keySelected() || !this.items()?.length || !this.keyField() || this.applyNow()) {\n return this.label();\n }\n for (const item of this.items()) {\n if (item[this.keyField()] === this.keySelected()) {\n return item[this.fieldDisplay()];\n }\n }\n\n return this.label();\n }\n}\n","<div\n #buttonDropdownEl\n class=\"libs-ui-buttons-dropdown flex {{ classIncludeContainer() || '' }}\"\n [class.libs-ui-buttons-dropdown-un-apply-now]=\"!applyNow()\"\n [class.libs-ui-buttons-dropdown-apply-now-button-primary]=\"applyNow() && typeButton() === 'button-primary'\"\n [class.libs-ui-buttons-dropdown-apply-now-button-secondary]=\"applyNow() && typeButton() === 'button-secondary'\">\n <libs_ui-components-buttons-button\n [disable]=\"disable()\"\n [iconOnlyType]=\"iconOnlyType()\"\n [classIconLeft]=\"classIconLeft()\"\n [classIconRight]=\"!applyNow() ? '' : classIconRight()\"\n [type]=\"typeButton()\"\n [classLabel]=\"classLabel()\"\n [classInclude]=\"classInclude()\"\n [sizeButton]=\"sizeButton()\"\n [popover]=\"{\n elementRefCustom: buttonDropdownEl,\n mode: modePopover(),\n ignoreShowPopover: !applyNow(),\n ignoreHiddenPopoverContentWhenMouseLeave: true,\n config: {\n animationConfig: {\n time: 0.5,\n },\n template: templateContentEl,\n whiteTheme: true,\n ignoreArrow: true,\n width: popupConfig().width,\n widthByParent: popupConfig().widthByParent ?? false,\n maxWidth: popupConfig().maxWidth,\n maxHeight: popupConfig().maxHeight,\n zIndex: popupConfig().zIndex,\n classInclude: 'rounded-[4px] ' + popupConfig().classInclude,\n direction: popupConfig().direction,\n timerDestroy: popupConfig().timeDestroy,\n directionDistance: 2,\n position: {\n mode: popupConfig().position?.mode || 'start',\n distance: popupConfig().position?.distance ?? 0,\n },\n },\n }\"\n [label]=\"labelDisplay()\"\n (outFunctionsControl)=\"handlerPopoverControlEvent($event)\"\n (outPopoverEvent)=\"handlerPopoverEvent($event)\"\n (outClick)=\"handlerApply()\" />\n @if (!applyNow()) {\n <div class=\"h-full w-[1px] bg-white\"></div>\n <libs_ui-components-buttons-button\n [type]=\"typeButton()\"\n [disable]=\"disable()\"\n [sizeButton]=\"sizeButton()\"\n [popover]=\"{\n mode: 'click-toggle',\n ignoreHiddenPopoverContentWhenMouseLeave: ignoreHiddenPopoverContentWhenMouseLeave(),\n config: {\n animationConfig: {\n time: 0.5,\n },\n template: templateContentEl,\n whiteTheme: true,\n ignoreArrow: true,\n width: popupConfig().width,\n maxWidth: popupConfig().maxWidth,\n widthByParent: popupConfig().widthByParent ?? false,\n maxHeight: popupConfig().maxHeight,\n zIndex: popupConfig().zIndex,\n direction: popupConfig().direction,\n classInclude: popupConfig().classInclude,\n directionDistance: 2,\n position: {\n mode: 'start',\n distance: 0,\n },\n },\n }\"\n [iconOnlyType]=\"true\"\n [classIconRight]=\"classIconRight()\"\n [classInclude]=\"classInclude() || '!py-[9px]'\"\n (outFunctionsControl)=\"handlerPopoverControlEvent($event)\"\n (outPopoverEvent)=\"handlerPopoverEvent($event)\" />\n }\n</div>\n<ng-template #templateContentEl>\n <div>\n @if (items() && items().length) {\n <div class=\"m-0 p-0\">\n @for (item of items(); track item) {\n <div class=\"{{ item.classRow || '' }}\">\n <div\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: item.popoverContent, zIndex: popupConfig().zIndex, directionDistance: -2 }\"\n [ignoreShowPopover]=\"!item.showPopover\"\n [ignoreStopPropagationEvent]=\"true\"\n class=\"libs-ui-bg-list-hover relative cursor-pointer py-[7px] {{ item.classInclude || '' }} {{ showBorderBottom() ? 'libs-ui-border-bottom-general' : '' }}\"\n tabindex=\"0\"\n [class.flex]=\"!item.ignoreFlex\"\n [class.px-[16px]]=\"applyNow()\"\n [class.pl-[16px]]=\"!applyNow()\"\n [class.pr-[40px]]=\"!applyNow()\"\n [class.libs-ui-disable]=\"item.disable\"\n [class.pointer-events-none]=\"item.disable\"\n (click)=\"handlerSelectItem($event, item)\"\n (keydown.enter)=\"handlerSelectItem($any($event), item)\"\n (keydown.space)=\"handlerSelectItem($any($event), item)\">\n @if (item[fieldClassIconLeft()]) {\n <i [class]=\"item[fieldClassIconLeft()]\"></i>\n }\n <span\n [class]=\"item[fieldClass()] ?? 'libs-ui-font-h5r'\"\n [innerHtml]=\"item[fieldDisplay()] | translate\"></span>\n @if (item.buttonTemplateConfig) {\n <libs_ui-components-buttons-button\n [classIconLeft]=\"item.buttonTemplateConfig.iconLeft\"\n [classIconRight]=\"item.buttonTemplateConfig.icon\"\n [label]=\"item.buttonTemplateConfig.label\"\n [classLabel]=\"item.buttonTemplateConfig.label\"\n (outClick)=\"handlerClickButtonTemplate($event, item, items())\"\n [type]=\"item.buttonTemplateConfig.type\" />\n }\n <ng-container *ngTemplateOutlet=\"item?.subTemplate || null; context: { item: item }\"></ng-container>\n @if (item[keyField()] === keySelected() && !applyNow()) {\n <i class=\"libs-ui-icon-check absolute right-[16px] top-[8px]\"></i>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div\n class=\"p-[20px]\"\n [innerHtml]=\"'i18n_no_data' | translate\"></div>\n }\n </div>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"libs-ui-components-buttons-dropdown.mjs","sources":["../../../../../../libs-ui/components/buttons/dropdown/src/dropdown.component.ts","../../../../../../libs-ui/components/buttons/dropdown/src/dropdown.component.html","../../../../../../libs-ui/components/buttons/dropdown/src/libs-ui-components-buttons-dropdown.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, input, model, output, signal } from '@angular/core';\nimport { LibsUiComponentsButtonsButtonComponent, TYPE_BUTTON, TYPE_SIZE_BUTTON } from '@libs-ui/components-buttons-button';\nimport { IPopoverFunctionControlEvent, LibsUiComponentsPopoverComponent, TYPE_POPOVER_EVENT, TYPE_POPOVER_MODE } from '@libs-ui/components-popover';\nimport { escapeHtml } from '@libs-ui/utils';\nimport { TranslateModule } from '@ngx-translate/core';\nimport { IPopupConfigButtonDropdown } from './dropdown.interface';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'libs_ui-components-buttons-dropdown',\n templateUrl: './dropdown.component.html',\n styleUrl: './dropdown.component.scss',\n standalone: true,\n imports: [TranslateModule, NgTemplateOutlet, LibsUiComponentsButtonsButtonComponent, LibsUiComponentsPopoverComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class LibsUiComponentsButtonsDropdownComponent {\n // #region PROPERTY\n private readonly functionsControlPopover = signal<IPopoverFunctionControlEvent | undefined>(undefined);\n protected labelDisplay = computed(this.labelComputed.bind(this));\n\n // #region INPUT\n readonly label = input<string>();\n readonly fieldClass = input<string>('class'); // change color label item of items\n readonly fieldClassIconLeft = input<string>('classIconLeft'); // iconclass item of items\n readonly items = input.required<Array<any>, Array<any>>({ transform: (data) => data.map((item) => ({ ...item, [this.fieldDisplay()]: escapeHtml(item[this.fieldDisplay()]) })) }); // requried\n readonly fieldDisplay = input<string, string | undefined>('label', { transform: (value) => value ?? 'label' });\n readonly keyField = input<string, string | undefined>('key', { transform: (value) => value ?? 'key' });\n readonly keySelected = model<string>();\n readonly applyNow = input<boolean>(false); // if not applyNow: keyField is requried\n readonly showBorderBottom = input<boolean>(false);\n readonly disable = input<boolean>(false);\n readonly sizeButton = input<TYPE_SIZE_BUTTON>('medium');\n readonly classLabel = input<string>('');\n readonly iconOnlyType = input<boolean>(false);\n readonly classIconRight = input<string>('libs-ui-icon-move-right rotate-[90deg]');\n readonly classIconLeft = input<string>('');\n readonly typeButton = input<TYPE_BUTTON>('button-primary');\n readonly popupConfig = input<IPopupConfigButtonDropdown>({ width: 205, maxWidth: 250, maxHeight: 140, zIndex: 1200, direction: 'top' });\n readonly ignoreHiddenPopoverContentWhenMouseLeave = input<boolean>(true);\n readonly classInclude = input<string>('');\n readonly modePopover = input<TYPE_POPOVER_MODE>('click-toggle');\n readonly classIncludeContainer = input<string>();\n\n // #region OUTPUT\n readonly outSelectItem = output<any>();\n readonly outHover = output<boolean>();\n readonly outApply = output<any>(); // sử dụng cho bấm button left chế độ applyNow = false;\n readonly outPopoverEvent = output<TYPE_POPOVER_EVENT>();\n readonly outFunctionsControl = output<IPopoverFunctionControlEvent>();\n readonly outIconEvent = output<MouseEvent>();\n\n /* FUNCTIONS */\n protected async handlerApply() {\n if (!this.applyNow()) {\n this.outApply.emit(this.items().find((item) => item[this.keyField()] === this.keySelected()));\n }\n }\n\n protected async handlerSelectItem(event: Event, data: any) {\n event.stopPropagation();\n if (data.subTemplate) {\n return;\n }\n if (!this.applyNow()) {\n this.keySelected.set(data[this.keyField()]);\n }\n this.outSelectItem.emit(data);\n this.outHover.emit(false);\n }\n\n protected async handlerPopoverEvent(event: TYPE_POPOVER_EVENT) {\n this.outPopoverEvent.emit(event);\n }\n\n protected async handlerPopoverControlEvent(control: IPopoverFunctionControlEvent) {\n this.outFunctionsControl.emit(control);\n this.functionsControlPopover.set(control);\n }\n\n public get FunctionsControl(): IPopoverFunctionControlEvent | undefined {\n return this.functionsControlPopover();\n }\n\n protected async handlerClickButtonTemplate(event: Event, data: any, items: Array<any>) {\n event.stopPropagation();\n data.buttonTemplateConfig.action(data, items);\n }\n\n private labelComputed() {\n if (!this.keySelected() || !this.items()?.length || !this.keyField() || this.applyNow()) {\n return this.label();\n }\n for (const item of this.items()) {\n if (item[this.keyField()] === this.keySelected()) {\n return item[this.fieldDisplay()];\n }\n }\n\n return this.label();\n }\n}\n","<div\n #buttonDropdownEl\n class=\"libs-ui-buttons-dropdown flex {{ classIncludeContainer() || '' }}\"\n [class.libs-ui-buttons-dropdown-un-apply-now]=\"!applyNow()\"\n [class.libs-ui-buttons-dropdown-apply-now-button-primary]=\"applyNow() && typeButton() === 'button-primary'\"\n [class.libs-ui-buttons-dropdown-apply-now-button-secondary]=\"applyNow() && typeButton() === 'button-secondary'\">\n <libs_ui-components-buttons-button\n [disable]=\"disable()\"\n [iconOnlyType]=\"iconOnlyType()\"\n [classIconLeft]=\"classIconLeft()\"\n [classIconRight]=\"!applyNow() ? '' : classIconRight()\"\n [type]=\"typeButton()\"\n [classLabel]=\"classLabel()\"\n [classInclude]=\"classInclude()\"\n [sizeButton]=\"sizeButton()\"\n [popover]=\"{\n elementRefCustom: buttonDropdownEl,\n mode: modePopover(),\n ignoreShowPopover: !applyNow(),\n ignoreHiddenPopoverContentWhenMouseLeave: true,\n config: {\n animationConfig: {\n time: 0.5,\n },\n template: templateContentEl,\n whiteTheme: true,\n ignoreArrow: true,\n width: popupConfig().width,\n widthByParent: popupConfig().widthByParent ?? false,\n maxWidth: popupConfig().maxWidth,\n maxHeight: popupConfig().maxHeight,\n zIndex: popupConfig().zIndex,\n classInclude: 'rounded-[4px] ' + popupConfig().classInclude,\n direction: popupConfig().direction,\n timerDestroy: popupConfig().timeDestroy,\n directionDistance: 2,\n position: {\n mode: popupConfig().position?.mode || 'start',\n distance: popupConfig().position?.distance ?? 0,\n },\n },\n }\"\n [label]=\"labelDisplay()\"\n (outFunctionsControl)=\"handlerPopoverControlEvent($event)\"\n (outPopoverEvent)=\"handlerPopoverEvent($event)\"\n (outClick)=\"handlerApply()\" />\n @if (!applyNow()) {\n <div class=\"h-full w-[1px] bg-white\"></div>\n <libs_ui-components-buttons-button\n [type]=\"typeButton()\"\n [disable]=\"disable()\"\n [sizeButton]=\"sizeButton()\"\n [popover]=\"{\n mode: 'click-toggle',\n ignoreHiddenPopoverContentWhenMouseLeave: ignoreHiddenPopoverContentWhenMouseLeave(),\n config: {\n animationConfig: {\n time: 0.5,\n },\n template: templateContentEl,\n whiteTheme: true,\n ignoreArrow: true,\n width: popupConfig().width,\n maxWidth: popupConfig().maxWidth,\n widthByParent: popupConfig().widthByParent ?? false,\n maxHeight: popupConfig().maxHeight,\n zIndex: popupConfig().zIndex,\n direction: popupConfig().direction,\n classInclude: popupConfig().classInclude,\n directionDistance: 2,\n position: {\n mode: 'start',\n distance: 0,\n },\n },\n }\"\n [iconOnlyType]=\"true\"\n [classIconRight]=\"classIconRight()\"\n [classInclude]=\"classInclude() || '!py-[9px]'\"\n (outFunctionsControl)=\"handlerPopoverControlEvent($event)\"\n (outPopoverEvent)=\"handlerPopoverEvent($event)\" />\n }\n</div>\n<ng-template #templateContentEl>\n <div>\n @if (items() && items().length) {\n <div class=\"m-0 p-0\">\n @for (item of items(); track item) {\n <div class=\"{{ item.classRow || '' }}\">\n <div\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: item.popoverContent, zIndex: popupConfig().zIndex, directionDistance: -2 }\"\n [ignoreShowPopover]=\"!item.showPopover\"\n [ignoreStopPropagationEvent]=\"true\"\n class=\"libs-ui-bg-list-hover relative cursor-pointer py-[7px] {{ item.classInclude || '' }} {{ showBorderBottom() ? 'libs-ui-border-bottom-general' : '' }}\"\n tabindex=\"0\"\n [class.flex]=\"!item.ignoreFlex\"\n [class.px-[16px]]=\"applyNow()\"\n [class.pl-[16px]]=\"!applyNow()\"\n [class.pr-[40px]]=\"!applyNow()\"\n [class.libs-ui-disable]=\"item.disable\"\n [class.pointer-events-none]=\"item.disable\"\n (click)=\"handlerSelectItem($event, item)\"\n (keydown.enter)=\"handlerSelectItem($any($event), item)\"\n (keydown.space)=\"handlerSelectItem($any($event), item)\">\n @if (item[fieldClassIconLeft()]) {\n <i [class]=\"item[fieldClassIconLeft()]\"></i>\n }\n <span\n [class]=\"item[fieldClass()] ?? 'libs-ui-font-h5r'\"\n [innerHtml]=\"item[fieldDisplay()] | translate\"></span>\n @if (item.buttonTemplateConfig) {\n <libs_ui-components-buttons-button\n [classIconLeft]=\"item.buttonTemplateConfig.iconLeft\"\n [classIconRight]=\"item.buttonTemplateConfig.icon\"\n [label]=\"item.buttonTemplateConfig.label\"\n [classLabel]=\"item.buttonTemplateConfig.label\"\n (outClick)=\"handlerClickButtonTemplate($event, item, items())\"\n [type]=\"item.buttonTemplateConfig.type\" />\n }\n <ng-container *ngTemplateOutlet=\"item?.subTemplate || null; context: { item: item }\"></ng-container>\n @if (item[keyField()] === keySelected() && !applyNow()) {\n <i class=\"libs-ui-icon-check absolute right-[16px] top-[8px]\"></i>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div\n class=\"p-[20px]\"\n [innerHtml]=\"'i18n_no_data' | translate\"></div>\n }\n </div>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libs-ui/components-buttons-dropdown",
|
|
3
|
-
"version": "0.2.356-
|
|
3
|
+
"version": "0.2.356-43",
|
|
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.356-
|
|
8
|
-
"@libs-ui/components-popover": "0.2.356-
|
|
9
|
-
"@libs-ui/utils": "0.2.356-
|
|
7
|
+
"@libs-ui/components-buttons-button": "0.2.356-43",
|
|
8
|
+
"@libs-ui/components-popover": "0.2.356-43",
|
|
9
|
+
"@libs-ui/utils": "0.2.356-43",
|
|
10
10
|
"@ngx-translate/core": "^15.0.0"
|
|
11
11
|
},
|
|
12
12
|
"sideEffects": false,
|