@caribeng/ui 22.2.0 → 22.4.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 (121) hide show
  1. package/README.md +93 -11
  2. package/fesm2022/caribeng-ui-accordion.mjs +2 -2
  3. package/fesm2022/caribeng-ui-avatar.mjs +2 -2
  4. package/fesm2022/caribeng-ui-badge.mjs +8 -2
  5. package/fesm2022/caribeng-ui-breadcrumb.mjs +13 -6
  6. package/fesm2022/caribeng-ui-chart.mjs +8 -5
  7. package/fesm2022/caribeng-ui-chat.mjs +1303 -0
  8. package/fesm2022/caribeng-ui-code-block.mjs +332 -0
  9. package/fesm2022/caribeng-ui-colorpicker.mjs +99 -5
  10. package/fesm2022/caribeng-ui-command-palette.mjs +476 -0
  11. package/fesm2022/caribeng-ui-confirmdialog.mjs +78 -13
  12. package/fesm2022/caribeng-ui-confirmpopup.mjs +91 -16
  13. package/fesm2022/caribeng-ui-contextmenu.mjs +8 -4
  14. package/fesm2022/caribeng-ui-copy-button.mjs +230 -0
  15. package/fesm2022/caribeng-ui-dataview.mjs +4 -1
  16. package/fesm2022/caribeng-ui-dock.mjs +52 -12
  17. package/fesm2022/caribeng-ui-drawer.mjs +9 -4
  18. package/fesm2022/caribeng-ui-editor.mjs +21 -0
  19. package/fesm2022/caribeng-ui-fieldset.mjs +2 -2
  20. package/fesm2022/caribeng-ui-file-card.mjs +134 -17
  21. package/fesm2022/caribeng-ui-folder-card.mjs +122 -12
  22. package/fesm2022/caribeng-ui-inlinemessage.mjs +2 -2
  23. package/fesm2022/caribeng-ui-inputmask.mjs +8 -2
  24. package/fesm2022/caribeng-ui-kanban.mjs +4612 -0
  25. package/fesm2022/caribeng-ui-kbd.mjs +122 -0
  26. package/fesm2022/caribeng-ui-megamenu.mjs +13 -9
  27. package/fesm2022/caribeng-ui-mentions.mjs +495 -0
  28. package/fesm2022/caribeng-ui-menu.mjs +8 -4
  29. package/fesm2022/caribeng-ui-menubar.mjs +9 -5
  30. package/fesm2022/caribeng-ui-message.mjs +6 -3
  31. package/fesm2022/caribeng-ui-organizationchart.mjs +6 -10
  32. package/fesm2022/caribeng-ui-panel.mjs +6 -6
  33. package/fesm2022/caribeng-ui-panelmenu.mjs +9 -6
  34. package/fesm2022/caribeng-ui-phone-input.mjs +688 -0
  35. package/fesm2022/caribeng-ui-pricing.mjs +263 -69
  36. package/fesm2022/caribeng-ui-qrcode.mjs +564 -0
  37. package/fesm2022/caribeng-ui-ripple.mjs +2 -0
  38. package/fesm2022/caribeng-ui-scrolltop.mjs +3 -1
  39. package/fesm2022/caribeng-ui-sidebar.mjs +573 -0
  40. package/fesm2022/caribeng-ui-stepper.mjs +10 -3
  41. package/fesm2022/caribeng-ui-table.mjs +10 -4
  42. package/fesm2022/caribeng-ui-tabmenu.mjs +8 -4
  43. package/fesm2022/caribeng-ui-tieredmenu.mjs +109 -19
  44. package/fesm2022/caribeng-ui.mjs +388 -1
  45. package/package.json +42 -2
  46. package/schematics/collection.json +5 -0
  47. package/schematics/migrate-from-primeng/core-icons.json +1 -0
  48. package/schematics/migrate-from-primeng/icons.js +269 -0
  49. package/schematics/migrate-from-primeng/index.js +290 -0
  50. package/schematics/migrate-from-primeng/mappings/button.js +93 -0
  51. package/schematics/migrate-from-primeng/mappings/card.js +33 -0
  52. package/schematics/migrate-from-primeng/mappings/checkbox.js +44 -0
  53. package/schematics/migrate-from-primeng/mappings/confirm.js +221 -0
  54. package/schematics/migrate-from-primeng/mappings/datepicker.js +121 -0
  55. package/schematics/migrate-from-primeng/mappings/dialog.js +84 -0
  56. package/schematics/migrate-from-primeng/mappings/index.js +88 -0
  57. package/schematics/migrate-from-primeng/mappings/inputnumber.js +62 -0
  58. package/schematics/migrate-from-primeng/mappings/inputtext.js +60 -0
  59. package/schematics/migrate-from-primeng/mappings/menu.js +468 -0
  60. package/schematics/migrate-from-primeng/mappings/multiselect.js +49 -0
  61. package/schematics/migrate-from-primeng/mappings/radiobutton.js +22 -0
  62. package/schematics/migrate-from-primeng/mappings/rules.js +206 -0
  63. package/schematics/migrate-from-primeng/mappings/select.js +97 -0
  64. package/schematics/migrate-from-primeng/mappings/service-calls.js +100 -0
  65. package/schematics/migrate-from-primeng/mappings/table.js +613 -0
  66. package/schematics/migrate-from-primeng/mappings/tabs.js +225 -0
  67. package/schematics/migrate-from-primeng/mappings/tag.js +29 -0
  68. package/schematics/migrate-from-primeng/mappings/textarea.js +44 -0
  69. package/schematics/migrate-from-primeng/mappings/toast.js +173 -0
  70. package/schematics/migrate-from-primeng/mappings/toggleswitch.js +37 -0
  71. package/schematics/migrate-from-primeng/mappings/tooltip.js +44 -0
  72. package/schematics/migrate-from-primeng/mappings/types.js +10 -0
  73. package/schematics/migrate-from-primeng/report.js +79 -0
  74. package/schematics/migrate-from-primeng/schema.js +2 -0
  75. package/schematics/migrate-from-primeng/schema.json +34 -0
  76. package/schematics/migrate-from-primeng/template.js +387 -0
  77. package/schematics/migrate-from-primeng/todo.js +5 -0
  78. package/schematics/migrate-from-primeng/typescript.js +442 -0
  79. package/schematics/migrate-from-primeng/workspace.js +117 -0
  80. package/schematics/ng-add/index.js +16 -1
  81. package/types/caribeng-ui-badge.d.ts +3 -1
  82. package/types/caribeng-ui-breadcrumb.d.ts +8 -0
  83. package/types/caribeng-ui-chart.d.ts +3 -1
  84. package/types/caribeng-ui-chat.d.ts +299 -0
  85. package/types/caribeng-ui-code-block.d.ts +65 -0
  86. package/types/caribeng-ui-colorpicker.d.ts +5 -1
  87. package/types/caribeng-ui-command-palette.d.ts +133 -0
  88. package/types/caribeng-ui-confirmdialog.d.ts +34 -2
  89. package/types/caribeng-ui-confirmpopup.d.ts +39 -2
  90. package/types/caribeng-ui-contextmenu.d.ts +7 -0
  91. package/types/caribeng-ui-copy-button.d.ts +90 -0
  92. package/types/caribeng-ui-dataview.d.ts +2 -0
  93. package/types/caribeng-ui-dock.d.ts +13 -1
  94. package/types/caribeng-ui-drawer.d.ts +3 -1
  95. package/types/caribeng-ui-file-card.d.ts +27 -2
  96. package/types/caribeng-ui-folder-card.d.ts +27 -5
  97. package/types/caribeng-ui-inputmask.d.ts +3 -1
  98. package/types/caribeng-ui-kanban.d.ts +783 -0
  99. package/types/caribeng-ui-kbd.d.ts +36 -0
  100. package/types/caribeng-ui-megamenu.d.ts +11 -0
  101. package/types/caribeng-ui-mentions.d.ts +127 -0
  102. package/types/caribeng-ui-menu.d.ts +7 -0
  103. package/types/caribeng-ui-menubar.d.ts +7 -0
  104. package/types/caribeng-ui-message.d.ts +2 -0
  105. package/types/caribeng-ui-panelmenu.d.ts +7 -0
  106. package/types/caribeng-ui-phone-input.d.ts +168 -0
  107. package/types/caribeng-ui-pricing.d.ts +41 -4
  108. package/types/caribeng-ui-qrcode.d.ts +88 -0
  109. package/types/caribeng-ui-sidebar.d.ts +167 -0
  110. package/types/caribeng-ui-stepper.d.ts +2 -0
  111. package/types/caribeng-ui-table.d.ts +1 -1
  112. package/types/caribeng-ui-tabmenu.d.ts +7 -0
  113. package/types/caribeng-ui-tieredmenu.d.ts +17 -1
  114. package/types/caribeng-ui.d.ts +276 -2
  115. package/styles/caribeng.css +0 -380
  116. package/styles/scss/_mixins.scss +0 -46
  117. package/styles/scss/_overlay.scss +0 -15
  118. package/styles/scss/_tokens.scss +0 -267
  119. package/styles/scss/_utilities.scss +0 -73
  120. package/styles/scss/_variables.scss +0 -33
  121. package/styles/scss/index.scss +0 -16
@@ -0,0 +1,613 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.table = void 0;
37
+ const ts = __importStar(require("typescript"));
38
+ const todo_1 = require("../todo");
39
+ const rules_1 = require("./rules");
40
+ const service_calls_1 = require("./service-calls");
41
+ /** Plantillas de p-table que se trasladan; con cualquier otra la tabla se deja para migrar a mano. */
42
+ const KNOWN_TEMPLATES = new Set(['header', 'body', 'emptymessage', 'rowexpansion', 'caption', 'summary', 'loadingbody']);
43
+ const NO_INITIAL_SORT = 'cb-table empieza sin orden; el usuario ordena desde la cabecera.';
44
+ const NO_PAGINATOR_OPTION = 'cb-table usa su propio paginador.';
45
+ /** Atributos de `<p-table>` → `<cb-table>`. */
46
+ const TABLE_RULES = {
47
+ rows: (0, rules_1.numeric)(),
48
+ totalRecords: (0, rules_1.numeric)(),
49
+ stripedRows: (0, rules_1.rename)('striped'),
50
+ size: (0, rules_1.values)('size', rules_1.SIZE_VALUES),
51
+ styleClass: (0, rules_1.styleClass)(),
52
+ // Las columnas se generan a partir de las plantillas.
53
+ columns: (0, rules_1.drop)(),
54
+ scrollable: (0, rules_1.drop)(),
55
+ responsiveLayout: (0, rules_1.drop)(),
56
+ breakpoint: (0, rules_1.drop)(),
57
+ rowTrackBy: (0, rules_1.drop)(),
58
+ lazyLoadOnInit: (0, rules_1.drop)(),
59
+ loadingIcon: (0, rules_1.drop)(),
60
+ showLoader: (0, rules_1.drop)(),
61
+ metaKeySelection: (0, rules_1.drop)(),
62
+ compareSelectionBy: (0, rules_1.drop)(),
63
+ filterDelay: (0, rules_1.drop)(),
64
+ filterLocale: (0, rules_1.drop)(),
65
+ groupRowsByOrder: (0, rules_1.drop)(),
66
+ rowGroupMode: (binding, el) => {
67
+ if (!(binding.kind === 'static' && binding.value === 'subheader'))
68
+ el.todos.push(`${binding.source} — cb-table agrupa con cabeceras de grupo (groupRowsBy).`);
69
+ },
70
+ pageLinks: (0, rules_1.drop)(),
71
+ alwaysShowPaginator: (0, rules_1.drop)(),
72
+ paginatorPosition: (0, rules_1.unsupported)(NO_PAGINATOR_OPTION),
73
+ paginatorStyleClass: (0, rules_1.drop)(),
74
+ paginatorDropdownAppendTo: (0, rules_1.drop)(),
75
+ paginatorDropdownScrollHeight: (0, rules_1.drop)(),
76
+ paginatorLocale: (0, rules_1.drop)(),
77
+ currentPageReportTemplate: (0, rules_1.unsupported)(NO_PAGINATOR_OPTION),
78
+ showCurrentPageReport: (0, rules_1.drop)(),
79
+ showJumpToPageDropdown: (0, rules_1.drop)(),
80
+ showJumpToPageInput: (0, rules_1.drop)(),
81
+ showFirstLastIcon: (0, rules_1.drop)(),
82
+ showPageLinks: (0, rules_1.drop)(),
83
+ first: (0, rules_1.unsupported)('cb-table empieza en la primera página.'),
84
+ tableStyle: (0, rules_1.unsupported)('ajusta el ancho mínimo con CSS sobre cb-table.'),
85
+ tableStyleClass: (0, rules_1.unsupported)('aplica las clases a cb-table.'),
86
+ style: (0, rules_1.unsupported)('personaliza la tabla con los tokens CSS de CaribeNG.'),
87
+ showGridlines: (0, rules_1.unsupported)('cb-table no tiene modo con todas las líneas; usa striped o tokens CSS.'),
88
+ sortField: (0, rules_1.unsupported)(NO_INITIAL_SORT),
89
+ sortOrder: (0, rules_1.unsupported)(NO_INITIAL_SORT),
90
+ defaultSortOrder: (0, rules_1.unsupported)(NO_INITIAL_SORT),
91
+ sortMode: (0, rules_1.unsupported)('cb-table ordena por una columna a la vez.'),
92
+ multiSortMeta: (0, rules_1.unsupported)('cb-table ordena por una columna a la vez.'),
93
+ resetPageOnSort: (0, rules_1.drop)(),
94
+ customSort: (0, rules_1.unsupported)('cb-table ordena por el valor de la columna.'),
95
+ expandedRowKeys: (0, rules_1.unsupported)('cb-table usa un array de claves en [(expandedRowKeys)], no un objeto { clave: true }.'),
96
+ rowExpandMode: (0, rules_1.unsupported)('cb-table permite varias filas expandidas.'),
97
+ editMode: (0, rules_1.unsupported)('cb-table no tiene edición en celda; usa controles en un cbTableCell.'),
98
+ editingRowKeys: (0, rules_1.unsupported)('cb-table no tiene edición en celda.'),
99
+ virtualScroll: (0, rules_1.unsupported)('cb-table pagina o usa scrollHeight; no tiene scroll virtual.'),
100
+ virtualScrollItemSize: (0, rules_1.unsupported)('cb-table no tiene scroll virtual.'),
101
+ virtualScrollOptions: (0, rules_1.unsupported)('cb-table no tiene scroll virtual.'),
102
+ frozenColumns: (0, rules_1.unsupported)('marca las columnas con frozen: true.'),
103
+ frozenValue: (0, rules_1.unsupported)('cb-table no tiene filas fijas.'),
104
+ contextMenu: (0, rules_1.unsupported)('cb-table no tiene menú contextual de fila; envuélvela en un <cb-contextmenu>.'),
105
+ contextMenuSelection: (0, rules_1.unsupported)('cb-table no tiene menú contextual de fila.'),
106
+ reorderableColumns: (0, rules_1.unsupported)('cb-table no permite reordenar columnas.'),
107
+ csvSeparator: (0, rules_1.unsupported)('pásalo en exportCSV(nombre, { separator }).'),
108
+ exportFilename: (0, rules_1.unsupported)('pásalo en exportCSV(nombre).'),
109
+ exportHeader: (0, rules_1.unsupported)('cb-table exporta el header de cada columna.'),
110
+ exportFunction: (0, rules_1.unsupported)('cb-table exporta el valor de cada columna.'),
111
+ filters: (0, rules_1.unsupported)('cb-table filtra por columna con filter: true.'),
112
+ stateKey: (0, rules_1.unsupported)('cb-table no guarda su estado.'),
113
+ stateStorage: (0, rules_1.unsupported)('cb-table no guarda su estado.'),
114
+ rowSelectable: (0, rules_1.unsupported)('cb-table permite seleccionar todas las filas.'),
115
+ selectionPageOnly: (0, rules_1.unsupported)('cb-table selecciona sobre todos los datos.'),
116
+ '(onSort)': (0, rules_1.event)('sortChange'),
117
+ '(onLazyLoad)': (0, rules_1.event)('lazyLoad', () => null),
118
+ '(onRowExpand)': (0, rules_1.event)('rowExpand', (0, rules_1.adaptEvent)('data')),
119
+ '(onRowCollapse)': (0, rules_1.event)('rowCollapse', (0, rules_1.adaptEvent)('data')),
120
+ '(onRowSelect)': (0, rules_1.unsupported)('escucha (selectionChange).'),
121
+ '(onRowUnselect)': (0, rules_1.unsupported)('escucha (selectionChange).'),
122
+ '(onFilter)': (0, rules_1.unsupported)('escucha (filterChange) (recibe { global, columns }).'),
123
+ '(onPage)': (0, rules_1.unsupported)('escucha (rowsChange) o usa lazy + (lazyLoad).'),
124
+ '(firstChange)': (0, rules_1.unsupported)('cb-table no expone la primera fila visible.'),
125
+ '(onColResize)': (0, rules_1.unsupported)('escucha (columnResize) (recibe { field, width }).'),
126
+ '(onContextMenuSelect)': (0, rules_1.unsupported)('cb-table no tiene menú contextual de fila.'),
127
+ '(onEditInit)': (0, rules_1.unsupported)('cb-table no tiene edición en celda.'),
128
+ '(onEditComplete)': (0, rules_1.unsupported)('cb-table no tiene edición en celda.'),
129
+ '(onEditCancel)': (0, rules_1.unsupported)('cb-table no tiene edición en celda.'),
130
+ '(sortFunction)': (0, rules_1.unsupported)('cb-table ordena por el valor de la columna.'),
131
+ };
132
+ /** Hijos que cuentan (sin el espacio en blanco). */
133
+ function significant(node) {
134
+ return node.children.filter((child) => child.kind !== 'text' || child.inner.trim() !== '');
135
+ }
136
+ /** Nombre de la plantilla: `#header` o `pTemplate="header"`. */
137
+ function templateName(node) {
138
+ if (node.name !== 'ng-template')
139
+ return undefined;
140
+ return node.attrs.find((a) => /^#/.test(a.name))?.name.slice(1) ?? node.bindings.find((b) => b.kind === 'static' && b.name === 'pTemplate')?.value;
141
+ }
142
+ /** `let-producto` → `producto` (la variable de la fila). */
143
+ function rowVariable(template) {
144
+ return template.attrs.find((a) => a.name.startsWith('let-') && (a.value === '' || a.value === '$implicit'))?.name.slice(4);
145
+ }
146
+ /** Otras variables de la plantilla (`let-i="rowIndex"`, `let-expanded="expanded"`). */
147
+ function otherVariables(template) {
148
+ return template.attrs.filter((a) => a.name.startsWith('let-') && a.value !== '' && a.value !== '$implicit').map((a) => a.name.slice(4));
149
+ }
150
+ /** El único `<tr>` de una plantilla, o `null`. */
151
+ function singleRow(template) {
152
+ const rows = significant(template);
153
+ return rows.length === 1 && rows[0].name === 'tr' ? rows[0] : null;
154
+ }
155
+ /** `'texto'` con comillas escapadas para un literal dentro de un atributo con comillas dobles. */
156
+ function quote(text) {
157
+ return `'${text.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/"/g, '&quot;')}'`;
158
+ }
159
+ /** Texto con interpolaciones → expresión: `Total ({{ n }})` → `'Total (' + (n) + ')'`. */
160
+ function textExpression(text) {
161
+ const parts = [];
162
+ let last = 0;
163
+ for (const match of text.matchAll(/\{\{([\s\S]*?)\}\}/g)) {
164
+ if (match.index > last)
165
+ parts.push(quote(text.slice(last, match.index)));
166
+ parts.push(`(${match[1].trim()})`);
167
+ last = match.index + match[0].length;
168
+ }
169
+ if (last < text.length)
170
+ parts.push(quote(text.slice(last)));
171
+ return parts.join(' + ') || "''";
172
+ }
173
+ const SORT_ICON = /<p-sort-?[Ii]con\b[^>]*?(?:\/>|>\s*<\/p-sort-?[Ii]con>)/g;
174
+ const COLUMN_FILTER = /<p-column-?[Ff]ilter\b([^>]*?)(?:\/>|>[\s\S]*?<\/p-column-?[Ff]ilter>)/g;
175
+ function columnLiteral(col) {
176
+ const props = [`field: ${quote(col.field)}`, `header: ${col.header}`];
177
+ if (col.sortable)
178
+ props.push('sortable: true');
179
+ if (col.filter)
180
+ props.push('filter: true');
181
+ if (col.matchMode)
182
+ props.push(`filterMatchMode: ${quote(col.matchMode)}`);
183
+ if (col.width)
184
+ props.push(`width: ${quote(col.width)}`);
185
+ if (col.frozen)
186
+ props.push('frozen: true');
187
+ return `{ ${props.join(', ')} }`;
188
+ }
189
+ function isFrozen(node) {
190
+ return node.bindings.some((b) => b.name === 'pFrozenColumn' && (b.kind === 'static' || b.value.trim() === 'true'));
191
+ }
192
+ /** Contenido de `<tr><td …>contenido</td></tr>` (filas de mensaje vacío y de expansión). */
193
+ function singleCellContent(template) {
194
+ const row = singleRow(template);
195
+ const cells = row ? significant(row) : [];
196
+ return cells.length === 1 && cells[0].name === 'td' ? cells[0].inner.trim() : null;
197
+ }
198
+ /** Quita la sangría común de las líneas (la primera ya viene sin espacios al inicio). */
199
+ function dedent(content) {
200
+ const lines = content.split(/\r?\n/);
201
+ const rest = lines.slice(1).filter((line) => line.trim());
202
+ if (!rest.length)
203
+ return content;
204
+ const common = Math.min(...rest.map((line) => /^[ \t]*/.exec(line)[0].length));
205
+ return [lines[0], ...lines.slice(1).map((line) => line.slice(Math.min(common, /^[ \t]*/.exec(line)[0].length)))].join(content.includes('\r\n') ? '\r\n' : '\n');
206
+ }
207
+ function todoComment(message) {
208
+ return `<!-- ${todo_1.TODO_MARK}: ${message.replace(/--+/g, '-').replace(/\s+/g, ' ')} -->`;
209
+ }
210
+ /** Columna que cb-table pone sola: checkbox (selección múltiple), radio (simple) o botón de expandir. */
211
+ function specialColumn(cell) {
212
+ if (/<p-table(Header)?Checkbox\b/.test(cell.inner))
213
+ return 'multiple';
214
+ if (/<p-tableRadioButton\b/.test(cell.inner))
215
+ return 'single';
216
+ if (/\bpRowToggler\b/.test(cell.inner))
217
+ return 'toggler';
218
+ return null;
219
+ }
220
+ /** `@for (col of columns; …) { <th>…</th> }` o `<th *ngFor="let col of columns">`: variable, iterable y celda. */
221
+ function columnLoop(node, tag) {
222
+ if (node.kind === 'block' && node.name === 'for') {
223
+ const match = /^\s*([A-Za-z_$][\w$]*)\s+of\s+(.+?)\s*$/.exec(node.parameters[0] ?? '');
224
+ const cells = significant(node);
225
+ if (match && cells.length === 1 && cells[0].name === tag)
226
+ return { variable: match[1], iterable: match[2], cell: cells[0] };
227
+ return null;
228
+ }
229
+ const ngFor = node.name === tag ? node.attrs.find((a) => a.name === '*ngFor') : undefined;
230
+ const match = ngFor && /^\s*let\s+([A-Za-z_$][\w$]*)\s+of\s+([^;]+?)\s*(;|$)/.exec(ngFor.value);
231
+ return match ? { variable: match[1], iterable: match[2], cell: node } : null;
232
+ }
233
+ /** Escapa un nombre para usarlo en una expresión regular. */
234
+ function re(name) {
235
+ return name.replace(/[$.]/g, (c) => `\\${c}`);
236
+ }
237
+ /**
238
+ * Columnas dinámicas: `[columns]="cols"` + `@for (col of columns)` en cabecera y cuerpo →
239
+ * `<cb-table [columns]="cols">`. Las ramas `@if (col.field === 'precio')` / `@switch (col.field)`
240
+ * del cuerpo pasan a un `cbTableCell` por campo; el resto muestra `fila[col.field]`.
241
+ */
242
+ function dynamicColumns(node, r, header, body, templates, row, todos) {
243
+ // La lista de columnas: el [columns] de p-table (si los bucles recorren la variable let-columns) o la propiedad que recorren.
244
+ const columnsBinding = node.bindings.find((b) => b.name === 'columns' && b.kind === 'property')?.value.trim();
245
+ const templateVariables = new Set([...templates.header.attrs, ...templates.body.attrs].filter((a) => a.name.startsWith('let-')).map((a) => a.name.slice(4)));
246
+ const sourceOf = (iterable) => (templateVariables.has(iterable) ? columnsBinding : iterable);
247
+ const source = sourceOf(header.iterable);
248
+ if (!source || source !== sourceOf(body.iterable))
249
+ return 'la cabecera y el cuerpo no recorren la misma lista de columnas.';
250
+ // Cabecera: {{ col.header }}, con orden y filtro opcionales para todas las columnas.
251
+ const th = header.cell;
252
+ const col = header.variable;
253
+ let filter = false;
254
+ const headerText = th.inner.replace(SORT_ICON, '').replace(COLUMN_FILTER, () => ((filter = true), '')).trim();
255
+ if (!new RegExp(`^\\{\\{\\s*${re(col)}\\.header\\s*\\}\\}$`).test(headerText))
256
+ return 'la cabecera dinámica no es {{ col.header }}.';
257
+ const sortable = th.bindings.some((b) => b.name === 'pSortableColumn' && b.kind === 'property' && b.value.trim() === `${col}.field`);
258
+ if (sortable || filter) {
259
+ const flags = [sortable && 'sortable: true', filter && 'filter: true'].filter(Boolean).join(' y ');
260
+ todos.push(`en PrimeNG la cabecera hacía ordenables/filtrables todas las columnas: el migrador añade ${flags} a ${source} si es un array del componente; si las columnas vienen de otro sitio, añádelo tú.`);
261
+ }
262
+ // Cuerpo: fila[col.field], o ramas por campo.
263
+ const td = body.cell;
264
+ const c = body.variable;
265
+ const isDefault = (text) => text.trim() === '' || new RegExp(`^\\{\\{\\s*${re(row)}\\??\\.?\\[\\s*${re(c)}\\.field\\s*\\]\\s*\\}\\}$`).test(text.trim());
266
+ if (isDefault(td.inner))
267
+ return { columns: { source }, cells: [] };
268
+ const fieldOf = (condition) => new RegExp(`^\\s*${re(c)}\\.field\\s*===?\\s*'([^']+)'\\s*$`).exec(condition)?.[1] ?? new RegExp(`^\\s*'([^']+)'\\s*===?\\s*${re(c)}\\.field\\s*$`).exec(condition)?.[1];
269
+ const branches = [];
270
+ let fallback = '';
271
+ const blocks = significant(td);
272
+ if (blocks.length === 1 && blocks[0].kind === 'block' && blocks[0].name === 'switch' && blocks[0].parameters[0]?.trim() === `${c}.field`) {
273
+ for (const option of significant(blocks[0])) {
274
+ const field = option.name === 'case' ? /^\s*'([^']+)'\s*$/.exec(option.parameters[0] ?? '')?.[1] : undefined;
275
+ if (field)
276
+ branches.push({ field, inner: option.inner });
277
+ else if (option.name === 'default')
278
+ fallback = option.inner;
279
+ else
280
+ return 'la celda dinámica tiene un @case que no es un campo fijo.';
281
+ }
282
+ }
283
+ else if (blocks.length && blocks.every((b) => b.kind === 'block') && blocks[0].name === 'if') {
284
+ for (const [i, branch] of blocks.entries()) {
285
+ if (branch.name === 'else' && i === blocks.length - 1) {
286
+ fallback = branch.inner;
287
+ continue;
288
+ }
289
+ const field = (branch.name === 'if' ? i === 0 : branch.name === 'else if') ? fieldOf(branch.parameters[0] ?? '') : undefined;
290
+ if (!field)
291
+ return 'la celda dinámica tiene condiciones que no comparan col.field con un campo fijo.';
292
+ branches.push({ field, inner: branch.inner });
293
+ }
294
+ }
295
+ else {
296
+ return 'la celda dinámica muestra algo distinto de fila[col.field] y no se separa por campo con @if/@switch.';
297
+ }
298
+ if (!isDefault(fallback))
299
+ return 'la rama por defecto de la celda dinámica no es solo {{ fila[col.field] }}.';
300
+ const cells = branches.map(({ field, inner }) => {
301
+ const content = r.migrate(dedent(inner.trim()));
302
+ return { field, content, colVariable: new RegExp(`\\b${re(c)}\\b`).test(content) ? c : undefined };
303
+ });
304
+ return { columns: { source }, cells };
305
+ }
306
+ /**
307
+ * `<p-table>` → `<cb-table [columns]>`. Columnas escritas una a una en `#header` / `#body`
308
+ * (se genera el array) o dinámicas con `@for` (se usa el array del componente), y un
309
+ * `cbTableCell` por cada celda personalizada.
310
+ */
311
+ function restructureTable(node, r) {
312
+ const manual = (why) => `${why} Migra a <cb-table [columns]> con plantillas cbTableCell a mano.`;
313
+ const templates = significant(node);
314
+ if (templates.some((t) => t.name !== 'ng-template'))
315
+ return manual('p-table tiene contenido fuera de sus plantillas.');
316
+ const byName = new Map();
317
+ for (const template of templates) {
318
+ const name = templateName(template);
319
+ if (!name || !KNOWN_TEMPLATES.has(name))
320
+ return manual(`p-table usa la plantilla "${name ?? '?'}", que cb-table no tiene.`);
321
+ byName.set(name, template);
322
+ }
323
+ const header = byName.get('header');
324
+ const body = byName.get('body');
325
+ if (!header || !body)
326
+ return manual('p-table sin plantillas header y body.');
327
+ const headerRow = singleRow(header);
328
+ const bodyRow = singleRow(body);
329
+ if (!headerRow || !bodyRow)
330
+ return manual('la cabecera o el cuerpo no son una sola fila <tr> (varias filas o @if).');
331
+ const thsAll = significant(headerRow);
332
+ const tdsAll = significant(bodyRow);
333
+ if (thsAll.length !== tdsAll.length)
334
+ return manual('la cabecera y el cuerpo no tienen el mismo número de celdas (colspan).');
335
+ const row = rowVariable(body);
336
+ if (!row)
337
+ return manual('la plantilla body no declara la fila (let-fila).');
338
+ const used = otherVariables(body).filter((name) => tdsAll.some((td) => new RegExp(`\\b${re(name)}\\b`).test(td.inner)));
339
+ if (used.length)
340
+ return manual(`las celdas usan ${used.join(', ')}, que cbTableCell no ofrece.`);
341
+ // Columnas de checkbox, radio y expandir: cb-table las pone sola.
342
+ let selection = null;
343
+ const ths = [];
344
+ const tds = [];
345
+ thsAll.forEach((th, i) => {
346
+ const special = specialColumn(th) ?? specialColumn(tdsAll[i]);
347
+ if (special === 'multiple' || special === 'single')
348
+ selection = special;
349
+ if (special)
350
+ return;
351
+ ths.push(th);
352
+ tds.push(tdsAll[i]);
353
+ });
354
+ const todos = [];
355
+ let columns;
356
+ let cells;
357
+ const headerLoop = ths.length === 1 ? columnLoop(ths[0], 'th') : null;
358
+ const bodyLoop = tds.length === 1 ? columnLoop(tds[0], 'td') : null;
359
+ if (headerLoop && bodyLoop) {
360
+ const dynamic = dynamicColumns(node, r, headerLoop, bodyLoop, { header, body }, row, todos);
361
+ if (typeof dynamic === 'string')
362
+ return manual(dynamic);
363
+ ({ columns, cells } = dynamic);
364
+ }
365
+ else {
366
+ if (ths.some((th) => th.name !== 'th') || tds.some((td) => td.name !== 'td'))
367
+ return manual('las celdas se generan con @for/@if que no son de columnas.');
368
+ const statics = staticColumns(r, ths, tds, row, todos);
369
+ if (typeof statics === 'string')
370
+ return manual(statics);
371
+ ({ columns, cells } = statics);
372
+ }
373
+ const rowAttrs = bodyRow.attrs.filter((a) => !/^\[?(pSelectableRow|pSelectableRowIndex|pRowToggler|pSelectableRowDisabled)\]?$/.test(a.name));
374
+ if (rowAttrs.length)
375
+ todos.push(`la fila tenía ${rowAttrs.map((a) => a.source).join(' ')}; cb-table no admite atributos por fila.`);
376
+ const { attrs, todos: ruleTodos } = r.rules(node, { to: 'cb-table', rules: TABLE_RULES });
377
+ const finalAttrs = [...attrs];
378
+ if (selection && !node.bindings.some((b) => b.name === 'selectionMode'))
379
+ finalAttrs.push(`selectionMode="${selection}"`);
380
+ const empty = byName.get('emptymessage');
381
+ if (empty) {
382
+ const text = singleCellContent(empty);
383
+ if (text !== null && !/[<@]/.test(text))
384
+ finalAttrs.push(text.includes('{{') ? `[emptyMessage]="${textExpression(text)}"` : `emptyMessage="${text.replace(/"/g, '&quot;')}"`);
385
+ else
386
+ todos.push('el mensaje de tabla vacía tenía marcado; cb-table solo admite texto en emptyMessage.');
387
+ }
388
+ const expansionNode = byName.get('rowexpansion');
389
+ let expansion;
390
+ if (expansionNode) {
391
+ const content = singleCellContent(expansionNode);
392
+ const variable = rowVariable(expansionNode);
393
+ if (content === null || !variable)
394
+ return manual('la fila de expansión no es <tr><td>…</td></tr>.');
395
+ expansion = { variable, content: r.migrate(dedent(content)) };
396
+ }
397
+ const { eol } = r;
398
+ const indent = node.indent;
399
+ const inner = `${indent} `;
400
+ const fixFilterGlobal = (fragment) => fragment.replace(/\.filterGlobal\(([\s\S]*?),\s*['"][A-Za-z]+['"]\s*\)/g, '.filterGlobal($1)');
401
+ const moved = (name, where) => {
402
+ const template = byName.get(name);
403
+ if (!template)
404
+ return '';
405
+ todos.push(`el contenido de #${name} de p-table está ${where} de cb-table (no tiene esa zona).`);
406
+ return fixFilterGlobal(r.migrate(template.inner.trim()));
407
+ };
408
+ const caption = moved('caption', 'antes');
409
+ const summary = moved('summary', 'después');
410
+ // Sin coma final: el parser de expresiones de Angular no la admite en todos los casos.
411
+ const columnsAttr = 'source' in columns
412
+ ? `[columns]="${columns.source}"`
413
+ : `[columns]="[${eol}${columns.literal.map((col) => `${inner} ${columnLiteral(col)}`).join(`,${eol}`)}${eol}${inner}]"`;
414
+ /** Contenido de una plantilla: en la misma línea si es corto, o como bloque sangrado. */
415
+ const templateBody = (content) => {
416
+ if (!/\r?\n/.test(content))
417
+ return content;
418
+ return eol + content.split(/\r?\n/).map((line) => (line.trim() ? `${inner} ${line}` : '')).join(eol) + eol + inner;
419
+ };
420
+ const templateLines = cells.map((cell) => `${inner}<ng-template cbTableCell=${JSON.stringify(cell.field)} let-${row}${cell.colVariable ? ` let-${cell.colVariable}="col"` : ''}>${templateBody(cell.content)}</ng-template>`);
421
+ if (expansion)
422
+ templateLines.push(`${inner}<ng-template cbTableRowExpansion let-${expansion.variable}>${templateBody(expansion.content)}</ng-template>`);
423
+ let result = [...ruleTodos, ...todos].map((todo) => todoComment(todo) + eol + indent).join('');
424
+ if (caption)
425
+ result += caption + eol + indent;
426
+ result += `<cb-table${finalAttrs.map((a) => eol + inner + a).join('')}${eol}${inner}${columnsAttr}${eol}${indent}>`;
427
+ if (templateLines.length)
428
+ result += eol + templateLines.join(eol) + eol + indent;
429
+ result += '</cb-table>';
430
+ if (summary)
431
+ result += eol + indent + summary;
432
+ r.replace(node, result);
433
+ return null;
434
+ }
435
+ /** Columnas escritas una a una: un `<th>` y un `<td>` por columna. */
436
+ function staticColumns(r, ths, tds, row, todos) {
437
+ const literal = [];
438
+ const cells = [];
439
+ const fields = new Set();
440
+ const rowPath = new RegExp(`(?<![\\w$.])${re(row)}((?:\\??\\.[A-Za-z_$][\\w$]*)+)(\\s*\\()?`);
441
+ for (let i = 0; i < ths.length; i++) {
442
+ const th = ths[i];
443
+ const td = tds[i];
444
+ const sortBinding = th.bindings.find((b) => b.name === 'pSortableColumn');
445
+ const sortField = sortBinding?.kind === 'static' ? sortBinding.value : sortBinding && /^'([^']+)'$/.exec(sortBinding.value.trim())?.[1];
446
+ if (sortBinding && !sortField)
447
+ todos.push(`${sortBinding.source} — el campo de orden es una expresión; revisa sortable en la columna.`);
448
+ let filter = false;
449
+ let matchMode;
450
+ const headerText = th.inner
451
+ .replace(SORT_ICON, '')
452
+ .replace(COLUMN_FILTER, (_match, attrs) => {
453
+ filter = true;
454
+ const mode = /matchMode="(contains|startsWith|equals)"/.exec(attrs)?.[1];
455
+ if (mode && mode !== 'contains')
456
+ matchMode = mode;
457
+ return '';
458
+ })
459
+ .trim()
460
+ .replace(/\s+/g, ' ');
461
+ if (/[<@]/.test(headerText))
462
+ return `la cabecera "${headerText.slice(0, 40)}" tiene marcado (iconos, badges…) y cb-table solo admite texto en header.`;
463
+ const width = /(?:^|;)\s*width\s*:\s*([^;]+?)\s*(?:;|$)/.exec(th.attrs.find((a) => a.name === 'style')?.value ?? '')?.[1];
464
+ const content = td.inner.trim();
465
+ const simple = new RegExp(`^\\{\\{\\s*${re(row)}\\.([A-Za-z_$][\\w$]*(?:\\.[A-Za-z_$][\\w$]*)*)\\s*\\}\\}$`).exec(content)?.[1];
466
+ const fromContent = (() => {
467
+ const match = rowPath.exec(content);
468
+ if (!match)
469
+ return undefined;
470
+ const segments = match[1].replace(/\?/g, '').split('.').filter(Boolean);
471
+ if (match[2])
472
+ segments.pop();
473
+ return segments.join('.') || undefined;
474
+ })();
475
+ let field = sortField ?? simple ?? fromContent ?? `col${i + 1}`;
476
+ if (fields.has(field))
477
+ field = `${field}_${i + 1}`;
478
+ fields.add(field);
479
+ const ignoredAttrs = td.attrs.filter((a) => !/^\[?pFrozenColumn\]?$/.test(a.name) && !/^\[?alignFrozen\]?$/.test(a.name));
480
+ if (ignoredAttrs.length)
481
+ todos.push(`la celda de "${headerText}" tenía ${ignoredAttrs.map((a) => a.source).join(' ')}; aplica esos estilos dentro de su cbTableCell.`);
482
+ literal.push({ field, header: textExpression(headerText), sortable: !!sortField, filter, matchMode, width, frozen: isFrozen(th) || isFrozen(td) });
483
+ if (!(simple && simple === field))
484
+ cells.push({ field, content: r.migrate(dedent(content)) });
485
+ }
486
+ return { columns: { literal }, cells };
487
+ }
488
+ /**
489
+ * Propiedades usadas como `[columns]` de una p-table cuya cabecera dinámica hace todas las
490
+ * columnas ordenables (`[pSortableColumn]="col.field"`) o filtrables (`<p-columnFilter [field]="col.field">`).
491
+ */
492
+ function dynamicColumnFlags(templates) {
493
+ const flags = new Map();
494
+ for (const template of templates) {
495
+ for (const [table] of template.matchAll(/<p-table\b[\s\S]*?<\/p-table>/g)) {
496
+ const name = /\[columns\]\s*=\s*"\s*(?:this\.)?([A-Za-z_$][\w$]*)(?:\(\))?\s*"/.exec(table)?.[1];
497
+ if (!name)
498
+ continue;
499
+ const sortable = /\[pSortableColumn\]\s*=\s*"\s*[A-Za-z_$][\w$]*\.field\s*"/.test(table);
500
+ const filter = /<p-column-?[Ff]ilter\b[^>]*\[field\]\s*=\s*"\s*[A-Za-z_$][\w$]*\.field\s*"/.test(table);
501
+ if (sortable || filter)
502
+ flags.set(name, { sortable, filter });
503
+ }
504
+ }
505
+ return flags;
506
+ }
507
+ /**
508
+ * Columnas dinámicas: añade `sortable: true` / `filter: true` a los objetos del array del
509
+ * componente (en PrimeNG lo decidía la plantilla) y lo tipa como `CbTableColumn[]`.
510
+ */
511
+ const rewriteTableColumns = (sf, context, edits) => {
512
+ if (!context.locals.has('TableModule') && !context.locals.has('Table'))
513
+ return;
514
+ const flags = dynamicColumnFlags(context.templates);
515
+ if (!flags.size)
516
+ return;
517
+ const addFlags = (array, wanted) => {
518
+ for (const element of array.elements) {
519
+ if (!ts.isObjectLiteralExpression(element))
520
+ continue;
521
+ const names = new Set(element.properties.map((p) => (0, service_calls_1.propertyName)(p)));
522
+ const missing = [wanted.sortable && !names.has('sortable') && 'sortable: true', wanted.filter && !names.has('filter') && 'filter: true'].filter(Boolean);
523
+ if (!missing.length)
524
+ continue;
525
+ const last = element.properties[element.properties.length - 1];
526
+ if (last)
527
+ edits.push({ start: last.getEnd(), end: last.getEnd(), text: `, ${missing.join(', ')}` });
528
+ else
529
+ edits.push({ start: element.getStart(sf) + 1, end: element.getEnd() - 1, text: ` ${missing.join(', ')} ` });
530
+ }
531
+ };
532
+ /** `[...]` o `signal([...])`. */
533
+ const arrayOf = (expression) => {
534
+ if (!expression)
535
+ return undefined;
536
+ if (ts.isArrayLiteralExpression(expression))
537
+ return expression;
538
+ if (ts.isCallExpression(expression) && expression.arguments[0] && ts.isArrayLiteralExpression(expression.arguments[0]))
539
+ return expression.arguments[0];
540
+ return undefined;
541
+ };
542
+ /** `Column[]`, `Array<Column>` o `signal<Column[]>` → `CbTableColumn`. */
543
+ const retype = (node) => {
544
+ const visit = (current) => {
545
+ const element = ts.isArrayTypeNode(current) ? current.elementType : undefined;
546
+ if (element && ts.isTypeReferenceNode(element) && ts.isIdentifier(element.typeName) && element.typeName.text !== 'CbTableColumn') {
547
+ edits.push({ start: element.getStart(sf), end: element.getEnd(), text: 'CbTableColumn' });
548
+ context.addImport('CbTableColumn', '@caribeng/ui/table');
549
+ return;
550
+ }
551
+ ts.forEachChild(current, visit);
552
+ };
553
+ visit(node);
554
+ };
555
+ const visit = (node) => {
556
+ if (ts.isPropertyDeclaration(node) && ts.isIdentifier(node.name) && flags.has(node.name.text)) {
557
+ const array = arrayOf(node.initializer);
558
+ if (array)
559
+ addFlags(array, flags.get(node.name.text));
560
+ if (node.type)
561
+ retype(node.type);
562
+ if (node.initializer && ts.isCallExpression(node.initializer))
563
+ node.initializer.typeArguments?.forEach(retype);
564
+ return;
565
+ }
566
+ if (ts.isBinaryExpression(node) &&
567
+ node.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
568
+ ts.isPropertyAccessExpression(node.left) &&
569
+ node.left.expression.kind === ts.SyntaxKind.ThisKeyword &&
570
+ flags.has(node.left.name.text)) {
571
+ const array = arrayOf(node.right);
572
+ if (array)
573
+ addFlags(array, flags.get(node.left.name.text));
574
+ return;
575
+ }
576
+ ts.forEachChild(node, visit);
577
+ };
578
+ visit(sf);
579
+ };
580
+ exports.table = {
581
+ name: 'table',
582
+ entry: '@caribeng/ui/table',
583
+ symbol: 'CbTable',
584
+ attrs: { cbTableCell: 'CbTableCellDirective', cbTableRowExpansion: 'CbTableRowExpansion' },
585
+ rewriteSource: rewriteTableColumns,
586
+ modules: {
587
+ 'primeng/table': { TableModule: 'CbTable', Table: 'CbTable', TableLazyLoadEvent: 'CbTableLazyLoadEvent' },
588
+ },
589
+ elements: [
590
+ {
591
+ tag: 'p-table',
592
+ to: 'cb-table',
593
+ rules: TABLE_RULES,
594
+ restructure: restructureTable,
595
+ same: [
596
+ 'value',
597
+ 'paginator',
598
+ 'rowsPerPageOptions',
599
+ 'dataKey',
600
+ 'selection',
601
+ 'selectionMode',
602
+ 'globalFilterFields',
603
+ 'scrollHeight',
604
+ 'resizableColumns',
605
+ 'lazy',
606
+ 'loading',
607
+ 'groupRowsBy',
608
+ 'rowHover',
609
+ 'ariaLabel',
610
+ ],
611
+ },
612
+ ],
613
+ };