integra-ng 21.0.7 → 21.0.9

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.
@@ -3087,11 +3087,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
3087
3087
  class MenuComponent {
3088
3088
  model = [];
3089
3089
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3090
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: MenuComponent, isStandalone: true, selector: "i-menu", inputs: { model: "model" }, ngImport: i0, template: "<ul class=\"menu\">\n @for(group of model; track $index) {\n <li class=\"menu-group\">\n @if (group.label) {\n <div class=\"menu-group-label\">\n {{ group.label }}\n </div>\n }\n\n <ul class=\"menu-items\">\n @for(item of group.items; track $index) {\n <li class=\"menu-item\">\n <a\n [routerLink]=\"item.routerLink\"\n routerLinkActive=\"active\"\n [routerLinkActiveOptions]=\"{ exact: true }\"\n >\n @if (item.icon) {\n <i class=\"{{ item.icon }}\"></i>\n }\n <span>{{ item.label }}</span>\n </a>\n\n @if (item.items) {\n <ul class=\"submenu\">\n @for(subItem of item.items; track $index) {\n <li class=\"submenu-item\">\n <a\n [routerLink]=\"subItem.routerLink\"\n routerLinkActive=\"active\"\n [routerLinkActiveOptions]=\"{ exact: true }\"\n >\n @if (subItem.icon) {\n <i class=\"{{ subItem.icon }}\"></i>\n }\n <span>{{ subItem.label }}</span>\n </a>\n </li>\n }\n </ul>\n }\n </li>\n }\n </ul>\n\n @if (group.separator) {\n <hr class=\"separator\" />\n }\n </li>\n }\n</ul>\n", styles: [".menu{list-style:none;margin:0;padding:0}.menu-group{margin-bottom:1rem}.menu-group .menu-group-label{font-size:1em;font-weight:600;text-transform:uppercase;padding:.5rem 1rem;color:var(--color-contrast)}.menu-group .menu-items{list-style:none;margin:0;padding:0}.menu-group .menu-items .menu-item a{display:flex;align-items:center;padding:.75rem 1rem;color:var(--color-text-primary);text-decoration:none;font-size:1em;border-left:3px solid transparent;transition:all .2s ease}.menu-group .menu-items .menu-item a i{margin-right:.5rem;font-size:1em}.menu-group .menu-items .menu-item a:hover{background-color:var(--surface-hover);border-radius:6px}.menu-group .menu-items .menu-item a.active{background-color:var(--surface-hover);border-radius:6px;border-left:3px solid var(--color-primary);font-weight:600}.menu-group .menu-items .menu-item .submenu{list-style:none;padding-left:1.5rem}.menu-group .menu-items .menu-item .submenu .submenu-item a{padding:.5rem 1rem;font-size:.95em;color:var(--color-text-tertiary)}.menu-group .menu-items .menu-item .submenu .submenu-item a:hover{background-color:var(--surface-hover);color:var(--color-text-primary)}.menu-group .menu-items .menu-item .submenu .submenu-item a.active{color:var(--color-primary);font-weight:600}.separator{border:none;border-top:1px solid #334155;margin:.5rem 0}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
3090
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: MenuComponent, isStandalone: true, selector: "i-menu", inputs: { model: "model" }, ngImport: i0, template: "<ul class=\"menu\">\n @for(group of model; track $index) {\n <li class=\"menu-group\">\n @if (group.label) {\n <div class=\"menu-group-label\">\n {{ group.label }}\n </div>\n }\n\n <ul class=\"menu-items\">\n @for(item of group.items; track $index) {\n <li class=\"menu-item\">\n <a\n [routerLink]=\"item.routerLink\"\n routerLinkActive=\"active\"\n [routerLinkActiveOptions]=\"{ exact: true }\"\n >\n @if (item.icon) {\n <i class=\"{{ item.icon }}\"></i>\n }\n <span>{{ item.label }}</span>\n </a>\n\n @if (item.items) {\n <ul class=\"submenu\">\n @for(subItem of item.items; track $index) {\n <li class=\"submenu-item\">\n <a\n [routerLink]=\"subItem.routerLink\"\n routerLinkActive=\"active\"\n [routerLinkActiveOptions]=\"{ exact: true }\"\n >\n @if (subItem.icon) {\n <i class=\"{{ subItem.icon }}\"></i>\n }\n <span>{{ subItem.label }}</span>\n </a>\n </li>\n }\n </ul>\n }\n </li>\n }\n </ul>\n\n @if (group.separator) {\n <hr class=\"separator\" />\n }\n </li>\n }\n</ul>\n", styles: [".menu{list-style:none;margin:0;padding:0}.menu-group{margin-bottom:1rem}.menu-group .menu-group-label{font-size:1em;font-weight:600;text-transform:uppercase;padding:.5rem 1rem;color:var(--color-contrast)}.menu-group .menu-items{list-style:none;margin:0;padding:0}.menu-group .menu-items .menu-item a{display:flex;align-items:center;padding:.75rem 1rem;color:var(--color-text-secondary);text-decoration:none;font-size:1em;border-left:3px solid transparent;transition:all .2s ease}.menu-group .menu-items .menu-item a i{margin-right:.5rem;font-size:1em}.menu-group .menu-items .menu-item a:hover{background-color:var(--surface-hover);border-radius:6px}.menu-group .menu-items .menu-item a.active{background-color:var(--surface-hover);border-radius:6px;border-left:3px solid var(--color-primary);font-weight:600}.menu-group .menu-items .menu-item .submenu{list-style:none;padding-left:1.5rem}.menu-group .menu-items .menu-item .submenu .submenu-item a{padding:.5rem 1rem;font-size:.95em;color:var(--color-text-tertiary)}.menu-group .menu-items .menu-item .submenu .submenu-item a:hover{background-color:var(--surface-hover);color:var(--color-text-primary)}.menu-group .menu-items .menu-item .submenu .submenu-item a.active{color:var(--color-primary);font-weight:600}.separator{border:none;border-top:1px solid #334155;margin:.5rem 0}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
3091
3091
  }
3092
3092
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: MenuComponent, decorators: [{
3093
3093
  type: Component,
3094
- args: [{ selector: 'i-menu', imports: [RouterLink, RouterLinkActive], template: "<ul class=\"menu\">\n @for(group of model; track $index) {\n <li class=\"menu-group\">\n @if (group.label) {\n <div class=\"menu-group-label\">\n {{ group.label }}\n </div>\n }\n\n <ul class=\"menu-items\">\n @for(item of group.items; track $index) {\n <li class=\"menu-item\">\n <a\n [routerLink]=\"item.routerLink\"\n routerLinkActive=\"active\"\n [routerLinkActiveOptions]=\"{ exact: true }\"\n >\n @if (item.icon) {\n <i class=\"{{ item.icon }}\"></i>\n }\n <span>{{ item.label }}</span>\n </a>\n\n @if (item.items) {\n <ul class=\"submenu\">\n @for(subItem of item.items; track $index) {\n <li class=\"submenu-item\">\n <a\n [routerLink]=\"subItem.routerLink\"\n routerLinkActive=\"active\"\n [routerLinkActiveOptions]=\"{ exact: true }\"\n >\n @if (subItem.icon) {\n <i class=\"{{ subItem.icon }}\"></i>\n }\n <span>{{ subItem.label }}</span>\n </a>\n </li>\n }\n </ul>\n }\n </li>\n }\n </ul>\n\n @if (group.separator) {\n <hr class=\"separator\" />\n }\n </li>\n }\n</ul>\n", styles: [".menu{list-style:none;margin:0;padding:0}.menu-group{margin-bottom:1rem}.menu-group .menu-group-label{font-size:1em;font-weight:600;text-transform:uppercase;padding:.5rem 1rem;color:var(--color-contrast)}.menu-group .menu-items{list-style:none;margin:0;padding:0}.menu-group .menu-items .menu-item a{display:flex;align-items:center;padding:.75rem 1rem;color:var(--color-text-primary);text-decoration:none;font-size:1em;border-left:3px solid transparent;transition:all .2s ease}.menu-group .menu-items .menu-item a i{margin-right:.5rem;font-size:1em}.menu-group .menu-items .menu-item a:hover{background-color:var(--surface-hover);border-radius:6px}.menu-group .menu-items .menu-item a.active{background-color:var(--surface-hover);border-radius:6px;border-left:3px solid var(--color-primary);font-weight:600}.menu-group .menu-items .menu-item .submenu{list-style:none;padding-left:1.5rem}.menu-group .menu-items .menu-item .submenu .submenu-item a{padding:.5rem 1rem;font-size:.95em;color:var(--color-text-tertiary)}.menu-group .menu-items .menu-item .submenu .submenu-item a:hover{background-color:var(--surface-hover);color:var(--color-text-primary)}.menu-group .menu-items .menu-item .submenu .submenu-item a.active{color:var(--color-primary);font-weight:600}.separator{border:none;border-top:1px solid #334155;margin:.5rem 0}\n"] }]
3094
+ args: [{ selector: 'i-menu', imports: [RouterLink, RouterLinkActive], template: "<ul class=\"menu\">\n @for(group of model; track $index) {\n <li class=\"menu-group\">\n @if (group.label) {\n <div class=\"menu-group-label\">\n {{ group.label }}\n </div>\n }\n\n <ul class=\"menu-items\">\n @for(item of group.items; track $index) {\n <li class=\"menu-item\">\n <a\n [routerLink]=\"item.routerLink\"\n routerLinkActive=\"active\"\n [routerLinkActiveOptions]=\"{ exact: true }\"\n >\n @if (item.icon) {\n <i class=\"{{ item.icon }}\"></i>\n }\n <span>{{ item.label }}</span>\n </a>\n\n @if (item.items) {\n <ul class=\"submenu\">\n @for(subItem of item.items; track $index) {\n <li class=\"submenu-item\">\n <a\n [routerLink]=\"subItem.routerLink\"\n routerLinkActive=\"active\"\n [routerLinkActiveOptions]=\"{ exact: true }\"\n >\n @if (subItem.icon) {\n <i class=\"{{ subItem.icon }}\"></i>\n }\n <span>{{ subItem.label }}</span>\n </a>\n </li>\n }\n </ul>\n }\n </li>\n }\n </ul>\n\n @if (group.separator) {\n <hr class=\"separator\" />\n }\n </li>\n }\n</ul>\n", styles: [".menu{list-style:none;margin:0;padding:0}.menu-group{margin-bottom:1rem}.menu-group .menu-group-label{font-size:1em;font-weight:600;text-transform:uppercase;padding:.5rem 1rem;color:var(--color-contrast)}.menu-group .menu-items{list-style:none;margin:0;padding:0}.menu-group .menu-items .menu-item a{display:flex;align-items:center;padding:.75rem 1rem;color:var(--color-text-secondary);text-decoration:none;font-size:1em;border-left:3px solid transparent;transition:all .2s ease}.menu-group .menu-items .menu-item a i{margin-right:.5rem;font-size:1em}.menu-group .menu-items .menu-item a:hover{background-color:var(--surface-hover);border-radius:6px}.menu-group .menu-items .menu-item a.active{background-color:var(--surface-hover);border-radius:6px;border-left:3px solid var(--color-primary);font-weight:600}.menu-group .menu-items .menu-item .submenu{list-style:none;padding-left:1.5rem}.menu-group .menu-items .menu-item .submenu .submenu-item a{padding:.5rem 1rem;font-size:.95em;color:var(--color-text-tertiary)}.menu-group .menu-items .menu-item .submenu .submenu-item a:hover{background-color:var(--surface-hover);color:var(--color-text-primary)}.menu-group .menu-items .menu-item .submenu .submenu-item a.active{color:var(--color-primary);font-weight:600}.separator{border:none;border-top:1px solid #334155;margin:.5rem 0}\n"] }]
3095
3095
  }], propDecorators: { model: [{
3096
3096
  type: Input
3097
3097
  }] } });
@@ -6212,11 +6212,11 @@ class ITreeView {
6212
6212
  allNodes.length > 0 && selectedNodes.length === allNodes.length;
6213
6213
  }
6214
6214
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ITreeView, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
6215
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ITreeView, isStandalone: true, selector: "i-tree-view", inputs: { value: "value", selectionMode: "selectionMode", selection: "selection", scrollHeight: "scrollHeight", loading: "loading", emptyMessage: "emptyMessage", togglerTemplate: "togglerTemplate", filter: "filter", filterBy: "filterBy", filterMode: "filterMode", filterPlaceholder: "filterPlaceholder", filteredNodes: "filteredNodes", validateDrop: "validateDrop", propagateSelectionUp: "propagateSelectionUp", propagateSelectionDown: "propagateSelectionDown", selectAll: "selectAll" }, outputs: { onNodeSelect: "onNodeSelect", onNodeUnselect: "onNodeUnselect", onNodeExpand: "onNodeExpand", onNodeCollapse: "onNodeCollapse", selectionChange: "selectionChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"i-tree-view-wrapper\" [style.height]=\"scrollHeight\">\n @if (filter) {\n <div class=\"i-tree-view-filter-container\">\n <i-input-text\n [(ngModel)]=\"filterValue\"\n [placeholder]=\"filterPlaceholder\"\n [icon]=\"'pi pi-search'\"\n [useFloatLabel]=\"false\"\n [fluid]=\"true\"\n (input)=\"onFilterKeyup($event)\"\n class=\"i-tree-view-filter\"\n >\n </i-input-text>\n </div>\n } @if (selectAll && selectionMode === 'checkbox') {\n <div class=\"i-tree-view-select-all-container\">\n <div class=\"select-box\">\n <i-checkbox\n [(ngModel)]=\"selectAllChecked\"\n [id]=\"componentId + '-select-all'\"\n [label]=\"'Select All'\"\n (ngModelChange)=\"onSelectAllChange()\"\n />\n </div>\n </div>\n }\n\n <div class=\"i-tree-view-container\">\n @if (loading) {\n <div class=\"i-tree-view-loading\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Loading...</span>\n </div>\n } @else if (filteredValue.length === 0) {\n <div class=\"i-tree-view-empty\">\n <span>{{ emptyMessage }}</span>\n </div>\n } @else {\n <ul class=\"i-tree-view-root\" [attr.id]=\"componentId\" role=\"tree\">\n @for (node of filteredValue; track node.key || $index) {\n <li>\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: node, level: 0 }\"\n ></ng-container>\n </li>\n }\n </ul>\n }\n </div>\n</div>\n\n<ng-template #nodeTemplate let-node let-level=\"level\">\n <div\n class=\"i-tree-view-node\"\n [class.i-tree-view-node--selected]=\"isNodeHighlighted(node)\"\n [class.i-tree-view-node--leaf]=\"!hasChildren(node)\"\n [class.i-tree-view-node--expanded]=\"node.expanded\"\n [class.i-tree-view-node--collapsed]=\"!node.expanded && hasChildren(node)\"\n [class.i-tree-view-node--temporary-highlight]=\"\n isTemporarilyHighlighted(node)\n \"\n [class]=\"node.styleClass\"\n [style.padding-left.rem]=\"level * 1\"\n role=\"treeitem\"\n [attr.aria-expanded]=\"hasChildren(node) ? node.expanded : null\"\n [attr.aria-selected]=\"isSelected(node)\"\n [attr.aria-level]=\"level + 1\"\n tabindex=\"0\"\n (click)=\"onNodeClick($event, node)\"\n (keydown.enter)=\"onNodeClick($event, node)\"\n (keydown.space)=\"$event.preventDefault(); onNodeClick($event, node)\"\n >\n <div class=\"i-tree-view-node-content\">\n @if (hasChildren(node)) {\n <button\n type=\"button\"\n class=\"i-tree-view-toggler\"\n (click)=\"$event.stopPropagation(); toggleNode($event, node)\"\n [attr.aria-label]=\"node.expanded ? 'Collapse' : 'Expand'\"\n tabindex=\"-1\"\n >\n <i [class]=\"getToggleIcon(node)\"></i>\n </button>\n } @else {\n <span class=\"i-tree-view-toggler-spacer\"></span>\n } @if (selectionMode === 'checkbox') {\n <div class=\"i-tree-view-checkbox-container\">\n <i-checkbox\n [checked]=\"isSelected(node) && !isPartiallySelected(node)\"\n [indeterminate]=\"isPartiallySelected(node)\"\n (onChange)=\"onCheckboxChange($event, node)\"\n [id]=\"getCheckboxId(node)\"\n size=\"small\"\n tabindex=\"-1\"\n >\n </i-checkbox>\n </div>\n }\n\n <i [class]=\"getNodeIcon(node)\" class=\"i-tree-view-node-icon\"></i>\n\n <span class=\"i-tree-view-node-label\">{{ node.label }}</span>\n </div>\n </div>\n\n @if (hasChildren(node) && node.expanded) {\n <ul class=\"i-tree-view-children\" role=\"group\">\n @for (child of node.children; track child.key || $index) {\n <li>\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: child, level: level + 1 }\"\n ></ng-container>\n </li>\n }\n </ul>\n }\n</ng-template>\n", styles: [".i-tree-view-wrapper{background-color:var(--surface-ground);color:var(--color-text-primary);border:1px solid var(--surface-border);border-radius:4px;overflow:hidden}.i-tree-view-wrapper .i-tree-view-loading{color:var(--color-text-secondary)}.i-tree-view-wrapper .i-tree-view-loading .pi-spinner{color:var(--color-primary)}.i-tree-view-wrapper .i-tree-view-empty{color:var(--color-text-secondary)}.i-tree-view-node .i-tree-view-node-content:hover{background-color:var(--surface-hover)}.i-tree-view-node.i-tree-view-node--selected .i-tree-view-node-content,.i-tree-view-node.i-tree-view-node--temporary-highlight .i-tree-view-node-content{background-color:var(--surface-hover);border-color:var(--surface-border)}.i-tree-view-node .i-tree-view-toggler{color:var(--color-text-secondary)}.i-tree-view-node .i-tree-view-toggler:hover{background-color:var(--surface-hover);color:var(--color-text-primary)}.i-tree-view-node .i-tree-view-checkbox-container .i-tree-view-partial-overlay i{color:var(--color-primary)}.i-tree-view-node .i-tree-view-node-icon{color:var(--color-text-secondary)}.i-tree-view-node .i-tree-view-node-label{color:var(--color-text-primary)}.i-tree-view-wrapper{padding:8px 0 0 8px;overflow:hidden;box-sizing:border-box;display:flex;flex-direction:column}.i-tree-view-wrapper .i-tree-view-filter-container{position:relative;margin-bottom:8px;flex-shrink:0}.i-tree-view-wrapper .i-tree-view-select-all-container{margin-bottom:8px;padding:8px 0;border-bottom:1px solid var(--border-color, #e0e0e0);flex-shrink:0}.i-tree-view-wrapper .i-tree-view-select-all-container .select-box{padding-left:10px}.i-tree-view-wrapper .i-tree-view-container{overflow:auto;flex:1;min-height:0;box-sizing:border-box}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:hover{background:#00000059}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:active{background:#00000080}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-corner{background:transparent}.i-tree-view-wrapper .i-tree-view-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.i-tree-view-wrapper .i-tree-view-container{scrollbar-color:var(--color-text-secondary) transparent}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar{width:6px;height:6px}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.i-tree-view-wrapper .i-tree-view-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.i-tree-view-wrapper .i-tree-view-loading{display:flex;align-items:center;justify-content:center;gap:8px;padding:20px;font-size:1em}.i-tree-view-wrapper .i-tree-view-loading .pi-spinner{font-size:16px}.i-tree-view-wrapper .i-tree-view-empty{display:flex;align-items:center;justify-content:center;padding:20px;font-size:1em;font-style:italic}.i-tree-view-root,.i-tree-view-children{list-style:none;margin:0;padding:0}.i-tree-view-children{padding-left:0}.i-tree-view-node{position:relative;cursor:pointer;outline:none;-webkit-user-select:none;user-select:none}.i-tree-view-node:focus{outline:none}.i-tree-view-node.i-tree-view-node--temporary-highlight .i-tree-view-node-content{animation:highlight-fade .7s ease-out}.i-tree-view-node .i-tree-view-node-content{display:flex;align-items:center;gap:4px;padding:4px 8px;border-radius:4px;transition:all .15s ease;min-height:32px}.i-tree-view-node .i-tree-view-toggler{display:flex;align-items:center;justify-content:center;width:20px;height:20px;border:none;background:transparent;cursor:pointer;border-radius:2px;transition:all .15s ease}.i-tree-view-node .i-tree-view-toggler:focus{outline:none}.i-tree-view-node .i-tree-view-toggler i{font-size:12px;transition:transform .15s ease}.i-tree-view-node .i-tree-view-toggler-spacer{width:20px;height:20px;flex-shrink:0}.i-tree-view-node .i-tree-view-checkbox-container{display:flex;align-items:center;flex-shrink:0}.i-tree-view-node .i-tree-view-node-icon{font-size:1em;flex-shrink:0}.i-tree-view-node .i-tree-view-node-label{font-size:1em;line-height:1.4;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ICheckbox, selector: "i-checkbox", inputs: ["label", "id", "disabled", "readonly", "size", "indeterminate", "checked"], outputs: ["onChange"] }, { kind: "component", type: IInputText, selector: "i-input-text", inputs: ["label", "type", "id", "fluid", "forceFloated", "hideText", "useFloatLabel", "placeholder", "externalInvalid", "externalErrorMessage", "backgroundStyle", "icon", "readonly", "disabled", "errorMessages"] }] });
6215
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ITreeView, isStandalone: true, selector: "i-tree-view", inputs: { value: "value", selectionMode: "selectionMode", selection: "selection", scrollHeight: "scrollHeight", loading: "loading", emptyMessage: "emptyMessage", togglerTemplate: "togglerTemplate", filter: "filter", filterBy: "filterBy", filterMode: "filterMode", filterPlaceholder: "filterPlaceholder", filteredNodes: "filteredNodes", validateDrop: "validateDrop", propagateSelectionUp: "propagateSelectionUp", propagateSelectionDown: "propagateSelectionDown", selectAll: "selectAll" }, outputs: { onNodeSelect: "onNodeSelect", onNodeUnselect: "onNodeUnselect", onNodeExpand: "onNodeExpand", onNodeCollapse: "onNodeCollapse", selectionChange: "selectionChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"i-tree-view-wrapper\" [style.height]=\"scrollHeight\">\n @if (filter) {\n <div class=\"i-tree-view-filter-container\">\n <i-input-text\n [(ngModel)]=\"filterValue\"\n [placeholder]=\"filterPlaceholder\"\n [icon]=\"'pi pi-search'\"\n [useFloatLabel]=\"false\"\n [fluid]=\"true\"\n (input)=\"onFilterKeyup($event)\"\n class=\"i-tree-view-filter\"\n >\n </i-input-text>\n </div>\n } @if (selectAll && selectionMode === 'checkbox') {\n <div class=\"i-tree-view-select-all-container\">\n <div class=\"select-box\">\n <i-checkbox\n [(ngModel)]=\"selectAllChecked\"\n [id]=\"componentId + '-select-all'\"\n [label]=\"'Select All'\"\n (ngModelChange)=\"onSelectAllChange()\"\n />\n </div>\n </div>\n }\n\n <div class=\"i-tree-view-container\">\n @if (loading) {\n <div class=\"i-tree-view-loading\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Loading...</span>\n </div>\n } @else if (filteredValue.length === 0) {\n <div class=\"i-tree-view-empty\">\n <span>{{ emptyMessage }}</span>\n </div>\n } @else {\n <ul class=\"i-tree-view-root\" [attr.id]=\"componentId\" role=\"tree\">\n @for (node of filteredValue; track node.key || $index) {\n <li>\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: node, level: 0 }\"\n ></ng-container>\n </li>\n }\n </ul>\n }\n </div>\n</div>\n\n<ng-template #nodeTemplate let-node let-level=\"level\">\n <div\n class=\"i-tree-view-node\"\n [class.i-tree-view-node--selected]=\"isNodeHighlighted(node)\"\n [class.i-tree-view-node--leaf]=\"!hasChildren(node)\"\n [class.i-tree-view-node--expanded]=\"node.expanded\"\n [class.i-tree-view-node--collapsed]=\"!node.expanded && hasChildren(node)\"\n [class.i-tree-view-node--temporary-highlight]=\"\n isTemporarilyHighlighted(node)\n \"\n [class]=\"node.styleClass\"\n [style.padding-left.rem]=\"level * 1\"\n role=\"treeitem\"\n [attr.aria-expanded]=\"hasChildren(node) ? node.expanded : null\"\n [attr.aria-selected]=\"isSelected(node)\"\n [attr.aria-level]=\"level + 1\"\n tabindex=\"0\"\n (click)=\"onNodeClick($event, node)\"\n (keydown.enter)=\"onNodeClick($event, node)\"\n (keydown.space)=\"$event.preventDefault(); onNodeClick($event, node)\"\n >\n <div class=\"i-tree-view-node-content\">\n @if (hasChildren(node)) {\n <button\n type=\"button\"\n class=\"i-tree-view-toggler\"\n (click)=\"$event.stopPropagation(); toggleNode($event, node)\"\n [attr.aria-label]=\"node.expanded ? 'Collapse' : 'Expand'\"\n tabindex=\"-1\"\n >\n <i [class]=\"getToggleIcon(node)\"></i>\n </button>\n } @else {\n <span class=\"i-tree-view-toggler-spacer\"></span>\n } @if (selectionMode === 'checkbox') {\n <div class=\"i-tree-view-checkbox-container\">\n <i-checkbox\n [checked]=\"isSelected(node) && !isPartiallySelected(node)\"\n [indeterminate]=\"isPartiallySelected(node)\"\n (onChange)=\"onCheckboxChange($event, node)\"\n [id]=\"getCheckboxId(node)\"\n size=\"small\"\n tabindex=\"-1\"\n >\n </i-checkbox>\n </div>\n }\n\n <i [class]=\"getNodeIcon(node)\" class=\"i-tree-view-node-icon\"></i>\n\n <span class=\"i-tree-view-node-label\">{{ node.label }}</span>\n </div>\n </div>\n\n @if (hasChildren(node) && node.expanded) {\n <ul class=\"i-tree-view-children\" role=\"group\">\n @for (child of node.children; track child.key || $index) {\n <li>\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: child, level: level + 1 }\"\n ></ng-container>\n </li>\n }\n </ul>\n }\n</ng-template>\n", styles: [".i-tree-view-wrapper{background-color:var(--surface-ground);color:var(--color-text-primary);border:1px solid var(--surface-border);border-radius:4px;overflow:hidden}.i-tree-view-wrapper .i-tree-view-select-all-container{border-bottom:1px solid var(--surface-border)}.i-tree-view-wrapper .i-tree-view-loading{color:var(--color-text-secondary)}.i-tree-view-wrapper .i-tree-view-loading .pi-spinner{color:var(--color-primary)}.i-tree-view-wrapper .i-tree-view-empty{color:var(--color-text-secondary)}.i-tree-view-node .i-tree-view-node-content:hover{background-color:var(--surface-hover)}.i-tree-view-node.i-tree-view-node--selected .i-tree-view-node-content,.i-tree-view-node.i-tree-view-node--temporary-highlight .i-tree-view-node-content{background-color:var(--surface-hover);border-color:var(--surface-border)}.i-tree-view-node .i-tree-view-toggler{color:var(--color-text-secondary)}.i-tree-view-node .i-tree-view-toggler:hover{background-color:var(--surface-hover);color:var(--color-text-primary)}.i-tree-view-node .i-tree-view-checkbox-container .i-tree-view-partial-overlay i{color:var(--color-primary)}.i-tree-view-node .i-tree-view-node-icon{color:var(--color-text-secondary)}.i-tree-view-node .i-tree-view-node-label{color:var(--color-text-primary)}.i-tree-view-wrapper{padding:8px 8px 0;overflow:hidden;box-sizing:border-box;display:flex;flex-direction:column}.i-tree-view-wrapper .i-tree-view-filter-container{position:relative;margin-bottom:8px;flex-shrink:0}.i-tree-view-wrapper .i-tree-view-select-all-container{margin-bottom:8px;padding:8px 0;flex-shrink:0}.i-tree-view-wrapper .i-tree-view-select-all-container .select-box{padding-left:10px}.i-tree-view-wrapper .i-tree-view-container{overflow:auto;flex:1;min-height:0;box-sizing:border-box}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:hover{background:#00000059}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:active{background:#00000080}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-corner{background:transparent}.i-tree-view-wrapper .i-tree-view-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.i-tree-view-wrapper .i-tree-view-container{scrollbar-color:var(--color-text-secondary) transparent}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar{width:6px;height:6px}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.i-tree-view-wrapper .i-tree-view-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.i-tree-view-wrapper .i-tree-view-loading{display:flex;align-items:center;justify-content:center;gap:8px;padding:20px;font-size:1em}.i-tree-view-wrapper .i-tree-view-loading .pi-spinner{font-size:16px}.i-tree-view-wrapper .i-tree-view-empty{display:flex;align-items:center;justify-content:center;padding:20px;font-size:1em;font-style:italic}.i-tree-view-root,.i-tree-view-children{list-style:none;margin:0;padding:0}.i-tree-view-children{padding-left:0}.i-tree-view-node{position:relative;cursor:pointer;outline:none;-webkit-user-select:none;user-select:none}.i-tree-view-node:focus{outline:none}.i-tree-view-node.i-tree-view-node--temporary-highlight .i-tree-view-node-content{animation:highlight-fade .7s ease-out}.i-tree-view-node .i-tree-view-node-content{display:flex;align-items:center;gap:4px;padding:4px 8px;border-radius:4px;transition:all .15s ease;min-height:32px}.i-tree-view-node .i-tree-view-toggler{display:flex;align-items:center;justify-content:center;width:20px;height:20px;border:none;background:transparent;cursor:pointer;border-radius:2px;transition:all .15s ease}.i-tree-view-node .i-tree-view-toggler:focus{outline:none}.i-tree-view-node .i-tree-view-toggler i{font-size:12px;transition:transform .15s ease}.i-tree-view-node .i-tree-view-toggler-spacer{width:20px;height:20px;flex-shrink:0}.i-tree-view-node .i-tree-view-checkbox-container{display:flex;align-items:center;flex-shrink:0}.i-tree-view-node .i-tree-view-node-icon{font-size:1em;flex-shrink:0}.i-tree-view-node .i-tree-view-node-label{font-size:1em;line-height:1.4;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ICheckbox, selector: "i-checkbox", inputs: ["label", "id", "disabled", "readonly", "size", "indeterminate", "checked"], outputs: ["onChange"] }, { kind: "component", type: IInputText, selector: "i-input-text", inputs: ["label", "type", "id", "fluid", "forceFloated", "hideText", "useFloatLabel", "placeholder", "externalInvalid", "externalErrorMessage", "backgroundStyle", "icon", "readonly", "disabled", "errorMessages"] }] });
6216
6216
  }
6217
6217
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ITreeView, decorators: [{
6218
6218
  type: Component,
6219
- args: [{ selector: 'i-tree-view', standalone: true, imports: [CommonModule, FormsModule, ICheckbox, IInputText], template: "<div class=\"i-tree-view-wrapper\" [style.height]=\"scrollHeight\">\n @if (filter) {\n <div class=\"i-tree-view-filter-container\">\n <i-input-text\n [(ngModel)]=\"filterValue\"\n [placeholder]=\"filterPlaceholder\"\n [icon]=\"'pi pi-search'\"\n [useFloatLabel]=\"false\"\n [fluid]=\"true\"\n (input)=\"onFilterKeyup($event)\"\n class=\"i-tree-view-filter\"\n >\n </i-input-text>\n </div>\n } @if (selectAll && selectionMode === 'checkbox') {\n <div class=\"i-tree-view-select-all-container\">\n <div class=\"select-box\">\n <i-checkbox\n [(ngModel)]=\"selectAllChecked\"\n [id]=\"componentId + '-select-all'\"\n [label]=\"'Select All'\"\n (ngModelChange)=\"onSelectAllChange()\"\n />\n </div>\n </div>\n }\n\n <div class=\"i-tree-view-container\">\n @if (loading) {\n <div class=\"i-tree-view-loading\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Loading...</span>\n </div>\n } @else if (filteredValue.length === 0) {\n <div class=\"i-tree-view-empty\">\n <span>{{ emptyMessage }}</span>\n </div>\n } @else {\n <ul class=\"i-tree-view-root\" [attr.id]=\"componentId\" role=\"tree\">\n @for (node of filteredValue; track node.key || $index) {\n <li>\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: node, level: 0 }\"\n ></ng-container>\n </li>\n }\n </ul>\n }\n </div>\n</div>\n\n<ng-template #nodeTemplate let-node let-level=\"level\">\n <div\n class=\"i-tree-view-node\"\n [class.i-tree-view-node--selected]=\"isNodeHighlighted(node)\"\n [class.i-tree-view-node--leaf]=\"!hasChildren(node)\"\n [class.i-tree-view-node--expanded]=\"node.expanded\"\n [class.i-tree-view-node--collapsed]=\"!node.expanded && hasChildren(node)\"\n [class.i-tree-view-node--temporary-highlight]=\"\n isTemporarilyHighlighted(node)\n \"\n [class]=\"node.styleClass\"\n [style.padding-left.rem]=\"level * 1\"\n role=\"treeitem\"\n [attr.aria-expanded]=\"hasChildren(node) ? node.expanded : null\"\n [attr.aria-selected]=\"isSelected(node)\"\n [attr.aria-level]=\"level + 1\"\n tabindex=\"0\"\n (click)=\"onNodeClick($event, node)\"\n (keydown.enter)=\"onNodeClick($event, node)\"\n (keydown.space)=\"$event.preventDefault(); onNodeClick($event, node)\"\n >\n <div class=\"i-tree-view-node-content\">\n @if (hasChildren(node)) {\n <button\n type=\"button\"\n class=\"i-tree-view-toggler\"\n (click)=\"$event.stopPropagation(); toggleNode($event, node)\"\n [attr.aria-label]=\"node.expanded ? 'Collapse' : 'Expand'\"\n tabindex=\"-1\"\n >\n <i [class]=\"getToggleIcon(node)\"></i>\n </button>\n } @else {\n <span class=\"i-tree-view-toggler-spacer\"></span>\n } @if (selectionMode === 'checkbox') {\n <div class=\"i-tree-view-checkbox-container\">\n <i-checkbox\n [checked]=\"isSelected(node) && !isPartiallySelected(node)\"\n [indeterminate]=\"isPartiallySelected(node)\"\n (onChange)=\"onCheckboxChange($event, node)\"\n [id]=\"getCheckboxId(node)\"\n size=\"small\"\n tabindex=\"-1\"\n >\n </i-checkbox>\n </div>\n }\n\n <i [class]=\"getNodeIcon(node)\" class=\"i-tree-view-node-icon\"></i>\n\n <span class=\"i-tree-view-node-label\">{{ node.label }}</span>\n </div>\n </div>\n\n @if (hasChildren(node) && node.expanded) {\n <ul class=\"i-tree-view-children\" role=\"group\">\n @for (child of node.children; track child.key || $index) {\n <li>\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: child, level: level + 1 }\"\n ></ng-container>\n </li>\n }\n </ul>\n }\n</ng-template>\n", styles: [".i-tree-view-wrapper{background-color:var(--surface-ground);color:var(--color-text-primary);border:1px solid var(--surface-border);border-radius:4px;overflow:hidden}.i-tree-view-wrapper .i-tree-view-loading{color:var(--color-text-secondary)}.i-tree-view-wrapper .i-tree-view-loading .pi-spinner{color:var(--color-primary)}.i-tree-view-wrapper .i-tree-view-empty{color:var(--color-text-secondary)}.i-tree-view-node .i-tree-view-node-content:hover{background-color:var(--surface-hover)}.i-tree-view-node.i-tree-view-node--selected .i-tree-view-node-content,.i-tree-view-node.i-tree-view-node--temporary-highlight .i-tree-view-node-content{background-color:var(--surface-hover);border-color:var(--surface-border)}.i-tree-view-node .i-tree-view-toggler{color:var(--color-text-secondary)}.i-tree-view-node .i-tree-view-toggler:hover{background-color:var(--surface-hover);color:var(--color-text-primary)}.i-tree-view-node .i-tree-view-checkbox-container .i-tree-view-partial-overlay i{color:var(--color-primary)}.i-tree-view-node .i-tree-view-node-icon{color:var(--color-text-secondary)}.i-tree-view-node .i-tree-view-node-label{color:var(--color-text-primary)}.i-tree-view-wrapper{padding:8px 0 0 8px;overflow:hidden;box-sizing:border-box;display:flex;flex-direction:column}.i-tree-view-wrapper .i-tree-view-filter-container{position:relative;margin-bottom:8px;flex-shrink:0}.i-tree-view-wrapper .i-tree-view-select-all-container{margin-bottom:8px;padding:8px 0;border-bottom:1px solid var(--border-color, #e0e0e0);flex-shrink:0}.i-tree-view-wrapper .i-tree-view-select-all-container .select-box{padding-left:10px}.i-tree-view-wrapper .i-tree-view-container{overflow:auto;flex:1;min-height:0;box-sizing:border-box}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:hover{background:#00000059}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:active{background:#00000080}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-corner{background:transparent}.i-tree-view-wrapper .i-tree-view-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.i-tree-view-wrapper .i-tree-view-container{scrollbar-color:var(--color-text-secondary) transparent}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar{width:6px;height:6px}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.i-tree-view-wrapper .i-tree-view-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.i-tree-view-wrapper .i-tree-view-loading{display:flex;align-items:center;justify-content:center;gap:8px;padding:20px;font-size:1em}.i-tree-view-wrapper .i-tree-view-loading .pi-spinner{font-size:16px}.i-tree-view-wrapper .i-tree-view-empty{display:flex;align-items:center;justify-content:center;padding:20px;font-size:1em;font-style:italic}.i-tree-view-root,.i-tree-view-children{list-style:none;margin:0;padding:0}.i-tree-view-children{padding-left:0}.i-tree-view-node{position:relative;cursor:pointer;outline:none;-webkit-user-select:none;user-select:none}.i-tree-view-node:focus{outline:none}.i-tree-view-node.i-tree-view-node--temporary-highlight .i-tree-view-node-content{animation:highlight-fade .7s ease-out}.i-tree-view-node .i-tree-view-node-content{display:flex;align-items:center;gap:4px;padding:4px 8px;border-radius:4px;transition:all .15s ease;min-height:32px}.i-tree-view-node .i-tree-view-toggler{display:flex;align-items:center;justify-content:center;width:20px;height:20px;border:none;background:transparent;cursor:pointer;border-radius:2px;transition:all .15s ease}.i-tree-view-node .i-tree-view-toggler:focus{outline:none}.i-tree-view-node .i-tree-view-toggler i{font-size:12px;transition:transform .15s ease}.i-tree-view-node .i-tree-view-toggler-spacer{width:20px;height:20px;flex-shrink:0}.i-tree-view-node .i-tree-view-checkbox-container{display:flex;align-items:center;flex-shrink:0}.i-tree-view-node .i-tree-view-node-icon{font-size:1em;flex-shrink:0}.i-tree-view-node .i-tree-view-node-label{font-size:1em;line-height:1.4;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"] }]
6219
+ args: [{ selector: 'i-tree-view', standalone: true, imports: [CommonModule, FormsModule, ICheckbox, IInputText], template: "<div class=\"i-tree-view-wrapper\" [style.height]=\"scrollHeight\">\n @if (filter) {\n <div class=\"i-tree-view-filter-container\">\n <i-input-text\n [(ngModel)]=\"filterValue\"\n [placeholder]=\"filterPlaceholder\"\n [icon]=\"'pi pi-search'\"\n [useFloatLabel]=\"false\"\n [fluid]=\"true\"\n (input)=\"onFilterKeyup($event)\"\n class=\"i-tree-view-filter\"\n >\n </i-input-text>\n </div>\n } @if (selectAll && selectionMode === 'checkbox') {\n <div class=\"i-tree-view-select-all-container\">\n <div class=\"select-box\">\n <i-checkbox\n [(ngModel)]=\"selectAllChecked\"\n [id]=\"componentId + '-select-all'\"\n [label]=\"'Select All'\"\n (ngModelChange)=\"onSelectAllChange()\"\n />\n </div>\n </div>\n }\n\n <div class=\"i-tree-view-container\">\n @if (loading) {\n <div class=\"i-tree-view-loading\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Loading...</span>\n </div>\n } @else if (filteredValue.length === 0) {\n <div class=\"i-tree-view-empty\">\n <span>{{ emptyMessage }}</span>\n </div>\n } @else {\n <ul class=\"i-tree-view-root\" [attr.id]=\"componentId\" role=\"tree\">\n @for (node of filteredValue; track node.key || $index) {\n <li>\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: node, level: 0 }\"\n ></ng-container>\n </li>\n }\n </ul>\n }\n </div>\n</div>\n\n<ng-template #nodeTemplate let-node let-level=\"level\">\n <div\n class=\"i-tree-view-node\"\n [class.i-tree-view-node--selected]=\"isNodeHighlighted(node)\"\n [class.i-tree-view-node--leaf]=\"!hasChildren(node)\"\n [class.i-tree-view-node--expanded]=\"node.expanded\"\n [class.i-tree-view-node--collapsed]=\"!node.expanded && hasChildren(node)\"\n [class.i-tree-view-node--temporary-highlight]=\"\n isTemporarilyHighlighted(node)\n \"\n [class]=\"node.styleClass\"\n [style.padding-left.rem]=\"level * 1\"\n role=\"treeitem\"\n [attr.aria-expanded]=\"hasChildren(node) ? node.expanded : null\"\n [attr.aria-selected]=\"isSelected(node)\"\n [attr.aria-level]=\"level + 1\"\n tabindex=\"0\"\n (click)=\"onNodeClick($event, node)\"\n (keydown.enter)=\"onNodeClick($event, node)\"\n (keydown.space)=\"$event.preventDefault(); onNodeClick($event, node)\"\n >\n <div class=\"i-tree-view-node-content\">\n @if (hasChildren(node)) {\n <button\n type=\"button\"\n class=\"i-tree-view-toggler\"\n (click)=\"$event.stopPropagation(); toggleNode($event, node)\"\n [attr.aria-label]=\"node.expanded ? 'Collapse' : 'Expand'\"\n tabindex=\"-1\"\n >\n <i [class]=\"getToggleIcon(node)\"></i>\n </button>\n } @else {\n <span class=\"i-tree-view-toggler-spacer\"></span>\n } @if (selectionMode === 'checkbox') {\n <div class=\"i-tree-view-checkbox-container\">\n <i-checkbox\n [checked]=\"isSelected(node) && !isPartiallySelected(node)\"\n [indeterminate]=\"isPartiallySelected(node)\"\n (onChange)=\"onCheckboxChange($event, node)\"\n [id]=\"getCheckboxId(node)\"\n size=\"small\"\n tabindex=\"-1\"\n >\n </i-checkbox>\n </div>\n }\n\n <i [class]=\"getNodeIcon(node)\" class=\"i-tree-view-node-icon\"></i>\n\n <span class=\"i-tree-view-node-label\">{{ node.label }}</span>\n </div>\n </div>\n\n @if (hasChildren(node) && node.expanded) {\n <ul class=\"i-tree-view-children\" role=\"group\">\n @for (child of node.children; track child.key || $index) {\n <li>\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: child, level: level + 1 }\"\n ></ng-container>\n </li>\n }\n </ul>\n }\n</ng-template>\n", styles: [".i-tree-view-wrapper{background-color:var(--surface-ground);color:var(--color-text-primary);border:1px solid var(--surface-border);border-radius:4px;overflow:hidden}.i-tree-view-wrapper .i-tree-view-select-all-container{border-bottom:1px solid var(--surface-border)}.i-tree-view-wrapper .i-tree-view-loading{color:var(--color-text-secondary)}.i-tree-view-wrapper .i-tree-view-loading .pi-spinner{color:var(--color-primary)}.i-tree-view-wrapper .i-tree-view-empty{color:var(--color-text-secondary)}.i-tree-view-node .i-tree-view-node-content:hover{background-color:var(--surface-hover)}.i-tree-view-node.i-tree-view-node--selected .i-tree-view-node-content,.i-tree-view-node.i-tree-view-node--temporary-highlight .i-tree-view-node-content{background-color:var(--surface-hover);border-color:var(--surface-border)}.i-tree-view-node .i-tree-view-toggler{color:var(--color-text-secondary)}.i-tree-view-node .i-tree-view-toggler:hover{background-color:var(--surface-hover);color:var(--color-text-primary)}.i-tree-view-node .i-tree-view-checkbox-container .i-tree-view-partial-overlay i{color:var(--color-primary)}.i-tree-view-node .i-tree-view-node-icon{color:var(--color-text-secondary)}.i-tree-view-node .i-tree-view-node-label{color:var(--color-text-primary)}.i-tree-view-wrapper{padding:8px 8px 0;overflow:hidden;box-sizing:border-box;display:flex;flex-direction:column}.i-tree-view-wrapper .i-tree-view-filter-container{position:relative;margin-bottom:8px;flex-shrink:0}.i-tree-view-wrapper .i-tree-view-select-all-container{margin-bottom:8px;padding:8px 0;flex-shrink:0}.i-tree-view-wrapper .i-tree-view-select-all-container .select-box{padding-left:10px}.i-tree-view-wrapper .i-tree-view-container{overflow:auto;flex:1;min-height:0;box-sizing:border-box}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:hover{background:#00000059}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:active{background:#00000080}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-corner{background:transparent}.i-tree-view-wrapper .i-tree-view-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.i-tree-view-wrapper .i-tree-view-container{scrollbar-color:var(--color-text-secondary) transparent}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar{width:6px;height:6px}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.i-tree-view-wrapper .i-tree-view-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.i-tree-view-wrapper .i-tree-view-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.i-tree-view-wrapper .i-tree-view-loading{display:flex;align-items:center;justify-content:center;gap:8px;padding:20px;font-size:1em}.i-tree-view-wrapper .i-tree-view-loading .pi-spinner{font-size:16px}.i-tree-view-wrapper .i-tree-view-empty{display:flex;align-items:center;justify-content:center;padding:20px;font-size:1em;font-style:italic}.i-tree-view-root,.i-tree-view-children{list-style:none;margin:0;padding:0}.i-tree-view-children{padding-left:0}.i-tree-view-node{position:relative;cursor:pointer;outline:none;-webkit-user-select:none;user-select:none}.i-tree-view-node:focus{outline:none}.i-tree-view-node.i-tree-view-node--temporary-highlight .i-tree-view-node-content{animation:highlight-fade .7s ease-out}.i-tree-view-node .i-tree-view-node-content{display:flex;align-items:center;gap:4px;padding:4px 8px;border-radius:4px;transition:all .15s ease;min-height:32px}.i-tree-view-node .i-tree-view-toggler{display:flex;align-items:center;justify-content:center;width:20px;height:20px;border:none;background:transparent;cursor:pointer;border-radius:2px;transition:all .15s ease}.i-tree-view-node .i-tree-view-toggler:focus{outline:none}.i-tree-view-node .i-tree-view-toggler i{font-size:12px;transition:transform .15s ease}.i-tree-view-node .i-tree-view-toggler-spacer{width:20px;height:20px;flex-shrink:0}.i-tree-view-node .i-tree-view-checkbox-container{display:flex;align-items:center;flex-shrink:0}.i-tree-view-node .i-tree-view-node-icon{font-size:1em;flex-shrink:0}.i-tree-view-node .i-tree-view-node-label{font-size:1em;line-height:1.4;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"] }]
6220
6220
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { value: [{
6221
6221
  type: Input
6222
6222
  }], selectionMode: [{
@@ -7196,19 +7196,19 @@ class ITable {
7196
7196
  return this.getCellValue(row, column.field) || '';
7197
7197
  }
7198
7198
  /**
7199
- * Gets the icon color for a cell
7199
+ * Gets the severity/color for a cell (applies to text and icons)
7200
7200
  * @internal
7201
7201
  */
7202
- getCellIconColor(row, column) {
7203
- if (column.type !== 'icon' || !column.iconColor)
7202
+ getCellSeverity(row, column) {
7203
+ if (!column.severity)
7204
7204
  return '';
7205
- if (typeof column.iconColor === 'function') {
7206
- return column.iconColor(row);
7205
+ if (typeof column.severity === 'function') {
7206
+ return String(column.severity(row));
7207
7207
  }
7208
- else if (typeof column.iconColor === 'string') {
7209
- // Check if it's a field reference or a direct color value
7210
- const fieldValue = this.getCellValue(row, column.iconColor);
7211
- return fieldValue || column.iconColor;
7208
+ else if (typeof column.severity === 'string') {
7209
+ // Check if it's a field reference or a direct severity value
7210
+ const fieldValue = this.getCellValue(row, column.severity);
7211
+ return fieldValue || column.severity;
7212
7212
  }
7213
7213
  return '';
7214
7214
  }
@@ -7420,6 +7420,30 @@ class ITable {
7420
7420
  }
7421
7421
  return action.disabled ?? false;
7422
7422
  }
7423
+ /**
7424
+ * Checks if an action is visible for a row
7425
+ * @internal
7426
+ */
7427
+ isActionVisible(action, row) {
7428
+ if (action.visible === undefined)
7429
+ return true;
7430
+ if (typeof action.visible === 'function') {
7431
+ return action.visible(row);
7432
+ }
7433
+ return action.visible;
7434
+ }
7435
+ /**
7436
+ * Gets the tooltip text for an action
7437
+ * @internal
7438
+ */
7439
+ getActionTooltip(action, row) {
7440
+ if (!action.tooltip)
7441
+ return '';
7442
+ if (typeof action.tooltip === 'function') {
7443
+ return action.tooltip(row);
7444
+ }
7445
+ return action.tooltip;
7446
+ }
7423
7447
  // ===== ROW EXPANSION METHODS =====
7424
7448
  /**
7425
7449
  * Toggles row expansion
@@ -7733,7 +7757,7 @@ class ITable {
7733
7757
  return 0;
7734
7758
  }
7735
7759
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ITable, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
7736
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ITable, isStandalone: true, selector: "i-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, groupedData: { classPropertyName: "groupedData", publicName: "groupedData", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: false, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: false, isRequired: false, transformFunction: null }, sortField: { classPropertyName: "sortField", publicName: "sortField", isSignal: false, isRequired: false, transformFunction: null }, sortOrder: { classPropertyName: "sortOrder", publicName: "sortOrder", isSignal: false, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: false, isRequired: false, transformFunction: null }, globalFilter: { classPropertyName: "globalFilter", publicName: "globalFilter", isSignal: false, isRequired: false, transformFunction: null }, filterDelay: { classPropertyName: "filterDelay", publicName: "filterDelay", isSignal: false, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: false, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: false, isRequired: false, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: false, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: false, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: false, isRequired: false, transformFunction: null }, striped: { classPropertyName: "striped", publicName: "striped", isSignal: false, isRequired: false, transformFunction: null }, hoverable: { classPropertyName: "hoverable", publicName: "hoverable", isSignal: false, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: false, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: false, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: false, isRequired: false, transformFunction: null }, scrollable: { classPropertyName: "scrollable", publicName: "scrollable", isSignal: false, isRequired: false, transformFunction: null }, scrollHeight: { classPropertyName: "scrollHeight", publicName: "scrollHeight", isSignal: false, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: false, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: false, isRequired: false, transformFunction: null }, virtualScrollItemSize: { classPropertyName: "virtualScrollItemSize", publicName: "virtualScrollItemSize", isSignal: false, isRequired: false, transformFunction: null }, virtualScrollMinBufferPx: { classPropertyName: "virtualScrollMinBufferPx", publicName: "virtualScrollMinBufferPx", isSignal: false, isRequired: false, transformFunction: null }, virtualScrollMaxBufferPx: { classPropertyName: "virtualScrollMaxBufferPx", publicName: "virtualScrollMaxBufferPx", isSignal: false, isRequired: false, transformFunction: null }, resizableColumns: { classPropertyName: "resizableColumns", publicName: "resizableColumns", isSignal: false, isRequired: false, transformFunction: null }, reorderableColumns: { classPropertyName: "reorderableColumns", publicName: "reorderableColumns", isSignal: false, isRequired: false, transformFunction: null }, rowExpandable: { classPropertyName: "rowExpandable", publicName: "rowExpandable", isSignal: false, isRequired: false, transformFunction: null }, downloadable: { classPropertyName: "downloadable", publicName: "downloadable", isSignal: false, isRequired: false, transformFunction: null }, downloadMode: { classPropertyName: "downloadMode", publicName: "downloadMode", isSignal: false, isRequired: false, transformFunction: null }, downloadFormat: { classPropertyName: "downloadFormat", publicName: "downloadFormat", isSignal: false, isRequired: false, transformFunction: null }, downloadFilename: { classPropertyName: "downloadFilename", publicName: "downloadFilename", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { onSort: "onSort", onFilter: "onFilter", selectionChange: "selectionChange", onSelectionChange: "onSelectionChange", onRowSelect: "onRowSelect", onRowUnselect: "onRowUnselect", onAction: "onAction", onRowExpand: "onRowExpand", onRowCollapse: "onRowCollapse", onDownload: "onDownload" }, host: { listeners: { "document:mousemove": "onColumnResize($event)", "document:mouseup": "onColumnResizeEnd()" } }, viewQueries: [{ propertyName: "virtualScrollViewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], ngImport: i0, template: "<div class=\"i-table-wrapper\" [ngClass]=\"getTableClasses()\">\n <!-- Table Header with ng-content, search, and download -->\n @if (globalFilter || downloadable) {\n <div class=\"i-table-header\">\n <div class=\"i-table-header-start\">\n <ng-content select=\"[header]\"></ng-content>\n </div>\n <div class=\"i-table-header-end\">\n @if (globalFilter) {\n <div class=\"i-table-global-filter\">\n <i-input-text\n [useFloatLabel]=\"false\"\n placeholder=\"Search...\"\n [ngModel]=\"globalFilterValue()\"\n (ngModelChange)=\"onGlobalFilterInput($event)\"\n [fluid]=\"false\"\n [icon]=\"'pi pi-search'\"\n ></i-input-text>\n </div>\n } @if (downloadable) {\n <div class=\"i-table-download\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n icon=\"pi pi-download\"\n label=\"Download\"\n (clicked)=\"handleDownload()\"\n ></i-button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Loading Overlay -->\n @if (loading) {\n <div class=\"i-table-loading-overlay\">\n <i class=\"pi pi-spin pi-spinner i-table-loading-icon\"></i>\n </div>\n }\n\n <!-- Scrollable Table Container -->\n <div\n class=\"i-table-container\"\n [class.i-table-container--scrollable]=\"scrollable || height || scrollHeight\"\n [class.i-table-container--virtual-scroll]=\"virtualScroll\"\n [style.height]=\"virtualScroll ? height || scrollHeight || '400px' : null\"\n [style.max-height]=\"!virtualScroll ? height || scrollHeight || null : null\"\n >\n <!-- Virtual Scroll Mode -->\n @if (virtualScroll) {\n <!-- Sticky Header Table (outside viewport) -->\n <div class=\"i-table-virtual-header\">\n <table class=\"i-table\">\n <thead>\n <!-- Column Filters Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\"></th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"onColumnFilterInput(column.field, $event)\"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n } } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers Row -->\n <tr>\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i [class]=\"getSortIcon(column)\" class=\"i-table-sort-icon\"></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n </table>\n </div>\n\n <!-- Virtual Scroll Viewport (body only) -->\n <cdk-virtual-scroll-viewport\n [itemSize]=\"virtualScrollItemSize\"\n [minBufferPx]=\"virtualScrollMinBufferPx\"\n [maxBufferPx]=\"virtualScrollMaxBufferPx\"\n class=\"i-table-virtual-viewport\"\n >\n <table class=\"i-table i-table-virtual-body\">\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n }\n <!-- Virtual Scroll Rows -->\n <tr\n *cdkVirtualFor=\"\n let row of processedData();\n let rowIndex = index;\n trackBy: trackByRow\n \"\n [style.height.px]=\"virtualScrollItemSize\"\n [class.i-table-row-odd]=\"rowIndex % 2 !== 0\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === 'multiple') {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n } @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [style.color]=\"getCellIconColor(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else {\n {{ formatCellValue(getCellValue(row, column.field), column) }}\n }\n </td>\n } @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n } @else {\n <!-- Non-Virtual Scroll Table -->\n <table class=\"i-table\">\n <!-- Table Header (sticky when scrollable) -->\n <thead>\n <!-- Column Filters Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\"></th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"onColumnFilterInput(column.field, $event)\"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n } } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers Row -->\n <tr>\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i [class]=\"getSortIcon(column)\" class=\"i-table-sort-icon\"></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n\n <!-- Table Body - Grouped Mode -->\n @if (isGroupedMode()) {\n <tbody>\n @for (group of groupedData(); track $index) {\n <!-- Group Header Row -->\n <tr class=\"i-table-group-header\" [ngClass]=\"group.styleClass\">\n <td\n [attr.colspan]=\"\n (getGroupColumns(group).length || columns().length) +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n (click)=\"toggleGroupExpansion(group.label)\"\n >\n <div class=\"i-table-group-header-content\">\n <i\n [class]=\"\n isGroupExpanded(group.label)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n class=\"i-table-group-toggle-icon\"\n ></i>\n <span class=\"i-table-group-label\">{{ group.label }}</span>\n <span class=\"i-table-group-count\">({{ group.data.length }})</span>\n </div>\n </td>\n </tr>\n\n <!-- Group Column Headers (when expanded) -->\n @if (isGroupExpanded(group.label) && group.columns) {\n <tr class=\"i-table-group-columns-header\">\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\"></th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of getGroupColumns(group); track trackByColumn($index,\n column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n >\n {{ column.header }}\n </th>\n } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n }\n\n <!-- Group Data Rows (when expanded) -->\n @if (isGroupExpanded(group.label)) { @if (group.data.length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n (getGroupColumns(group).length || columns().length) +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n } @else { @for (row of group.data; track trackByRow($index, row)) {\n <tr\n class=\"i-table-group-row\"\n [class.i-table-row-odd]=\"$odd\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === 'multiple') {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n } @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n } @for (column of getGroupColumns(group); track trackByColumn($index,\n column)) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [style.color]=\"getCellIconColor(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else {\n {{ formatCellValue(getCellValue(row, column.field), column) }}\n }\n </td>\n } @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n <!-- Expanded Row Content -->\n @if (rowExpandable && isRowExpanded(row)) {\n <tr class=\"i-table-expanded-row\">\n <td\n [attr.colspan]=\"\n (getGroupColumns(group).length || columns().length) +\n (selectionMode === 'multiple' ? 1 : 0) +\n 1 +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <div class=\"i-table-expanded-content\">\n <pre>{{ row | json }}</pre>\n </div>\n </td>\n </tr>\n } } } } }\n </tbody>\n } @else {\n <!-- Table Body - Regular Mode -->\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n } @else { @for (row of processedData(); track trackByRow($index, row);\n let rowIndex = $index) {\n <tr\n [class.i-table-row-odd]=\"$odd\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === 'multiple') {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n } @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [style.color]=\"getCellIconColor(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else {\n {{ formatCellValue(getCellValue(row, column.field), column) }}\n }\n </td>\n } @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n <!-- Expanded Row Content -->\n @if (rowExpandable && isRowExpanded(row)) {\n <tr class=\"i-table-expanded-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n 1 +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <div class=\"i-table-expanded-content\">\n <pre>{{ row | json }}</pre>\n </div>\n </td>\n </tr>\n } } }\n </tbody>\n }\n </table>\n }\n </div>\n</div>\n", styles: [".i-table-wrapper{color:var(--color-text-primary);background:var(--color-component-background)}.i-table-wrapper .i-table-header{background:var(--surface-section);border-bottom:1px solid var(--surface-border)}.i-table-wrapper .i-table-global-filter .i-input-text{background:var(--surface-ground)}.i-table-wrapper .i-table-loading-overlay{background:#ffffffb3}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{color:var(--color-primary)}.i-table-wrapper table thead tr{background:var(--color-component-background)}.i-table-wrapper table thead tr th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table thead tr th.i-table-sortable-column{cursor:pointer}.i-table-wrapper table thead tr th.i-table-sortable-column:hover{background:var(--surface-hover)}.i-table-wrapper table thead tr th.i-table-sorted{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table thead tr th .i-table-sort-icon{color:var(--color-text-secondary)}.i-table-wrapper table thead tr th.i-table-sorted .i-table-sort-icon{color:var(--color-primary)}.i-table-wrapper table thead .i-table-filter-row th{background:var(--color-component-background)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter{border:1px solid var(--surface-border);background:var(--surface-ground);color:var(--color-text-primary)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter:focus{border-color:var(--color-primary);box-shadow:0 2px 10px #0003;outline:none}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter::placeholder{color:var(--color-text-tertiary)}.i-table-wrapper table tbody tr{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody tr td{color:var(--color-text-primary)}.i-table-wrapper table tbody tr.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody tr.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table tbody .i-table-expanded-row{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-expanded-row .i-table-expanded-content{background:var(--surface-ground);border:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-empty-row td{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-header{background:var(--color-component-background);border-bottom:2px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-header td{color:var(--color-text-primary)}.i-table-wrapper table tbody .i-table-group-header:hover{background:var(--surface-hover)}.i-table-wrapper table tbody .i-table-group-header .i-table-group-toggle-icon,.i-table-wrapper table tbody .i-table-group-header .i-table-group-count{color:var(--color-text-secondary)}.i-table-wrapper table tbody .i-table-group-columns-header{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-columns-header th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-row,.i-table-wrapper table tbody .i-table-group-row.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-row.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper.i-table--bordered table,.i-table-wrapper.i-table--bordered table th,.i-table-wrapper.i-table--bordered table td{border:1px solid var(--surface-border)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header):hover{background:var(--surface-hover)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header).i-table-row-selected:hover{background:var(--surface-hover)}.i-table-wrapper .i-table-column-resizer{background:var(--surface-border)}.i-table-wrapper .i-table-column-resizer:hover{background:var(--color-primary)}.i-table-wrapper{position:relative;display:block;border-radius:4px;overflow:visible}.i-table-wrapper.i-table--small table thead th{padding:8px 12px;font-size:13px}.i-table-wrapper.i-table--small table tbody td{padding:6px 12px;font-size:1em}.i-table-wrapper.i-table--small table .i-table-filter-row th{padding:4px 12px}.i-table-wrapper.i-table--large table thead th,.i-table-wrapper.i-table--large table tbody td{padding:16px 20px;font-size:16px}.i-table-wrapper.i-table--large table .i-table-filter-row th{padding:12px 20px}.i-table-wrapper.i-table--scrollable table{table-layout:fixed}.i-table-wrapper.i-table--loading{pointer-events:none;-webkit-user-select:none;user-select:none}.i-table-wrapper .i-table-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;gap:16px}.i-table-wrapper .i-table-header .i-table-header-start{flex:0 1 auto;display:flex;align-items:center}.i-table-wrapper .i-table-header .i-table-header-end{flex:0 1 auto;display:flex;align-items:center;gap:12px;margin-left:auto}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{width:250px}.i-table-wrapper .i-table-header .i-table-header-end .i-table-download{flex-shrink:0}.i-table-wrapper .i-table-loading-overlay{position:absolute;inset:0;z-index:10;display:flex;align-items:center;justify-content:center}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{font-size:32px}.i-table-wrapper .i-table-container{overflow-x:auto}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:#00000059}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:#00000080}.i-table-wrapper .i-table-container::-webkit-scrollbar-corner{background:transparent}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.i-table-wrapper .i-table-container{scrollbar-color:var(--color-text-secondary) transparent}.i-table-wrapper .i-table-container::-webkit-scrollbar{width:6px;height:6px}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.i-table-wrapper .i-table-container--scrollable{overflow-y:auto}.i-table-wrapper .i-table-container--scrollable thead{position:sticky;top:0;z-index:2}.i-table-wrapper .i-table-container--virtual-scroll{overflow:hidden;display:flex;flex-direction:column}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header{flex-shrink:0;overflow:hidden;background:var(--color-surface-50)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header table{width:100%;border-collapse:collapse;table-layout:fixed}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport{flex:1;min-height:0;width:100%}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport .cdk-virtual-scroll-content-wrapper{width:100%}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-body{width:100%;border-collapse:collapse;table-layout:fixed}.i-table-wrapper .i-table-container--virtual-scroll table{display:table;width:100%;border-collapse:collapse}.i-table-wrapper .i-table-container--virtual-scroll tbody{display:table-row-group}.i-table-wrapper .i-table-container--virtual-scroll tr{display:table-row;box-sizing:border-box}.i-table-wrapper .i-table-container--virtual-scroll td,.i-table-wrapper .i-table-container--virtual-scroll th{display:table-cell}.i-table-wrapper table{width:100%;border-collapse:collapse;table-layout:auto}.i-table-wrapper table thead tr th{position:relative;padding:12px 16px;font-weight:600;text-align:left;white-space:nowrap;-webkit-user-select:none;user-select:none}.i-table-wrapper table thead tr th .i-table-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table thead tr th .i-table-header-content .i-table-header-text{flex:1}.i-table-wrapper table thead tr th .i-table-sort-icon{font-size:1em;opacity:.6;transition:opacity .15s ease,color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column{transition:background-color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column .i-table-sort-icon{opacity:.4}.i-table-wrapper table thead tr th.i-table-sortable-column:hover .i-table-sort-icon,.i-table-wrapper table thead tr th.i-table-sortable-column.i-table-sorted .i-table-sort-icon{opacity:1}.i-table-wrapper table thead tr th:hover .i-table-column-resizer{opacity:.5}.i-table-wrapper table thead .i-table-filter-row th{padding:8px 16px}.i-table-wrapper table thead .i-table-filter-row th .i-table-column-filter{width:100%;padding:6px 10px;font-size:1em;border-radius:4px;transition:border-color .15s ease,box-shadow .15s ease}.i-table-wrapper table tbody{display:table-row-group}.i-table-wrapper table tbody tr{transition:background-color .15s ease}.i-table-wrapper table tbody tr td{padding:12px 16px;vertical-align:middle}.i-table-wrapper table tbody .i-table-empty-row td{padding:40px 16px;text-align:center}.i-table-wrapper table tbody .i-table-expanded-row td{padding:0}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content{padding:16px;margin:8px 16px;border-radius:4px}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content pre{margin:0;font-family:monospace;font-size:1em;white-space:pre-wrap;word-wrap:break-word}.i-table-wrapper table tbody .i-table-group-header td{padding:12px 16px;font-weight:600;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease}.i-table-wrapper table tbody .i-table-group-header td:hover{opacity:.8}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-toggle-icon{font-size:.9em;transition:transform .15s ease}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-label{flex:1;font-size:1.1em}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-columns-header th{font-size:.95em;font-weight:600;padding:10px 16px}.i-table-wrapper table tbody .i-table-group-row td{padding-left:32px}.i-table-wrapper table tbody .i-table-group-row td:first-child{padding-left:16px}.i-table-wrapper .i-table-selection-header,.i-table-wrapper .i-table-selection-cell,.i-table-wrapper .i-table-expand-header,.i-table-wrapper .i-table-expand-cell{width:50px;text-align:center}.i-table-wrapper .i-table-actions-header,.i-table-wrapper .i-table-actions-cell{width:auto;white-space:nowrap}.i-table-wrapper .i-table-actions-header .i-table-actions,.i-table-wrapper .i-table-actions-cell .i-table-actions{display:flex;gap:4px;justify-content:flex-end}.i-table-wrapper .i-table-column-resizer{position:absolute;right:0;top:50%;transform:translateY(-50%);width:4px;height:60%;cursor:col-resize;opacity:0;transition:opacity .15s ease,background-color .15s ease}.i-table-wrapper .i-table-column-resizer:hover{opacity:1}@media(max-width:768px){.i-table-wrapper .i-table-header{padding:8px 12px;flex-wrap:wrap}.i-table-wrapper .i-table-header .i-table-header-start{flex:1 1 100%;margin-bottom:8px}.i-table-wrapper .i-table-header .i-table-header-end{flex:1 1 100%;justify-content:flex-end}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{flex:1;max-width:250px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "directive", type: CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "component", type: IInputText, selector: "i-input-text", inputs: ["label", "type", "id", "fluid", "forceFloated", "hideText", "useFloatLabel", "placeholder", "externalInvalid", "externalErrorMessage", "backgroundStyle", "icon", "readonly", "disabled", "errorMessages"] }, { kind: "component", type: IButton, selector: "i-button", inputs: ["severity", "size", "type", "disabled", "outlined", "raised", "text", "icon", "fluid", "loading"], outputs: ["clicked"] }, { kind: "component", type: ICheckbox, selector: "i-checkbox", inputs: ["label", "id", "disabled", "readonly", "size", "indeterminate", "checked"], outputs: ["onChange"] }, { kind: "component", type: NoContentComponent, selector: "i-no-content", inputs: ["icon", "message"] }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }] });
7760
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ITable, isStandalone: true, selector: "i-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, groupedData: { classPropertyName: "groupedData", publicName: "groupedData", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: false, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: false, isRequired: false, transformFunction: null }, sortField: { classPropertyName: "sortField", publicName: "sortField", isSignal: false, isRequired: false, transformFunction: null }, sortOrder: { classPropertyName: "sortOrder", publicName: "sortOrder", isSignal: false, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: false, isRequired: false, transformFunction: null }, globalFilter: { classPropertyName: "globalFilter", publicName: "globalFilter", isSignal: false, isRequired: false, transformFunction: null }, filterDelay: { classPropertyName: "filterDelay", publicName: "filterDelay", isSignal: false, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: false, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: false, isRequired: false, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: false, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: false, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: false, isRequired: false, transformFunction: null }, striped: { classPropertyName: "striped", publicName: "striped", isSignal: false, isRequired: false, transformFunction: null }, hoverable: { classPropertyName: "hoverable", publicName: "hoverable", isSignal: false, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: false, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: false, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: false, isRequired: false, transformFunction: null }, scrollable: { classPropertyName: "scrollable", publicName: "scrollable", isSignal: false, isRequired: false, transformFunction: null }, scrollHeight: { classPropertyName: "scrollHeight", publicName: "scrollHeight", isSignal: false, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: false, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: false, isRequired: false, transformFunction: null }, virtualScrollItemSize: { classPropertyName: "virtualScrollItemSize", publicName: "virtualScrollItemSize", isSignal: false, isRequired: false, transformFunction: null }, virtualScrollMinBufferPx: { classPropertyName: "virtualScrollMinBufferPx", publicName: "virtualScrollMinBufferPx", isSignal: false, isRequired: false, transformFunction: null }, virtualScrollMaxBufferPx: { classPropertyName: "virtualScrollMaxBufferPx", publicName: "virtualScrollMaxBufferPx", isSignal: false, isRequired: false, transformFunction: null }, resizableColumns: { classPropertyName: "resizableColumns", publicName: "resizableColumns", isSignal: false, isRequired: false, transformFunction: null }, reorderableColumns: { classPropertyName: "reorderableColumns", publicName: "reorderableColumns", isSignal: false, isRequired: false, transformFunction: null }, rowExpandable: { classPropertyName: "rowExpandable", publicName: "rowExpandable", isSignal: false, isRequired: false, transformFunction: null }, downloadable: { classPropertyName: "downloadable", publicName: "downloadable", isSignal: false, isRequired: false, transformFunction: null }, downloadMode: { classPropertyName: "downloadMode", publicName: "downloadMode", isSignal: false, isRequired: false, transformFunction: null }, downloadFormat: { classPropertyName: "downloadFormat", publicName: "downloadFormat", isSignal: false, isRequired: false, transformFunction: null }, downloadFilename: { classPropertyName: "downloadFilename", publicName: "downloadFilename", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { onSort: "onSort", onFilter: "onFilter", selectionChange: "selectionChange", onSelectionChange: "onSelectionChange", onRowSelect: "onRowSelect", onRowUnselect: "onRowUnselect", onAction: "onAction", onRowExpand: "onRowExpand", onRowCollapse: "onRowCollapse", onDownload: "onDownload" }, host: { listeners: { "document:mousemove": "onColumnResize($event)", "document:mouseup": "onColumnResizeEnd()" } }, viewQueries: [{ propertyName: "virtualScrollViewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], ngImport: i0, template: "<div class=\"i-table-wrapper\" [ngClass]=\"getTableClasses()\">\n <!-- Table Header with ng-content, search, and download -->\n @if (globalFilter || downloadable) {\n <div class=\"i-table-header\">\n <div class=\"i-table-header-start\">\n <ng-content select=\"[header]\"></ng-content>\n </div>\n <div class=\"i-table-header-end\">\n @if (globalFilter) {\n <div class=\"i-table-global-filter\">\n <i-input-text\n [useFloatLabel]=\"false\"\n placeholder=\"Search...\"\n [ngModel]=\"globalFilterValue()\"\n (ngModelChange)=\"onGlobalFilterInput($event)\"\n [fluid]=\"false\"\n [icon]=\"'pi pi-search'\"\n ></i-input-text>\n </div>\n } @if (downloadable) {\n <div class=\"i-table-download\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n icon=\"pi pi-download\"\n label=\"Download\"\n (clicked)=\"handleDownload()\"\n ></i-button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Loading Overlay -->\n @if (loading) {\n <div class=\"i-table-loading-overlay\">\n <i class=\"pi pi-spin pi-spinner i-table-loading-icon\"></i>\n </div>\n }\n\n <!-- Scrollable Table Container -->\n <div\n class=\"i-table-container\"\n [class.i-table-container--scrollable]=\"scrollable || height || scrollHeight\"\n [class.i-table-container--virtual-scroll]=\"virtualScroll\"\n [style.height]=\"virtualScroll ? height || scrollHeight || '400px' : null\"\n [style.max-height]=\"!virtualScroll ? height || scrollHeight || null : null\"\n >\n <!-- Virtual Scroll Mode -->\n @if (virtualScroll) {\n <!-- Sticky Header Table (outside viewport) -->\n <div class=\"i-table-virtual-header\">\n <table class=\"i-table\">\n <thead>\n <!-- Column Filters Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\"></th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"onColumnFilterInput(column.field, $event)\"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n } } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers Row -->\n <tr>\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i [class]=\"getSortIcon(column)\" class=\"i-table-sort-icon\"></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n </table>\n </div>\n\n <!-- Virtual Scroll Viewport (body only) -->\n <cdk-virtual-scroll-viewport\n [itemSize]=\"virtualScrollItemSize\"\n [minBufferPx]=\"virtualScrollMinBufferPx\"\n [maxBufferPx]=\"virtualScrollMaxBufferPx\"\n class=\"i-table-virtual-viewport\"\n >\n <table class=\"i-table i-table-virtual-body\">\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n }\n <!-- Virtual Scroll Rows -->\n <tr\n *cdkVirtualFor=\"\n let row of processedData();\n let rowIndex = index;\n trackBy: trackByRow\n \"\n [style.height.px]=\"virtualScrollItemSize\"\n [class.i-table-row-odd]=\"rowIndex % 2 !== 0\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === 'multiple') {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n } @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [class.i-severity-icon]=\"getCellSeverity(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else {\n <span [class.i-severity-text]=\"getCellSeverity(row, column)\">\n {{ formatCellValue(getCellValue(row, column.field), column) }}\n </span>\n }\n </td>\n } @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"!isActionVisible(action, row)\"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n } @else {\n <!-- Non-Virtual Scroll Table -->\n <table class=\"i-table\">\n <!-- Table Header (sticky when scrollable) -->\n <thead>\n <!-- Column Filters Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\"></th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"onColumnFilterInput(column.field, $event)\"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n } } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers Row -->\n <tr>\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i [class]=\"getSortIcon(column)\" class=\"i-table-sort-icon\"></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n\n <!-- Table Body - Grouped Mode -->\n @if (isGroupedMode()) {\n <tbody>\n @for (group of groupedData(); track $index) {\n <!-- Group Header Row -->\n <tr class=\"i-table-group-header\" [ngClass]=\"group.styleClass\">\n <td\n [attr.colspan]=\"\n (getGroupColumns(group).length || columns().length) +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n (click)=\"toggleGroupExpansion(group.label)\"\n >\n <div class=\"i-table-group-header-content\">\n <i\n [class]=\"\n isGroupExpanded(group.label)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n class=\"i-table-group-toggle-icon\"\n ></i>\n <span class=\"i-table-group-label\">{{ group.label }}</span>\n <span class=\"i-table-group-count\">({{ group.data.length }})</span>\n </div>\n </td>\n </tr>\n\n <!-- Group Column Headers (when expanded) -->\n @if (isGroupExpanded(group.label) && group.columns) {\n <tr class=\"i-table-group-columns-header\">\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\"></th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of getGroupColumns(group); track trackByColumn($index,\n column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n >\n {{ column.header }}\n </th>\n } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n }\n\n <!-- Group Data Rows (when expanded) -->\n @if (isGroupExpanded(group.label)) { @if (group.data.length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n (getGroupColumns(group).length || columns().length) +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n } @else { @for (row of group.data; track trackByRow($index, row)) {\n <tr\n class=\"i-table-group-row\"\n [class.i-table-row-odd]=\"$odd\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === 'multiple') {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n } @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n } @for (column of getGroupColumns(group); track trackByColumn($index,\n column)) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [class.i-severity-icon]=\"getCellSeverity(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else {\n <span [class.i-severity-text]=\"getCellSeverity(row, column)\">\n {{ formatCellValue(getCellValue(row, column.field), column) }}\n </span>\n }\n </td>\n } @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"!isActionVisible(action, row)\"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n <!-- Expanded Row Content -->\n @if (rowExpandable && isRowExpanded(row)) {\n <tr class=\"i-table-expanded-row\">\n <td\n [attr.colspan]=\"\n (getGroupColumns(group).length || columns().length) +\n (selectionMode === 'multiple' ? 1 : 0) +\n 1 +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <div class=\"i-table-expanded-content\">\n <pre>{{ row | json }}</pre>\n </div>\n </td>\n </tr>\n } } } } }\n </tbody>\n } @else {\n <!-- Table Body - Regular Mode -->\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n } @else { @for (row of processedData(); track trackByRow($index, row);\n let rowIndex = $index) {\n <tr\n [class.i-table-row-odd]=\"$odd\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === 'multiple') {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n } @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [class.i-severity-icon]=\"getCellSeverity(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else {\n <span [class.i-severity-text]=\"getCellSeverity(row, column)\">\n {{ formatCellValue(getCellValue(row, column.field), column) }}\n </span>\n }\n </td>\n } @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"!isActionVisible(action, row)\"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n <!-- Expanded Row Content -->\n @if (rowExpandable && isRowExpanded(row)) {\n <tr class=\"i-table-expanded-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n 1 +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <div class=\"i-table-expanded-content\">\n <pre>{{ row | json }}</pre>\n </div>\n </td>\n </tr>\n } } }\n </tbody>\n }\n </table>\n }\n </div>\n</div>\n", styles: [".i-table-wrapper{color:var(--color-text-primary);background:var(--color-component-background)}.i-table-wrapper .i-table-header{background:var(--surface-section);border-bottom:1px solid var(--surface-border)}.i-table-wrapper .i-table-global-filter .i-input-text{background:var(--surface-ground)}.i-table-wrapper .i-table-loading-overlay{background:#ffffffb3}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{color:var(--color-primary)}.i-table-wrapper table thead tr{background:var(--color-component-background)}.i-table-wrapper table thead tr th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table thead tr th.i-table-sortable-column{cursor:pointer}.i-table-wrapper table thead tr th.i-table-sortable-column:hover{background:var(--surface-hover)}.i-table-wrapper table thead tr th.i-table-sorted{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table thead tr th .i-table-sort-icon{color:var(--color-text-secondary)}.i-table-wrapper table thead tr th.i-table-sorted .i-table-sort-icon{color:var(--color-primary)}.i-table-wrapper table thead .i-table-filter-row th{background:var(--color-component-background)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter{border:1px solid var(--surface-border);background:var(--surface-ground);color:var(--color-text-primary)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter:focus{border-color:var(--color-primary);box-shadow:0 2px 10px #0003;outline:none}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter::placeholder{color:var(--color-text-tertiary)}.i-table-wrapper table tbody tr{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody tr td{color:var(--color-text-primary)}.i-table-wrapper table tbody tr.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody tr.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table tbody .i-table-expanded-row{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-expanded-row .i-table-expanded-content{background:var(--surface-ground);border:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-empty-row td{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-header{background:var(--color-component-background);border-bottom:2px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-header td{color:var(--color-text-primary)}.i-table-wrapper table tbody .i-table-group-header:hover{background:var(--surface-hover)}.i-table-wrapper table tbody .i-table-group-header .i-table-group-toggle-icon,.i-table-wrapper table tbody .i-table-group-header .i-table-group-count{color:var(--color-text-secondary)}.i-table-wrapper table tbody .i-table-group-columns-header{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-columns-header th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-row,.i-table-wrapper table tbody .i-table-group-row.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-row.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper.i-table--bordered table,.i-table-wrapper.i-table--bordered table th,.i-table-wrapper.i-table--bordered table td{border:1px solid var(--surface-border)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header):hover{background:var(--surface-hover)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header).i-table-row-selected:hover{background:var(--surface-hover)}.i-table-wrapper .i-table-column-resizer{background:var(--surface-border)}.i-table-wrapper .i-table-column-resizer:hover{background:var(--color-primary)}.i-table-wrapper{position:relative;display:block;border-radius:4px;overflow:visible}.i-table-wrapper.i-table--small table thead th{padding:8px 12px;font-size:13px}.i-table-wrapper.i-table--small table tbody td{padding:6px 12px;font-size:1em}.i-table-wrapper.i-table--small table .i-table-filter-row th{padding:4px 12px}.i-table-wrapper.i-table--large table thead th,.i-table-wrapper.i-table--large table tbody td{padding:16px 20px;font-size:16px}.i-table-wrapper.i-table--large table .i-table-filter-row th{padding:12px 20px}.i-table-wrapper.i-table--scrollable table{table-layout:fixed}.i-table-wrapper.i-table--loading{pointer-events:none;-webkit-user-select:none;user-select:none}.i-table-wrapper .i-table-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;gap:16px}.i-table-wrapper .i-table-header .i-table-header-start{flex:0 1 auto;display:flex;align-items:center}.i-table-wrapper .i-table-header .i-table-header-end{flex:0 1 auto;display:flex;align-items:center;gap:12px;margin-left:auto}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{width:250px}.i-table-wrapper .i-table-header .i-table-header-end .i-table-download{flex-shrink:0}.i-table-wrapper .i-table-loading-overlay{position:absolute;inset:0;z-index:10;display:flex;align-items:center;justify-content:center}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{font-size:32px}.i-table-wrapper .i-table-container{overflow-x:auto}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:#00000059}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:#00000080}.i-table-wrapper .i-table-container::-webkit-scrollbar-corner{background:transparent}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.i-table-wrapper .i-table-container{scrollbar-color:var(--color-text-secondary) transparent}.i-table-wrapper .i-table-container::-webkit-scrollbar{width:6px;height:6px}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.i-table-wrapper .i-table-container--scrollable{overflow-y:auto}.i-table-wrapper .i-table-container--scrollable thead{position:sticky;top:0;z-index:2}.i-table-wrapper .i-table-container--virtual-scroll{overflow:hidden;display:flex;flex-direction:column}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header{flex-shrink:0;overflow:hidden;background:var(--color-surface-50)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header table{width:100%;border-collapse:collapse;table-layout:fixed}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport{flex:1;min-height:0;width:100%}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport .cdk-virtual-scroll-content-wrapper{width:100%}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-body{width:100%;border-collapse:collapse;table-layout:fixed}.i-table-wrapper .i-table-container--virtual-scroll table{display:table;width:100%;border-collapse:collapse}.i-table-wrapper .i-table-container--virtual-scroll tbody{display:table-row-group}.i-table-wrapper .i-table-container--virtual-scroll tr{display:table-row;box-sizing:border-box}.i-table-wrapper .i-table-container--virtual-scroll td,.i-table-wrapper .i-table-container--virtual-scroll th{display:table-cell}.i-table-wrapper table{width:100%;border-collapse:collapse;table-layout:auto}.i-table-wrapper table thead tr th{position:relative;padding:12px 16px;font-weight:600;text-align:left;white-space:nowrap;-webkit-user-select:none;user-select:none}.i-table-wrapper table thead tr th .i-table-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table thead tr th .i-table-header-content .i-table-header-text{flex:1}.i-table-wrapper table thead tr th .i-table-sort-icon{font-size:1em;opacity:.6;transition:opacity .15s ease,color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column{transition:background-color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column .i-table-sort-icon{opacity:.4}.i-table-wrapper table thead tr th.i-table-sortable-column:hover .i-table-sort-icon,.i-table-wrapper table thead tr th.i-table-sortable-column.i-table-sorted .i-table-sort-icon{opacity:1}.i-table-wrapper table thead tr th:hover .i-table-column-resizer{opacity:.5}.i-table-wrapper table thead .i-table-filter-row th{padding:8px 16px}.i-table-wrapper table thead .i-table-filter-row th .i-table-column-filter{width:100%;padding:6px 10px;font-size:1em;border-radius:4px;transition:border-color .15s ease,box-shadow .15s ease}.i-table-wrapper table tbody{display:table-row-group}.i-table-wrapper table tbody tr{transition:background-color .15s ease}.i-table-wrapper table tbody tr td{padding:12px 16px;vertical-align:middle}.i-table-wrapper table tbody .i-table-empty-row td{padding:40px 16px;text-align:center}.i-table-wrapper table tbody .i-table-expanded-row td{padding:0}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content{padding:16px;margin:8px 16px;border-radius:4px}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content pre{margin:0;font-family:monospace;font-size:1em;white-space:pre-wrap;word-wrap:break-word}.i-table-wrapper table tbody .i-table-group-header td{padding:12px 16px;font-weight:600;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease}.i-table-wrapper table tbody .i-table-group-header td:hover{opacity:.8}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-toggle-icon{font-size:.9em;transition:transform .15s ease}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-label{flex:1;font-size:1.1em}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-columns-header th{font-size:.95em;font-weight:600;padding:10px 16px}.i-table-wrapper table tbody .i-table-group-row td{padding-left:32px}.i-table-wrapper table tbody .i-table-group-row td:first-child{padding-left:16px}.i-table-wrapper .i-table-selection-header,.i-table-wrapper .i-table-selection-cell,.i-table-wrapper .i-table-expand-header,.i-table-wrapper .i-table-expand-cell{width:50px;text-align:center}.i-table-wrapper .i-table-actions-header,.i-table-wrapper .i-table-actions-cell{width:auto;white-space:nowrap}.i-table-wrapper .i-table-actions-header .i-table-actions,.i-table-wrapper .i-table-actions-cell .i-table-actions{display:flex;gap:4px;justify-content:flex-end}.i-table-wrapper .i-table-column-resizer{position:absolute;right:0;top:50%;transform:translateY(-50%);width:4px;height:60%;cursor:col-resize;opacity:0;transition:opacity .15s ease,background-color .15s ease}.i-table-wrapper .i-table-column-resizer:hover{opacity:1}.i-severity-icon.success,.i-table-cell-success .i-severity-icon,.i-severity-text.success,.i-table-cell-success .i-severity-text{color:var(--color-success)}.i-severity-icon.info,.i-table-cell-info .i-severity-icon,.i-severity-text.info,.i-table-cell-info .i-severity-text{color:var(--color-info)}.i-severity-icon.warning,.i-table-cell-warning .i-severity-icon,.i-severity-text.warning,.i-table-cell-warning .i-severity-text{color:var(--color-warning)}.i-severity-icon.danger,.i-table-cell-danger .i-severity-icon,.i-severity-text.danger,.i-table-cell-danger .i-severity-text{color:var(--color-danger)}.i-severity-icon.secondary,.i-table-cell-secondary .i-severity-icon,.i-severity-text.secondary,.i-table-cell-secondary .i-severity-text{color:var(--color-text-secondary)}.i-action-hidden{visibility:hidden;pointer-events:none}@media(max-width:768px){.i-table-wrapper .i-table-header{padding:8px 12px;flex-wrap:wrap}.i-table-wrapper .i-table-header .i-table-header-start{flex:1 1 100%;margin-bottom:8px}.i-table-wrapper .i-table-header .i-table-header-end{flex:1 1 100%;justify-content:flex-end}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{flex:1;max-width:250px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "directive", type: CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "component", type: IInputText, selector: "i-input-text", inputs: ["label", "type", "id", "fluid", "forceFloated", "hideText", "useFloatLabel", "placeholder", "externalInvalid", "externalErrorMessage", "backgroundStyle", "icon", "readonly", "disabled", "errorMessages"] }, { kind: "component", type: IButton, selector: "i-button", inputs: ["severity", "size", "type", "disabled", "outlined", "raised", "text", "icon", "fluid", "loading"], outputs: ["clicked"] }, { kind: "component", type: ICheckbox, selector: "i-checkbox", inputs: ["label", "id", "disabled", "readonly", "size", "indeterminate", "checked"], outputs: ["onChange"] }, { kind: "component", type: NoContentComponent, selector: "i-no-content", inputs: ["icon", "message"] }, { kind: "directive", type: TooltipDirective, selector: "[iTooltip]", inputs: ["iTooltip", "tooltipPosition", "tooltipDelay"] }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }] });
7737
7761
  }
7738
7762
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ITable, decorators: [{
7739
7763
  type: Component,
@@ -7747,7 +7771,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
7747
7771
  IButton,
7748
7772
  ICheckbox,
7749
7773
  NoContentComponent,
7750
- ], template: "<div class=\"i-table-wrapper\" [ngClass]=\"getTableClasses()\">\n <!-- Table Header with ng-content, search, and download -->\n @if (globalFilter || downloadable) {\n <div class=\"i-table-header\">\n <div class=\"i-table-header-start\">\n <ng-content select=\"[header]\"></ng-content>\n </div>\n <div class=\"i-table-header-end\">\n @if (globalFilter) {\n <div class=\"i-table-global-filter\">\n <i-input-text\n [useFloatLabel]=\"false\"\n placeholder=\"Search...\"\n [ngModel]=\"globalFilterValue()\"\n (ngModelChange)=\"onGlobalFilterInput($event)\"\n [fluid]=\"false\"\n [icon]=\"'pi pi-search'\"\n ></i-input-text>\n </div>\n } @if (downloadable) {\n <div class=\"i-table-download\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n icon=\"pi pi-download\"\n label=\"Download\"\n (clicked)=\"handleDownload()\"\n ></i-button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Loading Overlay -->\n @if (loading) {\n <div class=\"i-table-loading-overlay\">\n <i class=\"pi pi-spin pi-spinner i-table-loading-icon\"></i>\n </div>\n }\n\n <!-- Scrollable Table Container -->\n <div\n class=\"i-table-container\"\n [class.i-table-container--scrollable]=\"scrollable || height || scrollHeight\"\n [class.i-table-container--virtual-scroll]=\"virtualScroll\"\n [style.height]=\"virtualScroll ? height || scrollHeight || '400px' : null\"\n [style.max-height]=\"!virtualScroll ? height || scrollHeight || null : null\"\n >\n <!-- Virtual Scroll Mode -->\n @if (virtualScroll) {\n <!-- Sticky Header Table (outside viewport) -->\n <div class=\"i-table-virtual-header\">\n <table class=\"i-table\">\n <thead>\n <!-- Column Filters Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\"></th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"onColumnFilterInput(column.field, $event)\"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n } } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers Row -->\n <tr>\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i [class]=\"getSortIcon(column)\" class=\"i-table-sort-icon\"></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n </table>\n </div>\n\n <!-- Virtual Scroll Viewport (body only) -->\n <cdk-virtual-scroll-viewport\n [itemSize]=\"virtualScrollItemSize\"\n [minBufferPx]=\"virtualScrollMinBufferPx\"\n [maxBufferPx]=\"virtualScrollMaxBufferPx\"\n class=\"i-table-virtual-viewport\"\n >\n <table class=\"i-table i-table-virtual-body\">\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n }\n <!-- Virtual Scroll Rows -->\n <tr\n *cdkVirtualFor=\"\n let row of processedData();\n let rowIndex = index;\n trackBy: trackByRow\n \"\n [style.height.px]=\"virtualScrollItemSize\"\n [class.i-table-row-odd]=\"rowIndex % 2 !== 0\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === 'multiple') {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n } @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [style.color]=\"getCellIconColor(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else {\n {{ formatCellValue(getCellValue(row, column.field), column) }}\n }\n </td>\n } @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n } @else {\n <!-- Non-Virtual Scroll Table -->\n <table class=\"i-table\">\n <!-- Table Header (sticky when scrollable) -->\n <thead>\n <!-- Column Filters Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\"></th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"onColumnFilterInput(column.field, $event)\"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n } } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers Row -->\n <tr>\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i [class]=\"getSortIcon(column)\" class=\"i-table-sort-icon\"></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n\n <!-- Table Body - Grouped Mode -->\n @if (isGroupedMode()) {\n <tbody>\n @for (group of groupedData(); track $index) {\n <!-- Group Header Row -->\n <tr class=\"i-table-group-header\" [ngClass]=\"group.styleClass\">\n <td\n [attr.colspan]=\"\n (getGroupColumns(group).length || columns().length) +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n (click)=\"toggleGroupExpansion(group.label)\"\n >\n <div class=\"i-table-group-header-content\">\n <i\n [class]=\"\n isGroupExpanded(group.label)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n class=\"i-table-group-toggle-icon\"\n ></i>\n <span class=\"i-table-group-label\">{{ group.label }}</span>\n <span class=\"i-table-group-count\">({{ group.data.length }})</span>\n </div>\n </td>\n </tr>\n\n <!-- Group Column Headers (when expanded) -->\n @if (isGroupExpanded(group.label) && group.columns) {\n <tr class=\"i-table-group-columns-header\">\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\"></th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of getGroupColumns(group); track trackByColumn($index,\n column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n >\n {{ column.header }}\n </th>\n } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n }\n\n <!-- Group Data Rows (when expanded) -->\n @if (isGroupExpanded(group.label)) { @if (group.data.length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n (getGroupColumns(group).length || columns().length) +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n } @else { @for (row of group.data; track trackByRow($index, row)) {\n <tr\n class=\"i-table-group-row\"\n [class.i-table-row-odd]=\"$odd\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === 'multiple') {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n } @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n } @for (column of getGroupColumns(group); track trackByColumn($index,\n column)) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [style.color]=\"getCellIconColor(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else {\n {{ formatCellValue(getCellValue(row, column.field), column) }}\n }\n </td>\n } @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n <!-- Expanded Row Content -->\n @if (rowExpandable && isRowExpanded(row)) {\n <tr class=\"i-table-expanded-row\">\n <td\n [attr.colspan]=\"\n (getGroupColumns(group).length || columns().length) +\n (selectionMode === 'multiple' ? 1 : 0) +\n 1 +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <div class=\"i-table-expanded-content\">\n <pre>{{ row | json }}</pre>\n </div>\n </td>\n </tr>\n } } } } }\n </tbody>\n } @else {\n <!-- Table Body - Regular Mode -->\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n } @else { @for (row of processedData(); track trackByRow($index, row);\n let rowIndex = $index) {\n <tr\n [class.i-table-row-odd]=\"$odd\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === 'multiple') {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n } @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [style.color]=\"getCellIconColor(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else {\n {{ formatCellValue(getCellValue(row, column.field), column) }}\n }\n </td>\n } @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n <!-- Expanded Row Content -->\n @if (rowExpandable && isRowExpanded(row)) {\n <tr class=\"i-table-expanded-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n 1 +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <div class=\"i-table-expanded-content\">\n <pre>{{ row | json }}</pre>\n </div>\n </td>\n </tr>\n } } }\n </tbody>\n }\n </table>\n }\n </div>\n</div>\n", styles: [".i-table-wrapper{color:var(--color-text-primary);background:var(--color-component-background)}.i-table-wrapper .i-table-header{background:var(--surface-section);border-bottom:1px solid var(--surface-border)}.i-table-wrapper .i-table-global-filter .i-input-text{background:var(--surface-ground)}.i-table-wrapper .i-table-loading-overlay{background:#ffffffb3}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{color:var(--color-primary)}.i-table-wrapper table thead tr{background:var(--color-component-background)}.i-table-wrapper table thead tr th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table thead tr th.i-table-sortable-column{cursor:pointer}.i-table-wrapper table thead tr th.i-table-sortable-column:hover{background:var(--surface-hover)}.i-table-wrapper table thead tr th.i-table-sorted{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table thead tr th .i-table-sort-icon{color:var(--color-text-secondary)}.i-table-wrapper table thead tr th.i-table-sorted .i-table-sort-icon{color:var(--color-primary)}.i-table-wrapper table thead .i-table-filter-row th{background:var(--color-component-background)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter{border:1px solid var(--surface-border);background:var(--surface-ground);color:var(--color-text-primary)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter:focus{border-color:var(--color-primary);box-shadow:0 2px 10px #0003;outline:none}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter::placeholder{color:var(--color-text-tertiary)}.i-table-wrapper table tbody tr{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody tr td{color:var(--color-text-primary)}.i-table-wrapper table tbody tr.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody tr.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table tbody .i-table-expanded-row{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-expanded-row .i-table-expanded-content{background:var(--surface-ground);border:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-empty-row td{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-header{background:var(--color-component-background);border-bottom:2px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-header td{color:var(--color-text-primary)}.i-table-wrapper table tbody .i-table-group-header:hover{background:var(--surface-hover)}.i-table-wrapper table tbody .i-table-group-header .i-table-group-toggle-icon,.i-table-wrapper table tbody .i-table-group-header .i-table-group-count{color:var(--color-text-secondary)}.i-table-wrapper table tbody .i-table-group-columns-header{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-columns-header th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-row,.i-table-wrapper table tbody .i-table-group-row.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-row.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper.i-table--bordered table,.i-table-wrapper.i-table--bordered table th,.i-table-wrapper.i-table--bordered table td{border:1px solid var(--surface-border)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header):hover{background:var(--surface-hover)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header).i-table-row-selected:hover{background:var(--surface-hover)}.i-table-wrapper .i-table-column-resizer{background:var(--surface-border)}.i-table-wrapper .i-table-column-resizer:hover{background:var(--color-primary)}.i-table-wrapper{position:relative;display:block;border-radius:4px;overflow:visible}.i-table-wrapper.i-table--small table thead th{padding:8px 12px;font-size:13px}.i-table-wrapper.i-table--small table tbody td{padding:6px 12px;font-size:1em}.i-table-wrapper.i-table--small table .i-table-filter-row th{padding:4px 12px}.i-table-wrapper.i-table--large table thead th,.i-table-wrapper.i-table--large table tbody td{padding:16px 20px;font-size:16px}.i-table-wrapper.i-table--large table .i-table-filter-row th{padding:12px 20px}.i-table-wrapper.i-table--scrollable table{table-layout:fixed}.i-table-wrapper.i-table--loading{pointer-events:none;-webkit-user-select:none;user-select:none}.i-table-wrapper .i-table-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;gap:16px}.i-table-wrapper .i-table-header .i-table-header-start{flex:0 1 auto;display:flex;align-items:center}.i-table-wrapper .i-table-header .i-table-header-end{flex:0 1 auto;display:flex;align-items:center;gap:12px;margin-left:auto}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{width:250px}.i-table-wrapper .i-table-header .i-table-header-end .i-table-download{flex-shrink:0}.i-table-wrapper .i-table-loading-overlay{position:absolute;inset:0;z-index:10;display:flex;align-items:center;justify-content:center}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{font-size:32px}.i-table-wrapper .i-table-container{overflow-x:auto}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:#00000059}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:#00000080}.i-table-wrapper .i-table-container::-webkit-scrollbar-corner{background:transparent}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.i-table-wrapper .i-table-container{scrollbar-color:var(--color-text-secondary) transparent}.i-table-wrapper .i-table-container::-webkit-scrollbar{width:6px;height:6px}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.i-table-wrapper .i-table-container--scrollable{overflow-y:auto}.i-table-wrapper .i-table-container--scrollable thead{position:sticky;top:0;z-index:2}.i-table-wrapper .i-table-container--virtual-scroll{overflow:hidden;display:flex;flex-direction:column}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header{flex-shrink:0;overflow:hidden;background:var(--color-surface-50)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header table{width:100%;border-collapse:collapse;table-layout:fixed}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport{flex:1;min-height:0;width:100%}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport .cdk-virtual-scroll-content-wrapper{width:100%}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-body{width:100%;border-collapse:collapse;table-layout:fixed}.i-table-wrapper .i-table-container--virtual-scroll table{display:table;width:100%;border-collapse:collapse}.i-table-wrapper .i-table-container--virtual-scroll tbody{display:table-row-group}.i-table-wrapper .i-table-container--virtual-scroll tr{display:table-row;box-sizing:border-box}.i-table-wrapper .i-table-container--virtual-scroll td,.i-table-wrapper .i-table-container--virtual-scroll th{display:table-cell}.i-table-wrapper table{width:100%;border-collapse:collapse;table-layout:auto}.i-table-wrapper table thead tr th{position:relative;padding:12px 16px;font-weight:600;text-align:left;white-space:nowrap;-webkit-user-select:none;user-select:none}.i-table-wrapper table thead tr th .i-table-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table thead tr th .i-table-header-content .i-table-header-text{flex:1}.i-table-wrapper table thead tr th .i-table-sort-icon{font-size:1em;opacity:.6;transition:opacity .15s ease,color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column{transition:background-color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column .i-table-sort-icon{opacity:.4}.i-table-wrapper table thead tr th.i-table-sortable-column:hover .i-table-sort-icon,.i-table-wrapper table thead tr th.i-table-sortable-column.i-table-sorted .i-table-sort-icon{opacity:1}.i-table-wrapper table thead tr th:hover .i-table-column-resizer{opacity:.5}.i-table-wrapper table thead .i-table-filter-row th{padding:8px 16px}.i-table-wrapper table thead .i-table-filter-row th .i-table-column-filter{width:100%;padding:6px 10px;font-size:1em;border-radius:4px;transition:border-color .15s ease,box-shadow .15s ease}.i-table-wrapper table tbody{display:table-row-group}.i-table-wrapper table tbody tr{transition:background-color .15s ease}.i-table-wrapper table tbody tr td{padding:12px 16px;vertical-align:middle}.i-table-wrapper table tbody .i-table-empty-row td{padding:40px 16px;text-align:center}.i-table-wrapper table tbody .i-table-expanded-row td{padding:0}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content{padding:16px;margin:8px 16px;border-radius:4px}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content pre{margin:0;font-family:monospace;font-size:1em;white-space:pre-wrap;word-wrap:break-word}.i-table-wrapper table tbody .i-table-group-header td{padding:12px 16px;font-weight:600;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease}.i-table-wrapper table tbody .i-table-group-header td:hover{opacity:.8}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-toggle-icon{font-size:.9em;transition:transform .15s ease}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-label{flex:1;font-size:1.1em}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-columns-header th{font-size:.95em;font-weight:600;padding:10px 16px}.i-table-wrapper table tbody .i-table-group-row td{padding-left:32px}.i-table-wrapper table tbody .i-table-group-row td:first-child{padding-left:16px}.i-table-wrapper .i-table-selection-header,.i-table-wrapper .i-table-selection-cell,.i-table-wrapper .i-table-expand-header,.i-table-wrapper .i-table-expand-cell{width:50px;text-align:center}.i-table-wrapper .i-table-actions-header,.i-table-wrapper .i-table-actions-cell{width:auto;white-space:nowrap}.i-table-wrapper .i-table-actions-header .i-table-actions,.i-table-wrapper .i-table-actions-cell .i-table-actions{display:flex;gap:4px;justify-content:flex-end}.i-table-wrapper .i-table-column-resizer{position:absolute;right:0;top:50%;transform:translateY(-50%);width:4px;height:60%;cursor:col-resize;opacity:0;transition:opacity .15s ease,background-color .15s ease}.i-table-wrapper .i-table-column-resizer:hover{opacity:1}@media(max-width:768px){.i-table-wrapper .i-table-header{padding:8px 12px;flex-wrap:wrap}.i-table-wrapper .i-table-header .i-table-header-start{flex:1 1 100%;margin-bottom:8px}.i-table-wrapper .i-table-header .i-table-header-end{flex:1 1 100%;justify-content:flex-end}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{flex:1;max-width:250px}}\n"] }]
7774
+ TooltipDirective,
7775
+ ], template: "<div class=\"i-table-wrapper\" [ngClass]=\"getTableClasses()\">\n <!-- Table Header with ng-content, search, and download -->\n @if (globalFilter || downloadable) {\n <div class=\"i-table-header\">\n <div class=\"i-table-header-start\">\n <ng-content select=\"[header]\"></ng-content>\n </div>\n <div class=\"i-table-header-end\">\n @if (globalFilter) {\n <div class=\"i-table-global-filter\">\n <i-input-text\n [useFloatLabel]=\"false\"\n placeholder=\"Search...\"\n [ngModel]=\"globalFilterValue()\"\n (ngModelChange)=\"onGlobalFilterInput($event)\"\n [fluid]=\"false\"\n [icon]=\"'pi pi-search'\"\n ></i-input-text>\n </div>\n } @if (downloadable) {\n <div class=\"i-table-download\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n icon=\"pi pi-download\"\n label=\"Download\"\n (clicked)=\"handleDownload()\"\n ></i-button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Loading Overlay -->\n @if (loading) {\n <div class=\"i-table-loading-overlay\">\n <i class=\"pi pi-spin pi-spinner i-table-loading-icon\"></i>\n </div>\n }\n\n <!-- Scrollable Table Container -->\n <div\n class=\"i-table-container\"\n [class.i-table-container--scrollable]=\"scrollable || height || scrollHeight\"\n [class.i-table-container--virtual-scroll]=\"virtualScroll\"\n [style.height]=\"virtualScroll ? height || scrollHeight || '400px' : null\"\n [style.max-height]=\"!virtualScroll ? height || scrollHeight || null : null\"\n >\n <!-- Virtual Scroll Mode -->\n @if (virtualScroll) {\n <!-- Sticky Header Table (outside viewport) -->\n <div class=\"i-table-virtual-header\">\n <table class=\"i-table\">\n <thead>\n <!-- Column Filters Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\"></th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"onColumnFilterInput(column.field, $event)\"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n } } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers Row -->\n <tr>\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i [class]=\"getSortIcon(column)\" class=\"i-table-sort-icon\"></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n </table>\n </div>\n\n <!-- Virtual Scroll Viewport (body only) -->\n <cdk-virtual-scroll-viewport\n [itemSize]=\"virtualScrollItemSize\"\n [minBufferPx]=\"virtualScrollMinBufferPx\"\n [maxBufferPx]=\"virtualScrollMaxBufferPx\"\n class=\"i-table-virtual-viewport\"\n >\n <table class=\"i-table i-table-virtual-body\">\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n }\n <!-- Virtual Scroll Rows -->\n <tr\n *cdkVirtualFor=\"\n let row of processedData();\n let rowIndex = index;\n trackBy: trackByRow\n \"\n [style.height.px]=\"virtualScrollItemSize\"\n [class.i-table-row-odd]=\"rowIndex % 2 !== 0\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === 'multiple') {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n } @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [class.i-severity-icon]=\"getCellSeverity(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else {\n <span [class.i-severity-text]=\"getCellSeverity(row, column)\">\n {{ formatCellValue(getCellValue(row, column.field), column) }}\n </span>\n }\n </td>\n } @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"!isActionVisible(action, row)\"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n } @else {\n <!-- Non-Virtual Scroll Table -->\n <table class=\"i-table\">\n <!-- Table Header (sticky when scrollable) -->\n <thead>\n <!-- Column Filters Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\"></th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"onColumnFilterInput(column.field, $event)\"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n } } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers Row -->\n <tr>\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i [class]=\"getSortIcon(column)\" class=\"i-table-sort-icon\"></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n\n <!-- Table Body - Grouped Mode -->\n @if (isGroupedMode()) {\n <tbody>\n @for (group of groupedData(); track $index) {\n <!-- Group Header Row -->\n <tr class=\"i-table-group-header\" [ngClass]=\"group.styleClass\">\n <td\n [attr.colspan]=\"\n (getGroupColumns(group).length || columns().length) +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n (click)=\"toggleGroupExpansion(group.label)\"\n >\n <div class=\"i-table-group-header-content\">\n <i\n [class]=\"\n isGroupExpanded(group.label)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n class=\"i-table-group-toggle-icon\"\n ></i>\n <span class=\"i-table-group-label\">{{ group.label }}</span>\n <span class=\"i-table-group-count\">({{ group.data.length }})</span>\n </div>\n </td>\n </tr>\n\n <!-- Group Column Headers (when expanded) -->\n @if (isGroupExpanded(group.label) && group.columns) {\n <tr class=\"i-table-group-columns-header\">\n @if (selectionMode === 'multiple') {\n <th class=\"i-table-selection-header\"></th>\n } @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n } @for (column of getGroupColumns(group); track trackByColumn($index,\n column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n >\n {{ column.header }}\n </th>\n } @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n }\n\n <!-- Group Data Rows (when expanded) -->\n @if (isGroupExpanded(group.label)) { @if (group.data.length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n (getGroupColumns(group).length || columns().length) +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n } @else { @for (row of group.data; track trackByRow($index, row)) {\n <tr\n class=\"i-table-group-row\"\n [class.i-table-row-odd]=\"$odd\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === 'multiple') {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n } @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n } @for (column of getGroupColumns(group); track trackByColumn($index,\n column)) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [class.i-severity-icon]=\"getCellSeverity(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else {\n <span [class.i-severity-text]=\"getCellSeverity(row, column)\">\n {{ formatCellValue(getCellValue(row, column.field), column) }}\n </span>\n }\n </td>\n } @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"!isActionVisible(action, row)\"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n <!-- Expanded Row Content -->\n @if (rowExpandable && isRowExpanded(row)) {\n <tr class=\"i-table-expanded-row\">\n <td\n [attr.colspan]=\"\n (getGroupColumns(group).length || columns().length) +\n (selectionMode === 'multiple' ? 1 : 0) +\n 1 +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <div class=\"i-table-expanded-content\">\n <pre>{{ row | json }}</pre>\n </div>\n </td>\n </tr>\n } } } } }\n </tbody>\n } @else {\n <!-- Table Body - Regular Mode -->\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n } @else { @for (row of processedData(); track trackByRow($index, row);\n let rowIndex = $index) {\n <tr\n [class.i-table-row-odd]=\"$odd\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === 'multiple') {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n } @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n } @for (column of columns(); track trackByColumn($index, column)) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [class.i-severity-icon]=\"getCellSeverity(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else {\n <span [class.i-severity-text]=\"getCellSeverity(row, column)\">\n {{ formatCellValue(getCellValue(row, column.field), column) }}\n </span>\n }\n </td>\n } @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"!isActionVisible(action, row)\"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n <!-- Expanded Row Content -->\n @if (rowExpandable && isRowExpanded(row)) {\n <tr class=\"i-table-expanded-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n 1 +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <div class=\"i-table-expanded-content\">\n <pre>{{ row | json }}</pre>\n </div>\n </td>\n </tr>\n } } }\n </tbody>\n }\n </table>\n }\n </div>\n</div>\n", styles: [".i-table-wrapper{color:var(--color-text-primary);background:var(--color-component-background)}.i-table-wrapper .i-table-header{background:var(--surface-section);border-bottom:1px solid var(--surface-border)}.i-table-wrapper .i-table-global-filter .i-input-text{background:var(--surface-ground)}.i-table-wrapper .i-table-loading-overlay{background:#ffffffb3}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{color:var(--color-primary)}.i-table-wrapper table thead tr{background:var(--color-component-background)}.i-table-wrapper table thead tr th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table thead tr th.i-table-sortable-column{cursor:pointer}.i-table-wrapper table thead tr th.i-table-sortable-column:hover{background:var(--surface-hover)}.i-table-wrapper table thead tr th.i-table-sorted{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table thead tr th .i-table-sort-icon{color:var(--color-text-secondary)}.i-table-wrapper table thead tr th.i-table-sorted .i-table-sort-icon{color:var(--color-primary)}.i-table-wrapper table thead .i-table-filter-row th{background:var(--color-component-background)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter{border:1px solid var(--surface-border);background:var(--surface-ground);color:var(--color-text-primary)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter:focus{border-color:var(--color-primary);box-shadow:0 2px 10px #0003;outline:none}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter::placeholder{color:var(--color-text-tertiary)}.i-table-wrapper table tbody tr{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody tr td{color:var(--color-text-primary)}.i-table-wrapper table tbody tr.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody tr.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table tbody .i-table-expanded-row{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-expanded-row .i-table-expanded-content{background:var(--surface-ground);border:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-empty-row td{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-header{background:var(--color-component-background);border-bottom:2px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-header td{color:var(--color-text-primary)}.i-table-wrapper table tbody .i-table-group-header:hover{background:var(--surface-hover)}.i-table-wrapper table tbody .i-table-group-header .i-table-group-toggle-icon,.i-table-wrapper table tbody .i-table-group-header .i-table-group-count{color:var(--color-text-secondary)}.i-table-wrapper table tbody .i-table-group-columns-header{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-columns-header th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-row,.i-table-wrapper table tbody .i-table-group-row.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-row.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper.i-table--bordered table,.i-table-wrapper.i-table--bordered table th,.i-table-wrapper.i-table--bordered table td{border:1px solid var(--surface-border)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header):hover{background:var(--surface-hover)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header).i-table-row-selected:hover{background:var(--surface-hover)}.i-table-wrapper .i-table-column-resizer{background:var(--surface-border)}.i-table-wrapper .i-table-column-resizer:hover{background:var(--color-primary)}.i-table-wrapper{position:relative;display:block;border-radius:4px;overflow:visible}.i-table-wrapper.i-table--small table thead th{padding:8px 12px;font-size:13px}.i-table-wrapper.i-table--small table tbody td{padding:6px 12px;font-size:1em}.i-table-wrapper.i-table--small table .i-table-filter-row th{padding:4px 12px}.i-table-wrapper.i-table--large table thead th,.i-table-wrapper.i-table--large table tbody td{padding:16px 20px;font-size:16px}.i-table-wrapper.i-table--large table .i-table-filter-row th{padding:12px 20px}.i-table-wrapper.i-table--scrollable table{table-layout:fixed}.i-table-wrapper.i-table--loading{pointer-events:none;-webkit-user-select:none;user-select:none}.i-table-wrapper .i-table-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;gap:16px}.i-table-wrapper .i-table-header .i-table-header-start{flex:0 1 auto;display:flex;align-items:center}.i-table-wrapper .i-table-header .i-table-header-end{flex:0 1 auto;display:flex;align-items:center;gap:12px;margin-left:auto}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{width:250px}.i-table-wrapper .i-table-header .i-table-header-end .i-table-download{flex-shrink:0}.i-table-wrapper .i-table-loading-overlay{position:absolute;inset:0;z-index:10;display:flex;align-items:center;justify-content:center}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{font-size:32px}.i-table-wrapper .i-table-container{overflow-x:auto}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:#00000059}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:#00000080}.i-table-wrapper .i-table-container::-webkit-scrollbar-corner{background:transparent}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.i-table-wrapper .i-table-container{scrollbar-color:var(--color-text-secondary) transparent}.i-table-wrapper .i-table-container::-webkit-scrollbar{width:6px;height:6px}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.i-table-wrapper .i-table-container--scrollable{overflow-y:auto}.i-table-wrapper .i-table-container--scrollable thead{position:sticky;top:0;z-index:2}.i-table-wrapper .i-table-container--virtual-scroll{overflow:hidden;display:flex;flex-direction:column}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header{flex-shrink:0;overflow:hidden;background:var(--color-surface-50)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header table{width:100%;border-collapse:collapse;table-layout:fixed}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport{flex:1;min-height:0;width:100%}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport .cdk-virtual-scroll-content-wrapper{width:100%}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-body{width:100%;border-collapse:collapse;table-layout:fixed}.i-table-wrapper .i-table-container--virtual-scroll table{display:table;width:100%;border-collapse:collapse}.i-table-wrapper .i-table-container--virtual-scroll tbody{display:table-row-group}.i-table-wrapper .i-table-container--virtual-scroll tr{display:table-row;box-sizing:border-box}.i-table-wrapper .i-table-container--virtual-scroll td,.i-table-wrapper .i-table-container--virtual-scroll th{display:table-cell}.i-table-wrapper table{width:100%;border-collapse:collapse;table-layout:auto}.i-table-wrapper table thead tr th{position:relative;padding:12px 16px;font-weight:600;text-align:left;white-space:nowrap;-webkit-user-select:none;user-select:none}.i-table-wrapper table thead tr th .i-table-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table thead tr th .i-table-header-content .i-table-header-text{flex:1}.i-table-wrapper table thead tr th .i-table-sort-icon{font-size:1em;opacity:.6;transition:opacity .15s ease,color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column{transition:background-color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column .i-table-sort-icon{opacity:.4}.i-table-wrapper table thead tr th.i-table-sortable-column:hover .i-table-sort-icon,.i-table-wrapper table thead tr th.i-table-sortable-column.i-table-sorted .i-table-sort-icon{opacity:1}.i-table-wrapper table thead tr th:hover .i-table-column-resizer{opacity:.5}.i-table-wrapper table thead .i-table-filter-row th{padding:8px 16px}.i-table-wrapper table thead .i-table-filter-row th .i-table-column-filter{width:100%;padding:6px 10px;font-size:1em;border-radius:4px;transition:border-color .15s ease,box-shadow .15s ease}.i-table-wrapper table tbody{display:table-row-group}.i-table-wrapper table tbody tr{transition:background-color .15s ease}.i-table-wrapper table tbody tr td{padding:12px 16px;vertical-align:middle}.i-table-wrapper table tbody .i-table-empty-row td{padding:40px 16px;text-align:center}.i-table-wrapper table tbody .i-table-expanded-row td{padding:0}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content{padding:16px;margin:8px 16px;border-radius:4px}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content pre{margin:0;font-family:monospace;font-size:1em;white-space:pre-wrap;word-wrap:break-word}.i-table-wrapper table tbody .i-table-group-header td{padding:12px 16px;font-weight:600;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease}.i-table-wrapper table tbody .i-table-group-header td:hover{opacity:.8}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-toggle-icon{font-size:.9em;transition:transform .15s ease}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-label{flex:1;font-size:1.1em}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-columns-header th{font-size:.95em;font-weight:600;padding:10px 16px}.i-table-wrapper table tbody .i-table-group-row td{padding-left:32px}.i-table-wrapper table tbody .i-table-group-row td:first-child{padding-left:16px}.i-table-wrapper .i-table-selection-header,.i-table-wrapper .i-table-selection-cell,.i-table-wrapper .i-table-expand-header,.i-table-wrapper .i-table-expand-cell{width:50px;text-align:center}.i-table-wrapper .i-table-actions-header,.i-table-wrapper .i-table-actions-cell{width:auto;white-space:nowrap}.i-table-wrapper .i-table-actions-header .i-table-actions,.i-table-wrapper .i-table-actions-cell .i-table-actions{display:flex;gap:4px;justify-content:flex-end}.i-table-wrapper .i-table-column-resizer{position:absolute;right:0;top:50%;transform:translateY(-50%);width:4px;height:60%;cursor:col-resize;opacity:0;transition:opacity .15s ease,background-color .15s ease}.i-table-wrapper .i-table-column-resizer:hover{opacity:1}.i-severity-icon.success,.i-table-cell-success .i-severity-icon,.i-severity-text.success,.i-table-cell-success .i-severity-text{color:var(--color-success)}.i-severity-icon.info,.i-table-cell-info .i-severity-icon,.i-severity-text.info,.i-table-cell-info .i-severity-text{color:var(--color-info)}.i-severity-icon.warning,.i-table-cell-warning .i-severity-icon,.i-severity-text.warning,.i-table-cell-warning .i-severity-text{color:var(--color-warning)}.i-severity-icon.danger,.i-table-cell-danger .i-severity-icon,.i-severity-text.danger,.i-table-cell-danger .i-severity-text{color:var(--color-danger)}.i-severity-icon.secondary,.i-table-cell-secondary .i-severity-icon,.i-severity-text.secondary,.i-table-cell-secondary .i-severity-text{color:var(--color-text-secondary)}.i-action-hidden{visibility:hidden;pointer-events:none}@media(max-width:768px){.i-table-wrapper .i-table-header{padding:8px 12px;flex-wrap:wrap}.i-table-wrapper .i-table-header .i-table-header-start{flex:1 1 100%;margin-bottom:8px}.i-table-wrapper .i-table-header .i-table-header-end{flex:1 1 100%;justify-content:flex-end}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{flex:1;max-width:250px}}\n"] }]
7751
7776
  }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], groupedData: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupedData", required: false }] }], emptyMessage: [{
7752
7777
  type: Input
7753
7778
  }], sortable: [{
@@ -8071,6 +8096,11 @@ class IChart {
8071
8096
  * @internal
8072
8097
  */
8073
8098
  cdr = inject(ChangeDetectorRef);
8099
+ /**
8100
+ * Reference to the host element
8101
+ * @internal
8102
+ */
8103
+ el = inject(ElementRef);
8074
8104
  ngAfterViewInit() {
8075
8105
  this.initialized = true;
8076
8106
  this.initializeCharts();
@@ -8152,17 +8182,18 @@ class IChart {
8152
8182
  * @internal
8153
8183
  */
8154
8184
  transformToChartDisplay(chart, index) {
8185
+ // Read resolved CSS variables from the host element
8186
+ // This picks up the values defined in chart.component.scss which map to the global theme
8187
+ const computedStyle = getComputedStyle(this.el.nativeElement);
8155
8188
  const documentStyle = getComputedStyle(document.documentElement);
8156
- // Use proper theme CSS variable names with fallbacks
8157
- const textColor = documentStyle.getPropertyValue('--color-text-primary').trim() ||
8158
- documentStyle.getPropertyValue('--text-color').trim() ||
8159
- '#333333';
8160
- const textColorSecondary = documentStyle.getPropertyValue('--color-text-secondary').trim() ||
8161
- documentStyle.getPropertyValue('--text-color-secondary').trim() ||
8162
- '#666666';
8163
- const surfaceBorder = documentStyle.getPropertyValue('--surface-border').trim() ||
8164
- documentStyle.getPropertyValue('--color-border').trim() ||
8165
- '#e2e8f0';
8189
+ const getStyle = (name, fallback) => {
8190
+ const value = computedStyle.getPropertyValue(name).trim();
8191
+ return value && !value.startsWith('var(') ? value : fallback;
8192
+ };
8193
+ // Use the chart-specific variables defined in SCSS
8194
+ const textColor = getStyle('--chart-text-color', '#334155');
8195
+ const textColorSecondary = getStyle('--chart-text-secondary', '#64748b');
8196
+ const surfaceBorder = getStyle('--chart-grid-color', '#e2e8f0');
8166
8197
  const chartType = this.mapChartType(chart.chartType);
8167
8198
  const height = this.getChartHeight(chart.chartType);
8168
8199
  const options = this.getChartOptions(chart.chartType, textColor, textColorSecondary, surfaceBorder);
@@ -8262,7 +8293,7 @@ class IChart {
8262
8293
  case 'line':
8263
8294
  return {
8264
8295
  ...baseOptions,
8265
- scales: this.getLineScales(textColorSecondary, surfaceBorder),
8296
+ scales: this.getBarScales(textColorSecondary, surfaceBorder),
8266
8297
  };
8267
8298
  case 'radar':
8268
8299
  return {
@@ -8350,30 +8381,6 @@ class IChart {
8350
8381
  },
8351
8382
  };
8352
8383
  }
8353
- /**
8354
- * Get scales configuration for line charts
8355
- * @internal
8356
- */
8357
- getLineScales(textColorSecondary, surfaceBorder) {
8358
- return {
8359
- x: {
8360
- ticks: {
8361
- color: textColorSecondary,
8362
- },
8363
- grid: {
8364
- color: surfaceBorder,
8365
- },
8366
- },
8367
- y: {
8368
- ticks: {
8369
- color: textColorSecondary,
8370
- },
8371
- grid: {
8372
- color: surfaceBorder,
8373
- },
8374
- },
8375
- };
8376
- }
8377
8384
  /**
8378
8385
  * Transform dataset with resolved colors
8379
8386
  * @internal
@@ -8400,7 +8407,9 @@ class IChart {
8400
8407
  */
8401
8408
  resolveColor(color, documentStyle) {
8402
8409
  // If it's already a hex color or rgb/rgba, return as-is
8403
- if (color.startsWith('#') || color.startsWith('rgb(') || color.startsWith('rgba(')) {
8410
+ if (color.startsWith('#') ||
8411
+ color.startsWith('rgb(') ||
8412
+ color.startsWith('rgba(')) {
8404
8413
  return color;
8405
8414
  }
8406
8415
  // Handle CSS variable format (--color-name or --color-shade)
@@ -8482,11 +8491,11 @@ class IChart {
8482
8491
  return this.chartInstances.length;
8483
8492
  }
8484
8493
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: IChart, deps: [], target: i0.ɵɵFactoryTarget.Component });
8485
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: IChart, isStandalone: true, selector: "i-chart", inputs: { charts: "charts", height: "height", responsive: "responsive" }, viewQueries: [{ propertyName: "canvasElements", predicate: ["chartCanvas"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"i-charts-container\">\n @for (chartDisplay of chartDisplays; track chartDisplay.id) {\n <div class=\"i-chart-item\" [style.height]=\"getChartHeightStyle(chartDisplay)\">\n <canvas #chartCanvas></canvas>\n </div>\n }\n</div>\n", styles: [".i-charts-container{display:flex;flex-wrap:wrap;width:100%;gap:4rem}.i-chart-item{flex:1 1 45%;min-width:300px;box-sizing:border-box}@media(max-width:768px){.i-charts-container{flex-direction:column}.i-chart-item{width:100%}}\n"] });
8494
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: IChart, isStandalone: true, selector: "i-chart", inputs: { charts: "charts", height: "height", responsive: "responsive" }, viewQueries: [{ propertyName: "canvasElements", predicate: ["chartCanvas"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"i-charts-container\">\n @for (chartDisplay of chartDisplays; track chartDisplay.id) {\n <div class=\"i-chart-item\" [style.height]=\"getChartHeightStyle(chartDisplay)\">\n <canvas #chartCanvas></canvas>\n </div>\n }\n</div>\n", styles: [":host{--chart-grid-color: var(--surface-border);--chart-text-color: var(--color-text-primary);--chart-text-secondary: var(--color-text-secondary)}.i-charts-container{display:flex;flex-wrap:wrap;width:100%;gap:4rem}.i-chart-item{flex:1 1 45%;min-width:300px;box-sizing:border-box}@media(max-width:768px){.i-charts-container{flex-direction:column}.i-chart-item{width:100%}}\n"] });
8486
8495
  }
8487
8496
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: IChart, decorators: [{
8488
8497
  type: Component,
8489
- args: [{ selector: 'i-chart', standalone: true, imports: [], template: "<div class=\"i-charts-container\">\n @for (chartDisplay of chartDisplays; track chartDisplay.id) {\n <div class=\"i-chart-item\" [style.height]=\"getChartHeightStyle(chartDisplay)\">\n <canvas #chartCanvas></canvas>\n </div>\n }\n</div>\n", styles: [".i-charts-container{display:flex;flex-wrap:wrap;width:100%;gap:4rem}.i-chart-item{flex:1 1 45%;min-width:300px;box-sizing:border-box}@media(max-width:768px){.i-charts-container{flex-direction:column}.i-chart-item{width:100%}}\n"] }]
8498
+ args: [{ selector: 'i-chart', standalone: true, imports: [], template: "<div class=\"i-charts-container\">\n @for (chartDisplay of chartDisplays; track chartDisplay.id) {\n <div class=\"i-chart-item\" [style.height]=\"getChartHeightStyle(chartDisplay)\">\n <canvas #chartCanvas></canvas>\n </div>\n }\n</div>\n", styles: [":host{--chart-grid-color: var(--surface-border);--chart-text-color: var(--color-text-primary);--chart-text-secondary: var(--color-text-secondary)}.i-charts-container{display:flex;flex-wrap:wrap;width:100%;gap:4rem}.i-chart-item{flex:1 1 45%;min-width:300px;box-sizing:border-box}@media(max-width:768px){.i-charts-container{flex-direction:column}.i-chart-item{width:100%}}\n"] }]
8490
8499
  }], propDecorators: { charts: [{
8491
8500
  type: Input
8492
8501
  }], height: [{