@caribeng/ui 22.4.0 → 22.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/README.md +311 -313
  2. package/fesm2022/caribeng-ui-account-picker.mjs +533 -0
  3. package/fesm2022/caribeng-ui-aging.mjs +488 -0
  4. package/fesm2022/{caribeng-ui-caribe-alert.mjs → caribeng-ui-alert.mjs} +45 -45
  5. package/fesm2022/caribeng-ui-amount.mjs +249 -0
  6. package/fesm2022/caribeng-ui-anchor.mjs +2 -2
  7. package/fesm2022/{caribeng-ui-caribe-animation-lottie.mjs → caribeng-ui-animation-lottie.mjs} +41 -41
  8. package/fesm2022/caribeng-ui-audit-log.mjs +323 -0
  9. package/fesm2022/caribeng-ui-avatar.mjs +2 -2
  10. package/fesm2022/caribeng-ui-breadcrumb.mjs +13 -3
  11. package/fesm2022/{caribeng-ui-caribe-button-group.mjs → caribeng-ui-button-group.mjs} +15 -15
  12. package/fesm2022/caribeng-ui-button.mjs +2 -2
  13. package/fesm2022/{caribeng-ui-caribe-card-content.mjs → caribeng-ui-card-content.mjs} +39 -39
  14. package/fesm2022/{caribeng-ui-caribe-card-move.mjs → caribeng-ui-card-move.mjs} +65 -65
  15. package/fesm2022/{caribeng-ui-caribe-card-primary.mjs → caribeng-ui-card-primary.mjs} +31 -31
  16. package/fesm2022/{caribeng-ui-caribe-card-select.mjs → caribeng-ui-card-select.mjs} +67 -67
  17. package/fesm2022/caribeng-ui-carousel.mjs +2 -2
  18. package/fesm2022/caribeng-ui-cascadeselect.mjs +45 -9
  19. package/fesm2022/caribeng-ui-chat.mjs +2 -2
  20. package/fesm2022/{caribeng-ui-caribe-coachmark.mjs → caribeng-ui-coachmark.mjs} +85 -85
  21. package/fesm2022/caribeng-ui-command-palette.mjs +2 -2
  22. package/fesm2022/caribeng-ui-comments.mjs +864 -0
  23. package/fesm2022/caribeng-ui-datagrid.mjs +1635 -0
  24. package/fesm2022/caribeng-ui-dataview.mjs +2 -2
  25. package/fesm2022/caribeng-ui-datepicker.mjs +2 -2
  26. package/fesm2022/caribeng-ui-document.mjs +495 -0
  27. package/fesm2022/{caribeng-ui-caribe-dots-indicator.mjs → caribeng-ui-dots-indicator.mjs} +41 -41
  28. package/fesm2022/caribeng-ui-dynamic-form.mjs +1581 -0
  29. package/fesm2022/caribeng-ui-editor.mjs +2303 -1311
  30. package/fesm2022/{caribeng-ui-caribe-expansion-panel.mjs → caribeng-ui-expansion-panel.mjs} +39 -39
  31. package/fesm2022/{caribeng-ui-caribe-fab-menu.mjs → caribeng-ui-fab-menu.mjs} +75 -75
  32. package/fesm2022/caribeng-ui-file-card.mjs +2 -2
  33. package/fesm2022/{caribeng-ui-caribe-file-download.mjs → caribeng-ui-file-download.mjs} +63 -63
  34. package/fesm2022/caribeng-ui-financial-report.mjs +380 -0
  35. package/fesm2022/{caribeng-ui-caribe-float-menu.mjs → caribeng-ui-float-menu.mjs} +31 -31
  36. package/fesm2022/caribeng-ui-floatlabel.mjs +2 -2
  37. package/fesm2022/caribeng-ui-flow.mjs +1508 -0
  38. package/fesm2022/{caribeng-ui-caribe-footer.mjs → caribeng-ui-footer.mjs} +19 -19
  39. package/fesm2022/caribeng-ui-gantt.mjs +1094 -0
  40. package/fesm2022/{caribeng-ui-caribe-header.mjs → caribeng-ui-header.mjs} +49 -49
  41. package/fesm2022/{caribeng-ui-caribe-icon-button.mjs → caribeng-ui-icon-button.mjs} +23 -23
  42. package/fesm2022/caribeng-ui-image-cropper.mjs +671 -0
  43. package/fesm2022/caribeng-ui-import-wizard.mjs +746 -0
  44. package/fesm2022/caribeng-ui-infinite-scroll.mjs +226 -0
  45. package/fesm2022/caribeng-ui-input-number.mjs +22 -6
  46. package/fesm2022/{caribeng-ui-caribe-input-search.mjs → caribeng-ui-input-search.mjs} +65 -65
  47. package/fesm2022/{caribeng-ui-caribe-input-token.mjs → caribeng-ui-input-token.mjs} +59 -59
  48. package/fesm2022/caribeng-ui-inputotp.mjs +2 -2
  49. package/fesm2022/caribeng-ui-journal-entry.mjs +340 -0
  50. package/fesm2022/caribeng-ui-kanban.mjs +6 -6
  51. package/fesm2022/caribeng-ui-kpi.mjs +189 -0
  52. package/fesm2022/{caribeng-ui-caribe-link.mjs → caribeng-ui-link.mjs} +37 -37
  53. package/fesm2022/caribeng-ui-masonry.mjs +93 -0
  54. package/fesm2022/caribeng-ui-media-player.mjs +821 -0
  55. package/fesm2022/caribeng-ui-mentions.mjs +2 -2
  56. package/fesm2022/caribeng-ui-notification-center.mjs +636 -0
  57. package/fesm2022/{caribeng-ui-caribe-off-canvas.mjs → caribeng-ui-off-canvas.mjs} +55 -55
  58. package/fesm2022/{caribeng-ui-caribe-onboarding.mjs → caribeng-ui-onboarding.mjs} +105 -105
  59. package/fesm2022/caribeng-ui-orderlist.mjs +2 -2
  60. package/fesm2022/caribeng-ui-pdfviewer.mjs +1755 -25
  61. package/fesm2022/caribeng-ui-period-picker.mjs +637 -0
  62. package/fesm2022/caribeng-ui-phone-input.mjs +2 -2
  63. package/fesm2022/caribeng-ui-picklist.mjs +2 -2
  64. package/fesm2022/caribeng-ui-pivot.mjs +419 -0
  65. package/fesm2022/caribeng-ui-pricing.mjs +2 -2
  66. package/fesm2022/caribeng-ui-rating.mjs +14 -17
  67. package/fesm2022/caribeng-ui-reconciliation.mjs +386 -0
  68. package/fesm2022/caribeng-ui-scheduler.mjs +1027 -0
  69. package/fesm2022/caribeng-ui-select.mjs +2 -2
  70. package/fesm2022/{caribeng-ui-caribe-shortcut.mjs → caribeng-ui-shortcut.mjs} +29 -29
  71. package/fesm2022/caribeng-ui-sidebar.mjs +2 -2
  72. package/fesm2022/caribeng-ui-signature-pad.mjs +654 -0
  73. package/fesm2022/{caribeng-ui-caribe-status.mjs → caribeng-ui-status.mjs} +11 -11
  74. package/fesm2022/{caribeng-ui-caribe-step-indicator.mjs → caribeng-ui-step-indicator.mjs} +53 -53
  75. package/fesm2022/caribeng-ui-stepper.mjs +2 -2
  76. package/fesm2022/caribeng-ui-steps.mjs +2 -2
  77. package/fesm2022/caribeng-ui-table.mjs +323 -15
  78. package/fesm2022/caribeng-ui-tabmenu.mjs +2 -2
  79. package/fesm2022/caribeng-ui-tabs.mjs +2 -2
  80. package/fesm2022/{caribeng-ui-caribe-tag-button.mjs → caribeng-ui-tag-button.mjs} +25 -25
  81. package/fesm2022/caribeng-ui-tag.mjs +2 -2
  82. package/fesm2022/caribeng-ui-tieredmenu.mjs +6 -6
  83. package/fesm2022/{caribeng-ui-caribe-tracker.mjs → caribeng-ui-tracker.mjs} +29 -29
  84. package/fesm2022/{caribeng-ui-caribe-transaction-status.mjs → caribeng-ui-transaction-status.mjs} +11 -11
  85. package/fesm2022/caribeng-ui-treeselect.mjs +44 -9
  86. package/fesm2022/caribeng-ui-treetable.mjs +236 -17
  87. package/fesm2022/{caribeng-ui-caribe-voucher.mjs → caribeng-ui-voucher.mjs} +45 -45
  88. package/fesm2022/caribeng-ui-xlsx.mjs +486 -0
  89. package/fesm2022/caribeng-ui.mjs +1181 -1
  90. package/package.json +217 -177
  91. package/types/caribeng-ui-account-picker.d.ts +142 -0
  92. package/types/caribeng-ui-aging.d.ts +123 -0
  93. package/types/{caribeng-ui-caribe-alert.d.ts → caribeng-ui-alert.d.ts} +2 -2
  94. package/types/caribeng-ui-amount.d.ts +82 -0
  95. package/types/{caribeng-ui-caribe-animation-lottie.d.ts → caribeng-ui-animation-lottie.d.ts} +2 -2
  96. package/types/caribeng-ui-audit-log.d.ts +86 -0
  97. package/types/caribeng-ui-breadcrumb.d.ts +2 -2
  98. package/types/{caribeng-ui-caribe-button-group.d.ts → caribeng-ui-button-group.d.ts} +2 -2
  99. package/types/{caribeng-ui-caribe-card-content.d.ts → caribeng-ui-card-content.d.ts} +2 -2
  100. package/types/{caribeng-ui-caribe-card-move.d.ts → caribeng-ui-card-move.d.ts} +1 -1
  101. package/types/{caribeng-ui-caribe-card-primary.d.ts → caribeng-ui-card-primary.d.ts} +2 -2
  102. package/types/{caribeng-ui-caribe-card-select.d.ts → caribeng-ui-card-select.d.ts} +2 -2
  103. package/types/caribeng-ui-cascadeselect.d.ts +6 -0
  104. package/types/{caribeng-ui-caribe-coachmark.d.ts → caribeng-ui-coachmark.d.ts} +2 -2
  105. package/types/caribeng-ui-comments.d.ts +214 -0
  106. package/types/caribeng-ui-datagrid.d.ts +269 -0
  107. package/types/caribeng-ui-document.d.ts +138 -0
  108. package/types/{caribeng-ui-caribe-dots-indicator.d.ts → caribeng-ui-dots-indicator.d.ts} +2 -2
  109. package/types/caribeng-ui-dynamic-form.d.ts +409 -0
  110. package/types/caribeng-ui-editor.d.ts +110 -12
  111. package/types/{caribeng-ui-caribe-expansion-panel.d.ts → caribeng-ui-expansion-panel.d.ts} +1 -1
  112. package/types/{caribeng-ui-caribe-fab-menu.d.ts → caribeng-ui-fab-menu.d.ts} +2 -2
  113. package/types/{caribeng-ui-caribe-file-download.d.ts → caribeng-ui-file-download.d.ts} +1 -1
  114. package/types/caribeng-ui-financial-report.d.ts +102 -0
  115. package/types/{caribeng-ui-caribe-float-menu.d.ts → caribeng-ui-float-menu.d.ts} +2 -2
  116. package/types/caribeng-ui-flow.d.ts +228 -0
  117. package/types/{caribeng-ui-caribe-footer.d.ts → caribeng-ui-footer.d.ts} +2 -2
  118. package/types/caribeng-ui-gantt.d.ts +244 -0
  119. package/types/{caribeng-ui-caribe-header.d.ts → caribeng-ui-header.d.ts} +2 -2
  120. package/types/{caribeng-ui-caribe-icon-button.d.ts → caribeng-ui-icon-button.d.ts} +2 -2
  121. package/types/{caribeng-ui-caribe-illustration.d.ts → caribeng-ui-illustration.d.ts} +1 -1
  122. package/types/caribeng-ui-image-cropper.d.ts +169 -0
  123. package/types/caribeng-ui-import-wizard.d.ts +149 -0
  124. package/types/caribeng-ui-infinite-scroll.d.ts +75 -0
  125. package/types/caribeng-ui-input-number.d.ts +1 -1
  126. package/types/{caribeng-ui-caribe-input-search.d.ts → caribeng-ui-input-search.d.ts} +2 -2
  127. package/types/{caribeng-ui-caribe-input-token.d.ts → caribeng-ui-input-token.d.ts} +2 -2
  128. package/types/caribeng-ui-journal-entry.d.ts +110 -0
  129. package/types/caribeng-ui-kpi.d.ts +64 -0
  130. package/types/{caribeng-ui-caribe-link.d.ts → caribeng-ui-link.d.ts} +2 -2
  131. package/types/{caribeng-ui-caribe-logo.d.ts → caribeng-ui-logo.d.ts} +1 -1
  132. package/types/caribeng-ui-masonry.d.ts +32 -0
  133. package/types/caribeng-ui-media-player.d.ts +140 -0
  134. package/types/caribeng-ui-notification-center.d.ts +153 -0
  135. package/types/{caribeng-ui-caribe-off-canvas.d.ts → caribeng-ui-off-canvas.d.ts} +2 -2
  136. package/types/{caribeng-ui-caribe-onboarding.d.ts → caribeng-ui-onboarding.d.ts} +2 -2
  137. package/types/caribeng-ui-pdfviewer.d.ts +245 -5
  138. package/types/caribeng-ui-period-picker.d.ts +148 -0
  139. package/types/caribeng-ui-pivot.d.ts +116 -0
  140. package/types/caribeng-ui-reconciliation.d.ts +109 -0
  141. package/types/caribeng-ui-scheduler.d.ts +188 -0
  142. package/types/{caribeng-ui-caribe-shortcut.d.ts → caribeng-ui-shortcut.d.ts} +2 -2
  143. package/types/caribeng-ui-signature-pad.d.ts +151 -0
  144. package/types/{caribeng-ui-caribe-status.d.ts → caribeng-ui-status.d.ts} +2 -2
  145. package/types/{caribeng-ui-caribe-step-indicator.d.ts → caribeng-ui-step-indicator.d.ts} +2 -2
  146. package/types/caribeng-ui-table.d.ts +66 -2
  147. package/types/{caribeng-ui-caribe-tag-button.d.ts → caribeng-ui-tag-button.d.ts} +2 -2
  148. package/types/{caribeng-ui-caribe-tracker.d.ts → caribeng-ui-tracker.d.ts} +2 -2
  149. package/types/{caribeng-ui-caribe-transaction-status.d.ts → caribeng-ui-transaction-status.d.ts} +2 -2
  150. package/types/caribeng-ui-treeselect.d.ts +6 -0
  151. package/types/caribeng-ui-treetable.d.ts +67 -2
  152. package/types/{caribeng-ui-caribe-voucher.d.ts → caribeng-ui-voucher.d.ts} +2 -2
  153. package/types/caribeng-ui-xlsx.d.ts +79 -0
  154. package/types/caribeng-ui.d.ts +711 -2
  155. package/fesm2022/caribeng-ui-caribe-calendar.mjs +0 -92
  156. package/fesm2022/caribeng-ui-caribe-circle-loading.mjs +0 -130
  157. package/fesm2022/caribeng-ui-caribe-data-table.mjs +0 -94
  158. package/fesm2022/caribeng-ui-caribe-file-select.mjs +0 -88
  159. package/fesm2022/caribeng-ui-caribe-inline-alert.mjs +0 -100
  160. package/fesm2022/caribeng-ui-caribe-input-date.mjs +0 -138
  161. package/fesm2022/caribeng-ui-caribe-input-select.mjs +0 -154
  162. package/fesm2022/caribeng-ui-caribe-loader.mjs +0 -48
  163. package/fesm2022/caribeng-ui-caribe-modal.mjs +0 -119
  164. package/fesm2022/caribeng-ui-caribe-pictogram.mjs +0 -52
  165. package/fesm2022/caribeng-ui-caribe-pop-over.mjs +0 -104
  166. package/fesm2022/caribeng-ui-caribe-preloader.mjs +0 -57
  167. package/fesm2022/caribeng-ui-caribe-progress-bar.mjs +0 -84
  168. package/fesm2022/caribeng-ui-caribe-stroke.mjs +0 -69
  169. package/fesm2022/caribeng-ui-caribe-switch.mjs +0 -182
  170. package/types/caribeng-ui-caribe-calendar.d.ts +0 -27
  171. package/types/caribeng-ui-caribe-circle-loading.d.ts +0 -28
  172. package/types/caribeng-ui-caribe-data-table.d.ts +0 -26
  173. package/types/caribeng-ui-caribe-file-select.d.ts +0 -31
  174. package/types/caribeng-ui-caribe-inline-alert.d.ts +0 -28
  175. package/types/caribeng-ui-caribe-input-date.d.ts +0 -40
  176. package/types/caribeng-ui-caribe-input-select.d.ts +0 -47
  177. package/types/caribeng-ui-caribe-loader.d.ts +0 -22
  178. package/types/caribeng-ui-caribe-modal.d.ts +0 -21
  179. package/types/caribeng-ui-caribe-pictogram.d.ts +0 -15
  180. package/types/caribeng-ui-caribe-pop-over.d.ts +0 -17
  181. package/types/caribeng-ui-caribe-preloader.d.ts +0 -24
  182. package/types/caribeng-ui-caribe-progress-bar.d.ts +0 -28
  183. package/types/caribeng-ui-caribe-stroke.d.ts +0 -17
  184. package/types/caribeng-ui-caribe-switch.d.ts +0 -55
  185. /package/fesm2022/{caribeng-ui-caribe-illustration.mjs → caribeng-ui-illustration.mjs} +0 -0
  186. /package/fesm2022/{caribeng-ui-caribe-logo.mjs → caribeng-ui-logo.mjs} +0 -0
@@ -3,7 +3,8 @@ import { input, inject, TemplateRef, Directive, contentChildren, contentChild, v
3
3
  import { DOCUMENT, NgTemplateOutlet } from '@angular/common';
4
4
  import { CbIcon } from '@caribeng/ui/icon';
5
5
  import { CbPaginator } from '@caribeng/ui/paginator';
6
- import { injectCbTranslation, cbFormat } from '@caribeng/ui';
6
+ import { currencySymbol, cbDownloadXlsx } from '@caribeng/ui/xlsx';
7
+ import { injectCbTranslation, cbFormat, CB_CONFIG, cbSummarize, cbToNumber, cbFormatAmount } from '@caribeng/ui';
7
8
 
8
9
  /** Plantilla de las celdas de una columna: `<ng-template cbTableCell="campo" let-row let-value="value">`. */
9
10
  class CbTableCellDirective {
@@ -147,6 +148,14 @@ class CbTable {
147
148
  ...(ngDevMode ? [{ debugName: "totalRecords" }] : /* istanbul ignore next */ []));
148
149
  /** Muestra la capa de carga y marca la tabla con `aria-busy`. */
149
150
  this.loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: toBoolean });
151
+ /** Con `groupRowsBy`, una fila de subtotal al final de cada grupo (columnas con `summary`). */
152
+ this.groupSubtotals = input(false, { ...(ngDevMode ? { debugName: "groupSubtotals" } : /* istanbul ignore next */ {}), transform: toBoolean });
153
+ /** Moneda de las columnas `currency` (si no, la de `provideCaribeNG({ currency })`). */
154
+ this.currency = input(undefined, /* @ts-ignore */
155
+ ...(ngDevMode ? [{ debugName: "currency" }] : /* istanbul ignore next */ []));
156
+ /** Negativos con signo o entre paréntesis (si no, el de `provideCaribeNG({ negativeStyle })`). */
157
+ this.negativeStyle = input(undefined, /* @ts-ignore */
158
+ ...(ngDevMode ? [{ debugName: "negativeStyle" }] : /* istanbul ignore next */ []));
150
159
  this.selection = model(null, /* @ts-ignore */
151
160
  ...(ngDevMode ? [{ debugName: "selection" }] : /* istanbul ignore next */ []));
152
161
  this.sortChange = output();
@@ -239,6 +248,50 @@ class CbTable {
239
248
  return data.slice(start, start + this.rows());
240
249
  }, /* @ts-ignore */
241
250
  ...(ngDevMode ? [{ debugName: "pageRows" }] : /* istanbul ignore next */ []));
251
+ this.config = inject(CB_CONFIG);
252
+ this.hasSummary = computed(() => this.columns().some((c) => c.summary), /* @ts-ignore */
253
+ ...(ngDevMode ? [{ debugName: "hasSummary" }] : /* istanbul ignore next */ []));
254
+ this.hasFooterText = computed(() => this.columns().some((c) => c.footer), /* @ts-ignore */
255
+ ...(ngDevMode ? [{ debugName: "hasFooterText" }] : /* istanbul ignore next */ []));
256
+ this.hasFooter = computed(() => this.hasSummary() || this.hasFooterText(), /* @ts-ignore */
257
+ ...(ngDevMode ? [{ debugName: "hasFooter" }] : /* istanbul ignore next */ []));
258
+ /** Columna donde va la etiqueta "Total" / "Subtotal": la primera sin total. */
259
+ this.labelColumn = computed(() => Math.max(0, this.displayColumns().findIndex((c) => !c.summary)), /* @ts-ignore */
260
+ ...(ngDevMode ? [{ debugName: "labelColumn" }] : /* istanbul ignore next */ []));
261
+ /**
262
+ * Columnas que ocupa la etiqueta: desde la suya hasta la siguiente con total
263
+ * (sin partir columnas fijas de no fijas).
264
+ */
265
+ this.labelSpan = computed(() => {
266
+ const cols = this.displayColumns();
267
+ const start = this.labelColumn();
268
+ let end = start + 1;
269
+ while (end < cols.length && !cols[end].summary && !!cols[end].frozen === !!cols[start].frozen)
270
+ end++;
271
+ return end - start;
272
+ }, /* @ts-ignore */
273
+ ...(ngDevMode ? [{ debugName: "labelSpan" }] : /* istanbul ignore next */ []));
274
+ /** Totales del pie, sobre todas las filas filtradas (no solo la página). */
275
+ this.totals = computed(() => this.summarize(this.sorted()), /* @ts-ignore */
276
+ ...(ngDevMode ? [{ debugName: "totals" }] : /* istanbul ignore next */ []));
277
+ /** Totales por grupo (con `groupSubtotals`). */
278
+ this.groupTotals = computed(() => {
279
+ const field = this.groupRowsBy();
280
+ const out = new Map();
281
+ if (!field || !this.groupSubtotals() || !this.hasSummary())
282
+ return out;
283
+ const groups = new Map();
284
+ for (const row of this.sorted()) {
285
+ const key = fieldValue(row, field);
286
+ if (!groups.has(key))
287
+ groups.set(key, []);
288
+ groups.get(key).push(row);
289
+ }
290
+ for (const [key, rows] of groups)
291
+ out.set(key, this.summarize(rows));
292
+ return out;
293
+ }, /* @ts-ignore */
294
+ ...(ngDevMode ? [{ debugName: "groupTotals" }] : /* istanbul ignore next */ []));
242
295
  this.colspan = computed(() => this.displayColumns().length + (this.selectionMode() ? 1 : 0) + (this.expansion() ? 1 : 0), /* @ts-ignore */
243
296
  ...(ngDevMode ? [{ debugName: "colspan" }] : /* istanbul ignore next */ []));
244
297
  this.selectedCount = computed(() => {
@@ -419,6 +472,14 @@ class CbTable {
419
472
  groupCount(row) {
420
473
  return this.groupCounts().get(this.groupOf(row)) ?? 0;
421
474
  }
475
+ /** La fila cierra grupo si es la última de la página o el siguiente cambia de grupo. */
476
+ isGroupEnd(index) {
477
+ const rows = this.pageRows();
478
+ return index === rows.length - 1 || this.groupOf(rows[index + 1]) !== this.groupOf(rows[index]);
479
+ }
480
+ groupSummary(row, col) {
481
+ return this.groupTotals().get(this.groupOf(row))?.[col.field];
482
+ }
422
483
  /** La fila abre grupo si es la primera de la página o cambia el valor del grupo. */
423
484
  isGroupStart(index) {
424
485
  const rows = this.pageRows();
@@ -449,6 +510,47 @@ class CbTable {
449
510
  this.frozenOffsets.set(offsets);
450
511
  }
451
512
  // --- Exportación ---------------------------------------------------------------------
513
+ /**
514
+ * Hoja de Excel con las columnas visibles (salvo `exportable: false`) y todas las
515
+ * filas filtradas y ordenadas: importes como números con su formato, subtotales
516
+ * de grupo y totales en negrita.
517
+ */
518
+ toExcelSheet(options = {}) {
519
+ const cols = this.displayColumns().filter((c) => c.exportable !== false);
520
+ const locale = this.config.numberLocale ?? this.t().intlLocale;
521
+ const columns = cols.map((c) => {
522
+ const currency = c.currency ?? this.currency() ?? this.config.currency;
523
+ const negative = c.negative ?? this.negativeStyle() ?? this.config.negativeStyle;
524
+ return {
525
+ header: c.header,
526
+ type: c.type === 'currency' ? (currency ? 'currency' : 'number') : c.type === 'number' ? 'number' : c.type === 'percent' ? 'percent' : 'text',
527
+ decimals: c.decimals,
528
+ negative,
529
+ symbol: c.type === 'currency' && currency ? currencySymbol(currency, locale) : undefined,
530
+ };
531
+ });
532
+ const cell = (row, c) => {
533
+ const v = fieldValue(row, c.field);
534
+ return c.format && !this.isNumeric(c) ? c.format(v, row) : v;
535
+ };
536
+ const source = options.selectionOnly ? this.sorted().filter((row) => this.isSelected(row)) : this.sorted();
537
+ const rows = [];
538
+ const group = this.groupRowsBy();
539
+ source.forEach((row, i) => {
540
+ rows.push({ cells: cols.map((c) => cell(row, c)) });
541
+ const key = group ? fieldValue(row, group) : null;
542
+ if (group && this.groupSubtotals() && this.hasSummary() && (i === source.length - 1 || fieldValue(source[i + 1], group) !== key)) {
543
+ const totals = this.groupTotals().get(key) ?? {};
544
+ rows.push({ bold: true, cells: cols.map((c, ci) => (ci === 0 && !c.summary ? cbFormat(this.t().tableSubtotal, key) : totals[c.field])) });
545
+ }
546
+ });
547
+ const totals = this.hasSummary() ? cols.map((c, ci) => (ci === 0 && !c.summary ? (c.footer ?? this.t().tableTotal) : (this.totals()[c.field] ?? c.footer ?? null))) : undefined;
548
+ return { name: options.sheetName ?? this.ariaLabel() ?? 'Datos', title: options.title, columns, rows, totals };
549
+ }
550
+ /** Descarga las filas en Excel (`nombre.xlsx`) con formatos de número, subtotales y totales. */
551
+ exportExcel(filename = 'datos', options = {}) {
552
+ cbDownloadXlsx(filename, this.toExcelSheet(options));
553
+ }
452
554
  /**
453
555
  * Datos en CSV: columnas visibles (salvo `exportable: false`) y todas las filas
454
556
  * filtradas y ordenadas (no solo la página), o las seleccionadas con `selectionOnly`.
@@ -473,6 +575,58 @@ class CbTable {
473
575
  link.click();
474
576
  setTimeout(() => URL.revokeObjectURL(url));
475
577
  }
578
+ // --- Formato y totales -----------------------------------------------------------
579
+ /** Totales de las columnas con `summary` sobre unas filas. */
580
+ summarize(rows) {
581
+ const out = {};
582
+ for (const col of this.columns()) {
583
+ if (!col.summary)
584
+ continue;
585
+ out[col.field] = typeof col.summary === 'function' ? col.summary(rows) : cbSummarize(rows.map((r) => fieldValue(r, col.field)), col.summary);
586
+ }
587
+ return out;
588
+ }
589
+ isNumeric(col) {
590
+ return col.type === 'number' || col.type === 'currency' || col.type === 'percent';
591
+ }
592
+ alignOf(col) {
593
+ return col.align || (this.isNumeric(col) ? 'right' : null);
594
+ }
595
+ isNegative(value, col) {
596
+ if (!this.isNumeric(col))
597
+ return false;
598
+ const n = cbToNumber(value);
599
+ return n !== null && n < 0;
600
+ }
601
+ /** Texto de una celda: `format`, o el formato de su `type`. */
602
+ display(value, col, row) {
603
+ if (col.format)
604
+ return col.format(value, row);
605
+ return this.isNumeric(col) ? this.formatNumber(value, col) : value;
606
+ }
607
+ /** Texto de un total: con el formato de la columna (una cuenta, como número entero). */
608
+ summaryText(value, col) {
609
+ if (value === undefined || value === null)
610
+ return '';
611
+ if (col.summary === 'count')
612
+ return cbFormatAmount(value, this.config.numberLocale ?? this.t().intlLocale, { decimals: 0 });
613
+ if (col.format && typeof col.summary !== 'function')
614
+ return col.format(value, null);
615
+ return this.isNumeric(col) ? this.formatNumber(value, col) : String(value);
616
+ }
617
+ formatNumber(value, col) {
618
+ const locale = this.config.numberLocale ?? this.t().intlLocale;
619
+ const negative = col.negative ?? this.negativeStyle() ?? this.config.negativeStyle ?? 'minus';
620
+ if (col.type === 'percent') {
621
+ const n = cbToNumber(value);
622
+ if (n === null)
623
+ return value == null ? '' : String(value);
624
+ const text = new Intl.NumberFormat(locale, { style: 'percent', minimumFractionDigits: col.decimals ?? 0, maximumFractionDigits: col.decimals ?? 2 }).format(Math.abs(n));
625
+ return n < 0 ? (negative === 'parens' ? `(${text})` : `-${text}`) : text;
626
+ }
627
+ const currency = col.type === 'currency' ? (col.currency ?? this.currency() ?? this.config.currency ?? null) : null;
628
+ return cbFormatAmount(value, locale, { currency, decimals: col.decimals, negative });
629
+ }
476
630
  // --- Helpers ---------------------------------------------------------------
477
631
  cellValue(row, col) {
478
632
  return fieldValue(row, col.field);
@@ -516,9 +670,16 @@ class CbTable {
516
670
  return String(av).localeCompare(String(bv), undefined, { numeric: true });
517
671
  }
518
672
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CbTable, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
519
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: CbTable, isStandalone: true, selector: "cb-table", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, paginator: { classPropertyName: "paginator", publicName: "paginator", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, rowsPerPageOptions: { classPropertyName: "rowsPerPageOptions", publicName: "rowsPerPageOptions", isSignal: true, isRequired: false, transformFunction: null }, striped: { classPropertyName: "striped", publicName: "striped", isSignal: true, isRequired: false, transformFunction: null }, rowHover: { classPropertyName: "rowHover", publicName: "rowHover", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: true, isRequired: false, transformFunction: null }, globalFilter: { classPropertyName: "globalFilter", publicName: "globalFilter", isSignal: true, isRequired: false, transformFunction: null }, globalFilterFields: { classPropertyName: "globalFilterFields", publicName: "globalFilterFields", isSignal: true, isRequired: false, transformFunction: null }, resizableColumns: { classPropertyName: "resizableColumns", publicName: "resizableColumns", isSignal: true, isRequired: false, transformFunction: null }, expandedRowKeys: { classPropertyName: "expandedRowKeys", publicName: "expandedRowKeys", isSignal: true, isRequired: false, transformFunction: null }, scrollHeight: { classPropertyName: "scrollHeight", publicName: "scrollHeight", isSignal: true, isRequired: false, transformFunction: null }, groupRowsBy: { classPropertyName: "groupRowsBy", publicName: "groupRowsBy", isSignal: true, isRequired: false, transformFunction: null }, lazy: { classPropertyName: "lazy", publicName: "lazy", isSignal: true, isRequired: false, transformFunction: null }, totalRecords: { classPropertyName: "totalRecords", publicName: "totalRecords", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rows: "rowsChange", globalFilter: "globalFilterChange", expandedRowKeys: "expandedRowKeysChange", selection: "selectionChange", sortChange: "sortChange", filterChange: "filterChange", columnResize: "columnResize", rowExpand: "rowExpand", rowCollapse: "rowCollapse", lazyLoad: "lazyLoad" }, host: { classAttribute: "cb-table-host" }, queries: [{ propertyName: "cellTemplates", predicate: CbTableCellDirective, isSignal: true }, { propertyName: "expansion", first: true, predicate: CbTableRowExpansion, descendants: true, isSignal: true }, { propertyName: "groupHeader", first: true, predicate: CbTableGroupHeader, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "tableRef", first: true, predicate: ["table"], descendants: true, isSignal: true }], ngImport: i0, template: `
673
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: CbTable, isStandalone: true, selector: "cb-table", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, paginator: { classPropertyName: "paginator", publicName: "paginator", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, rowsPerPageOptions: { classPropertyName: "rowsPerPageOptions", publicName: "rowsPerPageOptions", isSignal: true, isRequired: false, transformFunction: null }, striped: { classPropertyName: "striped", publicName: "striped", isSignal: true, isRequired: false, transformFunction: null }, rowHover: { classPropertyName: "rowHover", publicName: "rowHover", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: true, isRequired: false, transformFunction: null }, globalFilter: { classPropertyName: "globalFilter", publicName: "globalFilter", isSignal: true, isRequired: false, transformFunction: null }, globalFilterFields: { classPropertyName: "globalFilterFields", publicName: "globalFilterFields", isSignal: true, isRequired: false, transformFunction: null }, resizableColumns: { classPropertyName: "resizableColumns", publicName: "resizableColumns", isSignal: true, isRequired: false, transformFunction: null }, expandedRowKeys: { classPropertyName: "expandedRowKeys", publicName: "expandedRowKeys", isSignal: true, isRequired: false, transformFunction: null }, scrollHeight: { classPropertyName: "scrollHeight", publicName: "scrollHeight", isSignal: true, isRequired: false, transformFunction: null }, groupRowsBy: { classPropertyName: "groupRowsBy", publicName: "groupRowsBy", isSignal: true, isRequired: false, transformFunction: null }, lazy: { classPropertyName: "lazy", publicName: "lazy", isSignal: true, isRequired: false, transformFunction: null }, totalRecords: { classPropertyName: "totalRecords", publicName: "totalRecords", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, groupSubtotals: { classPropertyName: "groupSubtotals", publicName: "groupSubtotals", isSignal: true, isRequired: false, transformFunction: null }, currency: { classPropertyName: "currency", publicName: "currency", isSignal: true, isRequired: false, transformFunction: null }, negativeStyle: { classPropertyName: "negativeStyle", publicName: "negativeStyle", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rows: "rowsChange", globalFilter: "globalFilterChange", expandedRowKeys: "expandedRowKeysChange", selection: "selectionChange", sortChange: "sortChange", filterChange: "filterChange", columnResize: "columnResize", rowExpand: "rowExpand", rowCollapse: "rowCollapse", lazyLoad: "lazyLoad" }, host: { classAttribute: "cb-table-host" }, queries: [{ propertyName: "cellTemplates", predicate: CbTableCellDirective, isSignal: true }, { propertyName: "expansion", first: true, predicate: CbTableRowExpansion, descendants: true, isSignal: true }, { propertyName: "groupHeader", first: true, predicate: CbTableGroupHeader, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "tableRef", first: true, predicate: ["table"], descendants: true, isSignal: true }], ngImport: i0, template: `
520
674
  <ng-content select="[cbTableHeader]" />
521
- <div class="cb-table__wrap" [class.cb-table__wrap--scroll]="!!scrollHeight()" [style.max-height]="scrollHeight()">
675
+ <div
676
+ class="cb-table__wrap"
677
+ [class.cb-table__wrap--scroll]="!!scrollHeight()"
678
+ [style.max-height]="scrollHeight()"
679
+ [attr.tabindex]="scrollHeight() ? 0 : null"
680
+ [attr.role]="scrollHeight() ? 'region' : null"
681
+ [attr.aria-label]="scrollHeight() ? ariaLabel() || t().tableScrollRegion : null"
682
+ >
522
683
  <table
523
684
  #table
524
685
  class="cb-table"
@@ -564,6 +725,7 @@ class CbTable {
564
725
  }
565
726
  @for (col of displayColumns(); track col.field) {
566
727
  <th
728
+ #th
567
729
  class="cb-table__th"
568
730
  scope="col"
569
731
  [attr.data-key]="col.field"
@@ -572,7 +734,7 @@ class CbTable {
572
734
  [style.left.px]="col.frozen ? frozenLeft(col.field) : null"
573
735
  [class.cb-is-sortable]="col.sortable"
574
736
  [style.width]="columnWidth(col)"
575
- [style.text-align]="col.align || null"
737
+ [style.text-align]="alignOf(col)"
576
738
  [attr.aria-sort]="ariaSort(col)"
577
739
  >
578
740
  @if (col.sortable) {
@@ -595,7 +757,7 @@ class CbTable {
595
757
  aria-orientation="vertical"
596
758
  tabindex="0"
597
759
  [attr.aria-label]="fmt(t().resizeColumn, col.header)"
598
- [attr.aria-valuenow]="widths()[col.field] ?? null"
760
+ [attr.aria-valuenow]="widths()[col.field] ?? (th.offsetWidth || minColumnWidth)"
599
761
  [attr.aria-valuemin]="minColumnWidth"
600
762
  (pointerdown)="startResize($event, col)"
601
763
  (keydown)="onResizerKeydown($event, col)"
@@ -693,17 +855,51 @@ class CbTable {
693
855
  class="cb-table__td"
694
856
  [class.cb-is-frozen]="!!col.frozen"
695
857
  [class.cb-is-frozen-last]="col.field === lastFrozen()"
858
+ [class.cb-table__num]="isNumeric(col)"
859
+ [class.cb-is-negative]="isNegative(cellValue(row, col), col)"
696
860
  [style.left.px]="col.frozen ? frozenLeft(col.field) : null"
697
- [style.text-align]="col.align || null"
861
+ [style.text-align]="alignOf(col)"
698
862
  >
699
863
  @if (cellTemplate(col.field); as cell) {
700
864
  <ng-container [ngTemplateOutlet]="cell.template" [ngTemplateOutletContext]="cellContext(row, col)" />
701
865
  } @else {
702
- {{ cellValue(row, col) }}
866
+ {{ display(cellValue(row, col), col, row) }}
703
867
  }
704
868
  </td>
705
869
  }
706
870
  </tr>
871
+ @if (groupRowsBy() && groupSubtotals() && hasSummary() && isGroupEnd(i)) {
872
+ <tr class="cb-table__subtotal">
873
+ @if (expansion()) {
874
+ <td class="cb-table__sel" [class.cb-is-frozen]="hasFrozen()" [style.left.px]="frozenLeft('__exp')"></td>
875
+ }
876
+ @if (selectionMode()) {
877
+ <td class="cb-table__sel" [class.cb-is-frozen]="hasFrozen()" [style.left.px]="frozenLeft('__sel')"></td>
878
+ }
879
+ @for (col of displayColumns(); track col.field; let c = $index) {
880
+ @if (c < labelColumn() + labelSpan() && c > labelColumn()) {
881
+ <!-- cubierta por la etiqueta -->
882
+ } @else if (c === labelColumn()) {
883
+ <th
884
+ scope="row"
885
+ class="cb-table__td"
886
+ [attr.colspan]="labelSpan() > 1 ? labelSpan() : null"
887
+ [class.cb-is-frozen]="!!col.frozen"
888
+ [style.left.px]="col.frozen ? frozenLeft(col.field) : null"
889
+ >{{ fmt(t().tableSubtotal, groupOf(row)) }}</th>
890
+ } @else {
891
+ <td
892
+ class="cb-table__td"
893
+ [class.cb-is-frozen]="!!col.frozen"
894
+ [class.cb-table__num]="isNumeric(col)"
895
+ [class.cb-is-negative]="isNegative(groupSummary(row, col), col)"
896
+ [style.left.px]="col.frozen ? frozenLeft(col.field) : null"
897
+ [style.text-align]="alignOf(col)"
898
+ >{{ summaryText(groupSummary(row, col), col) }}</td>
899
+ }
900
+ }
901
+ </tr>
902
+ }
707
903
  @if (expansion(); as exp) {
708
904
  @if (isExpanded(row)) {
709
905
  <tr class="cb-table__expansion" [id]="expansionId(first() + i)">
@@ -722,6 +918,41 @@ class CbTable {
722
918
  </tr>
723
919
  }
724
920
  </tbody>
921
+ @if (hasFooter() && pageRows().length) {
922
+ <tfoot>
923
+ <tr class="cb-table__foot">
924
+ @if (expansion()) {
925
+ <td class="cb-table__sel" [class.cb-is-frozen]="hasFrozen()" [style.left.px]="frozenLeft('__exp')"></td>
926
+ }
927
+ @if (selectionMode()) {
928
+ <td class="cb-table__sel" [class.cb-is-frozen]="hasFrozen()" [style.left.px]="frozenLeft('__sel')"></td>
929
+ }
930
+ @for (col of displayColumns(); track col.field; let c = $index) {
931
+ @if (!hasFooterText() && c < labelColumn() + labelSpan() && c > labelColumn()) {
932
+ <!-- cubierta por la etiqueta -->
933
+ } @else if (col.footer || (c === labelColumn() && !hasFooterText())) {
934
+ <th
935
+ scope="row"
936
+ class="cb-table__td"
937
+ [attr.colspan]="!hasFooterText() && labelSpan() > 1 ? labelSpan() : null"
938
+ [class.cb-is-frozen]="!!col.frozen"
939
+ [style.left.px]="col.frozen ? frozenLeft(col.field) : null"
940
+ [style.text-align]="hasFooterText() ? alignOf(col) : null"
941
+ >{{ col.footer || t().tableTotal }}</th>
942
+ } @else {
943
+ <td
944
+ class="cb-table__td"
945
+ [class.cb-is-frozen]="!!col.frozen"
946
+ [class.cb-table__num]="isNumeric(col)"
947
+ [class.cb-is-negative]="isNegative(totals()[col.field], col)"
948
+ [style.left.px]="col.frozen ? frozenLeft(col.field) : null"
949
+ [style.text-align]="alignOf(col)"
950
+ >{{ summaryText(totals()[col.field], col) }}</td>
951
+ }
952
+ }
953
+ </tr>
954
+ </tfoot>
955
+ }
725
956
  </table>
726
957
  @if (loading()) {
727
958
  <div class="cb-table__loading" role="status">
@@ -744,13 +975,20 @@ class CbTable {
744
975
  (pageChange)="onPageChange($event)"
745
976
  />
746
977
  }
747
- `, isInline: true, styles: [":host{display:block;font-family:var(--cb-font-sans);color:var(--cb-color-text)}.cb-table__wrap{overflow-x:auto;border:var(--cb-border-width) solid var(--cb-color-border);border-radius:var(--cb-radius-md)}.cb-table{width:100%;border-collapse:collapse;font-size:var(--cb-text-sm)}.cb-table__th,.cb-table__td,.cb-table__sel{padding:var(--cb-space-3) var(--cb-space-4);text-align:left;border-bottom:var(--cb-border-width) solid var(--cb-color-border);vertical-align:middle}.cb-table--sm .cb-table__th,.cb-table--sm .cb-table__td,.cb-table--sm .cb-table__sel{padding:var(--cb-space-2) var(--cb-space-3)}.cb-table--lg .cb-table__th,.cb-table--lg .cb-table__td,.cb-table--lg .cb-table__sel{padding:var(--cb-space-4) var(--cb-space-5)}.cb-table thead .cb-table__th,.cb-table thead .cb-table__sel{background-color:var(--cb-color-surface-subtle);color:var(--cb-color-text);font-weight:var(--cb-font-weight-semibold);white-space:nowrap;border-bottom-width:2px}.cb-table__th-inner{display:inline-flex;align-items:center;gap:var(--cb-space-1)}.cb-table__th{position:relative}.cb-table__th.cb-is-sortable:hover{background-color:var(--cb-color-surface-hover)}.cb-table__sort-btn{margin:0;padding:0;font:inherit;color:inherit;text-align:inherit;background:none;border:none;border-radius:var(--cb-radius-sm);cursor:pointer;-webkit-user-select:none;user-select:none}.cb-table__sort-btn:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:2px}.cb-table--resizable{table-layout:fixed}.cb-table--resizable .cb-table__th{overflow:hidden;text-overflow:ellipsis}.cb-table__resizer{position:absolute;top:0;right:0;width:.5rem;height:100%;cursor:col-resize;touch-action:none}.cb-table__resizer:after{content:\"\";position:absolute;top:25%;right:.2rem;width:2px;height:50%;background-color:var(--cb-color-border-strong);border-radius:1px}.cb-table__resizer:hover:after,.cb-table__resizer:focus-visible:after{background-color:var(--cb-color-primary-500)}.cb-table__resizer:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:-2px}.cb-table__filter-row td{padding:var(--cb-space-2) var(--cb-space-4);background-color:var(--cb-color-surface-subtle);border-bottom:var(--cb-border-width) solid var(--cb-color-border)}.cb-table__filter{box-sizing:border-box;width:100%;min-width:6rem;padding:var(--cb-space-1) var(--cb-space-2);font:inherit;font-size:var(--cb-text-sm);color:var(--cb-color-text);background-color:var(--cb-color-surface-0);border:var(--cb-border-width) solid var(--cb-color-border-strong);border-radius:var(--cb-radius-sm)}.cb-table__filter:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:1px}.cb-table__expander{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;padding:0;color:var(--cb-color-text-muted);background:none;border:none;border-radius:var(--cb-radius-sm);cursor:pointer}.cb-table__expander:hover{background-color:var(--cb-color-surface-hover)}.cb-table__expander:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:1px}.cb-table__expansion>td{padding:var(--cb-space-4);background-color:var(--cb-color-surface-subtle);border-bottom:var(--cb-border-width) solid var(--cb-color-border)}.cb-table__sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.cb-table__sort{color:var(--cb-color-text-muted)}.cb-table tbody tr:last-child .cb-table__td,.cb-table tbody tr:last-child .cb-table__sel{border-bottom:none}.cb-table--striped tbody tr:nth-child(2n){background-color:var(--cb-color-surface-subtle)}.cb-table--hover tbody .cb-table__row:hover{background-color:var(--cb-color-surface-hover)}.cb-table__row.cb-is-selectable{cursor:pointer}.cb-table__row.cb-is-selected{background-color:var(--cb-color-primary-50)!important}.cb-table__sel{width:1px;white-space:nowrap}.cb-table__check{display:inline-flex;align-items:center;justify-content:center;width:1.1rem;height:1.1rem;border:var(--cb-border-width) solid var(--cb-color-border-strong);border-radius:var(--cb-radius-sm);color:var(--cb-color-primary-contrast);outline:none}.cb-table__check:focus-visible{box-shadow:0 0 0 3px var(--cb-color-focus-ring)}.cb-table__check.cb-is-checked,.cb-table__check.cb-is-mixed{background-color:var(--cb-color-primary-500);border-color:var(--cb-color-primary-500)}.cb-table__check--radio{border-radius:50%}.cb-table__empty{padding:var(--cb-space-6);text-align:center;color:var(--cb-color-text-muted)}.cb-table__paginator{margin-top:var(--cb-space-3)}:host-context([data-theme=\"dark\"]) .cb-table__row.cb-is-selected{background-color:color-mix(in srgb,var(--cb-color-primary-500) 20%,transparent)!important}.cb-table__wrap{position:relative}.cb-table__wrap--scroll{overflow:auto}.cb-table--scroll thead{position:sticky;top:0;z-index:2}.cb-is-frozen{position:sticky;z-index:1;background-color:var(--cb-color-surface-raised)}thead .cb-is-frozen{z-index:3;background-color:var(--cb-color-surface-subtle)}.cb-table--striped tbody tr:nth-child(2n) .cb-is-frozen{background-color:var(--cb-color-surface-subtle)}.cb-table--hover tbody .cb-table__row:hover .cb-is-frozen{background-color:var(--cb-color-surface-hover)}.cb-is-frozen-last{box-shadow:4px 0 6px -4px #00000040}.cb-table__group>th{padding:var(--cb-space-2) var(--cb-space-4);font-size:var(--cb-text-sm);font-weight:var(--cb-font-weight-semibold);text-align:left;color:var(--cb-color-text-strong);background-color:var(--cb-color-surface-subtle);border-bottom:var(--cb-border-width) solid var(--cb-color-border)}.cb-table__group-count{font-weight:var(--cb-font-weight-normal, 400);color:var(--cb-color-text-muted)}.cb-table__loading{position:absolute;inset:0;z-index:4;display:flex;align-items:center;justify-content:center;color:var(--cb-color-primary-500);background-color:color-mix(in srgb,var(--cb-color-surface-raised) 65%,transparent)}\n"], dependencies: [{ kind: "component", type: CbIcon, selector: "cb-icon", inputs: ["name", "size", "spin", "ariaLabel"] }, { kind: "component", type: CbPaginator, selector: "cb-paginator", inputs: ["totalRecords", "rows", "first", "rowsPerPageOptions", "showReport", "maxPageLinks"], outputs: ["rowsChange", "firstChange", "pageChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
978
+ `, isInline: true, styles: [":host{display:block;font-family:var(--cb-font-sans);color:var(--cb-color-text)}.cb-table__wrap{overflow-x:auto;border:var(--cb-border-width) solid var(--cb-color-border);border-radius:var(--cb-radius-md)}.cb-table{width:100%;border-collapse:collapse;font-size:var(--cb-text-sm)}.cb-table__th,.cb-table__td,.cb-table__sel{padding:var(--cb-space-3) var(--cb-space-4);text-align:left;border-bottom:var(--cb-border-width) solid var(--cb-color-border);vertical-align:middle}.cb-table--sm .cb-table__th,.cb-table--sm .cb-table__td,.cb-table--sm .cb-table__sel{padding:var(--cb-space-2) var(--cb-space-3)}.cb-table--lg .cb-table__th,.cb-table--lg .cb-table__td,.cb-table--lg .cb-table__sel{padding:var(--cb-space-4) var(--cb-space-5)}.cb-table thead .cb-table__th,.cb-table thead .cb-table__sel{background-color:var(--cb-color-surface-subtle);color:var(--cb-color-text);font-weight:var(--cb-font-weight-semibold);white-space:nowrap;border-bottom-width:2px}.cb-table__th-inner{display:inline-flex;align-items:center;gap:var(--cb-space-1)}.cb-table__th{position:relative}.cb-table__th.cb-is-sortable:hover{background-color:var(--cb-color-surface-hover)}.cb-table__sort-btn{margin:0;padding:0;font:inherit;color:inherit;text-align:inherit;background:none;border:none;border-radius:var(--cb-radius-sm);cursor:pointer;-webkit-user-select:none;user-select:none}.cb-table__sort-btn:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:2px}.cb-table--resizable{table-layout:fixed}.cb-table--resizable .cb-table__th{overflow:hidden;text-overflow:ellipsis}.cb-table__resizer{position:absolute;top:0;right:0;width:.5rem;height:100%;cursor:col-resize;touch-action:none}.cb-table__resizer:after{content:\"\";position:absolute;top:25%;right:.2rem;width:2px;height:50%;background-color:var(--cb-color-border-strong);border-radius:1px}.cb-table__resizer:hover:after,.cb-table__resizer:focus-visible:after{background-color:var(--cb-color-primary-500)}.cb-table__resizer:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:-2px}.cb-table__filter-row td{padding:var(--cb-space-2) var(--cb-space-4);background-color:var(--cb-color-surface-subtle);border-bottom:var(--cb-border-width) solid var(--cb-color-border)}.cb-table__filter{box-sizing:border-box;width:100%;min-width:6rem;padding:var(--cb-space-1) var(--cb-space-2);font:inherit;font-size:var(--cb-text-sm);color:var(--cb-color-text);background-color:var(--cb-color-surface-0);border:var(--cb-border-width) solid var(--cb-color-border-strong);border-radius:var(--cb-radius-sm)}.cb-table__filter:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:1px}.cb-table__expander{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;padding:0;color:var(--cb-color-text-muted);background:none;border:none;border-radius:var(--cb-radius-sm);cursor:pointer}.cb-table__expander:hover{background-color:var(--cb-color-surface-hover)}.cb-table__expander:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:1px}.cb-table__expansion>td{padding:var(--cb-space-4);background-color:var(--cb-color-surface-subtle);border-bottom:var(--cb-border-width) solid var(--cb-color-border)}.cb-table__sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.cb-table__sort{color:var(--cb-color-text-muted)}.cb-table tbody tr:last-child .cb-table__td,.cb-table tbody tr:last-child .cb-table__sel{border-bottom:none}.cb-table--striped tbody tr:nth-child(2n){background-color:var(--cb-color-surface-subtle)}.cb-table--hover tbody .cb-table__row:hover{background-color:var(--cb-color-surface-hover)}.cb-table__row.cb-is-selectable{cursor:pointer}.cb-table__row.cb-is-selected{background-color:var(--cb-color-primary-50)!important}.cb-table__sel{width:1px;white-space:nowrap}.cb-table__check{display:inline-flex;align-items:center;justify-content:center;width:1.1rem;height:1.1rem;border:var(--cb-border-width) solid var(--cb-color-border-strong);border-radius:var(--cb-radius-sm);color:var(--cb-color-primary-contrast);outline:none}.cb-table__check:focus-visible{box-shadow:0 0 0 3px var(--cb-color-focus-ring)}.cb-table__check.cb-is-checked,.cb-table__check.cb-is-mixed{background-color:var(--cb-color-primary-500);border-color:var(--cb-color-primary-500)}.cb-table__check--radio{border-radius:50%}.cb-table__empty{padding:var(--cb-space-6);text-align:center;color:var(--cb-color-text-muted)}.cb-table__paginator{margin-top:var(--cb-space-3)}:host-context([data-theme=\"dark\"]) .cb-table__row.cb-is-selected{background-color:color-mix(in srgb,var(--cb-color-primary-500) 20%,transparent)!important}.cb-table__wrap{position:relative}.cb-table__wrap--scroll{overflow:auto}.cb-table__wrap--scroll:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:2px}.cb-table--scroll thead{position:sticky;top:0;z-index:2}.cb-is-frozen{position:sticky;z-index:1;background-color:var(--cb-color-surface-raised)}thead .cb-is-frozen{z-index:3;background-color:var(--cb-color-surface-subtle)}.cb-table--striped tbody tr:nth-child(2n) .cb-is-frozen{background-color:var(--cb-color-surface-subtle)}.cb-table--hover tbody .cb-table__row:hover .cb-is-frozen{background-color:var(--cb-color-surface-hover)}.cb-is-frozen-last{box-shadow:4px 0 6px -4px #00000040}.cb-table__group>th{padding:var(--cb-space-2) var(--cb-space-4);font-size:var(--cb-text-sm);font-weight:var(--cb-font-weight-semibold);text-align:left;color:var(--cb-color-text-strong);background-color:var(--cb-color-surface-subtle);border-bottom:var(--cb-border-width) solid var(--cb-color-border)}.cb-table__group-count{font-weight:var(--cb-font-weight-normal, 400);color:var(--cb-color-text-muted)}.cb-table__num{font-variant-numeric:tabular-nums;white-space:nowrap}.cb-table .cb-is-negative{color:var(--cb-color-danger-text, #dc2626)}.cb-table__subtotal>.cb-table__td{font-weight:var(--cb-font-weight-semibold);background-color:var(--cb-color-surface-subtle);border-bottom:var(--cb-border-width) solid var(--cb-color-border-strong)}.cb-table__foot>.cb-table__td,.cb-table__foot>.cb-table__sel{font-weight:var(--cb-font-weight-semibold);color:var(--cb-color-text-strong);background-color:var(--cb-color-surface-subtle);border-top:2px solid var(--cb-color-border-strong);border-bottom:0}.cb-table--scroll tfoot{position:sticky;bottom:0;z-index:2}tfoot .cb-is-frozen,.cb-table__subtotal .cb-is-frozen{background-color:var(--cb-color-surface-subtle)}.cb-table__loading{position:absolute;inset:0;z-index:4;display:flex;align-items:center;justify-content:center;color:var(--cb-color-primary-text);background-color:color-mix(in srgb,var(--cb-color-surface-raised) 65%,transparent)}\n"], dependencies: [{ kind: "component", type: CbIcon, selector: "cb-icon", inputs: ["name", "size", "spin", "ariaLabel"] }, { kind: "component", type: CbPaginator, selector: "cb-paginator", inputs: ["totalRecords", "rows", "first", "rowsPerPageOptions", "showReport", "maxPageLinks"], outputs: ["rowsChange", "firstChange", "pageChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
748
979
  }
749
980
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CbTable, decorators: [{
750
981
  type: Component,
751
982
  args: [{ selector: 'cb-table', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, imports: [CbIcon, CbPaginator, NgTemplateOutlet], host: { class: 'cb-table-host' }, template: `
752
983
  <ng-content select="[cbTableHeader]" />
753
- <div class="cb-table__wrap" [class.cb-table__wrap--scroll]="!!scrollHeight()" [style.max-height]="scrollHeight()">
984
+ <div
985
+ class="cb-table__wrap"
986
+ [class.cb-table__wrap--scroll]="!!scrollHeight()"
987
+ [style.max-height]="scrollHeight()"
988
+ [attr.tabindex]="scrollHeight() ? 0 : null"
989
+ [attr.role]="scrollHeight() ? 'region' : null"
990
+ [attr.aria-label]="scrollHeight() ? ariaLabel() || t().tableScrollRegion : null"
991
+ >
754
992
  <table
755
993
  #table
756
994
  class="cb-table"
@@ -796,6 +1034,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
796
1034
  }
797
1035
  @for (col of displayColumns(); track col.field) {
798
1036
  <th
1037
+ #th
799
1038
  class="cb-table__th"
800
1039
  scope="col"
801
1040
  [attr.data-key]="col.field"
@@ -804,7 +1043,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
804
1043
  [style.left.px]="col.frozen ? frozenLeft(col.field) : null"
805
1044
  [class.cb-is-sortable]="col.sortable"
806
1045
  [style.width]="columnWidth(col)"
807
- [style.text-align]="col.align || null"
1046
+ [style.text-align]="alignOf(col)"
808
1047
  [attr.aria-sort]="ariaSort(col)"
809
1048
  >
810
1049
  @if (col.sortable) {
@@ -827,7 +1066,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
827
1066
  aria-orientation="vertical"
828
1067
  tabindex="0"
829
1068
  [attr.aria-label]="fmt(t().resizeColumn, col.header)"
830
- [attr.aria-valuenow]="widths()[col.field] ?? null"
1069
+ [attr.aria-valuenow]="widths()[col.field] ?? (th.offsetWidth || minColumnWidth)"
831
1070
  [attr.aria-valuemin]="minColumnWidth"
832
1071
  (pointerdown)="startResize($event, col)"
833
1072
  (keydown)="onResizerKeydown($event, col)"
@@ -925,17 +1164,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
925
1164
  class="cb-table__td"
926
1165
  [class.cb-is-frozen]="!!col.frozen"
927
1166
  [class.cb-is-frozen-last]="col.field === lastFrozen()"
1167
+ [class.cb-table__num]="isNumeric(col)"
1168
+ [class.cb-is-negative]="isNegative(cellValue(row, col), col)"
928
1169
  [style.left.px]="col.frozen ? frozenLeft(col.field) : null"
929
- [style.text-align]="col.align || null"
1170
+ [style.text-align]="alignOf(col)"
930
1171
  >
931
1172
  @if (cellTemplate(col.field); as cell) {
932
1173
  <ng-container [ngTemplateOutlet]="cell.template" [ngTemplateOutletContext]="cellContext(row, col)" />
933
1174
  } @else {
934
- {{ cellValue(row, col) }}
1175
+ {{ display(cellValue(row, col), col, row) }}
935
1176
  }
936
1177
  </td>
937
1178
  }
938
1179
  </tr>
1180
+ @if (groupRowsBy() && groupSubtotals() && hasSummary() && isGroupEnd(i)) {
1181
+ <tr class="cb-table__subtotal">
1182
+ @if (expansion()) {
1183
+ <td class="cb-table__sel" [class.cb-is-frozen]="hasFrozen()" [style.left.px]="frozenLeft('__exp')"></td>
1184
+ }
1185
+ @if (selectionMode()) {
1186
+ <td class="cb-table__sel" [class.cb-is-frozen]="hasFrozen()" [style.left.px]="frozenLeft('__sel')"></td>
1187
+ }
1188
+ @for (col of displayColumns(); track col.field; let c = $index) {
1189
+ @if (c < labelColumn() + labelSpan() && c > labelColumn()) {
1190
+ <!-- cubierta por la etiqueta -->
1191
+ } @else if (c === labelColumn()) {
1192
+ <th
1193
+ scope="row"
1194
+ class="cb-table__td"
1195
+ [attr.colspan]="labelSpan() > 1 ? labelSpan() : null"
1196
+ [class.cb-is-frozen]="!!col.frozen"
1197
+ [style.left.px]="col.frozen ? frozenLeft(col.field) : null"
1198
+ >{{ fmt(t().tableSubtotal, groupOf(row)) }}</th>
1199
+ } @else {
1200
+ <td
1201
+ class="cb-table__td"
1202
+ [class.cb-is-frozen]="!!col.frozen"
1203
+ [class.cb-table__num]="isNumeric(col)"
1204
+ [class.cb-is-negative]="isNegative(groupSummary(row, col), col)"
1205
+ [style.left.px]="col.frozen ? frozenLeft(col.field) : null"
1206
+ [style.text-align]="alignOf(col)"
1207
+ >{{ summaryText(groupSummary(row, col), col) }}</td>
1208
+ }
1209
+ }
1210
+ </tr>
1211
+ }
939
1212
  @if (expansion(); as exp) {
940
1213
  @if (isExpanded(row)) {
941
1214
  <tr class="cb-table__expansion" [id]="expansionId(first() + i)">
@@ -954,6 +1227,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
954
1227
  </tr>
955
1228
  }
956
1229
  </tbody>
1230
+ @if (hasFooter() && pageRows().length) {
1231
+ <tfoot>
1232
+ <tr class="cb-table__foot">
1233
+ @if (expansion()) {
1234
+ <td class="cb-table__sel" [class.cb-is-frozen]="hasFrozen()" [style.left.px]="frozenLeft('__exp')"></td>
1235
+ }
1236
+ @if (selectionMode()) {
1237
+ <td class="cb-table__sel" [class.cb-is-frozen]="hasFrozen()" [style.left.px]="frozenLeft('__sel')"></td>
1238
+ }
1239
+ @for (col of displayColumns(); track col.field; let c = $index) {
1240
+ @if (!hasFooterText() && c < labelColumn() + labelSpan() && c > labelColumn()) {
1241
+ <!-- cubierta por la etiqueta -->
1242
+ } @else if (col.footer || (c === labelColumn() && !hasFooterText())) {
1243
+ <th
1244
+ scope="row"
1245
+ class="cb-table__td"
1246
+ [attr.colspan]="!hasFooterText() && labelSpan() > 1 ? labelSpan() : null"
1247
+ [class.cb-is-frozen]="!!col.frozen"
1248
+ [style.left.px]="col.frozen ? frozenLeft(col.field) : null"
1249
+ [style.text-align]="hasFooterText() ? alignOf(col) : null"
1250
+ >{{ col.footer || t().tableTotal }}</th>
1251
+ } @else {
1252
+ <td
1253
+ class="cb-table__td"
1254
+ [class.cb-is-frozen]="!!col.frozen"
1255
+ [class.cb-table__num]="isNumeric(col)"
1256
+ [class.cb-is-negative]="isNegative(totals()[col.field], col)"
1257
+ [style.left.px]="col.frozen ? frozenLeft(col.field) : null"
1258
+ [style.text-align]="alignOf(col)"
1259
+ >{{ summaryText(totals()[col.field], col) }}</td>
1260
+ }
1261
+ }
1262
+ </tr>
1263
+ </tfoot>
1264
+ }
957
1265
  </table>
958
1266
  @if (loading()) {
959
1267
  <div class="cb-table__loading" role="status">
@@ -976,8 +1284,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
976
1284
  (pageChange)="onPageChange($event)"
977
1285
  />
978
1286
  }
979
- `, styles: [":host{display:block;font-family:var(--cb-font-sans);color:var(--cb-color-text)}.cb-table__wrap{overflow-x:auto;border:var(--cb-border-width) solid var(--cb-color-border);border-radius:var(--cb-radius-md)}.cb-table{width:100%;border-collapse:collapse;font-size:var(--cb-text-sm)}.cb-table__th,.cb-table__td,.cb-table__sel{padding:var(--cb-space-3) var(--cb-space-4);text-align:left;border-bottom:var(--cb-border-width) solid var(--cb-color-border);vertical-align:middle}.cb-table--sm .cb-table__th,.cb-table--sm .cb-table__td,.cb-table--sm .cb-table__sel{padding:var(--cb-space-2) var(--cb-space-3)}.cb-table--lg .cb-table__th,.cb-table--lg .cb-table__td,.cb-table--lg .cb-table__sel{padding:var(--cb-space-4) var(--cb-space-5)}.cb-table thead .cb-table__th,.cb-table thead .cb-table__sel{background-color:var(--cb-color-surface-subtle);color:var(--cb-color-text);font-weight:var(--cb-font-weight-semibold);white-space:nowrap;border-bottom-width:2px}.cb-table__th-inner{display:inline-flex;align-items:center;gap:var(--cb-space-1)}.cb-table__th{position:relative}.cb-table__th.cb-is-sortable:hover{background-color:var(--cb-color-surface-hover)}.cb-table__sort-btn{margin:0;padding:0;font:inherit;color:inherit;text-align:inherit;background:none;border:none;border-radius:var(--cb-radius-sm);cursor:pointer;-webkit-user-select:none;user-select:none}.cb-table__sort-btn:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:2px}.cb-table--resizable{table-layout:fixed}.cb-table--resizable .cb-table__th{overflow:hidden;text-overflow:ellipsis}.cb-table__resizer{position:absolute;top:0;right:0;width:.5rem;height:100%;cursor:col-resize;touch-action:none}.cb-table__resizer:after{content:\"\";position:absolute;top:25%;right:.2rem;width:2px;height:50%;background-color:var(--cb-color-border-strong);border-radius:1px}.cb-table__resizer:hover:after,.cb-table__resizer:focus-visible:after{background-color:var(--cb-color-primary-500)}.cb-table__resizer:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:-2px}.cb-table__filter-row td{padding:var(--cb-space-2) var(--cb-space-4);background-color:var(--cb-color-surface-subtle);border-bottom:var(--cb-border-width) solid var(--cb-color-border)}.cb-table__filter{box-sizing:border-box;width:100%;min-width:6rem;padding:var(--cb-space-1) var(--cb-space-2);font:inherit;font-size:var(--cb-text-sm);color:var(--cb-color-text);background-color:var(--cb-color-surface-0);border:var(--cb-border-width) solid var(--cb-color-border-strong);border-radius:var(--cb-radius-sm)}.cb-table__filter:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:1px}.cb-table__expander{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;padding:0;color:var(--cb-color-text-muted);background:none;border:none;border-radius:var(--cb-radius-sm);cursor:pointer}.cb-table__expander:hover{background-color:var(--cb-color-surface-hover)}.cb-table__expander:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:1px}.cb-table__expansion>td{padding:var(--cb-space-4);background-color:var(--cb-color-surface-subtle);border-bottom:var(--cb-border-width) solid var(--cb-color-border)}.cb-table__sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.cb-table__sort{color:var(--cb-color-text-muted)}.cb-table tbody tr:last-child .cb-table__td,.cb-table tbody tr:last-child .cb-table__sel{border-bottom:none}.cb-table--striped tbody tr:nth-child(2n){background-color:var(--cb-color-surface-subtle)}.cb-table--hover tbody .cb-table__row:hover{background-color:var(--cb-color-surface-hover)}.cb-table__row.cb-is-selectable{cursor:pointer}.cb-table__row.cb-is-selected{background-color:var(--cb-color-primary-50)!important}.cb-table__sel{width:1px;white-space:nowrap}.cb-table__check{display:inline-flex;align-items:center;justify-content:center;width:1.1rem;height:1.1rem;border:var(--cb-border-width) solid var(--cb-color-border-strong);border-radius:var(--cb-radius-sm);color:var(--cb-color-primary-contrast);outline:none}.cb-table__check:focus-visible{box-shadow:0 0 0 3px var(--cb-color-focus-ring)}.cb-table__check.cb-is-checked,.cb-table__check.cb-is-mixed{background-color:var(--cb-color-primary-500);border-color:var(--cb-color-primary-500)}.cb-table__check--radio{border-radius:50%}.cb-table__empty{padding:var(--cb-space-6);text-align:center;color:var(--cb-color-text-muted)}.cb-table__paginator{margin-top:var(--cb-space-3)}:host-context([data-theme=\"dark\"]) .cb-table__row.cb-is-selected{background-color:color-mix(in srgb,var(--cb-color-primary-500) 20%,transparent)!important}.cb-table__wrap{position:relative}.cb-table__wrap--scroll{overflow:auto}.cb-table--scroll thead{position:sticky;top:0;z-index:2}.cb-is-frozen{position:sticky;z-index:1;background-color:var(--cb-color-surface-raised)}thead .cb-is-frozen{z-index:3;background-color:var(--cb-color-surface-subtle)}.cb-table--striped tbody tr:nth-child(2n) .cb-is-frozen{background-color:var(--cb-color-surface-subtle)}.cb-table--hover tbody .cb-table__row:hover .cb-is-frozen{background-color:var(--cb-color-surface-hover)}.cb-is-frozen-last{box-shadow:4px 0 6px -4px #00000040}.cb-table__group>th{padding:var(--cb-space-2) var(--cb-space-4);font-size:var(--cb-text-sm);font-weight:var(--cb-font-weight-semibold);text-align:left;color:var(--cb-color-text-strong);background-color:var(--cb-color-surface-subtle);border-bottom:var(--cb-border-width) solid var(--cb-color-border)}.cb-table__group-count{font-weight:var(--cb-font-weight-normal, 400);color:var(--cb-color-text-muted)}.cb-table__loading{position:absolute;inset:0;z-index:4;display:flex;align-items:center;justify-content:center;color:var(--cb-color-primary-500);background-color:color-mix(in srgb,var(--cb-color-surface-raised) 65%,transparent)}\n"] }]
980
- }], ctorParameters: () => [], propDecorators: { cellTemplates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => CbTableCellDirective), { isSignal: true }] }], expansion: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CbTableRowExpansion), { isSignal: true }] }], groupHeader: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CbTableGroupHeader), { isSignal: true }] }], tableRef: [{ type: i0.ViewChild, args: ['table', { isSignal: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], paginator: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginator", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }, { type: i0.Output, args: ["rowsChange"] }], rowsPerPageOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowsPerPageOptions", required: false }] }], striped: [{ type: i0.Input, args: [{ isSignal: true, alias: "striped", required: false }] }], rowHover: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHover", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], dataKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataKey", required: false }] }], globalFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "globalFilter", required: false }] }, { type: i0.Output, args: ["globalFilterChange"] }], globalFilterFields: [{ type: i0.Input, args: [{ isSignal: true, alias: "globalFilterFields", required: false }] }], resizableColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizableColumns", required: false }] }], expandedRowKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedRowKeys", required: false }] }, { type: i0.Output, args: ["expandedRowKeysChange"] }], scrollHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollHeight", required: false }] }], groupRowsBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupRowsBy", required: false }] }], lazy: [{ type: i0.Input, args: [{ isSignal: true, alias: "lazy", required: false }] }], totalRecords: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalRecords", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], columnResize: [{ type: i0.Output, args: ["columnResize"] }], rowExpand: [{ type: i0.Output, args: ["rowExpand"] }], rowCollapse: [{ type: i0.Output, args: ["rowCollapse"] }], lazyLoad: [{ type: i0.Output, args: ["lazyLoad"] }] } });
1287
+ `, styles: [":host{display:block;font-family:var(--cb-font-sans);color:var(--cb-color-text)}.cb-table__wrap{overflow-x:auto;border:var(--cb-border-width) solid var(--cb-color-border);border-radius:var(--cb-radius-md)}.cb-table{width:100%;border-collapse:collapse;font-size:var(--cb-text-sm)}.cb-table__th,.cb-table__td,.cb-table__sel{padding:var(--cb-space-3) var(--cb-space-4);text-align:left;border-bottom:var(--cb-border-width) solid var(--cb-color-border);vertical-align:middle}.cb-table--sm .cb-table__th,.cb-table--sm .cb-table__td,.cb-table--sm .cb-table__sel{padding:var(--cb-space-2) var(--cb-space-3)}.cb-table--lg .cb-table__th,.cb-table--lg .cb-table__td,.cb-table--lg .cb-table__sel{padding:var(--cb-space-4) var(--cb-space-5)}.cb-table thead .cb-table__th,.cb-table thead .cb-table__sel{background-color:var(--cb-color-surface-subtle);color:var(--cb-color-text);font-weight:var(--cb-font-weight-semibold);white-space:nowrap;border-bottom-width:2px}.cb-table__th-inner{display:inline-flex;align-items:center;gap:var(--cb-space-1)}.cb-table__th{position:relative}.cb-table__th.cb-is-sortable:hover{background-color:var(--cb-color-surface-hover)}.cb-table__sort-btn{margin:0;padding:0;font:inherit;color:inherit;text-align:inherit;background:none;border:none;border-radius:var(--cb-radius-sm);cursor:pointer;-webkit-user-select:none;user-select:none}.cb-table__sort-btn:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:2px}.cb-table--resizable{table-layout:fixed}.cb-table--resizable .cb-table__th{overflow:hidden;text-overflow:ellipsis}.cb-table__resizer{position:absolute;top:0;right:0;width:.5rem;height:100%;cursor:col-resize;touch-action:none}.cb-table__resizer:after{content:\"\";position:absolute;top:25%;right:.2rem;width:2px;height:50%;background-color:var(--cb-color-border-strong);border-radius:1px}.cb-table__resizer:hover:after,.cb-table__resizer:focus-visible:after{background-color:var(--cb-color-primary-500)}.cb-table__resizer:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:-2px}.cb-table__filter-row td{padding:var(--cb-space-2) var(--cb-space-4);background-color:var(--cb-color-surface-subtle);border-bottom:var(--cb-border-width) solid var(--cb-color-border)}.cb-table__filter{box-sizing:border-box;width:100%;min-width:6rem;padding:var(--cb-space-1) var(--cb-space-2);font:inherit;font-size:var(--cb-text-sm);color:var(--cb-color-text);background-color:var(--cb-color-surface-0);border:var(--cb-border-width) solid var(--cb-color-border-strong);border-radius:var(--cb-radius-sm)}.cb-table__filter:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:1px}.cb-table__expander{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;padding:0;color:var(--cb-color-text-muted);background:none;border:none;border-radius:var(--cb-radius-sm);cursor:pointer}.cb-table__expander:hover{background-color:var(--cb-color-surface-hover)}.cb-table__expander:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:1px}.cb-table__expansion>td{padding:var(--cb-space-4);background-color:var(--cb-color-surface-subtle);border-bottom:var(--cb-border-width) solid var(--cb-color-border)}.cb-table__sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.cb-table__sort{color:var(--cb-color-text-muted)}.cb-table tbody tr:last-child .cb-table__td,.cb-table tbody tr:last-child .cb-table__sel{border-bottom:none}.cb-table--striped tbody tr:nth-child(2n){background-color:var(--cb-color-surface-subtle)}.cb-table--hover tbody .cb-table__row:hover{background-color:var(--cb-color-surface-hover)}.cb-table__row.cb-is-selectable{cursor:pointer}.cb-table__row.cb-is-selected{background-color:var(--cb-color-primary-50)!important}.cb-table__sel{width:1px;white-space:nowrap}.cb-table__check{display:inline-flex;align-items:center;justify-content:center;width:1.1rem;height:1.1rem;border:var(--cb-border-width) solid var(--cb-color-border-strong);border-radius:var(--cb-radius-sm);color:var(--cb-color-primary-contrast);outline:none}.cb-table__check:focus-visible{box-shadow:0 0 0 3px var(--cb-color-focus-ring)}.cb-table__check.cb-is-checked,.cb-table__check.cb-is-mixed{background-color:var(--cb-color-primary-500);border-color:var(--cb-color-primary-500)}.cb-table__check--radio{border-radius:50%}.cb-table__empty{padding:var(--cb-space-6);text-align:center;color:var(--cb-color-text-muted)}.cb-table__paginator{margin-top:var(--cb-space-3)}:host-context([data-theme=\"dark\"]) .cb-table__row.cb-is-selected{background-color:color-mix(in srgb,var(--cb-color-primary-500) 20%,transparent)!important}.cb-table__wrap{position:relative}.cb-table__wrap--scroll{overflow:auto}.cb-table__wrap--scroll:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:2px}.cb-table--scroll thead{position:sticky;top:0;z-index:2}.cb-is-frozen{position:sticky;z-index:1;background-color:var(--cb-color-surface-raised)}thead .cb-is-frozen{z-index:3;background-color:var(--cb-color-surface-subtle)}.cb-table--striped tbody tr:nth-child(2n) .cb-is-frozen{background-color:var(--cb-color-surface-subtle)}.cb-table--hover tbody .cb-table__row:hover .cb-is-frozen{background-color:var(--cb-color-surface-hover)}.cb-is-frozen-last{box-shadow:4px 0 6px -4px #00000040}.cb-table__group>th{padding:var(--cb-space-2) var(--cb-space-4);font-size:var(--cb-text-sm);font-weight:var(--cb-font-weight-semibold);text-align:left;color:var(--cb-color-text-strong);background-color:var(--cb-color-surface-subtle);border-bottom:var(--cb-border-width) solid var(--cb-color-border)}.cb-table__group-count{font-weight:var(--cb-font-weight-normal, 400);color:var(--cb-color-text-muted)}.cb-table__num{font-variant-numeric:tabular-nums;white-space:nowrap}.cb-table .cb-is-negative{color:var(--cb-color-danger-text, #dc2626)}.cb-table__subtotal>.cb-table__td{font-weight:var(--cb-font-weight-semibold);background-color:var(--cb-color-surface-subtle);border-bottom:var(--cb-border-width) solid var(--cb-color-border-strong)}.cb-table__foot>.cb-table__td,.cb-table__foot>.cb-table__sel{font-weight:var(--cb-font-weight-semibold);color:var(--cb-color-text-strong);background-color:var(--cb-color-surface-subtle);border-top:2px solid var(--cb-color-border-strong);border-bottom:0}.cb-table--scroll tfoot{position:sticky;bottom:0;z-index:2}tfoot .cb-is-frozen,.cb-table__subtotal .cb-is-frozen{background-color:var(--cb-color-surface-subtle)}.cb-table__loading{position:absolute;inset:0;z-index:4;display:flex;align-items:center;justify-content:center;color:var(--cb-color-primary-text);background-color:color-mix(in srgb,var(--cb-color-surface-raised) 65%,transparent)}\n"] }]
1288
+ }], ctorParameters: () => [], propDecorators: { cellTemplates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => CbTableCellDirective), { isSignal: true }] }], expansion: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CbTableRowExpansion), { isSignal: true }] }], groupHeader: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CbTableGroupHeader), { isSignal: true }] }], tableRef: [{ type: i0.ViewChild, args: ['table', { isSignal: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], paginator: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginator", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }, { type: i0.Output, args: ["rowsChange"] }], rowsPerPageOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowsPerPageOptions", required: false }] }], striped: [{ type: i0.Input, args: [{ isSignal: true, alias: "striped", required: false }] }], rowHover: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHover", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], dataKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataKey", required: false }] }], globalFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "globalFilter", required: false }] }, { type: i0.Output, args: ["globalFilterChange"] }], globalFilterFields: [{ type: i0.Input, args: [{ isSignal: true, alias: "globalFilterFields", required: false }] }], resizableColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizableColumns", required: false }] }], expandedRowKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedRowKeys", required: false }] }, { type: i0.Output, args: ["expandedRowKeysChange"] }], scrollHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollHeight", required: false }] }], groupRowsBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupRowsBy", required: false }] }], lazy: [{ type: i0.Input, args: [{ isSignal: true, alias: "lazy", required: false }] }], totalRecords: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalRecords", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], groupSubtotals: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupSubtotals", required: false }] }], currency: [{ type: i0.Input, args: [{ isSignal: true, alias: "currency", required: false }] }], negativeStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "negativeStyle", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], columnResize: [{ type: i0.Output, args: ["columnResize"] }], rowExpand: [{ type: i0.Output, args: ["rowExpand"] }], rowCollapse: [{ type: i0.Output, args: ["rowCollapse"] }], lazyLoad: [{ type: i0.Output, args: ["lazyLoad"] }] } });
981
1289
  function toBoolean(value) {
982
1290
  return value !== false && value != null && `${value}` !== 'false';
983
1291
  }
@@ -47,7 +47,7 @@ class CbTabMenu {
47
47
  }
48
48
  </ul>
49
49
  </nav>
50
- `, isInline: true, styles: [":host{display:block;color:var(--cb-color-text);font-family:var(--cb-font-sans)}.cb-tabmenu__list{display:flex;gap:.25rem;margin:0;padding:0;list-style:none;border-bottom:1px solid var(--cb-color-border)}.cb-tabmenu__link{display:flex;align-items:center;gap:.5rem;min-height:2.75rem;padding:.625rem .875rem;border:0;border-bottom:2px solid transparent;background:transparent;color:inherit;font:inherit;text-decoration:none;cursor:pointer}.cb-tabmenu__link:hover:not(:disabled),.cb-tabmenu__link:focus-visible{background:var(--cb-color-surface);outline:none}.cb-tabmenu__link[aria-current=page]{border-bottom-color:var(--cb-color-primary);color:var(--cb-color-primary);font-weight:600}.cb-tabmenu__link:disabled{opacity:.5;cursor:default}\n"], dependencies: [{ kind: "component", type: CbIcon, selector: "cb-icon", inputs: ["name", "size", "spin", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
50
+ `, isInline: true, styles: [":host{display:block;min-width:0;color:var(--cb-color-text);font-family:var(--cb-font-sans)}.cb-tabmenu__list{display:flex;gap:.25rem;margin:0;padding:0;overflow-x:auto;scrollbar-width:thin;list-style:none;border-bottom:1px solid var(--cb-color-border)}.cb-tabmenu__entry{flex:none}.cb-tabmenu__link{display:flex;align-items:center;gap:.5rem;min-height:2.75rem;white-space:nowrap;padding:.625rem .875rem;border:0;border-bottom:2px solid transparent;background:transparent;color:inherit;font:inherit;text-decoration:none;cursor:pointer}.cb-tabmenu__link:hover:not(:disabled),.cb-tabmenu__link:focus-visible{background:var(--cb-color-surface);outline:none}.cb-tabmenu__link[aria-current=page]{border-bottom-color:var(--cb-color-primary);color:var(--cb-color-primary-text);font-weight:600}.cb-tabmenu__link:disabled{opacity:.5;cursor:default}\n"], dependencies: [{ kind: "component", type: CbIcon, selector: "cb-icon", inputs: ["name", "size", "spin", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
51
51
  }
52
52
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CbTabMenu, decorators: [{
53
53
  type: Component,
@@ -71,7 +71,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
71
71
  }
72
72
  </ul>
73
73
  </nav>
74
- `, styles: [":host{display:block;color:var(--cb-color-text);font-family:var(--cb-font-sans)}.cb-tabmenu__list{display:flex;gap:.25rem;margin:0;padding:0;list-style:none;border-bottom:1px solid var(--cb-color-border)}.cb-tabmenu__link{display:flex;align-items:center;gap:.5rem;min-height:2.75rem;padding:.625rem .875rem;border:0;border-bottom:2px solid transparent;background:transparent;color:inherit;font:inherit;text-decoration:none;cursor:pointer}.cb-tabmenu__link:hover:not(:disabled),.cb-tabmenu__link:focus-visible{background:var(--cb-color-surface);outline:none}.cb-tabmenu__link[aria-current=page]{border-bottom-color:var(--cb-color-primary);color:var(--cb-color-primary);font-weight:600}.cb-tabmenu__link:disabled{opacity:.5;cursor:default}\n"] }]
74
+ `, styles: [":host{display:block;min-width:0;color:var(--cb-color-text);font-family:var(--cb-font-sans)}.cb-tabmenu__list{display:flex;gap:.25rem;margin:0;padding:0;overflow-x:auto;scrollbar-width:thin;list-style:none;border-bottom:1px solid var(--cb-color-border)}.cb-tabmenu__entry{flex:none}.cb-tabmenu__link{display:flex;align-items:center;gap:.5rem;min-height:2.75rem;white-space:nowrap;padding:.625rem .875rem;border:0;border-bottom:2px solid transparent;background:transparent;color:inherit;font:inherit;text-decoration:none;cursor:pointer}.cb-tabmenu__link:hover:not(:disabled),.cb-tabmenu__link:focus-visible{background:var(--cb-color-surface);outline:none}.cb-tabmenu__link[aria-current=page]{border-bottom-color:var(--cb-color-primary);color:var(--cb-color-primary-text);font-weight:600}.cb-tabmenu__link:disabled{opacity:.5;cursor:default}\n"] }]
75
75
  }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], activeIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIndex", required: false }] }, { type: i0.Output, args: ["activeIndexChange"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], itemSelect: [{ type: i0.Output, args: ["itemSelect"] }] } });
76
76
 
77
77
  /**
@@ -82,7 +82,7 @@ class CbTabs {
82
82
  <div class="cb-tabs__panels">
83
83
  <ng-content />
84
84
  </div>
85
- `, isInline: true, styles: [":host{display:block;font-family:var(--cb-font-sans);color:var(--cb-color-text)}.cb-tabs__list{display:flex;gap:var(--cb-space-1);border-bottom:var(--cb-border-width) solid var(--cb-color-border);overflow-x:auto}.cb-tabs__tab{position:relative;padding:var(--cb-space-3) var(--cb-space-4);border:none;background:transparent;color:var(--cb-color-text-muted);font:inherit;font-weight:var(--cb-font-weight-medium);white-space:nowrap;cursor:pointer;transition:color var(--cb-duration-fast) var(--cb-ease)}.cb-tabs__tab:after{content:\"\";position:absolute;left:var(--cb-space-3);right:var(--cb-space-3);bottom:-1px;height:2px;border-radius:2px;background-color:transparent;transition:background-color var(--cb-duration-fast) var(--cb-ease)}.cb-tabs__tab:hover{color:var(--cb-color-text)}.cb-tabs__tab.cb-is-active{color:var(--cb-color-primary-500)}.cb-tabs__tab.cb-is-active:after{background-color:var(--cb-color-primary-500)}.cb-tabs__tab:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:-2px;border-radius:var(--cb-radius-sm)}.cb-tabs__tab:disabled{opacity:var(--cb-opacity-disabled, .55);cursor:default}.cb-tabs__panels{padding:var(--cb-space-4) 0;font-size:var(--cb-text-sm);line-height:var(--cb-line-height-normal)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
85
+ `, isInline: true, styles: [":host{display:block;font-family:var(--cb-font-sans);color:var(--cb-color-text)}.cb-tabs__list{display:flex;gap:var(--cb-space-1);border-bottom:var(--cb-border-width) solid var(--cb-color-border);overflow-x:auto}.cb-tabs__tab{position:relative;padding:var(--cb-space-3) var(--cb-space-4);border:none;background:transparent;color:var(--cb-color-text-muted);font:inherit;font-weight:var(--cb-font-weight-medium);white-space:nowrap;cursor:pointer;transition:color var(--cb-duration-fast) var(--cb-ease)}.cb-tabs__tab:after{content:\"\";position:absolute;left:var(--cb-space-3);right:var(--cb-space-3);bottom:-1px;height:2px;border-radius:2px;background-color:transparent;transition:background-color var(--cb-duration-fast) var(--cb-ease)}.cb-tabs__tab:hover{color:var(--cb-color-text)}.cb-tabs__tab.cb-is-active{color:var(--cb-color-primary-text)}.cb-tabs__tab.cb-is-active:after{background-color:var(--cb-color-primary-500)}.cb-tabs__tab:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:-2px;border-radius:var(--cb-radius-sm)}.cb-tabs__tab:disabled{opacity:var(--cb-opacity-disabled, .55);cursor:default}.cb-tabs__panels{padding:var(--cb-space-4) 0;font-size:var(--cb-text-sm);line-height:var(--cb-line-height-normal)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
86
86
  }
87
87
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CbTabs, decorators: [{
88
88
  type: Component,
@@ -109,7 +109,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
109
109
  <div class="cb-tabs__panels">
110
110
  <ng-content />
111
111
  </div>
112
- `, styles: [":host{display:block;font-family:var(--cb-font-sans);color:var(--cb-color-text)}.cb-tabs__list{display:flex;gap:var(--cb-space-1);border-bottom:var(--cb-border-width) solid var(--cb-color-border);overflow-x:auto}.cb-tabs__tab{position:relative;padding:var(--cb-space-3) var(--cb-space-4);border:none;background:transparent;color:var(--cb-color-text-muted);font:inherit;font-weight:var(--cb-font-weight-medium);white-space:nowrap;cursor:pointer;transition:color var(--cb-duration-fast) var(--cb-ease)}.cb-tabs__tab:after{content:\"\";position:absolute;left:var(--cb-space-3);right:var(--cb-space-3);bottom:-1px;height:2px;border-radius:2px;background-color:transparent;transition:background-color var(--cb-duration-fast) var(--cb-ease)}.cb-tabs__tab:hover{color:var(--cb-color-text)}.cb-tabs__tab.cb-is-active{color:var(--cb-color-primary-500)}.cb-tabs__tab.cb-is-active:after{background-color:var(--cb-color-primary-500)}.cb-tabs__tab:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:-2px;border-radius:var(--cb-radius-sm)}.cb-tabs__tab:disabled{opacity:var(--cb-opacity-disabled, .55);cursor:default}.cb-tabs__panels{padding:var(--cb-space-4) 0;font-size:var(--cb-text-sm);line-height:var(--cb-line-height-normal)}\n"] }]
112
+ `, styles: [":host{display:block;font-family:var(--cb-font-sans);color:var(--cb-color-text)}.cb-tabs__list{display:flex;gap:var(--cb-space-1);border-bottom:var(--cb-border-width) solid var(--cb-color-border);overflow-x:auto}.cb-tabs__tab{position:relative;padding:var(--cb-space-3) var(--cb-space-4);border:none;background:transparent;color:var(--cb-color-text-muted);font:inherit;font-weight:var(--cb-font-weight-medium);white-space:nowrap;cursor:pointer;transition:color var(--cb-duration-fast) var(--cb-ease)}.cb-tabs__tab:after{content:\"\";position:absolute;left:var(--cb-space-3);right:var(--cb-space-3);bottom:-1px;height:2px;border-radius:2px;background-color:transparent;transition:background-color var(--cb-duration-fast) var(--cb-ease)}.cb-tabs__tab:hover{color:var(--cb-color-text)}.cb-tabs__tab.cb-is-active{color:var(--cb-color-primary-text)}.cb-tabs__tab.cb-is-active:after{background-color:var(--cb-color-primary-500)}.cb-tabs__tab:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:-2px;border-radius:var(--cb-radius-sm)}.cb-tabs__tab:disabled{opacity:var(--cb-opacity-disabled, .55);cursor:default}.cb-tabs__panels{padding:var(--cb-space-4) 0;font-size:var(--cb-text-sm);line-height:var(--cb-line-height-normal)}\n"] }]
113
113
  }], propDecorators: { tabs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => CbTab), { isSignal: true }] }] } });
114
114
  /** Pestaña individual de un `<cb-tabs>`. */
115
115
  class CbTab {