codexly-ui 0.4.1 → 0.4.2

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.
@@ -1156,6 +1156,7 @@ class ClxTagComponent {
1156
1156
  <ng-content />
1157
1157
  <button
1158
1158
  clx-button
1159
+ type="button"
1159
1160
  variant="ghost"
1160
1161
  [color]="_closeBtnColor()"
1161
1162
  shape="circle"
@@ -1177,6 +1178,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
1177
1178
  <ng-content />
1178
1179
  <button
1179
1180
  clx-button
1181
+ type="button"
1180
1182
  variant="ghost"
1181
1183
  [color]="_closeBtnColor()"
1182
1184
  shape="circle"
@@ -2727,6 +2729,7 @@ class ClxInputComponent {
2727
2729
  @if (type() === 'password') {
2728
2730
  <div class="absolute right-0 top-0 h-full flex items-center pr-1">
2729
2731
  <button clx-button
2732
+ type="button"
2730
2733
  variant="ghost"
2731
2734
  [color]="_color()"
2732
2735
  shape="circle"
@@ -2821,6 +2824,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
2821
2824
  @if (type() === 'password') {
2822
2825
  <div class="absolute right-0 top-0 h-full flex items-center pr-1">
2823
2826
  <button clx-button
2827
+ type="button"
2824
2828
  variant="ghost"
2825
2829
  [color]="_color()"
2826
2830
  shape="circle"
@@ -3344,6 +3348,7 @@ class ClxNumberComponent {
3344
3348
  <!-- − + buttons -->
3345
3349
  <div class="flex items-center self-center pr-1 gap-0">
3346
3350
  <button clx-button
3351
+ type="button"
3347
3352
  variant="ghost"
3348
3353
  [color]="_color()"
3349
3354
  shape="circle"
@@ -3354,6 +3359,7 @@ class ClxNumberComponent {
3354
3359
  (mousedown)="$event.preventDefault()"
3355
3360
  (click)="_decrement()"></button>
3356
3361
  <button clx-button
3362
+ type="button"
3357
3363
  variant="ghost"
3358
3364
  [color]="_color()"
3359
3365
  shape="circle"
@@ -3373,6 +3379,7 @@ class ClxNumberComponent {
3373
3379
 
3374
3380
  <!-- Decrement -->
3375
3381
  <button clx-button
3382
+ type="button"
3376
3383
  variant="ghost"
3377
3384
  [color]="_color()"
3378
3385
  shape="circle"
@@ -3388,6 +3395,7 @@ class ClxNumberComponent {
3388
3395
 
3389
3396
  <!-- Increment -->
3390
3397
  <button clx-button
3398
+ type="button"
3391
3399
  variant="ghost"
3392
3400
  [color]="_color()"
3393
3401
  shape="circle"
@@ -3457,6 +3465,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
3457
3465
  <!-- − + buttons -->
3458
3466
  <div class="flex items-center self-center pr-1 gap-0">
3459
3467
  <button clx-button
3468
+ type="button"
3460
3469
  variant="ghost"
3461
3470
  [color]="_color()"
3462
3471
  shape="circle"
@@ -3467,6 +3476,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
3467
3476
  (mousedown)="$event.preventDefault()"
3468
3477
  (click)="_decrement()"></button>
3469
3478
  <button clx-button
3479
+ type="button"
3470
3480
  variant="ghost"
3471
3481
  [color]="_color()"
3472
3482
  shape="circle"
@@ -3486,6 +3496,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
3486
3496
 
3487
3497
  <!-- Decrement -->
3488
3498
  <button clx-button
3499
+ type="button"
3489
3500
  variant="ghost"
3490
3501
  [color]="_color()"
3491
3502
  shape="circle"
@@ -3501,6 +3512,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
3501
3512
 
3502
3513
  <!-- Increment -->
3503
3514
  <button clx-button
3515
+ type="button"
3504
3516
  variant="ghost"
3505
3517
  [color]="_color()"
3506
3518
  shape="circle"
@@ -3821,6 +3833,7 @@ class ClxSelectComponent {
3821
3833
  @if (_hasValue() && !_disabled() && multiple()) {
3822
3834
  <button
3823
3835
  clx-button
3836
+ type="button"
3824
3837
  variant="ghost"
3825
3838
  [color]="_activeColor()"
3826
3839
  shape="circle"
@@ -3833,6 +3846,7 @@ class ClxSelectComponent {
3833
3846
  }
3834
3847
  <button
3835
3848
  clx-button
3849
+ type="button"
3836
3850
  variant="ghost"
3837
3851
  [color]="_activeColor()"
3838
3852
  shape="circle"
@@ -3968,6 +3982,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
3968
3982
  @if (_hasValue() && !_disabled() && multiple()) {
3969
3983
  <button
3970
3984
  clx-button
3985
+ type="button"
3971
3986
  variant="ghost"
3972
3987
  [color]="_activeColor()"
3973
3988
  shape="circle"
@@ -3980,6 +3995,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
3980
3995
  }
3981
3996
  <button
3982
3997
  clx-button
3998
+ type="button"
3983
3999
  variant="ghost"
3984
4000
  [color]="_activeColor()"
3985
4001
  shape="circle"
@@ -5781,6 +5797,7 @@ class ClxColorPickerComponent {
5781
5797
  @if (_hasValue() && !_disabled()) {
5782
5798
  <button
5783
5799
  clx-button
5800
+ type="button"
5784
5801
  variant="ghost"
5785
5802
  [color]="_activeColor()"
5786
5803
  shape="circle"
@@ -5793,6 +5810,7 @@ class ClxColorPickerComponent {
5793
5810
  }
5794
5811
  <button
5795
5812
  clx-button
5813
+ type="button"
5796
5814
  variant="ghost"
5797
5815
  [color]="_activeColor()"
5798
5816
  shape="circle"
@@ -5948,6 +5966,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
5948
5966
  @if (_hasValue() && !_disabled()) {
5949
5967
  <button
5950
5968
  clx-button
5969
+ type="button"
5951
5970
  variant="ghost"
5952
5971
  [color]="_activeColor()"
5953
5972
  shape="circle"
@@ -5960,6 +5979,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
5960
5979
  }
5961
5980
  <button
5962
5981
  clx-button
5982
+ type="button"
5963
5983
  variant="ghost"
5964
5984
  [color]="_activeColor()"
5965
5985
  shape="circle"
@@ -6335,7 +6355,7 @@ class ClxDatepickerComponent {
6335
6355
 
6336
6356
  @if (_value() && !_disabled()) {
6337
6357
  <div class="absolute right-0 top-0 h-full flex items-center pr-1">
6338
- <button clx-button variant="ghost" [color]="_color()" shape="circle" size="sm"
6358
+ <button clx-button type="button" variant="ghost" [color]="_color()" shape="circle" size="sm"
6339
6359
  icon="close" [iconOnly]="true"
6340
6360
  (mousedown)="$event.preventDefault()"
6341
6361
  (click)="$event.stopPropagation(); _clear()"></button>
@@ -6357,12 +6377,12 @@ class ClxDatepickerComponent {
6357
6377
  <div [class]="_panelClass()" role="dialog" aria-label="Calendario">
6358
6378
 
6359
6379
  <div class="flex items-center justify-between px-4 py-3 border-b border-clx-border-soft">
6360
- <button clx-button variant="ghost" [color]="_color()" shape="circle" size="sm"
6380
+ <button clx-button type="button" variant="ghost" [color]="_color()" shape="circle" size="sm"
6361
6381
  icon="chevron_left" [iconOnly]="true" (click)="_prevMonth()"></button>
6362
6382
  <button type="button" [class]="_headerLabelCls()" (click)="_toggleYearView()">
6363
6383
  {{ _headerLabel() }}
6364
6384
  </button>
6365
- <button clx-button variant="ghost" [color]="_color()" shape="circle" size="sm"
6385
+ <button clx-button type="button" variant="ghost" [color]="_color()" shape="circle" size="sm"
6366
6386
  icon="chevron_right" [iconOnly]="true" (click)="_nextMonth()"></button>
6367
6387
  </div>
6368
6388
 
@@ -6389,8 +6409,8 @@ class ClxDatepickerComponent {
6389
6409
  }
6390
6410
 
6391
6411
  <div class="flex items-center justify-between px-4 py-2 border-t border-clx-border-soft">
6392
- <button clx-button variant="ghost" [color]="_color()" size="sm" (click)="_selectToday()">Hoy</button>
6393
- <button clx-button variant="ghost" color="slate" size="sm" (click)="_closePanel()">Cerrar</button>
6412
+ <button clx-button type="button" variant="ghost" [color]="_color()" size="sm" (click)="_selectToday()">Hoy</button>
6413
+ <button clx-button type="button" variant="ghost" color="slate" size="sm" (click)="_closePanel()">Cerrar</button>
6394
6414
  </div>
6395
6415
 
6396
6416
  </div>
@@ -6435,7 +6455,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
6435
6455
 
6436
6456
  @if (_value() && !_disabled()) {
6437
6457
  <div class="absolute right-0 top-0 h-full flex items-center pr-1">
6438
- <button clx-button variant="ghost" [color]="_color()" shape="circle" size="sm"
6458
+ <button clx-button type="button" variant="ghost" [color]="_color()" shape="circle" size="sm"
6439
6459
  icon="close" [iconOnly]="true"
6440
6460
  (mousedown)="$event.preventDefault()"
6441
6461
  (click)="$event.stopPropagation(); _clear()"></button>
@@ -6457,12 +6477,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
6457
6477
  <div [class]="_panelClass()" role="dialog" aria-label="Calendario">
6458
6478
 
6459
6479
  <div class="flex items-center justify-between px-4 py-3 border-b border-clx-border-soft">
6460
- <button clx-button variant="ghost" [color]="_color()" shape="circle" size="sm"
6480
+ <button clx-button type="button" variant="ghost" [color]="_color()" shape="circle" size="sm"
6461
6481
  icon="chevron_left" [iconOnly]="true" (click)="_prevMonth()"></button>
6462
6482
  <button type="button" [class]="_headerLabelCls()" (click)="_toggleYearView()">
6463
6483
  {{ _headerLabel() }}
6464
6484
  </button>
6465
- <button clx-button variant="ghost" [color]="_color()" shape="circle" size="sm"
6485
+ <button clx-button type="button" variant="ghost" [color]="_color()" shape="circle" size="sm"
6466
6486
  icon="chevron_right" [iconOnly]="true" (click)="_nextMonth()"></button>
6467
6487
  </div>
6468
6488
 
@@ -6489,8 +6509,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
6489
6509
  }
6490
6510
 
6491
6511
  <div class="flex items-center justify-between px-4 py-2 border-t border-clx-border-soft">
6492
- <button clx-button variant="ghost" [color]="_color()" size="sm" (click)="_selectToday()">Hoy</button>
6493
- <button clx-button variant="ghost" color="slate" size="sm" (click)="_closePanel()">Cerrar</button>
6512
+ <button clx-button type="button" variant="ghost" [color]="_color()" size="sm" (click)="_selectToday()">Hoy</button>
6513
+ <button clx-button type="button" variant="ghost" color="slate" size="sm" (click)="_closePanel()">Cerrar</button>
6494
6514
  </div>
6495
6515
 
6496
6516
  </div>
@@ -6663,7 +6683,7 @@ class ClxTimepickerComponent {
6663
6683
 
6664
6684
  @if (_value() && !_disabled()) {
6665
6685
  <div class="absolute right-0 top-0 h-full flex items-center pr-1">
6666
- <button clx-button variant="ghost" [color]="_color()" shape="circle" size="sm"
6686
+ <button clx-button type="button" variant="ghost" [color]="_color()" shape="circle" size="sm"
6667
6687
  icon="close" [iconOnly]="true"
6668
6688
  (mousedown)="$event.preventDefault()"
6669
6689
  (click)="$event.stopPropagation(); _clear()"></button>
@@ -6704,8 +6724,8 @@ class ClxTimepickerComponent {
6704
6724
  </div>
6705
6725
 
6706
6726
  <div class="flex items-center justify-between px-4 py-2 border-t border-clx-border-soft">
6707
- <button clx-button variant="ghost" [color]="_color()" size="sm" (click)="_selectNow()">Ahora</button>
6708
- <button clx-button variant="ghost" color="slate" size="sm" (click)="_closePanel()">Cerrar</button>
6727
+ <button clx-button type="button" variant="ghost" [color]="_color()" size="sm" (click)="_selectNow()">Ahora</button>
6728
+ <button clx-button type="button" variant="ghost" color="slate" size="sm" (click)="_closePanel()">Cerrar</button>
6709
6729
  </div>
6710
6730
 
6711
6731
  </div>
@@ -6750,7 +6770,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
6750
6770
 
6751
6771
  @if (_value() && !_disabled()) {
6752
6772
  <div class="absolute right-0 top-0 h-full flex items-center pr-1">
6753
- <button clx-button variant="ghost" [color]="_color()" shape="circle" size="sm"
6773
+ <button clx-button type="button" variant="ghost" [color]="_color()" shape="circle" size="sm"
6754
6774
  icon="close" [iconOnly]="true"
6755
6775
  (mousedown)="$event.preventDefault()"
6756
6776
  (click)="$event.stopPropagation(); _clear()"></button>
@@ -6791,8 +6811,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
6791
6811
  </div>
6792
6812
 
6793
6813
  <div class="flex items-center justify-between px-4 py-2 border-t border-clx-border-soft">
6794
- <button clx-button variant="ghost" [color]="_color()" size="sm" (click)="_selectNow()">Ahora</button>
6795
- <button clx-button variant="ghost" color="slate" size="sm" (click)="_closePanel()">Cerrar</button>
6814
+ <button clx-button type="button" variant="ghost" [color]="_color()" size="sm" (click)="_selectNow()">Ahora</button>
6815
+ <button clx-button type="button" variant="ghost" color="slate" size="sm" (click)="_closePanel()">Cerrar</button>
6796
6816
  </div>
6797
6817
 
6798
6818
  </div>
@@ -7151,7 +7171,7 @@ class ClxDateRangePickerComponent {
7151
7171
 
7152
7172
  @if (_hasValue() && !_disabled()) {
7153
7173
  <div class="absolute right-0 top-0 h-full flex items-center pr-1">
7154
- <button clx-button variant="ghost" [color]="_color()" shape="circle" size="sm"
7174
+ <button clx-button type="button" variant="ghost" [color]="_color()" shape="circle" size="sm"
7155
7175
  icon="close" [iconOnly]="true"
7156
7176
  (mousedown)="$event.preventDefault()"
7157
7177
  (click)="$event.stopPropagation(); _clear()"></button>
@@ -7191,7 +7211,7 @@ class ClxDateRangePickerComponent {
7191
7211
  <!-- Left calendar (cursor month) -->
7192
7212
  <div class="p-4">
7193
7213
  <div class="flex items-center justify-between mb-3">
7194
- <button clx-button variant="ghost" [color]="_color()" shape="circle" size="sm"
7214
+ <button clx-button type="button" variant="ghost" [color]="_color()" shape="circle" size="sm"
7195
7215
  icon="chevron_left" [iconOnly]="true" (click)="_prevMonth()"></button>
7196
7216
  <span class="text-sm font-semibold text-clx-text-label">{{ _leftLabel() }}</span>
7197
7217
  <div class="w-9"></div>
@@ -7219,7 +7239,7 @@ class ClxDateRangePickerComponent {
7219
7239
  <div class="flex items-center justify-between mb-3">
7220
7240
  <div class="w-9"></div>
7221
7241
  <span class="text-sm font-semibold text-clx-text-label">{{ _rightLabel() }}</span>
7222
- <button clx-button variant="ghost" [color]="_color()" shape="circle" size="sm"
7242
+ <button clx-button type="button" variant="ghost" [color]="_color()" shape="circle" size="sm"
7223
7243
  icon="chevron_right" [iconOnly]="true" (click)="_nextMonth()"></button>
7224
7244
  </div>
7225
7245
  <div class="grid grid-cols-7 mb-1">
@@ -7254,8 +7274,8 @@ class ClxDateRangePickerComponent {
7254
7274
  }
7255
7275
  </span>
7256
7276
  <div class="flex items-center gap-2">
7257
- <button clx-button variant="ghost" color="slate" size="sm" (click)="_cancel()">Cancelar</button>
7258
- <button clx-button variant="solid" [color]="_color()" size="sm"
7277
+ <button clx-button type="button" variant="ghost" color="slate" size="sm" (click)="_cancel()">Cancelar</button>
7278
+ <button clx-button type="button" variant="solid" [color]="_color()" size="sm"
7259
7279
  [disabled]="!_canApply()"
7260
7280
  (click)="_apply()">
7261
7281
  Aplicar
@@ -7308,7 +7328,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
7308
7328
 
7309
7329
  @if (_hasValue() && !_disabled()) {
7310
7330
  <div class="absolute right-0 top-0 h-full flex items-center pr-1">
7311
- <button clx-button variant="ghost" [color]="_color()" shape="circle" size="sm"
7331
+ <button clx-button type="button" variant="ghost" [color]="_color()" shape="circle" size="sm"
7312
7332
  icon="close" [iconOnly]="true"
7313
7333
  (mousedown)="$event.preventDefault()"
7314
7334
  (click)="$event.stopPropagation(); _clear()"></button>
@@ -7348,7 +7368,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
7348
7368
  <!-- Left calendar (cursor month) -->
7349
7369
  <div class="p-4">
7350
7370
  <div class="flex items-center justify-between mb-3">
7351
- <button clx-button variant="ghost" [color]="_color()" shape="circle" size="sm"
7371
+ <button clx-button type="button" variant="ghost" [color]="_color()" shape="circle" size="sm"
7352
7372
  icon="chevron_left" [iconOnly]="true" (click)="_prevMonth()"></button>
7353
7373
  <span class="text-sm font-semibold text-clx-text-label">{{ _leftLabel() }}</span>
7354
7374
  <div class="w-9"></div>
@@ -7376,7 +7396,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
7376
7396
  <div class="flex items-center justify-between mb-3">
7377
7397
  <div class="w-9"></div>
7378
7398
  <span class="text-sm font-semibold text-clx-text-label">{{ _rightLabel() }}</span>
7379
- <button clx-button variant="ghost" [color]="_color()" shape="circle" size="sm"
7399
+ <button clx-button type="button" variant="ghost" [color]="_color()" shape="circle" size="sm"
7380
7400
  icon="chevron_right" [iconOnly]="true" (click)="_nextMonth()"></button>
7381
7401
  </div>
7382
7402
  <div class="grid grid-cols-7 mb-1">
@@ -7411,8 +7431,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
7411
7431
  }
7412
7432
  </span>
7413
7433
  <div class="flex items-center gap-2">
7414
- <button clx-button variant="ghost" color="slate" size="sm" (click)="_cancel()">Cancelar</button>
7415
- <button clx-button variant="solid" [color]="_color()" size="sm"
7434
+ <button clx-button type="button" variant="ghost" color="slate" size="sm" (click)="_cancel()">Cancelar</button>
7435
+ <button clx-button type="button" variant="solid" [color]="_color()" size="sm"
7416
7436
  [disabled]="!_canApply()"
7417
7437
  (click)="_apply()">
7418
7438
  Aplicar
@@ -7493,6 +7513,7 @@ class ClxModalComponent {
7493
7513
  @if (showClose()) {
7494
7514
  <button
7495
7515
  clx-button
7516
+ type="button"
7496
7517
  variant="ghost"
7497
7518
  color="zinc"
7498
7519
  shape="circle"
@@ -7516,6 +7537,7 @@ class ClxModalComponent {
7516
7537
  @if (showCancelButton()) {
7517
7538
  <button
7518
7539
  clx-button
7540
+ type="button"
7519
7541
  [color]="_cancelColor()"
7520
7542
  [variant]="_cancelVariant()"
7521
7543
  size="md"
@@ -7525,6 +7547,7 @@ class ClxModalComponent {
7525
7547
  }
7526
7548
  <button
7527
7549
  clx-button
7550
+ type="button"
7528
7551
  [color]="_confirmColor()"
7529
7552
  [variant]="_confirmVariant()"
7530
7553
  size="md"
@@ -7552,6 +7575,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
7552
7575
  @if (showClose()) {
7553
7576
  <button
7554
7577
  clx-button
7578
+ type="button"
7555
7579
  variant="ghost"
7556
7580
  color="zinc"
7557
7581
  shape="circle"
@@ -7575,6 +7599,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
7575
7599
  @if (showCancelButton()) {
7576
7600
  <button
7577
7601
  clx-button
7602
+ type="button"
7578
7603
  [color]="_cancelColor()"
7579
7604
  [variant]="_cancelVariant()"
7580
7605
  size="md"
@@ -7584,6 +7609,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
7584
7609
  }
7585
7610
  <button
7586
7611
  clx-button
7612
+ type="button"
7587
7613
  [color]="_confirmColor()"
7588
7614
  [variant]="_confirmVariant()"
7589
7615
  size="md"
@@ -8288,6 +8314,7 @@ class ClxEditorComponent {
8288
8314
  @for (btn of group; track btn.cmd) {
8289
8315
  <button
8290
8316
  clx-button
8317
+ type="button"
8291
8318
  [variant]="_btnVariant(btn.mark)"
8292
8319
  [color]="_color()"
8293
8320
  size="xs"
@@ -8309,6 +8336,7 @@ class ClxEditorComponent {
8309
8336
  <!-- Text color -->
8310
8337
  <button
8311
8338
  clx-button
8339
+ type="button"
8312
8340
  variant="ghost"
8313
8341
  [color]="_color()"
8314
8342
  size="xs"
@@ -8324,6 +8352,7 @@ class ClxEditorComponent {
8324
8352
  <!-- Highlight -->
8325
8353
  <button
8326
8354
  clx-button
8355
+ type="button"
8327
8356
  variant="ghost"
8328
8357
  [color]="_color()"
8329
8358
  size="xs"
@@ -8342,6 +8371,7 @@ class ClxEditorComponent {
8342
8371
  <!-- HTML source toggle -->
8343
8372
  <button
8344
8373
  clx-button
8374
+ type="button"
8345
8375
  [variant]="_sourceMode() ? 'light' : 'ghost'"
8346
8376
  [color]="_color()"
8347
8377
  size="xs"
@@ -8356,6 +8386,7 @@ class ClxEditorComponent {
8356
8386
  <!-- Copy HTML -->
8357
8387
  <button
8358
8388
  clx-button
8389
+ type="button"
8359
8390
  variant="ghost"
8360
8391
  [color]="_color()"
8361
8392
  size="xs"
@@ -8470,6 +8501,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
8470
8501
  @for (btn of group; track btn.cmd) {
8471
8502
  <button
8472
8503
  clx-button
8504
+ type="button"
8473
8505
  [variant]="_btnVariant(btn.mark)"
8474
8506
  [color]="_color()"
8475
8507
  size="xs"
@@ -8491,6 +8523,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
8491
8523
  <!-- Text color -->
8492
8524
  <button
8493
8525
  clx-button
8526
+ type="button"
8494
8527
  variant="ghost"
8495
8528
  [color]="_color()"
8496
8529
  size="xs"
@@ -8506,6 +8539,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
8506
8539
  <!-- Highlight -->
8507
8540
  <button
8508
8541
  clx-button
8542
+ type="button"
8509
8543
  variant="ghost"
8510
8544
  [color]="_color()"
8511
8545
  size="xs"
@@ -8524,6 +8558,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
8524
8558
  <!-- HTML source toggle -->
8525
8559
  <button
8526
8560
  clx-button
8561
+ type="button"
8527
8562
  [variant]="_sourceMode() ? 'light' : 'ghost'"
8528
8563
  [color]="_color()"
8529
8564
  size="xs"
@@ -8538,6 +8573,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
8538
8573
  <!-- Copy HTML -->
8539
8574
  <button
8540
8575
  clx-button
8576
+ type="button"
8541
8577
  variant="ghost"
8542
8578
  [color]="_color()"
8543
8579
  size="xs"
@@ -8658,6 +8694,7 @@ class ClxTabsComponent {
8658
8694
  @for (tab of tabs(); track tab.id) {
8659
8695
  <div class="flex relative">
8660
8696
  <button clx-button
8697
+ type="button"
8661
8698
  role="tab"
8662
8699
  variant="ghost"
8663
8700
  [color]="activeTab() === tab.id ? _clxColor() : 'slate'"
@@ -8698,6 +8735,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
8698
8735
  @for (tab of tabs(); track tab.id) {
8699
8736
  <div class="flex relative">
8700
8737
  <button clx-button
8738
+ type="button"
8701
8739
  role="tab"
8702
8740
  variant="ghost"
8703
8741
  [color]="activeTab() === tab.id ? _clxColor() : 'slate'"
@@ -8916,6 +8954,7 @@ class ClxWizardComponent {
8916
8954
  @if (_currentIndex() > 0) {
8917
8955
  <button
8918
8956
  clx-button
8957
+ type="button"
8919
8958
  [color]="_color()"
8920
8959
  variant="ghost"
8921
8960
  size="sm"
@@ -8927,6 +8966,7 @@ class ClxWizardComponent {
8927
8966
  @if (_currentIndex() < _lastIndex()) {
8928
8967
  <button
8929
8968
  clx-button
8969
+ type="button"
8930
8970
  [color]="_color()"
8931
8971
  variant="solid"
8932
8972
  size="sm"
@@ -8938,6 +8978,7 @@ class ClxWizardComponent {
8938
8978
  } @else {
8939
8979
  <button
8940
8980
  clx-button
8981
+ type="button"
8941
8982
  color="green"
8942
8983
  variant="solid"
8943
8984
  size="sm"
@@ -9021,6 +9062,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
9021
9062
  @if (_currentIndex() > 0) {
9022
9063
  <button
9023
9064
  clx-button
9065
+ type="button"
9024
9066
  [color]="_color()"
9025
9067
  variant="ghost"
9026
9068
  size="sm"
@@ -9032,6 +9074,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
9032
9074
  @if (_currentIndex() < _lastIndex()) {
9033
9075
  <button
9034
9076
  clx-button
9077
+ type="button"
9035
9078
  [color]="_color()"
9036
9079
  variant="solid"
9037
9080
  size="sm"
@@ -9043,6 +9086,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
9043
9086
  } @else {
9044
9087
  <button
9045
9088
  clx-button
9089
+ type="button"
9046
9090
  color="green"
9047
9091
  variant="solid"
9048
9092
  size="sm"
@@ -9755,7 +9799,7 @@ class ClxProfileComponent {
9755
9799
  @if (menuItems().length) {
9756
9800
  <div class="p-1.5">
9757
9801
  @for (item of menuItems(); track item.action) {
9758
- <button clx-button variant="ghost" [color]="_color()" [block]="true" [icon]="item.icon"
9802
+ <button clx-button type="button" variant="ghost" [color]="_color()" [block]="true" [icon]="item.icon"
9759
9803
  class="justify-start rounded-xl!"
9760
9804
  (click)="_onAction(item.action)">
9761
9805
  {{ item.label }}
@@ -9767,7 +9811,7 @@ class ClxProfileComponent {
9767
9811
 
9768
9812
  <!-- Sign out -->
9769
9813
  <div class="p-1.5">
9770
- <button clx-button variant="ghost" color="red" [block]="true" icon="logout"
9814
+ <button clx-button type="button" variant="ghost" color="red" [block]="true" icon="logout"
9771
9815
  class="justify-start rounded-xl!"
9772
9816
  (click)="_onSignOut()">
9773
9817
  {{ signOutLabel() }}
@@ -9836,7 +9880,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
9836
9880
  @if (menuItems().length) {
9837
9881
  <div class="p-1.5">
9838
9882
  @for (item of menuItems(); track item.action) {
9839
- <button clx-button variant="ghost" [color]="_color()" [block]="true" [icon]="item.icon"
9883
+ <button clx-button type="button" variant="ghost" [color]="_color()" [block]="true" [icon]="item.icon"
9840
9884
  class="justify-start rounded-xl!"
9841
9885
  (click)="_onAction(item.action)">
9842
9886
  {{ item.label }}
@@ -9848,7 +9892,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
9848
9892
 
9849
9893
  <!-- Sign out -->
9850
9894
  <div class="p-1.5">
9851
- <button clx-button variant="ghost" color="red" [block]="true" icon="logout"
9895
+ <button clx-button type="button" variant="ghost" color="red" [block]="true" icon="logout"
9852
9896
  class="justify-start rounded-xl!"
9853
9897
  (click)="_onSignOut()">
9854
9898
  {{ signOutLabel() }}
@@ -9910,6 +9954,7 @@ class ClxDrawerComponent {
9910
9954
  @if (showClose()) {
9911
9955
  <button
9912
9956
  clx-button
9957
+ type="button"
9913
9958
  variant="ghost"
9914
9959
  color="zinc"
9915
9960
  shape="circle"
@@ -9933,6 +9978,7 @@ class ClxDrawerComponent {
9933
9978
  @if (showCancelButton()) {
9934
9979
  <button
9935
9980
  clx-button
9981
+ type="button"
9936
9982
  [color]="_cancelColor()"
9937
9983
  [variant]="_cancelVariant()"
9938
9984
  size="md"
@@ -9942,6 +9988,7 @@ class ClxDrawerComponent {
9942
9988
  }
9943
9989
  <button
9944
9990
  clx-button
9991
+ type="button"
9945
9992
  [color]="_confirmColor()"
9946
9993
  [variant]="_confirmVariant()"
9947
9994
  size="md"
@@ -9969,6 +10016,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
9969
10016
  @if (showClose()) {
9970
10017
  <button
9971
10018
  clx-button
10019
+ type="button"
9972
10020
  variant="ghost"
9973
10021
  color="zinc"
9974
10022
  shape="circle"
@@ -9992,6 +10040,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
9992
10040
  @if (showCancelButton()) {
9993
10041
  <button
9994
10042
  clx-button
10043
+ type="button"
9995
10044
  [color]="_cancelColor()"
9996
10045
  [variant]="_cancelVariant()"
9997
10046
  size="md"
@@ -10001,6 +10050,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
10001
10050
  }
10002
10051
  <button
10003
10052
  clx-button
10053
+ type="button"
10004
10054
  [color]="_confirmColor()"
10005
10055
  [variant]="_confirmVariant()"
10006
10056
  size="md"
@@ -10213,6 +10263,7 @@ class ClxAlertComponent {
10213
10263
  @if (_showCancel()) {
10214
10264
  <button
10215
10265
  clx-button
10266
+ type="button"
10216
10267
  [color]="_cancelColor()"
10217
10268
  [variant]="_cancelVariant()"
10218
10269
  size="md"
@@ -10224,6 +10275,7 @@ class ClxAlertComponent {
10224
10275
 
10225
10276
  <button
10226
10277
  clx-button
10278
+ type="button"
10227
10279
  [color]="_confirmColor()"
10228
10280
  variant="solid"
10229
10281
  size="md"
@@ -10283,6 +10335,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
10283
10335
  @if (_showCancel()) {
10284
10336
  <button
10285
10337
  clx-button
10338
+ type="button"
10286
10339
  [color]="_cancelColor()"
10287
10340
  [variant]="_cancelVariant()"
10288
10341
  size="md"
@@ -10294,6 +10347,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
10294
10347
 
10295
10348
  <button
10296
10349
  clx-button
10350
+ type="button"
10297
10351
  [color]="_confirmColor()"
10298
10352
  variant="solid"
10299
10353
  size="md"
@@ -10580,6 +10634,7 @@ class ClxToastComponent {
10580
10634
  @if (entry().action) {
10581
10635
  <button
10582
10636
  clx-button
10637
+ type="button"
10583
10638
  variant="link"
10584
10639
  [color]="_buttonColor()"
10585
10640
  size="xs"
@@ -10594,6 +10649,7 @@ class ClxToastComponent {
10594
10649
  <!-- Close button -->
10595
10650
  <button
10596
10651
  clx-button
10652
+ type="button"
10597
10653
  variant="ghost"
10598
10654
  [color]="_buttonColor()"
10599
10655
  size="xxs"
@@ -10649,6 +10705,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
10649
10705
  @if (entry().action) {
10650
10706
  <button
10651
10707
  clx-button
10708
+ type="button"
10652
10709
  variant="link"
10653
10710
  [color]="_buttonColor()"
10654
10711
  size="xs"
@@ -10663,6 +10720,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
10663
10720
  <!-- Close button -->
10664
10721
  <button
10665
10722
  clx-button
10723
+ type="button"
10666
10724
  variant="ghost"
10667
10725
  [color]="_buttonColor()"
10668
10726
  size="xxs"
@@ -11132,6 +11190,7 @@ class ClxPaginationComponent {
11132
11190
  <!-- |<< Primera página -->
11133
11191
  <button
11134
11192
  clx-button
11193
+ type="button"
11135
11194
  variant="ghost"
11136
11195
  color="slate"
11137
11196
  [size]="_cfg().btnSize"
@@ -11145,6 +11204,7 @@ class ClxPaginationComponent {
11145
11204
  <!-- < Anterior -->
11146
11205
  <button
11147
11206
  clx-button
11207
+ type="button"
11148
11208
  variant="ghost"
11149
11209
  color="slate"
11150
11210
  [size]="_cfg().btnSize"
@@ -11160,6 +11220,7 @@ class ClxPaginationComponent {
11160
11220
  @if (item.type === 'page') {
11161
11221
  <button
11162
11222
  clx-button
11223
+ type="button"
11163
11224
  [variant]="currentPage() === item.page ? 'solid' : 'ghost'"
11164
11225
  [color]="currentPage() === item.page ? _color() : 'slate'"
11165
11226
  [size]="_cfg().btnSize"
@@ -11177,6 +11238,7 @@ class ClxPaginationComponent {
11177
11238
  <!-- > Siguiente -->
11178
11239
  <button
11179
11240
  clx-button
11241
+ type="button"
11180
11242
  variant="ghost"
11181
11243
  color="slate"
11182
11244
  [size]="_cfg().btnSize"
@@ -11190,6 +11252,7 @@ class ClxPaginationComponent {
11190
11252
  <!-- >>| Última página -->
11191
11253
  <button
11192
11254
  clx-button
11255
+ type="button"
11193
11256
  variant="ghost"
11194
11257
  color="slate"
11195
11258
  [size]="_cfg().btnSize"
@@ -11238,6 +11301,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
11238
11301
  <!-- |<< Primera página -->
11239
11302
  <button
11240
11303
  clx-button
11304
+ type="button"
11241
11305
  variant="ghost"
11242
11306
  color="slate"
11243
11307
  [size]="_cfg().btnSize"
@@ -11251,6 +11315,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
11251
11315
  <!-- < Anterior -->
11252
11316
  <button
11253
11317
  clx-button
11318
+ type="button"
11254
11319
  variant="ghost"
11255
11320
  color="slate"
11256
11321
  [size]="_cfg().btnSize"
@@ -11266,6 +11331,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
11266
11331
  @if (item.type === 'page') {
11267
11332
  <button
11268
11333
  clx-button
11334
+ type="button"
11269
11335
  [variant]="currentPage() === item.page ? 'solid' : 'ghost'"
11270
11336
  [color]="currentPage() === item.page ? _color() : 'slate'"
11271
11337
  [size]="_cfg().btnSize"
@@ -11283,6 +11349,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
11283
11349
  <!-- > Siguiente -->
11284
11350
  <button
11285
11351
  clx-button
11352
+ type="button"
11286
11353
  variant="ghost"
11287
11354
  color="slate"
11288
11355
  [size]="_cfg().btnSize"
@@ -11296,6 +11363,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
11296
11363
  <!-- >>| Última página -->
11297
11364
  <button
11298
11365
  clx-button
11366
+ type="button"
11299
11367
  variant="ghost"
11300
11368
  color="slate"
11301
11369
  [size]="_cfg().btnSize"
@@ -11432,7 +11500,7 @@ class ClxFilterPanelComponent {
11432
11500
  }
11433
11501
  </div>
11434
11502
  @if (_activeCount() > 0) {
11435
- <button clx-button variant="ghost" color="slate" size="sm" (click)="_reset()">
11503
+ <button clx-button type="button" variant="ghost" color="slate" size="sm" (click)="_reset()">
11436
11504
  Limpiar
11437
11505
  </button>
11438
11506
  }
@@ -11542,7 +11610,7 @@ class ClxFilterPanelComponent {
11542
11610
  <!-- Apply footer -->
11543
11611
  @if (showApply()) {
11544
11612
  <div class="px-4 py-3 border-t border-clx-border-soft flex gap-2">
11545
- <button clx-button variant="solid" [color]="_color()" size="sm" class="flex-1" (click)="_apply()">
11613
+ <button clx-button type="button" variant="solid" [color]="_color()" size="sm" class="flex-1" (click)="_apply()">
11546
11614
  Aplicar filtros
11547
11615
  </button>
11548
11616
  </div>
@@ -11566,7 +11634,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
11566
11634
  }
11567
11635
  </div>
11568
11636
  @if (_activeCount() > 0) {
11569
- <button clx-button variant="ghost" color="slate" size="sm" (click)="_reset()">
11637
+ <button clx-button type="button" variant="ghost" color="slate" size="sm" (click)="_reset()">
11570
11638
  Limpiar
11571
11639
  </button>
11572
11640
  }
@@ -11676,7 +11744,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
11676
11744
  <!-- Apply footer -->
11677
11745
  @if (showApply()) {
11678
11746
  <div class="px-4 py-3 border-t border-clx-border-soft flex gap-2">
11679
- <button clx-button variant="solid" [color]="_color()" size="sm" class="flex-1" (click)="_apply()">
11747
+ <button clx-button type="button" variant="solid" [color]="_color()" size="sm" class="flex-1" (click)="_apply()">
11680
11748
  Aplicar filtros
11681
11749
  </button>
11682
11750
  </div>
@@ -11839,6 +11907,7 @@ class ClxCarouselComponent {
11839
11907
  @if (_slides().length > 1) {
11840
11908
  <div class="absolute left-3 top-1/2 -translate-y-1/2 z-10">
11841
11909
  <button clx-button
11910
+ type="button"
11842
11911
  variant="solid"
11843
11912
  color="white"
11844
11913
  shape="circle"
@@ -11853,6 +11922,7 @@ class ClxCarouselComponent {
11853
11922
  <!-- Arrow: Next -->
11854
11923
  <div class="absolute right-3 top-1/2 -translate-y-1/2 z-10">
11855
11924
  <button clx-button
11925
+ type="button"
11856
11926
  variant="solid"
11857
11927
  color="white"
11858
11928
  shape="circle"
@@ -11905,6 +11975,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
11905
11975
  @if (_slides().length > 1) {
11906
11976
  <div class="absolute left-3 top-1/2 -translate-y-1/2 z-10">
11907
11977
  <button clx-button
11978
+ type="button"
11908
11979
  variant="solid"
11909
11980
  color="white"
11910
11981
  shape="circle"
@@ -11919,6 +11990,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
11919
11990
  <!-- Arrow: Next -->
11920
11991
  <div class="absolute right-3 top-1/2 -translate-y-1/2 z-10">
11921
11992
  <button clx-button
11993
+ type="button"
11922
11994
  variant="solid"
11923
11995
  color="white"
11924
11996
  shape="circle"
@@ -12072,6 +12144,7 @@ class ClxPageEmptyComponent {
12072
12144
  @if (ctaLabel()) {
12073
12145
  <button
12074
12146
  clx-button
12147
+ type="button"
12075
12148
  [color]="_ctaColor()"
12076
12149
  variant="solid"
12077
12150
  [icon]="ctaIcon()"
@@ -12105,6 +12178,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
12105
12178
  @if (ctaLabel()) {
12106
12179
  <button
12107
12180
  clx-button
12181
+ type="button"
12108
12182
  [color]="_ctaColor()"
12109
12183
  variant="solid"
12110
12184
  [icon]="ctaIcon()"
@@ -12589,6 +12663,7 @@ class ClxPageNotFoundComponent {
12589
12663
  @if (backLabel()) {
12590
12664
  <button
12591
12665
  clx-button
12666
+ type="button"
12592
12667
  color="indigo"
12593
12668
  variant="solid"
12594
12669
  icon="arrow_back"
@@ -12619,6 +12694,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
12619
12694
  @if (backLabel()) {
12620
12695
  <button
12621
12696
  clx-button
12697
+ type="button"
12622
12698
  color="indigo"
12623
12699
  variant="solid"
12624
12700
  icon="arrow_back"
@@ -12652,6 +12728,7 @@ class ClxPageUnauthorizedComponent {
12652
12728
  @if (loginLabel()) {
12653
12729
  <button
12654
12730
  clx-button
12731
+ type="button"
12655
12732
  color="indigo"
12656
12733
  variant="solid"
12657
12734
  icon="login"
@@ -12662,6 +12739,7 @@ class ClxPageUnauthorizedComponent {
12662
12739
  @if (backLabel()) {
12663
12740
  <button
12664
12741
  clx-button
12742
+ type="button"
12665
12743
  color="slate"
12666
12744
  variant="ghost"
12667
12745
  icon="arrow_back"
@@ -12694,6 +12772,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
12694
12772
  @if (loginLabel()) {
12695
12773
  <button
12696
12774
  clx-button
12775
+ type="button"
12697
12776
  color="indigo"
12698
12777
  variant="solid"
12699
12778
  icon="login"
@@ -12704,6 +12783,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
12704
12783
  @if (backLabel()) {
12705
12784
  <button
12706
12785
  clx-button
12786
+ type="button"
12707
12787
  color="slate"
12708
12788
  variant="ghost"
12709
12789
  icon="arrow_back"
@@ -12742,6 +12822,7 @@ class ClxPageServerErrorComponent {
12742
12822
  @if (retryLabel()) {
12743
12823
  <button
12744
12824
  clx-button
12825
+ type="button"
12745
12826
  color="red"
12746
12827
  variant="solid"
12747
12828
  icon="refresh"
@@ -12752,6 +12833,7 @@ class ClxPageServerErrorComponent {
12752
12833
  @if (backLabel()) {
12753
12834
  <button
12754
12835
  clx-button
12836
+ type="button"
12755
12837
  color="slate"
12756
12838
  variant="ghost"
12757
12839
  icon="arrow_back"
@@ -12788,6 +12870,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
12788
12870
  @if (retryLabel()) {
12789
12871
  <button
12790
12872
  clx-button
12873
+ type="button"
12791
12874
  color="red"
12792
12875
  variant="solid"
12793
12876
  icon="refresh"
@@ -12798,6 +12881,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
12798
12881
  @if (backLabel()) {
12799
12882
  <button
12800
12883
  clx-button
12884
+ type="button"
12801
12885
  color="slate"
12802
12886
  variant="ghost"
12803
12887
  icon="arrow_back"
@@ -13233,6 +13317,7 @@ class ClxProductComponent {
13233
13317
  <div class="absolute bottom-3 right-3">
13234
13318
  <button
13235
13319
  clx-button
13320
+ type="button"
13236
13321
  [color]="clxColor()"
13237
13322
  variant="solid"
13238
13323
  [size]="_buttonSize()"
@@ -13276,6 +13361,7 @@ class ClxProductComponent {
13276
13361
  <div [class]="_actionsClass()">
13277
13362
  <button
13278
13363
  clx-button
13364
+ type="button"
13279
13365
  [color]="clxColor()"
13280
13366
  variant="solid"
13281
13367
  [size]="_buttonSize()"
@@ -13366,6 +13452,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
13366
13452
  <div class="absolute bottom-3 right-3">
13367
13453
  <button
13368
13454
  clx-button
13455
+ type="button"
13369
13456
  [color]="clxColor()"
13370
13457
  variant="solid"
13371
13458
  [size]="_buttonSize()"
@@ -13409,6 +13496,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
13409
13496
  <div [class]="_actionsClass()">
13410
13497
  <button
13411
13498
  clx-button
13499
+ type="button"
13412
13500
  [color]="clxColor()"
13413
13501
  variant="solid"
13414
13502
  [size]="_buttonSize()"
@@ -13504,7 +13592,7 @@ class ClxProductDetailComponent {
13504
13592
  specsLeft(specs) { return specs.slice(0, Math.ceil(specs.length / 2)); }
13505
13593
  specsRight(specs) { return specs.slice(Math.ceil(specs.length / 2)); }
13506
13594
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxProductDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13507
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxProductDetailComponent, isStandalone: true, selector: "clx-product-detail", inputs: { product: { classPropertyName: "product", publicName: "product", isSignal: true, isRequired: false, transformFunction: null }, clxColor: { classPropertyName: "clxColor", publicName: "clxColor", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, currency: { classPropertyName: "currency", publicName: "currency", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "_carousel", first: true, predicate: ClxCarouselComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<!-- \u2550\u2550 SKELETON \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n@if (loading()) {\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-8 p-6\">\n <div class=\"space-y-3\">\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"420px\" class=\"rounded-2xl\"></clx-skeleton>\n <div class=\"flex gap-2\">\n @for (t of [1,2,3,4]; track t) {\n <clx-skeleton variant=\"rectangular\" width=\"80px\" height=\"80px\" class=\"rounded-xl\"></clx-skeleton>\n }\n </div>\n </div>\n <div class=\"space-y-4 pt-2\">\n <clx-skeleton variant=\"text\" size=\"lg\" width=\"70%\"></clx-skeleton>\n <clx-skeleton variant=\"text\" size=\"sm\" width=\"40%\"></clx-skeleton>\n <clx-skeleton variant=\"text\" size=\"xl\" width=\"50%\"></clx-skeleton>\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"100px\" class=\"rounded-xl\"></clx-skeleton>\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"52px\" class=\"rounded-xl\"></clx-skeleton>\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"52px\" class=\"rounded-xl\"></clx-skeleton>\n </div>\n </div>\n}\n\n<!-- \u2550\u2550 CONTENT \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n@if (!loading() && product(); as p) {\n @let v = activeVariation();\n <div class=\"space-y-8\">\n\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-8 xl:items-start\">\n\n <!-- \u2500\u2500 Column 1: Image Gallery \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"space-y-3\">\n <div class=\"relative\">\n <clx-carousel [clxColor]=\"clxColor()\" aspectRatio=\"4/3\" [loop]=\"true\">\n @for (img of v?.images ?? []; track img) {\n <ng-template clxSlide>\n <img [src]=\"img\" [alt]=\"p.product_name\" class=\"w-full h-full object-cover\" loading=\"lazy\" />\n </ng-template>\n }\n </clx-carousel>\n <div class=\"absolute top-3 right-3 z-10\">\n <button clx-button variant=\"solid\" [color]=\"clxColor()\" shape=\"circle\" size=\"md\"\n [iconOnly]=\"true\" clxTooltip=\"Add to Wishlist\" [clxTooltipColor]=\"clxColor()\" clxTooltipPosition=\"left\">\n <span clx-icon name=\"favorite_border\" size=\"sm\"></span>\n </button>\n </div>\n </div>\n <div class=\"flex flex-wrap gap-2\">\n @for (img of v?.images ?? []; track img; let i = $index) {\n <img [src]=\"img\" [alt]=\"p.product_name\"\n class=\"w-20 h-20 rounded-xl object-cover border-[3px] cursor-pointer shrink-0 transition-[border-color,opacity]\"\n [class]=\"_carousel()?.currentPageIndex() === i\n ? 'border-' + clxColor() + '-500 opacity-100'\n : 'border-transparent opacity-60 hover:opacity-90'\"\n loading=\"lazy\"\n (click)=\"_carousel()?.goTo(i)\" />\n }\n </div>\n </div>\n\n <!-- \u2500\u2500 Column 2: Purchase Info \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"space-y-5\">\n\n <!-- Tags (st_products.tags) -->\n <div class=\"flex flex-wrap gap-2\">\n @for (tag of p.tags; track tag) {\n <span clx-badge variant=\"light\" [color]=\"clxColor()\" size=\"sm\" shape=\"pill\">{{ tag }}</span>\n }\n </div>\n\n <!-- Title -->\n <div>\n <p class=\"text-xs text-clx-text-subtle uppercase tracking-wide font-medium\">{{ p.trademark }}</p>\n <h1 class=\"text-2xl font-bold text-clx-text-label leading-tight mt-0.5\">{{ p.product_name }}</h1>\n @if (v?.description) {\n <p class=\"text-clx-text-muted text-sm mt-1\">{{ v!.description }}</p>\n }\n </div>\n\n <!-- Rating -->\n <div class=\"flex items-center gap-2\">\n <clx-rating [value]=\"p.rating\" [color]=\"clxColor()\"></clx-rating>\n <span class=\"text-sm font-semibold text-clx-text-label\">{{ p.rating | number:'1.1-1' }}</span>\n <span class=\"text-sm text-clx-text-subtle\">({{ p.review_count }} reviews)</span>\n </div>\n\n <!-- Price block -->\n <div class=\"py-4\">\n <div class=\"flex items-baseline gap-3\">\n <span class=\"text-4xl font-black text-clx-text-label\">\n {{ finalPrice() | currency:currency():'symbol':'1.0-0' }}\n </span>\n @if (p.has_discount && p.discount_price) {\n <span class=\"text-lg text-clx-text-subtle line-through\">\n {{ p.discount_price | currency:currency():'symbol':'1.0-0' }}\n </span>\n <span clx-badge variant=\"solid\" [color]=\"clxColor()\" size=\"sm\" shape=\"pill\">\n -{{ discount() }}%\n </span>\n }\n </div>\n @if (v && !v.in_stock) {\n <p class=\"text-sm text-rose-500 font-medium mt-1\">Out of stock</p>\n }\n </div>\n\n <!-- Selectores de variaci\u00F3n (st_spec_types + st_spec_options) -->\n @for (specType of p.spec_types; track specType.id) {\n @if (specType.input_type === 'color') {\n <clx-button-group [label]=\"specType.name\" shape=\"circular\" [attached]=\"false\">\n @for (opt of specType.options; track opt.id) {\n <button clx-button\n [variant]=\"isSpecSelected(specType.id, opt.id) ? 'solid' : 'outline'\"\n [color]=\"asColor(opt.value)\"\n shape=\"circle\" size=\"xs\" [iconOnly]=\"true\"\n [disabled]=\"!isOptionAvailable(specType.id, opt.id)\"\n [clxTooltip]=\"opt.value\"\n [clxTooltipColor]=\"asColor(opt.value)\"\n clxTooltipPosition=\"top\"\n (click)=\"selectSpec(specType.id, opt.id)\">\n </button>\n }\n </clx-button-group>\n } @else {\n <clx-button-group [label]=\"specType.name\" shape=\"flat\" [attached]=\"false\">\n @for (opt of specType.options; track opt.id) {\n <button clx-button\n [variant]=\"isSpecSelected(specType.id, opt.id) ? 'solid' : 'outline'\"\n [color]=\"clxColor()\" size=\"sm\"\n [disabled]=\"!isOptionAvailable(specType.id, opt.id)\"\n (click)=\"selectSpec(specType.id, opt.id)\">\n {{ opt.value }}\n </button>\n }\n </clx-button-group>\n }\n }\n\n <!-- Quantity -->\n <clx-number label=\"Quantity:\" variant=\"stepper\" [color]=\"clxColor()\"\n [min]=\"1\" [max]=\"99\" [ngModel]=\"quantity()\" (ngModelChange)=\"quantity.set($event)\">\n </clx-number>\n\n <!-- CTA -->\n <div class=\"flex gap-3\">\n <button clx-button variant=\"solid\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"bolt\"\n [disabled]=\"!v?.in_stock\">Buy Now</button>\n <button clx-button variant=\"light\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"shopping_cart\"\n [disabled]=\"!v?.in_stock\">Add to Cart</button>\n </div>\n\n </div>\n </div>\n\n <!-- \u2500\u2500 Tabs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <clx-tabs [tabs]=\"tabItems\" [clxColor]=\"clxColor()\" [(activeTab)]=\"activeTab\">\n\n <!-- Tab: Caracter\u00EDsticas generales (st_product_specs \u2014 ficha t\u00E9cnica global) -->\n <ng-template [clxTabPanel]=\"'general'\">\n <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-x-8\">\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (spec of specsLeft(p.product_specs); track spec.id) {\n <clx-list-item [label]=\"spec.name + ':'\" [sublabel]=\"spec.value\" [icon]=\"spec.icon ?? ''\" />\n }\n </clx-list>\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (spec of specsRight(p.product_specs); track spec.id) {\n <clx-list-item [label]=\"spec.name + ':'\" [sublabel]=\"spec.value\" [icon]=\"spec.icon ?? ''\" />\n }\n </clx-list>\n </div>\n </ng-template>\n\n <!-- Tab: Especificaciones (st_spec_types \u2014 specs de la variaci\u00F3n activa) -->\n <ng-template [clxTabPanel]=\"'specs'\">\n <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-x-8\">\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (st of specsLeft(p.spec_types); track st.id) {\n <clx-list-item [label]=\"st.name + ':'\" [sublabel]=\"selectedOptionLabel(st)\" [icon]=\"st.icon ?? ''\" />\n }\n </clx-list>\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (st of specsRight(p.spec_types); track st.id) {\n <clx-list-item [label]=\"st.name + ':'\" [sublabel]=\"selectedOptionLabel(st)\" [icon]=\"st.icon ?? ''\" />\n }\n </clx-list>\n </div>\n </ng-template>\n\n <!-- Tab: Descripci\u00F3n (st_product_descriptions) -->\n <ng-template [clxTabPanel]=\"'description'\">\n <div class=\"space-y-5 max-w-3xl\">\n @for (block of p.descriptions; track block.id) {\n <div>\n @if (block.title) {\n <h3 class=\"text-base font-semibold text-clx-text-label mb-1\">{{ block.title }}</h3>\n }\n <p class=\"text-sm text-clx-text-muted leading-relaxed\">{{ block.body }}</p>\n </div>\n }\n </div>\n </ng-template>\n\n </clx-tabs>\n\n <!-- \u2500\u2500 Reviews \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"grid grid-cols-1 xl:grid-cols-3 gap-8 border-t border-clx-border pt-8\">\n\n <div class=\"space-y-3\">\n <h2 class=\"text-base font-bold text-clx-text-label\">Customer Reviews</h2>\n <div class=\"flex items-end gap-3\">\n <span class=\"text-5xl font-black text-clx-text-label\">{{ p.rating | number:'1.1-1' }}</span>\n <div class=\"pb-1 space-y-1\">\n <clx-rating [value]=\"p.rating\" [color]=\"clxColor()\"></clx-rating>\n <p class=\"text-xs text-clx-text-muted\">{{ p.review_count }} verified ratings</p>\n </div>\n </div>\n <p class=\"text-sm font-semibold\" [class]=\"'text-' + clxColor() + '-600'\">Very Good</p>\n <div class=\"pt-2 space-y-2\">\n <button clx-button variant=\"solid\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"rate_review\">\n Leave Us a Review\n </button>\n <button clx-button variant=\"light\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"flag\">\n Report abuse\n </button>\n </div>\n </div>\n\n <div class=\"lg:col-span-2 space-y-4\">\n @for (review of p.reviews ?? []; track review.id) {\n <div class=\"rounded-2xl overflow-hidden shadow-sm\">\n <div class=\"flex items-center gap-3 px-4 py-3\">\n <div class=\"w-10 h-10 rounded-full bg-clx-surface-2 flex items-center justify-center shrink-0\">\n <span class=\"text-sm font-bold text-clx-text-muted\">\n {{ review.author_name.substring(0,1) }}{{ review.author_name.split(' ')[1]?.substring(0,1) ?? '' }}\n </span>\n </div>\n <div class=\"flex-1 min-w-0\">\n <p class=\"font-semibold text-sm text-clx-text-label truncate\">{{ review.author_name }}</p>\n <p class=\"text-xs text-clx-text-subtle\">{{ review.created_at }}</p>\n </div>\n @if (review.is_verified) {\n <span clx-badge variant=\"light\" color=\"emerald\" size=\"sm\" shape=\"pill\">Verified</span>\n }\n </div>\n <div class=\"px-4 pb-4 space-y-2\">\n <div class=\"flex items-center gap-2\">\n <clx-rating [value]=\"review.rating\" [color]=\"clxColor()\"></clx-rating>\n @if (review.title) {\n <span class=\"text-sm font-semibold text-clx-text-label\">{{ review.title }}</span>\n }\n </div>\n @if (review.body) {\n <p class=\"text-sm text-clx-text-muted\">{{ review.body }}</p>\n }\n <div class=\"flex items-center gap-3 pt-1\">\n <span class=\"text-xs text-clx-text-subtle\">Helpful?</span>\n <button clx-button variant=\"ghost\" color=\"slate\" size=\"xs\" icon=\"thumb_up\">{{ review.helpful }}</button>\n <button clx-button variant=\"ghost\" color=\"slate\" size=\"xs\" icon=\"thumb_down\">{{ review.not_helpful }}</button>\n </div>\n </div>\n </div>\n }\n </div>\n\n </div>\n\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ClxButtonComponent, selector: "button[clx-button], a[clx-button]", inputs: ["variant", "color", "size", "shape", "loading", "disabled", "block", "icon", "iconPosition", "iconOnly", "badge", "badgeColor"] }, { kind: "component", type: ClxButtonGroupComponent, selector: "clx-button-group", inputs: ["label", "shape", "attached", "orientation"] }, { kind: "component", type: ClxBadgeComponent, selector: "span[clx-badge]", inputs: ["variant", "color", "size", "shape", "positioned"] }, { kind: "component", type: ClxIconComponent, selector: "span[clx-icon]", inputs: ["name", "size", "color", "fill"] }, { kind: "component", type: ClxSkeletonComponent, selector: "clx-skeleton", inputs: ["variant", "size", "width", "height"] }, { kind: "component", type: ClxRatingComponent, selector: "clx-rating", inputs: ["value", "max", "color"] }, { kind: "component", type: ClxCarouselComponent, selector: "clx-carousel", inputs: ["clxColor", "autoPlay", "interval", "loop", "aspectRatio", "transparent"] }, { kind: "directive", type: ClxCarouselDirective, selector: "[clxSlide]" }, { kind: "component", type: ClxTabsComponent, selector: "clx-tabs", inputs: ["tabs", "clxColor", "activeTab"], outputs: ["activeTabChange"] }, { kind: "directive", type: ClxTabDirective, selector: "[clxTabPanel]", inputs: ["clxTabPanel"] }, { kind: "component", type: ClxNumberComponent, selector: "clx-number", inputs: ["variant", "size", "color", "label", "placeholder", "hint", "prefixIcon", "min", "max", "step", "value", "disabled"] }, { kind: "directive", type: ClxTooltipDirective, selector: "[clxTooltip]", inputs: ["clxTooltip", "clxTooltipPosition", "clxTooltipColor", "clxTooltipSize", "clxTooltipDelay"] }, { kind: "component", type: ClxListComponent, selector: "clx-list", inputs: ["color", "variant", "size", "numbered"] }, { kind: "component", type: ClxListItemComponent, selector: "clx-list-item", inputs: ["label", "sublabel", "icon", "meta", "metaColor", "disabled"] }, { kind: "pipe", type: CurrencyPipe, name: "currency" }, { kind: "pipe", type: DecimalPipe, name: "number" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
13595
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxProductDetailComponent, isStandalone: true, selector: "clx-product-detail", inputs: { product: { classPropertyName: "product", publicName: "product", isSignal: true, isRequired: false, transformFunction: null }, clxColor: { classPropertyName: "clxColor", publicName: "clxColor", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, currency: { classPropertyName: "currency", publicName: "currency", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "_carousel", first: true, predicate: ClxCarouselComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<!-- \u2550\u2550 SKELETON \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n@if (loading()) {\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-8 p-6\">\n <div class=\"space-y-3\">\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"420px\" class=\"rounded-2xl\"></clx-skeleton>\n <div class=\"flex gap-2\">\n @for (t of [1,2,3,4]; track t) {\n <clx-skeleton variant=\"rectangular\" width=\"80px\" height=\"80px\" class=\"rounded-xl\"></clx-skeleton>\n }\n </div>\n </div>\n <div class=\"space-y-4 pt-2\">\n <clx-skeleton variant=\"text\" size=\"lg\" width=\"70%\"></clx-skeleton>\n <clx-skeleton variant=\"text\" size=\"sm\" width=\"40%\"></clx-skeleton>\n <clx-skeleton variant=\"text\" size=\"xl\" width=\"50%\"></clx-skeleton>\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"100px\" class=\"rounded-xl\"></clx-skeleton>\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"52px\" class=\"rounded-xl\"></clx-skeleton>\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"52px\" class=\"rounded-xl\"></clx-skeleton>\n </div>\n </div>\n}\n\n<!-- \u2550\u2550 CONTENT \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n@if (!loading() && product(); as p) {\n @let v = activeVariation();\n <div class=\"space-y-8\">\n\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-8 xl:items-start\">\n\n <!-- \u2500\u2500 Column 1: Image Gallery \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"space-y-3\">\n <div class=\"relative\">\n <clx-carousel [clxColor]=\"clxColor()\" aspectRatio=\"4/3\" [loop]=\"true\">\n @for (img of v?.images ?? []; track img) {\n <ng-template clxSlide>\n <img [src]=\"img\" [alt]=\"p.product_name\" class=\"w-full h-full object-cover\" loading=\"lazy\" />\n </ng-template>\n }\n </clx-carousel>\n <div class=\"absolute top-3 right-3 z-10\">\n <button clx-button type=\"button\" variant=\"solid\" [color]=\"clxColor()\" shape=\"circle\" size=\"md\"\n [iconOnly]=\"true\" clxTooltip=\"Add to Wishlist\" [clxTooltipColor]=\"clxColor()\" clxTooltipPosition=\"left\">\n <span clx-icon name=\"favorite_border\" size=\"sm\"></span>\n </button>\n </div>\n </div>\n <div class=\"flex flex-wrap gap-2\">\n @for (img of v?.images ?? []; track img; let i = $index) {\n <img [src]=\"img\" [alt]=\"p.product_name\"\n class=\"w-20 h-20 rounded-xl object-cover border-[3px] cursor-pointer shrink-0 transition-[border-color,opacity]\"\n [class]=\"_carousel()?.currentPageIndex() === i\n ? 'border-' + clxColor() + '-500 opacity-100'\n : 'border-transparent opacity-60 hover:opacity-90'\"\n loading=\"lazy\"\n (click)=\"_carousel()?.goTo(i)\" />\n }\n </div>\n </div>\n\n <!-- \u2500\u2500 Column 2: Purchase Info \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"space-y-5\">\n\n <!-- Tags (st_products.tags) -->\n <div class=\"flex flex-wrap gap-2\">\n @for (tag of p.tags; track tag) {\n <span clx-badge variant=\"light\" [color]=\"clxColor()\" size=\"sm\" shape=\"pill\">{{ tag }}</span>\n }\n </div>\n\n <!-- Title -->\n <div>\n <p class=\"text-xs text-clx-text-subtle uppercase tracking-wide font-medium\">{{ p.trademark }}</p>\n <h1 class=\"text-2xl font-bold text-clx-text-label leading-tight mt-0.5\">{{ p.product_name }}</h1>\n @if (v?.description) {\n <p class=\"text-clx-text-muted text-sm mt-1\">{{ v!.description }}</p>\n }\n </div>\n\n <!-- Rating -->\n <div class=\"flex items-center gap-2\">\n <clx-rating [value]=\"p.rating\" [color]=\"clxColor()\"></clx-rating>\n <span class=\"text-sm font-semibold text-clx-text-label\">{{ p.rating | number:'1.1-1' }}</span>\n <span class=\"text-sm text-clx-text-subtle\">({{ p.review_count }} reviews)</span>\n </div>\n\n <!-- Price block -->\n <div class=\"py-4\">\n <div class=\"flex items-baseline gap-3\">\n <span class=\"text-4xl font-black text-clx-text-label\">\n {{ finalPrice() | currency:currency():'symbol':'1.0-0' }}\n </span>\n @if (p.has_discount && p.discount_price) {\n <span class=\"text-lg text-clx-text-subtle line-through\">\n {{ p.discount_price | currency:currency():'symbol':'1.0-0' }}\n </span>\n <span clx-badge variant=\"solid\" [color]=\"clxColor()\" size=\"sm\" shape=\"pill\">\n -{{ discount() }}%\n </span>\n }\n </div>\n @if (v && !v.in_stock) {\n <p class=\"text-sm text-rose-500 font-medium mt-1\">Out of stock</p>\n }\n </div>\n\n <!-- Selectores de variaci\u00F3n (st_spec_types + st_spec_options) -->\n @for (specType of p.spec_types; track specType.id) {\n @if (specType.input_type === 'color') {\n <clx-button-group [label]=\"specType.name\" shape=\"circular\" [attached]=\"false\">\n @for (opt of specType.options; track opt.id) {\n <button clx-button\n type=\"button\"\n [variant]=\"isSpecSelected(specType.id, opt.id) ? 'solid' : 'outline'\"\n [color]=\"asColor(opt.value)\"\n shape=\"circle\" size=\"xs\" [iconOnly]=\"true\"\n [disabled]=\"!isOptionAvailable(specType.id, opt.id)\"\n [clxTooltip]=\"opt.value\"\n [clxTooltipColor]=\"asColor(opt.value)\"\n clxTooltipPosition=\"top\"\n (click)=\"selectSpec(specType.id, opt.id)\">\n </button>\n }\n </clx-button-group>\n } @else {\n <clx-button-group [label]=\"specType.name\" shape=\"flat\" [attached]=\"false\">\n @for (opt of specType.options; track opt.id) {\n <button clx-button\n type=\"button\"\n [variant]=\"isSpecSelected(specType.id, opt.id) ? 'solid' : 'outline'\"\n [color]=\"clxColor()\" size=\"sm\"\n [disabled]=\"!isOptionAvailable(specType.id, opt.id)\"\n (click)=\"selectSpec(specType.id, opt.id)\">\n {{ opt.value }}\n </button>\n }\n </clx-button-group>\n }\n }\n\n <!-- Quantity -->\n <clx-number label=\"Quantity:\" variant=\"stepper\" [color]=\"clxColor()\"\n [min]=\"1\" [max]=\"99\" [ngModel]=\"quantity()\" (ngModelChange)=\"quantity.set($event)\">\n </clx-number>\n\n <!-- CTA -->\n <div class=\"flex gap-3\">\n <button clx-button type=\"button\" variant=\"solid\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"bolt\"\n [disabled]=\"!v?.in_stock\">Buy Now</button>\n <button clx-button type=\"button\" variant=\"light\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"shopping_cart\"\n [disabled]=\"!v?.in_stock\">Add to Cart</button>\n </div>\n\n </div>\n </div>\n\n <!-- \u2500\u2500 Tabs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <clx-tabs [tabs]=\"tabItems\" [clxColor]=\"clxColor()\" [(activeTab)]=\"activeTab\">\n\n <!-- Tab: Caracter\u00EDsticas generales (st_product_specs \u2014 ficha t\u00E9cnica global) -->\n <ng-template [clxTabPanel]=\"'general'\">\n <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-x-8\">\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (spec of specsLeft(p.product_specs); track spec.id) {\n <clx-list-item [label]=\"spec.name + ':'\" [sublabel]=\"spec.value\" [icon]=\"spec.icon ?? ''\" />\n }\n </clx-list>\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (spec of specsRight(p.product_specs); track spec.id) {\n <clx-list-item [label]=\"spec.name + ':'\" [sublabel]=\"spec.value\" [icon]=\"spec.icon ?? ''\" />\n }\n </clx-list>\n </div>\n </ng-template>\n\n <!-- Tab: Especificaciones (st_spec_types \u2014 specs de la variaci\u00F3n activa) -->\n <ng-template [clxTabPanel]=\"'specs'\">\n <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-x-8\">\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (st of specsLeft(p.spec_types); track st.id) {\n <clx-list-item [label]=\"st.name + ':'\" [sublabel]=\"selectedOptionLabel(st)\" [icon]=\"st.icon ?? ''\" />\n }\n </clx-list>\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (st of specsRight(p.spec_types); track st.id) {\n <clx-list-item [label]=\"st.name + ':'\" [sublabel]=\"selectedOptionLabel(st)\" [icon]=\"st.icon ?? ''\" />\n }\n </clx-list>\n </div>\n </ng-template>\n\n <!-- Tab: Descripci\u00F3n (st_product_descriptions) -->\n <ng-template [clxTabPanel]=\"'description'\">\n <div class=\"space-y-5 max-w-3xl\">\n @for (block of p.descriptions; track block.id) {\n <div>\n @if (block.title) {\n <h3 class=\"text-base font-semibold text-clx-text-label mb-1\">{{ block.title }}</h3>\n }\n <p class=\"text-sm text-clx-text-muted leading-relaxed\">{{ block.body }}</p>\n </div>\n }\n </div>\n </ng-template>\n\n </clx-tabs>\n\n <!-- \u2500\u2500 Reviews \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"grid grid-cols-1 xl:grid-cols-3 gap-8 border-t border-clx-border pt-8\">\n\n <div class=\"space-y-3\">\n <h2 class=\"text-base font-bold text-clx-text-label\">Customer Reviews</h2>\n <div class=\"flex items-end gap-3\">\n <span class=\"text-5xl font-black text-clx-text-label\">{{ p.rating | number:'1.1-1' }}</span>\n <div class=\"pb-1 space-y-1\">\n <clx-rating [value]=\"p.rating\" [color]=\"clxColor()\"></clx-rating>\n <p class=\"text-xs text-clx-text-muted\">{{ p.review_count }} verified ratings</p>\n </div>\n </div>\n <p class=\"text-sm font-semibold\" [class]=\"'text-' + clxColor() + '-600'\">Very Good</p>\n <div class=\"pt-2 space-y-2\">\n <button clx-button type=\"button\" variant=\"solid\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"rate_review\">\n Leave Us a Review\n </button>\n <button clx-button type=\"button\" variant=\"light\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"flag\">\n Report abuse\n </button>\n </div>\n </div>\n\n <div class=\"lg:col-span-2 space-y-4\">\n @for (review of p.reviews ?? []; track review.id) {\n <div class=\"rounded-2xl overflow-hidden shadow-sm\">\n <div class=\"flex items-center gap-3 px-4 py-3\">\n <div class=\"w-10 h-10 rounded-full bg-clx-surface-2 flex items-center justify-center shrink-0\">\n <span class=\"text-sm font-bold text-clx-text-muted\">\n {{ review.author_name.substring(0,1) }}{{ review.author_name.split(' ')[1]?.substring(0,1) ?? '' }}\n </span>\n </div>\n <div class=\"flex-1 min-w-0\">\n <p class=\"font-semibold text-sm text-clx-text-label truncate\">{{ review.author_name }}</p>\n <p class=\"text-xs text-clx-text-subtle\">{{ review.created_at }}</p>\n </div>\n @if (review.is_verified) {\n <span clx-badge variant=\"light\" color=\"emerald\" size=\"sm\" shape=\"pill\">Verified</span>\n }\n </div>\n <div class=\"px-4 pb-4 space-y-2\">\n <div class=\"flex items-center gap-2\">\n <clx-rating [value]=\"review.rating\" [color]=\"clxColor()\"></clx-rating>\n @if (review.title) {\n <span class=\"text-sm font-semibold text-clx-text-label\">{{ review.title }}</span>\n }\n </div>\n @if (review.body) {\n <p class=\"text-sm text-clx-text-muted\">{{ review.body }}</p>\n }\n <div class=\"flex items-center gap-3 pt-1\">\n <span class=\"text-xs text-clx-text-subtle\">Helpful?</span>\n <button clx-button type=\"button\" variant=\"ghost\" color=\"slate\" size=\"xs\" icon=\"thumb_up\">{{ review.helpful }}</button>\n <button clx-button type=\"button\" variant=\"ghost\" color=\"slate\" size=\"xs\" icon=\"thumb_down\">{{ review.not_helpful }}</button>\n </div>\n </div>\n </div>\n }\n </div>\n\n </div>\n\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ClxButtonComponent, selector: "button[clx-button], a[clx-button]", inputs: ["variant", "color", "size", "shape", "loading", "disabled", "block", "icon", "iconPosition", "iconOnly", "badge", "badgeColor"] }, { kind: "component", type: ClxButtonGroupComponent, selector: "clx-button-group", inputs: ["label", "shape", "attached", "orientation"] }, { kind: "component", type: ClxBadgeComponent, selector: "span[clx-badge]", inputs: ["variant", "color", "size", "shape", "positioned"] }, { kind: "component", type: ClxIconComponent, selector: "span[clx-icon]", inputs: ["name", "size", "color", "fill"] }, { kind: "component", type: ClxSkeletonComponent, selector: "clx-skeleton", inputs: ["variant", "size", "width", "height"] }, { kind: "component", type: ClxRatingComponent, selector: "clx-rating", inputs: ["value", "max", "color"] }, { kind: "component", type: ClxCarouselComponent, selector: "clx-carousel", inputs: ["clxColor", "autoPlay", "interval", "loop", "aspectRatio", "transparent"] }, { kind: "directive", type: ClxCarouselDirective, selector: "[clxSlide]" }, { kind: "component", type: ClxTabsComponent, selector: "clx-tabs", inputs: ["tabs", "clxColor", "activeTab"], outputs: ["activeTabChange"] }, { kind: "directive", type: ClxTabDirective, selector: "[clxTabPanel]", inputs: ["clxTabPanel"] }, { kind: "component", type: ClxNumberComponent, selector: "clx-number", inputs: ["variant", "size", "color", "label", "placeholder", "hint", "prefixIcon", "min", "max", "step", "value", "disabled"] }, { kind: "directive", type: ClxTooltipDirective, selector: "[clxTooltip]", inputs: ["clxTooltip", "clxTooltipPosition", "clxTooltipColor", "clxTooltipSize", "clxTooltipDelay"] }, { kind: "component", type: ClxListComponent, selector: "clx-list", inputs: ["color", "variant", "size", "numbered"] }, { kind: "component", type: ClxListItemComponent, selector: "clx-list-item", inputs: ["label", "sublabel", "icon", "meta", "metaColor", "disabled"] }, { kind: "pipe", type: CurrencyPipe, name: "currency" }, { kind: "pipe", type: DecimalPipe, name: "number" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
13508
13596
  }
13509
13597
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxProductDetailComponent, decorators: [{
13510
13598
  type: Component,
@@ -13526,7 +13614,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
13526
13614
  ClxTooltipDirective,
13527
13615
  ClxListComponent,
13528
13616
  ClxListItemComponent,
13529
- ], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- \u2550\u2550 SKELETON \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n@if (loading()) {\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-8 p-6\">\n <div class=\"space-y-3\">\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"420px\" class=\"rounded-2xl\"></clx-skeleton>\n <div class=\"flex gap-2\">\n @for (t of [1,2,3,4]; track t) {\n <clx-skeleton variant=\"rectangular\" width=\"80px\" height=\"80px\" class=\"rounded-xl\"></clx-skeleton>\n }\n </div>\n </div>\n <div class=\"space-y-4 pt-2\">\n <clx-skeleton variant=\"text\" size=\"lg\" width=\"70%\"></clx-skeleton>\n <clx-skeleton variant=\"text\" size=\"sm\" width=\"40%\"></clx-skeleton>\n <clx-skeleton variant=\"text\" size=\"xl\" width=\"50%\"></clx-skeleton>\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"100px\" class=\"rounded-xl\"></clx-skeleton>\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"52px\" class=\"rounded-xl\"></clx-skeleton>\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"52px\" class=\"rounded-xl\"></clx-skeleton>\n </div>\n </div>\n}\n\n<!-- \u2550\u2550 CONTENT \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n@if (!loading() && product(); as p) {\n @let v = activeVariation();\n <div class=\"space-y-8\">\n\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-8 xl:items-start\">\n\n <!-- \u2500\u2500 Column 1: Image Gallery \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"space-y-3\">\n <div class=\"relative\">\n <clx-carousel [clxColor]=\"clxColor()\" aspectRatio=\"4/3\" [loop]=\"true\">\n @for (img of v?.images ?? []; track img) {\n <ng-template clxSlide>\n <img [src]=\"img\" [alt]=\"p.product_name\" class=\"w-full h-full object-cover\" loading=\"lazy\" />\n </ng-template>\n }\n </clx-carousel>\n <div class=\"absolute top-3 right-3 z-10\">\n <button clx-button variant=\"solid\" [color]=\"clxColor()\" shape=\"circle\" size=\"md\"\n [iconOnly]=\"true\" clxTooltip=\"Add to Wishlist\" [clxTooltipColor]=\"clxColor()\" clxTooltipPosition=\"left\">\n <span clx-icon name=\"favorite_border\" size=\"sm\"></span>\n </button>\n </div>\n </div>\n <div class=\"flex flex-wrap gap-2\">\n @for (img of v?.images ?? []; track img; let i = $index) {\n <img [src]=\"img\" [alt]=\"p.product_name\"\n class=\"w-20 h-20 rounded-xl object-cover border-[3px] cursor-pointer shrink-0 transition-[border-color,opacity]\"\n [class]=\"_carousel()?.currentPageIndex() === i\n ? 'border-' + clxColor() + '-500 opacity-100'\n : 'border-transparent opacity-60 hover:opacity-90'\"\n loading=\"lazy\"\n (click)=\"_carousel()?.goTo(i)\" />\n }\n </div>\n </div>\n\n <!-- \u2500\u2500 Column 2: Purchase Info \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"space-y-5\">\n\n <!-- Tags (st_products.tags) -->\n <div class=\"flex flex-wrap gap-2\">\n @for (tag of p.tags; track tag) {\n <span clx-badge variant=\"light\" [color]=\"clxColor()\" size=\"sm\" shape=\"pill\">{{ tag }}</span>\n }\n </div>\n\n <!-- Title -->\n <div>\n <p class=\"text-xs text-clx-text-subtle uppercase tracking-wide font-medium\">{{ p.trademark }}</p>\n <h1 class=\"text-2xl font-bold text-clx-text-label leading-tight mt-0.5\">{{ p.product_name }}</h1>\n @if (v?.description) {\n <p class=\"text-clx-text-muted text-sm mt-1\">{{ v!.description }}</p>\n }\n </div>\n\n <!-- Rating -->\n <div class=\"flex items-center gap-2\">\n <clx-rating [value]=\"p.rating\" [color]=\"clxColor()\"></clx-rating>\n <span class=\"text-sm font-semibold text-clx-text-label\">{{ p.rating | number:'1.1-1' }}</span>\n <span class=\"text-sm text-clx-text-subtle\">({{ p.review_count }} reviews)</span>\n </div>\n\n <!-- Price block -->\n <div class=\"py-4\">\n <div class=\"flex items-baseline gap-3\">\n <span class=\"text-4xl font-black text-clx-text-label\">\n {{ finalPrice() | currency:currency():'symbol':'1.0-0' }}\n </span>\n @if (p.has_discount && p.discount_price) {\n <span class=\"text-lg text-clx-text-subtle line-through\">\n {{ p.discount_price | currency:currency():'symbol':'1.0-0' }}\n </span>\n <span clx-badge variant=\"solid\" [color]=\"clxColor()\" size=\"sm\" shape=\"pill\">\n -{{ discount() }}%\n </span>\n }\n </div>\n @if (v && !v.in_stock) {\n <p class=\"text-sm text-rose-500 font-medium mt-1\">Out of stock</p>\n }\n </div>\n\n <!-- Selectores de variaci\u00F3n (st_spec_types + st_spec_options) -->\n @for (specType of p.spec_types; track specType.id) {\n @if (specType.input_type === 'color') {\n <clx-button-group [label]=\"specType.name\" shape=\"circular\" [attached]=\"false\">\n @for (opt of specType.options; track opt.id) {\n <button clx-button\n [variant]=\"isSpecSelected(specType.id, opt.id) ? 'solid' : 'outline'\"\n [color]=\"asColor(opt.value)\"\n shape=\"circle\" size=\"xs\" [iconOnly]=\"true\"\n [disabled]=\"!isOptionAvailable(specType.id, opt.id)\"\n [clxTooltip]=\"opt.value\"\n [clxTooltipColor]=\"asColor(opt.value)\"\n clxTooltipPosition=\"top\"\n (click)=\"selectSpec(specType.id, opt.id)\">\n </button>\n }\n </clx-button-group>\n } @else {\n <clx-button-group [label]=\"specType.name\" shape=\"flat\" [attached]=\"false\">\n @for (opt of specType.options; track opt.id) {\n <button clx-button\n [variant]=\"isSpecSelected(specType.id, opt.id) ? 'solid' : 'outline'\"\n [color]=\"clxColor()\" size=\"sm\"\n [disabled]=\"!isOptionAvailable(specType.id, opt.id)\"\n (click)=\"selectSpec(specType.id, opt.id)\">\n {{ opt.value }}\n </button>\n }\n </clx-button-group>\n }\n }\n\n <!-- Quantity -->\n <clx-number label=\"Quantity:\" variant=\"stepper\" [color]=\"clxColor()\"\n [min]=\"1\" [max]=\"99\" [ngModel]=\"quantity()\" (ngModelChange)=\"quantity.set($event)\">\n </clx-number>\n\n <!-- CTA -->\n <div class=\"flex gap-3\">\n <button clx-button variant=\"solid\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"bolt\"\n [disabled]=\"!v?.in_stock\">Buy Now</button>\n <button clx-button variant=\"light\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"shopping_cart\"\n [disabled]=\"!v?.in_stock\">Add to Cart</button>\n </div>\n\n </div>\n </div>\n\n <!-- \u2500\u2500 Tabs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <clx-tabs [tabs]=\"tabItems\" [clxColor]=\"clxColor()\" [(activeTab)]=\"activeTab\">\n\n <!-- Tab: Caracter\u00EDsticas generales (st_product_specs \u2014 ficha t\u00E9cnica global) -->\n <ng-template [clxTabPanel]=\"'general'\">\n <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-x-8\">\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (spec of specsLeft(p.product_specs); track spec.id) {\n <clx-list-item [label]=\"spec.name + ':'\" [sublabel]=\"spec.value\" [icon]=\"spec.icon ?? ''\" />\n }\n </clx-list>\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (spec of specsRight(p.product_specs); track spec.id) {\n <clx-list-item [label]=\"spec.name + ':'\" [sublabel]=\"spec.value\" [icon]=\"spec.icon ?? ''\" />\n }\n </clx-list>\n </div>\n </ng-template>\n\n <!-- Tab: Especificaciones (st_spec_types \u2014 specs de la variaci\u00F3n activa) -->\n <ng-template [clxTabPanel]=\"'specs'\">\n <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-x-8\">\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (st of specsLeft(p.spec_types); track st.id) {\n <clx-list-item [label]=\"st.name + ':'\" [sublabel]=\"selectedOptionLabel(st)\" [icon]=\"st.icon ?? ''\" />\n }\n </clx-list>\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (st of specsRight(p.spec_types); track st.id) {\n <clx-list-item [label]=\"st.name + ':'\" [sublabel]=\"selectedOptionLabel(st)\" [icon]=\"st.icon ?? ''\" />\n }\n </clx-list>\n </div>\n </ng-template>\n\n <!-- Tab: Descripci\u00F3n (st_product_descriptions) -->\n <ng-template [clxTabPanel]=\"'description'\">\n <div class=\"space-y-5 max-w-3xl\">\n @for (block of p.descriptions; track block.id) {\n <div>\n @if (block.title) {\n <h3 class=\"text-base font-semibold text-clx-text-label mb-1\">{{ block.title }}</h3>\n }\n <p class=\"text-sm text-clx-text-muted leading-relaxed\">{{ block.body }}</p>\n </div>\n }\n </div>\n </ng-template>\n\n </clx-tabs>\n\n <!-- \u2500\u2500 Reviews \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"grid grid-cols-1 xl:grid-cols-3 gap-8 border-t border-clx-border pt-8\">\n\n <div class=\"space-y-3\">\n <h2 class=\"text-base font-bold text-clx-text-label\">Customer Reviews</h2>\n <div class=\"flex items-end gap-3\">\n <span class=\"text-5xl font-black text-clx-text-label\">{{ p.rating | number:'1.1-1' }}</span>\n <div class=\"pb-1 space-y-1\">\n <clx-rating [value]=\"p.rating\" [color]=\"clxColor()\"></clx-rating>\n <p class=\"text-xs text-clx-text-muted\">{{ p.review_count }} verified ratings</p>\n </div>\n </div>\n <p class=\"text-sm font-semibold\" [class]=\"'text-' + clxColor() + '-600'\">Very Good</p>\n <div class=\"pt-2 space-y-2\">\n <button clx-button variant=\"solid\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"rate_review\">\n Leave Us a Review\n </button>\n <button clx-button variant=\"light\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"flag\">\n Report abuse\n </button>\n </div>\n </div>\n\n <div class=\"lg:col-span-2 space-y-4\">\n @for (review of p.reviews ?? []; track review.id) {\n <div class=\"rounded-2xl overflow-hidden shadow-sm\">\n <div class=\"flex items-center gap-3 px-4 py-3\">\n <div class=\"w-10 h-10 rounded-full bg-clx-surface-2 flex items-center justify-center shrink-0\">\n <span class=\"text-sm font-bold text-clx-text-muted\">\n {{ review.author_name.substring(0,1) }}{{ review.author_name.split(' ')[1]?.substring(0,1) ?? '' }}\n </span>\n </div>\n <div class=\"flex-1 min-w-0\">\n <p class=\"font-semibold text-sm text-clx-text-label truncate\">{{ review.author_name }}</p>\n <p class=\"text-xs text-clx-text-subtle\">{{ review.created_at }}</p>\n </div>\n @if (review.is_verified) {\n <span clx-badge variant=\"light\" color=\"emerald\" size=\"sm\" shape=\"pill\">Verified</span>\n }\n </div>\n <div class=\"px-4 pb-4 space-y-2\">\n <div class=\"flex items-center gap-2\">\n <clx-rating [value]=\"review.rating\" [color]=\"clxColor()\"></clx-rating>\n @if (review.title) {\n <span class=\"text-sm font-semibold text-clx-text-label\">{{ review.title }}</span>\n }\n </div>\n @if (review.body) {\n <p class=\"text-sm text-clx-text-muted\">{{ review.body }}</p>\n }\n <div class=\"flex items-center gap-3 pt-1\">\n <span class=\"text-xs text-clx-text-subtle\">Helpful?</span>\n <button clx-button variant=\"ghost\" color=\"slate\" size=\"xs\" icon=\"thumb_up\">{{ review.helpful }}</button>\n <button clx-button variant=\"ghost\" color=\"slate\" size=\"xs\" icon=\"thumb_down\">{{ review.not_helpful }}</button>\n </div>\n </div>\n </div>\n }\n </div>\n\n </div>\n\n </div>\n}\n" }]
13617
+ ], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- \u2550\u2550 SKELETON \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n@if (loading()) {\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-8 p-6\">\n <div class=\"space-y-3\">\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"420px\" class=\"rounded-2xl\"></clx-skeleton>\n <div class=\"flex gap-2\">\n @for (t of [1,2,3,4]; track t) {\n <clx-skeleton variant=\"rectangular\" width=\"80px\" height=\"80px\" class=\"rounded-xl\"></clx-skeleton>\n }\n </div>\n </div>\n <div class=\"space-y-4 pt-2\">\n <clx-skeleton variant=\"text\" size=\"lg\" width=\"70%\"></clx-skeleton>\n <clx-skeleton variant=\"text\" size=\"sm\" width=\"40%\"></clx-skeleton>\n <clx-skeleton variant=\"text\" size=\"xl\" width=\"50%\"></clx-skeleton>\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"100px\" class=\"rounded-xl\"></clx-skeleton>\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"52px\" class=\"rounded-xl\"></clx-skeleton>\n <clx-skeleton variant=\"rectangular\" width=\"100%\" height=\"52px\" class=\"rounded-xl\"></clx-skeleton>\n </div>\n </div>\n}\n\n<!-- \u2550\u2550 CONTENT \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n@if (!loading() && product(); as p) {\n @let v = activeVariation();\n <div class=\"space-y-8\">\n\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-8 xl:items-start\">\n\n <!-- \u2500\u2500 Column 1: Image Gallery \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"space-y-3\">\n <div class=\"relative\">\n <clx-carousel [clxColor]=\"clxColor()\" aspectRatio=\"4/3\" [loop]=\"true\">\n @for (img of v?.images ?? []; track img) {\n <ng-template clxSlide>\n <img [src]=\"img\" [alt]=\"p.product_name\" class=\"w-full h-full object-cover\" loading=\"lazy\" />\n </ng-template>\n }\n </clx-carousel>\n <div class=\"absolute top-3 right-3 z-10\">\n <button clx-button type=\"button\" variant=\"solid\" [color]=\"clxColor()\" shape=\"circle\" size=\"md\"\n [iconOnly]=\"true\" clxTooltip=\"Add to Wishlist\" [clxTooltipColor]=\"clxColor()\" clxTooltipPosition=\"left\">\n <span clx-icon name=\"favorite_border\" size=\"sm\"></span>\n </button>\n </div>\n </div>\n <div class=\"flex flex-wrap gap-2\">\n @for (img of v?.images ?? []; track img; let i = $index) {\n <img [src]=\"img\" [alt]=\"p.product_name\"\n class=\"w-20 h-20 rounded-xl object-cover border-[3px] cursor-pointer shrink-0 transition-[border-color,opacity]\"\n [class]=\"_carousel()?.currentPageIndex() === i\n ? 'border-' + clxColor() + '-500 opacity-100'\n : 'border-transparent opacity-60 hover:opacity-90'\"\n loading=\"lazy\"\n (click)=\"_carousel()?.goTo(i)\" />\n }\n </div>\n </div>\n\n <!-- \u2500\u2500 Column 2: Purchase Info \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"space-y-5\">\n\n <!-- Tags (st_products.tags) -->\n <div class=\"flex flex-wrap gap-2\">\n @for (tag of p.tags; track tag) {\n <span clx-badge variant=\"light\" [color]=\"clxColor()\" size=\"sm\" shape=\"pill\">{{ tag }}</span>\n }\n </div>\n\n <!-- Title -->\n <div>\n <p class=\"text-xs text-clx-text-subtle uppercase tracking-wide font-medium\">{{ p.trademark }}</p>\n <h1 class=\"text-2xl font-bold text-clx-text-label leading-tight mt-0.5\">{{ p.product_name }}</h1>\n @if (v?.description) {\n <p class=\"text-clx-text-muted text-sm mt-1\">{{ v!.description }}</p>\n }\n </div>\n\n <!-- Rating -->\n <div class=\"flex items-center gap-2\">\n <clx-rating [value]=\"p.rating\" [color]=\"clxColor()\"></clx-rating>\n <span class=\"text-sm font-semibold text-clx-text-label\">{{ p.rating | number:'1.1-1' }}</span>\n <span class=\"text-sm text-clx-text-subtle\">({{ p.review_count }} reviews)</span>\n </div>\n\n <!-- Price block -->\n <div class=\"py-4\">\n <div class=\"flex items-baseline gap-3\">\n <span class=\"text-4xl font-black text-clx-text-label\">\n {{ finalPrice() | currency:currency():'symbol':'1.0-0' }}\n </span>\n @if (p.has_discount && p.discount_price) {\n <span class=\"text-lg text-clx-text-subtle line-through\">\n {{ p.discount_price | currency:currency():'symbol':'1.0-0' }}\n </span>\n <span clx-badge variant=\"solid\" [color]=\"clxColor()\" size=\"sm\" shape=\"pill\">\n -{{ discount() }}%\n </span>\n }\n </div>\n @if (v && !v.in_stock) {\n <p class=\"text-sm text-rose-500 font-medium mt-1\">Out of stock</p>\n }\n </div>\n\n <!-- Selectores de variaci\u00F3n (st_spec_types + st_spec_options) -->\n @for (specType of p.spec_types; track specType.id) {\n @if (specType.input_type === 'color') {\n <clx-button-group [label]=\"specType.name\" shape=\"circular\" [attached]=\"false\">\n @for (opt of specType.options; track opt.id) {\n <button clx-button\n type=\"button\"\n [variant]=\"isSpecSelected(specType.id, opt.id) ? 'solid' : 'outline'\"\n [color]=\"asColor(opt.value)\"\n shape=\"circle\" size=\"xs\" [iconOnly]=\"true\"\n [disabled]=\"!isOptionAvailable(specType.id, opt.id)\"\n [clxTooltip]=\"opt.value\"\n [clxTooltipColor]=\"asColor(opt.value)\"\n clxTooltipPosition=\"top\"\n (click)=\"selectSpec(specType.id, opt.id)\">\n </button>\n }\n </clx-button-group>\n } @else {\n <clx-button-group [label]=\"specType.name\" shape=\"flat\" [attached]=\"false\">\n @for (opt of specType.options; track opt.id) {\n <button clx-button\n type=\"button\"\n [variant]=\"isSpecSelected(specType.id, opt.id) ? 'solid' : 'outline'\"\n [color]=\"clxColor()\" size=\"sm\"\n [disabled]=\"!isOptionAvailable(specType.id, opt.id)\"\n (click)=\"selectSpec(specType.id, opt.id)\">\n {{ opt.value }}\n </button>\n }\n </clx-button-group>\n }\n }\n\n <!-- Quantity -->\n <clx-number label=\"Quantity:\" variant=\"stepper\" [color]=\"clxColor()\"\n [min]=\"1\" [max]=\"99\" [ngModel]=\"quantity()\" (ngModelChange)=\"quantity.set($event)\">\n </clx-number>\n\n <!-- CTA -->\n <div class=\"flex gap-3\">\n <button clx-button type=\"button\" variant=\"solid\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"bolt\"\n [disabled]=\"!v?.in_stock\">Buy Now</button>\n <button clx-button type=\"button\" variant=\"light\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"shopping_cart\"\n [disabled]=\"!v?.in_stock\">Add to Cart</button>\n </div>\n\n </div>\n </div>\n\n <!-- \u2500\u2500 Tabs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <clx-tabs [tabs]=\"tabItems\" [clxColor]=\"clxColor()\" [(activeTab)]=\"activeTab\">\n\n <!-- Tab: Caracter\u00EDsticas generales (st_product_specs \u2014 ficha t\u00E9cnica global) -->\n <ng-template [clxTabPanel]=\"'general'\">\n <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-x-8\">\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (spec of specsLeft(p.product_specs); track spec.id) {\n <clx-list-item [label]=\"spec.name + ':'\" [sublabel]=\"spec.value\" [icon]=\"spec.icon ?? ''\" />\n }\n </clx-list>\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (spec of specsRight(p.product_specs); track spec.id) {\n <clx-list-item [label]=\"spec.name + ':'\" [sublabel]=\"spec.value\" [icon]=\"spec.icon ?? ''\" />\n }\n </clx-list>\n </div>\n </ng-template>\n\n <!-- Tab: Especificaciones (st_spec_types \u2014 specs de la variaci\u00F3n activa) -->\n <ng-template [clxTabPanel]=\"'specs'\">\n <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-x-8\">\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (st of specsLeft(p.spec_types); track st.id) {\n <clx-list-item [label]=\"st.name + ':'\" [sublabel]=\"selectedOptionLabel(st)\" [icon]=\"st.icon ?? ''\" />\n }\n </clx-list>\n <clx-list [color]=\"clxColor()\" variant=\"flush\" size=\"sm\">\n @for (st of specsRight(p.spec_types); track st.id) {\n <clx-list-item [label]=\"st.name + ':'\" [sublabel]=\"selectedOptionLabel(st)\" [icon]=\"st.icon ?? ''\" />\n }\n </clx-list>\n </div>\n </ng-template>\n\n <!-- Tab: Descripci\u00F3n (st_product_descriptions) -->\n <ng-template [clxTabPanel]=\"'description'\">\n <div class=\"space-y-5 max-w-3xl\">\n @for (block of p.descriptions; track block.id) {\n <div>\n @if (block.title) {\n <h3 class=\"text-base font-semibold text-clx-text-label mb-1\">{{ block.title }}</h3>\n }\n <p class=\"text-sm text-clx-text-muted leading-relaxed\">{{ block.body }}</p>\n </div>\n }\n </div>\n </ng-template>\n\n </clx-tabs>\n\n <!-- \u2500\u2500 Reviews \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"grid grid-cols-1 xl:grid-cols-3 gap-8 border-t border-clx-border pt-8\">\n\n <div class=\"space-y-3\">\n <h2 class=\"text-base font-bold text-clx-text-label\">Customer Reviews</h2>\n <div class=\"flex items-end gap-3\">\n <span class=\"text-5xl font-black text-clx-text-label\">{{ p.rating | number:'1.1-1' }}</span>\n <div class=\"pb-1 space-y-1\">\n <clx-rating [value]=\"p.rating\" [color]=\"clxColor()\"></clx-rating>\n <p class=\"text-xs text-clx-text-muted\">{{ p.review_count }} verified ratings</p>\n </div>\n </div>\n <p class=\"text-sm font-semibold\" [class]=\"'text-' + clxColor() + '-600'\">Very Good</p>\n <div class=\"pt-2 space-y-2\">\n <button clx-button type=\"button\" variant=\"solid\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"rate_review\">\n Leave Us a Review\n </button>\n <button clx-button type=\"button\" variant=\"light\" [color]=\"clxColor()\" size=\"md\" [block]=\"true\" icon=\"flag\">\n Report abuse\n </button>\n </div>\n </div>\n\n <div class=\"lg:col-span-2 space-y-4\">\n @for (review of p.reviews ?? []; track review.id) {\n <div class=\"rounded-2xl overflow-hidden shadow-sm\">\n <div class=\"flex items-center gap-3 px-4 py-3\">\n <div class=\"w-10 h-10 rounded-full bg-clx-surface-2 flex items-center justify-center shrink-0\">\n <span class=\"text-sm font-bold text-clx-text-muted\">\n {{ review.author_name.substring(0,1) }}{{ review.author_name.split(' ')[1]?.substring(0,1) ?? '' }}\n </span>\n </div>\n <div class=\"flex-1 min-w-0\">\n <p class=\"font-semibold text-sm text-clx-text-label truncate\">{{ review.author_name }}</p>\n <p class=\"text-xs text-clx-text-subtle\">{{ review.created_at }}</p>\n </div>\n @if (review.is_verified) {\n <span clx-badge variant=\"light\" color=\"emerald\" size=\"sm\" shape=\"pill\">Verified</span>\n }\n </div>\n <div class=\"px-4 pb-4 space-y-2\">\n <div class=\"flex items-center gap-2\">\n <clx-rating [value]=\"review.rating\" [color]=\"clxColor()\"></clx-rating>\n @if (review.title) {\n <span class=\"text-sm font-semibold text-clx-text-label\">{{ review.title }}</span>\n }\n </div>\n @if (review.body) {\n <p class=\"text-sm text-clx-text-muted\">{{ review.body }}</p>\n }\n <div class=\"flex items-center gap-3 pt-1\">\n <span class=\"text-xs text-clx-text-subtle\">Helpful?</span>\n <button clx-button type=\"button\" variant=\"ghost\" color=\"slate\" size=\"xs\" icon=\"thumb_up\">{{ review.helpful }}</button>\n <button clx-button type=\"button\" variant=\"ghost\" color=\"slate\" size=\"xs\" icon=\"thumb_down\">{{ review.not_helpful }}</button>\n </div>\n </div>\n </div>\n }\n </div>\n\n </div>\n\n </div>\n}\n" }]
13530
13618
  }], ctorParameters: () => [], propDecorators: { product: [{ type: i0.Input, args: [{ isSignal: true, alias: "product", required: false }] }], clxColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "clxColor", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], currency: [{ type: i0.Input, args: [{ isSignal: true, alias: "currency", required: false }] }], _carousel: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ClxCarouselComponent), { isSignal: true }] }] } });
13531
13619
 
13532
13620
  const WISHLIST_PAGE_SIZE_DEFAULT = 6;
@@ -13664,6 +13752,7 @@ class ClxWishlistComponent {
13664
13752
  </div>
13665
13753
  <button
13666
13754
  clx-button
13755
+ type="button"
13667
13756
  variant="light"
13668
13757
  [color]="color()"
13669
13758
  size="sm"
@@ -13756,6 +13845,7 @@ class ClxWishlistComponent {
13756
13845
  <div class="absolute top-3 right-3 z-10">
13757
13846
  <button
13758
13847
  clx-button
13848
+ type="button"
13759
13849
  variant="ghost"
13760
13850
  color="red"
13761
13851
  size="md"
@@ -13773,6 +13863,7 @@ class ClxWishlistComponent {
13773
13863
  <div [class]="_actionsClass">
13774
13864
  <button
13775
13865
  clx-button
13866
+ type="button"
13776
13867
  [color]="color()"
13777
13868
  variant="solid"
13778
13869
  size="md"
@@ -13863,6 +13954,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
13863
13954
  </div>
13864
13955
  <button
13865
13956
  clx-button
13957
+ type="button"
13866
13958
  variant="light"
13867
13959
  [color]="color()"
13868
13960
  size="sm"
@@ -13955,6 +14047,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
13955
14047
  <div class="absolute top-3 right-3 z-10">
13956
14048
  <button
13957
14049
  clx-button
14050
+ type="button"
13958
14051
  variant="ghost"
13959
14052
  color="red"
13960
14053
  size="md"
@@ -13972,6 +14065,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
13972
14065
  <div [class]="_actionsClass">
13973
14066
  <button
13974
14067
  clx-button
14068
+ type="button"
13975
14069
  [color]="color()"
13976
14070
  variant="solid"
13977
14071
  size="md"
@@ -14101,7 +14195,7 @@ class ClxCartComponent {
14101
14195
  <span clx-badge variant="light" [color]="color()" size="sm">{{ _totalUnits() }}</span>
14102
14196
  </div>
14103
14197
  <button
14104
- clx-button variant="ghost" color="red" size="sm" icon="delete_sweep"
14198
+ clx-button type="button" variant="ghost" color="red" size="sm" icon="delete_sweep"
14105
14199
  (click)="onClearCart.emit()">
14106
14200
  Vaciar
14107
14201
  </button>
@@ -14141,7 +14235,7 @@ class ClxCartComponent {
14141
14235
  <!-- Remove -->
14142
14236
  <div class="absolute top-2 right-2 z-10">
14143
14237
  <button
14144
- clx-button variant="ghost" color="red" size="sm"
14238
+ clx-button type="button" variant="ghost" color="red" size="sm"
14145
14239
  icon="close" [iconOnly]="true" shape="circle"
14146
14240
  (click)="onRemove.emit(item)">
14147
14241
  </button>
@@ -14181,7 +14275,7 @@ class ClxCartComponent {
14181
14275
  <!-- Quantity control -->
14182
14276
  <div class="flex items-center border border-clx-border rounded-xl overflow-hidden">
14183
14277
  <button
14184
- clx-button variant="ghost" color="slate" size="sm"
14278
+ clx-button type="button" variant="ghost" color="slate" size="sm"
14185
14279
  icon="remove" [iconOnly]="true"
14186
14280
  [disabled]="item.quantity <= 1"
14187
14281
  (click)="onQuantityChange.emit({ item, quantity: item.quantity - 1 })">
@@ -14190,7 +14284,7 @@ class ClxCartComponent {
14190
14284
  {{ item.quantity }}
14191
14285
  </span>
14192
14286
  <button
14193
- clx-button variant="ghost" [color]="color()" size="sm"
14287
+ clx-button type="button" variant="ghost" [color]="color()" size="sm"
14194
14288
  icon="add" [iconOnly]="true"
14195
14289
  [disabled]="!item.in_stock || (!!item.max_quantity && item.quantity >= item.max_quantity)"
14196
14290
  (click)="onQuantityChange.emit({ item, quantity: item.quantity + 1 })">
@@ -14231,13 +14325,13 @@ class ClxCartComponent {
14231
14325
  </div>
14232
14326
  @if (coupon()?.valid) {
14233
14327
  <button
14234
- clx-button variant="ghost" color="red" size="sm"
14328
+ clx-button type="button" variant="ghost" color="red" size="sm"
14235
14329
  icon="close" [iconOnly]="true" shape="circle"
14236
14330
  (click)="removeCoupon()">
14237
14331
  </button>
14238
14332
  } @else {
14239
14333
  <button
14240
- clx-button [color]="color()" variant="solid" size="sm" shape="pill"
14334
+ clx-button type="button" [color]="color()" variant="solid" size="sm" shape="pill"
14241
14335
  [disabled]="!_couponCode.trim()"
14242
14336
  (click)="applyCoupon()">
14243
14337
  Aplicar
@@ -14289,7 +14383,7 @@ class ClxCartComponent {
14289
14383
 
14290
14384
  <!-- Checkout -->
14291
14385
  <button
14292
- clx-button [color]="color()" variant="solid" size="lg"
14386
+ clx-button type="button" [color]="color()" variant="solid" size="lg"
14293
14387
  icon="arrow_forward" iconPosition="right" [block]="true"
14294
14388
  (click)="onCheckout.emit()">
14295
14389
  Proceder al pago
@@ -14379,7 +14473,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
14379
14473
  <span clx-badge variant="light" [color]="color()" size="sm">{{ _totalUnits() }}</span>
14380
14474
  </div>
14381
14475
  <button
14382
- clx-button variant="ghost" color="red" size="sm" icon="delete_sweep"
14476
+ clx-button type="button" variant="ghost" color="red" size="sm" icon="delete_sweep"
14383
14477
  (click)="onClearCart.emit()">
14384
14478
  Vaciar
14385
14479
  </button>
@@ -14419,7 +14513,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
14419
14513
  <!-- Remove -->
14420
14514
  <div class="absolute top-2 right-2 z-10">
14421
14515
  <button
14422
- clx-button variant="ghost" color="red" size="sm"
14516
+ clx-button type="button" variant="ghost" color="red" size="sm"
14423
14517
  icon="close" [iconOnly]="true" shape="circle"
14424
14518
  (click)="onRemove.emit(item)">
14425
14519
  </button>
@@ -14459,7 +14553,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
14459
14553
  <!-- Quantity control -->
14460
14554
  <div class="flex items-center border border-clx-border rounded-xl overflow-hidden">
14461
14555
  <button
14462
- clx-button variant="ghost" color="slate" size="sm"
14556
+ clx-button type="button" variant="ghost" color="slate" size="sm"
14463
14557
  icon="remove" [iconOnly]="true"
14464
14558
  [disabled]="item.quantity <= 1"
14465
14559
  (click)="onQuantityChange.emit({ item, quantity: item.quantity - 1 })">
@@ -14468,7 +14562,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
14468
14562
  {{ item.quantity }}
14469
14563
  </span>
14470
14564
  <button
14471
- clx-button variant="ghost" [color]="color()" size="sm"
14565
+ clx-button type="button" variant="ghost" [color]="color()" size="sm"
14472
14566
  icon="add" [iconOnly]="true"
14473
14567
  [disabled]="!item.in_stock || (!!item.max_quantity && item.quantity >= item.max_quantity)"
14474
14568
  (click)="onQuantityChange.emit({ item, quantity: item.quantity + 1 })">
@@ -14509,13 +14603,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
14509
14603
  </div>
14510
14604
  @if (coupon()?.valid) {
14511
14605
  <button
14512
- clx-button variant="ghost" color="red" size="sm"
14606
+ clx-button type="button" variant="ghost" color="red" size="sm"
14513
14607
  icon="close" [iconOnly]="true" shape="circle"
14514
14608
  (click)="removeCoupon()">
14515
14609
  </button>
14516
14610
  } @else {
14517
14611
  <button
14518
- clx-button [color]="color()" variant="solid" size="sm" shape="pill"
14612
+ clx-button type="button" [color]="color()" variant="solid" size="sm" shape="pill"
14519
14613
  [disabled]="!_couponCode.trim()"
14520
14614
  (click)="applyCoupon()">
14521
14615
  Aplicar
@@ -14567,7 +14661,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
14567
14661
 
14568
14662
  <!-- Checkout -->
14569
14663
  <button
14570
- clx-button [color]="color()" variant="solid" size="lg"
14664
+ clx-button type="button" [color]="color()" variant="solid" size="lg"
14571
14665
  icon="arrow_forward" iconPosition="right" [block]="true"
14572
14666
  (click)="onCheckout.emit()">
14573
14667
  Proceder al pago