@libs-ui/components-radio-group 0.2.356-9 → 0.2.357-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,136 +1,371 @@
1
1
  # @libs-ui/components-radio-group
2
2
 
3
- > Component hiển thị nhóm các lựa chọn Radio buttons, hỗ trợ layout ngang/dọc, validation và custom template.
3
+ > Nhóm radio buttons hỗ trợ layout ngang/dọc, validation required sub-content tùy chỉnh theo từng item.
4
4
 
5
5
  ## Giới thiệu
6
6
 
7
- `LibsUiComponentsRadioGroupComponent` là một standalone Angular component cho phép người dùng chọn một mục duy nhất từ một danh sách các tuỳ chọn. Component này được thiết kế để thay thế cho thẻ `<input type="radio">` mặc định, với nhiều tính năng nâng cao như validation, cấu hình label chung, hỗ trợ template tuỳ chỉnh, và layout linh hoạt.
7
+ `LibsUiComponentsRadioGroupComponent` là standalone Angular component cho phép người dùng chọn một mục duy nhất từ danh sách các tùy chọn. Component tích hợp Angular Signals, OnPush change detection, hỗ trợ validation required với thông báo lỗi, cấu hình label chung, sub-text/template cho từng item, và cung cấp API điều khiển bên ngoài thông qua `outFunctionsControl`.
8
8
 
9
- ### Tính năng
9
+ ## Tính năng
10
10
 
11
- - ✅ **Flexible Layout**: Hỗ trợ hiển thị theo chiều dọc (mặc định) hoặc chiều ngang (`horizontal`).
12
- - ✅ **Rich Content**: Hỗ trợ hiển thị Label, Description, Sub-text, Custom Template cho từng item.
13
- - ✅ **Validation Support**: Tích hợp validation `required` hiển thị thông báo lỗi.
14
- - ✅ **Global Config**: Cấu hình chung cho toàn bộ group (disable, label, class).
15
- - ✅ **Reactive**: Tích hợp chặt chẽ với Angular Signals Forms.
16
- - ✅ **Control API**: Cung cấp API để kiểm soát validation và reset state từ bên ngoài.
11
+ - ✅ **Layout linh hoạt**: Hiển thị theo chiều dọc (mặc định) hoặc chiều ngang với `[horizontal]="true"`.
12
+ - ✅ **Validation required**: Hiển thị thông báo lỗi khi chưa chọn, hỗ trợ i18n interpolate params.
13
+ - ✅ **Label tích hợp**: Cấu hình label toàn group qua `[labelConfig]` (required, description, buttons, popover...).
14
+ - ✅ **Sub-content per item**: Hiển thị `subText` (i18n) hoặc `subTemplate` (TemplateRef) bên dưới mỗi radio khi được chọn.
15
+ - ✅ **Disable linh hoạt**: Disable toàn group (`[disable]`) hoặc từng item theo danh sách key (`[keysDisable]`).
16
+ - ✅ **Programmatic control**: Emit `IRadioGroupFunctionControlEvent` để gọi `checkIsValid()`, `reset()`, `resetError()` từ bên ngoài.
17
+ - ✅ **Angular Signals + OnPush**: Hiệu năng cao, không re-render thừa.
17
18
 
18
19
  ## Khi nào sử dụng
19
20
 
20
- - Khi người dùng cần chọn chính xác một tùy chọn trong danh sách.
21
- - Thay thế cho dropdown khi số lượng tùy chọn ít (dưới 5) để người dùng có thể nhìn thấy tất cả các lựa chọn ngay lập tức.
22
- - Cần hiển thị chi tiết phụ (sub-text) tả cho từng tùy chọn để giúp người dùng ra quyết định.
21
+ - Người dùng cần chọn chính xác một tùy chọn trong danh sách có ít lựa chọn (thường dưới 5).
22
+ - Cần thay thế dropdown để người dùng nhìn thấy tất cả lựa chọn ngay lập tức, không cần mở menu.
23
+ - Cần hiển thị tả phụ (sub-text) dưới mỗi tùy chọn để hỗ trợ quyết định (ví dụ: chọn gói dịch vụ).
24
+ - Cần tích hợp validation trong form và gọi kiểm tra từ nút submit bên ngoài component.
23
25
 
24
26
  ## Cài đặt
25
27
 
26
28
  ```bash
27
- # npm
28
29
  npm install @libs-ui/components-radio-group
29
-
30
- # yarn
31
- yarn add @libs-ui/components-radio-group
32
30
  ```
33
31
 
34
32
  ## Import
35
33
 
36
34
  ```typescript
37
35
  import { LibsUiComponentsRadioGroupComponent } from '@libs-ui/components-radio-group';
36
+ import { IRadioGroupItem, IRadioGroupFunctionControlEvent } from '@libs-ui/components-radio-group';
38
37
 
39
38
  @Component({
40
39
  standalone: true,
41
40
  imports: [LibsUiComponentsRadioGroupComponent],
42
- // ...
43
41
  })
44
42
  export class YourComponent {}
45
43
  ```
46
44
 
47
- ## Ví dụ
45
+ ## Ví dụ sử dụng
46
+
47
+ ### 1. Basic — Radio group dọc cơ bản
48
48
 
49
- ### Basic Usage
49
+ ```typescript
50
+ import { Component, signal } from '@angular/core';
51
+ import { LibsUiComponentsRadioGroupComponent, IRadioGroupItem } from '@libs-ui/components-radio-group';
52
+ import { IRadioEvent } from '@libs-ui/components-radio-single';
50
53
 
51
- ```html
52
- <libs_ui-components-radio-group
53
- [groups]="groups()"
54
- (outChange)="onChange($event)" />
54
+ @Component({
55
+ selector: 'app-plan-select',
56
+ standalone: true,
57
+ imports: [LibsUiComponentsRadioGroupComponent],
58
+ template: `
59
+ <libs_ui-components-radio-group
60
+ [groups]="planGroups()"
61
+ (outChange)="handlerPlanChange($event)" />
62
+ `,
63
+ })
64
+ export class PlanSelectComponent {
65
+ protected planGroups = signal<IRadioGroupItem[]>([
66
+ { item: { key: 'free', label: 'Free', active: true } },
67
+ { item: { key: 'pro', label: 'Pro', active: false } },
68
+ { item: { key: 'enterprise', label: 'Enterprise (Disabled)', active: false, disable: true } },
69
+ ]);
70
+
71
+ protected handlerPlanChange(event: IRadioEvent): void {
72
+ event.stopPropagation?.();
73
+ console.log('Selected key:', event.key, 'Item:', event.item);
74
+ }
75
+ }
55
76
  ```
56
77
 
78
+ ### 2. Horizontal layout
79
+
57
80
  ```typescript
58
- readonly groups = signal<IRadioGroupItem[]>([
59
- { item: { key: 'opt1', label: 'Option 1', active: true } },
60
- { item: { key: 'opt2', label: 'Option 2', active: false } }
61
- ]);
81
+ import { Component, signal } from '@angular/core';
82
+ import { LibsUiComponentsRadioGroupComponent, IRadioGroupItem } from '@libs-ui/components-radio-group';
83
+
84
+ @Component({
85
+ selector: 'app-gender-select',
86
+ standalone: true,
87
+ imports: [LibsUiComponentsRadioGroupComponent],
88
+ template: `
89
+ <libs_ui-components-radio-group
90
+ [groups]="genderGroups()"
91
+ [horizontal]="true"
92
+ [horizontalClassInclude]="'mr-[24px]'"
93
+ [ignoreClassMarginLastItem]="true" />
94
+ `,
95
+ })
96
+ export class GenderSelectComponent {
97
+ protected genderGroups = signal<IRadioGroupItem[]>([
98
+ { item: { key: 'male', label: 'Nam', active: false } },
99
+ { item: { key: 'female', label: 'Nữ', active: false } },
100
+ { item: { key: 'other', label: 'Khác', active: false } },
101
+ ]);
102
+ }
62
103
  ```
63
104
 
64
- ### With Validation & Label
105
+ ### 3. Với Label, Validation Sub-text
65
106
 
66
- ```html
67
- <libs_ui-components-radio-group
68
- [groups]="groups()"
69
- [labelConfig]="{ labelLeft: 'Choose Plan', required: true }"
70
- [validRequired]="{ message: 'Plan is required' }"
71
- (outFunctionsControl)="control = $event" />
107
+ ```typescript
108
+ import { Component, signal } from '@angular/core';
109
+ import { LibsUiComponentsRadioGroupComponent, IRadioGroupItem, IRadioGroupFunctionControlEvent } from '@libs-ui/components-radio-group';
110
+ import { ILabel } from '@libs-ui/components-label';
111
+
112
+ @Component({
113
+ selector: 'app-subscription-form',
114
+ standalone: true,
115
+ imports: [LibsUiComponentsRadioGroupComponent],
116
+ template: `
117
+ <libs_ui-components-radio-group
118
+ [groups]="subscriptionGroups()"
119
+ [labelConfig]="labelConfig"
120
+ [validRequired]="validRequiredConfig"
121
+ (outFunctionsControl)="handlerFunctionsControl($event)" />
122
+
123
+ <div class="flex gap-2 mt-4">
124
+ <button (click)="handlerValidate()">Validate</button>
125
+ <button (click)="handlerReset()">Reset</button>
126
+ </div>
127
+ `,
128
+ })
129
+ export class SubscriptionFormComponent {
130
+ private functionsControl: IRadioGroupFunctionControlEvent | undefined;
131
+
132
+ protected subscriptionGroups = signal<IRadioGroupItem[]>([
133
+ {
134
+ item: { key: 'standard', label: 'Standard Plan', active: false },
135
+ subText: 'Tính năng cơ bản cho cá nhân',
136
+ },
137
+ {
138
+ item: { key: 'pro', label: 'Pro Plan', active: false },
139
+ subText: 'Tính năng nâng cao cho chuyên gia',
140
+ classIncludeSubText: 'text-blue-500',
141
+ },
142
+ {
143
+ item: { key: 'enterprise', label: 'Enterprise Plan', active: false },
144
+ subText: 'Toàn bộ tính năng cho doanh nghiệp',
145
+ },
146
+ ]);
147
+
148
+ protected readonly labelConfig: ILabel = {
149
+ labelLeft: 'Chọn gói đăng ký',
150
+ required: true,
151
+ description: 'Chọn gói phù hợp với nhu cầu của bạn',
152
+ };
153
+
154
+ protected readonly validRequiredConfig = {
155
+ message: 'Vui lòng chọn một gói để tiếp tục',
156
+ };
157
+
158
+ protected handlerFunctionsControl(event: IRadioGroupFunctionControlEvent): void {
159
+ this.functionsControl = event;
160
+ }
161
+
162
+ protected async handlerValidate(): Promise<void> {
163
+ const isValid = await this.functionsControl?.checkIsValid();
164
+ console.log('Form valid:', isValid);
165
+ }
166
+
167
+ protected async handlerReset(): Promise<void> {
168
+ await this.functionsControl?.reset();
169
+ }
170
+ }
171
+ ```
172
+
173
+ ### 4. Điều khiển active từ bên ngoài (keyActive)
174
+
175
+ ```typescript
176
+ import { Component, signal } from '@angular/core';
177
+ import { LibsUiComponentsRadioGroupComponent, IRadioGroupItem } from '@libs-ui/components-radio-group';
178
+
179
+ @Component({
180
+ selector: 'app-status-filter',
181
+ standalone: true,
182
+ imports: [LibsUiComponentsRadioGroupComponent],
183
+ template: `
184
+ <libs_ui-components-radio-group
185
+ [groups]="statusGroups()"
186
+ [keyActive]="selectedStatus()"
187
+ [horizontal]="true" />
188
+
189
+ <button (click)="handlerSelectActive()">Chọn Active</button>
190
+ `,
191
+ })
192
+ export class StatusFilterComponent {
193
+ protected selectedStatus = signal<string>('all');
194
+
195
+ protected statusGroups = signal<IRadioGroupItem[]>([
196
+ { item: { key: 'all', label: 'Tất cả', active: true } },
197
+ { item: { key: 'active', label: 'Đang hoạt động', active: false } },
198
+ { item: { key: 'inactive', label: 'Ngừng hoạt động', active: false } },
199
+ ]);
200
+
201
+ protected handlerSelectActive(): void {
202
+ this.selectedStatus.set('active');
203
+ }
204
+ }
72
205
  ```
73
206
 
74
- ## API
75
-
76
- ### libs_ui-components-radio-group
77
-
78
- #### Inputs
79
-
80
- | Property | Type | Default | Description |
81
- | ----------------------------- | ------------------------ | ------------ | ------------------------------------------------------------- |
82
- | `[groups]` | `Array<IRadioGroupItem>` | `[]` | Danh sách các nhóm radio buttons (Model Input). |
83
- | `[keyActive]` | `unknown` | `undefined` | Giá trị key của item đang active (để set initial state). |
84
- | `[fieldKey]` | `string` | `'key'` | Tên property dùng làm key định danh trong item. |
85
- | `[keysDisable]` | `Array<string>` | `undefined` | Danh sách các keys bị disable. |
86
- | `[horizontal]` | `boolean` | `false` | Hiển thị theo chiều ngang. |
87
- | `[disable]` | `boolean` | `false` | Vô hiệu hóa toàn bộ group. |
88
- | `[labelConfig]` | `ILabel` | `undefined` | Cấu hình label cho toàn bộ group. |
89
- | `[validRequired]` | `{ message?: string }` | `undefined` | Cấu hình validation bắt buộc chọn. |
90
- | `[typeRadio]` | `'normal' \| 'medium'` | `'normal'` | Kích thước của radio (mặc định cho cả group). |
91
- | `[alwaysShowSubText]` | `boolean` | `false` | Luôn hiển thị sub-text của item. |
92
- | `[ignoreClassMarginLastItem]` | `boolean` | `false` | Ẩn class margin cho item cuối cùng. |
93
- | `[horizontalClassInclude]` | `string` | `''` | Class margin cho item trong chế độ horizontal. |
94
- | `[classInclude]` | `string` | `''` | Custom class cho từng radio trong group. |
95
- | `[classLabelInclude]` | `string` | `''` | Custom class cho label của từng radio. |
96
- | `[classItemInclude]` | `string` | `'py-[4px]'` | Class cho từng item wrapper. |
97
- | `[clickExactly]` | `boolean` | `true` | Yêu cầu click chính xác vào radio (true) hay cả dòng (false). |
98
-
99
- #### Outputs
100
-
101
- | Property | Type | Description |
102
- | ----------------------- | --------------------------------- | ---------------------------------------------------------------------- |
103
- | `(outChange)` | `IRadioEvent` | Emit khi người dùng thay đổi lựa chọn. |
104
- | `(outClickButton)` | `IButton` | Emit khi click vào button trong label config (nếu có). |
105
- | `(outFunctionsControl)` | `IRadioGroupFunctionControlEvent` | Emit object chứa các hàm điều khiển (checkIsValid, reset, resetError). |
106
-
107
- #### Interfaces
108
-
109
- **IRadioGroupItem**
110
-
111
- | Property | Type | Description |
112
- | --------------------- | ------------- | -------------------------------------------------------------- |
113
- | `item` | `IRadioItem` | Object chứa thông tin chính của radio (key, label, active...). |
114
- | `subText` | `string` | Text phụ hiển thị dưới radio. |
115
- | `classIncludeSubText` | `string` | Class cho text phụ. |
116
- | `subTemplate` | `TemplateRef` | Template custom hiển thị dưới radio. |
117
- | `disableByKeys` | `boolean` | Disable item dựa trên keysDisable input. |
118
-
119
- **IRadioGroupFunctionControlEvent**
120
-
121
- | Method | Description |
122
- | ---------------- | ---------------------------------------------------------------------------------------- |
123
- | `checkIsValid()` | Kiểm tra validation `required` và hiển thị lỗi nếu chưa chọn. Trả về `Promise<boolean>`. |
124
- | `resetError()` | Xóa trạng thái lỗi. |
125
- | `reset()` | Reset toàn bộ selection về trạng thái ban đầu xóa lỗi. |
126
-
127
- ## Công nghệ
128
-
129
- | Technology | Version | Purpose |
130
- | --------------- | ------- | ---------------- |
131
- | Angular | 18+ | Framework |
132
- | Angular Signals | - | State management |
133
- | OnPush | - | Change Detection |
207
+ ### 5. Disable theo danh sách key (keysDisable)
208
+
209
+ ```typescript
210
+ import { Component, signal } from '@angular/core';
211
+ import { LibsUiComponentsRadioGroupComponent, IRadioGroupItem } from '@libs-ui/components-radio-group';
212
+
213
+ @Component({
214
+ selector: 'app-role-select',
215
+ standalone: true,
216
+ imports: [LibsUiComponentsRadioGroupComponent],
217
+ template: `
218
+ <libs_ui-components-radio-group
219
+ [groups]="roleGroups()"
220
+ [keysDisable]="disabledRoles()" />
221
+ `,
222
+ })
223
+ export class RoleSelectComponent {
224
+ protected roleGroups = signal<IRadioGroupItem[]>([
225
+ { item: { key: 'viewer', label: 'Xem', active: true } },
226
+ { item: { key: 'editor', label: 'Chỉnh sửa', active: false } },
227
+ { item: { key: 'admin', label: 'Quản trị', active: false } },
228
+ { item: { key: 'superadmin', label: 'Super Admin', active: false } },
229
+ ]);
230
+
231
+ protected disabledRoles = signal<string[]>(['admin', 'superadmin']);
232
+ }
233
+ ```
234
+
235
+ ## @Input()
236
+
237
+ | Input | Type | Default | tả | dụ |
238
+ |---|---|---|---|---|
239
+ | `[groups]` | `Array<IRadioGroupItem>` (model) | `[]` | Danh sách các radio item. Là `model()` — có thể dùng hai chiều với `[(groups)]`. | `[groups]="planGroups()"` |
240
+ | `[keyActive]` | `unknown` | `undefined` | Key của item cần set active từ bên ngoài. Component tự tìm item có `item[fieldKey] === keyActive` và đánh dấu active. | `[keyActive]="selectedKey()"` |
241
+ | `[fieldKey]` | `string` | `'key'` | Tên property trong `IRadioItem` dùng làm định danh. Thay đổi nếu data object dùng key khác (ví dụ: `'id'`). | `[fieldKey]="'id'"` |
242
+ | `[keysDisable]` | `Array<string>` | `undefined` | Danh sách các key bị disable. Component tự map và đặt `disableByKeys = true` cho các item tương ứng. | `[keysDisable]="['admin', 'superadmin']"` |
243
+ | `[disable]` | `boolean` | `false` | Disable toàn bộ group, bao gồm cả label buttons và toggle. | `[disable]="true"` |
244
+ | `[horizontal]` | `boolean` | `false` | Hiển thị các radio theo chiều ngang (flex row). | `[horizontal]="true"` |
245
+ | `[horizontalClassInclude]` | `string` | `''` | Class margin áp dụng cho mỗi item khi horizontal. Mặc định `mr-[24px]` nếu để rỗng. | `[horizontalClassInclude]="'mr-[16px]'"` |
246
+ | `[ignoreClassMarginLastItem]` | `boolean` | `false` | Bỏ class margin cho item cuối cùng trong horizontal layout. | `[ignoreClassMarginLastItem]="true"` |
247
+ | `[labelConfig]` | `ILabel` | `undefined` | Cấu hình label chung cho toàn group (tiêu đề, required, description, buttons, popover...). | `[labelConfig]="labelConfig"` |
248
+ | `[validRequired]` | `{ message?: string; interpolateParams?: { any: any } }` | `undefined` | Bật validation required. Khi `checkIsValid()` được gọi mà chưa có item active, sẽ hiển thị `message`. Hỗ trợ i18n. | `[validRequired]="{ message: 'i18n_required' }"` |
249
+ | `[typeRadio]` | `'normal' \| 'medium'` | `'normal'` | Kích thước radio button áp dụng cho toàn group. | `[typeRadio]="'medium'"` |
250
+ | `[clickExactly]` | `boolean` | `true` | `true` = chỉ click vào vòng tròn radio mới kích hoạt. `false` = click cả vùng label cũng kích hoạt. | `[clickExactly]="false"` |
251
+ | `[classInclude]` | `string` | `''` | Class CSS bổ sung cho mỗi radio button trong group. Ưu tiên hơn `group.item.classInclude`. | `[classInclude]="'w-full'"` |
252
+ | `[classLabelInclude]` | `string` | `''` | Class CSS cho label của mỗi radio. Ưu tiên hơn `group.item.classLabelInclude`. Mặc định từ item: `libs-ui-font-h5r`. | `[classLabelInclude]="'libs-ui-font-h5m'"` |
253
+ | `[classItemInclude]` | `string` | `'py-[4px]'` | Class CSS cho wrapper của mỗi item (div bao ngoài radio và sub-content). | `[classItemInclude]="'py-[8px]'"` |
254
+ | `[alwaysShowSubText]` | `boolean` | `undefined` | `true` = luôn hiển thị `subText`/`subTemplate`, không cần item active. | `[alwaysShowSubText]="true"` |
255
+
256
+ ## @Output()
257
+
258
+ | Output | Type | tả | Handler TS | Binding HTML |
259
+ |---|---|---|---|---|
260
+ | `(outChange)` | `IRadioEvent` | Emit khi người dùng chọn một radio item. Payload gồm `active`, `key`, và `item` là object gốc của item được chọn. | `handlerChange(event: IRadioEvent): void { event.stopPropagation?.(); ... }` | `(outChange)="handlerChange($event)"` |
261
+ | `(outClickButton)` | `IButton` | Emit khi người dùng click vào button được cấu hình trong `labelConfig.buttonsLeft` hoặc `buttonsDescription`. | `handlerClickLabelButton(event: IButton): void { event.stopPropagation?.(); ... }` | `(outClickButton)="handlerClickLabelButton($event)"` |
262
+ | `(outFunctionsControl)` | `IRadioGroupFunctionControlEvent` | Emit một lần trong `ngOnInit` với object chứa các hàm điều khiển. Lưu lại để gọi `checkIsValid()`, `reset()`, `resetError()` từ bên ngoài. | `handlerFunctionsControl(event: IRadioGroupFunctionControlEvent): void { this.control = event; }` | `(outFunctionsControl)="handlerFunctionsControl($event)"` |
263
+
264
+ ## Types & Interfaces
265
+
266
+ ```typescript
267
+ import {
268
+ IRadioGroupItem,
269
+ IRadioGroupFunctionControlEvent,
270
+ } from '@libs-ui/components-radio-group';
271
+
272
+ import { IRadioEvent, IRadioItem } from '@libs-ui/components-radio-single';
273
+ ```
274
+
275
+ ### IRadioGroupItem
276
+
277
+ Mỗi phần tử trong mảng `[groups]`:
278
+
279
+ ```typescript
280
+ interface IRadioGroupItem {
281
+ /** Thông tin chính của radio item */
282
+ item: IRadioItem;
283
+ /** Text phụ hiển thị dưới radio khi item active (hỗ trợ i18n key) */
284
+ subText?: string;
285
+ /** Class CSS tùy chỉnh cho sub-text */
286
+ classIncludeSubText?: string;
287
+ /** Template tùy chỉnh hiển thị dưới radio khi item active. Context: { item: IRadioItem } */
288
+ subTemplate?: TemplateRef<any>;
289
+ /** Nội bộ — được set tự động bởi [keysDisable], không cần truyền thủ công */
290
+ disableByKeys?: boolean;
291
+ }
292
+ ```
293
+
294
+ ### IRadioItem (từ @libs-ui/components-radio-single)
295
+
296
+ ```typescript
297
+ interface IRadioItem {
298
+ /** Định danh duy nhất của item (dùng để so sánh với [keyActive] và [keysDisable]) */
299
+ key: any;
300
+ /** Trạng thái active ban đầu */
301
+ active: boolean;
302
+ /** Nhãn hiển thị (hỗ trợ i18n key) */
303
+ label?: string;
304
+ /** Params cho i18n interpolation của label */
305
+ labelInterpolateParams?: Record<string, unknown>;
306
+ /** Disable item này */
307
+ disable?: boolean;
308
+ /** Disable chỉ phần label (vòng tròn radio vẫn click được) */
309
+ disableLabel?: boolean;
310
+ /** Class CSS bổ sung cho radio button */
311
+ classInclude?: string;
312
+ /** Class CSS bổ sung cho label */
313
+ classLabelInclude?: string;
314
+ /** Cấu hình popover khi hover vào item */
315
+ popover?: IPopover;
316
+ /** Cấu hình avatar hiển thị bên cạnh label */
317
+ avatarConfig?: IAvatarConfig;
318
+ /** z-index cho label (dùng khi overlap với element khác) */
319
+ zIndexLabel?: number;
320
+ /** Data payload tùy ý, được truyền nguyên vẹn qua IRadioEvent.item */
321
+ data?: any;
322
+ [key: string]: any;
323
+ }
324
+ ```
325
+
326
+ ### IRadioEvent (từ @libs-ui/components-radio-single)
327
+
328
+ ```typescript
329
+ interface IRadioEvent {
330
+ /** Trạng thái active sau khi click */
331
+ active: boolean;
332
+ /** Key của item được click */
333
+ key: any;
334
+ /** Object IRadioItem đầy đủ của item được click */
335
+ item?: IRadioItem;
336
+ }
337
+ ```
338
+
339
+ ### IRadioGroupFunctionControlEvent
340
+
341
+ API điều khiển emit qua `(outFunctionsControl)`:
342
+
343
+ ```typescript
344
+ interface IRadioGroupFunctionControlEvent {
345
+ /**
346
+ * Kiểm tra validation required.
347
+ * - Nếu [validRequired] được cấu hình và không có item nào active: hiển thị lỗi, trả về false.
348
+ * - Nếu [validRequired] không được cấu hình: không làm gì, trả về true.
349
+ */
350
+ checkIsValid: () => Promise<boolean>;
351
+ /** Ẩn thông báo lỗi validation (không reset selection) */
352
+ resetError: () => Promise<void>;
353
+ /** Reset toàn bộ selection (tất cả item về active = false) và ẩn lỗi */
354
+ reset: () => Promise<void>;
355
+ }
356
+ ```
357
+
358
+ ## Lưu ý quan trọng
359
+
360
+ ⚠️ **groups là model() hai chiều**: Input `[groups]` được khai báo là `model()`. Khi người dùng chọn, component tự cập nhật mảng nội bộ. Nếu truyền `[(groups)]="myGroups"`, signal gốc sẽ được cập nhật tự động. Nếu truyền chỉ `[groups]="myGroups()"`, cần lắng nghe `(outChange)` để cập nhật state bên ngoài.
361
+
362
+ ⚠️ **fieldKey phải khớp với key trong IRadioItem**: Mặc định component dùng `item['key']` để nhận diện item. Nếu data của bạn dùng `item.id` thay vì `item.key`, phải truyền `[fieldKey]="'id'"`. Sai fieldKey sẽ khiến `keyActive` và `keysDisable` không hoạt động.
363
+
364
+ ⚠️ **outFunctionsControl emit một lần trong ngOnInit**: Lưu giá trị emit vào biến class để sử dụng sau. Không cần unsubscribe vì `output()` tự cleanup. Đảm bảo không gọi `checkIsValid()` trước khi component được khởi tạo.
365
+
366
+ ⚠️ **subText và subTemplate chỉ hiển thị khi item active**: Mặc định sub-content chỉ xuất hiện khi `item.active === true`. Dùng `[alwaysShowSubText]="true"` để luôn hiển thị bất kể trạng thái.
367
+
368
+ ⚠️ **keysDisable không thay thế item.disable**: `[keysDisable]` là cơ chế disable linh hoạt từ bên ngoài (ví dụ: disable theo quyền từ API). `item.disable` trong IRadioItem là disable cứng khai báo sẵn trong data. Cả hai có thể dùng đồng thời — item bị disable nếu thỏa mãn một trong hai điều kiện.
134
369
 
135
370
  ## Demo
136
371
 
@@ -138,4 +373,4 @@ readonly groups = signal<IRadioGroupItem[]>([
138
373
  npx nx serve core-ui
139
374
  ```
140
375
 
141
- Truy cập path: `/components/radio/group`
376
+ Truy cập: `http://localhost:4500/components/radio/group`
@@ -1,6 +1,6 @@
1
1
  import { NgTemplateOutlet } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { signal, input, model, output, effect, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { signal, input, model, output, effect, untracked, Component, ChangeDetectionStrategy } from '@angular/core';
4
4
  import { LibsUiComponentsLabelComponent } from '@libs-ui/components-label';
5
5
  import { LibsUiComponentsRadioSingleComponent } from '@libs-ui/components-radio-single';
6
6
  import { ERROR_MESSAGE_EMPTY_VALID, isNil } from '@libs-ui/utils';
@@ -1 +1 @@
1
- {"version":3,"file":"libs-ui-components-radio-group.mjs","sources":["../../../../../../libs-ui/components/radio/group/src/group.component.ts","../../../../../../libs-ui/components/radio/group/src/group.component.html","../../../../../../libs-ui/components/radio/group/src/libs-ui-components-radio-group.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, OnInit, effect, input, model, output, signal, untracked } from '@angular/core';\nimport { IButton } from '@libs-ui/components-buttons-button';\nimport { ILabel, LibsUiComponentsLabelComponent } from '@libs-ui/components-label';\nimport { IRadioEvent, LibsUiComponentsRadioSingleComponent } from '@libs-ui/components-radio-single';\nimport { ERROR_MESSAGE_EMPTY_VALID, isNil } from '@libs-ui/utils';\nimport { TranslateModule } from '@ngx-translate/core';\nimport { IRadioGroupFunctionControlEvent, IRadioGroupItem } from './interfaces';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'libs_ui-components-radio-group',\n templateUrl: './group.component.html',\n styleUrls: ['./group.component.scss'],\n standalone: true,\n imports: [TranslateModule, NgTemplateOutlet, LibsUiComponentsLabelComponent, LibsUiComponentsRadioSingleComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class LibsUiComponentsRadioGroupComponent implements OnInit {\n // #region PROPERTY\n protected readonly ERROR_MESSAGE_EMPTY_VALID = ERROR_MESSAGE_EMPTY_VALID;\n protected isErrorRequired = signal<boolean>(false);\n\n // #region INPUT\n readonly fieldKey = input<string, string>('key', { transform: (value) => value || 'key' });\n readonly keyActive = input<unknown>();\n readonly keysDisable = input<Array<string>>();\n readonly groups = model<Array<IRadioGroupItem>>([]);\n readonly disable = input<boolean | undefined, boolean | undefined>(false, { transform: (value) => value ?? false });\n readonly clickExactly = input<boolean | undefined, boolean | undefined>(true, { transform: (value) => value ?? true });\n readonly horizontal = input<boolean | undefined, boolean | undefined>(false, { transform: (value) => value ?? false });\n readonly labelConfig = input<ILabel | undefined>();\n readonly validRequired = input<\n | {\n message?: string;\n interpolateParams?: { any: any };\n }\n | undefined\n >();\n readonly ignoreClassMarginLastItem = input<boolean | undefined>(false);\n readonly typeRadio = input<'normal' | 'medium' | undefined, 'normal' | 'medium' | undefined>('normal', { transform: (value) => value ?? 'normal' });\n readonly classInclude = input<string | undefined, string | undefined>('', { transform: (value) => value ?? '' });\n readonly classLabelInclude = input<string | undefined, string | undefined>('', { transform: (value) => value ?? '' });\n readonly classItemInclude = input<string | undefined, string | undefined>('py-[4px]', { transform: (value) => value ?? 'py-[4px]' });\n readonly alwaysShowSubText = input<boolean | undefined>();\n readonly horizontalClassInclude = input<string | undefined, string | undefined>('', { transform: (value) => value ?? '' });\n\n // #region OUTPUT\n readonly outClickButton = output<IButton>();\n readonly outChange = output<IRadioEvent>();\n readonly outFunctionsControl = output<IRadioGroupFunctionControlEvent>();\n\n constructor() {\n effect(() => {\n if (isNil(this.keyActive()) || !this.fieldKey()) {\n return;\n }\n untracked(() => {\n this.groups.update((data) => {\n return data.map<IRadioGroupItem>((group) => {\n group.item.active = false;\n if (group.item && group.item[this.fieldKey()] === this.keyActive()) {\n group.item.active = true;\n }\n return group;\n });\n });\n });\n });\n\n effect(() => {\n if (!Array.isArray(this.keysDisable()) || !this.fieldKey()) {\n return;\n }\n untracked(() => {\n this.groups.update((data) => {\n return data.map<IRadioGroupItem>((group) => {\n group.disableByKeys = false;\n if (group.item && this.keysDisable()?.includes(group.item[this.fieldKey()])) {\n group.disableByKeys = true;\n }\n return group;\n });\n });\n });\n });\n }\n\n ngOnInit() {\n this.outFunctionsControl.emit(this.FunctionsControl);\n }\n\n // #region FUNCTIONS\n public get FunctionsControl(): IRadioGroupFunctionControlEvent {\n return {\n checkIsValid: this.checkValid.bind(this),\n resetError: this.resetError.bind(this),\n reset: async () => {\n this.groups.update((data) => {\n return data.map<IRadioGroupItem>((group) => {\n group.item.active = false;\n return group;\n });\n });\n this.resetError();\n },\n };\n }\n protected async handlerClickButton(event: IButton) {\n this.outClickButton.emit(event);\n }\n\n protected async handlerChange(dataEvent: { active: boolean; key: any }) {\n if (this.disable()) {\n return;\n }\n const event: any = dataEvent;\n\n this.groups.update((data) => {\n return data.map<IRadioGroupItem>((group) => {\n const item = group.item;\n\n item.active = false;\n if (item[this.fieldKey()] === dataEvent.key) {\n item.active = dataEvent.active;\n event.item = item;\n }\n return group;\n });\n });\n this.outChange.emit(event);\n this.checkValid();\n }\n\n private async checkValid(): Promise<boolean> {\n this.isErrorRequired.set(false);\n if (!this.validRequired()) {\n return true;\n }\n\n this.isErrorRequired.set(!this.groups()?.some((group: IRadioGroupItem) => group.item?.active));\n\n return !this.isErrorRequired();\n }\n\n private async resetError() {\n this.isErrorRequired.set(false);\n }\n}\n","<div class=\"flex flex-col w-full\">\n @if (labelConfig(); as labelConfig) {\n <libs_ui-components-label\n [classInclude]=\"labelConfig.classInclude\"\n [labelLeft]=\"labelConfig.labelLeft\"\n [labelLeftClass]=\"labelConfig.labelLeftClass\"\n [required]=\"labelConfig.required\"\n [description]=\"labelConfig.description\"\n [descriptionClass]=\"labelConfig.descriptionClass\"\n [labelRight]=\"labelConfig.labelRight\"\n [labelRightClass]=\"labelConfig.labelRightClass\"\n [onlyShowCount]=\"labelConfig.onlyShowCount\"\n [buttonsLeft]=\"labelConfig.buttonsLeft\"\n [disableButtonsLeft]=\"labelConfig.disableButtonsLeft || disable()\"\n [hasToggle]=\"labelConfig.hasToggle\"\n [toggleActive]=\"labelConfig.toggleActive\"\n [toggleDisable]=\"labelConfig.toggleDisable || disable()\"\n [popover]=\"labelConfig.popover\"\n [iconPopoverClass]=\"labelConfig.iconPopoverClass\"\n [onlyShowCount]=\"labelConfig.onlyShowCount\"\n [limitLength]=\"labelConfig.limitLength\"\n [buttonsDescription]=\"labelConfig.buttonsDescription\"\n [disableButtonsDescription]=\"labelConfig.disableButtonsDescription || disable()\"\n [buttonsDescriptionContainerClass]=\"labelConfig.buttonsDescriptionContainerClass\"\n [count]=\"labelConfig.count\"\n (outClickButton)=\"handlerClickButton($event)\" />\n }\n @if (isErrorRequired()) {\n <div class=\"flex items-center mb-[8px]\">\n @let constHtmlMessage = validRequired()?.message || ERROR_MESSAGE_EMPTY_VALID;\n <span\n class=\"libs-ui-font-h5r libs-ui-text-error\"\n [innerHtml]=\"constHtmlMessage | translate: validRequired()?.interpolateParams\"></span>\n </div>\n }\n <div\n class=\"libs-ui-radio-group\"\n [class.flex]=\"horizontal()\">\n @for (group of groups(); track group; let isLast = $last) {\n <div [class]=\"horizontal() ? (isLast && ignoreClassMarginLastItem() ? '' : horizontalClassInclude() || 'mr-[24px]') : ''\">\n <div [class]=\"classItemInclude()\">\n <libs_ui-components-radio-single\n [labelInterpolateParams]=\"group.item.labelInterpolateParams\"\n [label]=\"group.item.label || ' '\"\n [active]=\"group.item.active || false\"\n [key]=\"group.item[fieldKey()]\"\n [disable]=\"group['disableByKeys'] || disable() || group.item.disable || false\"\n [disableLabel]=\"group.item.disableLabel || false\"\n [classLabelInclude]=\"classLabelInclude() || group.item.classLabelInclude || 'libs-ui-font-h5r'\"\n [classInclude]=\"classInclude() || group.item.classInclude || ''\"\n [zIndexLabel]=\"group.item.zIndexLabel\"\n [typeRadio]=\"typeRadio()\"\n [avatarConfig]=\"group.item.avatarConfig\"\n (outChange)=\"handlerChange($event)\"\n [popover]=\"group.item.popover\"\n [clickExactly]=\"clickExactly()\" />\n </div>\n @if (group.item.active || alwaysShowSubText()) {\n @if (group.subText) {\n <div\n [class]=\"'libs-ui-radio-group-sub-text libs-ui-font-h7r ' + (group.classIncludeSubText ? group.classIncludeSubText : '')\"\n [innerHtml]=\"group.subText | translate\"></div>\n }\n <ng-container *ngTemplateOutlet=\"group?.subTemplate || null; context: { item: group.item }\" />\n }\n </div>\n }\n </div>\n</div>\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-radio-group.mjs","sources":["../../../../../../libs-ui/components/radio/group/src/group.component.ts","../../../../../../libs-ui/components/radio/group/src/group.component.html","../../../../../../libs-ui/components/radio/group/src/libs-ui-components-radio-group.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, OnInit, effect, input, model, output, signal, untracked } from '@angular/core';\nimport { IButton } from '@libs-ui/components-buttons-button';\nimport { ILabel, LibsUiComponentsLabelComponent } from '@libs-ui/components-label';\nimport { IRadioEvent, LibsUiComponentsRadioSingleComponent } from '@libs-ui/components-radio-single';\nimport { ERROR_MESSAGE_EMPTY_VALID, isNil } from '@libs-ui/utils';\nimport { TranslateModule } from '@ngx-translate/core';\nimport { IRadioGroupFunctionControlEvent, IRadioGroupItem } from './interfaces';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'libs_ui-components-radio-group',\n templateUrl: './group.component.html',\n styleUrls: ['./group.component.scss'],\n standalone: true,\n imports: [TranslateModule, NgTemplateOutlet, LibsUiComponentsLabelComponent, LibsUiComponentsRadioSingleComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class LibsUiComponentsRadioGroupComponent implements OnInit {\n // #region PROPERTY\n protected readonly ERROR_MESSAGE_EMPTY_VALID = ERROR_MESSAGE_EMPTY_VALID;\n protected isErrorRequired = signal<boolean>(false);\n\n // #region INPUT\n readonly fieldKey = input<string, string>('key', { transform: (value) => value || 'key' });\n readonly keyActive = input<unknown>();\n readonly keysDisable = input<Array<string>>();\n readonly groups = model<Array<IRadioGroupItem>>([]);\n readonly disable = input<boolean | undefined, boolean | undefined>(false, { transform: (value) => value ?? false });\n readonly clickExactly = input<boolean | undefined, boolean | undefined>(true, { transform: (value) => value ?? true });\n readonly horizontal = input<boolean | undefined, boolean | undefined>(false, { transform: (value) => value ?? false });\n readonly labelConfig = input<ILabel | undefined>();\n readonly validRequired = input<\n | {\n message?: string;\n interpolateParams?: { any: any };\n }\n | undefined\n >();\n readonly ignoreClassMarginLastItem = input<boolean | undefined>(false);\n readonly typeRadio = input<'normal' | 'medium' | undefined, 'normal' | 'medium' | undefined>('normal', { transform: (value) => value ?? 'normal' });\n readonly classInclude = input<string | undefined, string | undefined>('', { transform: (value) => value ?? '' });\n readonly classLabelInclude = input<string | undefined, string | undefined>('', { transform: (value) => value ?? '' });\n readonly classItemInclude = input<string | undefined, string | undefined>('py-[4px]', { transform: (value) => value ?? 'py-[4px]' });\n readonly alwaysShowSubText = input<boolean | undefined>();\n readonly horizontalClassInclude = input<string | undefined, string | undefined>('', { transform: (value) => value ?? '' });\n\n // #region OUTPUT\n readonly outClickButton = output<IButton>();\n readonly outChange = output<IRadioEvent>();\n readonly outFunctionsControl = output<IRadioGroupFunctionControlEvent>();\n\n constructor() {\n effect(() => {\n if (isNil(this.keyActive()) || !this.fieldKey()) {\n return;\n }\n untracked(() => {\n this.groups.update((data) => {\n return data.map<IRadioGroupItem>((group) => {\n group.item.active = false;\n if (group.item && group.item[this.fieldKey()] === this.keyActive()) {\n group.item.active = true;\n }\n return group;\n });\n });\n });\n });\n\n effect(() => {\n if (!Array.isArray(this.keysDisable()) || !this.fieldKey()) {\n return;\n }\n untracked(() => {\n this.groups.update((data) => {\n return data.map<IRadioGroupItem>((group) => {\n group.disableByKeys = false;\n if (group.item && this.keysDisable()?.includes(group.item[this.fieldKey()])) {\n group.disableByKeys = true;\n }\n return group;\n });\n });\n });\n });\n }\n\n ngOnInit() {\n this.outFunctionsControl.emit(this.FunctionsControl);\n }\n\n // #region FUNCTIONS\n public get FunctionsControl(): IRadioGroupFunctionControlEvent {\n return {\n checkIsValid: this.checkValid.bind(this),\n resetError: this.resetError.bind(this),\n reset: async () => {\n this.groups.update((data) => {\n return data.map<IRadioGroupItem>((group) => {\n group.item.active = false;\n return group;\n });\n });\n this.resetError();\n },\n };\n }\n protected async handlerClickButton(event: IButton) {\n this.outClickButton.emit(event);\n }\n\n protected async handlerChange(dataEvent: { active: boolean; key: any }) {\n if (this.disable()) {\n return;\n }\n const event: any = dataEvent;\n\n this.groups.update((data) => {\n return data.map<IRadioGroupItem>((group) => {\n const item = group.item;\n\n item.active = false;\n if (item[this.fieldKey()] === dataEvent.key) {\n item.active = dataEvent.active;\n event.item = item;\n }\n return group;\n });\n });\n this.outChange.emit(event);\n this.checkValid();\n }\n\n private async checkValid(): Promise<boolean> {\n this.isErrorRequired.set(false);\n if (!this.validRequired()) {\n return true;\n }\n\n this.isErrorRequired.set(!this.groups()?.some((group: IRadioGroupItem) => group.item?.active));\n\n return !this.isErrorRequired();\n }\n\n private async resetError() {\n this.isErrorRequired.set(false);\n }\n}\n","<div class=\"flex flex-col w-full\">\n @if (labelConfig(); as labelConfig) {\n <libs_ui-components-label\n [classInclude]=\"labelConfig.classInclude\"\n [labelLeft]=\"labelConfig.labelLeft\"\n [labelLeftClass]=\"labelConfig.labelLeftClass\"\n [required]=\"labelConfig.required\"\n [description]=\"labelConfig.description\"\n [descriptionClass]=\"labelConfig.descriptionClass\"\n [labelRight]=\"labelConfig.labelRight\"\n [labelRightClass]=\"labelConfig.labelRightClass\"\n [onlyShowCount]=\"labelConfig.onlyShowCount\"\n [buttonsLeft]=\"labelConfig.buttonsLeft\"\n [disableButtonsLeft]=\"labelConfig.disableButtonsLeft || disable()\"\n [hasToggle]=\"labelConfig.hasToggle\"\n [toggleActive]=\"labelConfig.toggleActive\"\n [toggleDisable]=\"labelConfig.toggleDisable || disable()\"\n [popover]=\"labelConfig.popover\"\n [iconPopoverClass]=\"labelConfig.iconPopoverClass\"\n [onlyShowCount]=\"labelConfig.onlyShowCount\"\n [limitLength]=\"labelConfig.limitLength\"\n [buttonsDescription]=\"labelConfig.buttonsDescription\"\n [disableButtonsDescription]=\"labelConfig.disableButtonsDescription || disable()\"\n [buttonsDescriptionContainerClass]=\"labelConfig.buttonsDescriptionContainerClass\"\n [count]=\"labelConfig.count\"\n (outClickButton)=\"handlerClickButton($event)\" />\n }\n @if (isErrorRequired()) {\n <div class=\"flex items-center mb-[8px]\">\n @let constHtmlMessage = validRequired()?.message || ERROR_MESSAGE_EMPTY_VALID;\n <span\n class=\"libs-ui-font-h5r libs-ui-text-error\"\n [innerHtml]=\"constHtmlMessage | translate: validRequired()?.interpolateParams\"></span>\n </div>\n }\n <div\n class=\"libs-ui-radio-group\"\n [class.flex]=\"horizontal()\">\n @for (group of groups(); track group; let isLast = $last) {\n <div [class]=\"horizontal() ? (isLast && ignoreClassMarginLastItem() ? '' : horizontalClassInclude() || 'mr-[24px]') : ''\">\n <div [class]=\"classItemInclude()\">\n <libs_ui-components-radio-single\n [labelInterpolateParams]=\"group.item.labelInterpolateParams\"\n [label]=\"group.item.label || ' '\"\n [active]=\"group.item.active || false\"\n [key]=\"group.item[fieldKey()]\"\n [disable]=\"group['disableByKeys'] || disable() || group.item.disable || false\"\n [disableLabel]=\"group.item.disableLabel || false\"\n [classLabelInclude]=\"classLabelInclude() || group.item.classLabelInclude || 'libs-ui-font-h5r'\"\n [classInclude]=\"classInclude() || group.item.classInclude || ''\"\n [zIndexLabel]=\"group.item.zIndexLabel\"\n [typeRadio]=\"typeRadio()\"\n [avatarConfig]=\"group.item.avatarConfig\"\n (outChange)=\"handlerChange($event)\"\n [popover]=\"group.item.popover\"\n [clickExactly]=\"clickExactly()\" />\n </div>\n @if (group.item.active || alwaysShowSubText()) {\n @if (group.subText) {\n <div\n [class]=\"'libs-ui-radio-group-sub-text libs-ui-font-h7r ' + (group.classIncludeSubText ? group.classIncludeSubText : '')\"\n [innerHtml]=\"group.subText | translate\"></div>\n }\n <ng-container *ngTemplateOutlet=\"group?.subTemplate || null; context: { item: group.item }\" />\n }\n </div>\n }\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;AAAA;MAmBa,mCAAmC,CAAA;;IAE3B,yBAAyB,GAAG,yBAAyB,CAAC;AAC/D,IAAA,eAAe,GAAG,MAAM,CAAU,KAAK,CAAC,CAAC;;AAG1C,IAAA,QAAQ,GAAG,KAAK,CAAiB,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC;IAClF,SAAS,GAAG,KAAK,EAAW,CAAC;IAC7B,WAAW,GAAG,KAAK,EAAiB,CAAC;AACrC,IAAA,MAAM,GAAG,KAAK,CAAyB,EAAE,CAAC,CAAC;AAC3C,IAAA,OAAO,GAAG,KAAK,CAA2C,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC;AAC3G,IAAA,YAAY,GAAG,KAAK,CAA2C,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;AAC9G,IAAA,UAAU,GAAG,KAAK,CAA2C,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC;IAC9G,WAAW,GAAG,KAAK,EAAsB,CAAC;IAC1C,aAAa,GAAG,KAAK,EAM3B,CAAC;AACK,IAAA,yBAAyB,GAAG,KAAK,CAAsB,KAAK,CAAC,CAAC;AAC9D,IAAA,SAAS,GAAG,KAAK,CAAmE,QAAQ,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,QAAQ,EAAE,CAAC,CAAC;AAC3I,IAAA,YAAY,GAAG,KAAK,CAAyC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC;AACxG,IAAA,iBAAiB,GAAG,KAAK,CAAyC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC;AAC7G,IAAA,gBAAgB,GAAG,KAAK,CAAyC,UAAU,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,UAAU,EAAE,CAAC,CAAC;IAC5H,iBAAiB,GAAG,KAAK,EAAuB,CAAC;AACjD,IAAA,sBAAsB,GAAG,KAAK,CAAyC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC;;IAGlH,cAAc,GAAG,MAAM,EAAW,CAAC;IACnC,SAAS,GAAG,MAAM,EAAe,CAAC;IAClC,mBAAmB,GAAG,MAAM,EAAmC,CAAC;AAEzE,IAAA,WAAA,GAAA;QACE,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE;gBAC/C,OAAO;aACR;YACD,SAAS,CAAC,MAAK;gBACb,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,KAAI;AAC1B,oBAAA,OAAO,IAAI,CAAC,GAAG,CAAkB,CAAC,KAAK,KAAI;AACzC,wBAAA,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;AAC1B,wBAAA,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,IAAI,CAAC,SAAS,EAAE,EAAE;AAClE,4BAAA,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;yBAC1B;AACD,wBAAA,OAAO,KAAK,CAAC;AACf,qBAAC,CAAC,CAAC;AACL,iBAAC,CAAC,CAAC;AACL,aAAC,CAAC,CAAC;AACL,SAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE;gBAC1D,OAAO;aACR;YACD,SAAS,CAAC,MAAK;gBACb,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,KAAI;AAC1B,oBAAA,OAAO,IAAI,CAAC,GAAG,CAAkB,CAAC,KAAK,KAAI;AACzC,wBAAA,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC;wBAC5B,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE;AAC3E,4BAAA,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;yBAC5B;AACD,wBAAA,OAAO,KAAK,CAAC;AACf,qBAAC,CAAC,CAAC;AACL,iBAAC,CAAC,CAAC;AACL,aAAC,CAAC,CAAC;AACL,SAAC,CAAC,CAAC;KACJ;IAED,QAAQ,GAAA;QACN,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;KACtD;;AAGD,IAAA,IAAW,gBAAgB,GAAA;QACzB,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;YACxC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;YACtC,KAAK,EAAE,YAAW;gBAChB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,KAAI;AAC1B,oBAAA,OAAO,IAAI,CAAC,GAAG,CAAkB,CAAC,KAAK,KAAI;AACzC,wBAAA,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;AAC1B,wBAAA,OAAO,KAAK,CAAC;AACf,qBAAC,CAAC,CAAC;AACL,iBAAC,CAAC,CAAC;gBACH,IAAI,CAAC,UAAU,EAAE,CAAC;aACnB;SACF,CAAC;KACH;IACS,MAAM,kBAAkB,CAAC,KAAc,EAAA;AAC/C,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;KACjC;IAES,MAAM,aAAa,CAAC,SAAwC,EAAA;AACpE,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;YAClB,OAAO;SACR;QACD,MAAM,KAAK,GAAQ,SAAS,CAAC;QAE7B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,KAAI;AAC1B,YAAA,OAAO,IAAI,CAAC,GAAG,CAAkB,CAAC,KAAK,KAAI;AACzC,gBAAA,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;AAExB,gBAAA,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;AACpB,gBAAA,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,SAAS,CAAC,GAAG,EAAE;AAC3C,oBAAA,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;AAC/B,oBAAA,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;iBACnB;AACD,gBAAA,OAAO,KAAK,CAAC;AACf,aAAC,CAAC,CAAC;AACL,SAAC,CAAC,CAAC;AACH,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,CAAC,UAAU,EAAE,CAAC;KACnB;AAEO,IAAA,MAAM,UAAU,GAAA;AACtB,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAChC,QAAA,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE;AACzB,YAAA,OAAO,IAAI,CAAC;SACb;QAED,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC,KAAsB,KAAK,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;AAE/F,QAAA,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;KAChC;AAEO,IAAA,MAAM,UAAU,GAAA;AACtB,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACjC;wGAjIU,mCAAmC,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;4FAAnC,mCAAmC,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gCAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,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,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,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,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,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,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,yBAAA,EAAA,EAAA,iBAAA,EAAA,2BAAA,EAAA,UAAA,EAAA,2BAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,UAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,gBAAA,EAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,UAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,sBAAA,EAAA,EAAA,iBAAA,EAAA,wBAAA,EAAA,UAAA,EAAA,wBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,MAAA,EAAA,cAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,SAAA,EAAA,WAAA,EAAA,mBAAA,EAAA,qBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECnBhD,+5GAqEA,EDrDY,MAAA,EAAA,CAAA,mHAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,eAAe,4FAAE,gBAAgB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,kBAAA,EAAA,0BAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,8BAA8B,EAAA,QAAA,EAAA,0BAAA,EAAA,MAAA,EAAA,CAAA,kBAAA,EAAA,cAAA,EAAA,WAAA,EAAA,gBAAA,EAAA,6BAAA,EAAA,SAAA,EAAA,UAAA,EAAA,aAAA,EAAA,oBAAA,EAAA,cAAA,EAAA,qBAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,oBAAA,EAAA,WAAA,EAAA,YAAA,EAAA,cAAA,EAAA,eAAA,EAAA,aAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,2BAAA,EAAA,kCAAA,EAAA,eAAA,EAAA,eAAA,EAAA,qBAAA,EAAA,OAAA,EAAA,aAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,EAAA,gBAAA,EAAA,oBAAA,EAAA,mBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,oCAAoC,EAAA,QAAA,EAAA,iCAAA,EAAA,MAAA,EAAA,CAAA,KAAA,EAAA,QAAA,EAAA,cAAA,EAAA,OAAA,EAAA,wBAAA,EAAA,oBAAA,EAAA,mBAAA,EAAA,WAAA,EAAA,gBAAA,EAAA,cAAA,EAAA,mBAAA,EAAA,aAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,cAAA,EAAA,cAAA,EAAA,WAAA,EAAA,aAAA,EAAA,aAAA,EAAA,kBAAA,EAAA,qBAAA,EAAA,iBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,cAAA,EAAA,eAAA,EAAA,WAAA,EAAA,+BAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGtG,mCAAmC,EAAA,UAAA,EAAA,CAAA;kBAT/C,SAAS;AAEE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gCAAgC,EAG9B,UAAA,EAAA,IAAI,EACP,OAAA,EAAA,CAAC,eAAe,EAAE,gBAAgB,EAAE,8BAA8B,EAAE,oCAAoC,CAAC,EACjG,eAAA,EAAA,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,+5GAAA,EAAA,MAAA,EAAA,CAAA,mHAAA,CAAA,EAAA,CAAA;;;AEjBjD;;AAEG;;;;"}
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@libs-ui/components-radio-group",
3
- "version": "0.2.356-9",
3
+ "version": "0.2.357-0",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=18.0.0",
6
6
  "@angular/core": ">=18.0.0",
7
- "@libs-ui/components-buttons-button": "0.2.356-9",
8
- "@libs-ui/components-label": "0.2.356-9",
9
- "@libs-ui/components-radio-single": "0.2.356-9",
10
- "@libs-ui/utils": "0.2.356-9",
7
+ "@libs-ui/components-buttons-button": "0.2.357-0",
8
+ "@libs-ui/components-label": "0.2.357-0",
9
+ "@libs-ui/components-radio-single": "0.2.357-0",
10
+ "@libs-ui/utils": "0.2.357-0",
11
11
  "@ngx-translate/core": "^15.0.0",
12
- "@libs-ui/interfaces-types": "0.2.356-9"
12
+ "@libs-ui/interfaces-types": "0.2.357-0"
13
13
  },
14
14
  "sideEffects": false,
15
15
  "module": "fesm2022/libs-ui-components-radio-group.mjs",