@libs-ui/components-buttons-group 0.2.356-9 → 0.2.357-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.
package/README.md
CHANGED
|
@@ -1,38 +1,33 @@
|
|
|
1
1
|
# @libs-ui/components-buttons-group
|
|
2
2
|
|
|
3
|
-
> Component
|
|
3
|
+
> Component nhóm nhiều button thành một group liền kề với quản lý trạng thái active tự động.
|
|
4
4
|
|
|
5
5
|
## Giới thiệu
|
|
6
6
|
|
|
7
|
-
`LibsUiComponentsButtonsGroupComponent` là
|
|
7
|
+
`LibsUiComponentsButtonsGroupComponent` là standalone Angular component cho phép nhóm nhiều button thành một dải liền kề. Component tự động xử lý trạng thái active/inactive theo index, hỗ trợ two-way binding, disable theo group hoặc từng button riêng lẻ, và tích hợp popover cho từng button trong group.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Tính năng
|
|
10
10
|
|
|
11
|
-
- ✅ Nhóm nhiều button thành một
|
|
12
|
-
- ✅ Quản lý trạng thái active với visual feedback rõ ràng
|
|
13
|
-
- ✅ Two-way binding cho index button đang active
|
|
14
|
-
- ✅
|
|
15
|
-
- ✅
|
|
16
|
-
- ✅
|
|
17
|
-
- ✅
|
|
18
|
-
- ✅ Angular Signals
|
|
19
|
-
- ✅ OnPush Change Detection tối ưu hiệu năng
|
|
11
|
+
- ✅ Nhóm nhiều button thành một dải liền kề với border styling tự động
|
|
12
|
+
- ✅ Quản lý trạng thái active/inactive theo index với visual feedback rõ ràng
|
|
13
|
+
- ✅ Two-way binding `[(indexActive)]` cho index button đang active
|
|
14
|
+
- ✅ Disable toàn bộ group hoặc từng button riêng lẻ
|
|
15
|
+
- ✅ Hỗ trợ icon trái/phải và chế độ icon-only cho từng button
|
|
16
|
+
- ✅ Tích hợp popover cho từng button trong group
|
|
17
|
+
- ✅ Click vào button đang active không emit event (tránh re-render không cần thiết)
|
|
18
|
+
- ✅ Angular Signals + OnPush Change Detection tối ưu hiệu năng
|
|
20
19
|
|
|
21
20
|
## Khi nào sử dụng
|
|
22
21
|
|
|
23
|
-
- Khi cần nhóm các button
|
|
24
|
-
- Khi cần
|
|
25
|
-
- Khi cần
|
|
26
|
-
-
|
|
22
|
+
- Khi cần nhóm các button liên quan thành filter group (All / Active / Completed)
|
|
23
|
+
- Khi cần view switcher (List View / Grid View / Card View)
|
|
24
|
+
- Khi cần segmented control hoặc tab-style buttons
|
|
25
|
+
- Khi cần toolbar formatting (Bold / Italic / Underline) dạng icon-only
|
|
27
26
|
|
|
28
27
|
## Cài đặt
|
|
29
28
|
|
|
30
29
|
```bash
|
|
31
|
-
# npm
|
|
32
30
|
npm install @libs-ui/components-buttons-group
|
|
33
|
-
|
|
34
|
-
# yarn
|
|
35
|
-
yarn add @libs-ui/components-buttons-group
|
|
36
31
|
```
|
|
37
32
|
|
|
38
33
|
## Import
|
|
@@ -40,6 +35,7 @@ yarn add @libs-ui/components-buttons-group
|
|
|
40
35
|
```typescript
|
|
41
36
|
import { LibsUiComponentsButtonsGroupComponent } from '@libs-ui/components-buttons-group';
|
|
42
37
|
import { IButton } from '@libs-ui/components-buttons-button';
|
|
38
|
+
import { IPopoverFunctionControlEvent } from '@libs-ui/components-popover';
|
|
43
39
|
|
|
44
40
|
@Component({
|
|
45
41
|
standalone: true,
|
|
@@ -49,28 +45,81 @@ import { IButton } from '@libs-ui/components-buttons-button';
|
|
|
49
45
|
export class YourComponent {}
|
|
50
46
|
```
|
|
51
47
|
|
|
52
|
-
## Ví dụ
|
|
48
|
+
## Ví dụ sử dụng
|
|
53
49
|
|
|
54
|
-
### Basic
|
|
50
|
+
### Basic — View Switcher
|
|
55
51
|
|
|
56
52
|
```html
|
|
57
53
|
<libs_ui-components-buttons-group
|
|
58
54
|
[buttons]="viewButtons"
|
|
59
|
-
[(indexActive)]="
|
|
60
|
-
(outChange)="
|
|
55
|
+
[(indexActive)]="activeView"
|
|
56
|
+
(outChange)="handlerViewChange($event)"
|
|
57
|
+
/>
|
|
61
58
|
```
|
|
62
59
|
|
|
63
60
|
```typescript
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
61
|
+
import { Component, signal } from '@angular/core';
|
|
62
|
+
import { LibsUiComponentsButtonsGroupComponent } from '@libs-ui/components-buttons-group';
|
|
63
|
+
import { IButton } from '@libs-ui/components-buttons-button';
|
|
64
|
+
|
|
65
|
+
@Component({
|
|
66
|
+
selector: 'app-view-switcher',
|
|
67
|
+
standalone: true,
|
|
68
|
+
imports: [LibsUiComponentsButtonsGroupComponent],
|
|
69
|
+
templateUrl: './view-switcher.component.html',
|
|
70
|
+
})
|
|
71
|
+
export class ViewSwitcherComponent {
|
|
72
|
+
readonly activeView = signal<number>(0);
|
|
73
|
+
|
|
74
|
+
readonly viewButtons: IButton[] = [
|
|
75
|
+
{ label: 'List View', key: 'list' },
|
|
76
|
+
{ label: 'Grid View', key: 'grid' },
|
|
77
|
+
{ label: 'Card View', key: 'card' },
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
protected handlerViewChange(event: Event): void {
|
|
81
|
+
event.stopPropagation();
|
|
82
|
+
// activeView đã được cập nhật tự động qua two-way binding
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Filter Group
|
|
88
|
+
|
|
89
|
+
```html
|
|
90
|
+
<libs_ui-components-buttons-group
|
|
91
|
+
[buttons]="filterButtons"
|
|
92
|
+
[(indexActive)]="activeFilter"
|
|
93
|
+
(outChange)="handlerFilterChange($event)"
|
|
94
|
+
/>
|
|
95
|
+
<p>Đang lọc: {{ filterButtons[activeFilter()].key }}</p>
|
|
96
|
+
```
|
|
69
97
|
|
|
70
|
-
|
|
98
|
+
```typescript
|
|
99
|
+
import { Component, signal } from '@angular/core';
|
|
100
|
+
import { LibsUiComponentsButtonsGroupComponent } from '@libs-ui/components-buttons-group';
|
|
101
|
+
import { IButton } from '@libs-ui/components-buttons-button';
|
|
71
102
|
|
|
72
|
-
|
|
73
|
-
|
|
103
|
+
@Component({
|
|
104
|
+
selector: 'app-filter-group',
|
|
105
|
+
standalone: true,
|
|
106
|
+
imports: [LibsUiComponentsButtonsGroupComponent],
|
|
107
|
+
templateUrl: './filter-group.component.html',
|
|
108
|
+
})
|
|
109
|
+
export class FilterGroupComponent {
|
|
110
|
+
readonly activeFilter = signal<number>(0);
|
|
111
|
+
|
|
112
|
+
readonly filterButtons: IButton[] = [
|
|
113
|
+
{ label: 'All', key: 'all' },
|
|
114
|
+
{ label: 'Active', key: 'active' },
|
|
115
|
+
{ label: 'Completed', key: 'completed' },
|
|
116
|
+
{ label: 'Archived', key: 'archived' },
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
protected handlerFilterChange(button: IButton): void {
|
|
120
|
+
button.key; // 'all' | 'active' | 'completed' | 'archived'
|
|
121
|
+
// Thực hiện logic lọc dữ liệu theo button.key
|
|
122
|
+
}
|
|
74
123
|
}
|
|
75
124
|
```
|
|
76
125
|
|
|
@@ -79,79 +128,59 @@ handleChange(button: IButton) {
|
|
|
79
128
|
```html
|
|
80
129
|
<libs_ui-components-buttons-group
|
|
81
130
|
[buttons]="viewButtonsWithIcons"
|
|
82
|
-
[(indexActive)]="activeView"
|
|
131
|
+
[(indexActive)]="activeView"
|
|
132
|
+
/>
|
|
83
133
|
```
|
|
84
134
|
|
|
85
135
|
```typescript
|
|
86
|
-
viewButtonsWithIcons: IButton[] = [
|
|
87
|
-
{
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
classIconLeft: 'libs-ui-icon-list'
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
label: 'Grid',
|
|
94
|
-
key: 'grid',
|
|
95
|
-
classIconLeft: 'libs-ui-icon-grid'
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
label: 'Card',
|
|
99
|
-
key: 'card',
|
|
100
|
-
classIconLeft: 'libs-ui-icon-card'
|
|
101
|
-
}
|
|
136
|
+
readonly viewButtonsWithIcons: IButton[] = [
|
|
137
|
+
{ label: 'List', key: 'list', classIconLeft: 'libs-ui-icon-list-bulleted' },
|
|
138
|
+
{ label: 'Grid', key: 'grid', classIconLeft: 'libs-ui-icon-table' },
|
|
139
|
+
{ label: 'Card', key: 'card', classIconLeft: 'libs-ui-icon-image-solid' },
|
|
102
140
|
];
|
|
103
|
-
|
|
104
|
-
activeView = 0;
|
|
105
141
|
```
|
|
106
142
|
|
|
107
|
-
### Icon Only
|
|
143
|
+
### Icon Only (Toolbar)
|
|
108
144
|
|
|
109
145
|
```html
|
|
110
146
|
<libs_ui-components-buttons-group
|
|
111
|
-
[buttons]="
|
|
112
|
-
[(indexActive)]="
|
|
147
|
+
[buttons]="formatButtons"
|
|
148
|
+
[(indexActive)]="activeFormat"
|
|
149
|
+
/>
|
|
113
150
|
```
|
|
114
151
|
|
|
115
152
|
```typescript
|
|
116
|
-
|
|
117
|
-
{
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
iconOnlyType: true
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
key: 'italic',
|
|
124
|
-
classIconLeft: 'libs-ui-icon-italic',
|
|
125
|
-
iconOnlyType: true
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
key: 'underline',
|
|
129
|
-
classIconLeft: 'libs-ui-icon-underline',
|
|
130
|
-
iconOnlyType: true
|
|
131
|
-
}
|
|
153
|
+
readonly formatButtons: IButton[] = [
|
|
154
|
+
{ key: 'bold', classIconLeft: 'libs-ui-icon-editor-bold', iconOnlyType: true },
|
|
155
|
+
{ key: 'italic', classIconLeft: 'libs-ui-icon-editor-italic', iconOnlyType: true },
|
|
156
|
+
{ key: 'underline', classIconLeft: 'libs-ui-icon-editor-underlined', iconOnlyType: true },
|
|
132
157
|
];
|
|
133
158
|
```
|
|
134
159
|
|
|
135
|
-
###
|
|
160
|
+
### Disable — Toàn bộ group
|
|
136
161
|
|
|
137
162
|
```html
|
|
138
|
-
<!-- Disable entire group -->
|
|
139
163
|
<libs_ui-components-buttons-group
|
|
140
|
-
[buttons]="
|
|
164
|
+
[buttons]="viewButtons"
|
|
141
165
|
[disable]="true"
|
|
142
|
-
[(indexActive)]="
|
|
166
|
+
[(indexActive)]="activeView"
|
|
167
|
+
/>
|
|
168
|
+
```
|
|
143
169
|
|
|
144
|
-
|
|
170
|
+
### Disable — Từng button riêng lẻ
|
|
171
|
+
|
|
172
|
+
```html
|
|
145
173
|
<libs_ui-components-buttons-group
|
|
146
174
|
[buttons]="buttonsWithDisabled"
|
|
147
|
-
[(indexActive)]="activeIndex"
|
|
175
|
+
[(indexActive)]="activeIndex"
|
|
176
|
+
/>
|
|
148
177
|
```
|
|
149
178
|
|
|
150
179
|
```typescript
|
|
151
|
-
buttonsWithDisabled: IButton[] = [
|
|
180
|
+
readonly buttonsWithDisabled: IButton[] = [
|
|
152
181
|
{ label: 'Option 1', key: '1' },
|
|
153
182
|
{ label: 'Option 2', key: '2', disable: true },
|
|
154
|
-
{ label: 'Option 3', key: '3' }
|
|
183
|
+
{ label: 'Option 3', key: '3' },
|
|
155
184
|
];
|
|
156
185
|
```
|
|
157
186
|
|
|
@@ -161,174 +190,85 @@ buttonsWithDisabled: IButton[] = [
|
|
|
161
190
|
<libs_ui-components-buttons-group
|
|
162
191
|
[buttons]="buttonsWithPopover"
|
|
163
192
|
[(indexActive)]="activeIndex"
|
|
164
|
-
(outFunctionsControl)="
|
|
193
|
+
(outFunctionsControl)="handlerPopoverControl($event)"
|
|
194
|
+
/>
|
|
165
195
|
```
|
|
166
196
|
|
|
167
197
|
```typescript
|
|
168
|
-
|
|
198
|
+
import { IPopoverFunctionControlEvent } from '@libs-ui/components-popover';
|
|
199
|
+
|
|
200
|
+
readonly buttonsWithPopover: IButton[] = [
|
|
169
201
|
{
|
|
170
202
|
label: 'Info',
|
|
171
203
|
key: 'info',
|
|
172
|
-
popover: {
|
|
173
|
-
content: 'This is information button',
|
|
174
|
-
mode: 'hover'
|
|
175
|
-
}
|
|
204
|
+
popover: { content: 'Thông tin chi tiết về chức năng này', mode: 'hover' },
|
|
176
205
|
},
|
|
177
206
|
{
|
|
178
207
|
label: 'Warning',
|
|
179
208
|
key: 'warning',
|
|
180
|
-
popover: {
|
|
181
|
-
|
|
182
|
-
mode: 'hover'
|
|
183
|
-
}
|
|
184
|
-
}
|
|
209
|
+
popover: { content: 'Cảnh báo: thao tác này không thể hoàn tác', mode: 'hover' },
|
|
210
|
+
},
|
|
185
211
|
];
|
|
186
212
|
|
|
187
|
-
|
|
188
|
-
|
|
213
|
+
protected handlerPopoverControl(control: IPopoverFunctionControlEvent): void {
|
|
214
|
+
// Lưu lại control để thao tác popover thủ công nếu cần
|
|
215
|
+
// control.showPopover(), control.removePopoverOverlay(), ...
|
|
189
216
|
}
|
|
190
217
|
```
|
|
191
218
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
```html
|
|
195
|
-
<libs_ui-components-buttons-group
|
|
196
|
-
[buttons]="filterButtons"
|
|
197
|
-
[(indexActive)]="activeFilter"
|
|
198
|
-
(outChange)="applyFilter($event)" />
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
```typescript
|
|
202
|
-
filterButtons: IButton[] = [
|
|
203
|
-
{ label: 'All', key: 'all' },
|
|
204
|
-
{ label: 'Active', key: 'active' },
|
|
205
|
-
{ label: 'Completed', key: 'completed' },
|
|
206
|
-
{ label: 'Archived', key: 'archived' }
|
|
207
|
-
];
|
|
219
|
+
## @Input()
|
|
208
220
|
|
|
209
|
-
|
|
221
|
+
| Input | Type | Default | Mô tả | Ví dụ |
|
|
222
|
+
|---|---|---|---|---|
|
|
223
|
+
| `[buttons]` | `Array<IButton>` | **required** | Danh sách các button trong group. Không được để rỗng. | `[buttons]="viewButtons"` |
|
|
224
|
+
| `[disable]` | `boolean` | `false` | Disable toàn bộ button group. Từng button có thể disable riêng qua `IButton.disable`. | `[disable]="isLoading"` |
|
|
225
|
+
| `[(indexActive)]` | `number` | `0` | Index (0-based) của button đang active. Hỗ trợ two-way binding để đồng bộ state với component cha. | `[(indexActive)]="activeView"` |
|
|
210
226
|
|
|
211
|
-
|
|
212
|
-
// Apply filter based on button.key
|
|
213
|
-
console.log('Filtering by:', button.key);
|
|
214
|
-
}
|
|
215
|
-
```
|
|
227
|
+
## @Output()
|
|
216
228
|
|
|
217
|
-
|
|
229
|
+
| Output | Type | Mô tả | Handler TS | Binding HTML |
|
|
230
|
+
|---|---|---|---|---|
|
|
231
|
+
| `(outChange)` | `IButton` | Emit button vừa được chọn. Không emit khi click lại button đang active. | `handlerChange(button: IButton): void { button.stopPropagation?.(); /* xử lý */ }` | `(outChange)="handlerChange($event)"` |
|
|
232
|
+
| `(outFunctionsControl)` | `IPopoverFunctionControlEvent` | Emit API điều khiển popover khi popover của một button trong group được khởi tạo. | `handlerPopoverControl(control: IPopoverFunctionControlEvent): void { control; }` | `(outFunctionsControl)="handlerPopoverControl($event)"` |
|
|
218
233
|
|
|
219
|
-
|
|
220
|
-
<libs_ui-components-buttons-group
|
|
221
|
-
[buttons]="styledButtons"
|
|
222
|
-
[(indexActive)]="activeIndex" />
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
```typescript
|
|
226
|
-
styledButtons: IButton[] = [
|
|
227
|
-
{
|
|
228
|
-
label: 'Primary',
|
|
229
|
-
key: '1',
|
|
230
|
-
classInclude: 'custom-button-class'
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
label: 'Secondary',
|
|
234
|
-
key: '2',
|
|
235
|
-
classInclude: 'custom-button-class'
|
|
236
|
-
}
|
|
237
|
-
];
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
## API
|
|
241
|
-
|
|
242
|
-
### libs_ui-components-buttons-group
|
|
243
|
-
|
|
244
|
-
#### Inputs
|
|
245
|
-
|
|
246
|
-
| Property | Type | Default | Description |
|
|
247
|
-
| ----------------- | ---------------- | -------- | ---------------------------------------------- |
|
|
248
|
-
| `[buttons]` | `Array<IButton>` | required | Danh sách các button trong group |
|
|
249
|
-
| `[(indexActive)]` | `number` | `0` | Index của button đang active (two-way binding) |
|
|
250
|
-
| `[disable]` | `boolean` | `false` | Disable toàn bộ button group |
|
|
251
|
-
|
|
252
|
-
#### Outputs
|
|
253
|
-
|
|
254
|
-
| Property | Type | Description |
|
|
255
|
-
| ----------------------- | ------------------------------ | --------------------------------- |
|
|
256
|
-
| `(outChange)` | `IButton` | Emit khi chuyển đổi button active |
|
|
257
|
-
| `(outFunctionsControl)` | `IPopoverFunctionControlEvent` | Emit functions điều khiển popover |
|
|
258
|
-
|
|
259
|
-
#### Public Methods
|
|
260
|
-
|
|
261
|
-
| Method | Description |
|
|
262
|
-
| ------------------ | --------------------------------------- |
|
|
263
|
-
| `FunctionsControl` | Getter để lấy popover control functions |
|
|
234
|
+
> **Lưu ý `outChange`:** Event này không emit khi click vào button đang active (index không thay đổi). Handler không nhận `Event` DOM nên không cần `stopPropagation()` trong handler này.
|
|
264
235
|
|
|
265
236
|
## Types & Interfaces
|
|
266
237
|
|
|
267
|
-
### IButton
|
|
238
|
+
### IButton
|
|
268
239
|
|
|
269
|
-
|
|
240
|
+
Import từ `@libs-ui/components-buttons-button`:
|
|
270
241
|
|
|
271
242
|
```typescript
|
|
272
|
-
|
|
273
|
-
/** Unique key cho button */
|
|
274
|
-
key?: string;
|
|
275
|
-
|
|
276
|
-
/** Kiểu button (sẽ được override bởi component) */
|
|
277
|
-
type?: TYPE_BUTTON;
|
|
278
|
-
|
|
279
|
-
/** Kích thước button */
|
|
280
|
-
sizeButton?: TYPE_SIZE_BUTTON;
|
|
281
|
-
|
|
282
|
-
/** Chỉ hiển thị icon, ẩn label */
|
|
283
|
-
iconOnlyType?: boolean;
|
|
284
|
-
|
|
285
|
-
/** Label hiển thị trên button */
|
|
286
|
-
label?: string;
|
|
287
|
-
|
|
288
|
-
/** Disable button này */
|
|
289
|
-
disable?: boolean;
|
|
290
|
-
|
|
291
|
-
/** Class CSS bổ sung */
|
|
292
|
-
classInclude?: string;
|
|
293
|
-
|
|
294
|
-
/** Class icon bên trái */
|
|
295
|
-
classIconLeft?: string;
|
|
296
|
-
|
|
297
|
-
/** Class icon bên phải */
|
|
298
|
-
classIconRight?: string;
|
|
299
|
-
|
|
300
|
-
/** Class cho label */
|
|
301
|
-
classLabel?: string;
|
|
302
|
-
|
|
303
|
-
/** Cấu hình popover */
|
|
304
|
-
popover?: IPopover;
|
|
305
|
-
|
|
306
|
-
/** Không stop propagation event */
|
|
307
|
-
ignoreStopPropagationEvent?: boolean;
|
|
308
|
-
|
|
309
|
-
/** Z-index cho button */
|
|
310
|
-
zIndex?: number;
|
|
311
|
-
|
|
312
|
-
/** Trạng thái pending */
|
|
313
|
-
isPending?: boolean;
|
|
314
|
-
|
|
315
|
-
/** Action callback */
|
|
316
|
-
action?: (data?: any) => Promise<void>;
|
|
317
|
-
|
|
318
|
-
/** Style cho icon trái */
|
|
319
|
-
styleIconLeft?: Record<string, any>;
|
|
320
|
-
|
|
321
|
-
/** Style cho button */
|
|
322
|
-
styleButton?: Record<string, any>;
|
|
243
|
+
import { IButton } from '@libs-ui/components-buttons-button';
|
|
323
244
|
|
|
324
|
-
|
|
325
|
-
|
|
245
|
+
export interface IButton {
|
|
246
|
+
key?: string; // Định danh duy nhất cho button
|
|
247
|
+
type?: TYPE_BUTTON; // Bị override bởi component (xem Lưu ý quan trọng)
|
|
248
|
+
sizeButton?: TYPE_SIZE_BUTTON; // Kích thước button
|
|
249
|
+
iconOnlyType?: boolean; // Chỉ hiển thị icon, ẩn label
|
|
250
|
+
label?: string; // Nội dung text hiển thị
|
|
251
|
+
disable?: boolean; // Disable riêng button này
|
|
252
|
+
classInclude?: string; // Class CSS bổ sung cho button
|
|
253
|
+
classIconLeft?: string; // Class icon bên trái label
|
|
254
|
+
classIconRight?: string; // Class icon bên phải label
|
|
255
|
+
classLabel?: string; // Class CSS bổ sung cho label
|
|
256
|
+
popover?: IPopover; // Cấu hình popover của button
|
|
257
|
+
ignoreStopPropagationEvent?: boolean; // Không dừng propagation event
|
|
258
|
+
zIndex?: number; // z-index của button
|
|
259
|
+
isPending?: boolean; // Trạng thái loading/pending
|
|
260
|
+
action?: (data?: any) => Promise<void>; // Callback async tuỳ chỉnh
|
|
261
|
+
styleIconLeft?: Record<string, any>; // Inline style cho icon trái
|
|
262
|
+
styleButton?: Record<string, any>; // Inline style cho button
|
|
263
|
+
buttonCustom?: IColorButton; // Màu tuỳ chỉnh (khi type = 'button-custom')
|
|
326
264
|
}
|
|
327
265
|
```
|
|
328
266
|
|
|
329
267
|
### TYPE_BUTTON
|
|
330
268
|
|
|
331
269
|
```typescript
|
|
270
|
+
import { TYPE_BUTTON } from '@libs-ui/components-buttons-button';
|
|
271
|
+
|
|
332
272
|
export type TYPE_BUTTON =
|
|
333
273
|
| 'button-primary'
|
|
334
274
|
| 'button-primary-revert'
|
|
@@ -359,51 +299,37 @@ export type TYPE_BUTTON =
|
|
|
359
299
|
### TYPE_SIZE_BUTTON
|
|
360
300
|
|
|
361
301
|
```typescript
|
|
302
|
+
import { TYPE_SIZE_BUTTON } from '@libs-ui/components-buttons-button';
|
|
303
|
+
|
|
362
304
|
export type TYPE_SIZE_BUTTON = 'large' | 'medium' | 'small' | 'smaller';
|
|
363
305
|
```
|
|
364
306
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
Component tự động xử lý styling cho button group:
|
|
368
|
-
|
|
369
|
-
- **First button**: Border radius trái (top-left, bottom-left)
|
|
370
|
-
- **Middle buttons**: Không có border radius, border-left bị loại bỏ
|
|
371
|
-
- **Last button**: Border radius phải (top-right, bottom-right), border-left bị loại bỏ
|
|
372
|
-
- **Active button**: Sử dụng `button-primary` type
|
|
373
|
-
- **Inactive buttons**: Sử dụng `button-primary-revert` type
|
|
307
|
+
### IPopoverFunctionControlEvent
|
|
374
308
|
|
|
375
|
-
|
|
309
|
+
Import từ `@libs-ui/components-popover` (chỉ cần khi xử lý `(outFunctionsControl)`):
|
|
376
310
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
311
|
+
```typescript
|
|
312
|
+
import { IPopoverFunctionControlEvent } from '@libs-ui/components-popover';
|
|
313
|
+
|
|
314
|
+
export interface IPopoverFunctionControlEvent {
|
|
315
|
+
showPopover: (elementRef?: HTMLElement) => Promise<void>;
|
|
316
|
+
updatePopoverOverlayPosition: () => Promise<void>;
|
|
317
|
+
removePopoverOverlay: () => Promise<void>;
|
|
318
|
+
getRectContainer: () => Promise<IBoundingClientRect>;
|
|
319
|
+
getRectContent: () => Promise<IBoundingClientRect>;
|
|
320
|
+
updatePopoverOverlay: () => Promise<void>;
|
|
321
|
+
}
|
|
381
322
|
```
|
|
382
323
|
|
|
383
|
-
##
|
|
384
|
-
|
|
385
|
-
### Active State Management
|
|
386
|
-
|
|
387
|
-
- Khi click vào một button, nó sẽ trở thành active
|
|
388
|
-
- Click vào button đang active sẽ không có effect (không emit event)
|
|
389
|
-
- Index active được quản lý qua two-way binding `[(indexActive)]`
|
|
390
|
-
- Active button hiển thị với style `button-primary`
|
|
391
|
-
- Inactive buttons hiển thị với style `button-primary-revert`
|
|
324
|
+
## Lưu ý quan trọng
|
|
392
325
|
|
|
393
|
-
|
|
326
|
+
⚠️ **Type của button bị override tự động**: Component tự động đặt `type = 'button-primary'` cho button đang active và `type = 'button-primary-revert'` cho các button còn lại. Giá trị `type` trong `IButton.type` không có tác dụng khi dùng trong `buttons-group`.
|
|
394
327
|
|
|
395
|
-
-
|
|
396
|
-
- Khi button cụ thể có `disable: true`: Chỉ button đó bị disable
|
|
397
|
-
- Disabled buttons vẫn giữ border styling phù hợp với vị trí trong group
|
|
328
|
+
⚠️ **Index-based active state**: Component quản lý trạng thái active theo index (vị trí trong mảng), không theo `key`. Nếu mảng `buttons` thay đổi thứ tự phần tử, `indexActive` có thể trỏ sai button. Đảm bảo thứ tự mảng ổn định khi muốn giữ nguyên trạng thái active.
|
|
398
329
|
|
|
399
|
-
|
|
330
|
+
⚠️ **Click button đang active không emit event**: Khi người dùng click vào button có index trùng `indexActive()`, component bỏ qua và không emit `outChange`. Đây là behavior có chủ đích để tránh re-render không cần thiết.
|
|
400
331
|
|
|
401
|
-
|
|
402
|
-
| --------------- | ------- | ---------------- |
|
|
403
|
-
| Angular | 18+ | Framework |
|
|
404
|
-
| Angular Signals | - | State management |
|
|
405
|
-
| SCSS | - | Styling |
|
|
406
|
-
| OnPush | - | Change Detection |
|
|
332
|
+
⚠️ **`outChange` không truyền DOM Event**: Handler của `(outChange)` nhận `IButton` trực tiếp, không phải `Event` DOM — không cần và không thể gọi `event.stopPropagation()` trong handler này.
|
|
407
333
|
|
|
408
334
|
## Demo
|
|
409
335
|
|
|
@@ -411,75 +337,4 @@ Component sử dụng CSS variable:
|
|
|
411
337
|
npx nx serve core-ui
|
|
412
338
|
```
|
|
413
339
|
|
|
414
|
-
Truy cập:
|
|
415
|
-
|
|
416
|
-
## Unit Tests
|
|
417
|
-
|
|
418
|
-
```bash
|
|
419
|
-
# Chạy tests
|
|
420
|
-
npx nx test components-buttons-group
|
|
421
|
-
|
|
422
|
-
# Coverage
|
|
423
|
-
npx nx test components-buttons-group --coverage
|
|
424
|
-
|
|
425
|
-
# Watch mode
|
|
426
|
-
npx nx test components-buttons-group --watch
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
## Dependencies
|
|
430
|
-
|
|
431
|
-
- `@angular/core`: >=18.0.0
|
|
432
|
-
- `@libs-ui/components-buttons-button`: 0.2.355-14
|
|
433
|
-
- `@libs-ui/components-popover`: 0.2.355-14
|
|
434
|
-
- `@ngx-translate/core`: ^15.0.0
|
|
435
|
-
|
|
436
|
-
## Important Notes
|
|
437
|
-
|
|
438
|
-
### ⚠️ Type Override
|
|
439
|
-
|
|
440
|
-
Component tự động override `type` property của buttons:
|
|
441
|
-
|
|
442
|
-
- Active button → `button-primary`
|
|
443
|
-
- Inactive button → `button-primary-revert`
|
|
444
|
-
|
|
445
|
-
Nếu bạn muốn custom type, cần modify component source code.
|
|
446
|
-
|
|
447
|
-
### ⚠️ Border Styling
|
|
448
|
-
|
|
449
|
-
Component sử dụng `::ng-deep` để style nested components. Điều này cần thiết để style các button components bên trong nhưng có thể ảnh hưởng đến global styles nếu không cẩn thận.
|
|
450
|
-
|
|
451
|
-
### ⚠️ Index-based Active State
|
|
452
|
-
|
|
453
|
-
Component sử dụng index thay vì key để quản lý active state. Đảm bảo array `buttons` không thay đổi thứ tự nếu bạn muốn maintain active state.
|
|
454
|
-
|
|
455
|
-
## Best Practices
|
|
456
|
-
|
|
457
|
-
1. **Sử dụng key duy nhất**: Luôn cung cấp `key` unique cho mỗi button để dễ identify
|
|
458
|
-
2. **Limit số lượng buttons**: Nên giới hạn 3-5 buttons trong một group để UX tốt
|
|
459
|
-
3. **Consistent labels**: Sử dụng label ngắn gọn, rõ ràng và có độ dài tương đương
|
|
460
|
-
4. **Icon consistency**: Nếu dùng icon, nên dùng cho tất cả buttons hoặc không dùng
|
|
461
|
-
5. **Responsive design**: Cân nhắc sử dụng icon-only mode trên mobile
|
|
462
|
-
|
|
463
|
-
## Troubleshooting
|
|
464
|
-
|
|
465
|
-
### Button không chuyển active state
|
|
466
|
-
|
|
467
|
-
- Kiểm tra `[(indexActive)]` binding
|
|
468
|
-
- Đảm bảo không có logic nào block event handler
|
|
469
|
-
- Verify button không bị disable
|
|
470
|
-
|
|
471
|
-
### Border styling không đúng
|
|
472
|
-
|
|
473
|
-
- Kiểm tra ViewEncapsulation của parent component
|
|
474
|
-
- Verify CSS variables được define
|
|
475
|
-
- Check xem có CSS conflicts không
|
|
476
|
-
|
|
477
|
-
### Popover không hoạt động
|
|
478
|
-
|
|
479
|
-
- Đảm bảo đã import `@libs-ui/components-popover`
|
|
480
|
-
- Verify popover config đúng format
|
|
481
|
-
- Check z-index conflicts
|
|
482
|
-
|
|
483
|
-
## License
|
|
484
|
-
|
|
485
|
-
MIT
|
|
340
|
+
Truy cập: http://localhost:4500/components/buttons/group
|
|
@@ -27,10 +27,10 @@ export class LibsUiComponentsButtonsGroupComponent {
|
|
|
27
27
|
return this.functionsControlPopover();
|
|
28
28
|
}
|
|
29
29
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsButtonsGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
30
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LibsUiComponentsButtonsGroupComponent, isStandalone: true, selector: "libs_ui-components-buttons-group", inputs: { buttons: { classPropertyName: "buttons", publicName: "buttons", isSignal: true, isRequired: true, transformFunction: null }, indexActive: { classPropertyName: "indexActive", publicName: "indexActive", isSignal: true, isRequired: false, transformFunction: null }, disable: { classPropertyName: "disable", publicName: "disable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { indexActive: "indexActiveChange", outChange: "outChange", outFunctionsControl: "outFunctionsControl" }, ngImport: i0, template: "<div class=\"libs-ui-buttons-group\">\n @for (button of buttons(); track button) {\n <libs_ui-components-buttons-button\n [type]=\"indexActive() === $index ? 'button-primary' : 'button-primary-revert'\"\n [label]=\"button.label || ''\"\n [disable]=\"disable() || button.disable || false\"\n [classIconLeft]=\"button.classIconLeft || ''\"\n [classInclude]=\"button.classInclude || ''\"\n [classIconRight]=\"button.classIconRight || ''\"\n [popover]=\"button.popover || {}\"\n (outFunctionsControl)=\"handlerFunctionsControl($event)\"\n (outClick)=\"handlerClickButton($index, button)\" />\n }\n</div>\n", styles: [":host ::ng-deep .libs-ui-buttons-group{display:flex}:host ::ng-deep .libs-ui-buttons-group .libs-ui-button-disable{border:1px solid var(--libs-ui-button-other-color-border, #226ff5)!important}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button:hover{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button-disable{border-left:0!important}:host ::ng-deep .libs-ui-buttons-group>:first-child libs_ui-components-popover .libs-ui-button{border-radius:4px 0 0 4px}:host ::ng-deep .libs-ui-buttons-group>:last-child libs_ui-components-popover .libs-ui-button{border-left:0!important;border-radius:0 4px 4px 0}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "component", type: LibsUiComponentsButtonsButtonComponent, selector: "libs_ui-components-buttons-button", inputs: ["flagMouse", "type", "buttonCustom", "sizeButton", "label", "disable", "isPending", "imageLeft", "classInclude", "classIconLeft", "classIconRight", "classLabel", "iconOnlyType", "popover", "ignoreStopPropagationEvent", "zIndex", "widthLabelPopover", "styleIconLeft", "styleButton", "ignoreFocusWhenInputTab", "ignoreSetClickWhenShowPopover", "ignorePointerEvent", "isActive", "isHandlerEnterDocumentClickButton"], outputs: ["outClick", "outPopoverEvent", "outFunctionsControl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
30
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LibsUiComponentsButtonsGroupComponent, isStandalone: true, selector: "libs_ui-components-buttons-group", inputs: { buttons: { classPropertyName: "buttons", publicName: "buttons", isSignal: true, isRequired: true, transformFunction: null }, indexActive: { classPropertyName: "indexActive", publicName: "indexActive", isSignal: true, isRequired: false, transformFunction: null }, disable: { classPropertyName: "disable", publicName: "disable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { indexActive: "indexActiveChange", outChange: "outChange", outFunctionsControl: "outFunctionsControl" }, ngImport: i0, template: "<div class=\"libs-ui-buttons-group\">\n @for (button of buttons(); track button) {\n <libs_ui-components-buttons-button\n [type]=\"indexActive() === $index ? 'button-primary' : 'button-primary-revert'\"\n [label]=\"button.label || ''\"\n [disable]=\"disable() || button.disable || false\"\n [classIconLeft]=\"button.classIconLeft || ''\"\n [classInclude]=\"button.classInclude || ''\"\n [classIconRight]=\"button.classIconRight || ''\"\n [popover]=\"button.popover || {}\"\n [iconOnlyType]=\"button.iconOnlyType || false\"\n (outFunctionsControl)=\"handlerFunctionsControl($event)\"\n (outClick)=\"handlerClickButton($index, button)\" />\n }\n</div>\n", styles: [":host ::ng-deep .libs-ui-buttons-group{display:flex}:host ::ng-deep .libs-ui-buttons-group .libs-ui-button-disable{border:1px solid var(--libs-ui-button-other-color-border, #226ff5)!important}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button:hover{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button-disable{border-left:0!important}:host ::ng-deep .libs-ui-buttons-group>:first-child libs_ui-components-popover .libs-ui-button{border-radius:4px 0 0 4px}:host ::ng-deep .libs-ui-buttons-group>:last-child libs_ui-components-popover .libs-ui-button{border-left:0!important;border-radius:0 4px 4px 0}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "component", type: LibsUiComponentsButtonsButtonComponent, selector: "libs_ui-components-buttons-button", inputs: ["flagMouse", "type", "buttonCustom", "sizeButton", "label", "disable", "isPending", "imageLeft", "classInclude", "classIconLeft", "classIconRight", "classLabel", "iconOnlyType", "popover", "ignoreStopPropagationEvent", "zIndex", "widthLabelPopover", "styleIconLeft", "styleButton", "ignoreFocusWhenInputTab", "ignoreSetClickWhenShowPopover", "ignorePointerEvent", "isActive", "isHandlerEnterDocumentClickButton"], outputs: ["outClick", "outPopoverEvent", "outFunctionsControl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
31
31
|
}
|
|
32
32
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsButtonsGroupComponent, decorators: [{
|
|
33
33
|
type: Component,
|
|
34
|
-
args: [{ selector: 'libs_ui-components-buttons-group', standalone: true, imports: [TranslateModule, LibsUiComponentsButtonsButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"libs-ui-buttons-group\">\n @for (button of buttons(); track button) {\n <libs_ui-components-buttons-button\n [type]=\"indexActive() === $index ? 'button-primary' : 'button-primary-revert'\"\n [label]=\"button.label || ''\"\n [disable]=\"disable() || button.disable || false\"\n [classIconLeft]=\"button.classIconLeft || ''\"\n [classInclude]=\"button.classInclude || ''\"\n [classIconRight]=\"button.classIconRight || ''\"\n [popover]=\"button.popover || {}\"\n (outFunctionsControl)=\"handlerFunctionsControl($event)\"\n (outClick)=\"handlerClickButton($index, button)\" />\n }\n</div>\n", styles: [":host ::ng-deep .libs-ui-buttons-group{display:flex}:host ::ng-deep .libs-ui-buttons-group .libs-ui-button-disable{border:1px solid var(--libs-ui-button-other-color-border, #226ff5)!important}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button:hover{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button-disable{border-left:0!important}:host ::ng-deep .libs-ui-buttons-group>:first-child libs_ui-components-popover .libs-ui-button{border-radius:4px 0 0 4px}:host ::ng-deep .libs-ui-buttons-group>:last-child libs_ui-components-popover .libs-ui-button{border-left:0!important;border-radius:0 4px 4px 0}\n"] }]
|
|
34
|
+
args: [{ selector: 'libs_ui-components-buttons-group', standalone: true, imports: [TranslateModule, LibsUiComponentsButtonsButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"libs-ui-buttons-group\">\n @for (button of buttons(); track button) {\n <libs_ui-components-buttons-button\n [type]=\"indexActive() === $index ? 'button-primary' : 'button-primary-revert'\"\n [label]=\"button.label || ''\"\n [disable]=\"disable() || button.disable || false\"\n [classIconLeft]=\"button.classIconLeft || ''\"\n [classInclude]=\"button.classInclude || ''\"\n [classIconRight]=\"button.classIconRight || ''\"\n [popover]=\"button.popover || {}\"\n [iconOnlyType]=\"button.iconOnlyType || false\"\n (outFunctionsControl)=\"handlerFunctionsControl($event)\"\n (outClick)=\"handlerClickButton($index, button)\" />\n }\n</div>\n", styles: [":host ::ng-deep .libs-ui-buttons-group{display:flex}:host ::ng-deep .libs-ui-buttons-group .libs-ui-button-disable{border:1px solid var(--libs-ui-button-other-color-border, #226ff5)!important}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button:hover{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button-disable{border-left:0!important}:host ::ng-deep .libs-ui-buttons-group>:first-child libs_ui-components-popover .libs-ui-button{border-radius:4px 0 0 4px}:host ::ng-deep .libs-ui-buttons-group>:last-child libs_ui-components-popover .libs-ui-button{border-left:0!important;border-radius:0 4px 4px 0}\n"] }]
|
|
35
35
|
}] });
|
|
36
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
36
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JvdXAuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy11aS9jb21wb25lbnRzL2J1dHRvbnMvZ3JvdXAvc3JjL2dyb3VwLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9idXR0b25zL2dyb3VwL3NyYy9ncm91cC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRyxPQUFPLEVBQVcsc0NBQXNDLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUVyRyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7O0FBV3RELE1BQU0sT0FBTyxxQ0FBcUM7SUFDL0IsdUJBQXVCLEdBQUcsTUFBTSxDQUEyQyxTQUFTLENBQUMsQ0FBQztJQUV2RyxnQkFBZ0I7SUFDUCxPQUFPLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBa0IsQ0FBQztJQUMzQyxXQUFXLEdBQUcsS0FBSyxDQUFTLENBQUMsQ0FBQyxDQUFDO0lBQy9CLE9BQU8sR0FBRyxLQUFLLENBQVUsS0FBSyxDQUFDLENBQUM7SUFFekMsaUJBQWlCO0lBQ1IsU0FBUyxHQUFHLE1BQU0sRUFBVyxDQUFDO0lBQzlCLG1CQUFtQixHQUFHLE1BQU0sRUFBZ0MsQ0FBQztJQUV0RSxlQUFlO0lBQ0wsS0FBSyxDQUFDLGtCQUFrQixDQUFDLEtBQWEsRUFBRSxNQUFlO1FBQy9ELElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxLQUFLLEtBQUssRUFBRSxDQUFDO1lBQ2pDLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDNUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUVTLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxPQUFxQztRQUMzRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVELElBQVcsZ0JBQWdCO1FBQ3pCLE9BQU8sSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7SUFDeEMsQ0FBQzt3R0E1QlUscUNBQXFDOzRGQUFyQyxxQ0FBcUMsZ21CQ2RsRCxvc0JBZUEsdzhCREpZLGVBQWUsK0JBQUUsc0NBQXNDOzs0RkFHdEQscUNBQXFDO2tCQVRqRCxTQUFTOytCQUVFLGtDQUFrQyxjQUdoQyxJQUFJLFdBQ1AsQ0FBQyxlQUFlLEVBQUUsc0NBQXNDLENBQUMsbUJBQ2pELHVCQUF1QixDQUFDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBpbnB1dCwgbW9kZWwsIG91dHB1dCwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJQnV0dG9uLCBMaWJzVWlDb21wb25lbnRzQnV0dG9uc0J1dHRvbkNvbXBvbmVudCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtYnV0dG9ucy1idXR0b24nO1xuaW1wb3J0IHsgSVBvcG92ZXJGdW5jdGlvbkNvbnRyb2xFdmVudCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtcG9wb3Zlcic7XG5pbXBvcnQgeyBUcmFuc2xhdGVNb2R1bGUgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcblxuQENvbXBvbmVudCh7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvY29tcG9uZW50LXNlbGVjdG9yXG4gIHNlbGVjdG9yOiAnbGlic191aS1jb21wb25lbnRzLWJ1dHRvbnMtZ3JvdXAnLFxuICB0ZW1wbGF0ZVVybDogJy4vZ3JvdXAuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vZ3JvdXAuY29tcG9uZW50LnNjc3MnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbVHJhbnNsYXRlTW9kdWxlLCBMaWJzVWlDb21wb25lbnRzQnV0dG9uc0J1dHRvbkNvbXBvbmVudF0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBMaWJzVWlDb21wb25lbnRzQnV0dG9uc0dyb3VwQ29tcG9uZW50IHtcbiAgcHJpdmF0ZSByZWFkb25seSBmdW5jdGlvbnNDb250cm9sUG9wb3ZlciA9IHNpZ25hbDxJUG9wb3ZlckZ1bmN0aW9uQ29udHJvbEV2ZW50IHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuXG4gIC8vICNyZWdpb24gSU5QVVRcbiAgcmVhZG9ubHkgYnV0dG9ucyA9IGlucHV0LnJlcXVpcmVkPEFycmF5PElCdXR0b24+PigpO1xuICByZWFkb25seSBpbmRleEFjdGl2ZSA9IG1vZGVsPG51bWJlcj4oMCk7XG4gIHJlYWRvbmx5IGRpc2FibGUgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XG5cbiAgLy8gI3JlZ2lvbiBPVVRQVVRcbiAgcmVhZG9ubHkgb3V0Q2hhbmdlID0gb3V0cHV0PElCdXR0b24+KCk7XG4gIHJlYWRvbmx5IG91dEZ1bmN0aW9uc0NvbnRyb2wgPSBvdXRwdXQ8SVBvcG92ZXJGdW5jdGlvbkNvbnRyb2xFdmVudD4oKTtcblxuICAvKiBGVU5DVElPTlMgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJDbGlja0J1dHRvbihpbmRleDogbnVtYmVyLCBidXR0b246IElCdXR0b24pIHtcbiAgICBpZiAodGhpcy5pbmRleEFjdGl2ZSgpID09PSBpbmRleCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmluZGV4QWN0aXZlLnNldChpbmRleCk7XG4gICAgdGhpcy5vdXRDaGFuZ2UuZW1pdChidXR0b24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJGdW5jdGlvbnNDb250cm9sKGNvbnRyb2w6IElQb3BvdmVyRnVuY3Rpb25Db250cm9sRXZlbnQpIHtcbiAgICB0aGlzLm91dEZ1bmN0aW9uc0NvbnRyb2wuZW1pdChjb250cm9sKTtcbiAgICB0aGlzLmZ1bmN0aW9uc0NvbnRyb2xQb3BvdmVyLnNldChjb250cm9sKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgRnVuY3Rpb25zQ29udHJvbCgpOiBJUG9wb3ZlckZ1bmN0aW9uQ29udHJvbEV2ZW50IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5mdW5jdGlvbnNDb250cm9sUG9wb3ZlcigpO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwibGlicy11aS1idXR0b25zLWdyb3VwXCI+XG4gIEBmb3IgKGJ1dHRvbiBvZiBidXR0b25zKCk7IHRyYWNrIGJ1dHRvbikge1xuICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtYnV0dG9ucy1idXR0b25cbiAgICAgIFt0eXBlXT1cImluZGV4QWN0aXZlKCkgPT09ICRpbmRleCA/ICdidXR0b24tcHJpbWFyeScgOiAnYnV0dG9uLXByaW1hcnktcmV2ZXJ0J1wiXG4gICAgICBbbGFiZWxdPVwiYnV0dG9uLmxhYmVsIHx8ICcnXCJcbiAgICAgIFtkaXNhYmxlXT1cImRpc2FibGUoKSB8fCBidXR0b24uZGlzYWJsZSB8fCBmYWxzZVwiXG4gICAgICBbY2xhc3NJY29uTGVmdF09XCJidXR0b24uY2xhc3NJY29uTGVmdCB8fCAnJ1wiXG4gICAgICBbY2xhc3NJbmNsdWRlXT1cImJ1dHRvbi5jbGFzc0luY2x1ZGUgfHwgJydcIlxuICAgICAgW2NsYXNzSWNvblJpZ2h0XT1cImJ1dHRvbi5jbGFzc0ljb25SaWdodCB8fCAnJ1wiXG4gICAgICBbcG9wb3Zlcl09XCJidXR0b24ucG9wb3ZlciB8fCB7fVwiXG4gICAgICBbaWNvbk9ubHlUeXBlXT1cImJ1dHRvbi5pY29uT25seVR5cGUgfHwgZmFsc2VcIlxuICAgICAgKG91dEZ1bmN0aW9uc0NvbnRyb2wpPVwiaGFuZGxlckZ1bmN0aW9uc0NvbnRyb2woJGV2ZW50KVwiXG4gICAgICAob3V0Q2xpY2spPVwiaGFuZGxlckNsaWNrQnV0dG9uKCRpbmRleCwgYnV0dG9uKVwiIC8+XG4gIH1cbjwvZGl2PlxuIl19
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, input, model, output,
|
|
2
|
+
import { signal, input, model, output, Component, ChangeDetectionStrategy } from '@angular/core';
|
|
3
3
|
import { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';
|
|
4
4
|
import { TranslateModule } from '@ngx-translate/core';
|
|
5
5
|
|
|
@@ -28,11 +28,11 @@ class LibsUiComponentsButtonsGroupComponent {
|
|
|
28
28
|
return this.functionsControlPopover();
|
|
29
29
|
}
|
|
30
30
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsButtonsGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
31
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LibsUiComponentsButtonsGroupComponent, isStandalone: true, selector: "libs_ui-components-buttons-group", inputs: { buttons: { classPropertyName: "buttons", publicName: "buttons", isSignal: true, isRequired: true, transformFunction: null }, indexActive: { classPropertyName: "indexActive", publicName: "indexActive", isSignal: true, isRequired: false, transformFunction: null }, disable: { classPropertyName: "disable", publicName: "disable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { indexActive: "indexActiveChange", outChange: "outChange", outFunctionsControl: "outFunctionsControl" }, ngImport: i0, template: "<div class=\"libs-ui-buttons-group\">\n @for (button of buttons(); track button) {\n <libs_ui-components-buttons-button\n [type]=\"indexActive() === $index ? 'button-primary' : 'button-primary-revert'\"\n [label]=\"button.label || ''\"\n [disable]=\"disable() || button.disable || false\"\n [classIconLeft]=\"button.classIconLeft || ''\"\n [classInclude]=\"button.classInclude || ''\"\n [classIconRight]=\"button.classIconRight || ''\"\n [popover]=\"button.popover || {}\"\n (outFunctionsControl)=\"handlerFunctionsControl($event)\"\n (outClick)=\"handlerClickButton($index, button)\" />\n }\n</div>\n", styles: [":host ::ng-deep .libs-ui-buttons-group{display:flex}:host ::ng-deep .libs-ui-buttons-group .libs-ui-button-disable{border:1px solid var(--libs-ui-button-other-color-border, #226ff5)!important}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button:hover{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button-disable{border-left:0!important}:host ::ng-deep .libs-ui-buttons-group>:first-child libs_ui-components-popover .libs-ui-button{border-radius:4px 0 0 4px}:host ::ng-deep .libs-ui-buttons-group>:last-child libs_ui-components-popover .libs-ui-button{border-left:0!important;border-radius:0 4px 4px 0}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "component", type: LibsUiComponentsButtonsButtonComponent, selector: "libs_ui-components-buttons-button", inputs: ["flagMouse", "type", "buttonCustom", "sizeButton", "label", "disable", "isPending", "imageLeft", "classInclude", "classIconLeft", "classIconRight", "classLabel", "iconOnlyType", "popover", "ignoreStopPropagationEvent", "zIndex", "widthLabelPopover", "styleIconLeft", "styleButton", "ignoreFocusWhenInputTab", "ignoreSetClickWhenShowPopover", "ignorePointerEvent", "isActive", "isHandlerEnterDocumentClickButton"], outputs: ["outClick", "outPopoverEvent", "outFunctionsControl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
31
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LibsUiComponentsButtonsGroupComponent, isStandalone: true, selector: "libs_ui-components-buttons-group", inputs: { buttons: { classPropertyName: "buttons", publicName: "buttons", isSignal: true, isRequired: true, transformFunction: null }, indexActive: { classPropertyName: "indexActive", publicName: "indexActive", isSignal: true, isRequired: false, transformFunction: null }, disable: { classPropertyName: "disable", publicName: "disable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { indexActive: "indexActiveChange", outChange: "outChange", outFunctionsControl: "outFunctionsControl" }, ngImport: i0, template: "<div class=\"libs-ui-buttons-group\">\n @for (button of buttons(); track button) {\n <libs_ui-components-buttons-button\n [type]=\"indexActive() === $index ? 'button-primary' : 'button-primary-revert'\"\n [label]=\"button.label || ''\"\n [disable]=\"disable() || button.disable || false\"\n [classIconLeft]=\"button.classIconLeft || ''\"\n [classInclude]=\"button.classInclude || ''\"\n [classIconRight]=\"button.classIconRight || ''\"\n [popover]=\"button.popover || {}\"\n [iconOnlyType]=\"button.iconOnlyType || false\"\n (outFunctionsControl)=\"handlerFunctionsControl($event)\"\n (outClick)=\"handlerClickButton($index, button)\" />\n }\n</div>\n", styles: [":host ::ng-deep .libs-ui-buttons-group{display:flex}:host ::ng-deep .libs-ui-buttons-group .libs-ui-button-disable{border:1px solid var(--libs-ui-button-other-color-border, #226ff5)!important}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button:hover{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button-disable{border-left:0!important}:host ::ng-deep .libs-ui-buttons-group>:first-child libs_ui-components-popover .libs-ui-button{border-radius:4px 0 0 4px}:host ::ng-deep .libs-ui-buttons-group>:last-child libs_ui-components-popover .libs-ui-button{border-left:0!important;border-radius:0 4px 4px 0}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "component", type: LibsUiComponentsButtonsButtonComponent, selector: "libs_ui-components-buttons-button", inputs: ["flagMouse", "type", "buttonCustom", "sizeButton", "label", "disable", "isPending", "imageLeft", "classInclude", "classIconLeft", "classIconRight", "classLabel", "iconOnlyType", "popover", "ignoreStopPropagationEvent", "zIndex", "widthLabelPopover", "styleIconLeft", "styleButton", "ignoreFocusWhenInputTab", "ignoreSetClickWhenShowPopover", "ignorePointerEvent", "isActive", "isHandlerEnterDocumentClickButton"], outputs: ["outClick", "outPopoverEvent", "outFunctionsControl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
32
32
|
}
|
|
33
33
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsButtonsGroupComponent, decorators: [{
|
|
34
34
|
type: Component,
|
|
35
|
-
args: [{ selector: 'libs_ui-components-buttons-group', standalone: true, imports: [TranslateModule, LibsUiComponentsButtonsButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"libs-ui-buttons-group\">\n @for (button of buttons(); track button) {\n <libs_ui-components-buttons-button\n [type]=\"indexActive() === $index ? 'button-primary' : 'button-primary-revert'\"\n [label]=\"button.label || ''\"\n [disable]=\"disable() || button.disable || false\"\n [classIconLeft]=\"button.classIconLeft || ''\"\n [classInclude]=\"button.classInclude || ''\"\n [classIconRight]=\"button.classIconRight || ''\"\n [popover]=\"button.popover || {}\"\n (outFunctionsControl)=\"handlerFunctionsControl($event)\"\n (outClick)=\"handlerClickButton($index, button)\" />\n }\n</div>\n", styles: [":host ::ng-deep .libs-ui-buttons-group{display:flex}:host ::ng-deep .libs-ui-buttons-group .libs-ui-button-disable{border:1px solid var(--libs-ui-button-other-color-border, #226ff5)!important}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button:hover{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button-disable{border-left:0!important}:host ::ng-deep .libs-ui-buttons-group>:first-child libs_ui-components-popover .libs-ui-button{border-radius:4px 0 0 4px}:host ::ng-deep .libs-ui-buttons-group>:last-child libs_ui-components-popover .libs-ui-button{border-left:0!important;border-radius:0 4px 4px 0}\n"] }]
|
|
35
|
+
args: [{ selector: 'libs_ui-components-buttons-group', standalone: true, imports: [TranslateModule, LibsUiComponentsButtonsButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"libs-ui-buttons-group\">\n @for (button of buttons(); track button) {\n <libs_ui-components-buttons-button\n [type]=\"indexActive() === $index ? 'button-primary' : 'button-primary-revert'\"\n [label]=\"button.label || ''\"\n [disable]=\"disable() || button.disable || false\"\n [classIconLeft]=\"button.classIconLeft || ''\"\n [classInclude]=\"button.classInclude || ''\"\n [classIconRight]=\"button.classIconRight || ''\"\n [popover]=\"button.popover || {}\"\n [iconOnlyType]=\"button.iconOnlyType || false\"\n (outFunctionsControl)=\"handlerFunctionsControl($event)\"\n (outClick)=\"handlerClickButton($index, button)\" />\n }\n</div>\n", styles: [":host ::ng-deep .libs-ui-buttons-group{display:flex}:host ::ng-deep .libs-ui-buttons-group .libs-ui-button-disable{border:1px solid var(--libs-ui-button-other-color-border, #226ff5)!important}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button:hover{border-radius:0;border-left:0}:host ::ng-deep .libs-ui-buttons-group>:not(:first-child):not(:last-child) libs_ui-components-popover .libs-ui-button-disable{border-left:0!important}:host ::ng-deep .libs-ui-buttons-group>:first-child libs_ui-components-popover .libs-ui-button{border-radius:4px 0 0 4px}:host ::ng-deep .libs-ui-buttons-group>:last-child libs_ui-components-popover .libs-ui-button{border-left:0!important;border-radius:0 4px 4px 0}\n"] }]
|
|
36
36
|
}] });
|
|
37
37
|
|
|
38
38
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libs-ui-components-buttons-group.mjs","sources":["../../../../../../libs-ui/components/buttons/group/src/group.component.ts","../../../../../../libs-ui/components/buttons/group/src/group.component.html","../../../../../../libs-ui/components/buttons/group/src/libs-ui-components-buttons-group.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input, model, output, signal } from '@angular/core';\nimport { IButton, LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';\nimport { IPopoverFunctionControlEvent } from '@libs-ui/components-popover';\nimport { TranslateModule } from '@ngx-translate/core';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'libs_ui-components-buttons-group',\n templateUrl: './group.component.html',\n styleUrl: './group.component.scss',\n standalone: true,\n imports: [TranslateModule, LibsUiComponentsButtonsButtonComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class LibsUiComponentsButtonsGroupComponent {\n private functionsControlPopover = signal<IPopoverFunctionControlEvent | undefined>(undefined);\n\n // #region INPUT\n readonly buttons = input.required<Array<IButton>>();\n readonly indexActive = model<number>(0);\n readonly disable = input<boolean>(false);\n\n // #region OUTPUT\n readonly outChange = output<IButton>();\n readonly outFunctionsControl = output<IPopoverFunctionControlEvent>();\n\n /* FUNCTIONS */\n protected async handlerClickButton(index: number, button: IButton) {\n if (this.indexActive() === index) {\n return;\n }\n this.indexActive.set(index);\n this.outChange.emit(button);\n }\n\n protected async handlerFunctionsControl(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","<div class=\"libs-ui-buttons-group\">\n @for (button of buttons(); track button) {\n <libs_ui-components-buttons-button\n [type]=\"indexActive() === $index ? 'button-primary' : 'button-primary-revert'\"\n [label]=\"button.label || ''\"\n [disable]=\"disable() || button.disable || false\"\n [classIconLeft]=\"button.classIconLeft || ''\"\n [classInclude]=\"button.classInclude || ''\"\n [classIconRight]=\"button.classIconRight || ''\"\n [popover]=\"button.popover || {}\"\n (outFunctionsControl)=\"handlerFunctionsControl($event)\"\n (outClick)=\"handlerClickButton($index, button)\" />\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;MAca,qCAAqC,CAAA;
|
|
1
|
+
{"version":3,"file":"libs-ui-components-buttons-group.mjs","sources":["../../../../../../libs-ui/components/buttons/group/src/group.component.ts","../../../../../../libs-ui/components/buttons/group/src/group.component.html","../../../../../../libs-ui/components/buttons/group/src/libs-ui-components-buttons-group.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input, model, output, signal } from '@angular/core';\nimport { IButton, LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';\nimport { IPopoverFunctionControlEvent } from '@libs-ui/components-popover';\nimport { TranslateModule } from '@ngx-translate/core';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'libs_ui-components-buttons-group',\n templateUrl: './group.component.html',\n styleUrl: './group.component.scss',\n standalone: true,\n imports: [TranslateModule, LibsUiComponentsButtonsButtonComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class LibsUiComponentsButtonsGroupComponent {\n private readonly functionsControlPopover = signal<IPopoverFunctionControlEvent | undefined>(undefined);\n\n // #region INPUT\n readonly buttons = input.required<Array<IButton>>();\n readonly indexActive = model<number>(0);\n readonly disable = input<boolean>(false);\n\n // #region OUTPUT\n readonly outChange = output<IButton>();\n readonly outFunctionsControl = output<IPopoverFunctionControlEvent>();\n\n /* FUNCTIONS */\n protected async handlerClickButton(index: number, button: IButton) {\n if (this.indexActive() === index) {\n return;\n }\n this.indexActive.set(index);\n this.outChange.emit(button);\n }\n\n protected async handlerFunctionsControl(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","<div class=\"libs-ui-buttons-group\">\n @for (button of buttons(); track button) {\n <libs_ui-components-buttons-button\n [type]=\"indexActive() === $index ? 'button-primary' : 'button-primary-revert'\"\n [label]=\"button.label || ''\"\n [disable]=\"disable() || button.disable || false\"\n [classIconLeft]=\"button.classIconLeft || ''\"\n [classInclude]=\"button.classInclude || ''\"\n [classIconRight]=\"button.classIconRight || ''\"\n [popover]=\"button.popover || {}\"\n [iconOnlyType]=\"button.iconOnlyType || false\"\n (outFunctionsControl)=\"handlerFunctionsControl($event)\"\n (outClick)=\"handlerClickButton($index, button)\" />\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;MAca,qCAAqC,CAAA;AAC/B,IAAA,uBAAuB,GAAG,MAAM,CAA2C,SAAS,CAAC,CAAC;;AAG9F,IAAA,OAAO,GAAG,KAAK,CAAC,QAAQ,EAAkB,CAAC;AAC3C,IAAA,WAAW,GAAG,KAAK,CAAS,CAAC,CAAC,CAAC;AAC/B,IAAA,OAAO,GAAG,KAAK,CAAU,KAAK,CAAC,CAAC;;IAGhC,SAAS,GAAG,MAAM,EAAW,CAAC;IAC9B,mBAAmB,GAAG,MAAM,EAAgC,CAAC;;AAG5D,IAAA,MAAM,kBAAkB,CAAC,KAAa,EAAE,MAAe,EAAA;AAC/D,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE;YAChC,OAAO;SACR;AACD,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC5B,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;KAC7B;IAES,MAAM,uBAAuB,CAAC,OAAqC,EAAA;AAC3E,QAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACvC,QAAA,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;KAC3C;AAED,IAAA,IAAW,gBAAgB,GAAA;AACzB,QAAA,OAAO,IAAI,CAAC,uBAAuB,EAAE,CAAC;KACvC;wGA5BU,qCAAqC,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAArC,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,qCAAqC,ECdlD,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,kCAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,mBAAA,EAAA,SAAA,EAAA,WAAA,EAAA,mBAAA,EAAA,qBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,osBAeA,EDJY,MAAA,EAAA,CAAA,i5BAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,eAAe,+BAAE,sCAAsC,EAAA,QAAA,EAAA,mCAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,MAAA,EAAA,cAAA,EAAA,YAAA,EAAA,OAAA,EAAA,SAAA,EAAA,WAAA,EAAA,WAAA,EAAA,cAAA,EAAA,eAAA,EAAA,gBAAA,EAAA,YAAA,EAAA,cAAA,EAAA,SAAA,EAAA,4BAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,eAAA,EAAA,aAAA,EAAA,yBAAA,EAAA,+BAAA,EAAA,oBAAA,EAAA,UAAA,EAAA,mCAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,EAAA,iBAAA,EAAA,qBAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGtD,qCAAqC,EAAA,UAAA,EAAA,CAAA;kBATjD,SAAS;+BAEE,kCAAkC,EAAA,UAAA,EAGhC,IAAI,EAAA,OAAA,EACP,CAAC,eAAe,EAAE,sCAAsC,CAAC,EAAA,eAAA,EACjD,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,osBAAA,EAAA,MAAA,EAAA,CAAA,i5BAAA,CAAA,EAAA,CAAA;;;AEZjD;;AAEG;;;;"}
|
package/group.component.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { IButton } from '@libs-ui/components-buttons-button';
|
|
|
2
2
|
import { IPopoverFunctionControlEvent } from '@libs-ui/components-popover';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
export declare class LibsUiComponentsButtonsGroupComponent {
|
|
5
|
-
private functionsControlPopover;
|
|
5
|
+
private readonly functionsControlPopover;
|
|
6
6
|
readonly buttons: import("@angular/core").InputSignal<IButton[]>;
|
|
7
7
|
readonly indexActive: import("@angular/core").ModelSignal<number>;
|
|
8
8
|
readonly disable: import("@angular/core").InputSignal<boolean>;
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libs-ui/components-buttons-group",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.357-1",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@angular/core": ">=18.0.0",
|
|
6
|
-
"@libs-ui/components-buttons-button": "0.2.
|
|
7
|
-
"@libs-ui/components-popover": "0.2.
|
|
6
|
+
"@libs-ui/components-buttons-button": "0.2.357-1",
|
|
7
|
+
"@libs-ui/components-popover": "0.2.357-1",
|
|
8
8
|
"@ngx-translate/core": "^15.0.0"
|
|
9
9
|
},
|
|
10
10
|
"sideEffects": false,
|