@lukfel/ng-scaffold 22.3.1 → 22.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -453,7 +453,8 @@ In addition to the scaffold components provided by default by the the `ScaffoldC
453
453
 
454
454
  ### List
455
455
  A standalone Material Design inspired list and table hybrid component for displaying structured
456
- collections of items. It supports avatars, titles, subtitles, actions, selections and dragging —
456
+ collections of items. It supports avatars, titles, subtitles, actions, menus, selections and
457
+ dragging —
457
458
  making it ideal for dashboards, inventories, and administrative views.
458
459
 
459
460
  ```ts
@@ -461,7 +462,7 @@ import { ListComponent } from '@lukfel/ng-scaffold';
461
462
  ```
462
463
 
463
464
  ```ts
464
- import { Button, ListConfig, ListHeader, ListItem } from '@lukfel/ng-scaffold';
465
+ import { ListConfig, ListHeader, ListItem, MenuButton } from '@lukfel/ng-scaffold';
465
466
 
466
467
  public listConfig = signal<ListConfig>({ // (Optional) list config
467
468
  enableSelection: true,
@@ -484,9 +485,17 @@ public listItems = signal<ListItem[]>([
484
485
  { id: 2, matIcon: 'person', title: 'Item 3', subtitle: 'I have no edit buton', hiddenButtonIds: ['edit'] },
485
486
  ]);
486
487
 
487
- public listButtons = signal<Button[]>([ // (Optional) list buttons
488
+ public listButtons = signal<MenuButton[]>([ // (Optional) list buttons
488
489
  { id: 'edit', matIcon: 'edit' },
489
- { id: 'delete', matIcon: 'delete', cssClass: 'warn' }
490
+ { id: 'delete', matIcon: 'delete', cssClass: 'warn' },
491
+ { // A button with menuButtons opens a menu
492
+ id: 'more',
493
+ matIcon: 'more_vert',
494
+ menuButtons: [
495
+ { id: 'share', matIcon: 'share', label: 'Share' },
496
+ { id: 'archive', matIcon: 'archive', label: 'Archive' }
497
+ ]
498
+ }
490
499
  ]);
491
500
 
492
501
  // (Optional) Handle sort events
@@ -505,7 +514,7 @@ public onListSelectionChange(items: ListItem[]): void {
505
514
  }
506
515
 
507
516
  public onListButtonClick(event: { buttonId: string, item: ListItem }): void {
508
- // handle button click
517
+ // handle button click, menu entries report their own id here too
509
518
  }
510
519
 
511
520
  public onListItemClick(item: ListItem): void {
@@ -43,7 +43,7 @@ import * as i5 from '@angular/material/checkbox';
43
43
  import { MatCheckboxModule } from '@angular/material/checkbox';
44
44
  import * as i6$1 from '@angular/material/core';
45
45
  import { MatRippleModule } from '@angular/material/core';
46
- import * as i9 from '@angular/material/divider';
46
+ import * as i10 from '@angular/material/divider';
47
47
  import { MatDividerModule } from '@angular/material/divider';
48
48
 
49
49
  /**
@@ -1831,7 +1831,7 @@ class ListComponent {
1831
1831
  click.stopImmediatePropagation();
1832
1832
  }
1833
1833
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1834
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: ListComponent, isStandalone: true, selector: "lf-list", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, groupedItems: { classPropertyName: "groupedItems", publicName: "groupedItems", isSignal: true, isRequired: false, transformFunction: null }, buttons: { classPropertyName: "buttons", publicName: "buttons", isSignal: true, isRequired: false, transformFunction: null }, dropListId: { classPropertyName: "dropListId", publicName: "dropListId", isSignal: true, isRequired: false, transformFunction: null }, connectedDropListIds: { classPropertyName: "connectedDropListIds", publicName: "connectedDropListIds", isSignal: true, isRequired: false, transformFunction: null }, allSelected: { classPropertyName: "allSelected", publicName: "allSelected", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sortChangeEvent: "sortChangeEvent", selectionChangeEvent: "selectionChangeEvent", itemClickEvent: "itemClickEvent", itemDropEvent: "itemDropEvent", buttonClickEvent: "buttonClickEvent", allSelected: "allSelectedChange" }, queries: [{ propertyName: "avatarTemplate", first: true, predicate: ListItemAvatarDirective, descendants: true, isSignal: true }, { propertyName: "titleTemplate", first: true, predicate: ListItemTitleDirective, descendants: true, isSignal: true }, { propertyName: "subtitleTemplate", first: true, predicate: ListItemSubtitleDirective, descendants: true, isSignal: true }, { propertyName: "buttonsTemplate", first: true, predicate: ListItemButtonsDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"lf-list\" cdkDropListGroup>\r\n <!-- Header -->\r\n @if (header(); as header) {\r\n <div\r\n class=\"lf-list-item lf-list-item-header\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\">\r\n <!-- avatar -->\r\n @if (header.avatar) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <img [src]=\"header.avatar\" alt=\"Avatar of header\" (error)=\"onImageError($event)\" />\r\n </div>\r\n } @else if (header.matIcon || header.svgIcon) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <!-- icon -->\r\n @if (header.matIcon) {\r\n <mat-icon>\r\n {{ header.matIcon }}\r\n </mat-icon>\r\n } @else if (header.svgIcon) {\r\n <mat-icon [svgIcon]=\"header.svgIcon\"></mat-icon>\r\n }\r\n </div>\r\n } @else if (hasAvatars) {\r\n <div class=\"lf-list-item-avatar px-1\"></div>\r\n }\r\n\r\n <!-- title -->\r\n <div class=\"lf-list-item-title-wrapper flex-row\">\r\n @for (item of header.items; track $index) {\r\n <span [class.clickable]=\"item.sortToken\" (click)=\"updateSortToken(item.sortToken)\">\r\n {{ item.title }}\r\n @if (sortToken() === item.sortToken) {\r\n <mat-icon class=\"lf-list-item-sort-icon\">\r\n {{ sortAsc() ? 'arrow_downward' : 'arrow_upward' }}\r\n </mat-icon>\r\n }\r\n </span>\r\n }\r\n </div>\r\n\r\n <!-- buttons -->\r\n <div class=\"lf-list-item-buttons\" [class.gap-2]=\"!isMobile()\" [class.gap-1]=\"isMobile()\">\r\n @for (button of header.buttons; track button.id) {\r\n @if (button.label) {\r\n <button\r\n mat-button\r\n class=\"lf-list-item-button\"\r\n [class.disabled]=\"button.disabled\"\r\n [ngClass]=\"button.cssClass\"\r\n [disabled]=\"button.disabled\"\r\n [matTooltip]=\"button.tooltip\"\r\n (click)=\"clickButton({ buttonId: button.id, item: null! }, $event)\">\r\n <!-- icon -->\r\n @if (button.matIcon) {\r\n <mat-icon>\r\n {{ button.matIcon }}\r\n </mat-icon>\r\n } @else if (button.svgIcon) {\r\n <mat-icon [svgIcon]=\"button.svgIcon\"></mat-icon>\r\n }\r\n {{ button.label }}\r\n </button>\r\n } @else {\r\n <button\r\n mat-icon-button\r\n class=\"lf-list-item-icon\"\r\n [class.disabled]=\"button.disabled\"\r\n [ngClass]=\"button.cssClass\"\r\n [disabled]=\"button.disabled\"\r\n [matTooltip]=\"button.tooltip\"\r\n [aria-label]=\"button.id || button.tooltip\"\r\n (click)=\"clickButton({ buttonId: button.id, item: null! }, $event)\">\r\n <!-- icon -->\r\n @if (button.matIcon) {\r\n <mat-icon>\r\n {{ button.matIcon }}\r\n </mat-icon>\r\n } @else if (button.svgIcon) {\r\n <mat-icon [svgIcon]=\"button.svgIcon\"></mat-icon>\r\n }\r\n </button>\r\n }\r\n }\r\n </div>\r\n\r\n <!-- checkbox -->\r\n @if (config()?.enableSelection && !config()?.disableMultiselect) {\r\n <div class=\"lf-list-item-checkbox\">\r\n <mat-checkbox\r\n [(ngModel)]=\"allSelected\"\r\n [indeterminate]=\"someSelected\"\r\n (change)=\"selectAll($event)\"></mat-checkbox>\r\n </div>\r\n }\r\n </div>\r\n <mat-divider></mat-divider>\r\n }\r\n\r\n <!-- Grouped Items -->\r\n @if (config()?.mode === 'group' && groupedItems()) {\r\n @for (group of groupedItems() | keyvalue; track group.key; let first = $first) {\r\n <div class=\"lf-list-group\" [class.mt-4]=\"!first\">\r\n @if (group.key) {\r\n <div\r\n class=\"lf-list-item lf-list-group-header\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\">\r\n <div class=\"lf-list-item-avatar px-1\"></div>\r\n <div class=\"lf-list-item-title-wrapper flex-row\">\r\n <span>{{ group.key }}</span>\r\n </div>\r\n </div>\r\n }\r\n <div\r\n [id]=\"group.key\"\r\n cdkDropList\r\n [cdkDropListData]=\"group.value\"\r\n [cdkDropListDisabled]=\"!config()?.enableDragging\"\r\n [cdkDropListConnectedTo]=\"connectedDropListIds()!\"\r\n (cdkDropListDropped)=\"dropItem($event, group.key)\"\r\n [class.drop-zone]=\"config()?.enableDragging && group.value.length <= 0\">\r\n @for (item of group.value; track item.id; let last = $last) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"item.disabled || !config()?.enableDragging\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item, last: last }\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n <!-- Flat Items -->\r\n } @else {\r\n <div\r\n [id]=\"dropListId()!\"\r\n cdkDropList\r\n [cdkDropListData]=\"items()\"\r\n [cdkDropListDisabled]=\"!config()?.enableDragging\"\r\n [cdkDropListConnectedTo]=\"connectedDropListIds()!\"\r\n (cdkDropListDropped)=\"dropItem($event, dropListId()!)\"\r\n [class.drop-zone]=\"config()?.enableDragging && items().length <= 0\">\r\n @for (item of items(); track item.id; let last = $last) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"item.disabled || !config()?.enableDragging\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item, last: last }\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Item (template) -->\r\n <ng-template #listItemTemplate let-item let-last=\"last\">\r\n <div\r\n class=\"lf-list-item lf-list-item-data\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\"\r\n [class.active]=\"item.checked\"\r\n [class.disabled]=\"item.disabled\"\r\n [class.clickable]=\"item.clickable && !item.disabled\"\r\n [ngClass]=\"item.cssClass\"\r\n matRipple\r\n [matRippleDisabled]=\"!item.clickable\"\r\n (click)=\"item.clickable && !item.disabled && !isLink(item) ? clickItem(item, $event) : null\">\r\n <!-- content (anchor only when the item links, so buttons stay outside it) -->\r\n @if (isLink(item)) {\r\n @if (item.routerLink) {\r\n <a\r\n class=\"lf-list-item-link flex-row-nowrap align-center flex-auto h-100 overflow-hidden\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\"\r\n [routerLink]=\"item.routerLink\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemContentTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n </a>\r\n } @else {\r\n <a\r\n class=\"lf-list-item-link flex-row-nowrap align-center flex-auto h-100 overflow-hidden\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\"\r\n [href]=\"item.href\"\r\n [target]=\"item.externalTab ? '_blank' : null\"\r\n [rel]=\"item.externalTab ? 'noopener' : null\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemContentTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n </a>\r\n }\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemContentTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n }\r\n\r\n <!-- buttons -->\r\n <div class=\"lf-list-item-buttons\" [class.gap-2]=\"!isMobile()\" [class.gap-1]=\"isMobile()\">\r\n @if (buttonsTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"buttonsTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else {\r\n @let combinedButtons = getCombinedButtons(item);\r\n @for (button of combinedButtons; track button.id) {\r\n @if (!item.hiddenButtonIds?.includes(button.id)) {\r\n @let disabled =\r\n button.disabled || item.disabled || item.disabledButtonIds?.includes(button.id);\r\n @if (button.label) {\r\n <button\r\n mat-button\r\n class=\"lf-list-item-button\"\r\n [class.disabled]=\"disabled\"\r\n [ngClass]=\"button.cssClass\"\r\n [disabled]=\"disabled\"\r\n [matTooltip]=\"button.tooltip\"\r\n (click)=\"clickButton({ buttonId: button.id, item }, $event)\">\r\n <!-- icon -->\r\n @if (button.matIcon) {\r\n <mat-icon>\r\n {{ button.matIcon }}\r\n </mat-icon>\r\n } @else if (button.svgIcon) {\r\n <mat-icon [svgIcon]=\"button.svgIcon\"></mat-icon>\r\n }\r\n {{ button.label }}\r\n </button>\r\n } @else {\r\n <button\r\n mat-icon-button\r\n class=\"lf-list-item-icon\"\r\n [class.disabled]=\"disabled\"\r\n [ngClass]=\"button.cssClass\"\r\n [disabled]=\"disabled\"\r\n [matTooltip]=\"button.tooltip\"\r\n [aria-label]=\"button.id || button.tooltip\"\r\n (click)=\"clickButton({ buttonId: button.id, item }, $event)\">\r\n <!-- icon -->\r\n @if (button.matIcon) {\r\n <mat-icon>\r\n {{ button.matIcon }}\r\n </mat-icon>\r\n } @else if (button.svgIcon) {\r\n <mat-icon [svgIcon]=\"button.svgIcon\"></mat-icon>\r\n }\r\n </button>\r\n }\r\n }\r\n }\r\n }\r\n\r\n <!-- drag -->\r\n @if (config()?.enableDragging) {\r\n <button\r\n mat-icon-button\r\n class=\"lf-list-item-icon\"\r\n [class.disabled]=\"item.disabled\"\r\n [disabled]=\"item.disabled\"\r\n [aria-label]=\"'Drag handle'\"\r\n (click)=\"stopPropagation($event)\"\r\n cdkDragHandle>\r\n <mat-icon>drag_indicator</mat-icon>\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- checkbox -->\r\n @if (config()?.enableSelection) {\r\n <div class=\"lf-list-item-checkbox\">\r\n <mat-checkbox\r\n [(ngModel)]=\"item.checked\"\r\n [disabled]=\"item.disabled!\"\r\n (change)=\"selectItem(item, $event)\"\r\n (click)=\"stopPropagation($event)\"></mat-checkbox>\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (config()?.showDividers && !last) {\r\n <mat-divider></mat-divider>\r\n }\r\n </ng-template>\r\n\r\n <!-- Item content (template) -->\r\n <ng-template #listItemContentTemplate let-item>\r\n <!-- avatar -->\r\n @if (avatarTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"avatarTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else if (item.avatar) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <img [src]=\"item.avatar\" [alt]=\"'Avatar of ' + item.title\" (error)=\"onImageError($event)\" />\r\n </div>\r\n } @else if (item.matIcon || item.svgIcon) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <!-- icon -->\r\n @if (item.matIcon) {\r\n <mat-icon>\r\n {{ item.matIcon }}\r\n </mat-icon>\r\n } @else if (item.svgIcon) {\r\n <mat-icon [svgIcon]=\"item.svgIcon\"></mat-icon>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- title -->\r\n <div class=\"lf-list-item-title-wrapper\">\r\n <span class=\"lf-list-item-title\">\r\n @if (titleTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"titleTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ item.title }}\r\n }\r\n </span>\r\n @if (item.subtitle || subtitleTemplate()) {\r\n <span class=\"lf-list-item-subtitle\">\r\n @if (subtitleTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"subtitleTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ item.subtitle }}\r\n }\r\n </span>\r\n }\r\n </div>\r\n </ng-template>\r\n</div>\r\n", styles: [".lf-list,.lf-list .lf-list-group{width:100%}.lf-list .lf-list-group .lf-list-group-header{font-weight:500;height:calc(var(--list-item-height) - 16px)}.lf-list-item{width:100%;display:flex;flex-flow:row nowrap;align-items:center;justify-content:center;height:var(--list-item-height);border-radius:var(--list-item-border-radius);box-sizing:border-box;overflow:hidden}.lf-list-item.disabled .lf-list-item-title-wrapper{opacity:.64}.lf-list-item .lf-list-item-sort-icon{font-size:var(--list-item-sort-icon-size);width:var(--list-item-sort-icon-size);height:var(--list-item-sort-icon-size);vertical-align:text-top}.lf-list-item .lf-list-item-checkbox{flex:0 0 var(--list-item-checkbox-width)}.lf-list-item .lf-list-item-avatar{flex:0 0 var(--list-item-avatar-size);display:flex;align-items:center;justify-content:center}.lf-list-item .lf-list-item-avatar img{width:var(--list-item-avatar-size);height:var(--list-item-avatar-size);border-radius:50%;object-fit:cover}.lf-list-item .lf-list-item-title-wrapper{display:flex;flex-flow:column;align-items:flex-start;flex:1 1 var(--list-item-title-width);overflow:hidden}.lf-list-item .lf-list-item-title-wrapper .lf-list-item-title{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.lf-list-item .lf-list-item-title-wrapper .lf-list-item-subtitle{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:.8rem}.lf-list-item .lf-list-item-link{min-width:0;color:inherit;text-decoration:none}.lf-list-item .lf-list-item-buttons{flex:0 0 auto;display:flex;flex-flow:row nowrap;align-items:center;justify-content:space-between}.lf-list-item.lf-list-item-header{font-weight:500}.lf-list-item.lf-list-item-header .lf-list-item-title-wrapper span{width:var(--list-item-title-wrapper-width)}.lf-list-item.lf-list-item-data:hover{background-color:#00000014}.lf-list-item .flex-row{display:flex!important;flex-flow:row nowrap;align-items:center}.drop-zone{width:100%;height:var(--list-item-height);border:2px dashed var(--color-gray);border-radius:var(--list-item-border-radius);box-sizing:border-box}.clickable{cursor:pointer!important}.cdk-drag-preview{color:var(--mat-app-text-color, inherit)!important;background:var(--mat-app-background-color, inherit)!important;box-sizing:border-box;border-radius:var(--list-item-border-radius);opacity:.8;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:.4}.cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-animating{transition:transform .3s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$3.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i3$3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i3$3.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i3$3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i3$3.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatRippleModule }, { kind: "directive", type: i6$1.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i9.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1834
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: ListComponent, isStandalone: true, selector: "lf-list", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, groupedItems: { classPropertyName: "groupedItems", publicName: "groupedItems", isSignal: true, isRequired: false, transformFunction: null }, buttons: { classPropertyName: "buttons", publicName: "buttons", isSignal: true, isRequired: false, transformFunction: null }, dropListId: { classPropertyName: "dropListId", publicName: "dropListId", isSignal: true, isRequired: false, transformFunction: null }, connectedDropListIds: { classPropertyName: "connectedDropListIds", publicName: "connectedDropListIds", isSignal: true, isRequired: false, transformFunction: null }, allSelected: { classPropertyName: "allSelected", publicName: "allSelected", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sortChangeEvent: "sortChangeEvent", selectionChangeEvent: "selectionChangeEvent", itemClickEvent: "itemClickEvent", itemDropEvent: "itemDropEvent", buttonClickEvent: "buttonClickEvent", allSelected: "allSelectedChange" }, queries: [{ propertyName: "avatarTemplate", first: true, predicate: ListItemAvatarDirective, descendants: true, isSignal: true }, { propertyName: "titleTemplate", first: true, predicate: ListItemTitleDirective, descendants: true, isSignal: true }, { propertyName: "subtitleTemplate", first: true, predicate: ListItemSubtitleDirective, descendants: true, isSignal: true }, { propertyName: "buttonsTemplate", first: true, predicate: ListItemButtonsDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"lf-list\" cdkDropListGroup>\r\n <!-- Header -->\r\n @if (header(); as header) {\r\n <div\r\n class=\"lf-list-item lf-list-item-header\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\">\r\n <!-- avatar -->\r\n @if (header.avatar) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <img [src]=\"header.avatar\" alt=\"Avatar of header\" (error)=\"onImageError($event)\" />\r\n </div>\r\n } @else if (header.matIcon || header.svgIcon) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <!-- icon -->\r\n @if (header.matIcon) {\r\n <mat-icon>\r\n {{ header.matIcon }}\r\n </mat-icon>\r\n } @else if (header.svgIcon) {\r\n <mat-icon [svgIcon]=\"header.svgIcon\"></mat-icon>\r\n }\r\n </div>\r\n } @else if (hasAvatars) {\r\n <div class=\"lf-list-item-avatar px-1\"></div>\r\n }\r\n\r\n <!-- title -->\r\n <div class=\"lf-list-item-title-wrapper flex-row\">\r\n @for (item of header.items; track $index) {\r\n <span [class.clickable]=\"item.sortToken\" (click)=\"updateSortToken(item.sortToken)\">\r\n {{ item.title }}\r\n @if (sortToken() === item.sortToken) {\r\n <mat-icon class=\"lf-list-item-sort-icon\">\r\n {{ sortAsc() ? 'arrow_downward' : 'arrow_upward' }}\r\n </mat-icon>\r\n }\r\n </span>\r\n }\r\n </div>\r\n\r\n <!-- buttons -->\r\n <div class=\"lf-list-item-buttons\" [class.gap-2]=\"!isMobile()\" [class.gap-1]=\"isMobile()\">\r\n @for (button of header.buttons; track button.id) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"listButtonTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n button: button,\r\n item: null,\r\n disabled: button.disabled,\r\n }\"></ng-container>\r\n }\r\n </div>\r\n\r\n <!-- checkbox -->\r\n @if (config()?.enableSelection && !config()?.disableMultiselect) {\r\n <div class=\"lf-list-item-checkbox\">\r\n <mat-checkbox\r\n [(ngModel)]=\"allSelected\"\r\n [indeterminate]=\"someSelected\"\r\n (change)=\"selectAll($event)\"></mat-checkbox>\r\n </div>\r\n }\r\n </div>\r\n <mat-divider></mat-divider>\r\n }\r\n\r\n <!-- Grouped Items -->\r\n @if (config()?.mode === 'group' && groupedItems()) {\r\n @for (group of groupedItems() | keyvalue; track group.key; let first = $first) {\r\n <div class=\"lf-list-group\" [class.mt-4]=\"!first\">\r\n @if (group.key) {\r\n <div\r\n class=\"lf-list-item lf-list-group-header\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\">\r\n <div class=\"lf-list-item-avatar px-1\"></div>\r\n <div class=\"lf-list-item-title-wrapper flex-row\">\r\n <span>{{ group.key }}</span>\r\n </div>\r\n </div>\r\n }\r\n <div\r\n [id]=\"group.key\"\r\n cdkDropList\r\n [cdkDropListData]=\"group.value\"\r\n [cdkDropListDisabled]=\"!config()?.enableDragging\"\r\n [cdkDropListConnectedTo]=\"connectedDropListIds()!\"\r\n (cdkDropListDropped)=\"dropItem($event, group.key)\"\r\n [class.drop-zone]=\"config()?.enableDragging && group.value.length <= 0\">\r\n @for (item of group.value; track item.id; let last = $last) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"item.disabled || !config()?.enableDragging\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item, last: last }\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n <!-- Flat Items -->\r\n } @else {\r\n <div\r\n [id]=\"dropListId()!\"\r\n cdkDropList\r\n [cdkDropListData]=\"items()\"\r\n [cdkDropListDisabled]=\"!config()?.enableDragging\"\r\n [cdkDropListConnectedTo]=\"connectedDropListIds()!\"\r\n (cdkDropListDropped)=\"dropItem($event, dropListId()!)\"\r\n [class.drop-zone]=\"config()?.enableDragging && items().length <= 0\">\r\n @for (item of items(); track item.id; let last = $last) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"item.disabled || !config()?.enableDragging\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item, last: last }\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Item (template) -->\r\n <ng-template #listItemTemplate let-item let-last=\"last\">\r\n <div\r\n class=\"lf-list-item lf-list-item-data\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\"\r\n [class.active]=\"item.checked\"\r\n [class.disabled]=\"item.disabled\"\r\n [class.clickable]=\"item.clickable && !item.disabled\"\r\n [ngClass]=\"item.cssClass\"\r\n matRipple\r\n [matRippleDisabled]=\"!item.clickable\"\r\n (click)=\"item.clickable && !item.disabled && !isLink(item) ? clickItem(item, $event) : null\">\r\n <!-- content (anchor only when the item links, so buttons stay outside it) -->\r\n @if (isLink(item)) {\r\n @if (item.routerLink) {\r\n <a\r\n class=\"lf-list-item-link flex-row-nowrap align-center flex-auto h-100 overflow-hidden\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\"\r\n [routerLink]=\"item.routerLink\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemContentTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n </a>\r\n } @else {\r\n <a\r\n class=\"lf-list-item-link flex-row-nowrap align-center flex-auto h-100 overflow-hidden\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\"\r\n [href]=\"item.href\"\r\n [target]=\"item.externalTab ? '_blank' : null\"\r\n [rel]=\"item.externalTab ? 'noopener' : null\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemContentTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n </a>\r\n }\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemContentTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n }\r\n\r\n <!-- buttons -->\r\n <div class=\"lf-list-item-buttons\" [class.gap-2]=\"!isMobile()\" [class.gap-1]=\"isMobile()\">\r\n @if (buttonsTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"buttonsTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else {\r\n @let combinedButtons = getCombinedButtons(item);\r\n @for (button of combinedButtons; track button.id) {\r\n @if (!item.hiddenButtonIds?.includes(button.id)) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"listButtonTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n button: button,\r\n item: item,\r\n disabled:\r\n button.disabled || item.disabled || item.disabledButtonIds?.includes(button.id),\r\n }\"></ng-container>\r\n }\r\n }\r\n }\r\n\r\n <!-- drag -->\r\n @if (config()?.enableDragging) {\r\n <button\r\n mat-icon-button\r\n class=\"lf-list-item-icon\"\r\n [class.disabled]=\"item.disabled\"\r\n [disabled]=\"item.disabled\"\r\n [aria-label]=\"'Drag handle'\"\r\n (click)=\"stopPropagation($event)\"\r\n cdkDragHandle>\r\n <mat-icon>drag_indicator</mat-icon>\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- checkbox -->\r\n @if (config()?.enableSelection) {\r\n <div class=\"lf-list-item-checkbox\">\r\n <mat-checkbox\r\n [(ngModel)]=\"item.checked\"\r\n [disabled]=\"item.disabled!\"\r\n (change)=\"selectItem(item, $event)\"\r\n (click)=\"stopPropagation($event)\"></mat-checkbox>\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (config()?.showDividers && !last) {\r\n <mat-divider></mat-divider>\r\n }\r\n </ng-template>\r\n\r\n <!-- Item content (template) -->\r\n <ng-template #listItemContentTemplate let-item>\r\n <!-- avatar -->\r\n @if (avatarTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"avatarTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else if (item.avatar) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <img [src]=\"item.avatar\" [alt]=\"'Avatar of ' + item.title\" (error)=\"onImageError($event)\" />\r\n </div>\r\n } @else if (item.matIcon || item.svgIcon) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <!-- icon -->\r\n @if (item.matIcon) {\r\n <mat-icon>\r\n {{ item.matIcon }}\r\n </mat-icon>\r\n } @else if (item.svgIcon) {\r\n <mat-icon [svgIcon]=\"item.svgIcon\"></mat-icon>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- title -->\r\n <div class=\"lf-list-item-title-wrapper\">\r\n <span class=\"lf-list-item-title\">\r\n @if (titleTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"titleTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ item.title }}\r\n }\r\n </span>\r\n @if (item.subtitle || subtitleTemplate()) {\r\n <span class=\"lf-list-item-subtitle\">\r\n @if (subtitleTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"subtitleTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ item.subtitle }}\r\n }\r\n </span>\r\n }\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n<!-- button (template) -->\r\n<!-- The menu lives inside this template, so every button instantiation owns its own -->\r\n<ng-template #listButtonTemplate let-button=\"button\" let-item=\"item\" let-disabled=\"disabled\">\r\n @if (button.label) {\r\n <button\r\n mat-button\r\n class=\"lf-list-item-button\"\r\n [class.disabled]=\"disabled\"\r\n [ngClass]=\"button.cssClass\"\r\n [disabled]=\"disabled\"\r\n [matTooltip]=\"button.tooltip\"\r\n [matMenuTriggerFor]=\"button.menuButtons?.length ? menu : null\"\r\n (click)=\"clickButton({ buttonId: button.id, item }, $event)\">\r\n <!-- icon -->\r\n @if (button.matIcon) {\r\n <mat-icon>\r\n {{ button.matIcon }}\r\n </mat-icon>\r\n } @else if (button.svgIcon) {\r\n <mat-icon [svgIcon]=\"button.svgIcon\"></mat-icon>\r\n }\r\n {{ button.label }}\r\n </button>\r\n } @else {\r\n <button\r\n mat-icon-button\r\n class=\"lf-list-item-icon\"\r\n [class.disabled]=\"disabled\"\r\n [ngClass]=\"button.cssClass\"\r\n [disabled]=\"disabled\"\r\n [matTooltip]=\"button.tooltip\"\r\n [aria-label]=\"button.id || button.tooltip\"\r\n [matMenuTriggerFor]=\"button.menuButtons?.length ? menu : null\"\r\n (click)=\"clickButton({ buttonId: button.id, item }, $event)\">\r\n <!-- icon -->\r\n @if (button.matIcon) {\r\n <mat-icon>\r\n {{ button.matIcon }}\r\n </mat-icon>\r\n } @else if (button.svgIcon) {\r\n <mat-icon [svgIcon]=\"button.svgIcon\"></mat-icon>\r\n }\r\n </button>\r\n }\r\n\r\n <!-- menu -->\r\n <mat-menu #menu=\"matMenu\" xPosition=\"before\">\r\n @for (menuButton of button.menuButtons; track menuButton.id) {\r\n <button\r\n mat-menu-item\r\n [ngClass]=\"menuButton.cssClass\"\r\n [disabled]=\"menuButton.disabled\"\r\n [matTooltip]=\"menuButton.tooltip\"\r\n (click)=\"clickButton({ buttonId: menuButton.id, item }, $event)\">\r\n <!-- icon -->\r\n @if (menuButton.matIcon) {\r\n <mat-icon>\r\n {{ menuButton.matIcon }}\r\n </mat-icon>\r\n } @else if (menuButton.svgIcon) {\r\n <mat-icon [svgIcon]=\"menuButton.svgIcon\"></mat-icon>\r\n }\r\n <!-- label -->\r\n <span>{{ menuButton.label }}</span>\r\n </button>\r\n }\r\n </mat-menu>\r\n</ng-template>\r\n", styles: [".lf-list,.lf-list .lf-list-group{width:100%}.lf-list .lf-list-group .lf-list-group-header{font-weight:500;height:calc(var(--list-item-height) - 16px)}.lf-list-item{width:100%;display:flex;flex-flow:row nowrap;align-items:center;justify-content:center;height:var(--list-item-height);border-radius:var(--list-item-border-radius);box-sizing:border-box;overflow:hidden}.lf-list-item.disabled .lf-list-item-title-wrapper{opacity:.64}.lf-list-item .lf-list-item-sort-icon{font-size:var(--list-item-sort-icon-size);width:var(--list-item-sort-icon-size);height:var(--list-item-sort-icon-size);vertical-align:text-top}.lf-list-item .lf-list-item-checkbox{flex:0 0 var(--list-item-checkbox-width)}.lf-list-item .lf-list-item-avatar{flex:0 0 var(--list-item-avatar-size);display:flex;align-items:center;justify-content:center}.lf-list-item .lf-list-item-avatar img{width:var(--list-item-avatar-size);height:var(--list-item-avatar-size);border-radius:50%;object-fit:cover}.lf-list-item .lf-list-item-title-wrapper{display:flex;flex-flow:column;align-items:flex-start;flex:1 1 var(--list-item-title-width);overflow:hidden}.lf-list-item .lf-list-item-title-wrapper .lf-list-item-title{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.lf-list-item .lf-list-item-title-wrapper .lf-list-item-subtitle{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:.8rem}.lf-list-item .lf-list-item-link{min-width:0;color:inherit;text-decoration:none}.lf-list-item .lf-list-item-buttons{flex:0 0 auto;display:flex;flex-flow:row nowrap;align-items:center;justify-content:space-between}.lf-list-item.lf-list-item-header{font-weight:500}.lf-list-item.lf-list-item-header .lf-list-item-title-wrapper span{width:var(--list-item-title-wrapper-width)}.lf-list-item.lf-list-item-data:hover{background-color:#00000014}.lf-list-item .flex-row{display:flex!important;flex-flow:row nowrap;align-items:center}.drop-zone{width:100%;height:var(--list-item-height);border:2px dashed var(--color-gray);border-radius:var(--list-item-border-radius);box-sizing:border-box}.clickable{cursor:pointer!important}.cdk-drag-preview{color:var(--mat-app-text-color, inherit)!important;background:var(--mat-app-background-color, inherit)!important;box-sizing:border-box;border-radius:var(--list-item-border-radius);opacity:.8;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:.4}.cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-animating{transition:transform .3s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$3.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i3$3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i3$3.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i3$3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i3$3.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatRippleModule }, { kind: "directive", type: i6$1.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i3$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i3$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i10.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1835
1835
  }
1836
1836
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ListComponent, decorators: [{
1837
1837
  type: Component,
@@ -1843,12 +1843,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
1843
1843
  MatCheckboxModule,
1844
1844
  MatRippleModule,
1845
1845
  MatIconModule,
1846
+ MatMenuModule,
1846
1847
  MatTooltipModule,
1847
1848
  MatDividerModule,
1848
1849
  KeyValuePipe,
1849
1850
  NgClass,
1850
1851
  NgTemplateOutlet,
1851
- ], template: "<div class=\"lf-list\" cdkDropListGroup>\r\n <!-- Header -->\r\n @if (header(); as header) {\r\n <div\r\n class=\"lf-list-item lf-list-item-header\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\">\r\n <!-- avatar -->\r\n @if (header.avatar) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <img [src]=\"header.avatar\" alt=\"Avatar of header\" (error)=\"onImageError($event)\" />\r\n </div>\r\n } @else if (header.matIcon || header.svgIcon) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <!-- icon -->\r\n @if (header.matIcon) {\r\n <mat-icon>\r\n {{ header.matIcon }}\r\n </mat-icon>\r\n } @else if (header.svgIcon) {\r\n <mat-icon [svgIcon]=\"header.svgIcon\"></mat-icon>\r\n }\r\n </div>\r\n } @else if (hasAvatars) {\r\n <div class=\"lf-list-item-avatar px-1\"></div>\r\n }\r\n\r\n <!-- title -->\r\n <div class=\"lf-list-item-title-wrapper flex-row\">\r\n @for (item of header.items; track $index) {\r\n <span [class.clickable]=\"item.sortToken\" (click)=\"updateSortToken(item.sortToken)\">\r\n {{ item.title }}\r\n @if (sortToken() === item.sortToken) {\r\n <mat-icon class=\"lf-list-item-sort-icon\">\r\n {{ sortAsc() ? 'arrow_downward' : 'arrow_upward' }}\r\n </mat-icon>\r\n }\r\n </span>\r\n }\r\n </div>\r\n\r\n <!-- buttons -->\r\n <div class=\"lf-list-item-buttons\" [class.gap-2]=\"!isMobile()\" [class.gap-1]=\"isMobile()\">\r\n @for (button of header.buttons; track button.id) {\r\n @if (button.label) {\r\n <button\r\n mat-button\r\n class=\"lf-list-item-button\"\r\n [class.disabled]=\"button.disabled\"\r\n [ngClass]=\"button.cssClass\"\r\n [disabled]=\"button.disabled\"\r\n [matTooltip]=\"button.tooltip\"\r\n (click)=\"clickButton({ buttonId: button.id, item: null! }, $event)\">\r\n <!-- icon -->\r\n @if (button.matIcon) {\r\n <mat-icon>\r\n {{ button.matIcon }}\r\n </mat-icon>\r\n } @else if (button.svgIcon) {\r\n <mat-icon [svgIcon]=\"button.svgIcon\"></mat-icon>\r\n }\r\n {{ button.label }}\r\n </button>\r\n } @else {\r\n <button\r\n mat-icon-button\r\n class=\"lf-list-item-icon\"\r\n [class.disabled]=\"button.disabled\"\r\n [ngClass]=\"button.cssClass\"\r\n [disabled]=\"button.disabled\"\r\n [matTooltip]=\"button.tooltip\"\r\n [aria-label]=\"button.id || button.tooltip\"\r\n (click)=\"clickButton({ buttonId: button.id, item: null! }, $event)\">\r\n <!-- icon -->\r\n @if (button.matIcon) {\r\n <mat-icon>\r\n {{ button.matIcon }}\r\n </mat-icon>\r\n } @else if (button.svgIcon) {\r\n <mat-icon [svgIcon]=\"button.svgIcon\"></mat-icon>\r\n }\r\n </button>\r\n }\r\n }\r\n </div>\r\n\r\n <!-- checkbox -->\r\n @if (config()?.enableSelection && !config()?.disableMultiselect) {\r\n <div class=\"lf-list-item-checkbox\">\r\n <mat-checkbox\r\n [(ngModel)]=\"allSelected\"\r\n [indeterminate]=\"someSelected\"\r\n (change)=\"selectAll($event)\"></mat-checkbox>\r\n </div>\r\n }\r\n </div>\r\n <mat-divider></mat-divider>\r\n }\r\n\r\n <!-- Grouped Items -->\r\n @if (config()?.mode === 'group' && groupedItems()) {\r\n @for (group of groupedItems() | keyvalue; track group.key; let first = $first) {\r\n <div class=\"lf-list-group\" [class.mt-4]=\"!first\">\r\n @if (group.key) {\r\n <div\r\n class=\"lf-list-item lf-list-group-header\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\">\r\n <div class=\"lf-list-item-avatar px-1\"></div>\r\n <div class=\"lf-list-item-title-wrapper flex-row\">\r\n <span>{{ group.key }}</span>\r\n </div>\r\n </div>\r\n }\r\n <div\r\n [id]=\"group.key\"\r\n cdkDropList\r\n [cdkDropListData]=\"group.value\"\r\n [cdkDropListDisabled]=\"!config()?.enableDragging\"\r\n [cdkDropListConnectedTo]=\"connectedDropListIds()!\"\r\n (cdkDropListDropped)=\"dropItem($event, group.key)\"\r\n [class.drop-zone]=\"config()?.enableDragging && group.value.length <= 0\">\r\n @for (item of group.value; track item.id; let last = $last) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"item.disabled || !config()?.enableDragging\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item, last: last }\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n <!-- Flat Items -->\r\n } @else {\r\n <div\r\n [id]=\"dropListId()!\"\r\n cdkDropList\r\n [cdkDropListData]=\"items()\"\r\n [cdkDropListDisabled]=\"!config()?.enableDragging\"\r\n [cdkDropListConnectedTo]=\"connectedDropListIds()!\"\r\n (cdkDropListDropped)=\"dropItem($event, dropListId()!)\"\r\n [class.drop-zone]=\"config()?.enableDragging && items().length <= 0\">\r\n @for (item of items(); track item.id; let last = $last) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"item.disabled || !config()?.enableDragging\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item, last: last }\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Item (template) -->\r\n <ng-template #listItemTemplate let-item let-last=\"last\">\r\n <div\r\n class=\"lf-list-item lf-list-item-data\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\"\r\n [class.active]=\"item.checked\"\r\n [class.disabled]=\"item.disabled\"\r\n [class.clickable]=\"item.clickable && !item.disabled\"\r\n [ngClass]=\"item.cssClass\"\r\n matRipple\r\n [matRippleDisabled]=\"!item.clickable\"\r\n (click)=\"item.clickable && !item.disabled && !isLink(item) ? clickItem(item, $event) : null\">\r\n <!-- content (anchor only when the item links, so buttons stay outside it) -->\r\n @if (isLink(item)) {\r\n @if (item.routerLink) {\r\n <a\r\n class=\"lf-list-item-link flex-row-nowrap align-center flex-auto h-100 overflow-hidden\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\"\r\n [routerLink]=\"item.routerLink\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemContentTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n </a>\r\n } @else {\r\n <a\r\n class=\"lf-list-item-link flex-row-nowrap align-center flex-auto h-100 overflow-hidden\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\"\r\n [href]=\"item.href\"\r\n [target]=\"item.externalTab ? '_blank' : null\"\r\n [rel]=\"item.externalTab ? 'noopener' : null\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemContentTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n </a>\r\n }\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemContentTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n }\r\n\r\n <!-- buttons -->\r\n <div class=\"lf-list-item-buttons\" [class.gap-2]=\"!isMobile()\" [class.gap-1]=\"isMobile()\">\r\n @if (buttonsTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"buttonsTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else {\r\n @let combinedButtons = getCombinedButtons(item);\r\n @for (button of combinedButtons; track button.id) {\r\n @if (!item.hiddenButtonIds?.includes(button.id)) {\r\n @let disabled =\r\n button.disabled || item.disabled || item.disabledButtonIds?.includes(button.id);\r\n @if (button.label) {\r\n <button\r\n mat-button\r\n class=\"lf-list-item-button\"\r\n [class.disabled]=\"disabled\"\r\n [ngClass]=\"button.cssClass\"\r\n [disabled]=\"disabled\"\r\n [matTooltip]=\"button.tooltip\"\r\n (click)=\"clickButton({ buttonId: button.id, item }, $event)\">\r\n <!-- icon -->\r\n @if (button.matIcon) {\r\n <mat-icon>\r\n {{ button.matIcon }}\r\n </mat-icon>\r\n } @else if (button.svgIcon) {\r\n <mat-icon [svgIcon]=\"button.svgIcon\"></mat-icon>\r\n }\r\n {{ button.label }}\r\n </button>\r\n } @else {\r\n <button\r\n mat-icon-button\r\n class=\"lf-list-item-icon\"\r\n [class.disabled]=\"disabled\"\r\n [ngClass]=\"button.cssClass\"\r\n [disabled]=\"disabled\"\r\n [matTooltip]=\"button.tooltip\"\r\n [aria-label]=\"button.id || button.tooltip\"\r\n (click)=\"clickButton({ buttonId: button.id, item }, $event)\">\r\n <!-- icon -->\r\n @if (button.matIcon) {\r\n <mat-icon>\r\n {{ button.matIcon }}\r\n </mat-icon>\r\n } @else if (button.svgIcon) {\r\n <mat-icon [svgIcon]=\"button.svgIcon\"></mat-icon>\r\n }\r\n </button>\r\n }\r\n }\r\n }\r\n }\r\n\r\n <!-- drag -->\r\n @if (config()?.enableDragging) {\r\n <button\r\n mat-icon-button\r\n class=\"lf-list-item-icon\"\r\n [class.disabled]=\"item.disabled\"\r\n [disabled]=\"item.disabled\"\r\n [aria-label]=\"'Drag handle'\"\r\n (click)=\"stopPropagation($event)\"\r\n cdkDragHandle>\r\n <mat-icon>drag_indicator</mat-icon>\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- checkbox -->\r\n @if (config()?.enableSelection) {\r\n <div class=\"lf-list-item-checkbox\">\r\n <mat-checkbox\r\n [(ngModel)]=\"item.checked\"\r\n [disabled]=\"item.disabled!\"\r\n (change)=\"selectItem(item, $event)\"\r\n (click)=\"stopPropagation($event)\"></mat-checkbox>\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (config()?.showDividers && !last) {\r\n <mat-divider></mat-divider>\r\n }\r\n </ng-template>\r\n\r\n <!-- Item content (template) -->\r\n <ng-template #listItemContentTemplate let-item>\r\n <!-- avatar -->\r\n @if (avatarTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"avatarTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else if (item.avatar) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <img [src]=\"item.avatar\" [alt]=\"'Avatar of ' + item.title\" (error)=\"onImageError($event)\" />\r\n </div>\r\n } @else if (item.matIcon || item.svgIcon) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <!-- icon -->\r\n @if (item.matIcon) {\r\n <mat-icon>\r\n {{ item.matIcon }}\r\n </mat-icon>\r\n } @else if (item.svgIcon) {\r\n <mat-icon [svgIcon]=\"item.svgIcon\"></mat-icon>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- title -->\r\n <div class=\"lf-list-item-title-wrapper\">\r\n <span class=\"lf-list-item-title\">\r\n @if (titleTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"titleTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ item.title }}\r\n }\r\n </span>\r\n @if (item.subtitle || subtitleTemplate()) {\r\n <span class=\"lf-list-item-subtitle\">\r\n @if (subtitleTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"subtitleTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ item.subtitle }}\r\n }\r\n </span>\r\n }\r\n </div>\r\n </ng-template>\r\n</div>\r\n", styles: [".lf-list,.lf-list .lf-list-group{width:100%}.lf-list .lf-list-group .lf-list-group-header{font-weight:500;height:calc(var(--list-item-height) - 16px)}.lf-list-item{width:100%;display:flex;flex-flow:row nowrap;align-items:center;justify-content:center;height:var(--list-item-height);border-radius:var(--list-item-border-radius);box-sizing:border-box;overflow:hidden}.lf-list-item.disabled .lf-list-item-title-wrapper{opacity:.64}.lf-list-item .lf-list-item-sort-icon{font-size:var(--list-item-sort-icon-size);width:var(--list-item-sort-icon-size);height:var(--list-item-sort-icon-size);vertical-align:text-top}.lf-list-item .lf-list-item-checkbox{flex:0 0 var(--list-item-checkbox-width)}.lf-list-item .lf-list-item-avatar{flex:0 0 var(--list-item-avatar-size);display:flex;align-items:center;justify-content:center}.lf-list-item .lf-list-item-avatar img{width:var(--list-item-avatar-size);height:var(--list-item-avatar-size);border-radius:50%;object-fit:cover}.lf-list-item .lf-list-item-title-wrapper{display:flex;flex-flow:column;align-items:flex-start;flex:1 1 var(--list-item-title-width);overflow:hidden}.lf-list-item .lf-list-item-title-wrapper .lf-list-item-title{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.lf-list-item .lf-list-item-title-wrapper .lf-list-item-subtitle{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:.8rem}.lf-list-item .lf-list-item-link{min-width:0;color:inherit;text-decoration:none}.lf-list-item .lf-list-item-buttons{flex:0 0 auto;display:flex;flex-flow:row nowrap;align-items:center;justify-content:space-between}.lf-list-item.lf-list-item-header{font-weight:500}.lf-list-item.lf-list-item-header .lf-list-item-title-wrapper span{width:var(--list-item-title-wrapper-width)}.lf-list-item.lf-list-item-data:hover{background-color:#00000014}.lf-list-item .flex-row{display:flex!important;flex-flow:row nowrap;align-items:center}.drop-zone{width:100%;height:var(--list-item-height);border:2px dashed var(--color-gray);border-radius:var(--list-item-border-radius);box-sizing:border-box}.clickable{cursor:pointer!important}.cdk-drag-preview{color:var(--mat-app-text-color, inherit)!important;background:var(--mat-app-background-color, inherit)!important;box-sizing:border-box;border-radius:var(--list-item-border-radius);opacity:.8;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:.4}.cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-animating{transition:transform .3s cubic-bezier(0,0,.2,1)}\n"] }]
1852
+ ], template: "<div class=\"lf-list\" cdkDropListGroup>\r\n <!-- Header -->\r\n @if (header(); as header) {\r\n <div\r\n class=\"lf-list-item lf-list-item-header\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\">\r\n <!-- avatar -->\r\n @if (header.avatar) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <img [src]=\"header.avatar\" alt=\"Avatar of header\" (error)=\"onImageError($event)\" />\r\n </div>\r\n } @else if (header.matIcon || header.svgIcon) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <!-- icon -->\r\n @if (header.matIcon) {\r\n <mat-icon>\r\n {{ header.matIcon }}\r\n </mat-icon>\r\n } @else if (header.svgIcon) {\r\n <mat-icon [svgIcon]=\"header.svgIcon\"></mat-icon>\r\n }\r\n </div>\r\n } @else if (hasAvatars) {\r\n <div class=\"lf-list-item-avatar px-1\"></div>\r\n }\r\n\r\n <!-- title -->\r\n <div class=\"lf-list-item-title-wrapper flex-row\">\r\n @for (item of header.items; track $index) {\r\n <span [class.clickable]=\"item.sortToken\" (click)=\"updateSortToken(item.sortToken)\">\r\n {{ item.title }}\r\n @if (sortToken() === item.sortToken) {\r\n <mat-icon class=\"lf-list-item-sort-icon\">\r\n {{ sortAsc() ? 'arrow_downward' : 'arrow_upward' }}\r\n </mat-icon>\r\n }\r\n </span>\r\n }\r\n </div>\r\n\r\n <!-- buttons -->\r\n <div class=\"lf-list-item-buttons\" [class.gap-2]=\"!isMobile()\" [class.gap-1]=\"isMobile()\">\r\n @for (button of header.buttons; track button.id) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"listButtonTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n button: button,\r\n item: null,\r\n disabled: button.disabled,\r\n }\"></ng-container>\r\n }\r\n </div>\r\n\r\n <!-- checkbox -->\r\n @if (config()?.enableSelection && !config()?.disableMultiselect) {\r\n <div class=\"lf-list-item-checkbox\">\r\n <mat-checkbox\r\n [(ngModel)]=\"allSelected\"\r\n [indeterminate]=\"someSelected\"\r\n (change)=\"selectAll($event)\"></mat-checkbox>\r\n </div>\r\n }\r\n </div>\r\n <mat-divider></mat-divider>\r\n }\r\n\r\n <!-- Grouped Items -->\r\n @if (config()?.mode === 'group' && groupedItems()) {\r\n @for (group of groupedItems() | keyvalue; track group.key; let first = $first) {\r\n <div class=\"lf-list-group\" [class.mt-4]=\"!first\">\r\n @if (group.key) {\r\n <div\r\n class=\"lf-list-item lf-list-group-header\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\">\r\n <div class=\"lf-list-item-avatar px-1\"></div>\r\n <div class=\"lf-list-item-title-wrapper flex-row\">\r\n <span>{{ group.key }}</span>\r\n </div>\r\n </div>\r\n }\r\n <div\r\n [id]=\"group.key\"\r\n cdkDropList\r\n [cdkDropListData]=\"group.value\"\r\n [cdkDropListDisabled]=\"!config()?.enableDragging\"\r\n [cdkDropListConnectedTo]=\"connectedDropListIds()!\"\r\n (cdkDropListDropped)=\"dropItem($event, group.key)\"\r\n [class.drop-zone]=\"config()?.enableDragging && group.value.length <= 0\">\r\n @for (item of group.value; track item.id; let last = $last) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"item.disabled || !config()?.enableDragging\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item, last: last }\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n <!-- Flat Items -->\r\n } @else {\r\n <div\r\n [id]=\"dropListId()!\"\r\n cdkDropList\r\n [cdkDropListData]=\"items()\"\r\n [cdkDropListDisabled]=\"!config()?.enableDragging\"\r\n [cdkDropListConnectedTo]=\"connectedDropListIds()!\"\r\n (cdkDropListDropped)=\"dropItem($event, dropListId()!)\"\r\n [class.drop-zone]=\"config()?.enableDragging && items().length <= 0\">\r\n @for (item of items(); track item.id; let last = $last) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"item.disabled || !config()?.enableDragging\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item, last: last }\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Item (template) -->\r\n <ng-template #listItemTemplate let-item let-last=\"last\">\r\n <div\r\n class=\"lf-list-item lf-list-item-data\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\"\r\n [class.active]=\"item.checked\"\r\n [class.disabled]=\"item.disabled\"\r\n [class.clickable]=\"item.clickable && !item.disabled\"\r\n [ngClass]=\"item.cssClass\"\r\n matRipple\r\n [matRippleDisabled]=\"!item.clickable\"\r\n (click)=\"item.clickable && !item.disabled && !isLink(item) ? clickItem(item, $event) : null\">\r\n <!-- content (anchor only when the item links, so buttons stay outside it) -->\r\n @if (isLink(item)) {\r\n @if (item.routerLink) {\r\n <a\r\n class=\"lf-list-item-link flex-row-nowrap align-center flex-auto h-100 overflow-hidden\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\"\r\n [routerLink]=\"item.routerLink\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemContentTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n </a>\r\n } @else {\r\n <a\r\n class=\"lf-list-item-link flex-row-nowrap align-center flex-auto h-100 overflow-hidden\"\r\n [class.gap-2]=\"!isMobile()\"\r\n [class.gap-1]=\"isMobile()\"\r\n [href]=\"item.href\"\r\n [target]=\"item.externalTab ? '_blank' : null\"\r\n [rel]=\"item.externalTab ? 'noopener' : null\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemContentTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n </a>\r\n }\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"listItemContentTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n }\r\n\r\n <!-- buttons -->\r\n <div class=\"lf-list-item-buttons\" [class.gap-2]=\"!isMobile()\" [class.gap-1]=\"isMobile()\">\r\n @if (buttonsTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"buttonsTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else {\r\n @let combinedButtons = getCombinedButtons(item);\r\n @for (button of combinedButtons; track button.id) {\r\n @if (!item.hiddenButtonIds?.includes(button.id)) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"listButtonTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n button: button,\r\n item: item,\r\n disabled:\r\n button.disabled || item.disabled || item.disabledButtonIds?.includes(button.id),\r\n }\"></ng-container>\r\n }\r\n }\r\n }\r\n\r\n <!-- drag -->\r\n @if (config()?.enableDragging) {\r\n <button\r\n mat-icon-button\r\n class=\"lf-list-item-icon\"\r\n [class.disabled]=\"item.disabled\"\r\n [disabled]=\"item.disabled\"\r\n [aria-label]=\"'Drag handle'\"\r\n (click)=\"stopPropagation($event)\"\r\n cdkDragHandle>\r\n <mat-icon>drag_indicator</mat-icon>\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- checkbox -->\r\n @if (config()?.enableSelection) {\r\n <div class=\"lf-list-item-checkbox\">\r\n <mat-checkbox\r\n [(ngModel)]=\"item.checked\"\r\n [disabled]=\"item.disabled!\"\r\n (change)=\"selectItem(item, $event)\"\r\n (click)=\"stopPropagation($event)\"></mat-checkbox>\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (config()?.showDividers && !last) {\r\n <mat-divider></mat-divider>\r\n }\r\n </ng-template>\r\n\r\n <!-- Item content (template) -->\r\n <ng-template #listItemContentTemplate let-item>\r\n <!-- avatar -->\r\n @if (avatarTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"avatarTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else if (item.avatar) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <img [src]=\"item.avatar\" [alt]=\"'Avatar of ' + item.title\" (error)=\"onImageError($event)\" />\r\n </div>\r\n } @else if (item.matIcon || item.svgIcon) {\r\n <div class=\"lf-list-item-avatar px-1\">\r\n <!-- icon -->\r\n @if (item.matIcon) {\r\n <mat-icon>\r\n {{ item.matIcon }}\r\n </mat-icon>\r\n } @else if (item.svgIcon) {\r\n <mat-icon [svgIcon]=\"item.svgIcon\"></mat-icon>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- title -->\r\n <div class=\"lf-list-item-title-wrapper\">\r\n <span class=\"lf-list-item-title\">\r\n @if (titleTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"titleTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ item.title }}\r\n }\r\n </span>\r\n @if (item.subtitle || subtitleTemplate()) {\r\n <span class=\"lf-list-item-subtitle\">\r\n @if (subtitleTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"subtitleTemplate()!.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ item.subtitle }}\r\n }\r\n </span>\r\n }\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n<!-- button (template) -->\r\n<!-- The menu lives inside this template, so every button instantiation owns its own -->\r\n<ng-template #listButtonTemplate let-button=\"button\" let-item=\"item\" let-disabled=\"disabled\">\r\n @if (button.label) {\r\n <button\r\n mat-button\r\n class=\"lf-list-item-button\"\r\n [class.disabled]=\"disabled\"\r\n [ngClass]=\"button.cssClass\"\r\n [disabled]=\"disabled\"\r\n [matTooltip]=\"button.tooltip\"\r\n [matMenuTriggerFor]=\"button.menuButtons?.length ? menu : null\"\r\n (click)=\"clickButton({ buttonId: button.id, item }, $event)\">\r\n <!-- icon -->\r\n @if (button.matIcon) {\r\n <mat-icon>\r\n {{ button.matIcon }}\r\n </mat-icon>\r\n } @else if (button.svgIcon) {\r\n <mat-icon [svgIcon]=\"button.svgIcon\"></mat-icon>\r\n }\r\n {{ button.label }}\r\n </button>\r\n } @else {\r\n <button\r\n mat-icon-button\r\n class=\"lf-list-item-icon\"\r\n [class.disabled]=\"disabled\"\r\n [ngClass]=\"button.cssClass\"\r\n [disabled]=\"disabled\"\r\n [matTooltip]=\"button.tooltip\"\r\n [aria-label]=\"button.id || button.tooltip\"\r\n [matMenuTriggerFor]=\"button.menuButtons?.length ? menu : null\"\r\n (click)=\"clickButton({ buttonId: button.id, item }, $event)\">\r\n <!-- icon -->\r\n @if (button.matIcon) {\r\n <mat-icon>\r\n {{ button.matIcon }}\r\n </mat-icon>\r\n } @else if (button.svgIcon) {\r\n <mat-icon [svgIcon]=\"button.svgIcon\"></mat-icon>\r\n }\r\n </button>\r\n }\r\n\r\n <!-- menu -->\r\n <mat-menu #menu=\"matMenu\" xPosition=\"before\">\r\n @for (menuButton of button.menuButtons; track menuButton.id) {\r\n <button\r\n mat-menu-item\r\n [ngClass]=\"menuButton.cssClass\"\r\n [disabled]=\"menuButton.disabled\"\r\n [matTooltip]=\"menuButton.tooltip\"\r\n (click)=\"clickButton({ buttonId: menuButton.id, item }, $event)\">\r\n <!-- icon -->\r\n @if (menuButton.matIcon) {\r\n <mat-icon>\r\n {{ menuButton.matIcon }}\r\n </mat-icon>\r\n } @else if (menuButton.svgIcon) {\r\n <mat-icon [svgIcon]=\"menuButton.svgIcon\"></mat-icon>\r\n }\r\n <!-- label -->\r\n <span>{{ menuButton.label }}</span>\r\n </button>\r\n }\r\n </mat-menu>\r\n</ng-template>\r\n", styles: [".lf-list,.lf-list .lf-list-group{width:100%}.lf-list .lf-list-group .lf-list-group-header{font-weight:500;height:calc(var(--list-item-height) - 16px)}.lf-list-item{width:100%;display:flex;flex-flow:row nowrap;align-items:center;justify-content:center;height:var(--list-item-height);border-radius:var(--list-item-border-radius);box-sizing:border-box;overflow:hidden}.lf-list-item.disabled .lf-list-item-title-wrapper{opacity:.64}.lf-list-item .lf-list-item-sort-icon{font-size:var(--list-item-sort-icon-size);width:var(--list-item-sort-icon-size);height:var(--list-item-sort-icon-size);vertical-align:text-top}.lf-list-item .lf-list-item-checkbox{flex:0 0 var(--list-item-checkbox-width)}.lf-list-item .lf-list-item-avatar{flex:0 0 var(--list-item-avatar-size);display:flex;align-items:center;justify-content:center}.lf-list-item .lf-list-item-avatar img{width:var(--list-item-avatar-size);height:var(--list-item-avatar-size);border-radius:50%;object-fit:cover}.lf-list-item .lf-list-item-title-wrapper{display:flex;flex-flow:column;align-items:flex-start;flex:1 1 var(--list-item-title-width);overflow:hidden}.lf-list-item .lf-list-item-title-wrapper .lf-list-item-title{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.lf-list-item .lf-list-item-title-wrapper .lf-list-item-subtitle{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:.8rem}.lf-list-item .lf-list-item-link{min-width:0;color:inherit;text-decoration:none}.lf-list-item .lf-list-item-buttons{flex:0 0 auto;display:flex;flex-flow:row nowrap;align-items:center;justify-content:space-between}.lf-list-item.lf-list-item-header{font-weight:500}.lf-list-item.lf-list-item-header .lf-list-item-title-wrapper span{width:var(--list-item-title-wrapper-width)}.lf-list-item.lf-list-item-data:hover{background-color:#00000014}.lf-list-item .flex-row{display:flex!important;flex-flow:row nowrap;align-items:center}.drop-zone{width:100%;height:var(--list-item-height);border:2px dashed var(--color-gray);border-radius:var(--list-item-border-radius);box-sizing:border-box}.clickable{cursor:pointer!important}.cdk-drag-preview{color:var(--mat-app-text-color, inherit)!important;background:var(--mat-app-background-color, inherit)!important;box-sizing:border-box;border-radius:var(--list-item-border-radius);opacity:.8;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:.4}.cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-animating{transition:transform .3s cubic-bezier(0,0,.2,1)}\n"] }]
1852
1853
  }], ctorParameters: () => [], propDecorators: { avatarTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ListItemAvatarDirective), { isSignal: true }] }], titleTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ListItemTitleDirective), { isSignal: true }] }], subtitleTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ListItemSubtitleDirective), { isSignal: true }] }], buttonsTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ListItemButtonsDirective), { isSignal: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], header: [{ type: i0.Input, args: [{ isSignal: true, alias: "header", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], groupedItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupedItems", required: false }] }], buttons: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttons", required: false }] }], dropListId: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropListId", required: false }] }], connectedDropListIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "connectedDropListIds", required: false }] }], sortChangeEvent: [{ type: i0.Output, args: ["sortChangeEvent"] }], selectionChangeEvent: [{ type: i0.Output, args: ["selectionChangeEvent"] }], itemClickEvent: [{ type: i0.Output, args: ["itemClickEvent"] }], itemDropEvent: [{ type: i0.Output, args: ["itemDropEvent"] }], buttonClickEvent: [{ type: i0.Output, args: ["buttonClickEvent"] }], allSelected: [{ type: i0.Input, args: [{ isSignal: true, alias: "allSelected", required: false }] }, { type: i0.Output, args: ["allSelectedChange"] }] } });
1853
1854
 
1854
1855
  class NotificationComponent {