@telcomdev/ui 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -25,6 +25,82 @@ export class App {
25
25
  El icono hereda el color CSS mediante `currentColor`. Si el nombre no existe, se muestra
26
26
  `folder`.
27
27
 
28
+ ## Data table
29
+
30
+ `TdDataTable` usa `@angular/cdk/scrolling` para virtualizar las filas. La aplicación
31
+ consumidora mantiene la responsabilidad de consultar, paginar y modificar datos.
32
+
33
+ ```ts
34
+ import {
35
+ TdDataTable,
36
+ TdDataTableAccion,
37
+ TdDataTableAccionEvento,
38
+ TdDataTableBoton,
39
+ TdDataTableColumna,
40
+ } from '@telcomdev/ui';
41
+
42
+ @Component({
43
+ imports: [TdDataTable],
44
+ })
45
+ export class Establecimientos {
46
+ columnas: TdDataTableColumna<Establecimiento>[] = [
47
+ { clave: 'nombre', encabezado: 'Nombre', ancho: '1fr' },
48
+ { clave: 'codigoSunat', encabezado: 'Código Sunat', ancho: '8rem' },
49
+ { clave: 'direccion', encabezado: 'Dirección', ancho: '1.5fr' },
50
+ { clave: 'esPrincipal', encabezado: 'Principal', tipo: 'booleano' },
51
+ { clave: 'activo', encabezado: 'Estado', tipo: 'estado' },
52
+ ];
53
+
54
+ acciones: TdDataTableAccion<Establecimiento>[] = [
55
+ { id: 'editar', etiqueta: 'Editar', icono: 'edit' },
56
+ { id: 'eliminar', etiqueta: 'Eliminar', icono: 'delete', tono: 'peligro' },
57
+ ];
58
+
59
+ botones: TdDataTableBoton[] = [
60
+ { id: 'pdf', etiqueta: 'Exportar PDF', icono: 'pdf', tono: 'peligro' },
61
+ { id: 'excel', etiqueta: 'Exportar Excel', icono: 'description', tono: 'exito' },
62
+ ];
63
+
64
+ ejecutar(evento: TdDataTableAccionEvento<Establecimiento>) {
65
+ // evento.accion.id, evento.fila y evento.indice
66
+ }
67
+ }
68
+ ```
69
+
70
+ ```html
71
+ <td-data-table
72
+ campoId="establecimientoId"
73
+ textoAgregar="Agregar establecimiento"
74
+ [datos]="lista()"
75
+ [columnas]="columnas"
76
+ [acciones]="acciones"
77
+ [botones]="botones"
78
+ [total]="totalEstablecimientos()"
79
+ [cargando]="cargando()"
80
+ [puedeCargarMas]="paginaActual() < totalPaginas()"
81
+ (busquedaChange)="buscar($event)"
82
+ (agregar)="abrirModal(0)"
83
+ (accion)="ejecutar($event)"
84
+ (botonClick)="exportar($event)"
85
+ (cargarMas)="paginaSiguiente()"
86
+ >
87
+ <select tdDataTableFilters [(ngModel)]="estado">
88
+ <option value="">Todos los estados</option>
89
+ <option value="activo">Activos</option>
90
+ <option value="inactivo">Inactivos</option>
91
+ </select>
92
+
93
+ <input tdDataTableFilters type="date" [(ngModel)]="fecha" />
94
+
95
+ <button tdDataTableActions type="button">Acción personalizada</button>
96
+ </td-data-table>
97
+ ```
98
+
99
+ Incluye búsqueda con debounce, scroll virtual, carga incremental, chips de estado,
100
+ acciones condicionales, tema oscuro, estado vacío y skeleton de carga. Los elementos
101
+ marcados con `tdDataTableFilters` se colocan junto al buscador. Los elementos
102
+ `tdDataTableActions` aparecen junto al contador y al botón Agregar.
103
+
28
104
  ## Header
29
105
 
30
106
  ```ts
@@ -1,5 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, Input, ChangeDetectionStrategy, Injectable, inject, HostBinding, EventEmitter, HostListener, Output, signal } from '@angular/core';
2
+ import { Component, Injectable, inject, HostBinding, Input, ChangeDetectionStrategy, EventEmitter, Output, ViewChild, HostListener, signal } from '@angular/core';
3
+ import * as i2 from '@angular/cdk/scrolling';
4
+ import { ScrollingModule, CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
5
+ import * as i1 from '@angular/forms';
6
+ import { FormsModule } from '@angular/forms';
3
7
  import { NgTemplateOutlet } from '@angular/common';
4
8
  import { RouterLink, RouterLinkActive } from '@angular/router';
5
9
 
@@ -358,33 +362,6 @@ class TdAlerta {
358
362
  }
359
363
  }
360
364
 
361
- class TdFooter {
362
- empresa = 'TelcomDev';
363
- texto = 'Todos los derechos reservados.';
364
- version = '';
365
- oscuro = false;
366
- compacto = false;
367
- anio = new Date().getFullYear();
368
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TdFooter, deps: [], target: i0.ɵɵFactoryTarget.Component });
369
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: TdFooter, isStandalone: true, selector: "td-footer", inputs: { empresa: "empresa", texto: "texto", version: "version", oscuro: "oscuro", compacto: "compacto", anio: "anio" }, ngImport: i0, template: "<footer\n class=\"td-footer\"\n [class.td-footer--oscuro]=\"oscuro\"\n [class.td-footer--compacto]=\"compacto\"\n>\n <div class=\"td-footer__identidad\">\n <span>\u00A9 {{ anio }} {{ empresa }}</span>\n @if (texto) {\n <small>{{ texto }}</small>\n }\n </div>\n\n <nav class=\"td-footer__enlaces\" aria-label=\"Enlaces del pie de p\u00E1gina\">\n <ng-content select=\"[tdFooterLinks]\" />\n </nav>\n\n <div class=\"td-footer__final\">\n <ng-content select=\"[tdFooterActions]\" />\n @if (version) {\n <span class=\"td-footer__version\">v{{ version }}</span>\n }\n </div>\n</footer>\n", styles: [":host{display:block}*{box-sizing:border-box}.td-footer{--td-footer-fondo: #fff;--td-footer-borde: #e2e8f0;--td-footer-texto: #475569;--td-footer-suave: #94a3b8;display:grid;min-height:4.5rem;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:1rem;border-top:1px solid var(--td-footer-borde);padding:1rem 1.5rem;color:var(--td-footer-texto);background:var(--td-footer-fondo);font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:.75rem}.td-footer--oscuro{--td-footer-fondo: #111116;--td-footer-borde: #29292f;--td-footer-texto: #d4d4d8;--td-footer-suave: #71717a}.td-footer--compacto{min-height:3.25rem;padding-block:.65rem}.td-footer__identidad{display:flex;min-width:0;flex-wrap:wrap;gap:.3rem .75rem;align-items:center}.td-footer__identidad span{font-weight:700}.td-footer__identidad small{color:var(--td-footer-suave);font-size:inherit}.td-footer__enlaces{display:flex;align-items:center;justify-content:center;gap:1rem}.td-footer__final{display:flex;align-items:center;justify-content:flex-end;gap:.75rem}.td-footer__version{border:1px solid var(--td-footer-borde);border-radius:999px;padding:.22rem .55rem;color:var(--td-footer-suave);font:700 .65rem/1 ui-monospace,monospace}@media(max-width:720px){.td-footer{grid-template-columns:1fr;justify-items:center;text-align:center}.td-footer__identidad,.td-footer__final{justify-content:center}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
370
- }
371
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TdFooter, decorators: [{
372
- type: Component,
373
- args: [{ selector: 'td-footer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<footer\n class=\"td-footer\"\n [class.td-footer--oscuro]=\"oscuro\"\n [class.td-footer--compacto]=\"compacto\"\n>\n <div class=\"td-footer__identidad\">\n <span>\u00A9 {{ anio }} {{ empresa }}</span>\n @if (texto) {\n <small>{{ texto }}</small>\n }\n </div>\n\n <nav class=\"td-footer__enlaces\" aria-label=\"Enlaces del pie de p\u00E1gina\">\n <ng-content select=\"[tdFooterLinks]\" />\n </nav>\n\n <div class=\"td-footer__final\">\n <ng-content select=\"[tdFooterActions]\" />\n @if (version) {\n <span class=\"td-footer__version\">v{{ version }}</span>\n }\n </div>\n</footer>\n", styles: [":host{display:block}*{box-sizing:border-box}.td-footer{--td-footer-fondo: #fff;--td-footer-borde: #e2e8f0;--td-footer-texto: #475569;--td-footer-suave: #94a3b8;display:grid;min-height:4.5rem;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:1rem;border-top:1px solid var(--td-footer-borde);padding:1rem 1.5rem;color:var(--td-footer-texto);background:var(--td-footer-fondo);font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:.75rem}.td-footer--oscuro{--td-footer-fondo: #111116;--td-footer-borde: #29292f;--td-footer-texto: #d4d4d8;--td-footer-suave: #71717a}.td-footer--compacto{min-height:3.25rem;padding-block:.65rem}.td-footer__identidad{display:flex;min-width:0;flex-wrap:wrap;gap:.3rem .75rem;align-items:center}.td-footer__identidad span{font-weight:700}.td-footer__identidad small{color:var(--td-footer-suave);font-size:inherit}.td-footer__enlaces{display:flex;align-items:center;justify-content:center;gap:1rem}.td-footer__final{display:flex;align-items:center;justify-content:flex-end;gap:.75rem}.td-footer__version{border:1px solid var(--td-footer-borde);border-radius:999px;padding:.22rem .55rem;color:var(--td-footer-suave);font:700 .65rem/1 ui-monospace,monospace}@media(max-width:720px){.td-footer{grid-template-columns:1fr;justify-items:center;text-align:center}.td-footer__identidad,.td-footer__final{justify-content:center}}\n"] }]
374
- }], propDecorators: { empresa: [{
375
- type: Input
376
- }], texto: [{
377
- type: Input
378
- }], version: [{
379
- type: Input
380
- }], oscuro: [{
381
- type: Input
382
- }], compacto: [{
383
- type: Input
384
- }], anio: [{
385
- type: Input
386
- }] } });
387
-
388
365
  const TD_ICONOS = {
389
366
  home: {
390
367
  path: 'M3 10.5 12 3l9 7.5V21a1 1 0 0 1-1 1h-5v-7H9v7H4a1 1 0 0 1-1-1V10.5Z',
@@ -464,6 +441,27 @@ const TD_ICONOS = {
464
441
  help: {
465
442
  path: 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm0 18a8 8 0 1 1 0-16 8 8 0 0 1 0 16Zm0-4.5a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5Zm.2-9.5c-2 0-3.37 1.03-3.7 2.75l1.95.4c.17-.84.77-1.3 1.67-1.3 1 0 1.63.52 1.63 1.35 0 .67-.33 1.03-1.27 1.58-1.12.65-1.48 1.27-1.48 2.47V14h2v-.55c0-.67.2-.94 1.12-1.5 1.18-.72 1.88-1.58 1.88-2.9C16 7.25 14.5 6 12.2 6Z',
466
443
  },
444
+ add: {
445
+ path: 'M11 5h2v6h6v2h-6v6h-2v-6H5v-2h6V5Z',
446
+ },
447
+ edit: {
448
+ path: 'm16.86 3.49 3.65 3.65L8.65 19H5v-3.65L16.86 3.49ZM19.73 2.27a1.75 1.75 0 0 0-2.47 0l-1.35 1.35 3.65 3.65 1.35-1.35a1.75 1.75 0 0 0 0-2.47l-1.18-1.18Z',
449
+ },
450
+ delete: {
451
+ path: 'M8 3h8l1 2h4v2H3V5h4l1-2Zm-2 6h12l-1 12H7L6 9Zm4 2v7h2v-7h-2Zm4 0v7h2v-7h-2Z',
452
+ },
453
+ toggle_on: {
454
+ path: 'M17 6H7a6 6 0 0 0 0 12h10a6 6 0 0 0 0-12Zm0 10a4 4 0 1 1 0-8 4 4 0 0 1 0 8Z',
455
+ },
456
+ toggle_off: {
457
+ path: 'M17 6H7a6 6 0 0 0 0 12h10a6 6 0 0 0 0-12ZM7 16a4 4 0 1 1 0-8 4 4 0 0 1 0 8Z',
458
+ },
459
+ inbox: {
460
+ path: 'M4 3h16l3 11v7H1v-7L4 3Zm1.5 2L3 14h5l1 2h6l1-2h5l-2.5-9h-13Z',
461
+ },
462
+ pdf: {
463
+ path: 'M6 2h9l5 5v15H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2Zm8 1.5V8h4.5L14 3.5ZM8 12v7h2v-2h1.2a2.5 2.5 0 0 0 0-5H8Zm2 2h1.2a.5.5 0 0 1 0 1H10v-1Zm4-2v7h2v-2h1v-2h-1v-1h2v-2h-4Z',
464
+ },
467
465
  };
468
466
  const TD_ICONOS_NOMBRES = Object.freeze(Object.keys(TD_ICONOS));
469
467
 
@@ -548,6 +546,195 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
548
546
  args: ['style.--td-icon-size']
549
547
  }] } });
550
548
 
549
+ class TdDataTable {
550
+ viewport;
551
+ datos = [];
552
+ columnas = [];
553
+ acciones = [];
554
+ botones = [];
555
+ total = 0;
556
+ cargando = false;
557
+ puedeCargarMas = false;
558
+ itemSize = 65;
559
+ altura = 'min(620px, calc(100dvh - 18rem))';
560
+ campoId = 'id';
561
+ oscuro = false;
562
+ mostrarBusqueda = true;
563
+ mostrarAgregar = true;
564
+ placeholderBusqueda = 'Buscar...';
565
+ textoAgregar = 'Agregar';
566
+ textoVacio = 'No hay registros disponibles';
567
+ descripcionVacio = 'Comienza creando un nuevo registro.';
568
+ debounceBusqueda = 250;
569
+ busquedaChange = new EventEmitter();
570
+ agregar = new EventEmitter();
571
+ accion = new EventEmitter();
572
+ botonClick = new EventEmitter();
573
+ cargarMas = new EventEmitter();
574
+ busqueda = '';
575
+ timeoutBusqueda = null;
576
+ ultimaLongitudSolicitada = -1;
577
+ ngOnChanges(changes) {
578
+ if (changes['datos'] && this.datos.length !== this.ultimaLongitudSolicitada) {
579
+ this.ultimaLongitudSolicitada = -1;
580
+ }
581
+ }
582
+ ngOnDestroy() {
583
+ if (this.timeoutBusqueda)
584
+ clearTimeout(this.timeoutBusqueda);
585
+ }
586
+ columnasGrid() {
587
+ const columnas = this.columnas.map((columna) => columna.ancho ?? 'minmax(10rem, 1fr)');
588
+ if (this.acciones.length)
589
+ columnas.push('minmax(9rem, auto)');
590
+ return columnas.join(' ');
591
+ }
592
+ buscar() {
593
+ if (this.timeoutBusqueda)
594
+ clearTimeout(this.timeoutBusqueda);
595
+ this.timeoutBusqueda = setTimeout(() => this.busquedaChange.emit(this.busqueda.trim()), this.debounceBusqueda);
596
+ }
597
+ limpiarBusqueda() {
598
+ if (this.timeoutBusqueda)
599
+ clearTimeout(this.timeoutBusqueda);
600
+ this.busqueda = '';
601
+ this.busquedaChange.emit('');
602
+ }
603
+ valor(fila, clave) {
604
+ return fila[clave];
605
+ }
606
+ textoCelda(columna, fila, indice) {
607
+ const valor = this.valor(fila, columna.clave);
608
+ if (columna.formatear)
609
+ return columna.formatear(valor, fila, indice);
610
+ if (valor === null || valor === undefined || valor === '')
611
+ return '—';
612
+ if (columna.tipo === 'booleano')
613
+ return valor ? 'Sí' : 'No';
614
+ if (columna.tipo === 'estado')
615
+ return valor ? 'Activo' : 'Inactivo';
616
+ return String(valor);
617
+ }
618
+ tonoCelda(columna, fila) {
619
+ const valor = this.valor(fila, columna.clave);
620
+ if (columna.tono)
621
+ return columna.tono(valor, fila);
622
+ if (columna.tipo === 'estado')
623
+ return valor ? 'exito' : 'peligro';
624
+ if (columna.tipo === 'booleano')
625
+ return valor ? 'exito' : 'neutro';
626
+ return 'neutro';
627
+ }
628
+ accionesVisibles(fila) {
629
+ return this.acciones.filter((accion) => accion.visible?.(fila) ?? true);
630
+ }
631
+ botonesVisibles() {
632
+ return this.botones.filter((boton) => boton.visible ?? true);
633
+ }
634
+ ejecutarAccion(accion, fila, indice) {
635
+ if (accion.deshabilitada?.(fila))
636
+ return;
637
+ this.accion.emit({ accion, fila, indice });
638
+ }
639
+ alCambiarIndice() {
640
+ if (!this.viewport)
641
+ return;
642
+ const distanciaAlFinal = this.viewport.measureScrollOffset('bottom');
643
+ const umbralPx = this.itemSize * 2;
644
+ if (distanciaAlFinal <= umbralPx &&
645
+ this.datos.length > 0 &&
646
+ this.puedeCargarMas &&
647
+ !this.cargando &&
648
+ this.ultimaLongitudSolicitada !== this.datos.length) {
649
+ this.ultimaLongitudSolicitada = this.datos.length;
650
+ this.cargarMas.emit();
651
+ }
652
+ }
653
+ trackFila = (_indice, fila) => fila[this.campoId] ?? fila;
654
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TdDataTable, deps: [], target: i0.ɵɵFactoryTarget.Component });
655
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: TdDataTable, isStandalone: true, selector: "td-data-table", inputs: { datos: "datos", columnas: "columnas", acciones: "acciones", botones: "botones", total: "total", cargando: "cargando", puedeCargarMas: "puedeCargarMas", itemSize: "itemSize", altura: "altura", campoId: "campoId", oscuro: "oscuro", mostrarBusqueda: "mostrarBusqueda", mostrarAgregar: "mostrarAgregar", placeholderBusqueda: "placeholderBusqueda", textoAgregar: "textoAgregar", textoVacio: "textoVacio", descripcionVacio: "descripcionVacio", debounceBusqueda: "debounceBusqueda" }, outputs: { busquedaChange: "busquedaChange", agregar: "agregar", accion: "accion", botonClick: "botonClick", cargarMas: "cargarMas" }, viewQueries: [{ propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<section class=\"td-tabla\" [class.td-tabla--oscura]=\"oscuro\">\n <div class=\"td-tabla__toolbar\">\n <div class=\"td-tabla__filtros\">\n @if (mostrarBusqueda) {\n <label class=\"td-tabla__busqueda\">\n <td-icon nombre=\"search\" />\n <input\n type=\"search\"\n [(ngModel)]=\"busqueda\"\n [placeholder]=\"placeholderBusqueda\"\n (input)=\"buscar()\"\n />\n @if (busqueda) {\n <button type=\"button\" title=\"Limpiar b\u00FAsqueda\" (click)=\"limpiarBusqueda()\">\n <td-icon nombre=\"close\" tamano=\"1rem\" />\n </button>\n }\n </label>\n }\n <ng-content select=\"[tdDataTableFilters]\" />\n </div>\n </div>\n\n <div class=\"td-tabla__superficie\">\n <div class=\"td-tabla__resumen\">\n <span><strong>{{ datos.length }}</strong> de {{ total || datos.length }} registros</span>\n <div class=\"td-tabla__resumen-acciones\">\n @if (cargando) {\n <span class=\"td-tabla__cargando-inline\"><i></i> Cargando...</span>\n }\n <ng-content select=\"[tdDataTableActions]\" />\n @for (boton of botonesVisibles(); track boton.id) {\n <button\n type=\"button\"\n [class]=\"'td-tabla__boton td-tabla__boton--' + (boton.tono || 'neutro')\"\n [disabled]=\"boton.deshabilitado\"\n (click)=\"botonClick.emit(boton)\"\n >\n <td-icon [nombre]=\"boton.icono\" />\n <span>{{ boton.etiqueta }}</span>\n </button>\n }\n @if (mostrarAgregar) {\n <button class=\"td-tabla__agregar\" type=\"button\" (click)=\"agregar.emit()\">\n <td-icon nombre=\"add\" />\n <span>{{ textoAgregar }}</span>\n </button>\n }\n </div>\n </div>\n\n @if (datos.length) {\n <div\n class=\"td-tabla__encabezado\"\n role=\"row\"\n [style.grid-template-columns]=\"columnasGrid()\"\n >\n @for (columna of columnas; track columna.clave) {\n <div\n role=\"columnheader\"\n [class]=\"'td-tabla__alinear--' + (columna.alineacion || 'inicio')\"\n >\n {{ columna.encabezado }}\n </div>\n }\n @if (acciones.length) {\n <div role=\"columnheader\" class=\"td-tabla__alinear--centro\">Acciones</div>\n }\n </div>\n\n <cdk-virtual-scroll-viewport\n class=\"td-tabla__viewport\"\n [itemSize]=\"itemSize\"\n [style.height]=\"altura\"\n (scrolledIndexChange)=\"alCambiarIndice()\"\n >\n <div\n *cdkVirtualFor=\"let fila of datos; let indice = index; trackBy: trackFila\"\n class=\"td-tabla__fila\"\n role=\"row\"\n [style.height.px]=\"itemSize\"\n [style.grid-template-columns]=\"columnasGrid()\"\n >\n @for (columna of columnas; track columna.clave) {\n <div\n role=\"cell\"\n [class]=\"'td-tabla__celda td-tabla__alinear--' + (columna.alineacion || 'inicio')\"\n >\n @if (\n columna.tipo === 'estado' ||\n columna.tipo === 'booleano' ||\n columna.tipo === 'chip'\n ) {\n <span [class]=\"'td-tabla__chip td-tabla__chip--' + tonoCelda(columna, fila)\">\n {{ textoCelda(columna, fila, indice) }}\n </span>\n } @else {\n <span [class.td-tabla__numero]=\"columna.tipo === 'numero'\">\n {{ textoCelda(columna, fila, indice) }}\n </span>\n }\n </div>\n }\n\n @if (acciones.length) {\n <div class=\"td-tabla__acciones-fila\" role=\"cell\">\n @for (accionFila of accionesVisibles(fila); track accionFila.id) {\n <button\n type=\"button\"\n [class]=\"'td-tabla__accion td-tabla__accion--' + (accionFila.tono || 'neutro')\"\n [title]=\"accionFila.etiqueta\"\n [disabled]=\"accionFila.deshabilitada?.(fila) ?? false\"\n (click)=\"ejecutarAccion(accionFila, fila, indice)\"\n >\n <td-icon [nombre]=\"accionFila.icono\" />\n <span class=\"td-tabla__sr-only\">{{ accionFila.etiqueta }}</span>\n </button>\n }\n </div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n } @else if (!cargando) {\n <div class=\"td-tabla__vacio\">\n <span><td-icon nombre=\"inbox\" tamano=\"2.4rem\" /></span>\n <h3>{{ textoVacio }}</h3>\n <p>{{ descripcionVacio }}</p>\n </div>\n }\n\n @if (cargando && !datos.length) {\n <div class=\"td-tabla__skeleton\">\n @for (item of [1, 2, 3, 4, 5]; track item) {\n <span></span>\n }\n </div>\n }\n </div>\n</section>\n", styles: [":host{display:block}*{box-sizing:border-box}.td-tabla{--fondo: #fff;--fondo-suave: #f8fafc;--borde: #e4e8f0;--texto: #263147;--suave: #748096;--hover: #f7f8fc;--acento: #5746d8;color:var(--texto);font-family:Inter,ui-sans-serif,system-ui,sans-serif}.td-tabla--oscura{--fondo: #15151b;--fondo-suave: #1b1b22;--borde: #2d2d36;--texto: #ededf0;--suave: #9393a0;--hover: #202028;--acento: #a89cf7}.td-tabla__toolbar{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding-bottom:.85rem}.td-tabla__filtros{display:flex;min-width:0;flex:1;flex-wrap:wrap;align-items:center;gap:.65rem}.td-tabla__filtros ::ng-deep [tdDataTableFilters]{height:2.55rem;min-width:10.5rem;border:1px solid var(--borde);border-radius:.75rem;padding:0 .8rem;color:var(--texto);background-color:var(--fondo);font:600 .75rem/1 Inter,ui-sans-serif,system-ui,sans-serif;outline:none;transition:border-color .14s ease,box-shadow .14s ease,background-color .14s ease}.td-tabla__filtros ::ng-deep [tdDataTableFilters]:hover{border-color:color-mix(in srgb,var(--acento) 42%,var(--borde))}.td-tabla__filtros ::ng-deep [tdDataTableFilters]:focus{border-color:var(--acento);box-shadow:0 0 0 3px color-mix(in srgb,var(--acento) 15%,transparent)}.td-tabla__filtros ::ng-deep select[tdDataTableFilters]{appearance:none;padding-right:2.45rem;background-image:linear-gradient(45deg,transparent 50%,var(--suave) 50%),linear-gradient(135deg,var(--suave) 50%,transparent 50%);background-position:calc(100% - 1rem) 50%,calc(100% - .72rem) 50%;background-repeat:no-repeat;background-size:.3rem .3rem,.3rem .3rem;cursor:pointer}.td-tabla__filtros ::ng-deep input[type=date][tdDataTableFilters]{min-width:9.8rem;color-scheme:light;cursor:pointer}.td-tabla--oscura .td-tabla__filtros ::ng-deep input[type=date][tdDataTableFilters]{color-scheme:dark}.td-tabla__filtros ::ng-deep input[type=date][tdDataTableFilters]::-webkit-calendar-picker-indicator{opacity:.65;cursor:pointer}.td-tabla__filtros ::ng-deep [tdDataTableFilters]:disabled{opacity:.55;cursor:not-allowed}.td-tabla__busqueda{display:flex;width:min(22rem,100%);height:2.55rem;align-items:center;gap:.6rem;border:1px solid var(--borde);border-radius:.75rem;padding:0 .75rem;color:var(--suave);background:var(--fondo)}.td-tabla__busqueda:focus-within{border-color:var(--acento);box-shadow:0 0 0 3px color-mix(in srgb,var(--acento) 15%,transparent)}.td-tabla__busqueda input{min-width:0;flex:1;border:0;appearance:none;outline:0;color:var(--texto);background:transparent;font:inherit;font-size:.78rem}.td-tabla__busqueda input::-webkit-search-cancel-button,.td-tabla__busqueda input::-webkit-search-decoration{appearance:none;display:none}.td-tabla__busqueda input::-ms-clear,.td-tabla__busqueda input::-ms-reveal{display:none;width:0;height:0}.td-tabla__busqueda button{display:grid;place-items:center;border:0;padding:.2rem;color:var(--suave);background:transparent;cursor:pointer}.td-tabla__agregar,.td-tabla__vacio button,.td-tabla__boton{display:inline-flex;height:2.55rem;align-items:center;gap:.45rem;border:0;border-radius:.7rem;padding:0 1rem;color:#fff;background:linear-gradient(135deg,#5746d8,#7657df);box-shadow:0 7px 16px #5746d833;font-size:.75rem;font-weight:750;cursor:pointer}.td-tabla__resumen-acciones{display:flex;align-items:center;gap:.45rem}.td-tabla__boton{height:2.15rem;padding:0 .75rem;box-shadow:none;color:#526077;background:#edf0f5}.td-tabla__boton--primario{color:#fff;background:#5746d8}.td-tabla__boton--exito{color:#fff;background:#168447}.td-tabla__boton--advertencia{color:#fff;background:#b66d05}.td-tabla__boton--peligro{color:#fff;background:#d33f3f}.td-tabla__boton:disabled{opacity:.45;cursor:not-allowed}.td-tabla__superficie{overflow:hidden;border:1px solid var(--borde);border-radius:1rem;background:var(--fondo);box-shadow:0 12px 32px #1f2a440f}.td-tabla__resumen{display:flex;min-height:3rem;align-items:center;justify-content:space-between;border-bottom:1px solid var(--borde);padding:.7rem 1rem;color:var(--suave);background:var(--fondo-suave);font-size:.7rem}.td-tabla__resumen strong{color:var(--texto)}.td-tabla__cargando-inline{display:flex;align-items:center;gap:.4rem}.td-tabla__cargando-inline i{width:.65rem;height:.65rem;border:2px solid var(--borde);border-top-color:var(--acento);border-radius:50%;animation:td-tabla-girar .7s linear infinite}.td-tabla__encabezado,.td-tabla__fila{display:grid;min-width:max-content;align-items:center}.td-tabla__encabezado{position:relative;z-index:2;min-height:2.75rem;border-bottom:1px solid var(--borde);color:var(--suave);background:var(--fondo-suave);font-size:.62rem;font-weight:800;letter-spacing:.075em;text-transform:uppercase}.td-tabla__encabezado>div,.td-tabla__celda{padding:.6rem 1rem}.td-tabla__viewport{width:100%;min-height:12rem}.td-tabla__fila{border-bottom:1px solid var(--borde);transition:background .12s ease}.td-tabla__fila:hover{background:var(--hover)}.td-tabla__celda{overflow:hidden;color:var(--texto);font-size:.75rem;text-overflow:ellipsis;white-space:nowrap}.td-tabla__numero{font-variant-numeric:tabular-nums}.td-tabla__alinear--inicio{text-align:left}.td-tabla__alinear--centro{text-align:center;justify-content:center}.td-tabla__alinear--fin{text-align:right;justify-content:flex-end}.td-tabla__chip{display:inline-flex;border-radius:999px;padding:.25rem .55rem;color:#526077;background:#edf0f5;font-size:.65rem;font-weight:750}.td-tabla__chip--primario{color:#4f46e5;background:#eeecff}.td-tabla__chip--exito{color:#13713a;background:#dff7e8}.td-tabla__chip--advertencia{color:#9a5a05;background:#fff0cf}.td-tabla__chip--peligro{color:#b53434;background:#fee5e5}.td-tabla__acciones-fila{display:flex;align-items:center;justify-content:center;gap:.25rem;padding:0 .7rem}.td-tabla__accion{display:grid;width:2rem;height:2rem;place-items:center;border:0;border-radius:.55rem;color:var(--suave);background:transparent;cursor:pointer}.td-tabla__accion:hover{background:var(--hover);color:var(--acento)}.td-tabla__accion--exito{color:#168447}.td-tabla__accion--peligro{color:#dc3e3e}.td-tabla__accion--advertencia{color:#b66d05}.td-tabla__accion:disabled{opacity:.35;cursor:not-allowed}.td-tabla__vacio{display:grid;min-height:21rem;place-items:center;align-content:center;padding:2rem;text-align:center}.td-tabla__vacio>span{display:grid;width:4.5rem;height:4.5rem;place-items:center;border-radius:1.2rem;color:var(--acento);background:color-mix(in srgb,var(--acento) 10%,transparent)}.td-tabla__vacio h3{margin:1rem 0 .3rem;font-size:1rem}.td-tabla__vacio p{margin:0 0 1.25rem;color:var(--suave);font-size:.75rem}.td-tabla__skeleton{padding:.5rem 1rem}.td-tabla__skeleton span{display:block;height:3.5rem;border-bottom:1px solid var(--borde);background:linear-gradient(90deg,transparent,var(--hover),transparent);background-size:200% 100%;animation:td-tabla-cargar 1.2s linear infinite}.td-tabla__sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}@keyframes td-tabla-girar{to{transform:rotate(360deg)}}@keyframes td-tabla-cargar{to{background-position:-200% 0}}@media(max-width:640px){.td-tabla__toolbar{align-items:stretch;flex-direction:column}.td-tabla__busqueda{width:100%}.td-tabla__resumen{align-items:flex-start;flex-direction:column}.td-tabla__resumen-acciones{width:100%;flex-wrap:wrap}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i2.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i2.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i2.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: TdIcon, selector: "td-icon", inputs: ["nombre", "titulo", "tamano"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
656
+ }
657
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TdDataTable, decorators: [{
658
+ type: Component,
659
+ args: [{ selector: 'td-data-table', imports: [FormsModule, ScrollingModule, TdIcon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<section class=\"td-tabla\" [class.td-tabla--oscura]=\"oscuro\">\n <div class=\"td-tabla__toolbar\">\n <div class=\"td-tabla__filtros\">\n @if (mostrarBusqueda) {\n <label class=\"td-tabla__busqueda\">\n <td-icon nombre=\"search\" />\n <input\n type=\"search\"\n [(ngModel)]=\"busqueda\"\n [placeholder]=\"placeholderBusqueda\"\n (input)=\"buscar()\"\n />\n @if (busqueda) {\n <button type=\"button\" title=\"Limpiar b\u00FAsqueda\" (click)=\"limpiarBusqueda()\">\n <td-icon nombre=\"close\" tamano=\"1rem\" />\n </button>\n }\n </label>\n }\n <ng-content select=\"[tdDataTableFilters]\" />\n </div>\n </div>\n\n <div class=\"td-tabla__superficie\">\n <div class=\"td-tabla__resumen\">\n <span><strong>{{ datos.length }}</strong> de {{ total || datos.length }} registros</span>\n <div class=\"td-tabla__resumen-acciones\">\n @if (cargando) {\n <span class=\"td-tabla__cargando-inline\"><i></i> Cargando...</span>\n }\n <ng-content select=\"[tdDataTableActions]\" />\n @for (boton of botonesVisibles(); track boton.id) {\n <button\n type=\"button\"\n [class]=\"'td-tabla__boton td-tabla__boton--' + (boton.tono || 'neutro')\"\n [disabled]=\"boton.deshabilitado\"\n (click)=\"botonClick.emit(boton)\"\n >\n <td-icon [nombre]=\"boton.icono\" />\n <span>{{ boton.etiqueta }}</span>\n </button>\n }\n @if (mostrarAgregar) {\n <button class=\"td-tabla__agregar\" type=\"button\" (click)=\"agregar.emit()\">\n <td-icon nombre=\"add\" />\n <span>{{ textoAgregar }}</span>\n </button>\n }\n </div>\n </div>\n\n @if (datos.length) {\n <div\n class=\"td-tabla__encabezado\"\n role=\"row\"\n [style.grid-template-columns]=\"columnasGrid()\"\n >\n @for (columna of columnas; track columna.clave) {\n <div\n role=\"columnheader\"\n [class]=\"'td-tabla__alinear--' + (columna.alineacion || 'inicio')\"\n >\n {{ columna.encabezado }}\n </div>\n }\n @if (acciones.length) {\n <div role=\"columnheader\" class=\"td-tabla__alinear--centro\">Acciones</div>\n }\n </div>\n\n <cdk-virtual-scroll-viewport\n class=\"td-tabla__viewport\"\n [itemSize]=\"itemSize\"\n [style.height]=\"altura\"\n (scrolledIndexChange)=\"alCambiarIndice()\"\n >\n <div\n *cdkVirtualFor=\"let fila of datos; let indice = index; trackBy: trackFila\"\n class=\"td-tabla__fila\"\n role=\"row\"\n [style.height.px]=\"itemSize\"\n [style.grid-template-columns]=\"columnasGrid()\"\n >\n @for (columna of columnas; track columna.clave) {\n <div\n role=\"cell\"\n [class]=\"'td-tabla__celda td-tabla__alinear--' + (columna.alineacion || 'inicio')\"\n >\n @if (\n columna.tipo === 'estado' ||\n columna.tipo === 'booleano' ||\n columna.tipo === 'chip'\n ) {\n <span [class]=\"'td-tabla__chip td-tabla__chip--' + tonoCelda(columna, fila)\">\n {{ textoCelda(columna, fila, indice) }}\n </span>\n } @else {\n <span [class.td-tabla__numero]=\"columna.tipo === 'numero'\">\n {{ textoCelda(columna, fila, indice) }}\n </span>\n }\n </div>\n }\n\n @if (acciones.length) {\n <div class=\"td-tabla__acciones-fila\" role=\"cell\">\n @for (accionFila of accionesVisibles(fila); track accionFila.id) {\n <button\n type=\"button\"\n [class]=\"'td-tabla__accion td-tabla__accion--' + (accionFila.tono || 'neutro')\"\n [title]=\"accionFila.etiqueta\"\n [disabled]=\"accionFila.deshabilitada?.(fila) ?? false\"\n (click)=\"ejecutarAccion(accionFila, fila, indice)\"\n >\n <td-icon [nombre]=\"accionFila.icono\" />\n <span class=\"td-tabla__sr-only\">{{ accionFila.etiqueta }}</span>\n </button>\n }\n </div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n } @else if (!cargando) {\n <div class=\"td-tabla__vacio\">\n <span><td-icon nombre=\"inbox\" tamano=\"2.4rem\" /></span>\n <h3>{{ textoVacio }}</h3>\n <p>{{ descripcionVacio }}</p>\n </div>\n }\n\n @if (cargando && !datos.length) {\n <div class=\"td-tabla__skeleton\">\n @for (item of [1, 2, 3, 4, 5]; track item) {\n <span></span>\n }\n </div>\n }\n </div>\n</section>\n", styles: [":host{display:block}*{box-sizing:border-box}.td-tabla{--fondo: #fff;--fondo-suave: #f8fafc;--borde: #e4e8f0;--texto: #263147;--suave: #748096;--hover: #f7f8fc;--acento: #5746d8;color:var(--texto);font-family:Inter,ui-sans-serif,system-ui,sans-serif}.td-tabla--oscura{--fondo: #15151b;--fondo-suave: #1b1b22;--borde: #2d2d36;--texto: #ededf0;--suave: #9393a0;--hover: #202028;--acento: #a89cf7}.td-tabla__toolbar{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding-bottom:.85rem}.td-tabla__filtros{display:flex;min-width:0;flex:1;flex-wrap:wrap;align-items:center;gap:.65rem}.td-tabla__filtros ::ng-deep [tdDataTableFilters]{height:2.55rem;min-width:10.5rem;border:1px solid var(--borde);border-radius:.75rem;padding:0 .8rem;color:var(--texto);background-color:var(--fondo);font:600 .75rem/1 Inter,ui-sans-serif,system-ui,sans-serif;outline:none;transition:border-color .14s ease,box-shadow .14s ease,background-color .14s ease}.td-tabla__filtros ::ng-deep [tdDataTableFilters]:hover{border-color:color-mix(in srgb,var(--acento) 42%,var(--borde))}.td-tabla__filtros ::ng-deep [tdDataTableFilters]:focus{border-color:var(--acento);box-shadow:0 0 0 3px color-mix(in srgb,var(--acento) 15%,transparent)}.td-tabla__filtros ::ng-deep select[tdDataTableFilters]{appearance:none;padding-right:2.45rem;background-image:linear-gradient(45deg,transparent 50%,var(--suave) 50%),linear-gradient(135deg,var(--suave) 50%,transparent 50%);background-position:calc(100% - 1rem) 50%,calc(100% - .72rem) 50%;background-repeat:no-repeat;background-size:.3rem .3rem,.3rem .3rem;cursor:pointer}.td-tabla__filtros ::ng-deep input[type=date][tdDataTableFilters]{min-width:9.8rem;color-scheme:light;cursor:pointer}.td-tabla--oscura .td-tabla__filtros ::ng-deep input[type=date][tdDataTableFilters]{color-scheme:dark}.td-tabla__filtros ::ng-deep input[type=date][tdDataTableFilters]::-webkit-calendar-picker-indicator{opacity:.65;cursor:pointer}.td-tabla__filtros ::ng-deep [tdDataTableFilters]:disabled{opacity:.55;cursor:not-allowed}.td-tabla__busqueda{display:flex;width:min(22rem,100%);height:2.55rem;align-items:center;gap:.6rem;border:1px solid var(--borde);border-radius:.75rem;padding:0 .75rem;color:var(--suave);background:var(--fondo)}.td-tabla__busqueda:focus-within{border-color:var(--acento);box-shadow:0 0 0 3px color-mix(in srgb,var(--acento) 15%,transparent)}.td-tabla__busqueda input{min-width:0;flex:1;border:0;appearance:none;outline:0;color:var(--texto);background:transparent;font:inherit;font-size:.78rem}.td-tabla__busqueda input::-webkit-search-cancel-button,.td-tabla__busqueda input::-webkit-search-decoration{appearance:none;display:none}.td-tabla__busqueda input::-ms-clear,.td-tabla__busqueda input::-ms-reveal{display:none;width:0;height:0}.td-tabla__busqueda button{display:grid;place-items:center;border:0;padding:.2rem;color:var(--suave);background:transparent;cursor:pointer}.td-tabla__agregar,.td-tabla__vacio button,.td-tabla__boton{display:inline-flex;height:2.55rem;align-items:center;gap:.45rem;border:0;border-radius:.7rem;padding:0 1rem;color:#fff;background:linear-gradient(135deg,#5746d8,#7657df);box-shadow:0 7px 16px #5746d833;font-size:.75rem;font-weight:750;cursor:pointer}.td-tabla__resumen-acciones{display:flex;align-items:center;gap:.45rem}.td-tabla__boton{height:2.15rem;padding:0 .75rem;box-shadow:none;color:#526077;background:#edf0f5}.td-tabla__boton--primario{color:#fff;background:#5746d8}.td-tabla__boton--exito{color:#fff;background:#168447}.td-tabla__boton--advertencia{color:#fff;background:#b66d05}.td-tabla__boton--peligro{color:#fff;background:#d33f3f}.td-tabla__boton:disabled{opacity:.45;cursor:not-allowed}.td-tabla__superficie{overflow:hidden;border:1px solid var(--borde);border-radius:1rem;background:var(--fondo);box-shadow:0 12px 32px #1f2a440f}.td-tabla__resumen{display:flex;min-height:3rem;align-items:center;justify-content:space-between;border-bottom:1px solid var(--borde);padding:.7rem 1rem;color:var(--suave);background:var(--fondo-suave);font-size:.7rem}.td-tabla__resumen strong{color:var(--texto)}.td-tabla__cargando-inline{display:flex;align-items:center;gap:.4rem}.td-tabla__cargando-inline i{width:.65rem;height:.65rem;border:2px solid var(--borde);border-top-color:var(--acento);border-radius:50%;animation:td-tabla-girar .7s linear infinite}.td-tabla__encabezado,.td-tabla__fila{display:grid;min-width:max-content;align-items:center}.td-tabla__encabezado{position:relative;z-index:2;min-height:2.75rem;border-bottom:1px solid var(--borde);color:var(--suave);background:var(--fondo-suave);font-size:.62rem;font-weight:800;letter-spacing:.075em;text-transform:uppercase}.td-tabla__encabezado>div,.td-tabla__celda{padding:.6rem 1rem}.td-tabla__viewport{width:100%;min-height:12rem}.td-tabla__fila{border-bottom:1px solid var(--borde);transition:background .12s ease}.td-tabla__fila:hover{background:var(--hover)}.td-tabla__celda{overflow:hidden;color:var(--texto);font-size:.75rem;text-overflow:ellipsis;white-space:nowrap}.td-tabla__numero{font-variant-numeric:tabular-nums}.td-tabla__alinear--inicio{text-align:left}.td-tabla__alinear--centro{text-align:center;justify-content:center}.td-tabla__alinear--fin{text-align:right;justify-content:flex-end}.td-tabla__chip{display:inline-flex;border-radius:999px;padding:.25rem .55rem;color:#526077;background:#edf0f5;font-size:.65rem;font-weight:750}.td-tabla__chip--primario{color:#4f46e5;background:#eeecff}.td-tabla__chip--exito{color:#13713a;background:#dff7e8}.td-tabla__chip--advertencia{color:#9a5a05;background:#fff0cf}.td-tabla__chip--peligro{color:#b53434;background:#fee5e5}.td-tabla__acciones-fila{display:flex;align-items:center;justify-content:center;gap:.25rem;padding:0 .7rem}.td-tabla__accion{display:grid;width:2rem;height:2rem;place-items:center;border:0;border-radius:.55rem;color:var(--suave);background:transparent;cursor:pointer}.td-tabla__accion:hover{background:var(--hover);color:var(--acento)}.td-tabla__accion--exito{color:#168447}.td-tabla__accion--peligro{color:#dc3e3e}.td-tabla__accion--advertencia{color:#b66d05}.td-tabla__accion:disabled{opacity:.35;cursor:not-allowed}.td-tabla__vacio{display:grid;min-height:21rem;place-items:center;align-content:center;padding:2rem;text-align:center}.td-tabla__vacio>span{display:grid;width:4.5rem;height:4.5rem;place-items:center;border-radius:1.2rem;color:var(--acento);background:color-mix(in srgb,var(--acento) 10%,transparent)}.td-tabla__vacio h3{margin:1rem 0 .3rem;font-size:1rem}.td-tabla__vacio p{margin:0 0 1.25rem;color:var(--suave);font-size:.75rem}.td-tabla__skeleton{padding:.5rem 1rem}.td-tabla__skeleton span{display:block;height:3.5rem;border-bottom:1px solid var(--borde);background:linear-gradient(90deg,transparent,var(--hover),transparent);background-size:200% 100%;animation:td-tabla-cargar 1.2s linear infinite}.td-tabla__sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}@keyframes td-tabla-girar{to{transform:rotate(360deg)}}@keyframes td-tabla-cargar{to{background-position:-200% 0}}@media(max-width:640px){.td-tabla__toolbar{align-items:stretch;flex-direction:column}.td-tabla__busqueda{width:100%}.td-tabla__resumen{align-items:flex-start;flex-direction:column}.td-tabla__resumen-acciones{width:100%;flex-wrap:wrap}}\n"] }]
660
+ }], propDecorators: { viewport: [{
661
+ type: ViewChild,
662
+ args: [CdkVirtualScrollViewport]
663
+ }], datos: [{
664
+ type: Input
665
+ }], columnas: [{
666
+ type: Input
667
+ }], acciones: [{
668
+ type: Input
669
+ }], botones: [{
670
+ type: Input
671
+ }], total: [{
672
+ type: Input
673
+ }], cargando: [{
674
+ type: Input
675
+ }], puedeCargarMas: [{
676
+ type: Input
677
+ }], itemSize: [{
678
+ type: Input
679
+ }], altura: [{
680
+ type: Input
681
+ }], campoId: [{
682
+ type: Input
683
+ }], oscuro: [{
684
+ type: Input
685
+ }], mostrarBusqueda: [{
686
+ type: Input
687
+ }], mostrarAgregar: [{
688
+ type: Input
689
+ }], placeholderBusqueda: [{
690
+ type: Input
691
+ }], textoAgregar: [{
692
+ type: Input
693
+ }], textoVacio: [{
694
+ type: Input
695
+ }], descripcionVacio: [{
696
+ type: Input
697
+ }], debounceBusqueda: [{
698
+ type: Input
699
+ }], busquedaChange: [{
700
+ type: Output
701
+ }], agregar: [{
702
+ type: Output
703
+ }], accion: [{
704
+ type: Output
705
+ }], botonClick: [{
706
+ type: Output
707
+ }], cargarMas: [{
708
+ type: Output
709
+ }] } });
710
+
711
+ class TdFooter {
712
+ empresa = 'TelcomDev';
713
+ texto = 'Todos los derechos reservados.';
714
+ version = '';
715
+ oscuro = false;
716
+ compacto = false;
717
+ anio = new Date().getFullYear();
718
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TdFooter, deps: [], target: i0.ɵɵFactoryTarget.Component });
719
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: TdFooter, isStandalone: true, selector: "td-footer", inputs: { empresa: "empresa", texto: "texto", version: "version", oscuro: "oscuro", compacto: "compacto", anio: "anio" }, ngImport: i0, template: "<footer\n class=\"td-footer\"\n [class.td-footer--oscuro]=\"oscuro\"\n [class.td-footer--compacto]=\"compacto\"\n>\n <div class=\"td-footer__identidad\">\n <span>\u00A9 {{ anio }} {{ empresa }}</span>\n @if (texto) {\n <small>{{ texto }}</small>\n }\n </div>\n\n <nav class=\"td-footer__enlaces\" aria-label=\"Enlaces del pie de p\u00E1gina\">\n <ng-content select=\"[tdFooterLinks]\" />\n </nav>\n\n <div class=\"td-footer__final\">\n <ng-content select=\"[tdFooterActions]\" />\n @if (version) {\n <span class=\"td-footer__version\">v{{ version }}</span>\n }\n </div>\n</footer>\n", styles: [":host{display:block}*{box-sizing:border-box}.td-footer{--td-footer-fondo: #fff;--td-footer-borde: #e2e8f0;--td-footer-texto: #475569;--td-footer-suave: #94a3b8;display:grid;min-height:4.5rem;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:1rem;border-top:1px solid var(--td-footer-borde);padding:1rem 1.5rem;color:var(--td-footer-texto);background:var(--td-footer-fondo);font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:.75rem}.td-footer--oscuro{--td-footer-fondo: #111116;--td-footer-borde: #29292f;--td-footer-texto: #d4d4d8;--td-footer-suave: #71717a}.td-footer--compacto{min-height:3.25rem;padding-block:.65rem}.td-footer__identidad{display:flex;min-width:0;flex-wrap:wrap;gap:.3rem .75rem;align-items:center}.td-footer__identidad span{font-weight:700}.td-footer__identidad small{color:var(--td-footer-suave);font-size:inherit}.td-footer__enlaces{display:flex;align-items:center;justify-content:center;gap:1rem}.td-footer__final{display:flex;align-items:center;justify-content:flex-end;gap:.75rem}.td-footer__version{border:1px solid var(--td-footer-borde);border-radius:999px;padding:.22rem .55rem;color:var(--td-footer-suave);font:700 .65rem/1 ui-monospace,monospace}@media(max-width:720px){.td-footer{grid-template-columns:1fr;justify-items:center;text-align:center}.td-footer__identidad,.td-footer__final{justify-content:center}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
720
+ }
721
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TdFooter, decorators: [{
722
+ type: Component,
723
+ args: [{ selector: 'td-footer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<footer\n class=\"td-footer\"\n [class.td-footer--oscuro]=\"oscuro\"\n [class.td-footer--compacto]=\"compacto\"\n>\n <div class=\"td-footer__identidad\">\n <span>\u00A9 {{ anio }} {{ empresa }}</span>\n @if (texto) {\n <small>{{ texto }}</small>\n }\n </div>\n\n <nav class=\"td-footer__enlaces\" aria-label=\"Enlaces del pie de p\u00E1gina\">\n <ng-content select=\"[tdFooterLinks]\" />\n </nav>\n\n <div class=\"td-footer__final\">\n <ng-content select=\"[tdFooterActions]\" />\n @if (version) {\n <span class=\"td-footer__version\">v{{ version }}</span>\n }\n </div>\n</footer>\n", styles: [":host{display:block}*{box-sizing:border-box}.td-footer{--td-footer-fondo: #fff;--td-footer-borde: #e2e8f0;--td-footer-texto: #475569;--td-footer-suave: #94a3b8;display:grid;min-height:4.5rem;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:1rem;border-top:1px solid var(--td-footer-borde);padding:1rem 1.5rem;color:var(--td-footer-texto);background:var(--td-footer-fondo);font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:.75rem}.td-footer--oscuro{--td-footer-fondo: #111116;--td-footer-borde: #29292f;--td-footer-texto: #d4d4d8;--td-footer-suave: #71717a}.td-footer--compacto{min-height:3.25rem;padding-block:.65rem}.td-footer__identidad{display:flex;min-width:0;flex-wrap:wrap;gap:.3rem .75rem;align-items:center}.td-footer__identidad span{font-weight:700}.td-footer__identidad small{color:var(--td-footer-suave);font-size:inherit}.td-footer__enlaces{display:flex;align-items:center;justify-content:center;gap:1rem}.td-footer__final{display:flex;align-items:center;justify-content:flex-end;gap:.75rem}.td-footer__version{border:1px solid var(--td-footer-borde);border-radius:999px;padding:.22rem .55rem;color:var(--td-footer-suave);font:700 .65rem/1 ui-monospace,monospace}@media(max-width:720px){.td-footer{grid-template-columns:1fr;justify-items:center;text-align:center}.td-footer__identidad,.td-footer__final{justify-content:center}}\n"] }]
724
+ }], propDecorators: { empresa: [{
725
+ type: Input
726
+ }], texto: [{
727
+ type: Input
728
+ }], version: [{
729
+ type: Input
730
+ }], oscuro: [{
731
+ type: Input
732
+ }], compacto: [{
733
+ type: Input
734
+ }], anio: [{
735
+ type: Input
736
+ }] } });
737
+
551
738
  class TdHeader {
552
739
  menuAbierto = true;
553
740
  mostrarMenu = true;
@@ -738,5 +925,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
738
925
  * Generated bundle index. Do not edit.
739
926
  */
740
927
 
741
- export { TD_ICONOS, TD_ICONOS_NOMBRES, TdAlerta, TdFooter, TdHeader, TdIcon, TdIconoRegistry, TdSidebar, TelcomdevUi };
928
+ export { TD_ICONOS, TD_ICONOS_NOMBRES, TdAlerta, TdDataTable, TdFooter, TdHeader, TdIcon, TdIconoRegistry, TdSidebar, TelcomdevUi };
742
929
  //# sourceMappingURL=telcomdev-ui.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"telcomdev-ui.mjs","sources":["../../../projects/telcomdev-ui/src/lib/telcomdev-ui.ts","../../../projects/telcomdev-ui/src/lib/alerta/td-alerta.ts","../../../projects/telcomdev-ui/src/lib/footer/td-footer.ts","../../../projects/telcomdev-ui/src/lib/footer/td-footer.html","../../../projects/telcomdev-ui/src/lib/iconos/td-iconos.ts","../../../projects/telcomdev-ui/src/lib/iconos/td-icono-registry.ts","../../../projects/telcomdev-ui/src/lib/iconos/td-icon.ts","../../../projects/telcomdev-ui/src/lib/header/td-header.ts","../../../projects/telcomdev-ui/src/lib/header/td-header.html","../../../projects/telcomdev-ui/src/lib/sidebar/td-sidebar.ts","../../../projects/telcomdev-ui/src/lib/sidebar/td-sidebar.html","../../../projects/telcomdev-ui/src/public-api.ts","../../../projects/telcomdev-ui/src/telcomdev-ui.ts"],"sourcesContent":["import { Component } from '@angular/core';\n\n@Component({\n selector: 'td-telcomdev-ui',\n imports: [],\n template: ` <p>telcomdev-ui works!</p> `,\n styles: ``,\n})\nexport class TelcomdevUi {}\n","export type TdAlertaTipo = 'exito' | 'error' | 'advertencia' | 'info' | 'pregunta';\r\n\r\nexport interface TdAlertaOpciones {\r\n titulo?: string;\r\n mensaje?: string;\r\n tipo?: TdAlertaTipo;\r\n textoConfirmar?: string;\r\n textoCancelar?: string;\r\n mostrarCancelar?: boolean;\r\n cerrarConEscape?: boolean;\r\n cerrarConFondo?: boolean;\r\n}\r\n\r\nexport class TdAlerta {\r\n private static readonly estiloId = 'td-alerta-estilos';\r\n\r\n static exito(mensaje: string, titulo = '¡Operación exitosa!'): Promise<boolean> {\r\n return this.mostrar({\r\n titulo,\r\n mensaje,\r\n tipo: 'exito',\r\n textoConfirmar: 'Aceptar',\r\n });\r\n }\r\n\r\n static error(mensaje: string, titulo = '¡Error!'): Promise<boolean> {\r\n return this.mostrar({\r\n titulo,\r\n mensaje,\r\n tipo: 'error',\r\n textoConfirmar: 'Cerrar',\r\n });\r\n }\r\n\r\n static errorSistema(mensaje: string, titulo = '¡Error de Sistema!'): Promise<boolean> {\r\n return this.mostrar({\r\n titulo,\r\n mensaje,\r\n tipo: 'error',\r\n textoConfirmar: 'Cerrar',\r\n });\r\n }\r\n\r\n static advertencia(mensaje: string, titulo = '¡Advertencia!'): Promise<boolean> {\r\n return this.mostrar({\r\n titulo,\r\n mensaje,\r\n tipo: 'advertencia',\r\n textoConfirmar: 'Aceptar',\r\n });\r\n }\r\n\r\n static info(mensaje: string, titulo = 'Información'): Promise<boolean> {\r\n return this.mostrar({\r\n titulo,\r\n mensaje,\r\n tipo: 'info',\r\n textoConfirmar: 'Aceptar',\r\n });\r\n }\r\n\r\n static confirmar(\r\n mensaje: string,\r\n titulo = '¿Estás seguro?',\r\n textoConfirmar = 'Sí, continuar',\r\n textoCancelar = 'Cancelar'\r\n ): Promise<boolean> {\r\n return this.mostrar({\r\n titulo,\r\n mensaje,\r\n tipo: 'pregunta',\r\n textoConfirmar,\r\n textoCancelar,\r\n mostrarCancelar: true,\r\n });\r\n }\r\n\r\n static confirmarEliminar(\r\n mensaje = 'Esta acción no se puede deshacer.',\r\n titulo = '¿Eliminar registro?'\r\n ): Promise<boolean> {\r\n return this.mostrar({\r\n titulo,\r\n mensaje,\r\n tipo: 'advertencia',\r\n textoConfirmar: 'Sí, eliminar',\r\n textoCancelar: 'Cancelar',\r\n mostrarCancelar: true,\r\n });\r\n }\r\n\r\n static mostrar(opciones: TdAlertaOpciones): Promise<boolean> {\r\n if (typeof document === 'undefined') {\r\n return Promise.resolve(false);\r\n }\r\n\r\n this.inyectarEstilos();\r\n\r\n const config: Required<TdAlertaOpciones> = {\r\n titulo: opciones.titulo ?? '',\r\n mensaje: opciones.mensaje ?? '',\r\n tipo: opciones.tipo ?? 'info',\r\n textoConfirmar: opciones.textoConfirmar ?? 'Aceptar',\r\n textoCancelar: opciones.textoCancelar ?? 'Cancelar',\r\n mostrarCancelar: opciones.mostrarCancelar ?? false,\r\n cerrarConEscape: opciones.cerrarConEscape ?? true,\r\n cerrarConFondo: opciones.cerrarConFondo ?? false,\r\n };\r\n\r\n return new Promise<boolean>((resolve) => {\r\n const fondo = document.createElement('div');\r\n fondo.className = 'td-alerta-fondo';\r\n\r\n const modal = document.createElement('div');\r\n modal.className = 'td-alerta-modal';\r\n modal.setAttribute('role', 'dialog');\r\n modal.setAttribute('aria-modal', 'true');\r\n\r\n const icono = document.createElement('div');\r\n icono.className = `td-alerta-icono td-alerta-icono--${config.tipo}`;\r\n icono.textContent = this.obtenerIcono(config.tipo);\r\n\r\n const titulo = document.createElement('h2');\r\n titulo.className = 'td-alerta-titulo';\r\n titulo.textContent = config.titulo;\r\n\r\n const mensaje = document.createElement('p');\r\n mensaje.className = 'td-alerta-mensaje';\r\n mensaje.textContent = config.mensaje;\r\n\r\n const acciones = document.createElement('div');\r\n acciones.className = 'td-alerta-acciones';\r\n\r\n const botonConfirmar = document.createElement('button');\r\n botonConfirmar.type = 'button';\r\n botonConfirmar.className = `td-alerta-boton td-alerta-boton--${config.tipo}`;\r\n botonConfirmar.textContent = config.textoConfirmar;\r\n\r\n const botonCancelar = document.createElement('button');\r\n botonCancelar.type = 'button';\r\n botonCancelar.className = 'td-alerta-boton td-alerta-boton--cancelar';\r\n botonCancelar.textContent = config.textoCancelar;\r\n\r\n const cerrar = (resultado: boolean): void => {\r\n document.removeEventListener('keydown', onKeyDown);\r\n fondo.classList.add('td-alerta-saliendo');\r\n\r\n window.setTimeout(() => {\r\n fondo.remove();\r\n resolve(resultado);\r\n }, 140);\r\n };\r\n\r\n const onKeyDown = (event: KeyboardEvent): void => {\r\n if (event.key === 'Escape' && config.cerrarConEscape) {\r\n cerrar(false);\r\n }\r\n };\r\n\r\n botonConfirmar.addEventListener('click', () => cerrar(true));\r\n botonCancelar.addEventListener('click', () => cerrar(false));\r\n\r\n if (config.cerrarConFondo) {\r\n fondo.addEventListener('click', (event) => {\r\n if (event.target === fondo) {\r\n cerrar(false);\r\n }\r\n });\r\n }\r\n\r\n document.addEventListener('keydown', onKeyDown);\r\n\r\n if (config.mostrarCancelar) {\r\n acciones.appendChild(botonCancelar);\r\n }\r\n\r\n acciones.appendChild(botonConfirmar);\r\n\r\n modal.appendChild(icono);\r\n modal.appendChild(titulo);\r\n\r\n if (config.mensaje) {\r\n modal.appendChild(mensaje);\r\n }\r\n\r\n modal.appendChild(acciones);\r\n fondo.appendChild(modal);\r\n document.body.appendChild(fondo);\r\n\r\n botonConfirmar.focus();\r\n });\r\n }\r\n\r\n private static obtenerIcono(tipo: TdAlertaTipo): string {\r\n const iconos: Record<TdAlertaTipo, string> = {\r\n exito: '✓',\r\n error: '!',\r\n advertencia: '!',\r\n info: 'i',\r\n pregunta: '?',\r\n };\r\n\r\n return iconos[tipo];\r\n }\r\n\r\n private static inyectarEstilos(): void {\r\n if (document.getElementById(this.estiloId)) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = this.estiloId;\r\n style.textContent = `\r\n .td-alerta-fondo {\r\n position: fixed;\r\n inset: 0;\r\n z-index: 99999;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 1rem;\r\n background: rgba(15, 23, 42, 0.52);\r\n animation: td-alerta-fondo-entrada 160ms ease-out;\r\n }\r\n\r\n .td-alerta-modal {\r\n width: min(100%, 430px);\r\n border-radius: 18px;\r\n background: #ffffff;\r\n padding: 1.75rem;\r\n text-align: center;\r\n box-shadow: 0 22px 70px rgba(15, 23, 42, 0.28);\r\n animation: td-alerta-modal-entrada 180ms ease-out;\r\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\r\n }\r\n\r\n .td-alerta-icono {\r\n width: 4.25rem;\r\n height: 4.25rem;\r\n margin: 0 auto 1rem;\r\n border-radius: 999px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 2.1rem;\r\n font-weight: 800;\r\n }\r\n\r\n .td-alerta-icono--exito {\r\n color: #16a34a;\r\n background: #dcfce7;\r\n }\r\n\r\n .td-alerta-icono--error {\r\n color: #ef4444;\r\n background: #fee2e2;\r\n }\r\n\r\n .td-alerta-icono--advertencia {\r\n color: #f59e0b;\r\n background: #fef3c7;\r\n }\r\n\r\n .td-alerta-icono--info {\r\n color: #2563eb;\r\n background: #dbeafe;\r\n }\r\n\r\n .td-alerta-icono--pregunta {\r\n color: #7c3aed;\r\n background: #ede9fe;\r\n }\r\n\r\n .td-alerta-titulo {\r\n margin: 0;\r\n color: #111827;\r\n font-size: 1.35rem;\r\n line-height: 1.25;\r\n font-weight: 800;\r\n }\r\n\r\n .td-alerta-mensaje {\r\n margin: 0.75rem 0 0;\r\n color: #4b5563;\r\n font-size: 0.96rem;\r\n line-height: 1.55;\r\n }\r\n\r\n .td-alerta-acciones {\r\n display: flex;\r\n justify-content: center;\r\n gap: 0.75rem;\r\n margin-top: 1.5rem;\r\n }\r\n\r\n .td-alerta-boton {\r\n border: 0;\r\n border-radius: 10px;\r\n padding: 0.7rem 1.2rem;\r\n color: #ffffff;\r\n font-size: 0.93rem;\r\n font-weight: 700;\r\n cursor: pointer;\r\n transition: transform 120ms ease, filter 120ms ease, background 120ms ease;\r\n }\r\n\r\n .td-alerta-boton:hover {\r\n filter: brightness(0.96);\r\n }\r\n\r\n .td-alerta-boton:active {\r\n transform: scale(0.98);\r\n }\r\n\r\n .td-alerta-boton:focus {\r\n outline: 3px solid rgba(37, 99, 235, 0.25);\r\n outline-offset: 2px;\r\n }\r\n\r\n .td-alerta-boton--exito {\r\n background: #22c55e;\r\n }\r\n\r\n .td-alerta-boton--error {\r\n background: #ef4444;\r\n }\r\n\r\n .td-alerta-boton--advertencia {\r\n background: #f59e0b;\r\n }\r\n\r\n .td-alerta-boton--info {\r\n background: #2563eb;\r\n }\r\n\r\n .td-alerta-boton--pregunta {\r\n background: #7c3aed;\r\n }\r\n\r\n .td-alerta-boton--cancelar {\r\n background: #6b7280;\r\n }\r\n\r\n .td-alerta-saliendo {\r\n animation: td-alerta-fondo-salida 140ms ease-in forwards;\r\n }\r\n\r\n .td-alerta-saliendo .td-alerta-modal {\r\n animation: td-alerta-modal-salida 140ms ease-in forwards;\r\n }\r\n\r\n @keyframes td-alerta-fondo-entrada {\r\n from { opacity: 0; }\r\n to { opacity: 1; }\r\n }\r\n\r\n @keyframes td-alerta-modal-entrada {\r\n from {\r\n opacity: 0;\r\n transform: translateY(12px) scale(0.96);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0) scale(1);\r\n }\r\n }\r\n\r\n @keyframes td-alerta-fondo-salida {\r\n from { opacity: 1; }\r\n to { opacity: 0; }\r\n }\r\n\r\n @keyframes td-alerta-modal-salida {\r\n from {\r\n opacity: 1;\r\n transform: translateY(0) scale(1);\r\n }\r\n to {\r\n opacity: 0;\r\n transform: translateY(8px) scale(0.97);\r\n }\r\n }\r\n\r\n @media (max-width: 480px) {\r\n .td-alerta-modal {\r\n padding: 1.4rem;\r\n border-radius: 16px;\r\n }\r\n\r\n .td-alerta-acciones {\r\n flex-direction: column-reverse;\r\n }\r\n\r\n .td-alerta-boton {\r\n width: 100%;\r\n }\r\n }\r\n `;\r\n\r\n document.head.appendChild(style);\r\n }\r\n}","import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\n\n@Component({\n selector: 'td-footer',\n templateUrl: './td-footer.html',\n styleUrl: './td-footer.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class TdFooter {\n @Input() empresa = 'TelcomDev';\n @Input() texto = 'Todos los derechos reservados.';\n @Input() version = '';\n @Input() oscuro = false;\n @Input() compacto = false;\n @Input() anio = new Date().getFullYear();\n}\n","<footer\n class=\"td-footer\"\n [class.td-footer--oscuro]=\"oscuro\"\n [class.td-footer--compacto]=\"compacto\"\n>\n <div class=\"td-footer__identidad\">\n <span>© {{ anio }} {{ empresa }}</span>\n @if (texto) {\n <small>{{ texto }}</small>\n }\n </div>\n\n <nav class=\"td-footer__enlaces\" aria-label=\"Enlaces del pie de página\">\n <ng-content select=\"[tdFooterLinks]\" />\n </nav>\n\n <div class=\"td-footer__final\">\n <ng-content select=\"[tdFooterActions]\" />\n @if (version) {\n <span class=\"td-footer__version\">v{{ version }}</span>\n }\n </div>\n</footer>\n","import { TdIconoDefinicion } from './td-icono.model';\n\nexport const TD_ICONOS = {\n home: {\n path: 'M3 10.5 12 3l9 7.5V21a1 1 0 0 1-1 1h-5v-7H9v7H4a1 1 0 0 1-1-1V10.5Z',\n },\n dashboard: {\n path: 'M4 3h6a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1Zm10 0h6a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1Zm0 8h6a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1v-8a1 1 0 0 1 1-1ZM4 14h6a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-5a1 1 0 0 1 1-1Z',\n },\n folder: {\n path: 'M3 5a2 2 0 0 1 2-2h5l2 2h7a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5Z',\n },\n settings: {\n path: 'M12 8.5a3.5 3.5 0 1 0 0 7 3.5 3.5 0 0 0 0-7Zm8.5 3.5c0-.5-.05-.98-.14-1.45l2.02-1.57-2-3.46-2.47 1a8.7 8.7 0 0 0-2.5-1.45L15 2.5h-4l-.4 2.57a8.7 8.7 0 0 0-2.51 1.45l-2.47-1-2 3.46 2.02 1.57a7.7 7.7 0 0 0 0 2.9l-2.02 1.57 2 3.46 2.47-1a8.7 8.7 0 0 0 2.5 1.45L11 21.5h4l.4-2.57a8.7 8.7 0 0 0 2.51-1.45l2.47 1 2-3.46-2.02-1.57c.09-.47.14-.95.14-1.45Z',\n },\n people: {\n path: 'M16 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8ZM6.5 12a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7ZM16 13c-4 0-7 2-7 4.5V21h14v-3.5C23 15 20 13 16 13ZM6.5 14C2.9 14 1 15.8 1 18v3h6v-3.5c0-1.2.48-2.28 1.3-3.16A9.3 9.3 0 0 0 6.5 14Z',\n },\n person: {\n path: 'M12 12a5 5 0 1 0 0-10 5 5 0 0 0 0 10Zm0 2c-5 0-9 2.5-9 5.5V22h18v-2.5c0-3-4-5.5-9-5.5Z',\n },\n security: {\n path: 'M12 2 4 5v6c0 5.05 3.41 9.74 8 11 4.59-1.26 8-5.95 8-11V5l-8-3Zm-1 14-4-4 1.4-1.4 2.6 2.58 5.6-5.58L18 9l-7 7Z',\n },\n inventory: {\n path: 'm12 2 9 5-9 5-9-5 9-5Zm-7 8.5 6 3.33V22l-6-3.33V10.5Zm8 11.5v-8.17l6-3.33v8.17L13 22Z',\n },\n shopping_cart: {\n path: 'M7 18a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm10 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4ZM6.2 6l.8 2h11.6l-1.9 5H8.1L4.3 3H1v2h2l3.6 9.6A2 2 0 0 0 8.5 16H19v-2H8.5l-.4-1H18a2 2 0 0 0 1.86-1.27L22 6H6.2Z',\n },\n receipt: {\n path: 'M5 2v20l3-2 4 2 4-2 3 2V2l-3 2-4-2-4 2-3-2Zm3 6h8v2H8V8Zm0 4h8v2H8v-2Z',\n },\n assessment: {\n path: 'M4 20h16v2H4a2 2 0 0 1-2-2V4h2v16Zm3-2H5v-6h2v6Zm4 0H9V7h2v11Zm4 0h-2V4h2v14Zm4 0h-2v-9h2v9Z',\n },\n description: {\n path: 'M6 2h8l5 5v15H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2Zm7 1.5V8h4.5L13 3.5ZM8 12v2h8v-2H8Zm0 4v2h8v-2H8Z',\n },\n business: {\n path: 'M3 21V3h10v5h8v13h-7v-4h-2v4H3Zm3-14h2V5H6v2Zm4 0h2V5h-2v2Zm-4 4h2V9H6v2Zm4 0h2V9h-2v2Zm6 1h2v-2h-2v2Zm0 4h2v-2h-2v2Z',\n },\n chevron_left: {\n path: 'M14.7 5.3a1 1 0 0 1 0 1.4L9.4 12l5.3 5.3a1 1 0 1 1-1.4 1.4l-6-6a1 1 0 0 1 0-1.4l6-6a1 1 0 0 1 1.4 0Z',\n },\n chevron_right: {\n path: 'M9.3 5.3a1 1 0 0 0 0 1.4l5.3 5.3-5.3 5.3a1 1 0 1 0 1.4 1.4l6-6a1 1 0 0 0 0-1.4l-6-6a1 1 0 0 0-1.4 0Z',\n },\n sun: {\n path: 'M12 7a5 5 0 1 0 0 10 5 5 0 0 0 0-10Zm0-5a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0V3a1 1 0 0 1 1-1Zm0 17a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0v-2a1 1 0 0 1 1-1ZM2 12a1 1 0 0 1 1-1h2a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Zm17 0a1 1 0 0 1 1-1h2a1 1 0 1 1 0 2h-2a1 1 0 0 1-1-1ZM4.22 4.22a1 1 0 0 1 1.42 0l1.41 1.42a1 1 0 0 1-1.41 1.41L4.22 5.64a1 1 0 0 1 0-1.42Zm12.73 12.73a1 1 0 0 1 1.41 0l1.42 1.41a1 1 0 0 1-1.42 1.42l-1.41-1.42a1 1 0 0 1 0-1.41Zm2.83-12.73a1 1 0 0 1 0 1.42l-1.42 1.41a1 1 0 0 1-1.41-1.41l1.41-1.42a1 1 0 0 1 1.42 0ZM7.05 16.95a1 1 0 0 1 0 1.41l-1.41 1.42a1 1 0 0 1-1.42-1.42l1.42-1.41a1 1 0 0 1 1.41 0Z',\n },\n moon: {\n path: 'M20.5 15.2A8.5 8.5 0 0 1 8.8 3.5 9 9 0 1 0 20.5 15.2Z',\n },\n alert: {\n path: 'M12 2 1 21h22L12 2Zm-1 7h2v6h-2V9Zm0 8h2v2h-2v-2Z',\n },\n check: {\n path: 'm9.2 16.2-4.4-4.4-1.6 1.6 6 6L21 7.6 19.4 6 9.2 16.2Z',\n },\n close: {\n path: 'M6.4 5 12 10.6 17.6 5 19 6.4 13.4 12l5.6 5.6-1.4 1.4-5.6-5.6L6.4 19 5 17.6l5.6-5.6L5 6.4 6.4 5Z',\n },\n menu: {\n path: 'M3 6h18v2H3V6Zm0 5h18v2H3v-2Zm0 5h18v2H3v-2Z',\n },\n search: {\n path: 'M10.5 3a7.5 7.5 0 1 0 4.73 13.32L20.91 22 22 20.91l-5.68-5.68A7.5 7.5 0 0 0 10.5 3Zm0 2a5.5 5.5 0 1 1 0 11 5.5 5.5 0 0 1 0-11Z',\n },\n notifications: {\n path: 'M12 22a2.5 2.5 0 0 0 2.45-2h-4.9A2.5 2.5 0 0 0 12 22Zm7-6v-5a7 7 0 0 0-5.5-6.84V3a1.5 1.5 0 0 0-3 0v1.16A7 7 0 0 0 5 11v5l-2 2v1h18v-1l-2-2Z',\n },\n chevron_down: {\n path: 'M5.3 8.3a1 1 0 0 1 1.4 0l5.3 5.3 5.3-5.3a1 1 0 1 1 1.4 1.4l-6 6a1 1 0 0 1-1.4 0l-6-6a1 1 0 0 1 0-1.4Z',\n },\n apps: {\n path: 'M4 3h4a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1Zm12 0h4a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1ZM4 15h4a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1Zm12 0h4a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1Z',\n },\n help: {\n path: 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm0 18a8 8 0 1 1 0-16 8 8 0 0 1 0 16Zm0-4.5a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5Zm.2-9.5c-2 0-3.37 1.03-3.7 2.75l1.95.4c.17-.84.77-1.3 1.67-1.3 1 0 1.63.52 1.63 1.35 0 .67-.33 1.03-1.27 1.58-1.12.65-1.48 1.27-1.48 2.47V14h2v-.55c0-.67.2-.94 1.12-1.5 1.18-.72 1.88-1.58 1.88-2.9C16 7.25 14.5 6 12.2 6Z',\n },\n} satisfies Record<string, TdIconoDefinicion>;\n\nexport type TdIconoNombre = keyof typeof TD_ICONOS;\n\nexport const TD_ICONOS_NOMBRES = Object.freeze(\n Object.keys(TD_ICONOS) as TdIconoNombre[]\n);\n","import { Injectable } from '@angular/core';\nimport { TdIconoDefinicion, TdIconoPersonalizado } from './td-icono.model';\nimport { TD_ICONOS } from './td-iconos';\n\n@Injectable({ providedIn: 'root' })\nexport class TdIconoRegistry {\n private readonly iconos = new Map<string, TdIconoDefinicion>(\n Object.entries(TD_ICONOS)\n );\n\n registrar(iconos: TdIconoPersonalizado): void {\n for (const [nombre, definicion] of Object.entries(iconos)) {\n const clave = this.normalizar(nombre);\n if (!clave) continue;\n\n this.iconos.set(\n clave,\n typeof definicion === 'string' ? { path: definicion } : definicion\n );\n }\n }\n\n obtener(nombre: string | null | undefined): TdIconoDefinicion {\n return this.iconos.get(this.normalizar(nombre)) ?? this.iconos.get('folder')!;\n }\n\n existe(nombre: string): boolean {\n return this.iconos.has(this.normalizar(nombre));\n }\n\n nombres(): string[] {\n return [...this.iconos.keys()];\n }\n\n private normalizar(nombre: string | null | undefined): string {\n return (nombre ?? '').trim().toLowerCase();\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n HostBinding,\n Input,\n inject,\n} from '@angular/core';\nimport { TdIconoRegistry } from './td-icono-registry';\n\n@Component({\n selector: 'td-icon',\n template: `\n <svg\n [attr.viewBox]=\"definicion().viewBox || '0 0 24 24'\"\n [attr.aria-hidden]=\"titulo ? null : 'true'\"\n [attr.aria-label]=\"titulo || null\"\n [attr.role]=\"titulo ? 'img' : null\"\n focusable=\"false\"\n >\n <path [attr.d]=\"definicion().path\" />\n </svg>\n `,\n styles: `\n :host {\n display: inline-flex;\n width: var(--td-icon-size, 1.25rem);\n height: var(--td-icon-size, 1.25rem);\n flex: 0 0 auto;\n color: inherit;\n line-height: 0;\n vertical-align: middle;\n }\n svg { width: 100%; height: 100%; fill: currentColor; }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class TdIcon {\n private readonly registry = inject(TdIconoRegistry);\n\n @Input() nombre = 'folder';\n @Input() titulo = '';\n\n @Input()\n set tamano(value: string | number) {\n this.tamanoCss = typeof value === 'number' ? `${value}px` : value;\n }\n\n protected tamanoCss = '1.25rem';\n\n @HostBinding('style.--td-icon-size')\n protected get tamanoHost(): string {\n return this.tamanoCss;\n }\n\n protected definicion() {\n return this.registry.obtener(this.nombre);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n HostListener,\n Input,\n Output,\n} from '@angular/core';\nimport { TdIcon } from '../iconos';\n\nexport interface TdHeaderNotificacion {\n id: string | number;\n titulo: string;\n descripcion?: string;\n fecha?: string;\n icono?: string;\n leida?: boolean;\n}\n\nexport type TdHeaderAccionPerfil = 'perfil' | 'configuracion' | 'salir';\n\n@Component({\n selector: 'td-header',\n imports: [TdIcon],\n templateUrl: './td-header.html',\n styleUrl: './td-header.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class TdHeader {\n @Input() menuAbierto = true;\n @Input() mostrarMenu = true;\n @Input() usuario = '';\n @Input() cargo = '';\n @Input() avatarUrl = '';\n @Input() notificaciones: TdHeaderNotificacion[] = [];\n @Input() oscuro = false;\n @Input() fijo = true;\n\n @Output() readonly menuToggle = new EventEmitter<void>();\n @Output() readonly notificacionSeleccionada = new EventEmitter<TdHeaderNotificacion>();\n @Output() readonly verTodasNotificaciones = new EventEmitter<void>();\n @Output() readonly accionPerfil = new EventEmitter<TdHeaderAccionPerfil>();\n\n protected panelNotificacionesAbierto = false;\n protected panelPerfilAbierto = false;\n\n protected alternarMenu(): void {\n this.menuToggle.emit();\n }\n\n protected alternarNotificaciones(): void {\n this.panelNotificacionesAbierto = !this.panelNotificacionesAbierto;\n this.panelPerfilAbierto = false;\n }\n\n protected alternarPerfil(): void {\n this.panelPerfilAbierto = !this.panelPerfilAbierto;\n this.panelNotificacionesAbierto = false;\n }\n\n protected seleccionarNotificacion(notificacion: TdHeaderNotificacion): void {\n this.notificacionSeleccionada.emit(notificacion);\n this.panelNotificacionesAbierto = false;\n }\n\n protected emitirAccionPerfil(accion: TdHeaderAccionPerfil): void {\n this.accionPerfil.emit(accion);\n this.panelPerfilAbierto = false;\n }\n\n protected notificacionesNoLeidas(): number {\n return this.notificaciones.filter((item) => !item.leida).length;\n }\n\n protected inicialesUsuario(): string {\n const partes = this.usuario.trim().split(/\\s+/).filter(Boolean);\n return (\n partes\n .slice(0, 2)\n .map((parte) => parte.charAt(0))\n .join('') || 'U'\n ).toUpperCase();\n }\n\n @HostListener('document:keydown.escape')\n protected cerrarConEscape(): void {\n this.panelNotificacionesAbierto = false;\n this.panelPerfilAbierto = false;\n }\n}\n","<header\n class=\"td-header\"\n [class.td-header--oscuro]=\"oscuro\"\n [class.td-header--fijo]=\"fijo\"\n>\n <div class=\"td-header__inicio\">\n @if (mostrarMenu) {\n <button\n class=\"td-header__boton td-header__menu\"\n type=\"button\"\n [attr.aria-label]=\"menuAbierto ? 'Cerrar sidebar' : 'Abrir sidebar'\"\n [attr.aria-expanded]=\"menuAbierto\"\n (click)=\"alternarMenu()\"\n >\n <td-icon [nombre]=\"menuAbierto ? 'close' : 'menu'\" />\n </button>\n }\n\n <ng-content select=\"[tdHeaderStart]\" />\n </div>\n\n <div class=\"td-header__centro\">\n <ng-content select=\"[tdHeaderCenter]\" />\n </div>\n\n <div class=\"td-header__acciones\">\n <ng-content select=\"[tdHeaderActions]\" />\n\n <div class=\"td-header__desplegable\">\n <button\n class=\"td-header__boton td-header__notificaciones\"\n type=\"button\"\n aria-label=\"Notificaciones\"\n [attr.aria-expanded]=\"panelNotificacionesAbierto\"\n (click)=\"alternarNotificaciones()\"\n >\n <td-icon nombre=\"notifications\" />\n @if (notificacionesNoLeidas() > 0) {\n <span>{{ notificacionesNoLeidas() > 99 ? '99+' : notificacionesNoLeidas() }}</span>\n }\n </button>\n\n @if (panelNotificacionesAbierto) {\n <section class=\"td-header__panel td-header__panel--notificaciones\">\n <header>\n <div>\n <strong>Notificaciones</strong>\n <small>{{ notificacionesNoLeidas() }} sin leer</small>\n </div>\n <td-icon nombre=\"notifications\" />\n </header>\n\n <div class=\"td-header__lista-notificaciones\">\n @for (notificacion of notificaciones; track notificacion.id) {\n <button\n type=\"button\"\n [class.td-header__notificacion--nueva]=\"!notificacion.leida\"\n (click)=\"seleccionarNotificacion(notificacion)\"\n >\n <span class=\"td-header__notificacion-icono\">\n <td-icon [nombre]=\"notificacion.icono || 'notifications'\" />\n </span>\n <span>\n <strong>{{ notificacion.titulo }}</strong>\n @if (notificacion.descripcion) {\n <small>{{ notificacion.descripcion }}</small>\n }\n @if (notificacion.fecha) {\n <time>{{ notificacion.fecha }}</time>\n }\n </span>\n </button>\n } @empty {\n <p class=\"td-header__vacio\">No tienes notificaciones.</p>\n }\n </div>\n\n @if (notificaciones.length) {\n <button\n class=\"td-header__ver-todas\"\n type=\"button\"\n (click)=\"verTodasNotificaciones.emit(); panelNotificacionesAbierto = false\"\n >\n Ver todas las notificaciones\n </button>\n }\n </section>\n }\n </div>\n\n @if (usuario) {\n <span class=\"td-header__separador\" aria-hidden=\"true\"></span>\n\n <div class=\"td-header__desplegable\">\n <button\n class=\"td-header__perfil\"\n type=\"button\"\n aria-label=\"Abrir perfil de usuario\"\n [attr.aria-expanded]=\"panelPerfilAbierto\"\n (click)=\"alternarPerfil()\"\n >\n <span class=\"td-header__avatar\">\n @if (avatarUrl) {\n <img [src]=\"avatarUrl\" [alt]=\"usuario\" />\n } @else {\n {{ inicialesUsuario() }}\n }\n </span>\n <span class=\"td-header__usuario\">\n <strong>{{ usuario }}</strong>\n @if (cargo) {\n <small>{{ cargo }}</small>\n }\n </span>\n <td-icon nombre=\"chevron_down\" tamano=\"0.85rem\" />\n </button>\n\n @if (panelPerfilAbierto) {\n <section class=\"td-header__panel td-header__panel--perfil\">\n <div class=\"td-header__perfil-resumen\">\n <span class=\"td-header__avatar td-header__avatar--grande\">{{ inicialesUsuario() }}</span>\n <div>\n <strong>{{ usuario }}</strong>\n <small>{{ cargo || 'Usuario' }}</small>\n </div>\n </div>\n <div class=\"td-header__perfil-opciones\">\n <button type=\"button\" (click)=\"emitirAccionPerfil('perfil')\">\n <td-icon nombre=\"person\" /> Mi perfil\n </button>\n <button type=\"button\" (click)=\"emitirAccionPerfil('configuracion')\">\n <td-icon nombre=\"settings\" /> Configuración\n </button>\n <button class=\"td-header__salir\" type=\"button\" (click)=\"emitirAccionPerfil('salir')\">\n <td-icon nombre=\"close\" /> Cerrar sesión\n </button>\n </div>\n </section>\n }\n </div>\n }\n </div>\n</header>\n","import {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n Input,\n Output,\n signal,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { RouterLink, RouterLinkActive } from '@angular/router';\nimport { TdIcon } from '../iconos';\nimport { MenuSidebar, TdSidebarSeleccion } from './menu-sidebar';\n\nexport type TdSidebarModoCerrado = 'compacto' | 'oculto';\n\n@Component({\n selector: 'td-sidebar',\n imports: [NgTemplateOutlet, RouterLink, RouterLinkActive, TdIcon],\n templateUrl: './td-sidebar.html',\n styleUrl: './td-sidebar.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class TdSidebar {\n @Input() titulo = 'Gestión Corporativa';\n @Input() subtitulo = 'Central Platform';\n @Input() etiquetaNavegacion = 'Navegación';\n @Input() logoUrl = '';\n @Input() logoAlt = 'Logo';\n @Input() textoCarga = 'Cargando menú...';\n @Input() mensajeVacio = 'No hay opciones disponibles.';\n @Input() error = '';\n @Input() cargando = false;\n @Input() oscuro = false;\n @Input() modoCerrado: TdSidebarModoCerrado = 'compacto';\n\n @Input()\n set abierto(value: boolean) {\n this.abiertoInterno.set(value);\n }\n get abierto(): boolean {\n return this.abiertoInterno();\n }\n\n @Input()\n set menu(value: MenuSidebar[] | null | undefined) {\n this.menuNormalizado.set(this.normalizarMenu(value ?? []));\n }\n get menu(): MenuSidebar[] {\n return this.menuNormalizado();\n }\n\n @Output() readonly abiertoChange = new EventEmitter<boolean>();\n @Output() readonly seleccionar = new EventEmitter<TdSidebarSeleccion>();\n\n protected readonly abiertoInterno = signal(true);\n protected readonly menuNormalizado = signal<MenuSidebar[]>([]);\n protected readonly expandidos = signal<ReadonlySet<string>>(new Set<string>());\n\n protected alternarGrupo(clave: string): void {\n if (!this.abiertoInterno()) {\n this.abiertoInterno.set(true);\n this.abiertoChange.emit(true);\n }\n\n this.expandidos.update((actuales) => {\n const siguientes = new Set(actuales);\n siguientes.has(clave) ? siguientes.delete(clave) : siguientes.add(clave);\n return siguientes;\n });\n }\n\n protected estaExpandido(clave: string): boolean {\n return this.expandidos().has(clave);\n }\n\n protected seleccionarItem(item: MenuSidebar, nivel: number): void {\n this.seleccionar.emit({ item, nivel });\n }\n\n protected claveItem(item: MenuSidebar, padre: string, indice: number): string {\n return `${padre}/${item.nombre}-${indice}`;\n }\n\n protected inicialMarca(): string {\n return (this.titulo.trim().charAt(0) || 'T').toUpperCase();\n }\n\n private normalizarMenu(items: MenuSidebar[]): MenuSidebar[] {\n return [...items]\n .sort((a, b) => a.orden - b.orden)\n .map((item) => ({\n ...item,\n icono: item.icono?.trim() || 'folder',\n subMenus: this.normalizarMenu(item.subMenus ?? []),\n }));\n }\n}\n","<aside\n class=\"td-sidebar\"\n [class.td-sidebar--compacto]=\"!abiertoInterno() && modoCerrado === 'compacto'\"\n [class.td-sidebar--oculto]=\"!abiertoInterno() && modoCerrado === 'oculto'\"\n [class.td-sidebar--oscuro]=\"oscuro\"\n [attr.aria-hidden]=\"!abiertoInterno() && modoCerrado === 'oculto'\"\n>\n <header class=\"td-sidebar__marca\">\n <div class=\"td-sidebar__logo\">\n @if (logoUrl) {\n <img [src]=\"logoUrl\" [alt]=\"logoAlt\" />\n } @else {\n <span>{{ inicialMarca() }}</span>\n }\n </div>\n\n @if (abiertoInterno()) {\n <div class=\"td-sidebar__marca-texto\">\n <small>{{ subtitulo }}</small>\n <strong>{{ titulo }}</strong>\n </div>\n }\n\n </header>\n\n <div class=\"td-sidebar__encabezado\">\n @if (abiertoInterno()) {\n <span>{{ etiquetaNavegacion }}</span>\n } @else {\n <span aria-hidden=\"true\">•••</span>\n }\n </div>\n\n <nav class=\"td-sidebar__nav\" aria-label=\"Menú principal\">\n @if (cargando) {\n <p class=\"td-sidebar__estado\">{{ textoCarga }}</p>\n } @else if (error) {\n <p class=\"td-sidebar__estado td-sidebar__estado--error\">{{ error }}</p>\n } @else if (!menuNormalizado().length) {\n <p class=\"td-sidebar__estado\">{{ mensajeVacio }}</p>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"listaMenu\"\n [ngTemplateOutletContext]=\"{ items: menuNormalizado(), nivel: 0, padre: 'raiz' }\"\n />\n }\n </nav>\n</aside>\n\n<ng-template #listaMenu let-items=\"items\" let-nivel=\"nivel\" let-padre=\"padre\">\n <ul class=\"td-sidebar__lista\" [class.td-sidebar__lista--anidada]=\"nivel > 0\">\n @for (item of items; track item) {\n @let clave = claveItem(item, padre, $index);\n @let tieneHijos = item.subMenus.length > 0;\n\n <li class=\"td-sidebar__item\">\n @if (tieneHijos) {\n <button\n class=\"td-sidebar__enlace\"\n type=\"button\"\n [class.td-sidebar__enlace--activo]=\"estaExpandido(clave)\"\n [attr.aria-expanded]=\"estaExpandido(clave)\"\n [attr.title]=\"!abiertoInterno() ? item.nombre : null\"\n (click)=\"alternarGrupo(clave)\"\n >\n <td-icon class=\"td-sidebar__icono\" [nombre]=\"item.icono || 'folder'\" />\n @if (abiertoInterno()) {\n <span>{{ item.nombre }}</span>\n <td-icon\n class=\"td-sidebar__flecha\"\n [class.td-sidebar__flecha--abierta]=\"estaExpandido(clave)\"\n nombre=\"chevron_right\"\n />\n }\n </button>\n } @else {\n <a\n class=\"td-sidebar__enlace\"\n [routerLink]=\"item.ruta || '/'\"\n routerLinkActive=\"td-sidebar__enlace--ruta-activa\"\n [routerLinkActiveOptions]=\"{ exact: item.ruta === '/' }\"\n [attr.title]=\"!abiertoInterno() ? item.nombre : null\"\n (click)=\"seleccionarItem(item, nivel)\"\n >\n <td-icon class=\"td-sidebar__icono\" [nombre]=\"item.icono || 'folder'\" />\n @if (abiertoInterno()) {\n <span>{{ item.nombre }}</span>\n }\n </a>\n }\n\n @if (abiertoInterno() && tieneHijos && estaExpandido(clave)) {\n <ng-container\n [ngTemplateOutlet]=\"listaMenu\"\n [ngTemplateOutletContext]=\"{\n items: item.subMenus,\n nivel: nivel + 1,\n padre: clave\n }\"\n />\n }\n </li>\n }\n </ul>\n</ng-template>\n","/*\n * Public API Surface of telcomdev-ui\n */\n\nexport * from './lib/telcomdev-ui';\nexport * from './lib/alerta';\nexport * from './lib/footer';\nexport * from './lib/header';\nexport * from './lib/iconos';\nexport * from './lib/sidebar';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"telcomdev-ui.mjs","sources":["../../../projects/telcomdev-ui/src/lib/telcomdev-ui.ts","../../../projects/telcomdev-ui/src/lib/alerta/td-alerta.ts","../../../projects/telcomdev-ui/src/lib/iconos/td-iconos.ts","../../../projects/telcomdev-ui/src/lib/iconos/td-icono-registry.ts","../../../projects/telcomdev-ui/src/lib/iconos/td-icon.ts","../../../projects/telcomdev-ui/src/lib/data-table/td-data-table.ts","../../../projects/telcomdev-ui/src/lib/data-table/td-data-table.html","../../../projects/telcomdev-ui/src/lib/footer/td-footer.ts","../../../projects/telcomdev-ui/src/lib/footer/td-footer.html","../../../projects/telcomdev-ui/src/lib/header/td-header.ts","../../../projects/telcomdev-ui/src/lib/header/td-header.html","../../../projects/telcomdev-ui/src/lib/sidebar/td-sidebar.ts","../../../projects/telcomdev-ui/src/lib/sidebar/td-sidebar.html","../../../projects/telcomdev-ui/src/public-api.ts","../../../projects/telcomdev-ui/src/telcomdev-ui.ts"],"sourcesContent":["import { Component } from '@angular/core';\n\n@Component({\n selector: 'td-telcomdev-ui',\n imports: [],\n template: ` <p>telcomdev-ui works!</p> `,\n styles: ``,\n})\nexport class TelcomdevUi {}\n","export type TdAlertaTipo = 'exito' | 'error' | 'advertencia' | 'info' | 'pregunta';\r\n\r\nexport interface TdAlertaOpciones {\r\n titulo?: string;\r\n mensaje?: string;\r\n tipo?: TdAlertaTipo;\r\n textoConfirmar?: string;\r\n textoCancelar?: string;\r\n mostrarCancelar?: boolean;\r\n cerrarConEscape?: boolean;\r\n cerrarConFondo?: boolean;\r\n}\r\n\r\nexport class TdAlerta {\r\n private static readonly estiloId = 'td-alerta-estilos';\r\n\r\n static exito(mensaje: string, titulo = '¡Operación exitosa!'): Promise<boolean> {\r\n return this.mostrar({\r\n titulo,\r\n mensaje,\r\n tipo: 'exito',\r\n textoConfirmar: 'Aceptar',\r\n });\r\n }\r\n\r\n static error(mensaje: string, titulo = '¡Error!'): Promise<boolean> {\r\n return this.mostrar({\r\n titulo,\r\n mensaje,\r\n tipo: 'error',\r\n textoConfirmar: 'Cerrar',\r\n });\r\n }\r\n\r\n static errorSistema(mensaje: string, titulo = '¡Error de Sistema!'): Promise<boolean> {\r\n return this.mostrar({\r\n titulo,\r\n mensaje,\r\n tipo: 'error',\r\n textoConfirmar: 'Cerrar',\r\n });\r\n }\r\n\r\n static advertencia(mensaje: string, titulo = '¡Advertencia!'): Promise<boolean> {\r\n return this.mostrar({\r\n titulo,\r\n mensaje,\r\n tipo: 'advertencia',\r\n textoConfirmar: 'Aceptar',\r\n });\r\n }\r\n\r\n static info(mensaje: string, titulo = 'Información'): Promise<boolean> {\r\n return this.mostrar({\r\n titulo,\r\n mensaje,\r\n tipo: 'info',\r\n textoConfirmar: 'Aceptar',\r\n });\r\n }\r\n\r\n static confirmar(\r\n mensaje: string,\r\n titulo = '¿Estás seguro?',\r\n textoConfirmar = 'Sí, continuar',\r\n textoCancelar = 'Cancelar'\r\n ): Promise<boolean> {\r\n return this.mostrar({\r\n titulo,\r\n mensaje,\r\n tipo: 'pregunta',\r\n textoConfirmar,\r\n textoCancelar,\r\n mostrarCancelar: true,\r\n });\r\n }\r\n\r\n static confirmarEliminar(\r\n mensaje = 'Esta acción no se puede deshacer.',\r\n titulo = '¿Eliminar registro?'\r\n ): Promise<boolean> {\r\n return this.mostrar({\r\n titulo,\r\n mensaje,\r\n tipo: 'advertencia',\r\n textoConfirmar: 'Sí, eliminar',\r\n textoCancelar: 'Cancelar',\r\n mostrarCancelar: true,\r\n });\r\n }\r\n\r\n static mostrar(opciones: TdAlertaOpciones): Promise<boolean> {\r\n if (typeof document === 'undefined') {\r\n return Promise.resolve(false);\r\n }\r\n\r\n this.inyectarEstilos();\r\n\r\n const config: Required<TdAlertaOpciones> = {\r\n titulo: opciones.titulo ?? '',\r\n mensaje: opciones.mensaje ?? '',\r\n tipo: opciones.tipo ?? 'info',\r\n textoConfirmar: opciones.textoConfirmar ?? 'Aceptar',\r\n textoCancelar: opciones.textoCancelar ?? 'Cancelar',\r\n mostrarCancelar: opciones.mostrarCancelar ?? false,\r\n cerrarConEscape: opciones.cerrarConEscape ?? true,\r\n cerrarConFondo: opciones.cerrarConFondo ?? false,\r\n };\r\n\r\n return new Promise<boolean>((resolve) => {\r\n const fondo = document.createElement('div');\r\n fondo.className = 'td-alerta-fondo';\r\n\r\n const modal = document.createElement('div');\r\n modal.className = 'td-alerta-modal';\r\n modal.setAttribute('role', 'dialog');\r\n modal.setAttribute('aria-modal', 'true');\r\n\r\n const icono = document.createElement('div');\r\n icono.className = `td-alerta-icono td-alerta-icono--${config.tipo}`;\r\n icono.textContent = this.obtenerIcono(config.tipo);\r\n\r\n const titulo = document.createElement('h2');\r\n titulo.className = 'td-alerta-titulo';\r\n titulo.textContent = config.titulo;\r\n\r\n const mensaje = document.createElement('p');\r\n mensaje.className = 'td-alerta-mensaje';\r\n mensaje.textContent = config.mensaje;\r\n\r\n const acciones = document.createElement('div');\r\n acciones.className = 'td-alerta-acciones';\r\n\r\n const botonConfirmar = document.createElement('button');\r\n botonConfirmar.type = 'button';\r\n botonConfirmar.className = `td-alerta-boton td-alerta-boton--${config.tipo}`;\r\n botonConfirmar.textContent = config.textoConfirmar;\r\n\r\n const botonCancelar = document.createElement('button');\r\n botonCancelar.type = 'button';\r\n botonCancelar.className = 'td-alerta-boton td-alerta-boton--cancelar';\r\n botonCancelar.textContent = config.textoCancelar;\r\n\r\n const cerrar = (resultado: boolean): void => {\r\n document.removeEventListener('keydown', onKeyDown);\r\n fondo.classList.add('td-alerta-saliendo');\r\n\r\n window.setTimeout(() => {\r\n fondo.remove();\r\n resolve(resultado);\r\n }, 140);\r\n };\r\n\r\n const onKeyDown = (event: KeyboardEvent): void => {\r\n if (event.key === 'Escape' && config.cerrarConEscape) {\r\n cerrar(false);\r\n }\r\n };\r\n\r\n botonConfirmar.addEventListener('click', () => cerrar(true));\r\n botonCancelar.addEventListener('click', () => cerrar(false));\r\n\r\n if (config.cerrarConFondo) {\r\n fondo.addEventListener('click', (event) => {\r\n if (event.target === fondo) {\r\n cerrar(false);\r\n }\r\n });\r\n }\r\n\r\n document.addEventListener('keydown', onKeyDown);\r\n\r\n if (config.mostrarCancelar) {\r\n acciones.appendChild(botonCancelar);\r\n }\r\n\r\n acciones.appendChild(botonConfirmar);\r\n\r\n modal.appendChild(icono);\r\n modal.appendChild(titulo);\r\n\r\n if (config.mensaje) {\r\n modal.appendChild(mensaje);\r\n }\r\n\r\n modal.appendChild(acciones);\r\n fondo.appendChild(modal);\r\n document.body.appendChild(fondo);\r\n\r\n botonConfirmar.focus();\r\n });\r\n }\r\n\r\n private static obtenerIcono(tipo: TdAlertaTipo): string {\r\n const iconos: Record<TdAlertaTipo, string> = {\r\n exito: '✓',\r\n error: '!',\r\n advertencia: '!',\r\n info: 'i',\r\n pregunta: '?',\r\n };\r\n\r\n return iconos[tipo];\r\n }\r\n\r\n private static inyectarEstilos(): void {\r\n if (document.getElementById(this.estiloId)) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = this.estiloId;\r\n style.textContent = `\r\n .td-alerta-fondo {\r\n position: fixed;\r\n inset: 0;\r\n z-index: 99999;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 1rem;\r\n background: rgba(15, 23, 42, 0.52);\r\n animation: td-alerta-fondo-entrada 160ms ease-out;\r\n }\r\n\r\n .td-alerta-modal {\r\n width: min(100%, 430px);\r\n border-radius: 18px;\r\n background: #ffffff;\r\n padding: 1.75rem;\r\n text-align: center;\r\n box-shadow: 0 22px 70px rgba(15, 23, 42, 0.28);\r\n animation: td-alerta-modal-entrada 180ms ease-out;\r\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\r\n }\r\n\r\n .td-alerta-icono {\r\n width: 4.25rem;\r\n height: 4.25rem;\r\n margin: 0 auto 1rem;\r\n border-radius: 999px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 2.1rem;\r\n font-weight: 800;\r\n }\r\n\r\n .td-alerta-icono--exito {\r\n color: #16a34a;\r\n background: #dcfce7;\r\n }\r\n\r\n .td-alerta-icono--error {\r\n color: #ef4444;\r\n background: #fee2e2;\r\n }\r\n\r\n .td-alerta-icono--advertencia {\r\n color: #f59e0b;\r\n background: #fef3c7;\r\n }\r\n\r\n .td-alerta-icono--info {\r\n color: #2563eb;\r\n background: #dbeafe;\r\n }\r\n\r\n .td-alerta-icono--pregunta {\r\n color: #7c3aed;\r\n background: #ede9fe;\r\n }\r\n\r\n .td-alerta-titulo {\r\n margin: 0;\r\n color: #111827;\r\n font-size: 1.35rem;\r\n line-height: 1.25;\r\n font-weight: 800;\r\n }\r\n\r\n .td-alerta-mensaje {\r\n margin: 0.75rem 0 0;\r\n color: #4b5563;\r\n font-size: 0.96rem;\r\n line-height: 1.55;\r\n }\r\n\r\n .td-alerta-acciones {\r\n display: flex;\r\n justify-content: center;\r\n gap: 0.75rem;\r\n margin-top: 1.5rem;\r\n }\r\n\r\n .td-alerta-boton {\r\n border: 0;\r\n border-radius: 10px;\r\n padding: 0.7rem 1.2rem;\r\n color: #ffffff;\r\n font-size: 0.93rem;\r\n font-weight: 700;\r\n cursor: pointer;\r\n transition: transform 120ms ease, filter 120ms ease, background 120ms ease;\r\n }\r\n\r\n .td-alerta-boton:hover {\r\n filter: brightness(0.96);\r\n }\r\n\r\n .td-alerta-boton:active {\r\n transform: scale(0.98);\r\n }\r\n\r\n .td-alerta-boton:focus {\r\n outline: 3px solid rgba(37, 99, 235, 0.25);\r\n outline-offset: 2px;\r\n }\r\n\r\n .td-alerta-boton--exito {\r\n background: #22c55e;\r\n }\r\n\r\n .td-alerta-boton--error {\r\n background: #ef4444;\r\n }\r\n\r\n .td-alerta-boton--advertencia {\r\n background: #f59e0b;\r\n }\r\n\r\n .td-alerta-boton--info {\r\n background: #2563eb;\r\n }\r\n\r\n .td-alerta-boton--pregunta {\r\n background: #7c3aed;\r\n }\r\n\r\n .td-alerta-boton--cancelar {\r\n background: #6b7280;\r\n }\r\n\r\n .td-alerta-saliendo {\r\n animation: td-alerta-fondo-salida 140ms ease-in forwards;\r\n }\r\n\r\n .td-alerta-saliendo .td-alerta-modal {\r\n animation: td-alerta-modal-salida 140ms ease-in forwards;\r\n }\r\n\r\n @keyframes td-alerta-fondo-entrada {\r\n from { opacity: 0; }\r\n to { opacity: 1; }\r\n }\r\n\r\n @keyframes td-alerta-modal-entrada {\r\n from {\r\n opacity: 0;\r\n transform: translateY(12px) scale(0.96);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0) scale(1);\r\n }\r\n }\r\n\r\n @keyframes td-alerta-fondo-salida {\r\n from { opacity: 1; }\r\n to { opacity: 0; }\r\n }\r\n\r\n @keyframes td-alerta-modal-salida {\r\n from {\r\n opacity: 1;\r\n transform: translateY(0) scale(1);\r\n }\r\n to {\r\n opacity: 0;\r\n transform: translateY(8px) scale(0.97);\r\n }\r\n }\r\n\r\n @media (max-width: 480px) {\r\n .td-alerta-modal {\r\n padding: 1.4rem;\r\n border-radius: 16px;\r\n }\r\n\r\n .td-alerta-acciones {\r\n flex-direction: column-reverse;\r\n }\r\n\r\n .td-alerta-boton {\r\n width: 100%;\r\n }\r\n }\r\n `;\r\n\r\n document.head.appendChild(style);\r\n }\r\n}","import { TdIconoDefinicion } from './td-icono.model';\n\nexport const TD_ICONOS = {\n home: {\n path: 'M3 10.5 12 3l9 7.5V21a1 1 0 0 1-1 1h-5v-7H9v7H4a1 1 0 0 1-1-1V10.5Z',\n },\n dashboard: {\n path: 'M4 3h6a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1Zm10 0h6a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1Zm0 8h6a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1v-8a1 1 0 0 1 1-1ZM4 14h6a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-5a1 1 0 0 1 1-1Z',\n },\n folder: {\n path: 'M3 5a2 2 0 0 1 2-2h5l2 2h7a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5Z',\n },\n settings: {\n path: 'M12 8.5a3.5 3.5 0 1 0 0 7 3.5 3.5 0 0 0 0-7Zm8.5 3.5c0-.5-.05-.98-.14-1.45l2.02-1.57-2-3.46-2.47 1a8.7 8.7 0 0 0-2.5-1.45L15 2.5h-4l-.4 2.57a8.7 8.7 0 0 0-2.51 1.45l-2.47-1-2 3.46 2.02 1.57a7.7 7.7 0 0 0 0 2.9l-2.02 1.57 2 3.46 2.47-1a8.7 8.7 0 0 0 2.5 1.45L11 21.5h4l.4-2.57a8.7 8.7 0 0 0 2.51-1.45l2.47 1 2-3.46-2.02-1.57c.09-.47.14-.95.14-1.45Z',\n },\n people: {\n path: 'M16 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8ZM6.5 12a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7ZM16 13c-4 0-7 2-7 4.5V21h14v-3.5C23 15 20 13 16 13ZM6.5 14C2.9 14 1 15.8 1 18v3h6v-3.5c0-1.2.48-2.28 1.3-3.16A9.3 9.3 0 0 0 6.5 14Z',\n },\n person: {\n path: 'M12 12a5 5 0 1 0 0-10 5 5 0 0 0 0 10Zm0 2c-5 0-9 2.5-9 5.5V22h18v-2.5c0-3-4-5.5-9-5.5Z',\n },\n security: {\n path: 'M12 2 4 5v6c0 5.05 3.41 9.74 8 11 4.59-1.26 8-5.95 8-11V5l-8-3Zm-1 14-4-4 1.4-1.4 2.6 2.58 5.6-5.58L18 9l-7 7Z',\n },\n inventory: {\n path: 'm12 2 9 5-9 5-9-5 9-5Zm-7 8.5 6 3.33V22l-6-3.33V10.5Zm8 11.5v-8.17l6-3.33v8.17L13 22Z',\n },\n shopping_cart: {\n path: 'M7 18a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm10 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4ZM6.2 6l.8 2h11.6l-1.9 5H8.1L4.3 3H1v2h2l3.6 9.6A2 2 0 0 0 8.5 16H19v-2H8.5l-.4-1H18a2 2 0 0 0 1.86-1.27L22 6H6.2Z',\n },\n receipt: {\n path: 'M5 2v20l3-2 4 2 4-2 3 2V2l-3 2-4-2-4 2-3-2Zm3 6h8v2H8V8Zm0 4h8v2H8v-2Z',\n },\n assessment: {\n path: 'M4 20h16v2H4a2 2 0 0 1-2-2V4h2v16Zm3-2H5v-6h2v6Zm4 0H9V7h2v11Zm4 0h-2V4h2v14Zm4 0h-2v-9h2v9Z',\n },\n description: {\n path: 'M6 2h8l5 5v15H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2Zm7 1.5V8h4.5L13 3.5ZM8 12v2h8v-2H8Zm0 4v2h8v-2H8Z',\n },\n business: {\n path: 'M3 21V3h10v5h8v13h-7v-4h-2v4H3Zm3-14h2V5H6v2Zm4 0h2V5h-2v2Zm-4 4h2V9H6v2Zm4 0h2V9h-2v2Zm6 1h2v-2h-2v2Zm0 4h2v-2h-2v2Z',\n },\n chevron_left: {\n path: 'M14.7 5.3a1 1 0 0 1 0 1.4L9.4 12l5.3 5.3a1 1 0 1 1-1.4 1.4l-6-6a1 1 0 0 1 0-1.4l6-6a1 1 0 0 1 1.4 0Z',\n },\n chevron_right: {\n path: 'M9.3 5.3a1 1 0 0 0 0 1.4l5.3 5.3-5.3 5.3a1 1 0 1 0 1.4 1.4l6-6a1 1 0 0 0 0-1.4l-6-6a1 1 0 0 0-1.4 0Z',\n },\n sun: {\n path: 'M12 7a5 5 0 1 0 0 10 5 5 0 0 0 0-10Zm0-5a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0V3a1 1 0 0 1 1-1Zm0 17a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0v-2a1 1 0 0 1 1-1ZM2 12a1 1 0 0 1 1-1h2a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Zm17 0a1 1 0 0 1 1-1h2a1 1 0 1 1 0 2h-2a1 1 0 0 1-1-1ZM4.22 4.22a1 1 0 0 1 1.42 0l1.41 1.42a1 1 0 0 1-1.41 1.41L4.22 5.64a1 1 0 0 1 0-1.42Zm12.73 12.73a1 1 0 0 1 1.41 0l1.42 1.41a1 1 0 0 1-1.42 1.42l-1.41-1.42a1 1 0 0 1 0-1.41Zm2.83-12.73a1 1 0 0 1 0 1.42l-1.42 1.41a1 1 0 0 1-1.41-1.41l1.41-1.42a1 1 0 0 1 1.42 0ZM7.05 16.95a1 1 0 0 1 0 1.41l-1.41 1.42a1 1 0 0 1-1.42-1.42l1.42-1.41a1 1 0 0 1 1.41 0Z',\n },\n moon: {\n path: 'M20.5 15.2A8.5 8.5 0 0 1 8.8 3.5 9 9 0 1 0 20.5 15.2Z',\n },\n alert: {\n path: 'M12 2 1 21h22L12 2Zm-1 7h2v6h-2V9Zm0 8h2v2h-2v-2Z',\n },\n check: {\n path: 'm9.2 16.2-4.4-4.4-1.6 1.6 6 6L21 7.6 19.4 6 9.2 16.2Z',\n },\n close: {\n path: 'M6.4 5 12 10.6 17.6 5 19 6.4 13.4 12l5.6 5.6-1.4 1.4-5.6-5.6L6.4 19 5 17.6l5.6-5.6L5 6.4 6.4 5Z',\n },\n menu: {\n path: 'M3 6h18v2H3V6Zm0 5h18v2H3v-2Zm0 5h18v2H3v-2Z',\n },\n search: {\n path: 'M10.5 3a7.5 7.5 0 1 0 4.73 13.32L20.91 22 22 20.91l-5.68-5.68A7.5 7.5 0 0 0 10.5 3Zm0 2a5.5 5.5 0 1 1 0 11 5.5 5.5 0 0 1 0-11Z',\n },\n notifications: {\n path: 'M12 22a2.5 2.5 0 0 0 2.45-2h-4.9A2.5 2.5 0 0 0 12 22Zm7-6v-5a7 7 0 0 0-5.5-6.84V3a1.5 1.5 0 0 0-3 0v1.16A7 7 0 0 0 5 11v5l-2 2v1h18v-1l-2-2Z',\n },\n chevron_down: {\n path: 'M5.3 8.3a1 1 0 0 1 1.4 0l5.3 5.3 5.3-5.3a1 1 0 1 1 1.4 1.4l-6 6a1 1 0 0 1-1.4 0l-6-6a1 1 0 0 1 0-1.4Z',\n },\n apps: {\n path: 'M4 3h4a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1Zm12 0h4a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1ZM4 15h4a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1Zm12 0h4a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1Z',\n },\n help: {\n path: 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm0 18a8 8 0 1 1 0-16 8 8 0 0 1 0 16Zm0-4.5a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5Zm.2-9.5c-2 0-3.37 1.03-3.7 2.75l1.95.4c.17-.84.77-1.3 1.67-1.3 1 0 1.63.52 1.63 1.35 0 .67-.33 1.03-1.27 1.58-1.12.65-1.48 1.27-1.48 2.47V14h2v-.55c0-.67.2-.94 1.12-1.5 1.18-.72 1.88-1.58 1.88-2.9C16 7.25 14.5 6 12.2 6Z',\n },\n add: {\n path: 'M11 5h2v6h6v2h-6v6h-2v-6H5v-2h6V5Z',\n },\n edit: {\n path: 'm16.86 3.49 3.65 3.65L8.65 19H5v-3.65L16.86 3.49ZM19.73 2.27a1.75 1.75 0 0 0-2.47 0l-1.35 1.35 3.65 3.65 1.35-1.35a1.75 1.75 0 0 0 0-2.47l-1.18-1.18Z',\n },\n delete: {\n path: 'M8 3h8l1 2h4v2H3V5h4l1-2Zm-2 6h12l-1 12H7L6 9Zm4 2v7h2v-7h-2Zm4 0v7h2v-7h-2Z',\n },\n toggle_on: {\n path: 'M17 6H7a6 6 0 0 0 0 12h10a6 6 0 0 0 0-12Zm0 10a4 4 0 1 1 0-8 4 4 0 0 1 0 8Z',\n },\n toggle_off: {\n path: 'M17 6H7a6 6 0 0 0 0 12h10a6 6 0 0 0 0-12ZM7 16a4 4 0 1 1 0-8 4 4 0 0 1 0 8Z',\n },\n inbox: {\n path: 'M4 3h16l3 11v7H1v-7L4 3Zm1.5 2L3 14h5l1 2h6l1-2h5l-2.5-9h-13Z',\n },\n pdf: {\n path: 'M6 2h9l5 5v15H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2Zm8 1.5V8h4.5L14 3.5ZM8 12v7h2v-2h1.2a2.5 2.5 0 0 0 0-5H8Zm2 2h1.2a.5.5 0 0 1 0 1H10v-1Zm4-2v7h2v-2h1v-2h-1v-1h2v-2h-4Z',\n },\n} satisfies Record<string, TdIconoDefinicion>;\n\nexport type TdIconoNombre = keyof typeof TD_ICONOS;\n\nexport const TD_ICONOS_NOMBRES = Object.freeze(\n Object.keys(TD_ICONOS) as TdIconoNombre[]\n);\n","import { Injectable } from '@angular/core';\nimport { TdIconoDefinicion, TdIconoPersonalizado } from './td-icono.model';\nimport { TD_ICONOS } from './td-iconos';\n\n@Injectable({ providedIn: 'root' })\nexport class TdIconoRegistry {\n private readonly iconos = new Map<string, TdIconoDefinicion>(\n Object.entries(TD_ICONOS)\n );\n\n registrar(iconos: TdIconoPersonalizado): void {\n for (const [nombre, definicion] of Object.entries(iconos)) {\n const clave = this.normalizar(nombre);\n if (!clave) continue;\n\n this.iconos.set(\n clave,\n typeof definicion === 'string' ? { path: definicion } : definicion\n );\n }\n }\n\n obtener(nombre: string | null | undefined): TdIconoDefinicion {\n return this.iconos.get(this.normalizar(nombre)) ?? this.iconos.get('folder')!;\n }\n\n existe(nombre: string): boolean {\n return this.iconos.has(this.normalizar(nombre));\n }\n\n nombres(): string[] {\n return [...this.iconos.keys()];\n }\n\n private normalizar(nombre: string | null | undefined): string {\n return (nombre ?? '').trim().toLowerCase();\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n HostBinding,\n Input,\n inject,\n} from '@angular/core';\nimport { TdIconoRegistry } from './td-icono-registry';\n\n@Component({\n selector: 'td-icon',\n template: `\n <svg\n [attr.viewBox]=\"definicion().viewBox || '0 0 24 24'\"\n [attr.aria-hidden]=\"titulo ? null : 'true'\"\n [attr.aria-label]=\"titulo || null\"\n [attr.role]=\"titulo ? 'img' : null\"\n focusable=\"false\"\n >\n <path [attr.d]=\"definicion().path\" />\n </svg>\n `,\n styles: `\n :host {\n display: inline-flex;\n width: var(--td-icon-size, 1.25rem);\n height: var(--td-icon-size, 1.25rem);\n flex: 0 0 auto;\n color: inherit;\n line-height: 0;\n vertical-align: middle;\n }\n svg { width: 100%; height: 100%; fill: currentColor; }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class TdIcon {\n private readonly registry = inject(TdIconoRegistry);\n\n @Input() nombre = 'folder';\n @Input() titulo = '';\n\n @Input()\n set tamano(value: string | number) {\n this.tamanoCss = typeof value === 'number' ? `${value}px` : value;\n }\n\n protected tamanoCss = '1.25rem';\n\n @HostBinding('style.--td-icon-size')\n protected get tamanoHost(): string {\n return this.tamanoCss;\n }\n\n protected definicion() {\n return this.registry.obtener(this.nombre);\n }\n}\n","import { CdkVirtualScrollViewport, ScrollingModule } from '@angular/cdk/scrolling';\nimport {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n Input,\n OnChanges,\n OnDestroy,\n Output,\n SimpleChanges,\n ViewChild,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { TdIcon } from '../iconos';\nimport {\n TdDataTableAccion,\n TdDataTableAccionEvento,\n TdDataTableBoton,\n TdDataTableColumna,\n TdDataTableTono,\n} from './td-data-table.model';\n\n@Component({\n selector: 'td-data-table',\n imports: [FormsModule, ScrollingModule, TdIcon],\n templateUrl: './td-data-table.html',\n styleUrl: './td-data-table.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class TdDataTable<T extends object> implements OnChanges, OnDestroy {\n @ViewChild(CdkVirtualScrollViewport)\n private viewport?: CdkVirtualScrollViewport;\n\n @Input() datos: T[] = [];\n @Input() columnas: TdDataTableColumna<T>[] = [];\n @Input() acciones: TdDataTableAccion<T>[] = [];\n @Input() botones: TdDataTableBoton[] = [];\n @Input() total = 0;\n @Input() cargando = false;\n @Input() puedeCargarMas = false;\n @Input() itemSize = 65;\n @Input() altura = 'min(620px, calc(100dvh - 18rem))';\n @Input() campoId: keyof T & string = 'id' as keyof T & string;\n @Input() oscuro = false;\n @Input() mostrarBusqueda = true;\n @Input() mostrarAgregar = true;\n @Input() placeholderBusqueda = 'Buscar...';\n @Input() textoAgregar = 'Agregar';\n @Input() textoVacio = 'No hay registros disponibles';\n @Input() descripcionVacio = 'Comienza creando un nuevo registro.';\n @Input() debounceBusqueda = 250;\n\n @Output() readonly busquedaChange = new EventEmitter<string>();\n @Output() readonly agregar = new EventEmitter<void>();\n @Output() readonly accion = new EventEmitter<TdDataTableAccionEvento<T>>();\n @Output() readonly botonClick = new EventEmitter<TdDataTableBoton>();\n @Output() readonly cargarMas = new EventEmitter<void>();\n\n protected busqueda = '';\n private timeoutBusqueda: ReturnType<typeof setTimeout> | null = null;\n private ultimaLongitudSolicitada = -1;\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['datos'] && this.datos.length !== this.ultimaLongitudSolicitada) {\n this.ultimaLongitudSolicitada = -1;\n }\n }\n\n ngOnDestroy(): void {\n if (this.timeoutBusqueda) clearTimeout(this.timeoutBusqueda);\n }\n\n protected columnasGrid(): string {\n const columnas = this.columnas.map((columna) => columna.ancho ?? 'minmax(10rem, 1fr)');\n if (this.acciones.length) columnas.push('minmax(9rem, auto)');\n return columnas.join(' ');\n }\n\n protected buscar(): void {\n if (this.timeoutBusqueda) clearTimeout(this.timeoutBusqueda);\n this.timeoutBusqueda = setTimeout(\n () => this.busquedaChange.emit(this.busqueda.trim()),\n this.debounceBusqueda\n );\n }\n\n protected limpiarBusqueda(): void {\n if (this.timeoutBusqueda) clearTimeout(this.timeoutBusqueda);\n this.busqueda = '';\n this.busquedaChange.emit('');\n }\n\n protected valor(fila: T, clave: keyof T & string): unknown {\n return (fila as Record<string, unknown>)[clave];\n }\n\n protected textoCelda(columna: TdDataTableColumna<T>, fila: T, indice: number): string {\n const valor = this.valor(fila, columna.clave);\n if (columna.formatear) return columna.formatear(valor, fila, indice);\n if (valor === null || valor === undefined || valor === '') return '—';\n if (columna.tipo === 'booleano') return valor ? 'Sí' : 'No';\n if (columna.tipo === 'estado') return valor ? 'Activo' : 'Inactivo';\n return String(valor);\n }\n\n protected tonoCelda(columna: TdDataTableColumna<T>, fila: T): TdDataTableTono {\n const valor = this.valor(fila, columna.clave);\n if (columna.tono) return columna.tono(valor, fila);\n if (columna.tipo === 'estado') return valor ? 'exito' : 'peligro';\n if (columna.tipo === 'booleano') return valor ? 'exito' : 'neutro';\n return 'neutro';\n }\n\n protected accionesVisibles(fila: T): TdDataTableAccion<T>[] {\n return this.acciones.filter((accion) => accion.visible?.(fila) ?? true);\n }\n\n protected botonesVisibles(): TdDataTableBoton[] {\n return this.botones.filter((boton) => boton.visible ?? true);\n }\n\n protected ejecutarAccion(\n accion: TdDataTableAccion<T>,\n fila: T,\n indice: number\n ): void {\n if (accion.deshabilitada?.(fila)) return;\n this.accion.emit({ accion, fila, indice });\n }\n\n protected alCambiarIndice(): void {\n if (!this.viewport) return;\n\n const distanciaAlFinal = this.viewport.measureScrollOffset('bottom');\n const umbralPx = this.itemSize * 2;\n\n if (\n distanciaAlFinal <= umbralPx &&\n this.datos.length > 0 &&\n this.puedeCargarMas &&\n !this.cargando &&\n this.ultimaLongitudSolicitada !== this.datos.length\n ) {\n this.ultimaLongitudSolicitada = this.datos.length;\n this.cargarMas.emit();\n }\n }\n\n protected readonly trackFila = (_indice: number, fila: T): unknown =>\n (fila as Record<string, unknown>)[this.campoId] ?? fila;\n}\n","<section class=\"td-tabla\" [class.td-tabla--oscura]=\"oscuro\">\n <div class=\"td-tabla__toolbar\">\n <div class=\"td-tabla__filtros\">\n @if (mostrarBusqueda) {\n <label class=\"td-tabla__busqueda\">\n <td-icon nombre=\"search\" />\n <input\n type=\"search\"\n [(ngModel)]=\"busqueda\"\n [placeholder]=\"placeholderBusqueda\"\n (input)=\"buscar()\"\n />\n @if (busqueda) {\n <button type=\"button\" title=\"Limpiar búsqueda\" (click)=\"limpiarBusqueda()\">\n <td-icon nombre=\"close\" tamano=\"1rem\" />\n </button>\n }\n </label>\n }\n <ng-content select=\"[tdDataTableFilters]\" />\n </div>\n </div>\n\n <div class=\"td-tabla__superficie\">\n <div class=\"td-tabla__resumen\">\n <span><strong>{{ datos.length }}</strong> de {{ total || datos.length }} registros</span>\n <div class=\"td-tabla__resumen-acciones\">\n @if (cargando) {\n <span class=\"td-tabla__cargando-inline\"><i></i> Cargando...</span>\n }\n <ng-content select=\"[tdDataTableActions]\" />\n @for (boton of botonesVisibles(); track boton.id) {\n <button\n type=\"button\"\n [class]=\"'td-tabla__boton td-tabla__boton--' + (boton.tono || 'neutro')\"\n [disabled]=\"boton.deshabilitado\"\n (click)=\"botonClick.emit(boton)\"\n >\n <td-icon [nombre]=\"boton.icono\" />\n <span>{{ boton.etiqueta }}</span>\n </button>\n }\n @if (mostrarAgregar) {\n <button class=\"td-tabla__agregar\" type=\"button\" (click)=\"agregar.emit()\">\n <td-icon nombre=\"add\" />\n <span>{{ textoAgregar }}</span>\n </button>\n }\n </div>\n </div>\n\n @if (datos.length) {\n <div\n class=\"td-tabla__encabezado\"\n role=\"row\"\n [style.grid-template-columns]=\"columnasGrid()\"\n >\n @for (columna of columnas; track columna.clave) {\n <div\n role=\"columnheader\"\n [class]=\"'td-tabla__alinear--' + (columna.alineacion || 'inicio')\"\n >\n {{ columna.encabezado }}\n </div>\n }\n @if (acciones.length) {\n <div role=\"columnheader\" class=\"td-tabla__alinear--centro\">Acciones</div>\n }\n </div>\n\n <cdk-virtual-scroll-viewport\n class=\"td-tabla__viewport\"\n [itemSize]=\"itemSize\"\n [style.height]=\"altura\"\n (scrolledIndexChange)=\"alCambiarIndice()\"\n >\n <div\n *cdkVirtualFor=\"let fila of datos; let indice = index; trackBy: trackFila\"\n class=\"td-tabla__fila\"\n role=\"row\"\n [style.height.px]=\"itemSize\"\n [style.grid-template-columns]=\"columnasGrid()\"\n >\n @for (columna of columnas; track columna.clave) {\n <div\n role=\"cell\"\n [class]=\"'td-tabla__celda td-tabla__alinear--' + (columna.alineacion || 'inicio')\"\n >\n @if (\n columna.tipo === 'estado' ||\n columna.tipo === 'booleano' ||\n columna.tipo === 'chip'\n ) {\n <span [class]=\"'td-tabla__chip td-tabla__chip--' + tonoCelda(columna, fila)\">\n {{ textoCelda(columna, fila, indice) }}\n </span>\n } @else {\n <span [class.td-tabla__numero]=\"columna.tipo === 'numero'\">\n {{ textoCelda(columna, fila, indice) }}\n </span>\n }\n </div>\n }\n\n @if (acciones.length) {\n <div class=\"td-tabla__acciones-fila\" role=\"cell\">\n @for (accionFila of accionesVisibles(fila); track accionFila.id) {\n <button\n type=\"button\"\n [class]=\"'td-tabla__accion td-tabla__accion--' + (accionFila.tono || 'neutro')\"\n [title]=\"accionFila.etiqueta\"\n [disabled]=\"accionFila.deshabilitada?.(fila) ?? false\"\n (click)=\"ejecutarAccion(accionFila, fila, indice)\"\n >\n <td-icon [nombre]=\"accionFila.icono\" />\n <span class=\"td-tabla__sr-only\">{{ accionFila.etiqueta }}</span>\n </button>\n }\n </div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n } @else if (!cargando) {\n <div class=\"td-tabla__vacio\">\n <span><td-icon nombre=\"inbox\" tamano=\"2.4rem\" /></span>\n <h3>{{ textoVacio }}</h3>\n <p>{{ descripcionVacio }}</p>\n </div>\n }\n\n @if (cargando && !datos.length) {\n <div class=\"td-tabla__skeleton\">\n @for (item of [1, 2, 3, 4, 5]; track item) {\n <span></span>\n }\n </div>\n }\n </div>\n</section>\n","import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\n\n@Component({\n selector: 'td-footer',\n templateUrl: './td-footer.html',\n styleUrl: './td-footer.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class TdFooter {\n @Input() empresa = 'TelcomDev';\n @Input() texto = 'Todos los derechos reservados.';\n @Input() version = '';\n @Input() oscuro = false;\n @Input() compacto = false;\n @Input() anio = new Date().getFullYear();\n}\n","<footer\n class=\"td-footer\"\n [class.td-footer--oscuro]=\"oscuro\"\n [class.td-footer--compacto]=\"compacto\"\n>\n <div class=\"td-footer__identidad\">\n <span>© {{ anio }} {{ empresa }}</span>\n @if (texto) {\n <small>{{ texto }}</small>\n }\n </div>\n\n <nav class=\"td-footer__enlaces\" aria-label=\"Enlaces del pie de página\">\n <ng-content select=\"[tdFooterLinks]\" />\n </nav>\n\n <div class=\"td-footer__final\">\n <ng-content select=\"[tdFooterActions]\" />\n @if (version) {\n <span class=\"td-footer__version\">v{{ version }}</span>\n }\n </div>\n</footer>\n","import {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n HostListener,\n Input,\n Output,\n} from '@angular/core';\nimport { TdIcon } from '../iconos';\n\nexport interface TdHeaderNotificacion {\n id: string | number;\n titulo: string;\n descripcion?: string;\n fecha?: string;\n icono?: string;\n leida?: boolean;\n}\n\nexport type TdHeaderAccionPerfil = 'perfil' | 'configuracion' | 'salir';\n\n@Component({\n selector: 'td-header',\n imports: [TdIcon],\n templateUrl: './td-header.html',\n styleUrl: './td-header.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class TdHeader {\n @Input() menuAbierto = true;\n @Input() mostrarMenu = true;\n @Input() usuario = '';\n @Input() cargo = '';\n @Input() avatarUrl = '';\n @Input() notificaciones: TdHeaderNotificacion[] = [];\n @Input() oscuro = false;\n @Input() fijo = true;\n\n @Output() readonly menuToggle = new EventEmitter<void>();\n @Output() readonly notificacionSeleccionada = new EventEmitter<TdHeaderNotificacion>();\n @Output() readonly verTodasNotificaciones = new EventEmitter<void>();\n @Output() readonly accionPerfil = new EventEmitter<TdHeaderAccionPerfil>();\n\n protected panelNotificacionesAbierto = false;\n protected panelPerfilAbierto = false;\n\n protected alternarMenu(): void {\n this.menuToggle.emit();\n }\n\n protected alternarNotificaciones(): void {\n this.panelNotificacionesAbierto = !this.panelNotificacionesAbierto;\n this.panelPerfilAbierto = false;\n }\n\n protected alternarPerfil(): void {\n this.panelPerfilAbierto = !this.panelPerfilAbierto;\n this.panelNotificacionesAbierto = false;\n }\n\n protected seleccionarNotificacion(notificacion: TdHeaderNotificacion): void {\n this.notificacionSeleccionada.emit(notificacion);\n this.panelNotificacionesAbierto = false;\n }\n\n protected emitirAccionPerfil(accion: TdHeaderAccionPerfil): void {\n this.accionPerfil.emit(accion);\n this.panelPerfilAbierto = false;\n }\n\n protected notificacionesNoLeidas(): number {\n return this.notificaciones.filter((item) => !item.leida).length;\n }\n\n protected inicialesUsuario(): string {\n const partes = this.usuario.trim().split(/\\s+/).filter(Boolean);\n return (\n partes\n .slice(0, 2)\n .map((parte) => parte.charAt(0))\n .join('') || 'U'\n ).toUpperCase();\n }\n\n @HostListener('document:keydown.escape')\n protected cerrarConEscape(): void {\n this.panelNotificacionesAbierto = false;\n this.panelPerfilAbierto = false;\n }\n}\n","<header\n class=\"td-header\"\n [class.td-header--oscuro]=\"oscuro\"\n [class.td-header--fijo]=\"fijo\"\n>\n <div class=\"td-header__inicio\">\n @if (mostrarMenu) {\n <button\n class=\"td-header__boton td-header__menu\"\n type=\"button\"\n [attr.aria-label]=\"menuAbierto ? 'Cerrar sidebar' : 'Abrir sidebar'\"\n [attr.aria-expanded]=\"menuAbierto\"\n (click)=\"alternarMenu()\"\n >\n <td-icon [nombre]=\"menuAbierto ? 'close' : 'menu'\" />\n </button>\n }\n\n <ng-content select=\"[tdHeaderStart]\" />\n </div>\n\n <div class=\"td-header__centro\">\n <ng-content select=\"[tdHeaderCenter]\" />\n </div>\n\n <div class=\"td-header__acciones\">\n <ng-content select=\"[tdHeaderActions]\" />\n\n <div class=\"td-header__desplegable\">\n <button\n class=\"td-header__boton td-header__notificaciones\"\n type=\"button\"\n aria-label=\"Notificaciones\"\n [attr.aria-expanded]=\"panelNotificacionesAbierto\"\n (click)=\"alternarNotificaciones()\"\n >\n <td-icon nombre=\"notifications\" />\n @if (notificacionesNoLeidas() > 0) {\n <span>{{ notificacionesNoLeidas() > 99 ? '99+' : notificacionesNoLeidas() }}</span>\n }\n </button>\n\n @if (panelNotificacionesAbierto) {\n <section class=\"td-header__panel td-header__panel--notificaciones\">\n <header>\n <div>\n <strong>Notificaciones</strong>\n <small>{{ notificacionesNoLeidas() }} sin leer</small>\n </div>\n <td-icon nombre=\"notifications\" />\n </header>\n\n <div class=\"td-header__lista-notificaciones\">\n @for (notificacion of notificaciones; track notificacion.id) {\n <button\n type=\"button\"\n [class.td-header__notificacion--nueva]=\"!notificacion.leida\"\n (click)=\"seleccionarNotificacion(notificacion)\"\n >\n <span class=\"td-header__notificacion-icono\">\n <td-icon [nombre]=\"notificacion.icono || 'notifications'\" />\n </span>\n <span>\n <strong>{{ notificacion.titulo }}</strong>\n @if (notificacion.descripcion) {\n <small>{{ notificacion.descripcion }}</small>\n }\n @if (notificacion.fecha) {\n <time>{{ notificacion.fecha }}</time>\n }\n </span>\n </button>\n } @empty {\n <p class=\"td-header__vacio\">No tienes notificaciones.</p>\n }\n </div>\n\n @if (notificaciones.length) {\n <button\n class=\"td-header__ver-todas\"\n type=\"button\"\n (click)=\"verTodasNotificaciones.emit(); panelNotificacionesAbierto = false\"\n >\n Ver todas las notificaciones\n </button>\n }\n </section>\n }\n </div>\n\n @if (usuario) {\n <span class=\"td-header__separador\" aria-hidden=\"true\"></span>\n\n <div class=\"td-header__desplegable\">\n <button\n class=\"td-header__perfil\"\n type=\"button\"\n aria-label=\"Abrir perfil de usuario\"\n [attr.aria-expanded]=\"panelPerfilAbierto\"\n (click)=\"alternarPerfil()\"\n >\n <span class=\"td-header__avatar\">\n @if (avatarUrl) {\n <img [src]=\"avatarUrl\" [alt]=\"usuario\" />\n } @else {\n {{ inicialesUsuario() }}\n }\n </span>\n <span class=\"td-header__usuario\">\n <strong>{{ usuario }}</strong>\n @if (cargo) {\n <small>{{ cargo }}</small>\n }\n </span>\n <td-icon nombre=\"chevron_down\" tamano=\"0.85rem\" />\n </button>\n\n @if (panelPerfilAbierto) {\n <section class=\"td-header__panel td-header__panel--perfil\">\n <div class=\"td-header__perfil-resumen\">\n <span class=\"td-header__avatar td-header__avatar--grande\">{{ inicialesUsuario() }}</span>\n <div>\n <strong>{{ usuario }}</strong>\n <small>{{ cargo || 'Usuario' }}</small>\n </div>\n </div>\n <div class=\"td-header__perfil-opciones\">\n <button type=\"button\" (click)=\"emitirAccionPerfil('perfil')\">\n <td-icon nombre=\"person\" /> Mi perfil\n </button>\n <button type=\"button\" (click)=\"emitirAccionPerfil('configuracion')\">\n <td-icon nombre=\"settings\" /> Configuración\n </button>\n <button class=\"td-header__salir\" type=\"button\" (click)=\"emitirAccionPerfil('salir')\">\n <td-icon nombre=\"close\" /> Cerrar sesión\n </button>\n </div>\n </section>\n }\n </div>\n }\n </div>\n</header>\n","import {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n Input,\n Output,\n signal,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { RouterLink, RouterLinkActive } from '@angular/router';\nimport { TdIcon } from '../iconos';\nimport { MenuSidebar, TdSidebarSeleccion } from './menu-sidebar';\n\nexport type TdSidebarModoCerrado = 'compacto' | 'oculto';\n\n@Component({\n selector: 'td-sidebar',\n imports: [NgTemplateOutlet, RouterLink, RouterLinkActive, TdIcon],\n templateUrl: './td-sidebar.html',\n styleUrl: './td-sidebar.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class TdSidebar {\n @Input() titulo = 'Gestión Corporativa';\n @Input() subtitulo = 'Central Platform';\n @Input() etiquetaNavegacion = 'Navegación';\n @Input() logoUrl = '';\n @Input() logoAlt = 'Logo';\n @Input() textoCarga = 'Cargando menú...';\n @Input() mensajeVacio = 'No hay opciones disponibles.';\n @Input() error = '';\n @Input() cargando = false;\n @Input() oscuro = false;\n @Input() modoCerrado: TdSidebarModoCerrado = 'compacto';\n\n @Input()\n set abierto(value: boolean) {\n this.abiertoInterno.set(value);\n }\n get abierto(): boolean {\n return this.abiertoInterno();\n }\n\n @Input()\n set menu(value: MenuSidebar[] | null | undefined) {\n this.menuNormalizado.set(this.normalizarMenu(value ?? []));\n }\n get menu(): MenuSidebar[] {\n return this.menuNormalizado();\n }\n\n @Output() readonly abiertoChange = new EventEmitter<boolean>();\n @Output() readonly seleccionar = new EventEmitter<TdSidebarSeleccion>();\n\n protected readonly abiertoInterno = signal(true);\n protected readonly menuNormalizado = signal<MenuSidebar[]>([]);\n protected readonly expandidos = signal<ReadonlySet<string>>(new Set<string>());\n\n protected alternarGrupo(clave: string): void {\n if (!this.abiertoInterno()) {\n this.abiertoInterno.set(true);\n this.abiertoChange.emit(true);\n }\n\n this.expandidos.update((actuales) => {\n const siguientes = new Set(actuales);\n siguientes.has(clave) ? siguientes.delete(clave) : siguientes.add(clave);\n return siguientes;\n });\n }\n\n protected estaExpandido(clave: string): boolean {\n return this.expandidos().has(clave);\n }\n\n protected seleccionarItem(item: MenuSidebar, nivel: number): void {\n this.seleccionar.emit({ item, nivel });\n }\n\n protected claveItem(item: MenuSidebar, padre: string, indice: number): string {\n return `${padre}/${item.nombre}-${indice}`;\n }\n\n protected inicialMarca(): string {\n return (this.titulo.trim().charAt(0) || 'T').toUpperCase();\n }\n\n private normalizarMenu(items: MenuSidebar[]): MenuSidebar[] {\n return [...items]\n .sort((a, b) => a.orden - b.orden)\n .map((item) => ({\n ...item,\n icono: item.icono?.trim() || 'folder',\n subMenus: this.normalizarMenu(item.subMenus ?? []),\n }));\n }\n}\n","<aside\n class=\"td-sidebar\"\n [class.td-sidebar--compacto]=\"!abiertoInterno() && modoCerrado === 'compacto'\"\n [class.td-sidebar--oculto]=\"!abiertoInterno() && modoCerrado === 'oculto'\"\n [class.td-sidebar--oscuro]=\"oscuro\"\n [attr.aria-hidden]=\"!abiertoInterno() && modoCerrado === 'oculto'\"\n>\n <header class=\"td-sidebar__marca\">\n <div class=\"td-sidebar__logo\">\n @if (logoUrl) {\n <img [src]=\"logoUrl\" [alt]=\"logoAlt\" />\n } @else {\n <span>{{ inicialMarca() }}</span>\n }\n </div>\n\n @if (abiertoInterno()) {\n <div class=\"td-sidebar__marca-texto\">\n <small>{{ subtitulo }}</small>\n <strong>{{ titulo }}</strong>\n </div>\n }\n\n </header>\n\n <div class=\"td-sidebar__encabezado\">\n @if (abiertoInterno()) {\n <span>{{ etiquetaNavegacion }}</span>\n } @else {\n <span aria-hidden=\"true\">•••</span>\n }\n </div>\n\n <nav class=\"td-sidebar__nav\" aria-label=\"Menú principal\">\n @if (cargando) {\n <p class=\"td-sidebar__estado\">{{ textoCarga }}</p>\n } @else if (error) {\n <p class=\"td-sidebar__estado td-sidebar__estado--error\">{{ error }}</p>\n } @else if (!menuNormalizado().length) {\n <p class=\"td-sidebar__estado\">{{ mensajeVacio }}</p>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"listaMenu\"\n [ngTemplateOutletContext]=\"{ items: menuNormalizado(), nivel: 0, padre: 'raiz' }\"\n />\n }\n </nav>\n</aside>\n\n<ng-template #listaMenu let-items=\"items\" let-nivel=\"nivel\" let-padre=\"padre\">\n <ul class=\"td-sidebar__lista\" [class.td-sidebar__lista--anidada]=\"nivel > 0\">\n @for (item of items; track item) {\n @let clave = claveItem(item, padre, $index);\n @let tieneHijos = item.subMenus.length > 0;\n\n <li class=\"td-sidebar__item\">\n @if (tieneHijos) {\n <button\n class=\"td-sidebar__enlace\"\n type=\"button\"\n [class.td-sidebar__enlace--activo]=\"estaExpandido(clave)\"\n [attr.aria-expanded]=\"estaExpandido(clave)\"\n [attr.title]=\"!abiertoInterno() ? item.nombre : null\"\n (click)=\"alternarGrupo(clave)\"\n >\n <td-icon class=\"td-sidebar__icono\" [nombre]=\"item.icono || 'folder'\" />\n @if (abiertoInterno()) {\n <span>{{ item.nombre }}</span>\n <td-icon\n class=\"td-sidebar__flecha\"\n [class.td-sidebar__flecha--abierta]=\"estaExpandido(clave)\"\n nombre=\"chevron_right\"\n />\n }\n </button>\n } @else {\n <a\n class=\"td-sidebar__enlace\"\n [routerLink]=\"item.ruta || '/'\"\n routerLinkActive=\"td-sidebar__enlace--ruta-activa\"\n [routerLinkActiveOptions]=\"{ exact: item.ruta === '/' }\"\n [attr.title]=\"!abiertoInterno() ? item.nombre : null\"\n (click)=\"seleccionarItem(item, nivel)\"\n >\n <td-icon class=\"td-sidebar__icono\" [nombre]=\"item.icono || 'folder'\" />\n @if (abiertoInterno()) {\n <span>{{ item.nombre }}</span>\n }\n </a>\n }\n\n @if (abiertoInterno() && tieneHijos && estaExpandido(clave)) {\n <ng-container\n [ngTemplateOutlet]=\"listaMenu\"\n [ngTemplateOutletContext]=\"{\n items: item.subMenus,\n nivel: nivel + 1,\n padre: clave\n }\"\n />\n }\n </li>\n }\n </ul>\n</ng-template>\n","/*\n * Public API Surface of telcomdev-ui\n */\n\nexport * from './lib/telcomdev-ui';\nexport * from './lib/alerta';\nexport * from './lib/data-table';\nexport * from './lib/footer';\nexport * from './lib/header';\nexport * from './lib/iconos';\nexport * from './lib/sidebar';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telcomdev/ui",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Librería UI reutilizable para los sistemas TelcomDev.",
5
5
  "keywords": [
6
6
  "angular",
@@ -11,11 +11,14 @@
11
11
  "sidebar",
12
12
  "header",
13
13
  "footer",
14
- "icons"
14
+ "icons",
15
+ "data-table",
16
+ "virtual-scroll"
15
17
  ],
16
18
  "author": "TelcomDev",
17
19
  "license": "MIT",
18
20
  "peerDependencies": {
21
+ "@angular/cdk": "^21.2.0",
19
22
  "@angular/common": "^21.2.0",
20
23
  "@angular/core": "^21.2.0",
21
24
  "@angular/router": "^21.2.0"
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { EventEmitter } from '@angular/core';
2
+ import { OnChanges, OnDestroy, EventEmitter, SimpleChanges } from '@angular/core';
3
3
  import * as _telcomdev_ui from '@telcomdev/ui';
4
4
 
5
5
  declare class TelcomdevUi {
@@ -32,6 +32,85 @@ declare class TdAlerta {
32
32
  private static inyectarEstilos;
33
33
  }
34
34
 
35
+ type TdDataTableAlineacion = 'inicio' | 'centro' | 'fin';
36
+ type TdDataTableTipoColumna = 'texto' | 'numero' | 'booleano' | 'estado' | 'chip';
37
+ type TdDataTableTono = 'neutro' | 'primario' | 'exito' | 'advertencia' | 'peligro';
38
+ interface TdDataTableColumna<T> {
39
+ clave: keyof T & string;
40
+ encabezado: string;
41
+ ancho?: string;
42
+ tipo?: TdDataTableTipoColumna;
43
+ alineacion?: TdDataTableAlineacion;
44
+ formatear?: (valor: unknown, fila: T, indice: number) => string;
45
+ tono?: (valor: unknown, fila: T) => TdDataTableTono;
46
+ }
47
+ interface TdDataTableAccion<T> {
48
+ id: string;
49
+ etiqueta: string;
50
+ icono: string;
51
+ tono?: TdDataTableTono;
52
+ visible?: (fila: T) => boolean;
53
+ deshabilitada?: (fila: T) => boolean;
54
+ }
55
+ interface TdDataTableAccionEvento<T> {
56
+ accion: TdDataTableAccion<T>;
57
+ fila: T;
58
+ indice: number;
59
+ }
60
+ interface TdDataTableBoton {
61
+ id: string;
62
+ etiqueta: string;
63
+ icono: string;
64
+ tono?: TdDataTableTono;
65
+ visible?: boolean;
66
+ deshabilitado?: boolean;
67
+ }
68
+
69
+ declare class TdDataTable<T extends object> implements OnChanges, OnDestroy {
70
+ private viewport?;
71
+ datos: T[];
72
+ columnas: TdDataTableColumna<T>[];
73
+ acciones: TdDataTableAccion<T>[];
74
+ botones: TdDataTableBoton[];
75
+ total: number;
76
+ cargando: boolean;
77
+ puedeCargarMas: boolean;
78
+ itemSize: number;
79
+ altura: string;
80
+ campoId: keyof T & string;
81
+ oscuro: boolean;
82
+ mostrarBusqueda: boolean;
83
+ mostrarAgregar: boolean;
84
+ placeholderBusqueda: string;
85
+ textoAgregar: string;
86
+ textoVacio: string;
87
+ descripcionVacio: string;
88
+ debounceBusqueda: number;
89
+ readonly busquedaChange: EventEmitter<string>;
90
+ readonly agregar: EventEmitter<void>;
91
+ readonly accion: EventEmitter<TdDataTableAccionEvento<T>>;
92
+ readonly botonClick: EventEmitter<TdDataTableBoton>;
93
+ readonly cargarMas: EventEmitter<void>;
94
+ protected busqueda: string;
95
+ private timeoutBusqueda;
96
+ private ultimaLongitudSolicitada;
97
+ ngOnChanges(changes: SimpleChanges): void;
98
+ ngOnDestroy(): void;
99
+ protected columnasGrid(): string;
100
+ protected buscar(): void;
101
+ protected limpiarBusqueda(): void;
102
+ protected valor(fila: T, clave: keyof T & string): unknown;
103
+ protected textoCelda(columna: TdDataTableColumna<T>, fila: T, indice: number): string;
104
+ protected tonoCelda(columna: TdDataTableColumna<T>, fila: T): TdDataTableTono;
105
+ protected accionesVisibles(fila: T): TdDataTableAccion<T>[];
106
+ protected botonesVisibles(): TdDataTableBoton[];
107
+ protected ejecutarAccion(accion: TdDataTableAccion<T>, fila: T, indice: number): void;
108
+ protected alCambiarIndice(): void;
109
+ protected readonly trackFila: (_indice: number, fila: T) => unknown;
110
+ static ɵfac: i0.ɵɵFactoryDeclaration<TdDataTable<any>, never>;
111
+ static ɵcmp: i0.ɵɵComponentDeclaration<TdDataTable<any>, "td-data-table", never, { "datos": { "alias": "datos"; "required": false; }; "columnas": { "alias": "columnas"; "required": false; }; "acciones": { "alias": "acciones"; "required": false; }; "botones": { "alias": "botones"; "required": false; }; "total": { "alias": "total"; "required": false; }; "cargando": { "alias": "cargando"; "required": false; }; "puedeCargarMas": { "alias": "puedeCargarMas"; "required": false; }; "itemSize": { "alias": "itemSize"; "required": false; }; "altura": { "alias": "altura"; "required": false; }; "campoId": { "alias": "campoId"; "required": false; }; "oscuro": { "alias": "oscuro"; "required": false; }; "mostrarBusqueda": { "alias": "mostrarBusqueda"; "required": false; }; "mostrarAgregar": { "alias": "mostrarAgregar"; "required": false; }; "placeholderBusqueda": { "alias": "placeholderBusqueda"; "required": false; }; "textoAgregar": { "alias": "textoAgregar"; "required": false; }; "textoVacio": { "alias": "textoVacio"; "required": false; }; "descripcionVacio": { "alias": "descripcionVacio"; "required": false; }; "debounceBusqueda": { "alias": "debounceBusqueda"; "required": false; }; }, { "busquedaChange": "busquedaChange"; "agregar": "agregar"; "accion": "accion"; "botonClick": "botonClick"; "cargarMas": "cargarMas"; }, never, ["[tdDataTableFilters]", "[tdDataTableActions]"], true, never>;
112
+ }
113
+
35
114
  declare class TdFooter {
36
115
  empresa: string;
37
116
  texto: string;
@@ -187,9 +266,30 @@ declare const TD_ICONOS: {
187
266
  help: {
188
267
  path: string;
189
268
  };
269
+ add: {
270
+ path: string;
271
+ };
272
+ edit: {
273
+ path: string;
274
+ };
275
+ delete: {
276
+ path: string;
277
+ };
278
+ toggle_on: {
279
+ path: string;
280
+ };
281
+ toggle_off: {
282
+ path: string;
283
+ };
284
+ inbox: {
285
+ path: string;
286
+ };
287
+ pdf: {
288
+ path: string;
289
+ };
190
290
  };
191
291
  type TdIconoNombre = keyof typeof TD_ICONOS;
192
- declare const TD_ICONOS_NOMBRES: readonly ("menu" | "search" | "close" | "home" | "dashboard" | "folder" | "settings" | "people" | "person" | "security" | "inventory" | "shopping_cart" | "receipt" | "assessment" | "description" | "business" | "chevron_left" | "chevron_right" | "sun" | "moon" | "alert" | "check" | "notifications" | "chevron_down" | "apps" | "help")[];
292
+ declare const TD_ICONOS_NOMBRES: readonly ("menu" | "search" | "close" | "home" | "dashboard" | "folder" | "settings" | "people" | "person" | "security" | "inventory" | "shopping_cart" | "receipt" | "assessment" | "description" | "business" | "chevron_left" | "chevron_right" | "sun" | "moon" | "alert" | "check" | "notifications" | "chevron_down" | "apps" | "help" | "add" | "edit" | "delete" | "toggle_on" | "toggle_off" | "inbox" | "pdf")[];
193
293
 
194
294
  interface MenuSidebar {
195
295
  nombre: string;
@@ -235,5 +335,5 @@ declare class TdSidebar {
235
335
  static ɵcmp: i0.ɵɵComponentDeclaration<TdSidebar, "td-sidebar", never, { "titulo": { "alias": "titulo"; "required": false; }; "subtitulo": { "alias": "subtitulo"; "required": false; }; "etiquetaNavegacion": { "alias": "etiquetaNavegacion"; "required": false; }; "logoUrl": { "alias": "logoUrl"; "required": false; }; "logoAlt": { "alias": "logoAlt"; "required": false; }; "textoCarga": { "alias": "textoCarga"; "required": false; }; "mensajeVacio": { "alias": "mensajeVacio"; "required": false; }; "error": { "alias": "error"; "required": false; }; "cargando": { "alias": "cargando"; "required": false; }; "oscuro": { "alias": "oscuro"; "required": false; }; "modoCerrado": { "alias": "modoCerrado"; "required": false; }; "abierto": { "alias": "abierto"; "required": false; }; "menu": { "alias": "menu"; "required": false; }; }, { "abiertoChange": "abiertoChange"; "seleccionar": "seleccionar"; }, never, never, true, never>;
236
336
  }
237
337
 
238
- export { TD_ICONOS, TD_ICONOS_NOMBRES, TdAlerta, TdFooter, TdHeader, TdIcon, TdIconoRegistry, TdSidebar, TelcomdevUi };
239
- export type { MenuSidebar, TdAlertaOpciones, TdAlertaTipo, TdHeaderAccionPerfil, TdHeaderNotificacion, TdIconoDefinicion, TdIconoNombre, TdIconoPersonalizado, TdSidebarModoCerrado, TdSidebarSeleccion };
338
+ export { TD_ICONOS, TD_ICONOS_NOMBRES, TdAlerta, TdDataTable, TdFooter, TdHeader, TdIcon, TdIconoRegistry, TdSidebar, TelcomdevUi };
339
+ export type { MenuSidebar, TdAlertaOpciones, TdAlertaTipo, TdDataTableAccion, TdDataTableAccionEvento, TdDataTableAlineacion, TdDataTableBoton, TdDataTableColumna, TdDataTableTipoColumna, TdDataTableTono, TdHeaderAccionPerfil, TdHeaderNotificacion, TdIconoDefinicion, TdIconoNombre, TdIconoPersonalizado, TdSidebarModoCerrado, TdSidebarSeleccion };