@life-cockpit/angular-ui-kit 1.11.7 → 1.11.8

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
@@ -120,7 +120,7 @@ export class MyComponent {}
120
120
  | Skeleton | `lc-skeleton` | Loading placeholder |
121
121
  | Spinner | `lc-spinner` | Loading indicator |
122
122
  | Stepper | `lc-stepper` | Step-by-step progress |
123
- | Table | `lc-table` | Data table with sorting, filtering, pagination, formatter callbacks and custom cell templates |
123
+ | Table | `lc-table` | Data table with sorting, filtering, pagination, formatter callbacks, cell styling hooks and custom cell templates |
124
124
  | Toggle Group | `lc-toggle-group` | Segmented toggle |
125
125
 
126
126
  ### Feedback
@@ -6941,6 +6941,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImpo
6941
6941
  * - Size presets (sm, md, lg)
6942
6942
  * - Hoverable row highlighting
6943
6943
  * - Per-column formatter callbacks for display values
6944
+ * - Per-cell class/style callbacks for conditional styling
6944
6945
  * - Custom cell templates via content projection
6945
6946
  * - Composed cells (e.g. avatar + badge + actions)
6946
6947
  * - Responsive horizontal scrolling
@@ -7148,6 +7149,28 @@ class TableComponent {
7148
7149
  return value;
7149
7150
  return column.formatter(value, row, column, this.getAbsoluteIndex(relativeRowIndex));
7150
7151
  }
7152
+ getCellClasses(row, column, relativeRowIndex) {
7153
+ const classes = [];
7154
+ if (column.cssClass)
7155
+ classes.push(column.cssClass);
7156
+ if (typeof column.cellClass === 'string') {
7157
+ classes.push(column.cellClass);
7158
+ }
7159
+ else if (typeof column.cellClass === 'function') {
7160
+ const resolved = column.cellClass(this.getCellValue(row, column.key), row, column, this.getAbsoluteIndex(relativeRowIndex));
7161
+ if (resolved)
7162
+ classes.push(resolved);
7163
+ }
7164
+ return classes.join(' ').trim();
7165
+ }
7166
+ getCellStyles(row, column, relativeRowIndex) {
7167
+ if (!column.cellStyle)
7168
+ return null;
7169
+ if (typeof column.cellStyle === 'function') {
7170
+ return column.cellStyle(this.getCellValue(row, column.key), row, column, this.getAbsoluteIndex(relativeRowIndex));
7171
+ }
7172
+ return column.cellStyle;
7173
+ }
7151
7174
  getCellTemplate(columnKey) {
7152
7175
  return this.cellTemplates?.find((template) => template.columnKey() === columnKey);
7153
7176
  }
@@ -7263,11 +7286,11 @@ class TableComponent {
7263
7286
  return event.target.value;
7264
7287
  }
7265
7288
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7266
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: TableComponent, isStandalone: true, selector: "lc-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, hoverable: { classPropertyName: "hoverable", publicName: "hoverable", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, paginate: { classPropertyName: "paginate", publicName: "paginate", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sort: "sort", rowClick: "rowClick", cellEdit: "cellEdit", selectionChange: "selectionChange" }, queries: [{ propertyName: "cellTemplates", predicate: TableCellDirective }], ngImport: i0, template: "<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" role=\"table\">\n <thead>\n <!-- Filter row -->\n @if (filterable()) {\n <tr class=\"lc-table__filter-row\">\n @if (selectable()) {\n <th class=\"lc-table__select-cell\"></th>\n }\n @for (column of columns(); track column.key) {\n <th>\n @if (column.filterable !== false) {\n <input\n type=\"text\"\n class=\"lc-table__filter-input\"\n [placeholder]=\"'Filter ' + column.label\"\n [value]=\"getFilterValue(column.key)\"\n (input)=\"onFilterChange(column.key, $event)\"\n [attr.aria-label]=\"'Filter by ' + column.label\"\n />\n }\n </th>\n }\n </tr>\n }\n <!-- Header row -->\n <tr>\n @if (selectable()) {\n <th class=\"lc-table__select-cell\" scope=\"col\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"allSelected()\"\n (change)=\"toggleSelectAll()\"\n aria-label=\"Select all rows\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\">\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? 'sorted ascending' : 'sorted descending'\">\n @if (getSortState(column.key) === 'asc') {\n \u2191\n } @else {\n \u2193\n }\n </span>\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (displayData().length === 0) {\n <tr>\n <td [attr.colspan]=\"columns().length + (selectable() ? 1 : 0)\" class=\"lc-table__empty\">\n {{ emptyText() }}\n </td>\n </tr>\n } @else {\n @for (row of displayData(); track $index; let i = $index) {\n <tr\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(i)\"\n (click)=\"onRowClick(row)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected($index)\"\n (change)=\"toggleRowSelect($index)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"'Select row ' + ($index + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"column.cssClass || ''\"\n (dblclick)=\"editable() ? startEdit($index, column.key, getCellValue(row, column.key)) : null\"\n >\n @if (isEditing($index, column.key)) {\n <input\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit($index, column.key)\"\n (keydown)=\"onEditKeydown($event, $index, column.key)\"\n autofocus\n />\n } @else if (hasCustomTemplate(column.key)) {\n <ng-container *ngTemplateOutlet=\"getCellTemplate(column.key)!.template; context: { $implicit: row }\"></ng-container>\n } @else {\n {{ getFormattedCellValue(row, column, i) }}\n }\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Pagination -->\n@if (paginate()) {\n <div class=\"lc-table-pagination\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}\u2013{{ paginationEnd }} of {{ totalRows() }}\n </div>\n <div class=\"lc-table-pagination__controls\">\n <select\n class=\"lc-table-pagination__size\"\n [value]=\"internalPageSize()\"\n (change)=\"onPageSizeChange($event)\"\n aria-label=\"Rows per page\"\n >\n @for (opt of pageSizeOptions(); track opt) {\n <option [value]=\"opt\">{{ opt }} / page</option>\n }\n </select>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() === 0\"\n (click)=\"goToPage(currentPage() - 1)\"\n aria-label=\"Previous page\"\n >\u2039</button>\n <span class=\"lc-table-pagination__page\">\n {{ currentPage() + 1 }} / {{ totalPages() }}\n </span>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() >= totalPages() - 1\"\n (click)=\"goToPage(currentPage() + 1)\"\n aria-label=\"Next page\"\n >\u203A</button>\n </div>\n </div>\n}\n", styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-background);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface);border-bottom:2px solid var(--color-border)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;color:var(--color-text-secondary);font-style:italic}.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-50)}.lc-table--bordered{border:1px solid var(--color-border)}.lc-table--bordered thead tr th,.lc-table--bordered tbody tr td{border-right:1px solid var(--color-divider)}.lc-table--bordered thead tr th:last-child,.lc-table--bordered tbody tr td:last-child{border-right:none}.lc-table--bordered tbody tr{border-bottom:1px solid var(--color-border)}.lc-table--hoverable tbody tr{transition:background-color .15s ease;cursor:pointer}.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-100)}.lc-table--sm thead tr th,.lc-table--sm tbody tr td{padding:var(--lc-density-padding-xs, var(--spacing-2)) var(--lc-density-padding-sm, var(--spacing-3));font-size:var(--typography-font-size-xs)}.lc-table--lg thead tr th,.lc-table--lg tbody tr td{padding:var(--lc-density-padding-md, var(--spacing-4)) var(--spacing-5);font-size:var(--typography-font-size-base)}[data-theme=dark] .lc-table,:root[data-theme=dark] .lc-table{background-color:var(--color-neutral-900)}[data-theme=dark] .lc-table thead,:root[data-theme=dark] .lc-table thead{background-color:var(--color-neutral-800);border-bottom-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th,:root[data-theme=dark] .lc-table thead tr th{color:var(--color-text-primary);background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table thead tr th.sortable:hover,:root[data-theme=dark] .lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th.sorted-asc,[data-theme=dark] .lc-table thead tr th.sorted-desc,:root[data-theme=dark] .lc-table thead tr th.sorted-asc,:root[data-theme=dark] .lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n),:root[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover,:root[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-700)}.lc-table__filter-row th{padding:var(--spacing-2) var(--spacing-4)!important;background-color:var(--color-background)!important;border-bottom:1px solid var(--color-divider)!important}.lc-table__filter-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:1px solid var(--color-border);border-radius:var(--border-radius-sm);font-size:var(--typography-font-size-xs);background-color:var(--color-background);color:var(--color-text-primary);transition:border-color .15s ease}.lc-table__filter-input:focus{outline:none;border-color:var(--color-primary);box-shadow:0 0 0 2px rgba(var(--color-primary-rgb, 59, 130, 246),.15)}.lc-table__filter-input::placeholder{color:var(--color-text-secondary);opacity:.6}.lc-table__select-cell{width:40px;text-align:center!important;padding:var(--spacing-2)!important}.lc-table__checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--color-primary)}.lc-table__row--selected{background-color:var(--color-primary-50, rgba(59, 130, 246, .08))!important}.lc-table__edit-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:2px solid var(--color-primary);border-radius:var(--border-radius-sm);font-size:inherit;background-color:var(--color-background);color:var(--color-text-primary);outline:none}.lc-table-pagination{display:flex;align-items:center;justify-content:space-between;padding:var(--spacing-3) var(--spacing-1);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary)}.lc-table-pagination__info{white-space:nowrap}.lc-table-pagination__controls{display:flex;align-items:center;gap:var(--spacing-2)}.lc-table-pagination__size{appearance:none;padding:var(--spacing-1) var(--spacing-2);border:1px solid var(--color-border);border-radius:var(--border-radius-sm);background-color:var(--color-background);color:var(--color-text-primary);font-size:var(--typography-font-size-xs);cursor:pointer}.lc-table-pagination__btn{appearance:none;border:1px solid var(--color-border);background-color:var(--color-surface);color:var(--color-text-primary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--border-radius-sm);font-size:var(--typography-font-size-base);cursor:pointer;transition:background-color .15s ease}.lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-100)}.lc-table-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.lc-table-pagination__page{white-space:nowrap;min-width:60px;text-align:center}@media(max-width:640px){.lc-table-wrapper--stack .lc-table thead{display:none}.lc-table-wrapper--stack .lc-table tbody tr{display:block;margin-bottom:var(--spacing-4);border:1px solid var(--color-border);border-radius:var(--border-radius-md)}.lc-table-wrapper--stack .lc-table tbody tr td{display:block;text-align:right;padding:var(--spacing-2) var(--spacing-4);border-bottom:1px solid var(--color-divider)}.lc-table-wrapper--stack .lc-table tbody tr td:last-child{border-bottom:none}.lc-table-wrapper--stack .lc-table tbody tr td:before{content:attr(data-label);float:left;font-weight:var(--typography-font-weight-semibold);color:var(--color-text-secondary)}}[data-theme=dark] .lc-table__filter-input,:root[data-theme=dark] .lc-table__filter-input{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table__edit-input,:root[data-theme=dark] .lc-table__edit-input{background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table__row--selected,:root[data-theme=dark] .lc-table__row--selected{background-color:#3b82f61f!important}[data-theme=dark] .lc-table-pagination__size,[data-theme=dark] .lc-table-pagination__btn,:root[data-theme=dark] .lc-table-pagination__size,:root[data-theme=dark] .lc-table-pagination__btn{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table-pagination__size:hover:not(:disabled),[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled),:root[data-theme=dark] .lc-table-pagination__size:hover:not(:disabled),:root[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-700)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7289
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: TableComponent, isStandalone: true, selector: "lc-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, hoverable: { classPropertyName: "hoverable", publicName: "hoverable", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, paginate: { classPropertyName: "paginate", publicName: "paginate", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sort: "sort", rowClick: "rowClick", cellEdit: "cellEdit", selectionChange: "selectionChange" }, queries: [{ propertyName: "cellTemplates", predicate: TableCellDirective }], ngImport: i0, template: "<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" role=\"table\">\n <thead>\n <!-- Filter row -->\n @if (filterable()) {\n <tr class=\"lc-table__filter-row\">\n @if (selectable()) {\n <th class=\"lc-table__select-cell\"></th>\n }\n @for (column of columns(); track column.key) {\n <th>\n @if (column.filterable !== false) {\n <input\n type=\"text\"\n class=\"lc-table__filter-input\"\n [placeholder]=\"'Filter ' + column.label\"\n [value]=\"getFilterValue(column.key)\"\n (input)=\"onFilterChange(column.key, $event)\"\n [attr.aria-label]=\"'Filter by ' + column.label\"\n />\n }\n </th>\n }\n </tr>\n }\n <!-- Header row -->\n <tr>\n @if (selectable()) {\n <th class=\"lc-table__select-cell\" scope=\"col\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"allSelected()\"\n (change)=\"toggleSelectAll()\"\n aria-label=\"Select all rows\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\">\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? 'sorted ascending' : 'sorted descending'\">\n @if (getSortState(column.key) === 'asc') {\n \u2191\n } @else {\n \u2193\n }\n </span>\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (displayData().length === 0) {\n <tr>\n <td [attr.colspan]=\"columns().length + (selectable() ? 1 : 0)\" class=\"lc-table__empty\">\n {{ emptyText() }}\n </td>\n </tr>\n } @else {\n @for (row of displayData(); track $index; let i = $index) {\n <tr\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(i)\"\n (click)=\"onRowClick(row)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected($index)\"\n (change)=\"toggleRowSelect($index)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"'Select row ' + ($index + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"getCellClasses(row, column, i)\"\n [ngStyle]=\"getCellStyles(row, column, i)\"\n (dblclick)=\"editable() ? startEdit($index, column.key, getCellValue(row, column.key)) : null\"\n >\n @if (isEditing($index, column.key)) {\n <input\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit($index, column.key)\"\n (keydown)=\"onEditKeydown($event, $index, column.key)\"\n autofocus\n />\n } @else if (hasCustomTemplate(column.key)) {\n <ng-container *ngTemplateOutlet=\"getCellTemplate(column.key)!.template; context: { $implicit: row }\"></ng-container>\n } @else {\n {{ getFormattedCellValue(row, column, i) }}\n }\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Pagination -->\n@if (paginate()) {\n <div class=\"lc-table-pagination\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}\u2013{{ paginationEnd }} of {{ totalRows() }}\n </div>\n <div class=\"lc-table-pagination__controls\">\n <select\n class=\"lc-table-pagination__size\"\n [value]=\"internalPageSize()\"\n (change)=\"onPageSizeChange($event)\"\n aria-label=\"Rows per page\"\n >\n @for (opt of pageSizeOptions(); track opt) {\n <option [value]=\"opt\">{{ opt }} / page</option>\n }\n </select>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() === 0\"\n (click)=\"goToPage(currentPage() - 1)\"\n aria-label=\"Previous page\"\n >\u2039</button>\n <span class=\"lc-table-pagination__page\">\n {{ currentPage() + 1 }} / {{ totalPages() }}\n </span>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() >= totalPages() - 1\"\n (click)=\"goToPage(currentPage() + 1)\"\n aria-label=\"Next page\"\n >\u203A</button>\n </div>\n </div>\n}\n", styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-background);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface);border-bottom:2px solid var(--color-border)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;color:var(--color-text-secondary);font-style:italic}.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-50)}.lc-table--bordered{border:1px solid var(--color-border)}.lc-table--bordered thead tr th,.lc-table--bordered tbody tr td{border-right:1px solid var(--color-divider)}.lc-table--bordered thead tr th:last-child,.lc-table--bordered tbody tr td:last-child{border-right:none}.lc-table--bordered tbody tr{border-bottom:1px solid var(--color-border)}.lc-table--hoverable tbody tr{transition:background-color .15s ease;cursor:pointer}.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-100)}.lc-table--sm thead tr th,.lc-table--sm tbody tr td{padding:var(--lc-density-padding-xs, var(--spacing-2)) var(--lc-density-padding-sm, var(--spacing-3));font-size:var(--typography-font-size-xs)}.lc-table--lg thead tr th,.lc-table--lg tbody tr td{padding:var(--lc-density-padding-md, var(--spacing-4)) var(--spacing-5);font-size:var(--typography-font-size-base)}[data-theme=dark] .lc-table,:root[data-theme=dark] .lc-table{background-color:var(--color-neutral-900)}[data-theme=dark] .lc-table thead,:root[data-theme=dark] .lc-table thead{background-color:var(--color-neutral-800);border-bottom-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th,:root[data-theme=dark] .lc-table thead tr th{color:var(--color-text-primary);background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table thead tr th.sortable:hover,:root[data-theme=dark] .lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th.sorted-asc,[data-theme=dark] .lc-table thead tr th.sorted-desc,:root[data-theme=dark] .lc-table thead tr th.sorted-asc,:root[data-theme=dark] .lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n),:root[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover,:root[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-700)}.lc-table__filter-row th{padding:var(--spacing-2) var(--spacing-4)!important;background-color:var(--color-background)!important;border-bottom:1px solid var(--color-divider)!important}.lc-table__filter-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:1px solid var(--color-border);border-radius:var(--border-radius-sm);font-size:var(--typography-font-size-xs);background-color:var(--color-background);color:var(--color-text-primary);transition:border-color .15s ease}.lc-table__filter-input:focus{outline:none;border-color:var(--color-primary);box-shadow:0 0 0 2px rgba(var(--color-primary-rgb, 59, 130, 246),.15)}.lc-table__filter-input::placeholder{color:var(--color-text-secondary);opacity:.6}.lc-table__select-cell{width:40px;text-align:center!important;padding:var(--spacing-2)!important}.lc-table__checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--color-primary)}.lc-table__row--selected{background-color:var(--color-primary-50, rgba(59, 130, 246, .08))!important}.lc-table__edit-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:2px solid var(--color-primary);border-radius:var(--border-radius-sm);font-size:inherit;background-color:var(--color-background);color:var(--color-text-primary);outline:none}.lc-table-pagination{display:flex;align-items:center;justify-content:space-between;padding:var(--spacing-3) var(--spacing-1);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary)}.lc-table-pagination__info{white-space:nowrap}.lc-table-pagination__controls{display:flex;align-items:center;gap:var(--spacing-2)}.lc-table-pagination__size{appearance:none;padding:var(--spacing-1) var(--spacing-2);border:1px solid var(--color-border);border-radius:var(--border-radius-sm);background-color:var(--color-background);color:var(--color-text-primary);font-size:var(--typography-font-size-xs);cursor:pointer}.lc-table-pagination__btn{appearance:none;border:1px solid var(--color-border);background-color:var(--color-surface);color:var(--color-text-primary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--border-radius-sm);font-size:var(--typography-font-size-base);cursor:pointer;transition:background-color .15s ease}.lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-100)}.lc-table-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.lc-table-pagination__page{white-space:nowrap;min-width:60px;text-align:center}@media(max-width:640px){.lc-table-wrapper--stack .lc-table thead{display:none}.lc-table-wrapper--stack .lc-table tbody tr{display:block;margin-bottom:var(--spacing-4);border:1px solid var(--color-border);border-radius:var(--border-radius-md)}.lc-table-wrapper--stack .lc-table tbody tr td{display:block;text-align:right;padding:var(--spacing-2) var(--spacing-4);border-bottom:1px solid var(--color-divider)}.lc-table-wrapper--stack .lc-table tbody tr td:last-child{border-bottom:none}.lc-table-wrapper--stack .lc-table tbody tr td:before{content:attr(data-label);float:left;font-weight:var(--typography-font-weight-semibold);color:var(--color-text-secondary)}}[data-theme=dark] .lc-table__filter-input,:root[data-theme=dark] .lc-table__filter-input{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table__edit-input,:root[data-theme=dark] .lc-table__edit-input{background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table__row--selected,:root[data-theme=dark] .lc-table__row--selected{background-color:#3b82f61f!important}[data-theme=dark] .lc-table-pagination__size,[data-theme=dark] .lc-table-pagination__btn,:root[data-theme=dark] .lc-table-pagination__size,:root[data-theme=dark] .lc-table-pagination__btn{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table-pagination__size:hover:not(:disabled),[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled),:root[data-theme=dark] .lc-table-pagination__size:hover:not(:disabled),:root[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-700)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7267
7290
  }
7268
7291
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: TableComponent, decorators: [{
7269
7292
  type: Component,
7270
- args: [{ selector: 'lc-table', standalone: true, imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" role=\"table\">\n <thead>\n <!-- Filter row -->\n @if (filterable()) {\n <tr class=\"lc-table__filter-row\">\n @if (selectable()) {\n <th class=\"lc-table__select-cell\"></th>\n }\n @for (column of columns(); track column.key) {\n <th>\n @if (column.filterable !== false) {\n <input\n type=\"text\"\n class=\"lc-table__filter-input\"\n [placeholder]=\"'Filter ' + column.label\"\n [value]=\"getFilterValue(column.key)\"\n (input)=\"onFilterChange(column.key, $event)\"\n [attr.aria-label]=\"'Filter by ' + column.label\"\n />\n }\n </th>\n }\n </tr>\n }\n <!-- Header row -->\n <tr>\n @if (selectable()) {\n <th class=\"lc-table__select-cell\" scope=\"col\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"allSelected()\"\n (change)=\"toggleSelectAll()\"\n aria-label=\"Select all rows\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\">\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? 'sorted ascending' : 'sorted descending'\">\n @if (getSortState(column.key) === 'asc') {\n \u2191\n } @else {\n \u2193\n }\n </span>\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (displayData().length === 0) {\n <tr>\n <td [attr.colspan]=\"columns().length + (selectable() ? 1 : 0)\" class=\"lc-table__empty\">\n {{ emptyText() }}\n </td>\n </tr>\n } @else {\n @for (row of displayData(); track $index; let i = $index) {\n <tr\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(i)\"\n (click)=\"onRowClick(row)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected($index)\"\n (change)=\"toggleRowSelect($index)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"'Select row ' + ($index + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"column.cssClass || ''\"\n (dblclick)=\"editable() ? startEdit($index, column.key, getCellValue(row, column.key)) : null\"\n >\n @if (isEditing($index, column.key)) {\n <input\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit($index, column.key)\"\n (keydown)=\"onEditKeydown($event, $index, column.key)\"\n autofocus\n />\n } @else if (hasCustomTemplate(column.key)) {\n <ng-container *ngTemplateOutlet=\"getCellTemplate(column.key)!.template; context: { $implicit: row }\"></ng-container>\n } @else {\n {{ getFormattedCellValue(row, column, i) }}\n }\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Pagination -->\n@if (paginate()) {\n <div class=\"lc-table-pagination\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}\u2013{{ paginationEnd }} of {{ totalRows() }}\n </div>\n <div class=\"lc-table-pagination__controls\">\n <select\n class=\"lc-table-pagination__size\"\n [value]=\"internalPageSize()\"\n (change)=\"onPageSizeChange($event)\"\n aria-label=\"Rows per page\"\n >\n @for (opt of pageSizeOptions(); track opt) {\n <option [value]=\"opt\">{{ opt }} / page</option>\n }\n </select>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() === 0\"\n (click)=\"goToPage(currentPage() - 1)\"\n aria-label=\"Previous page\"\n >\u2039</button>\n <span class=\"lc-table-pagination__page\">\n {{ currentPage() + 1 }} / {{ totalPages() }}\n </span>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() >= totalPages() - 1\"\n (click)=\"goToPage(currentPage() + 1)\"\n aria-label=\"Next page\"\n >\u203A</button>\n </div>\n </div>\n}\n", styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-background);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface);border-bottom:2px solid var(--color-border)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;color:var(--color-text-secondary);font-style:italic}.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-50)}.lc-table--bordered{border:1px solid var(--color-border)}.lc-table--bordered thead tr th,.lc-table--bordered tbody tr td{border-right:1px solid var(--color-divider)}.lc-table--bordered thead tr th:last-child,.lc-table--bordered tbody tr td:last-child{border-right:none}.lc-table--bordered tbody tr{border-bottom:1px solid var(--color-border)}.lc-table--hoverable tbody tr{transition:background-color .15s ease;cursor:pointer}.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-100)}.lc-table--sm thead tr th,.lc-table--sm tbody tr td{padding:var(--lc-density-padding-xs, var(--spacing-2)) var(--lc-density-padding-sm, var(--spacing-3));font-size:var(--typography-font-size-xs)}.lc-table--lg thead tr th,.lc-table--lg tbody tr td{padding:var(--lc-density-padding-md, var(--spacing-4)) var(--spacing-5);font-size:var(--typography-font-size-base)}[data-theme=dark] .lc-table,:root[data-theme=dark] .lc-table{background-color:var(--color-neutral-900)}[data-theme=dark] .lc-table thead,:root[data-theme=dark] .lc-table thead{background-color:var(--color-neutral-800);border-bottom-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th,:root[data-theme=dark] .lc-table thead tr th{color:var(--color-text-primary);background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table thead tr th.sortable:hover,:root[data-theme=dark] .lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th.sorted-asc,[data-theme=dark] .lc-table thead tr th.sorted-desc,:root[data-theme=dark] .lc-table thead tr th.sorted-asc,:root[data-theme=dark] .lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n),:root[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover,:root[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-700)}.lc-table__filter-row th{padding:var(--spacing-2) var(--spacing-4)!important;background-color:var(--color-background)!important;border-bottom:1px solid var(--color-divider)!important}.lc-table__filter-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:1px solid var(--color-border);border-radius:var(--border-radius-sm);font-size:var(--typography-font-size-xs);background-color:var(--color-background);color:var(--color-text-primary);transition:border-color .15s ease}.lc-table__filter-input:focus{outline:none;border-color:var(--color-primary);box-shadow:0 0 0 2px rgba(var(--color-primary-rgb, 59, 130, 246),.15)}.lc-table__filter-input::placeholder{color:var(--color-text-secondary);opacity:.6}.lc-table__select-cell{width:40px;text-align:center!important;padding:var(--spacing-2)!important}.lc-table__checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--color-primary)}.lc-table__row--selected{background-color:var(--color-primary-50, rgba(59, 130, 246, .08))!important}.lc-table__edit-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:2px solid var(--color-primary);border-radius:var(--border-radius-sm);font-size:inherit;background-color:var(--color-background);color:var(--color-text-primary);outline:none}.lc-table-pagination{display:flex;align-items:center;justify-content:space-between;padding:var(--spacing-3) var(--spacing-1);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary)}.lc-table-pagination__info{white-space:nowrap}.lc-table-pagination__controls{display:flex;align-items:center;gap:var(--spacing-2)}.lc-table-pagination__size{appearance:none;padding:var(--spacing-1) var(--spacing-2);border:1px solid var(--color-border);border-radius:var(--border-radius-sm);background-color:var(--color-background);color:var(--color-text-primary);font-size:var(--typography-font-size-xs);cursor:pointer}.lc-table-pagination__btn{appearance:none;border:1px solid var(--color-border);background-color:var(--color-surface);color:var(--color-text-primary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--border-radius-sm);font-size:var(--typography-font-size-base);cursor:pointer;transition:background-color .15s ease}.lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-100)}.lc-table-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.lc-table-pagination__page{white-space:nowrap;min-width:60px;text-align:center}@media(max-width:640px){.lc-table-wrapper--stack .lc-table thead{display:none}.lc-table-wrapper--stack .lc-table tbody tr{display:block;margin-bottom:var(--spacing-4);border:1px solid var(--color-border);border-radius:var(--border-radius-md)}.lc-table-wrapper--stack .lc-table tbody tr td{display:block;text-align:right;padding:var(--spacing-2) var(--spacing-4);border-bottom:1px solid var(--color-divider)}.lc-table-wrapper--stack .lc-table tbody tr td:last-child{border-bottom:none}.lc-table-wrapper--stack .lc-table tbody tr td:before{content:attr(data-label);float:left;font-weight:var(--typography-font-weight-semibold);color:var(--color-text-secondary)}}[data-theme=dark] .lc-table__filter-input,:root[data-theme=dark] .lc-table__filter-input{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table__edit-input,:root[data-theme=dark] .lc-table__edit-input{background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table__row--selected,:root[data-theme=dark] .lc-table__row--selected{background-color:#3b82f61f!important}[data-theme=dark] .lc-table-pagination__size,[data-theme=dark] .lc-table-pagination__btn,:root[data-theme=dark] .lc-table-pagination__size,:root[data-theme=dark] .lc-table-pagination__btn{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table-pagination__size:hover:not(:disabled),[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled),:root[data-theme=dark] .lc-table-pagination__size:hover:not(:disabled),:root[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-700)}\n"] }]
7293
+ args: [{ selector: 'lc-table', standalone: true, imports: [NgTemplateOutlet, NgStyle], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" role=\"table\">\n <thead>\n <!-- Filter row -->\n @if (filterable()) {\n <tr class=\"lc-table__filter-row\">\n @if (selectable()) {\n <th class=\"lc-table__select-cell\"></th>\n }\n @for (column of columns(); track column.key) {\n <th>\n @if (column.filterable !== false) {\n <input\n type=\"text\"\n class=\"lc-table__filter-input\"\n [placeholder]=\"'Filter ' + column.label\"\n [value]=\"getFilterValue(column.key)\"\n (input)=\"onFilterChange(column.key, $event)\"\n [attr.aria-label]=\"'Filter by ' + column.label\"\n />\n }\n </th>\n }\n </tr>\n }\n <!-- Header row -->\n <tr>\n @if (selectable()) {\n <th class=\"lc-table__select-cell\" scope=\"col\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"allSelected()\"\n (change)=\"toggleSelectAll()\"\n aria-label=\"Select all rows\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\">\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? 'sorted ascending' : 'sorted descending'\">\n @if (getSortState(column.key) === 'asc') {\n \u2191\n } @else {\n \u2193\n }\n </span>\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (displayData().length === 0) {\n <tr>\n <td [attr.colspan]=\"columns().length + (selectable() ? 1 : 0)\" class=\"lc-table__empty\">\n {{ emptyText() }}\n </td>\n </tr>\n } @else {\n @for (row of displayData(); track $index; let i = $index) {\n <tr\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(i)\"\n (click)=\"onRowClick(row)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected($index)\"\n (change)=\"toggleRowSelect($index)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"'Select row ' + ($index + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"getCellClasses(row, column, i)\"\n [ngStyle]=\"getCellStyles(row, column, i)\"\n (dblclick)=\"editable() ? startEdit($index, column.key, getCellValue(row, column.key)) : null\"\n >\n @if (isEditing($index, column.key)) {\n <input\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit($index, column.key)\"\n (keydown)=\"onEditKeydown($event, $index, column.key)\"\n autofocus\n />\n } @else if (hasCustomTemplate(column.key)) {\n <ng-container *ngTemplateOutlet=\"getCellTemplate(column.key)!.template; context: { $implicit: row }\"></ng-container>\n } @else {\n {{ getFormattedCellValue(row, column, i) }}\n }\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Pagination -->\n@if (paginate()) {\n <div class=\"lc-table-pagination\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}\u2013{{ paginationEnd }} of {{ totalRows() }}\n </div>\n <div class=\"lc-table-pagination__controls\">\n <select\n class=\"lc-table-pagination__size\"\n [value]=\"internalPageSize()\"\n (change)=\"onPageSizeChange($event)\"\n aria-label=\"Rows per page\"\n >\n @for (opt of pageSizeOptions(); track opt) {\n <option [value]=\"opt\">{{ opt }} / page</option>\n }\n </select>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() === 0\"\n (click)=\"goToPage(currentPage() - 1)\"\n aria-label=\"Previous page\"\n >\u2039</button>\n <span class=\"lc-table-pagination__page\">\n {{ currentPage() + 1 }} / {{ totalPages() }}\n </span>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() >= totalPages() - 1\"\n (click)=\"goToPage(currentPage() + 1)\"\n aria-label=\"Next page\"\n >\u203A</button>\n </div>\n </div>\n}\n", styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-background);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface);border-bottom:2px solid var(--color-border)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;color:var(--color-text-secondary);font-style:italic}.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-50)}.lc-table--bordered{border:1px solid var(--color-border)}.lc-table--bordered thead tr th,.lc-table--bordered tbody tr td{border-right:1px solid var(--color-divider)}.lc-table--bordered thead tr th:last-child,.lc-table--bordered tbody tr td:last-child{border-right:none}.lc-table--bordered tbody tr{border-bottom:1px solid var(--color-border)}.lc-table--hoverable tbody tr{transition:background-color .15s ease;cursor:pointer}.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-100)}.lc-table--sm thead tr th,.lc-table--sm tbody tr td{padding:var(--lc-density-padding-xs, var(--spacing-2)) var(--lc-density-padding-sm, var(--spacing-3));font-size:var(--typography-font-size-xs)}.lc-table--lg thead tr th,.lc-table--lg tbody tr td{padding:var(--lc-density-padding-md, var(--spacing-4)) var(--spacing-5);font-size:var(--typography-font-size-base)}[data-theme=dark] .lc-table,:root[data-theme=dark] .lc-table{background-color:var(--color-neutral-900)}[data-theme=dark] .lc-table thead,:root[data-theme=dark] .lc-table thead{background-color:var(--color-neutral-800);border-bottom-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th,:root[data-theme=dark] .lc-table thead tr th{color:var(--color-text-primary);background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table thead tr th.sortable:hover,:root[data-theme=dark] .lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th.sorted-asc,[data-theme=dark] .lc-table thead tr th.sorted-desc,:root[data-theme=dark] .lc-table thead tr th.sorted-asc,:root[data-theme=dark] .lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n),:root[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover,:root[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-700)}.lc-table__filter-row th{padding:var(--spacing-2) var(--spacing-4)!important;background-color:var(--color-background)!important;border-bottom:1px solid var(--color-divider)!important}.lc-table__filter-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:1px solid var(--color-border);border-radius:var(--border-radius-sm);font-size:var(--typography-font-size-xs);background-color:var(--color-background);color:var(--color-text-primary);transition:border-color .15s ease}.lc-table__filter-input:focus{outline:none;border-color:var(--color-primary);box-shadow:0 0 0 2px rgba(var(--color-primary-rgb, 59, 130, 246),.15)}.lc-table__filter-input::placeholder{color:var(--color-text-secondary);opacity:.6}.lc-table__select-cell{width:40px;text-align:center!important;padding:var(--spacing-2)!important}.lc-table__checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--color-primary)}.lc-table__row--selected{background-color:var(--color-primary-50, rgba(59, 130, 246, .08))!important}.lc-table__edit-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:2px solid var(--color-primary);border-radius:var(--border-radius-sm);font-size:inherit;background-color:var(--color-background);color:var(--color-text-primary);outline:none}.lc-table-pagination{display:flex;align-items:center;justify-content:space-between;padding:var(--spacing-3) var(--spacing-1);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary)}.lc-table-pagination__info{white-space:nowrap}.lc-table-pagination__controls{display:flex;align-items:center;gap:var(--spacing-2)}.lc-table-pagination__size{appearance:none;padding:var(--spacing-1) var(--spacing-2);border:1px solid var(--color-border);border-radius:var(--border-radius-sm);background-color:var(--color-background);color:var(--color-text-primary);font-size:var(--typography-font-size-xs);cursor:pointer}.lc-table-pagination__btn{appearance:none;border:1px solid var(--color-border);background-color:var(--color-surface);color:var(--color-text-primary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--border-radius-sm);font-size:var(--typography-font-size-base);cursor:pointer;transition:background-color .15s ease}.lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-100)}.lc-table-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.lc-table-pagination__page{white-space:nowrap;min-width:60px;text-align:center}@media(max-width:640px){.lc-table-wrapper--stack .lc-table thead{display:none}.lc-table-wrapper--stack .lc-table tbody tr{display:block;margin-bottom:var(--spacing-4);border:1px solid var(--color-border);border-radius:var(--border-radius-md)}.lc-table-wrapper--stack .lc-table tbody tr td{display:block;text-align:right;padding:var(--spacing-2) var(--spacing-4);border-bottom:1px solid var(--color-divider)}.lc-table-wrapper--stack .lc-table tbody tr td:last-child{border-bottom:none}.lc-table-wrapper--stack .lc-table tbody tr td:before{content:attr(data-label);float:left;font-weight:var(--typography-font-weight-semibold);color:var(--color-text-secondary)}}[data-theme=dark] .lc-table__filter-input,:root[data-theme=dark] .lc-table__filter-input{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table__edit-input,:root[data-theme=dark] .lc-table__edit-input{background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table__row--selected,:root[data-theme=dark] .lc-table__row--selected{background-color:#3b82f61f!important}[data-theme=dark] .lc-table-pagination__size,[data-theme=dark] .lc-table-pagination__btn,:root[data-theme=dark] .lc-table-pagination__size,:root[data-theme=dark] .lc-table-pagination__btn{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table-pagination__size:hover:not(:disabled),[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled),:root[data-theme=dark] .lc-table-pagination__size:hover:not(:disabled),:root[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-700)}\n"] }]
7271
7294
  }], propDecorators: { cellTemplates: [{
7272
7295
  type: ContentChildren,
7273
7296
  args: [TableCellDirective]