@neural-ui/core 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -88
- package/accordion/package.json +4 -0
- package/alert/package.json +4 -0
- package/autocomplete/package.json +4 -0
- package/avatar/package.json +4 -0
- package/badge/package.json +4 -0
- package/block-ui/package.json +4 -0
- package/breadcrumb/package.json +4 -0
- package/button/package.json +4 -0
- package/card/package.json +4 -0
- package/chart/package.json +4 -0
- package/checkbox/package.json +4 -0
- package/chip/package.json +4 -0
- package/code-block/package.json +4 -0
- package/color-picker/package.json +4 -0
- package/command-palette/package.json +4 -0
- package/confirm-dialog/package.json +4 -0
- package/context-menu/package.json +4 -0
- package/dashboard-grid/package.json +4 -0
- package/date-input/package.json +4 -0
- package/divider/package.json +4 -0
- package/empty-state/package.json +4 -0
- package/fesm2022/neural-ui-core-accordion.mjs +162 -0
- package/fesm2022/neural-ui-core-accordion.mjs.map +1 -0
- package/fesm2022/neural-ui-core-alert.mjs +116 -0
- package/fesm2022/neural-ui-core-alert.mjs.map +1 -0
- package/fesm2022/neural-ui-core-autocomplete.mjs +332 -0
- package/fesm2022/neural-ui-core-autocomplete.mjs.map +1 -0
- package/fesm2022/neural-ui-core-avatar.mjs +109 -0
- package/fesm2022/neural-ui-core-avatar.mjs.map +1 -0
- package/fesm2022/neural-ui-core-badge.mjs +54 -0
- package/fesm2022/neural-ui-core-badge.mjs.map +1 -0
- package/fesm2022/neural-ui-core-block-ui.mjs +95 -0
- package/fesm2022/neural-ui-core-block-ui.mjs.map +1 -0
- package/fesm2022/neural-ui-core-breadcrumb.mjs +84 -0
- package/fesm2022/neural-ui-core-breadcrumb.mjs.map +1 -0
- package/fesm2022/neural-ui-core-button.mjs +125 -0
- package/fesm2022/neural-ui-core-button.mjs.map +1 -0
- package/fesm2022/neural-ui-core-card.mjs +69 -0
- package/fesm2022/neural-ui-core-card.mjs.map +1 -0
- package/fesm2022/neural-ui-core-chart.mjs +287 -0
- package/fesm2022/neural-ui-core-chart.mjs.map +1 -0
- package/fesm2022/neural-ui-core-checkbox.mjs +138 -0
- package/fesm2022/neural-ui-core-checkbox.mjs.map +1 -0
- package/fesm2022/neural-ui-core-chip.mjs +130 -0
- package/fesm2022/neural-ui-core-chip.mjs.map +1 -0
- package/fesm2022/neural-ui-core-code-block.mjs +250 -0
- package/fesm2022/neural-ui-core-code-block.mjs.map +1 -0
- package/fesm2022/neural-ui-core-color-picker.mjs +435 -0
- package/fesm2022/neural-ui-core-color-picker.mjs.map +1 -0
- package/fesm2022/neural-ui-core-command-palette.mjs +235 -0
- package/fesm2022/neural-ui-core-command-palette.mjs.map +1 -0
- package/fesm2022/neural-ui-core-confirm-dialog.mjs +118 -0
- package/fesm2022/neural-ui-core-confirm-dialog.mjs.map +1 -0
- package/fesm2022/neural-ui-core-context-menu.mjs +158 -0
- package/fesm2022/neural-ui-core-context-menu.mjs.map +1 -0
- package/fesm2022/neural-ui-core-dashboard-grid.mjs +144 -0
- package/fesm2022/neural-ui-core-dashboard-grid.mjs.map +1 -0
- package/fesm2022/neural-ui-core-date-input.mjs +1332 -0
- package/fesm2022/neural-ui-core-date-input.mjs.map +1 -0
- package/fesm2022/neural-ui-core-divider.mjs +54 -0
- package/fesm2022/neural-ui-core-divider.mjs.map +1 -0
- package/fesm2022/neural-ui-core-empty-state.mjs +84 -0
- package/fesm2022/neural-ui-core-empty-state.mjs.map +1 -0
- package/fesm2022/neural-ui-core-filter-bar.mjs +118 -0
- package/fesm2022/neural-ui-core-filter-bar.mjs.map +1 -0
- package/fesm2022/neural-ui-core-icon.mjs +50 -0
- package/fesm2022/neural-ui-core-icon.mjs.map +1 -0
- package/fesm2022/neural-ui-core-image-viewer.mjs +309 -0
- package/fesm2022/neural-ui-core-image-viewer.mjs.map +1 -0
- package/fesm2022/neural-ui-core-input-otp.mjs +192 -0
- package/fesm2022/neural-ui-core-input-otp.mjs.map +1 -0
- package/fesm2022/neural-ui-core-input.mjs +320 -0
- package/fesm2022/neural-ui-core-input.mjs.map +1 -0
- package/fesm2022/neural-ui-core-knob.mjs +323 -0
- package/fesm2022/neural-ui-core-knob.mjs.map +1 -0
- package/fesm2022/neural-ui-core-meter-group.mjs +122 -0
- package/fesm2022/neural-ui-core-meter-group.mjs.map +1 -0
- package/fesm2022/neural-ui-core-modal.mjs +156 -0
- package/fesm2022/neural-ui-core-modal.mjs.map +1 -0
- package/fesm2022/neural-ui-core-multiselect.mjs +748 -0
- package/fesm2022/neural-ui-core-multiselect.mjs.map +1 -0
- package/fesm2022/neural-ui-core-nav.mjs +952 -0
- package/fesm2022/neural-ui-core-nav.mjs.map +1 -0
- package/fesm2022/neural-ui-core-notification-center.mjs +264 -0
- package/fesm2022/neural-ui-core-notification-center.mjs.map +1 -0
- package/fesm2022/neural-ui-core-number-input.mjs +331 -0
- package/fesm2022/neural-ui-core-number-input.mjs.map +1 -0
- package/fesm2022/neural-ui-core-pagination.mjs +198 -0
- package/fesm2022/neural-ui-core-pagination.mjs.map +1 -0
- package/fesm2022/neural-ui-core-popover.mjs +207 -0
- package/fesm2022/neural-ui-core-popover.mjs.map +1 -0
- package/fesm2022/neural-ui-core-progress-bar.mjs +105 -0
- package/fesm2022/neural-ui-core-progress-bar.mjs.map +1 -0
- package/fesm2022/neural-ui-core-radio.mjs +171 -0
- package/fesm2022/neural-ui-core-radio.mjs.map +1 -0
- package/fesm2022/neural-ui-core-rating.mjs +151 -0
- package/fesm2022/neural-ui-core-rating.mjs.map +1 -0
- package/fesm2022/neural-ui-core-select.mjs +638 -0
- package/fesm2022/neural-ui-core-select.mjs.map +1 -0
- package/fesm2022/neural-ui-core-sidebar.mjs +214 -0
- package/fesm2022/neural-ui-core-sidebar.mjs.map +1 -0
- package/fesm2022/neural-ui-core-skeleton.mjs +40 -0
- package/fesm2022/neural-ui-core-skeleton.mjs.map +1 -0
- package/fesm2022/neural-ui-core-slider.mjs +146 -0
- package/fesm2022/neural-ui-core-slider.mjs.map +1 -0
- package/fesm2022/neural-ui-core-spinner.mjs +113 -0
- package/fesm2022/neural-ui-core-spinner.mjs.map +1 -0
- package/fesm2022/neural-ui-core-split-button.mjs +252 -0
- package/fesm2022/neural-ui-core-split-button.mjs.map +1 -0
- package/fesm2022/neural-ui-core-splitter.mjs +174 -0
- package/fesm2022/neural-ui-core-splitter.mjs.map +1 -0
- package/fesm2022/neural-ui-core-stats-card.mjs +163 -0
- package/fesm2022/neural-ui-core-stats-card.mjs.map +1 -0
- package/fesm2022/neural-ui-core-stepper.mjs +204 -0
- package/fesm2022/neural-ui-core-stepper.mjs.map +1 -0
- package/fesm2022/neural-ui-core-switch.mjs +111 -0
- package/fesm2022/neural-ui-core-switch.mjs.map +1 -0
- package/fesm2022/neural-ui-core-table.mjs +1860 -0
- package/fesm2022/neural-ui-core-table.mjs.map +1 -0
- package/fesm2022/neural-ui-core-tabs.mjs +246 -0
- package/fesm2022/neural-ui-core-tabs.mjs.map +1 -0
- package/fesm2022/neural-ui-core-textarea.mjs +188 -0
- package/fesm2022/neural-ui-core-textarea.mjs.map +1 -0
- package/fesm2022/neural-ui-core-timeline.mjs +117 -0
- package/fesm2022/neural-ui-core-timeline.mjs.map +1 -0
- package/fesm2022/neural-ui-core-toast.mjs +171 -0
- package/fesm2022/neural-ui-core-toast.mjs.map +1 -0
- package/fesm2022/neural-ui-core-toggle-button-group.mjs +162 -0
- package/fesm2022/neural-ui-core-toggle-button-group.mjs.map +1 -0
- package/fesm2022/neural-ui-core-toolbar.mjs +67 -0
- package/fesm2022/neural-ui-core-toolbar.mjs.map +1 -0
- package/fesm2022/neural-ui-core-tooltip.mjs +151 -0
- package/fesm2022/neural-ui-core-tooltip.mjs.map +1 -0
- package/fesm2022/neural-ui-core-url-state.mjs +96 -0
- package/fesm2022/neural-ui-core-url-state.mjs.map +1 -0
- package/fesm2022/neural-ui-core-virtual-list.mjs +126 -0
- package/fesm2022/neural-ui-core-virtual-list.mjs.map +1 -0
- package/fesm2022/neural-ui-core.mjs +11 -8544
- package/fesm2022/neural-ui-core.mjs.map +1 -1
- package/filter-bar/package.json +4 -0
- package/icon/package.json +4 -0
- package/image-viewer/package.json +4 -0
- package/input/package.json +4 -0
- package/input-otp/package.json +4 -0
- package/knob/package.json +4 -0
- package/meter-group/package.json +4 -0
- package/modal/package.json +4 -0
- package/multiselect/package.json +4 -0
- package/nav/package.json +4 -0
- package/notification-center/package.json +4 -0
- package/number-input/package.json +4 -0
- package/package.json +252 -5
- package/pagination/package.json +4 -0
- package/popover/package.json +4 -0
- package/progress-bar/package.json +4 -0
- package/radio/package.json +4 -0
- package/rating/package.json +4 -0
- package/select/package.json +4 -0
- package/sidebar/package.json +4 -0
- package/skeleton/package.json +4 -0
- package/slider/package.json +4 -0
- package/spinner/package.json +4 -0
- package/split-button/package.json +4 -0
- package/splitter/package.json +4 -0
- package/stats-card/package.json +4 -0
- package/stepper/package.json +4 -0
- package/styles/_tokens.scss +202 -0
- package/styles.scss +1 -0
- package/switch/package.json +4 -0
- package/table/package.json +4 -0
- package/tabs/package.json +4 -0
- package/textarea/package.json +4 -0
- package/timeline/package.json +4 -0
- package/toast/package.json +4 -0
- package/toggle-button-group/package.json +4 -0
- package/toolbar/package.json +4 -0
- package/tooltip/package.json +4 -0
- package/types/neural-ui-core-accordion.d.ts +55 -0
- package/types/neural-ui-core-alert.d.ts +47 -0
- package/types/neural-ui-core-autocomplete.d.ts +69 -0
- package/types/neural-ui-core-avatar.d.ts +39 -0
- package/types/neural-ui-core-badge.d.ts +36 -0
- package/types/neural-ui-core-block-ui.d.ts +46 -0
- package/types/neural-ui-core-breadcrumb.d.ts +38 -0
- package/types/neural-ui-core-button.d.ts +55 -0
- package/types/neural-ui-core-card.d.ts +37 -0
- package/types/neural-ui-core-chart.d.ts +236 -0
- package/types/neural-ui-core-checkbox.d.ts +33 -0
- package/types/neural-ui-core-chip.d.ts +53 -0
- package/types/neural-ui-core-code-block.d.ts +55 -0
- package/types/neural-ui-core-color-picker.d.ts +55 -0
- package/types/neural-ui-core-command-palette.d.ts +56 -0
- package/types/neural-ui-core-confirm-dialog.d.ts +50 -0
- package/types/neural-ui-core-context-menu.d.ts +66 -0
- package/types/neural-ui-core-dashboard-grid.d.ts +41 -0
- package/types/neural-ui-core-date-input.d.ts +178 -0
- package/types/neural-ui-core-divider.d.ts +20 -0
- package/types/neural-ui-core-empty-state.d.ts +32 -0
- package/types/neural-ui-core-filter-bar.d.ts +49 -0
- package/types/neural-ui-core-icon.d.ts +33 -0
- package/types/neural-ui-core-image-viewer.d.ts +67 -0
- package/types/neural-ui-core-input-otp.d.ts +49 -0
- package/types/neural-ui-core-input.d.ts +86 -0
- package/types/neural-ui-core-knob.d.ts +68 -0
- package/types/neural-ui-core-meter-group.d.ts +52 -0
- package/types/neural-ui-core-modal.d.ts +54 -0
- package/types/neural-ui-core-multiselect.d.ts +129 -0
- package/types/neural-ui-core-nav.d.ts +69 -0
- package/types/neural-ui-core-notification-center.d.ts +60 -0
- package/types/neural-ui-core-number-input.d.ts +63 -0
- package/types/neural-ui-core-pagination.d.ts +30 -0
- package/types/neural-ui-core-popover.d.ts +73 -0
- package/types/neural-ui-core-progress-bar.d.ts +35 -0
- package/types/neural-ui-core-radio.d.ts +51 -0
- package/types/neural-ui-core-rating.d.ts +34 -0
- package/types/neural-ui-core-select.d.ts +161 -0
- package/types/neural-ui-core-sidebar.d.ts +57 -0
- package/types/neural-ui-core-skeleton.d.ts +22 -0
- package/types/neural-ui-core-slider.d.ts +42 -0
- package/types/neural-ui-core-spinner.d.ts +38 -0
- package/types/neural-ui-core-split-button.d.ts +65 -0
- package/types/neural-ui-core-splitter.d.ts +28 -0
- package/types/neural-ui-core-stats-card.d.ts +39 -0
- package/types/neural-ui-core-stepper.d.ts +51 -0
- package/types/neural-ui-core-switch.d.ts +34 -0
- package/types/neural-ui-core-table.d.ts +282 -0
- package/types/neural-ui-core-tabs.d.ts +76 -0
- package/types/neural-ui-core-textarea.d.ts +52 -0
- package/types/neural-ui-core-timeline.d.ts +33 -0
- package/types/neural-ui-core-toast.d.ts +70 -0
- package/types/neural-ui-core-toggle-button-group.d.ts +63 -0
- package/types/neural-ui-core-toolbar.d.ts +36 -0
- package/types/neural-ui-core-tooltip.d.ts +48 -0
- package/types/neural-ui-core-url-state.d.ts +58 -0
- package/types/neural-ui-core-virtual-list.d.ts +60 -0
- package/types/neural-ui-core.d.ts +3 -2105
- package/url-state/package.json +4 -0
- package/virtual-list/package.json +4 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"neural-ui-core-table.mjs","sources":["../../../../projects/ui-core/table/neu-table-expand.directive.ts","../../../../projects/ui-core/table/neu-table.component.ts","../../../../projects/ui-core/table/neural-ui-core-table.ts"],"sourcesContent":["import { Directive, TemplateRef, inject } from '@angular/core';\n\n/**\n * Directiva para definir el template de expansión de fila en NeuTable.\n *\n * Uso:\n * ```html\n * <neu-table [expandable]=\"true\" [columns]=\"cols\" [data]=\"rows\">\n * <ng-template neuTableExpand let-row>\n * <div>{{ row.details }}</div>\n * </ng-template>\n * </neu-table>\n * ```\n */\n@Directive({\n selector: 'ng-template[neuTableExpand]',\n standalone: true,\n})\nexport class NeuTableExpandDirective {\n readonly templateRef = inject(TemplateRef) as TemplateRef<{ $implicit: Record<string, unknown> }>;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n PLATFORM_ID,\n TemplateRef,\n ViewEncapsulation,\n computed,\n contentChild,\n effect,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { isPlatformBrowser, NgTemplateOutlet } from '@angular/common';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { NeuTableExpandDirective } from './neu-table-expand.directive';\nimport { NeuUrlStateService } from '@neural-ui/core/url-state';\nimport { NeuInputComponent } from '@neural-ui/core/input';\nimport { NeuSelectComponent } from '@neural-ui/core/select';\nimport { NeuDateInputComponent } from '@neural-ui/core/date-input';\nimport { NeuIconComponent } from '@neural-ui/core/icon';\nimport type { NeuSelectOption } from '@neural-ui/core/select';\nimport type {\n NeuTableAction,\n NeuTableActionEvent,\n NeuTableColumn,\n NeuTableServerState,\n NeuTableSortEntry,\n} from './neu-table.types';\n\nexport type {\n NeuTableAction,\n NeuTableActionEvent,\n NeuTableBadgeConfig,\n NeuTableBadgeVariant,\n NeuTableCellType,\n NeuTableColumn,\n NeuTableServerState,\n NeuTableSortEntry,\n} from './neu-table.types';\n\ntype Row = Record<string, unknown>;\n\n// Conversor interno — el input acepta object[] para compatibilidad con\n// interfaces de usuario concretas (User, Product…). Internamente casteamos a Row.\nfunction asRows(data: object[]): Row[] {\n return data as Row[];\n}\n\n/**\n * NeuralUI Table — Componente Estrella\n *\n * Tabla de datos con:\n * - Búsqueda/filtrado → ?q=...\n * - Paginación → ?page=...\n * - Ordenación → ?sort=col&sortDir=asc|desc\n * - Selección de filas (múltiple) opcional\n * - Skeleton de carga animado\n * - Scroll horizontal elegante en mobile (<400px)\n *\n * Uso básico:\n * <neu-table [columns]=\"cols\" [data]=\"rows\" />\n *\n * Múltiples tablas por página:\n * <neu-table pageParam=\"userPage\" searchParam=\"userQ\" sortParam=\"userSort\" ... />\n */\n@Component({\n selector: 'neu-table',\n imports: [\n NgTemplateOutlet,\n ReactiveFormsModule,\n NeuInputComponent,\n NeuSelectComponent,\n NeuDateInputComponent,\n NeuIconComponent,\n ],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.neu-table__host]': 'true',\n '[class.neu-table__host--compact]': 'density() === \"compact\"',\n '[class.neu-table__host--relaxed]': 'density() === \"relaxed\"',\n },\n template: `\n <div class=\"neu-table-container\" [class.neu-table--sticky-header]=\"stickyHeader()\">\n <!-- ---- Toolbar ---- -->\n @if (searchable() || title() || exportable()) {\n <div class=\"neu-table__toolbar\">\n @if (title()) {\n <h3 class=\"neu-table__title\">{{ title() }}</h3>\n }\n @if (searchable()) {\n <div class=\"neu-table__search-group\">\n <div class=\"neu-table__search-wrapper\">\n <svg\n class=\"neu-table__search-icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n </svg>\n <input\n class=\"neu-table__search\"\n type=\"search\"\n [placeholder]=\"searchPlaceholder()\"\n [value]=\"searchQuery()\"\n (input)=\"onSearch($event)\"\n [attr.aria-label]=\"searchAriaLabel()\"\n />\n @if (searchQuery()) {\n <button\n class=\"neu-table__search-clear\"\n type=\"button\"\n [attr.aria-label]=\"clearSearchAriaLabel()\"\n (click)=\"clearSearch()\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n }\n </div>\n @if (exactMatchable()) {\n <label class=\"neu-table__exact-label\">\n <input\n class=\"neu-table__exact-checkbox\"\n type=\"checkbox\"\n [checked]=\"exactMatch()\"\n (change)=\"setExactMatch($any($event.target).checked)\"\n />\n {{ exactMatchLabel() }}\n </label>\n }\n </div>\n }\n @if (exportable() && !loading()) {\n <div class=\"neu-table__export-group\">\n @if (exportFormats().includes('csv')) {\n <button\n class=\"neu-table__export-btn\"\n type=\"button\"\n (click)=\"exportCsv()\"\n [title]=\"exportCsvTitle()\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n width=\"15\"\n height=\"15\"\n >\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </svg>\n CSV\n </button>\n }\n @if (exportFormats().includes('json')) {\n <button\n class=\"neu-table__export-btn\"\n type=\"button\"\n (click)=\"exportJson()\"\n [title]=\"exportJsonTitle()\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n width=\"15\"\n height=\"15\"\n >\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </svg>\n JSON\n </button>\n }\n </div>\n }\n </div>\n }\n\n <!-- Barra de selección (aparece al seleccionar) -->\n @if (selectable() && selectedCount() > 0) {\n <div class=\"neu-table__selection-bar\">\n <span>{{ selectedRowsInfo() }}</span>\n <button class=\"neu-table__selection-clear\" type=\"button\" (click)=\"clearSelection()\">\n {{ clearSelectionLabel() }}\n </button>\n </div>\n }\n\n <!-- ---- Scroll container ---- -->\n <div\n class=\"neu-table__scroll-container\"\n role=\"region\"\n [attr.aria-label]=\"title() || tableAriaLabel()\"\n >\n <table class=\"neu-table\" [attr.aria-rowcount]=\"filteredData().length\">\n <thead class=\"neu-table__head\">\n <tr>\n <!-- Checkbox de selección global -->\n @if (expandable()) {\n <th class=\"neu-table__th neu-table__th--expand-col\" scope=\"col\"></th>\n }\n @if (selectable()) {\n <th class=\"neu-table__th neu-table__th--check\" scope=\"col\">\n <input\n type=\"checkbox\"\n class=\"neu-table__checkbox\"\n [checked]=\"isAllFilteredSelected()\"\n [indeterminate]=\"isSomeFilteredSelected()\"\n (change)=\"toggleAll()\"\n [attr.aria-label]=\"selectAllAriaLabel()\"\n />\n </th>\n }\n @if (showRowNumbers()) {\n <th class=\"neu-table__th neu-table__th--rn\" scope=\"col\">#</th>\n }\n @for (col of columns(); track col.key) {\n <th\n class=\"neu-table__th\"\n [class.neu-table__th--sortable]=\"sortable() && col.sortable !== false\"\n [class.neu-table__th--sorted-asc]=\"\n !multiSort() && sortKey() === col.key && sortDir() === 'asc'\n \"\n [class.neu-table__th--sorted-desc]=\"\n !multiSort() && sortKey() === col.key && sortDir() === 'desc'\n \"\n [class]=\"col.cellClass ?? ''\"\n [class.neu-table__th--frozen-left]=\"col.frozen === 'left'\"\n [class.neu-table__th--frozen-right]=\"col.frozen === 'right'\"\n [class.neu-table__th--frozen-left-boundary]=\"isLastFrozenLeftColumn(col.key)\"\n [class.neu-table__th--frozen-right-boundary]=\"isFirstFrozenRightColumn(col.key)\"\n [style.left]=\"\n col.frozen === 'left' ? (_frozenLeftOffsets().get(col.key) ?? 0) + 'px' : null\n \"\n [style.width]=\"col.width ?? 'auto'\"\n [style.text-align]=\"col.align ?? 'left'\"\n scope=\"col\"\n (click)=\"sortable() && col.sortable !== false ? sortBy(col.key, $event) : null\"\n >\n @if (col.headerTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"col.headerTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: col }\"\n />\n } @else {\n {{ col.header }}\n }\n @if (sortable() && col.sortable !== false) {\n <span class=\"neu-table__sort-icon\" aria-hidden=\"true\">\n @if (multiSort()) {\n @let pri = getSortPriority(col.key);\n @if (pri >= 0) {\n <span class=\"neu-table__sort-priority\">{{ pri + 1 }}</span>\n {{ _sortEntries()[pri]?.dir === 'asc' ? '↑' : '↓' }}\n } @else {\n ↕\n }\n } @else {\n @if (sortKey() === col.key) {\n {{ sortDir() === 'asc' ? '↑' : '↓' }}\n } @else {\n ↕\n }\n }\n </span>\n }\n </th>\n }\n </tr>\n <!-- ── Fila de filtros de columna / Column filter row ── -->\n @if (_hasFilterableCol()) {\n <tr class=\"neu-table__filter-row\">\n @if (expandable()) {\n <th class=\"neu-table__th neu-table__th--filter-placeholder\" scope=\"col\"></th>\n }\n @if (selectable()) {\n <th class=\"neu-table__th neu-table__th--filter-placeholder\" scope=\"col\"></th>\n }\n @if (showRowNumbers()) {\n <th class=\"neu-table__th neu-table__th--filter-placeholder\" scope=\"col\"></th>\n }\n @for (col of columns(); track col.key) {\n <th\n class=\"neu-table__th neu-table__th--filter\"\n scope=\"col\"\n [style.width]=\"col.width ?? 'auto'\"\n >\n @if (col.filterable) {\n @if (col.filterType === 'select') {\n <neu-select\n [floatingLabel]=\"false\"\n [options]=\"_filterOpts(col)\"\n [formControl]=\"columnFilterControl(col.key)\"\n [attr.aria-label]=\"filterAriaPrefix() + ' ' + col.header\"\n />\n } @else if (col.filterType === 'date') {\n <neu-date-input\n [formControl]=\"columnFilterControl(col.key)\"\n [attr.aria-label]=\"filterAriaPrefix() + ' ' + col.header\"\n />\n } @else {\n <neu-input\n [floatingLabel]=\"false\"\n [placeholder]=\"filterPlaceholder()\"\n [formControl]=\"columnFilterControl(col.key)\"\n [attr.aria-label]=\"filterAriaPrefix() + ' ' + col.header\"\n />\n }\n }\n </th>\n }\n </tr>\n }\n </thead>\n\n <tbody class=\"neu-table__body\">\n @if (loading()) {\n <tr class=\"neu-table__row--loading\">\n <td [attr.colspan]=\"totalColspan()\" class=\"neu-table__td neu-table__td--center\">\n <div class=\"neu-table__skeleton-rows\">\n @for (_ of skeletonRows(); track $index) {\n <div class=\"neu-table__skeleton-row\">\n @for (__ of columns(); track $index) {\n <div class=\"neu-table__skeleton-cell\"></div>\n }\n </div>\n }\n </div>\n </td>\n </tr>\n } @else if (paginatedData().length === 0) {\n <tr>\n <td [attr.colspan]=\"totalColspan()\" class=\"neu-table__td neu-table__td--empty\">\n @if (emptyStateTemplate()) {\n <ng-container [ngTemplateOutlet]=\"emptyStateTemplate()!\" />\n } @else {\n <div class=\"neu-table__empty\">\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n </svg>\n <p>{{ emptyMessage() }}</p>\n @if (searchQuery()) {\n <button\n class=\"neu-table__clear-filter\"\n type=\"button\"\n (click)=\"clearSearch()\"\n >\n {{ clearFilterLabel() }}\n </button>\n }\n </div>\n }\n </td>\n </tr>\n } @else {\n @for (row of paginatedData(); track getRowKey(row); let rowIdx = $index) {\n <tr\n class=\"neu-table__row\"\n [class]=\"getRowClass(row)\"\n [class.neu-table__row--selected]=\"isRowSelected(row)\"\n [class.neu-table__row--clickable]=\"selectable()\"\n (click)=\"onRowClick(row, $event)\"\n (dblclick)=\"rowDblClick.emit(row)\"\n >\n @if (expandable()) {\n <td\n class=\"neu-table__td neu-table__td--expand-col\"\n (click)=\"$event.stopPropagation()\"\n >\n <button\n class=\"neu-table__expand-btn\"\n type=\"button\"\n (click)=\"toggleExpand(row)\"\n [class.neu-table__expand-btn--open]=\"isRowExpanded(row)\"\n [attr.aria-expanded]=\"isRowExpanded(row)\"\n [attr.aria-label]=\"expandRowAriaLabel()\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n </button>\n </td>\n }\n @if (selectable()) {\n <td\n class=\"neu-table__td neu-table__th--check\"\n (click)=\"$event.stopPropagation()\"\n >\n <input\n type=\"checkbox\"\n class=\"neu-table__checkbox\"\n [checked]=\"isRowSelected(row)\"\n (change)=\"toggleRow(row)\"\n [attr.aria-label]=\"selectRowAriaLabel()\"\n />\n </td>\n }\n @if (showRowNumbers()) {\n <td class=\"neu-table__td neu-table__td--rn\">\n {{ (currentPage() - 1) * effectivePageSize() + rowIdx + 1 }}\n </td>\n }\n @for (col of columns(); track col.key) {\n <td\n class=\"neu-table__td\"\n [class]=\"col.cellClass ?? ''\"\n [class.neu-table__td--frozen-left]=\"col.frozen === 'left'\"\n [class.neu-table__td--frozen-right]=\"col.frozen === 'right'\"\n [class.neu-table__td--frozen-left-boundary]=\"isLastFrozenLeftColumn(col.key)\"\n [class.neu-table__td--frozen-right-boundary]=\"\n isFirstFrozenRightColumn(col.key)\n \"\n [style.left]=\"\n col.frozen === 'left'\n ? (_frozenLeftOffsets().get(col.key) ?? 0) + 'px'\n : null\n \"\n [style.text-align]=\"col.align ?? 'left'\"\n >\n @if (col.cellTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"col.cellTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row, row: row, column: col }\"\n />\n } @else if (col.type === 'badge') {\n @let badgeVal = getCellValue(row, col);\n @let badgeCfg = col.badgeMap?.[badgeVal];\n <span\n class=\"neu-table__cell-badge neu-table__cell-badge--{{\n badgeCfg?.variant ?? 'default'\n }}\"\n >\n {{ badgeCfg?.label ?? badgeVal }}\n </span>\n } @else if (col.type === 'link') {\n <a\n class=\"neu-table__cell-link\"\n [href]=\"col.linkHref ? col.linkHref(row) : '#'\"\n [target]=\"col.linkTarget ?? '_self'\"\n (click)=\"$event.stopPropagation()\"\n >{{ getCellValue(row, col) }}</a\n >\n } @else if (col.type === 'actions') {\n <div class=\"neu-table__actions\">\n @for (action of col.actions ?? []; track action.key) {\n @if (action.show === undefined || action.show(row)) {\n @if (isConfirmPending(row, action)) {\n <span class=\"neu-table__action-confirm\">\n <span>{{ action.confirm }}</span>\n <button\n class=\"neu-table__action-btn neu-table__action-btn--danger\"\n type=\"button\"\n (click)=\"handleAction(row, action); $event.stopPropagation()\"\n >\n Sí\n </button>\n <button\n class=\"neu-table__action-btn\"\n type=\"button\"\n (click)=\"cancelConfirm(); $event.stopPropagation()\"\n >\n No\n </button>\n </span>\n } @else {\n <button\n class=\"neu-table__action-btn neu-table__action-btn--{{\n action.variant ?? 'ghost'\n }}\"\n type=\"button\"\n [disabled]=\"action.disabled ? action.disabled(row) : false\"\n [title]=\"action.label\"\n (click)=\"handleAction(row, action); $event.stopPropagation()\"\n >\n @if (action.icon.startsWith('lucide')) {\n <neu-icon\n class=\"neu-table__action-icon\"\n [name]=\"action.icon\"\n size=\"1rem\"\n aria-hidden=\"true\"\n />\n } @else {\n <span class=\"neu-table__action-icon\" aria-hidden=\"true\">{{\n action.icon\n }}</span>\n }\n <span class=\"sr-only\">{{ action.label }}</span>\n </button>\n }\n }\n }\n </div>\n } @else {\n {{ getCellValue(row, col) }}\n }\n </td>\n }\n </tr>\n @if (expandable() && isRowExpanded(row)) {\n <tr class=\"neu-table__row-expand-detail\">\n <td [attr.colspan]=\"totalColspan()\" class=\"neu-table__td--expand-panel\">\n <div class=\"neu-table__expand-content\">\n @if (expandTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: row }\"\n />\n }\n </div>\n </td>\n </tr>\n }\n }\n }\n </tbody>\n @if (footerRow()) {\n <tfoot class=\"neu-table__foot\">\n <tr class=\"neu-table__footer-row\">\n @if (expandable()) {\n <td class=\"neu-table__td\"></td>\n }\n @if (selectable()) {\n <td class=\"neu-table__td\"></td>\n }\n @if (showRowNumbers()) {\n <td class=\"neu-table__td\"></td>\n }\n @for (col of columns(); track col.key) {\n <td\n class=\"neu-table__td neu-table__td--footer\"\n [style.text-align]=\"col.align ?? 'left'\"\n >\n {{ footerRow()![col.key] !== undefined ? footerRow()![col.key] : '' }}\n </td>\n }\n </tr>\n </tfoot>\n }\n </table>\n </div>\n\n <!-- ---- Footer ---- -->\n @if (!loading() && filteredData().length > 0) {\n <div class=\"neu-table__footer\">\n @if (pageSizeOptions().length > 0) {\n <div class=\"neu-table__page-size\">\n <label class=\"neu-table__page-size-label\">{{ pageSizeLabel() }}</label>\n <neu-select\n class=\"neu-table__page-size-select\"\n [floatingLabel]=\"false\"\n [options]=\"_pageSizeOptions()\"\n [formControl]=\"_pageSizeControl\"\n [attr.aria-label]=\"pageSizeAriaLabel()\"\n size=\"sm\"\n />\n </div>\n }\n <span class=\"neu-table__info\">\n {{ paginationInfo() }}\n </span>\n @if (totalPages() > 1) {\n <nav class=\"neu-table__pagination\" [attr.aria-label]=\"paginationAriaLabel()\">\n <button\n class=\"neu-table__page-btn\"\n [disabled]=\"currentPage() === 1\"\n (click)=\"goToPage(currentPage() - 1)\"\n [attr.aria-label]=\"previousPageAriaLabel()\"\n type=\"button\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"15 18 9 12 15 6\" />\n </svg>\n </button>\n @for (page of pageNumbers(); track page) {\n <button\n class=\"neu-table__page-btn\"\n [class.neu-table__page-btn--active]=\"page === currentPage()\"\n (click)=\"goToPage(page)\"\n [attr.aria-current]=\"page === currentPage() ? 'page' : null\"\n type=\"button\"\n >\n {{ page }}\n </button>\n }\n <button\n class=\"neu-table__page-btn\"\n [disabled]=\"currentPage() === totalPages()\"\n (click)=\"goToPage(currentPage() + 1)\"\n [attr.aria-label]=\"nextPageAriaLabel()\"\n type=\"button\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n </button>\n </nav>\n }\n </div>\n }\n </div>\n `,\n styleUrl: './neu-table.component.scss',\n})\nexport class NeuTableComponent {\n private readonly _destroyRef = inject(DestroyRef);\n private readonly _urlState = inject(NeuUrlStateService);\n private readonly _platformId = inject(PLATFORM_ID);\n\n readonly expandTemplate = contentChild(NeuTableExpandDirective);\n\n // ── Inputs de datos ─────────────────────────────────────────────────\n readonly columns = input<NeuTableColumn[]>([]);\n readonly data = input<object[]>([]);\n readonly pageSize = input<number>(10);\n readonly loading = input<boolean>(false);\n readonly title = input<string>('');\n readonly emptyMessage = input<string>('No results found');\n readonly skeletonRows = input<number[]>([1, 2, 3, 4, 5]);\n\n // ── Inputs de funcionalidad ──────────────────────────────────────────\n readonly searchable = input<boolean>(true);\n readonly searchPlaceholder = input<string>('Search...');\n readonly exactMatchable = input<boolean>(false);\n readonly exactMatchLabel = input<string>('Exact match');\n readonly searchAriaLabel = input<string>('Search table');\n readonly clearSearchAriaLabel = input<string>('Clear search');\n readonly clearFilterLabel = input<string>('Clear filter');\n readonly previousPageAriaLabel = input<string>('Previous page');\n readonly nextPageAriaLabel = input<string>('Next page');\n readonly pageSizeLabel = input<string>('Rows:');\n readonly pageSizeAriaLabel = input<string>('Rows per page');\n readonly paginationAriaLabel = input<string>('Pagination');\n readonly exportCsvTitle = input<string>('Export CSV');\n readonly exportJsonTitle = input<string>('Export JSON');\n readonly clearSelectionLabel = input<string>('Clear selection');\n readonly selectionSummaryLabel = input<string>('selected');\n readonly tableAriaLabel = input<string>('Data table');\n readonly selectAllAriaLabel = input<string>('Select all filtered rows');\n readonly selectRowAriaLabel = input<string>('Select row');\n readonly expandRowAriaLabel = input<string>('Expand row');\n readonly filterPlaceholder = input<string>('Filter...');\n readonly filterAriaPrefix = input<string>('Filter by');\n readonly allFilterOptionLabel = input<string>('All');\n readonly ofLabel = input<string>('of');\n readonly resultLabelSingular = input<string>('result');\n readonly resultLabelPlural = input<string>('results');\n readonly sortable = input<boolean>(false);\n readonly selectable = input<boolean>(false);\n readonly expandable = input<boolean>(false);\n readonly exportable = input<boolean>(false);\n readonly exportFileName = input<string>('export');\n readonly pageSizeOptions = input<number[]>([]);\n readonly stickyHeader = input<boolean>(false);\n readonly rowKey = input<string>('id');\n\n // ── Inputs nuevos v1.3.0 ──────────────────────────────────────────────\n readonly density = input<'compact' | 'normal' | 'relaxed'>('normal');\n readonly showRowNumbers = input<boolean>(false);\n readonly rowClass = input<((row: Row) => string) | undefined>(undefined);\n readonly footerRow = input<Record<string, string | number> | undefined>(undefined);\n readonly emptyStateTemplate = input<TemplateRef<void> | undefined>(undefined);\n readonly serverSide = input<boolean>(false);\n readonly totalItems = input<number | undefined>(undefined);\n readonly multiSort = input<boolean>(false);\n readonly exportFormats = input<('csv' | 'json')[]>(['csv']);\n readonly exportColumns = input<string[]>([]);\n\n // ── URL params ────────────────────────────────────────────────────────\n readonly pageParam = input<string>('page');\n readonly searchParam = input<string>('q');\n readonly sortParam = input<string>('sort');\n readonly sortDirParam = input<string>('sortDir');\n /** Param used to persist multi-sort state in the URL / Param para persistir multisort en la URL */\n readonly multiSortParam = input<string>('msort');\n /**\n * Activa o desactiva la sincronización de estado con los queryParams de la URL.\n * Cuando es false, la paginación, búsqueda y ordenación se gestionan con\n * señales internas sin tocar la URL del navegador.\n *\n * Enables or disables URL query-param synchronization.\n * When false, pagination, search and sort are managed with internal signals\n * and the browser URL is never modified.\n */\n readonly useUrlState = input<boolean>(true);\n\n // ── Outputs ───────────────────────────────────────────────────────────\n readonly selectionChange = output<Row[]>();\n readonly rowClick = output<Row>();\n readonly rowDblClick = output<Row>();\n readonly actionClick = output<NeuTableActionEvent<Row>>();\n readonly serverStateChange = output<NeuTableServerState>();\n readonly searchChange = output<string>();\n\n // ── Estado interno (usado cuando useUrlState = false) ─────────────────\n // Internal state signals (used when useUrlState = false)\n private readonly _internalPage = signal(1);\n private readonly _internalSearch = signal('');\n private readonly _internalSortKey = signal('');\n private readonly _internalSortDir = signal<'asc' | 'desc'>('asc');\n private readonly _internalMultiSort = signal('');\n\n // ── URL State ─────────────────────────────────────────────────────────\n readonly currentPage = computed(() => {\n if (!this.useUrlState()) return this._internalPage();\n const raw = this._urlState.getParam(this.pageParam())();\n const n = Number(raw);\n return !raw || isNaN(n) || n < 1 ? 1 : n;\n });\n readonly searchQuery = computed(() => {\n if (!this.useUrlState()) return this._internalSearch();\n return this._urlState.getParam(this.searchParam())() ?? '';\n });\n readonly sortKey = computed(() => {\n if (!this.useUrlState()) return this._internalSortKey();\n return this._urlState.getParam(this.sortParam())() ?? '';\n });\n readonly sortDir = computed<'asc' | 'desc'>(() => {\n if (!this.useUrlState()) return this._internalSortDir();\n const d = this._urlState.getParam(this.sortDirParam())();\n return d === 'desc' ? 'desc' : 'asc';\n });\n\n // ---- Pipeline de datos / Data pipeline ----\n private readonly rows = computed(() => asRows(this.data()));\n\n // ── Estado interno ────────────────────────────────────────────────────\n private readonly _exactMatch = signal(false);\n readonly exactMatch = this._exactMatch.asReadonly();\n\n /**\n * Multi-sort entries derived from URL param or internal state.\n * Entradas de multisort derivadas del param de URL o del estado interno.\n */\n readonly _sortEntries = computed<NeuTableSortEntry[]>(() => {\n if (!this.multiSort()) return [];\n const param = this.useUrlState()\n ? this._urlState.getParam(this.multiSortParam())()\n : this._internalMultiSort();\n if (!param) return [];\n return param.split(',').flatMap((chunk) => {\n const [key, dir] = chunk.split(':');\n if (!key) return [];\n return [{ key, dir: (dir === 'desc' ? 'desc' : 'asc') as 'asc' | 'desc' }];\n });\n });\n readonly _columnFilters = signal<Record<string, unknown>>({});\n readonly _pageSizeControl = new FormControl('', { nonNullable: true });\n private readonly _columnFilterControls = new Map<string, FormControl<string>>();\n /** True when at least one column has filterable:true / True si alguna columna tiene filterable:true */\n readonly _hasFilterableCol = computed(() => this.columns().some((c) => c.filterable));\n\n /** Convierte filterOptions de string[] a NeuSelectOption[] con opción \"Todos\" al inicio.\n * Converts filterOptions from string[] to NeuSelectOption[] with a leading \"All\" option. */\n _filterOpts(col: NeuTableColumn): NeuSelectOption[] {\n return [\n { label: this.allFilterOptionLabel(), value: '' },\n ...(col.filterOptions ?? []).map((o) => ({ label: o, value: o })),\n ];\n }\n\n readonly _pageSizeOptions = computed<NeuSelectOption[]>(() =>\n this.pageSizeOptions().map((size) => ({ label: String(size), value: String(size) })),\n );\n\n constructor() {\n this._pageSizeControl.valueChanges\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((value) => this.onPageSizeChange(value));\n\n effect(() => {\n const nextSize = String(this.effectivePageSize());\n if (this._pageSizeControl.value !== nextSize) {\n this._pageSizeControl.setValue(nextSize, { emitEvent: false });\n }\n });\n\n effect(() => {\n const filters = this._columnFilters();\n for (const col of this.columns()) {\n if (!col.filterable) continue;\n const control = this.columnFilterControl(col.key);\n const nextValue = String(filters[col.key] ?? '');\n if (control.value !== nextValue) {\n control.setValue(nextValue, { emitEvent: false });\n }\n }\n });\n }\n\n private readonly _confirmPending = signal<{ rowKey: unknown; actionKey: string } | null>(null);\n\n // ── Pipeline de datos ─────────────────────────────────────────────────\n private readonly _rows = computed(() => asRows(this.data()));\n\n readonly filteredData = computed<Row[]>(() => {\n if (this.serverSide()) return this._rows();\n const rows = this._rows();\n const colFilters = this._columnFilters();\n const q = this.searchQuery().trim().toLowerCase();\n const exact = this._exactMatch();\n const matches = (text: string) =>\n exact ? text.toLowerCase() === q : text.toLowerCase().includes(q);\n return rows.filter((row) => {\n const passesGlobal =\n !q ||\n this.columns().some((col) => {\n const rawVal = String(row[col.key] ?? '');\n const displayVal = col.cell\n ? col.cell(row)\n : col.type === 'badge' && col.badgeMap?.[rawVal]?.label\n ? col.badgeMap[rawVal].label!\n : rawVal;\n return matches(displayVal) || matches(rawVal);\n });\n if (!passesGlobal) return false;\n for (const [colKey, filterVal] of Object.entries(colFilters)) {\n if (filterVal === null || filterVal === '' || filterVal === undefined) continue;\n if (\n !String(row[colKey] ?? '')\n .toLowerCase()\n .includes(String(filterVal).toLowerCase())\n )\n return false;\n }\n return true;\n });\n });\n\n readonly sortedData = computed<Row[]>(() => {\n if (this.serverSide()) return this.filteredData();\n const data = [...this.filteredData()];\n if (!this.sortable()) return data;\n if (this.multiSort() && this._sortEntries().length > 0) {\n const entries = this._sortEntries();\n return data.sort((a, b) => {\n for (const entry of entries) {\n const cmp = String(a[entry.key] ?? '').localeCompare(\n String(b[entry.key] ?? ''),\n undefined,\n { numeric: true },\n );\n if (cmp !== 0) return entry.dir === 'asc' ? cmp : -cmp;\n }\n return 0;\n });\n }\n const key = this.sortKey();\n if (!key) return data;\n const dir = this.sortDir();\n return data.sort((a, b) => {\n const cmp = String(a[key] ?? '').localeCompare(String(b[key] ?? ''), undefined, {\n numeric: true,\n });\n return dir === 'asc' ? cmp : -cmp;\n });\n });\n\n private readonly _dynamicPageSize = signal<number | null>(null);\n readonly effectivePageSize = computed(() => this._dynamicPageSize() ?? this.pageSize());\n\n readonly totalPages = computed(() => {\n const total =\n this.serverSide() && this.totalItems() != null\n ? this.totalItems()!\n : this.filteredData().length;\n return Math.max(1, Math.ceil(total / this.effectivePageSize()));\n });\n\n readonly paginatedData = computed(() => {\n if (this.serverSide()) return this._rows();\n const page = Math.min(this.currentPage(), this.totalPages());\n const size = this.effectivePageSize();\n return this.sortedData().slice((page - 1) * size, page * size);\n });\n\n readonly pageNumbers = computed<number[]>(() => {\n const total = this.totalPages();\n const current = this.currentPage();\n let start = Math.max(1, current - 2);\n const end = Math.min(total, start + 4);\n start = Math.max(1, end - 4);\n return Array.from({ length: end - start + 1 }, (_, i) => start + i);\n });\n\n readonly paginationInfo = computed(() => {\n const total =\n this.serverSide() && this.totalItems() != null\n ? this.totalItems()!\n : this.filteredData().length;\n const page = Math.min(this.currentPage(), this.totalPages());\n const size = this.effectivePageSize();\n const from = Math.min((page - 1) * size + 1, total);\n const to = Math.min(page * size, total);\n return `${from}\\u2013${to} ${this.ofLabel()} ${total} ${\n total === 1 ? this.resultLabelSingular() : this.resultLabelPlural()\n }`;\n });\n\n readonly totalColspan = computed(() => {\n let cols = this.columns().length;\n if (this.selectable()) cols++;\n if (this.expandable()) cols++;\n if (this.showRowNumbers()) cols++;\n return cols;\n });\n\n /** Calcula el offset izquierdo acumulado para columnas frozen-left múltiples.\n * Calculates cumulative left offset for multiple frozen-left columns. */\n readonly _frozenLeftOffsets = computed(() => {\n const offsets = new Map<string, number>();\n let leftPx = 0;\n for (const col of this.columns()) {\n if (col.frozen === 'left') {\n offsets.set(col.key, leftPx);\n if (col.width && col.width !== 'auto') {\n const px = parseFloat(col.width);\n if (!isNaN(px)) leftPx += px;\n }\n }\n }\n return offsets;\n });\n\n readonly _lastFrozenLeftKey = computed(() => {\n const frozenLeft = this.columns().filter((col) => col.frozen === 'left');\n return frozenLeft.at(-1)?.key ?? null;\n });\n\n readonly _firstFrozenRightKey = computed(() => {\n const frozenRight = this.columns().filter((col) => col.frozen === 'right');\n return frozenRight[0]?.key ?? null;\n });\n\n isLastFrozenLeftColumn(key: string): boolean {\n return this._lastFrozenLeftKey() === key;\n }\n\n isFirstFrozenRightColumn(key: string): boolean {\n return this._firstFrozenRightKey() === key;\n }\n\n // ── Expansión de filas ────────────────────────────────────────────────\n private readonly _expandedKeys = signal<Set<unknown>>(new Set());\n\n isRowExpanded(row: Row): boolean {\n return this._expandedKeys().has(this.getRowKey(row));\n }\n\n toggleExpand(row: Row): void {\n const key = this.getRowKey(row);\n const set = new Set(this._expandedKeys());\n if (set.has(key)) set.delete(key);\n else set.add(key);\n this._expandedKeys.set(set);\n }\n\n // ── Selección ─────────────────────────────────────────────────────────\n private readonly _selectedKeys = signal<Set<unknown>>(new Set());\n\n readonly selectedCount = computed(() => this._selectedKeys().size);\n readonly selectedRowsInfo = computed(\n () => `${this.selectedCount()} ${this.selectionSummaryLabel()}`,\n );\n\n /**\n * TRUE cuando TODOS los registros que pasan el filtro activo están seleccionados.\n * A diferencia de una selección global, actúa solo sobre el subconjunto filtrado.\n */\n readonly isAllFilteredSelected = computed(() => {\n const filtered = this.filteredData();\n return (\n filtered.length > 0 && filtered.every((r) => this._selectedKeys().has(this.getRowKey(r)))\n );\n });\n\n readonly isSomeFilteredSelected = computed(\n () =>\n this.filteredData().some((r) => this._selectedKeys().has(this.getRowKey(r))) &&\n !this.isAllFilteredSelected(),\n );\n\n isRowSelected(row: Row): boolean {\n return this._selectedKeys().has(this.getRowKey(row));\n }\n\n toggleRow(row: Row): void {\n const key = this.getRowKey(row);\n const set = new Set(this._selectedKeys());\n if (set.has(key)) set.delete(key);\n else set.add(key);\n this._selectedKeys.set(set);\n this._emitSelection(set);\n }\n\n /** Selecciona/deselecciona SOLO los datos filtrados activos. */\n toggleAll(): void {\n const set = new Set(this._selectedKeys());\n if (this.isAllFilteredSelected()) {\n this.filteredData().forEach((r) => set.delete(this.getRowKey(r)));\n } else {\n this.filteredData().forEach((r) => set.add(this.getRowKey(r)));\n }\n this._selectedKeys.set(set);\n this._emitSelection(set);\n }\n\n clearSelection(): void {\n this._selectedKeys.set(new Set());\n this.selectionChange.emit([]);\n }\n\n private _emitSelection(keys: Set<unknown>): void {\n const selected = this._rows().filter((r) => keys.has(this.getRowKey(r)));\n this.selectionChange.emit(selected);\n }\n\n // ── Navegación ────────────────────────────────────────────────────────\n goToPage(page: number): void {\n const clamped = Math.max(1, Math.min(page, this.totalPages()));\n if (this.serverSide()) {\n this._emitServerState({ page: clamped });\n } else if (this.useUrlState()) {\n this._urlState.setParam(this.pageParam(), String(clamped));\n } else {\n this._internalPage.set(clamped);\n }\n }\n\n sortBy(key: string, event?: MouseEvent): void {\n if (this.multiSort() && event?.shiftKey) {\n // Shift+click: toggle or add column / Shift+click: alterna o añade columna\n const entries = [...this._sortEntries()];\n const idx = entries.findIndex((e) => e.key === key);\n if (idx >= 0) {\n entries[idx] = { key, dir: entries[idx].dir === 'asc' ? 'desc' : 'asc' };\n } else {\n entries.push({ key, dir: 'asc' });\n }\n const val = entries.map((e) => `${e.key}:${e.dir}`).join(',') || null;\n if (this.useUrlState()) {\n this._urlState.setParam(this.multiSortParam(), val);\n } else {\n this._internalMultiSort.set(val ?? '');\n }\n } else if (this.multiSort()) {\n // Single click: replace sort / Click simple: reemplaza el orden\n const current = this._sortEntries().find((e) => e.key === key);\n const dir: 'asc' | 'desc' = current?.dir === 'asc' ? 'desc' : 'asc';\n const val = `${key}:${dir}`;\n if (this.useUrlState()) {\n this._urlState.setParam(this.multiSortParam(), val);\n } else {\n this._internalMultiSort.set(val);\n }\n } else {\n const dir = this.sortKey() === key && this.sortDir() === 'asc' ? 'desc' : 'asc';\n if (this.serverSide()) {\n this._emitServerState({ sortKey: key, sortDir: dir, page: 1 });\n } else if (this.useUrlState()) {\n this._urlState.patchParams({\n [this.sortParam()]: key,\n [this.sortDirParam()]: dir,\n [this.pageParam()]: '1',\n });\n } else {\n this._internalSortKey.set(key);\n this._internalSortDir.set(dir);\n this._internalPage.set(1);\n }\n }\n }\n\n onRowClick(row: Row, _event: MouseEvent): void {\n if (this.selectable()) this.toggleRow(row);\n this.rowClick.emit(row);\n }\n\n onSearch(event: Event): void {\n const q = (event.target as HTMLInputElement).value;\n this.searchChange.emit(q);\n if (this.serverSide()) {\n this._emitServerState({ search: q, page: 1 });\n } else if (this.useUrlState()) {\n this._urlState.patchParams({ [this.searchParam()]: q || null, [this.pageParam()]: '1' });\n } else {\n this._internalSearch.set(q);\n this._internalPage.set(1);\n }\n }\n\n clearSearch(): void {\n if (this.serverSide()) {\n this._emitServerState({ search: '', page: 1 });\n } else if (this.useUrlState()) {\n this._urlState.patchParams({ [this.searchParam()]: null, [this.pageParam()]: '1' });\n } else {\n this._internalSearch.set('');\n this._internalPage.set(1);\n }\n }\n\n onPageSizeChange(value: string | number | { target?: { value?: unknown } } | null): void {\n const normalizedValue =\n value && typeof value === 'object' ? (value.target?.value ?? null) : value;\n const size = Number(normalizedValue);\n if (!Number.isFinite(size) || size <= 0) return;\n this._dynamicPageSize.set(size);\n if (this.serverSide()) {\n this._emitServerState({ pageSize: size, page: 1 });\n } else if (this.useUrlState()) {\n this._urlState.patchParams({ [this.pageParam()]: '1' });\n } else {\n this._internalPage.set(1);\n }\n }\n\n setExactMatch(value: boolean): void {\n this._exactMatch.set(value);\n }\n\n setColumnFilter(colKey: string, value: unknown): void {\n // Column filters are local signal — no URL update avoids scroll jumps.\n // paginatedData already clamps currentPage to totalPages automatically.\n // Los filtros de columna son locales — sin URL para evitar saltos de scroll.\n // paginatedData ya adapta currentPage a totalPages automáticamente.\n this._columnFilters.update((f) => ({ ...f, [colKey]: value }));\n if (this.serverSide()) {\n this._emitServerState({\n columnFilters: { ...this._columnFilters(), [colKey]: value },\n page: 1,\n });\n }\n }\n\n clearColumnFilters(): void {\n this._columnFilters.set({});\n }\n\n // ── Actions ───────────────────────────────────────────────────────────\n isConfirmPending(row: Row, action: NeuTableAction<Row>): boolean {\n const p = this._confirmPending();\n return p !== null && p.rowKey === this.getRowKey(row) && p.actionKey === action.key;\n }\n\n handleAction(row: Row, action: NeuTableAction<Row>): void {\n if (action.confirm) {\n const p = this._confirmPending();\n const rowKey = this.getRowKey(row);\n if (p && p.rowKey === rowKey && p.actionKey === action.key) {\n this._confirmPending.set(null);\n this.actionClick.emit({ action, row });\n } else {\n this._confirmPending.set({ rowKey, actionKey: action.key });\n }\n } else {\n this.actionClick.emit({ action, row });\n }\n }\n\n cancelConfirm(): void {\n this._confirmPending.set(null);\n }\n\n // ── Export ────────────────────────────────────────────────────────────\n exportCsv(): void {\n if (!isPlatformBrowser(this._platformId)) return;\n const cols = this._getExportColumns();\n const headers = cols.map((c) => `\"${c.header.replace(/\"/g, '\"\"')}\"`);\n const rows = this.filteredData().map((row) =>\n cols.map((col) => `\"${this.getCellValue(row, col).replace(/\"/g, '\"\"')}\"`),\n );\n const csv = [headers, ...rows].map((r) => r.join(',')).join('\\r\\n');\n this._downloadBlob(\n new Blob([csv], { type: 'text/csv;charset=utf-8;' }),\n `${this.exportFileName()}.csv`,\n );\n }\n\n exportJson(): void {\n if (!isPlatformBrowser(this._platformId)) return;\n const cols = this._getExportColumns();\n const data = this.filteredData().map((row) => {\n const obj: Record<string, string> = {};\n cols.forEach((col) => (obj[col.key] = this.getCellValue(row, col)));\n return obj;\n });\n this._downloadBlob(\n new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }),\n `${this.exportFileName()}.json`,\n );\n }\n\n private _getExportColumns(): NeuTableColumn[] {\n const keys = this.exportColumns();\n const all = this.columns().filter((c) => c.type !== 'actions');\n return keys.length ? all.filter((c) => keys.includes(c.key)) : all;\n }\n\n private _downloadBlob(blob: Blob, filename: string): void {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n }\n\n // ── Utilidades ────────────────────────────────────────────────────────\n getRowKey(row: Row): unknown {\n return row[this.rowKey()] ?? JSON.stringify(row);\n }\n\n getRowClass(row: Row): string {\n return this.rowClass()?.(row) ?? '';\n }\n\n getCellValue(row: Row, col: NeuTableColumn): string {\n if (col.cell) return col.cell(row);\n const val = row[col.key];\n if (val == null) return '—';\n const locale = col.locale ?? 'es-ES';\n switch (col.type) {\n case 'date': {\n const d = val instanceof Date ? val : new Date(String(val));\n return isNaN(d.getTime())\n ? String(val)\n : d.toLocaleDateString(\n locale,\n col.dateFormat ?? { day: '2-digit', month: '2-digit', year: 'numeric' },\n );\n }\n case 'number':\n return new Intl.NumberFormat(locale, col.numberFormat).format(Number(val));\n case 'currency':\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: col.currencyCode ?? 'EUR',\n ...col.numberFormat,\n }).format(Number(val));\n default:\n return String(val);\n }\n }\n\n getSortPriority(key: string): number {\n if (!this.multiSort()) return -1;\n return this._sortEntries().findIndex((e) => e.key === key);\n }\n\n columnFilterControl(key: string): FormControl<string> {\n let control = this._columnFilterControls.get(key);\n if (!control) {\n control = new FormControl(String(this.getColumnFilterValue(key)), {\n nonNullable: true,\n });\n control.valueChanges\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((value) => this.setColumnFilter(key, value));\n this._columnFilterControls.set(key, control);\n }\n return control;\n }\n\n getColumnFilterValue(key: string): unknown {\n return this._columnFilters()[key] ?? '';\n }\n\n private _emitServerState(patch: Partial<NeuTableServerState>): void {\n const current: NeuTableServerState = {\n page: this.currentPage(),\n pageSize: this.effectivePageSize(),\n search: this.searchQuery(),\n sortKey: this.sortKey(),\n sortDir: this.sortDir(),\n sortEntries: this._sortEntries(),\n columnFilters: this._columnFilters(),\n };\n this.serverStateChange.emit({ ...current, ...patch });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, ElementRef, effect, input, output, computed, signal, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
|
|
3
|
+
import { NeuUrlStateService } from '@neural-ui/core/url-state';
|
|
4
|
+
|
|
5
|
+
// ----------------------------------------------------------------
|
|
6
|
+
// Token de contexto — permite a NeuTabPanelComponent inyectar
|
|
7
|
+
// la instancia padre sin pasar signals manualmente.
|
|
8
|
+
// ----------------------------------------------------------------
|
|
9
|
+
const NEU_TABS_CONTEXT = new InjectionToken('NeuTabsContext');
|
|
10
|
+
/**
|
|
11
|
+
* NeuralUI Tabs Component
|
|
12
|
+
*
|
|
13
|
+
* Sistema de pestañas con estado sincronizado a la URL via NeuUrlStateService. / Tab system with state synchronized to the URL via NeuUrlStateService.
|
|
14
|
+
* El panel activo se determina por ?{tabParam}={tabId}. / The active panel is determined by ?{tabParam}={tabId}.
|
|
15
|
+
*
|
|
16
|
+
* Uso:
|
|
17
|
+
* <neu-tabs [tabs]="tabs" tabParam="tab">
|
|
18
|
+
* <neu-tab-panel tabId="preview">...</neu-tab-panel>
|
|
19
|
+
* <neu-tab-panel tabId="api">...</neu-tab-panel>
|
|
20
|
+
* </neu-tabs>
|
|
21
|
+
*/
|
|
22
|
+
class NeuTabsComponent {
|
|
23
|
+
urlState = inject(NeuUrlStateService);
|
|
24
|
+
elRef = inject(ElementRef);
|
|
25
|
+
resizeObserver;
|
|
26
|
+
constructor() {
|
|
27
|
+
// Actualizar indicador cuando activeTabId cambie — debe estar en el constructor (injection context)
|
|
28
|
+
effect(() => {
|
|
29
|
+
this.activeTabId(); // dependencia reactiva
|
|
30
|
+
requestAnimationFrame(() => this._updateIndicator());
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/** Definición de pestañas / Tab definitions */
|
|
34
|
+
tabs = input([], ...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
|
|
35
|
+
/** QueryParam que almacena la pestaña activa / QueryParam that stores the active tab */
|
|
36
|
+
tabParam = input('tab', ...(ngDevMode ? [{ debugName: "tabParam" }] : /* istanbul ignore next */ []));
|
|
37
|
+
/** Si true, elimina el padding interno de los paneles / If true, removes the internal padding from panels */
|
|
38
|
+
flush = input(false, ...(ngDevMode ? [{ debugName: "flush" }] : /* istanbul ignore next */ []));
|
|
39
|
+
/** Etiqueta accesible del rol tablist / Accessible label for the tablist role */
|
|
40
|
+
ariaLabel = input('Pestañas de contenido', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
41
|
+
/** Emite al cambiar de pestaña / Emits when the tab changes */
|
|
42
|
+
tabChange = output();
|
|
43
|
+
/** ID de la pestaña activa (de la URL o la primera disponible) / Active tab ID (from the URL or the first available) */
|
|
44
|
+
activeTabId = computed(() => {
|
|
45
|
+
const fromUrl = this.urlState.getParam(this.tabParam())();
|
|
46
|
+
const available = this.tabs().find((t) => t.id === fromUrl && !t.disabled);
|
|
47
|
+
if (available)
|
|
48
|
+
return available.id;
|
|
49
|
+
// Fallback: primera pestaña no deshabilitada
|
|
50
|
+
return this.tabs().find((t) => !t.disabled)?.id ?? '';
|
|
51
|
+
}, ...(ngDevMode ? [{ debugName: "activeTabId" }] : /* istanbul ignore next */ []));
|
|
52
|
+
/** Posición del indicador calculada mediante medición DOM / Indicator position calculated via DOM measurement */
|
|
53
|
+
_indicatorLeft = signal('0px', ...(ngDevMode ? [{ debugName: "_indicatorLeft" }] : /* istanbul ignore next */ []));
|
|
54
|
+
_indicatorWidth = signal('0px', ...(ngDevMode ? [{ debugName: "_indicatorWidth" }] : /* istanbul ignore next */ []));
|
|
55
|
+
indicatorStyle = computed(() => `left: ${this._indicatorLeft()}; width: ${this._indicatorWidth()}`, ...(ngDevMode ? [{ debugName: "indicatorStyle" }] : /* istanbul ignore next */ []));
|
|
56
|
+
ngAfterViewInit() {
|
|
57
|
+
this._updateIndicator();
|
|
58
|
+
// Actualizar cuando cambie el tamaño del nav (p.ej. resize de ventana)
|
|
59
|
+
const nav = this.elRef.nativeElement.querySelector('.neu-tabs__nav');
|
|
60
|
+
if (nav && typeof ResizeObserver !== 'undefined') {
|
|
61
|
+
this.resizeObserver = new ResizeObserver(() => this._updateIndicator());
|
|
62
|
+
this.resizeObserver.observe(nav);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
ngOnDestroy() {
|
|
66
|
+
this.resizeObserver?.disconnect();
|
|
67
|
+
}
|
|
68
|
+
_updateIndicator() {
|
|
69
|
+
const nav = this.elRef.nativeElement.querySelector('.neu-tabs__nav');
|
|
70
|
+
if (!nav)
|
|
71
|
+
return;
|
|
72
|
+
const tabEls = nav.querySelectorAll('.neu-tabs__tab');
|
|
73
|
+
const idx = this.tabs().findIndex((t) => t.id === this.activeTabId());
|
|
74
|
+
const tabEl = tabEls[idx];
|
|
75
|
+
if (tabEl) {
|
|
76
|
+
this._indicatorLeft.set(tabEl.offsetLeft + 'px');
|
|
77
|
+
this._indicatorWidth.set(tabEl.offsetWidth + 'px');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
selectTab(tab) {
|
|
81
|
+
if (tab.disabled)
|
|
82
|
+
return;
|
|
83
|
+
this.urlState.setParam(this.tabParam(), tab.id);
|
|
84
|
+
this.tabChange.emit(tab.id);
|
|
85
|
+
requestAnimationFrame(() => this._updateIndicator());
|
|
86
|
+
}
|
|
87
|
+
/** Mueve el foco entre tabs con flechas (roving tabindex — WAI-ARIA Tabs Pattern) / Moves focus between tabs with arrows (roving tabindex — WAI-ARIA Tabs Pattern) */
|
|
88
|
+
focusTab(event, dir) {
|
|
89
|
+
event.preventDefault();
|
|
90
|
+
const enabledTabs = this.tabs().filter((t) => !t.disabled);
|
|
91
|
+
const currentIdx = enabledTabs.findIndex((t) => t.id === this.activeTabId());
|
|
92
|
+
let nextIdx;
|
|
93
|
+
if (dir === 'first') {
|
|
94
|
+
nextIdx = 0;
|
|
95
|
+
}
|
|
96
|
+
else if (dir === 'last') {
|
|
97
|
+
nextIdx = enabledTabs.length - 1;
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
nextIdx = (currentIdx + dir + enabledTabs.length) % enabledTabs.length;
|
|
101
|
+
}
|
|
102
|
+
const next = enabledTabs[nextIdx];
|
|
103
|
+
this.selectTab(next);
|
|
104
|
+
const btn = this.elRef.nativeElement.querySelector(`#neu-tab-${next.id}`);
|
|
105
|
+
btn?.focus();
|
|
106
|
+
}
|
|
107
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuTabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
108
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: NeuTabsComponent, isStandalone: true, selector: "neu-tabs", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: false, transformFunction: null }, tabParam: { classPropertyName: "tabParam", publicName: "tabParam", isSignal: true, isRequired: false, transformFunction: null }, flush: { classPropertyName: "flush", publicName: "flush", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tabChange: "tabChange" }, providers: [{ provide: NEU_TABS_CONTEXT, useExisting: NeuTabsComponent }], ngImport: i0, template: `
|
|
109
|
+
<!-- Barra de pestañas -->
|
|
110
|
+
<div class="neu-tabs" [class.neu-tabs--flush]="flush()">
|
|
111
|
+
<div class="neu-tabs__nav" role="tablist" [attr.aria-label]="ariaLabel()" #navRef>
|
|
112
|
+
@for (tab of tabs(); track tab.id) {
|
|
113
|
+
<button
|
|
114
|
+
class="neu-tabs__tab"
|
|
115
|
+
[class.neu-tabs__tab--active]="activeTabId() === tab.id"
|
|
116
|
+
[class.neu-tabs__tab--disabled]="tab.disabled"
|
|
117
|
+
role="tab"
|
|
118
|
+
[id]="'neu-tab-' + tab.id"
|
|
119
|
+
[attr.aria-selected]="activeTabId() === tab.id"
|
|
120
|
+
[attr.aria-controls]="'neu-tabpanel-' + tab.id"
|
|
121
|
+
[attr.tabindex]="activeTabId() === tab.id ? '0' : '-1'"
|
|
122
|
+
[disabled]="tab.disabled"
|
|
123
|
+
type="button"
|
|
124
|
+
(click)="selectTab(tab)"
|
|
125
|
+
(keydown.arrowRight)="focusTab($any($event), 1)"
|
|
126
|
+
(keydown.arrowLeft)="focusTab($any($event), -1)"
|
|
127
|
+
(keydown.home)="focusTab($any($event), 'first')"
|
|
128
|
+
(keydown.end)="focusTab($any($event), 'last')"
|
|
129
|
+
>
|
|
130
|
+
{{ tab.label }}
|
|
131
|
+
@if (tab.badge) {
|
|
132
|
+
<span class="neu-tabs__tab-badge">{{ tab.badge }}</span>
|
|
133
|
+
}
|
|
134
|
+
</button>
|
|
135
|
+
}
|
|
136
|
+
<!-- Indicador deslizante -->
|
|
137
|
+
<span class="neu-tabs__indicator" [style]="indicatorStyle()"></span>
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
<!-- Paneles (proyectados desde NeuTabPanelComponent) -->
|
|
141
|
+
<div class="neu-tabs__panels">
|
|
142
|
+
<ng-content />
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
`, isInline: true, styles: [".neu-tabs{display:flex;flex-direction:column}.neu-tabs__nav{position:relative;display:flex;border-bottom:1.5px solid var(--neu-border);overflow-x:auto;scrollbar-width:none}.neu-tabs__nav::-webkit-scrollbar{display:none}.neu-tabs__tab{position:relative;display:inline-flex;align-items:center;gap:var(--neu-space-2);padding:var(--neu-space-3) var(--neu-space-5);background:transparent;border:none;font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted);cursor:pointer;white-space:nowrap;flex-shrink:0;transition:color var(--neu-transition),background-color var(--neu-transition);outline:none}.neu-tabs__tab:hover:not(:disabled){color:var(--neu-text);background:var(--neu-surface-2)}.neu-tabs__tab:focus-visible{outline:2px solid var(--neu-primary);outline-offset:-2px;border-radius:var(--neu-radius-sm) var(--neu-radius-sm) 0 0}.neu-tabs__tab--active{color:var(--neu-primary);font-weight:600}.neu-tabs__tab--disabled{opacity:.4;cursor:not-allowed}.neu-tabs__tab-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:var(--neu-radius-full);background:var(--neu-primary-100);color:var(--neu-primary);font-size:10px;font-weight:700;line-height:1}.neu-tabs__indicator{position:absolute;bottom:-1.5px;height:2.5px;background:var(--neu-primary);border-radius:var(--neu-radius-full) var(--neu-radius-full) 0 0;transition:left var(--neu-transition-slow),width var(--neu-transition-slow);pointer-events:none}.neu-tabs__panels{flex:1}.neu-tab-panel{padding-top:1.5rem;animation:neu-tab-fade .18s ease}@keyframes neu-tab-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
146
|
+
}
|
|
147
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuTabsComponent, decorators: [{
|
|
148
|
+
type: Component,
|
|
149
|
+
args: [{ selector: 'neu-tabs', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: NEU_TABS_CONTEXT, useExisting: NeuTabsComponent }], template: `
|
|
150
|
+
<!-- Barra de pestañas -->
|
|
151
|
+
<div class="neu-tabs" [class.neu-tabs--flush]="flush()">
|
|
152
|
+
<div class="neu-tabs__nav" role="tablist" [attr.aria-label]="ariaLabel()" #navRef>
|
|
153
|
+
@for (tab of tabs(); track tab.id) {
|
|
154
|
+
<button
|
|
155
|
+
class="neu-tabs__tab"
|
|
156
|
+
[class.neu-tabs__tab--active]="activeTabId() === tab.id"
|
|
157
|
+
[class.neu-tabs__tab--disabled]="tab.disabled"
|
|
158
|
+
role="tab"
|
|
159
|
+
[id]="'neu-tab-' + tab.id"
|
|
160
|
+
[attr.aria-selected]="activeTabId() === tab.id"
|
|
161
|
+
[attr.aria-controls]="'neu-tabpanel-' + tab.id"
|
|
162
|
+
[attr.tabindex]="activeTabId() === tab.id ? '0' : '-1'"
|
|
163
|
+
[disabled]="tab.disabled"
|
|
164
|
+
type="button"
|
|
165
|
+
(click)="selectTab(tab)"
|
|
166
|
+
(keydown.arrowRight)="focusTab($any($event), 1)"
|
|
167
|
+
(keydown.arrowLeft)="focusTab($any($event), -1)"
|
|
168
|
+
(keydown.home)="focusTab($any($event), 'first')"
|
|
169
|
+
(keydown.end)="focusTab($any($event), 'last')"
|
|
170
|
+
>
|
|
171
|
+
{{ tab.label }}
|
|
172
|
+
@if (tab.badge) {
|
|
173
|
+
<span class="neu-tabs__tab-badge">{{ tab.badge }}</span>
|
|
174
|
+
}
|
|
175
|
+
</button>
|
|
176
|
+
}
|
|
177
|
+
<!-- Indicador deslizante -->
|
|
178
|
+
<span class="neu-tabs__indicator" [style]="indicatorStyle()"></span>
|
|
179
|
+
</div>
|
|
180
|
+
|
|
181
|
+
<!-- Paneles (proyectados desde NeuTabPanelComponent) -->
|
|
182
|
+
<div class="neu-tabs__panels">
|
|
183
|
+
<ng-content />
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
`, styles: [".neu-tabs{display:flex;flex-direction:column}.neu-tabs__nav{position:relative;display:flex;border-bottom:1.5px solid var(--neu-border);overflow-x:auto;scrollbar-width:none}.neu-tabs__nav::-webkit-scrollbar{display:none}.neu-tabs__tab{position:relative;display:inline-flex;align-items:center;gap:var(--neu-space-2);padding:var(--neu-space-3) var(--neu-space-5);background:transparent;border:none;font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted);cursor:pointer;white-space:nowrap;flex-shrink:0;transition:color var(--neu-transition),background-color var(--neu-transition);outline:none}.neu-tabs__tab:hover:not(:disabled){color:var(--neu-text);background:var(--neu-surface-2)}.neu-tabs__tab:focus-visible{outline:2px solid var(--neu-primary);outline-offset:-2px;border-radius:var(--neu-radius-sm) var(--neu-radius-sm) 0 0}.neu-tabs__tab--active{color:var(--neu-primary);font-weight:600}.neu-tabs__tab--disabled{opacity:.4;cursor:not-allowed}.neu-tabs__tab-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:var(--neu-radius-full);background:var(--neu-primary-100);color:var(--neu-primary);font-size:10px;font-weight:700;line-height:1}.neu-tabs__indicator{position:absolute;bottom:-1.5px;height:2.5px;background:var(--neu-primary);border-radius:var(--neu-radius-full) var(--neu-radius-full) 0 0;transition:left var(--neu-transition-slow),width var(--neu-transition-slow);pointer-events:none}.neu-tabs__panels{flex:1}.neu-tab-panel{padding-top:1.5rem;animation:neu-tab-fade .18s ease}@keyframes neu-tab-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
187
|
+
}], ctorParameters: () => [], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: false }] }], tabParam: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabParam", required: false }] }], flush: [{ type: i0.Input, args: [{ isSignal: true, alias: "flush", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], tabChange: [{ type: i0.Output, args: ["tabChange"] }] } });
|
|
188
|
+
// ----------------------------------------------------------------
|
|
189
|
+
// NeuTabPanelComponent — panel individual (usa DI para el contexto)
|
|
190
|
+
// ----------------------------------------------------------------
|
|
191
|
+
/**
|
|
192
|
+
* NeuralUI Tab Panel
|
|
193
|
+
*
|
|
194
|
+
* Panel de contenido asociado a una pestaña de NeuTabsComponent. / Content panel associated with a NeuTabsComponent tab.
|
|
195
|
+
* Solo se renderiza (no oculta con CSS) cuando la pestaña está activa. / Only rendered (not hidden with CSS) when the tab is active.
|
|
196
|
+
*
|
|
197
|
+
* Uso: hijo directo de <neu-tabs>
|
|
198
|
+
* <neu-tab-panel tabId="api">...</neu-tab-panel>
|
|
199
|
+
*/
|
|
200
|
+
class NeuTabPanelComponent {
|
|
201
|
+
tabs = inject(NEU_TABS_CONTEXT, { optional: true });
|
|
202
|
+
/** ID que debe coincidir con NeuTab.id del padre / ID that must match the parent NeuTab.id */
|
|
203
|
+
tabId = input.required(...(ngDevMode ? [{ debugName: "tabId" }] : /* istanbul ignore next */ []));
|
|
204
|
+
isActive = computed(() => this.tabs?.activeTabId() === this.tabId(), ...(ngDevMode ? [{ debugName: "isActive" }] : /* istanbul ignore next */ []));
|
|
205
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuTabPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
206
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: NeuTabPanelComponent, isStandalone: true, selector: "neu-tab-panel", inputs: { tabId: { classPropertyName: "tabId", publicName: "tabId", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
|
|
207
|
+
@if (isActive()) {
|
|
208
|
+
<div
|
|
209
|
+
class="neu-tab-panel"
|
|
210
|
+
role="tabpanel"
|
|
211
|
+
[id]="'neu-tabpanel-' + tabId()"
|
|
212
|
+
[attr.aria-labelledby]="'neu-tab-' + tabId()"
|
|
213
|
+
>
|
|
214
|
+
<ng-content />
|
|
215
|
+
</div>
|
|
216
|
+
}
|
|
217
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
218
|
+
}
|
|
219
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuTabPanelComponent, decorators: [{
|
|
220
|
+
type: Component,
|
|
221
|
+
args: [{
|
|
222
|
+
selector: 'neu-tab-panel',
|
|
223
|
+
imports: [],
|
|
224
|
+
encapsulation: ViewEncapsulation.None,
|
|
225
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
226
|
+
template: `
|
|
227
|
+
@if (isActive()) {
|
|
228
|
+
<div
|
|
229
|
+
class="neu-tab-panel"
|
|
230
|
+
role="tabpanel"
|
|
231
|
+
[id]="'neu-tabpanel-' + tabId()"
|
|
232
|
+
[attr.aria-labelledby]="'neu-tab-' + tabId()"
|
|
233
|
+
>
|
|
234
|
+
<ng-content />
|
|
235
|
+
</div>
|
|
236
|
+
}
|
|
237
|
+
`,
|
|
238
|
+
}]
|
|
239
|
+
}], propDecorators: { tabId: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabId", required: true }] }] } });
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Generated bundle index. Do not edit.
|
|
243
|
+
*/
|
|
244
|
+
|
|
245
|
+
export { NEU_TABS_CONTEXT, NeuTabPanelComponent, NeuTabsComponent };
|
|
246
|
+
//# sourceMappingURL=neural-ui-core-tabs.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"neural-ui-core-tabs.mjs","sources":["../../../../projects/ui-core/tabs/neu-tabs.component.ts","../../../../projects/ui-core/tabs/neural-ui-core-tabs.ts"],"sourcesContent":["import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InjectionToken,\n OnDestroy,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { NeuUrlStateService } from '@neural-ui/core/url-state';\n\n// ----------------------------------------------------------------\n// Token de contexto — permite a NeuTabPanelComponent inyectar\n// la instancia padre sin pasar signals manualmente.\n// ----------------------------------------------------------------\nexport const NEU_TABS_CONTEXT = new InjectionToken<NeuTabsComponent>('NeuTabsContext');\n\nexport interface NeuTab {\n /** ID único de la pestaña — se usa como valor en la URL / Unique tab ID — used as the URL value */\n id: string;\n /** Etiqueta visible / Visible label */\n label: string;\n /** Badge opcional junto al label / Optional badge next to the label */\n badge?: string;\n /** Deshabilita la pestaña sin ocultarla / Disables the tab without hiding it */\n disabled?: boolean;\n}\n\n/**\n * NeuralUI Tabs Component\n *\n * Sistema de pestañas con estado sincronizado a la URL via NeuUrlStateService. / Tab system with state synchronized to the URL via NeuUrlStateService.\n * El panel activo se determina por ?{tabParam}={tabId}. / The active panel is determined by ?{tabParam}={tabId}.\n *\n * Uso:\n * <neu-tabs [tabs]=\"tabs\" tabParam=\"tab\">\n * <neu-tab-panel tabId=\"preview\">...</neu-tab-panel>\n * <neu-tab-panel tabId=\"api\">...</neu-tab-panel>\n * </neu-tabs>\n */\n@Component({\n selector: 'neu-tabs',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [{ provide: NEU_TABS_CONTEXT, useExisting: NeuTabsComponent }],\n template: `\n <!-- Barra de pestañas -->\n <div class=\"neu-tabs\" [class.neu-tabs--flush]=\"flush()\">\n <div class=\"neu-tabs__nav\" role=\"tablist\" [attr.aria-label]=\"ariaLabel()\" #navRef>\n @for (tab of tabs(); track tab.id) {\n <button\n class=\"neu-tabs__tab\"\n [class.neu-tabs__tab--active]=\"activeTabId() === tab.id\"\n [class.neu-tabs__tab--disabled]=\"tab.disabled\"\n role=\"tab\"\n [id]=\"'neu-tab-' + tab.id\"\n [attr.aria-selected]=\"activeTabId() === tab.id\"\n [attr.aria-controls]=\"'neu-tabpanel-' + tab.id\"\n [attr.tabindex]=\"activeTabId() === tab.id ? '0' : '-1'\"\n [disabled]=\"tab.disabled\"\n type=\"button\"\n (click)=\"selectTab(tab)\"\n (keydown.arrowRight)=\"focusTab($any($event), 1)\"\n (keydown.arrowLeft)=\"focusTab($any($event), -1)\"\n (keydown.home)=\"focusTab($any($event), 'first')\"\n (keydown.end)=\"focusTab($any($event), 'last')\"\n >\n {{ tab.label }}\n @if (tab.badge) {\n <span class=\"neu-tabs__tab-badge\">{{ tab.badge }}</span>\n }\n </button>\n }\n <!-- Indicador deslizante -->\n <span class=\"neu-tabs__indicator\" [style]=\"indicatorStyle()\"></span>\n </div>\n\n <!-- Paneles (proyectados desde NeuTabPanelComponent) -->\n <div class=\"neu-tabs__panels\">\n <ng-content />\n </div>\n </div>\n `,\n styleUrl: './neu-tabs.component.scss',\n})\nexport class NeuTabsComponent implements AfterViewInit, OnDestroy {\n private readonly urlState = inject(NeuUrlStateService);\n private readonly elRef = inject(ElementRef);\n private resizeObserver?: ResizeObserver;\n\n constructor() {\n // Actualizar indicador cuando activeTabId cambie — debe estar en el constructor (injection context)\n effect(() => {\n this.activeTabId(); // dependencia reactiva\n requestAnimationFrame(() => this._updateIndicator());\n });\n }\n\n /** Definición de pestañas / Tab definitions */\n tabs = input<NeuTab[]>([]);\n\n /** QueryParam que almacena la pestaña activa / QueryParam that stores the active tab */\n tabParam = input<string>('tab');\n\n /** Si true, elimina el padding interno de los paneles / If true, removes the internal padding from panels */\n flush = input<boolean>(false);\n\n /** Etiqueta accesible del rol tablist / Accessible label for the tablist role */\n ariaLabel = input<string>('Pestañas de contenido');\n\n /** Emite al cambiar de pestaña / Emits when the tab changes */\n tabChange = output<string>();\n\n /** ID de la pestaña activa (de la URL o la primera disponible) / Active tab ID (from the URL or the first available) */\n readonly activeTabId = computed(() => {\n const fromUrl = this.urlState.getParam(this.tabParam())();\n const available = this.tabs().find((t) => t.id === fromUrl && !t.disabled);\n if (available) return available.id;\n // Fallback: primera pestaña no deshabilitada\n return this.tabs().find((t) => !t.disabled)?.id ?? '';\n });\n\n /** Posición del indicador calculada mediante medición DOM / Indicator position calculated via DOM measurement */\n private readonly _indicatorLeft = signal('0px');\n private readonly _indicatorWidth = signal('0px');\n\n readonly indicatorStyle = computed(\n () => `left: ${this._indicatorLeft()}; width: ${this._indicatorWidth()}`,\n );\n\n ngAfterViewInit(): void {\n this._updateIndicator();\n // Actualizar cuando cambie el tamaño del nav (p.ej. resize de ventana)\n const nav = this.elRef.nativeElement.querySelector('.neu-tabs__nav');\n if (nav && typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => this._updateIndicator());\n this.resizeObserver.observe(nav);\n }\n }\n\n ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n }\n\n private _updateIndicator(): void {\n const nav: HTMLElement | null = this.elRef.nativeElement.querySelector('.neu-tabs__nav');\n if (!nav) return;\n const tabEls = nav.querySelectorAll<HTMLElement>('.neu-tabs__tab');\n const idx = this.tabs().findIndex((t) => t.id === this.activeTabId());\n const tabEl = tabEls[idx];\n if (tabEl) {\n this._indicatorLeft.set(tabEl.offsetLeft + 'px');\n this._indicatorWidth.set(tabEl.offsetWidth + 'px');\n }\n }\n\n selectTab(tab: NeuTab): void {\n if (tab.disabled) return;\n this.urlState.setParam(this.tabParam(), tab.id);\n this.tabChange.emit(tab.id);\n requestAnimationFrame(() => this._updateIndicator());\n }\n\n /** Mueve el foco entre tabs con flechas (roving tabindex — WAI-ARIA Tabs Pattern) / Moves focus between tabs with arrows (roving tabindex — WAI-ARIA Tabs Pattern) */\n focusTab(event: Event, dir: 1 | -1 | 'first' | 'last'): void {\n event.preventDefault();\n const enabledTabs = this.tabs().filter((t) => !t.disabled);\n const currentIdx = enabledTabs.findIndex((t) => t.id === this.activeTabId());\n let nextIdx: number;\n if (dir === 'first') {\n nextIdx = 0;\n } else if (dir === 'last') {\n nextIdx = enabledTabs.length - 1;\n } else {\n nextIdx = (currentIdx + dir + enabledTabs.length) % enabledTabs.length;\n }\n const next = enabledTabs[nextIdx];\n this.selectTab(next);\n const btn = (this.elRef.nativeElement as HTMLElement).querySelector(\n `#neu-tab-${next.id}`,\n ) as HTMLElement | null;\n btn?.focus();\n }\n}\n\n// ----------------------------------------------------------------\n// NeuTabPanelComponent — panel individual (usa DI para el contexto)\n// ----------------------------------------------------------------\n\n/**\n * NeuralUI Tab Panel\n *\n * Panel de contenido asociado a una pestaña de NeuTabsComponent. / Content panel associated with a NeuTabsComponent tab.\n * Solo se renderiza (no oculta con CSS) cuando la pestaña está activa. / Only rendered (not hidden with CSS) when the tab is active.\n *\n * Uso: hijo directo de <neu-tabs>\n * <neu-tab-panel tabId=\"api\">...</neu-tab-panel>\n */\n@Component({\n selector: 'neu-tab-panel',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (isActive()) {\n <div\n class=\"neu-tab-panel\"\n role=\"tabpanel\"\n [id]=\"'neu-tabpanel-' + tabId()\"\n [attr.aria-labelledby]=\"'neu-tab-' + tabId()\"\n >\n <ng-content />\n </div>\n }\n `,\n})\nexport class NeuTabPanelComponent {\n private readonly tabs = inject(NEU_TABS_CONTEXT, { optional: true });\n\n /** ID que debe coincidir con NeuTab.id del padre / ID that must match the parent NeuTab.id */\n tabId = input.required<string>();\n\n readonly isActive = computed(() => this.tabs?.activeTabId() === this.tabId());\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|