cfc-ds
Version:
Design System do Conselho Federal de Contabilidade baseado no govbr-ds
207 lines • 69.9 kB
JavaScript
import { Component, Input, Output, EventEmitter } from '@angular/core';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/flex-layout/extended";
import * as i3 from "../icon/icon.component";
export class ListComponent {
// Propriedades existentes
items = [];
title = '';
headerActions = false;
layout = 'vertical';
spacing = 'none';
lineHeight = '1';
showDividers = true;
grouped = false;
expandable = true;
draggable = false;
// Novas propriedades para densidade
density = 'medium';
flexHeight = false;
// Eventos
itemClick = new EventEmitter();
actionClick = new EventEmitter();
checkboxChange = new EventEmitter();
itemsReordered = new EventEmitter();
// Estados internos
expandedGroups = new Set();
dragItemIndex = null;
dragGroupIndex = null;
dragGroupItemIndex = null;
constructor() { }
ngOnInit() {
// Se expandable for falso, todos os grupos começam expandidos
if (!this.expandable && this.grouped) {
this.items.forEach(group => {
if (this.isGroup(group)) {
this.expandedGroups.add(group.id);
}
});
}
}
// Verificar se o item é um grupo
isGroup(item) {
return item && item.hasOwnProperty('items') && Array.isArray(item.items);
}
// Verificar se um grupo está expandido
isGroupExpanded(groupId) {
return this.expandedGroups.has(groupId);
}
// Alternar a expansão de um grupo
toggleGroup(groupId) {
if (this.expandedGroups.has(groupId)) {
this.expandedGroups.delete(groupId);
}
else {
this.expandedGroups.add(groupId);
}
}
// Lidar com clique em um item
onItemClick(item) {
this.itemClick.emit(item);
}
// Lidar com clique em um botão de ação
onActionClick(event, item) {
event.stopPropagation();
this.actionClick.emit(item);
}
// Lidar com alteração no checkbox
onCheckboxChange(event, item) {
event.stopPropagation();
item.checked = event.target.checked;
this.checkboxChange.emit(item);
}
// Métodos para arrastar e soltar (Drag & Drop)
onDragStart(event, index) {
this.dragItemIndex = index;
this.dragGroupIndex = null;
this.dragGroupItemIndex = null;
if (event.dataTransfer) {
event.dataTransfer.effectAllowed = 'move';
event.dataTransfer.setData('text/plain', index.toString());
// Adicionar estilo de arrastar
const element = event.target;
setTimeout(() => {
element.classList.add('dragging');
}, 0);
}
}
onGroupItemDragStart(event, groupIndex, itemIndex) {
this.dragGroupIndex = groupIndex;
this.dragGroupItemIndex = itemIndex;
this.dragItemIndex = null;
if (event.dataTransfer) {
event.dataTransfer.effectAllowed = 'move';
event.dataTransfer.setData('text/plain', `${groupIndex}-${itemIndex}`);
// Adicionar estilo de arrastar
const element = event.target;
setTimeout(() => {
element.classList.add('dragging');
}, 0);
}
}
onDragOver(event, index) {
event.preventDefault();
const element = event.target;
const listItem = element.closest('.list-item');
if (listItem) {
listItem.classList.add('drag-over');
}
}
onDragLeave(event) {
const element = event.target;
const listItem = element.closest('.list-item');
if (listItem) {
listItem.classList.remove('drag-over');
}
}
onDrop(event, index) {
event.preventDefault();
const element = event.target;
const listItem = element.closest('.list-item');
if (listItem) {
listItem.classList.remove('drag-over');
}
if (this.dragItemIndex !== null && this.dragItemIndex !== index) {
// Reordenar itens
const item = this.items[this.dragItemIndex];
this.items.splice(this.dragItemIndex, 1);
this.items.splice(index, 0, item);
// Emitir evento de reordenação
this.itemsReordered.emit([...this.items]);
}
}
onGroupItemDrop(event, groupIndex, itemIndex) {
event.preventDefault();
const element = event.target;
const listItem = element.closest('.list-item');
if (listItem) {
listItem.classList.remove('drag-over');
}
if (this.dragGroupIndex !== null && this.dragGroupItemIndex !== null) {
if (this.dragGroupIndex === groupIndex && this.dragGroupItemIndex !== itemIndex) {
// Reordenar dentro do mesmo grupo
const group = this.items[groupIndex];
const item = group.items[this.dragGroupItemIndex];
group.items.splice(this.dragGroupItemIndex, 1);
group.items.splice(itemIndex, 0, item);
}
else if (this.dragGroupIndex !== groupIndex) {
// Mover entre grupos diferentes
const sourceGroup = this.items[this.dragGroupIndex];
const targetGroup = this.items[groupIndex];
const item = sourceGroup.items[this.dragGroupItemIndex];
sourceGroup.items.splice(this.dragGroupItemIndex, 1);
targetGroup.items.splice(itemIndex, 0, item);
}
// Emitir evento de reordenação
this.itemsReordered.emit([...this.items]);
}
}
onDragEnd(event) {
const element = event.target;
element.classList.remove('dragging');
this.dragItemIndex = null;
this.dragGroupIndex = null;
this.dragGroupItemIndex = null;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ListComponent, selector: "cfc-list", inputs: { items: "items", title: "title", headerActions: "headerActions", layout: "layout", spacing: "spacing", lineHeight: "lineHeight", showDividers: "showDividers", grouped: "grouped", expandable: "expandable", draggable: "draggable", density: "density", flexHeight: "flexHeight" }, outputs: { itemClick: "itemClick", actionClick: "actionClick", checkboxChange: "checkboxChange", itemsReordered: "itemsReordered" }, ngImport: i0, template: "<div class=\"list-container\" [ngClass]=\"{'list-horizontal': layout === 'horizontal'}\">\r\n <!-- Header (Optional) -->\r\n <div class=\"list-header\" *ngIf=\"title\">\r\n <h2 class=\"list-title\">{{ title }}</h2>\r\n <div class=\"header-actions\" *ngIf=\"headerActions\">\r\n <button class=\"header-action-button search-button\">\r\n <cfc-icon [familyName]=\"'fas'\" [iconName]=\"'search'\" size=\"24px\"></cfc-icon>\r\n </button>\r\n <button class=\"header-action-button menu-button\">\r\n <cfc-icon [familyName]=\"'fas'\" [iconName]=\"'ellipsis-v'\" size=\"24px\"></cfc-icon>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- List Items Container -->\r\n <div class=\"list-items\" [ngClass]=\"'spacing-' + spacing\">\r\n <ng-container *ngIf=\"!grouped; else groupedContent\">\r\n <!-- Regular List Items -->\r\n <ng-container *ngFor=\"let item of items; let i = index; let last = last\">\r\n <div \r\n class=\"list-item\" \r\n [ngClass]=\"{\r\n 'line-height-1': lineHeight === '1',\r\n 'line-height-2': lineHeight === '2',\r\n 'line-height-3': lineHeight === '3',\r\n 'item-checked': !isGroup(item) && item.checked,\r\n 'density-high': density === 'high',\r\n 'density-medium': density === 'medium',\r\n 'density-low': density === 'low',\r\n 'flex-height': flexHeight\r\n }\"\r\n (click)=\"!isGroup(item) && onItemClick(item)\"\r\n [draggable]=\"draggable\"\r\n (dragstart)=\"onDragStart($event, i)\"\r\n (dragover)=\"onDragOver($event, i)\"\r\n (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onDrop($event, i)\"\r\n (dragend)=\"onDragEnd($event)\">\r\n \r\n <!-- Visual Support (Optional) -->\r\n <div class=\"visual-support\" *ngIf=\"!isGroup(item) && (item.icon || item.avatar || item.image || draggable)\">\r\n <cfc-icon \r\n *ngIf=\"draggable\"\r\n [familyName]=\"'fas'\" \r\n [iconName]=\"'grip-lines'\"\r\n size=\"16px\"\r\n color=\"rgba(0, 0, 0, 0.3)\"\r\n class=\"drag-handle\">\r\n </cfc-icon>\r\n <img *ngIf=\"!isGroup(item) && item.avatar\" class=\"avatar\" [src]=\"item.avatar\" alt=\"Avatar\">\r\n <img *ngIf=\"!isGroup(item) && item.image\" class=\"image\" [src]=\"item.image\" alt=\"Image\">\r\n <cfc-icon \r\n *ngIf=\"!isGroup(item) && item.icon\" \r\n [familyName]=\"item.iconFamily || 'fas'\" \r\n [iconName]=\"item.icon\"\r\n size=\"24px\"\r\n color=\"rgba(0, 0, 0, 0.54)\">\r\n </cfc-icon>\r\n </div>\r\n \r\n <!-- Main Content (Required) -->\r\n <div class=\"main-content\" *ngIf=\"!isGroup(item)\">\r\n <div class=\"subtitle\" *ngIf=\"item.subtitle\">{{ item.subtitle }}</div>\r\n <div class=\"primary-text\">{{ item.primaryText }}</div>\r\n <div class=\"secondary-text\" *ngIf=\"item.secondaryText\">{{ item.secondaryText }}</div>\r\n </div>\r\n \r\n <!-- Complementary Support (Optional) -->\r\n <div class=\"complementary-support\" *ngIf=\"!isGroup(item)\">\r\n <span class=\"meta\" *ngIf=\"item.meta\">{{ item.meta }}</span>\r\n \r\n <input \r\n *ngIf=\"item.hasOwnProperty('checked')\" \r\n type=\"checkbox\" \r\n [checked]=\"item.checked\" \r\n (change)=\"onCheckboxChange($event, item)\"\r\n (click)=\"$event.stopPropagation()\">\r\n \r\n <button \r\n *ngIf=\"item.hasAction\" \r\n class=\"action-button\" \r\n (click)=\"onActionClick($event, item)\">\r\n <cfc-icon \r\n [familyName]=\"item.actionIconFamily || 'fas'\" \r\n [iconName]=\"item.actionIcon || 'chevron-right'\"\r\n size=\"24px\"\r\n color=\"rgba(0, 0, 0, 0.54)\">\r\n </cfc-icon>\r\n </button>\r\n </div>\r\n </div>\r\n \r\n <!-- Divider (Optional) -->\r\n <div class=\"divider\" *ngIf=\"showDividers && !last\"></div>\r\n </ng-container>\r\n </ng-container>\r\n \r\n <!-- Grouped Content Template -->\r\n <ng-template #groupedContent>\r\n <ng-container *ngFor=\"let group of items; let groupIndex = index; let lastGroup = last\">\r\n <ng-container *ngIf=\"isGroup(group)\">\r\n <!-- Group Label -->\r\n <div class=\"list-group-label\" (click)=\"expandable && toggleGroup(group.id)\">\r\n <div class=\"group-title\">{{ group.title }}</div>\r\n <button *ngIf=\"expandable\" class=\"expand-button\">\r\n <cfc-icon \r\n [familyName]=\"'fas'\" \r\n [iconName]=\"isGroupExpanded(group.id) ? 'chevron-up' : 'chevron-down'\"\r\n size=\"24px\"\r\n color=\"rgba(0, 0, 0, 0.54)\">\r\n </cfc-icon>\r\n </button>\r\n </div>\r\n \r\n <!-- Group Items -->\r\n <div class=\"group-items\" *ngIf=\"isGroupExpanded(group.id)\">\r\n <ng-container *ngFor=\"let subItem of group.items; let i = index; let lastItem = last\">\r\n <div \r\n class=\"list-item sub-item\" \r\n [ngClass]=\"{\r\n 'line-height-1': lineHeight === '1',\r\n 'line-height-2': lineHeight === '2',\r\n 'line-height-3': lineHeight === '3',\r\n 'item-checked': subItem.checked,\r\n 'density-high': density === 'high',\r\n 'density-medium': density === 'medium',\r\n 'density-low': density === 'low',\r\n 'flex-height': flexHeight\r\n }\"\r\n (click)=\"onItemClick(subItem)\"\r\n [draggable]=\"draggable\"\r\n (dragstart)=\"onGroupItemDragStart($event, groupIndex, i)\"\r\n (dragover)=\"onDragOver($event, i)\"\r\n (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onGroupItemDrop($event, groupIndex, i)\"\r\n (dragend)=\"onDragEnd($event)\">\r\n \r\n <!-- Visual Support -->\r\n <div class=\"visual-support\" *ngIf=\"subItem.icon || subItem.avatar || subItem.image || draggable\">\r\n <cfc-icon \r\n *ngIf=\"draggable\"\r\n [familyName]=\"'fas'\" \r\n [iconName]=\"'grip-lines'\"\r\n size=\"16px\"\r\n color=\"rgba(0, 0, 0, 0.3)\"\r\n class=\"drag-handle\">\r\n </cfc-icon>\r\n <img *ngIf=\"subItem.avatar\" class=\"avatar\" [src]=\"subItem.avatar\" alt=\"Avatar\">\r\n <img *ngIf=\"subItem.image\" class=\"image\" [src]=\"subItem.image\" alt=\"Image\">\r\n <cfc-icon \r\n *ngIf=\"subItem.icon\" \r\n [familyName]=\"subItem.iconFamily || 'fas'\" \r\n [iconName]=\"subItem.icon\"\r\n size=\"24px\"\r\n color=\"rgba(0, 0, 0, 0.54)\">\r\n </cfc-icon>\r\n </div>\r\n \r\n <!-- Main Content -->\r\n <div class=\"main-content\">\r\n <div class=\"subtitle\" *ngIf=\"subItem.subtitle\">{{ subItem.subtitle }}</div>\r\n <div class=\"primary-text\">{{ subItem.primaryText }}</div>\r\n <div class=\"secondary-text\" *ngIf=\"subItem.secondaryText\">{{ subItem.secondaryText }}</div>\r\n </div>\r\n \r\n <!-- Complementary Support -->\r\n <div class=\"complementary-support\">\r\n <span class=\"meta\" *ngIf=\"subItem.meta\">{{ subItem.meta }}</span>\r\n \r\n <input \r\n *ngIf=\"subItem.hasOwnProperty('checked')\" \r\n type=\"checkbox\" \r\n [checked]=\"subItem.checked\" \r\n (change)=\"onCheckboxChange($event, subItem)\"\r\n (click)=\"$event.stopPropagation()\">\r\n \r\n <button \r\n *ngIf=\"subItem.hasAction\" \r\n class=\"action-button\" \r\n (click)=\"onActionClick($event, subItem)\">\r\n <cfc-icon \r\n [familyName]=\"subItem.actionIconFamily || 'fas'\" \r\n [iconName]=\"subItem.actionIcon || 'chevron-right'\"\r\n size=\"24px\"\r\n color=\"rgba(0, 0, 0, 0.54)\">\r\n </cfc-icon>\r\n </button>\r\n </div>\r\n </div>\r\n \r\n <!-- Divider within group -->\r\n <div class=\"divider\" *ngIf=\"showDividers && !lastItem\"></div>\r\n </ng-container>\r\n </div>\r\n \r\n <!-- Divider between groups -->\r\n <div class=\"divider group-divider\" *ngIf=\"!lastGroup\"></div>\r\n </ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </div>\r\n</div>", styles: [".list-container{display:flex;flex-direction:column;width:100%;font-family:Roboto,sans-serif;color:#000000de;background-color:#fff;border-radius:4px;box-shadow:0 1px 3px #0000001f,0 1px 2px #0000003d;overflow:hidden}.list-container.list-horizontal .list-items{display:flex;flex-wrap:wrap}.list-container.list-horizontal .list-items .list-item{width:auto;margin-right:16px;margin-bottom:16px;border-radius:4px;box-shadow:0 1px 3px #0000001f}.list-container.list-horizontal .list-items .divider{display:none}.list-header{display:flex;justify-content:space-between;align-items:center;padding:16px 16px 8px}.list-header .list-title{margin:0;font-size:20px;font-weight:500;color:#000000de}.list-header .header-actions{display:flex}.list-header .header-actions .header-action-button{background:none;border:none;cursor:pointer;padding:8px;margin-left:8px;border-radius:50%}.list-header .header-actions .header-action-button:hover{background-color:#0000000a}.list-header .header-actions .header-action-button:active{background-color:#00000014}.list-items{overflow:auto}.list-items.spacing-none .list-item{padding-left:16px;padding-right:16px}.list-items.spacing-none .list-item+.list-item{margin-top:0}.list-items.spacing-small .list-item{padding-left:16px;padding-right:16px}.list-items.spacing-small .list-item+.list-item{margin-top:4px}.list-items.spacing-medium .list-item{padding-left:16px;padding-right:16px}.list-items.spacing-medium .list-item+.list-item{margin-top:8px}.list-items.spacing-large .list-item{padding-left:16px;padding-right:16px}.list-items.spacing-large .list-item+.list-item{margin-top:16px}.list-item{display:flex;align-items:center;cursor:pointer;transition:background-color .2s;position:relative;-webkit-user-select:none;user-select:none;padding:8px 16px}.list-item.density-high{padding-top:4px;padding-bottom:4px;min-height:32px}.list-item.density-high .visual-support .avatar{width:28px;height:28px}.list-item.density-high .visual-support .image{width:40px;height:40px}.list-item.density-high .main-content .primary-text{font-size:14px}.list-item.density-high .main-content .secondary-text{font-size:12px;margin-top:1px}.list-item.density-high .main-content .subtitle,.list-item.density-high .complementary-support .meta{font-size:11px}.list-item.density-high .complementary-support .action-button{padding:4px}.list-item.density-medium{padding-top:8px;padding-bottom:8px;min-height:48px}.list-item.density-low{padding-top:16px;padding-bottom:16px;min-height:64px}.list-item.density-low .visual-support .avatar{width:48px;height:48px}.list-item.density-low .visual-support .image{width:64px;height:64px}.list-item.flex-height{height:auto;min-height:auto!important}.list-item.flex-height .main-content .primary-text,.list-item.flex-height .main-content .secondary-text{white-space:normal}.list-item:hover{background-color:#0000000a}.list-item:active{background-color:#00000014}.list-item.item-checked{background-color:#2196f314}.list-item.line-height-1{min-height:48px}.list-item.line-height-2{min-height:64px}.list-item.line-height-3{min-height:88px}.list-item.density-high.line-height-1,.list-item.density-high.line-height-2,.list-item.density-high.line-height-3{min-height:32px}.list-item.density-medium.line-height-1,.list-item.density-medium.line-height-2,.list-item.density-medium.line-height-3{min-height:48px}.list-item.density-low.line-height-1,.list-item.density-low.line-height-2,.list-item.density-low.line-height-3{min-height:64px}.visual-support{display:flex;align-items:center;margin-right:16px}.visual-support .drag-handle{cursor:grab}.visual-support .drag-handle:active{cursor:grabbing}.visual-support .avatar{width:40px;height:40px;border-radius:50%;object-fit:cover}.visual-support .image{width:56px;height:56px;object-fit:cover;border-radius:4px}.main-content{flex:1;min-width:0}.main-content .subtitle{font-size:12px;color:#0000008a;margin-bottom:4px}.main-content .primary-text{font-size:16px;font-weight:400;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.main-content .secondary-text{font-size:14px;color:#0000008a;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:4px}.complementary-support{display:flex;align-items:center;margin-left:16px}.complementary-support .meta{font-size:12px;color:#0000008a;margin-right:16px;white-space:nowrap}.complementary-support input[type=checkbox]{margin-right:8px;cursor:pointer}.complementary-support .action-button{background:none;border:none;cursor:pointer;display:flex;padding:8px}.complementary-support .action-button:hover{opacity:.7}.divider{height:1px;background-color:#0000001f;margin:0}.divider.group-divider{margin:8px 0;background-color:#0003}.list-group-label{display:flex;justify-content:space-between;align-items:center;padding:8px 16px;background-color:#00000005}.list-group-label .group-title{font-size:14px;font-weight:500;color:#0000008a;text-transform:uppercase}.list-group-label .expand-button{background:none;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:8px}.group-items .list-item.sub-item{padding-left:32px}.list-item.dragging{opacity:.5;background-color:#f0f0f0}@media screen and (max-width: 767px){.list-header{padding:12px 12px 6px}.list-header .list-title{font-size:18px}.list-item.density-high{padding-top:3px;padding-bottom:3px;min-height:28px}.list-item.density-medium{padding-top:6px;padding-bottom:6px;min-height:40px}.list-item.density-low{padding-top:12px;padding-bottom:12px;min-height:56px}.visual-support .avatar{width:32px;height:32px}.visual-support .image{width:48px;height:48px}.main-content .primary-text{font-size:14px}.main-content .secondary-text{font-size:12px}}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }, { kind: "component", type: i3.IconComponent, selector: "cfc-icon", inputs: ["iconName", "familyName", "className", "size", "color"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ListComponent, decorators: [{
type: Component,
args: [{ selector: 'cfc-list', template: "<div class=\"list-container\" [ngClass]=\"{'list-horizontal': layout === 'horizontal'}\">\r\n <!-- Header (Optional) -->\r\n <div class=\"list-header\" *ngIf=\"title\">\r\n <h2 class=\"list-title\">{{ title }}</h2>\r\n <div class=\"header-actions\" *ngIf=\"headerActions\">\r\n <button class=\"header-action-button search-button\">\r\n <cfc-icon [familyName]=\"'fas'\" [iconName]=\"'search'\" size=\"24px\"></cfc-icon>\r\n </button>\r\n <button class=\"header-action-button menu-button\">\r\n <cfc-icon [familyName]=\"'fas'\" [iconName]=\"'ellipsis-v'\" size=\"24px\"></cfc-icon>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- List Items Container -->\r\n <div class=\"list-items\" [ngClass]=\"'spacing-' + spacing\">\r\n <ng-container *ngIf=\"!grouped; else groupedContent\">\r\n <!-- Regular List Items -->\r\n <ng-container *ngFor=\"let item of items; let i = index; let last = last\">\r\n <div \r\n class=\"list-item\" \r\n [ngClass]=\"{\r\n 'line-height-1': lineHeight === '1',\r\n 'line-height-2': lineHeight === '2',\r\n 'line-height-3': lineHeight === '3',\r\n 'item-checked': !isGroup(item) && item.checked,\r\n 'density-high': density === 'high',\r\n 'density-medium': density === 'medium',\r\n 'density-low': density === 'low',\r\n 'flex-height': flexHeight\r\n }\"\r\n (click)=\"!isGroup(item) && onItemClick(item)\"\r\n [draggable]=\"draggable\"\r\n (dragstart)=\"onDragStart($event, i)\"\r\n (dragover)=\"onDragOver($event, i)\"\r\n (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onDrop($event, i)\"\r\n (dragend)=\"onDragEnd($event)\">\r\n \r\n <!-- Visual Support (Optional) -->\r\n <div class=\"visual-support\" *ngIf=\"!isGroup(item) && (item.icon || item.avatar || item.image || draggable)\">\r\n <cfc-icon \r\n *ngIf=\"draggable\"\r\n [familyName]=\"'fas'\" \r\n [iconName]=\"'grip-lines'\"\r\n size=\"16px\"\r\n color=\"rgba(0, 0, 0, 0.3)\"\r\n class=\"drag-handle\">\r\n </cfc-icon>\r\n <img *ngIf=\"!isGroup(item) && item.avatar\" class=\"avatar\" [src]=\"item.avatar\" alt=\"Avatar\">\r\n <img *ngIf=\"!isGroup(item) && item.image\" class=\"image\" [src]=\"item.image\" alt=\"Image\">\r\n <cfc-icon \r\n *ngIf=\"!isGroup(item) && item.icon\" \r\n [familyName]=\"item.iconFamily || 'fas'\" \r\n [iconName]=\"item.icon\"\r\n size=\"24px\"\r\n color=\"rgba(0, 0, 0, 0.54)\">\r\n </cfc-icon>\r\n </div>\r\n \r\n <!-- Main Content (Required) -->\r\n <div class=\"main-content\" *ngIf=\"!isGroup(item)\">\r\n <div class=\"subtitle\" *ngIf=\"item.subtitle\">{{ item.subtitle }}</div>\r\n <div class=\"primary-text\">{{ item.primaryText }}</div>\r\n <div class=\"secondary-text\" *ngIf=\"item.secondaryText\">{{ item.secondaryText }}</div>\r\n </div>\r\n \r\n <!-- Complementary Support (Optional) -->\r\n <div class=\"complementary-support\" *ngIf=\"!isGroup(item)\">\r\n <span class=\"meta\" *ngIf=\"item.meta\">{{ item.meta }}</span>\r\n \r\n <input \r\n *ngIf=\"item.hasOwnProperty('checked')\" \r\n type=\"checkbox\" \r\n [checked]=\"item.checked\" \r\n (change)=\"onCheckboxChange($event, item)\"\r\n (click)=\"$event.stopPropagation()\">\r\n \r\n <button \r\n *ngIf=\"item.hasAction\" \r\n class=\"action-button\" \r\n (click)=\"onActionClick($event, item)\">\r\n <cfc-icon \r\n [familyName]=\"item.actionIconFamily || 'fas'\" \r\n [iconName]=\"item.actionIcon || 'chevron-right'\"\r\n size=\"24px\"\r\n color=\"rgba(0, 0, 0, 0.54)\">\r\n </cfc-icon>\r\n </button>\r\n </div>\r\n </div>\r\n \r\n <!-- Divider (Optional) -->\r\n <div class=\"divider\" *ngIf=\"showDividers && !last\"></div>\r\n </ng-container>\r\n </ng-container>\r\n \r\n <!-- Grouped Content Template -->\r\n <ng-template #groupedContent>\r\n <ng-container *ngFor=\"let group of items; let groupIndex = index; let lastGroup = last\">\r\n <ng-container *ngIf=\"isGroup(group)\">\r\n <!-- Group Label -->\r\n <div class=\"list-group-label\" (click)=\"expandable && toggleGroup(group.id)\">\r\n <div class=\"group-title\">{{ group.title }}</div>\r\n <button *ngIf=\"expandable\" class=\"expand-button\">\r\n <cfc-icon \r\n [familyName]=\"'fas'\" \r\n [iconName]=\"isGroupExpanded(group.id) ? 'chevron-up' : 'chevron-down'\"\r\n size=\"24px\"\r\n color=\"rgba(0, 0, 0, 0.54)\">\r\n </cfc-icon>\r\n </button>\r\n </div>\r\n \r\n <!-- Group Items -->\r\n <div class=\"group-items\" *ngIf=\"isGroupExpanded(group.id)\">\r\n <ng-container *ngFor=\"let subItem of group.items; let i = index; let lastItem = last\">\r\n <div \r\n class=\"list-item sub-item\" \r\n [ngClass]=\"{\r\n 'line-height-1': lineHeight === '1',\r\n 'line-height-2': lineHeight === '2',\r\n 'line-height-3': lineHeight === '3',\r\n 'item-checked': subItem.checked,\r\n 'density-high': density === 'high',\r\n 'density-medium': density === 'medium',\r\n 'density-low': density === 'low',\r\n 'flex-height': flexHeight\r\n }\"\r\n (click)=\"onItemClick(subItem)\"\r\n [draggable]=\"draggable\"\r\n (dragstart)=\"onGroupItemDragStart($event, groupIndex, i)\"\r\n (dragover)=\"onDragOver($event, i)\"\r\n (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onGroupItemDrop($event, groupIndex, i)\"\r\n (dragend)=\"onDragEnd($event)\">\r\n \r\n <!-- Visual Support -->\r\n <div class=\"visual-support\" *ngIf=\"subItem.icon || subItem.avatar || subItem.image || draggable\">\r\n <cfc-icon \r\n *ngIf=\"draggable\"\r\n [familyName]=\"'fas'\" \r\n [iconName]=\"'grip-lines'\"\r\n size=\"16px\"\r\n color=\"rgba(0, 0, 0, 0.3)\"\r\n class=\"drag-handle\">\r\n </cfc-icon>\r\n <img *ngIf=\"subItem.avatar\" class=\"avatar\" [src]=\"subItem.avatar\" alt=\"Avatar\">\r\n <img *ngIf=\"subItem.image\" class=\"image\" [src]=\"subItem.image\" alt=\"Image\">\r\n <cfc-icon \r\n *ngIf=\"subItem.icon\" \r\n [familyName]=\"subItem.iconFamily || 'fas'\" \r\n [iconName]=\"subItem.icon\"\r\n size=\"24px\"\r\n color=\"rgba(0, 0, 0, 0.54)\">\r\n </cfc-icon>\r\n </div>\r\n \r\n <!-- Main Content -->\r\n <div class=\"main-content\">\r\n <div class=\"subtitle\" *ngIf=\"subItem.subtitle\">{{ subItem.subtitle }}</div>\r\n <div class=\"primary-text\">{{ subItem.primaryText }}</div>\r\n <div class=\"secondary-text\" *ngIf=\"subItem.secondaryText\">{{ subItem.secondaryText }}</div>\r\n </div>\r\n \r\n <!-- Complementary Support -->\r\n <div class=\"complementary-support\">\r\n <span class=\"meta\" *ngIf=\"subItem.meta\">{{ subItem.meta }}</span>\r\n \r\n <input \r\n *ngIf=\"subItem.hasOwnProperty('checked')\" \r\n type=\"checkbox\" \r\n [checked]=\"subItem.checked\" \r\n (change)=\"onCheckboxChange($event, subItem)\"\r\n (click)=\"$event.stopPropagation()\">\r\n \r\n <button \r\n *ngIf=\"subItem.hasAction\" \r\n class=\"action-button\" \r\n (click)=\"onActionClick($event, subItem)\">\r\n <cfc-icon \r\n [familyName]=\"subItem.actionIconFamily || 'fas'\" \r\n [iconName]=\"subItem.actionIcon || 'chevron-right'\"\r\n size=\"24px\"\r\n color=\"rgba(0, 0, 0, 0.54)\">\r\n </cfc-icon>\r\n </button>\r\n </div>\r\n </div>\r\n \r\n <!-- Divider within group -->\r\n <div class=\"divider\" *ngIf=\"showDividers && !lastItem\"></div>\r\n </ng-container>\r\n </div>\r\n \r\n <!-- Divider between groups -->\r\n <div class=\"divider group-divider\" *ngIf=\"!lastGroup\"></div>\r\n </ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </div>\r\n</div>", styles: [".list-container{display:flex;flex-direction:column;width:100%;font-family:Roboto,sans-serif;color:#000000de;background-color:#fff;border-radius:4px;box-shadow:0 1px 3px #0000001f,0 1px 2px #0000003d;overflow:hidden}.list-container.list-horizontal .list-items{display:flex;flex-wrap:wrap}.list-container.list-horizontal .list-items .list-item{width:auto;margin-right:16px;margin-bottom:16px;border-radius:4px;box-shadow:0 1px 3px #0000001f}.list-container.list-horizontal .list-items .divider{display:none}.list-header{display:flex;justify-content:space-between;align-items:center;padding:16px 16px 8px}.list-header .list-title{margin:0;font-size:20px;font-weight:500;color:#000000de}.list-header .header-actions{display:flex}.list-header .header-actions .header-action-button{background:none;border:none;cursor:pointer;padding:8px;margin-left:8px;border-radius:50%}.list-header .header-actions .header-action-button:hover{background-color:#0000000a}.list-header .header-actions .header-action-button:active{background-color:#00000014}.list-items{overflow:auto}.list-items.spacing-none .list-item{padding-left:16px;padding-right:16px}.list-items.spacing-none .list-item+.list-item{margin-top:0}.list-items.spacing-small .list-item{padding-left:16px;padding-right:16px}.list-items.spacing-small .list-item+.list-item{margin-top:4px}.list-items.spacing-medium .list-item{padding-left:16px;padding-right:16px}.list-items.spacing-medium .list-item+.list-item{margin-top:8px}.list-items.spacing-large .list-item{padding-left:16px;padding-right:16px}.list-items.spacing-large .list-item+.list-item{margin-top:16px}.list-item{display:flex;align-items:center;cursor:pointer;transition:background-color .2s;position:relative;-webkit-user-select:none;user-select:none;padding:8px 16px}.list-item.density-high{padding-top:4px;padding-bottom:4px;min-height:32px}.list-item.density-high .visual-support .avatar{width:28px;height:28px}.list-item.density-high .visual-support .image{width:40px;height:40px}.list-item.density-high .main-content .primary-text{font-size:14px}.list-item.density-high .main-content .secondary-text{font-size:12px;margin-top:1px}.list-item.density-high .main-content .subtitle,.list-item.density-high .complementary-support .meta{font-size:11px}.list-item.density-high .complementary-support .action-button{padding:4px}.list-item.density-medium{padding-top:8px;padding-bottom:8px;min-height:48px}.list-item.density-low{padding-top:16px;padding-bottom:16px;min-height:64px}.list-item.density-low .visual-support .avatar{width:48px;height:48px}.list-item.density-low .visual-support .image{width:64px;height:64px}.list-item.flex-height{height:auto;min-height:auto!important}.list-item.flex-height .main-content .primary-text,.list-item.flex-height .main-content .secondary-text{white-space:normal}.list-item:hover{background-color:#0000000a}.list-item:active{background-color:#00000014}.list-item.item-checked{background-color:#2196f314}.list-item.line-height-1{min-height:48px}.list-item.line-height-2{min-height:64px}.list-item.line-height-3{min-height:88px}.list-item.density-high.line-height-1,.list-item.density-high.line-height-2,.list-item.density-high.line-height-3{min-height:32px}.list-item.density-medium.line-height-1,.list-item.density-medium.line-height-2,.list-item.density-medium.line-height-3{min-height:48px}.list-item.density-low.line-height-1,.list-item.density-low.line-height-2,.list-item.density-low.line-height-3{min-height:64px}.visual-support{display:flex;align-items:center;margin-right:16px}.visual-support .drag-handle{cursor:grab}.visual-support .drag-handle:active{cursor:grabbing}.visual-support .avatar{width:40px;height:40px;border-radius:50%;object-fit:cover}.visual-support .image{width:56px;height:56px;object-fit:cover;border-radius:4px}.main-content{flex:1;min-width:0}.main-content .subtitle{font-size:12px;color:#0000008a;margin-bottom:4px}.main-content .primary-text{font-size:16px;font-weight:400;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.main-content .secondary-text{font-size:14px;color:#0000008a;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:4px}.complementary-support{display:flex;align-items:center;margin-left:16px}.complementary-support .meta{font-size:12px;color:#0000008a;margin-right:16px;white-space:nowrap}.complementary-support input[type=checkbox]{margin-right:8px;cursor:pointer}.complementary-support .action-button{background:none;border:none;cursor:pointer;display:flex;padding:8px}.complementary-support .action-button:hover{opacity:.7}.divider{height:1px;background-color:#0000001f;margin:0}.divider.group-divider{margin:8px 0;background-color:#0003}.list-group-label{display:flex;justify-content:space-between;align-items:center;padding:8px 16px;background-color:#00000005}.list-group-label .group-title{font-size:14px;font-weight:500;color:#0000008a;text-transform:uppercase}.list-group-label .expand-button{background:none;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:8px}.group-items .list-item.sub-item{padding-left:32px}.list-item.dragging{opacity:.5;background-color:#f0f0f0}@media screen and (max-width: 767px){.list-header{padding:12px 12px 6px}.list-header .list-title{font-size:18px}.list-item.density-high{padding-top:3px;padding-bottom:3px;min-height:28px}.list-item.density-medium{padding-top:6px;padding-bottom:6px;min-height:40px}.list-item.density-low{padding-top:12px;padding-bottom:12px;min-height:56px}.visual-support .avatar{width:32px;height:32px}.visual-support .image{width:48px;height:48px}.main-content .primary-text{font-size:14px}.main-content .secondary-text{font-size:12px}}\n"] }]
}], ctorParameters: () => [], propDecorators: { items: [{
type: Input
}], title: [{
type: Input
}], headerActions: [{
type: Input
}], layout: [{
type: Input
}], spacing: [{
type: Input
}], lineHeight: [{
type: Input
}], showDividers: [{
type: Input
}], grouped: [{
type: Input
}], expandable: [{
type: Input
}], draggable: [{
type: Input
}], density: [{
type: Input
}], flexHeight: [{
type: Input
}], itemClick: [{
type: Output
}], actionClick: [{
type: Output
}], checkboxChange: [{
type: Output
}], itemsReordered: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jZmMtZHMvc3JjL2xpYi9jb21wb25lbnRzL2xpc3QvbGlzdC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jZmMtZHMvc3JjL2xpYi9jb21wb25lbnRzL2xpc3QvbGlzdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFVLE1BQU0sZUFBZSxDQUFDOzs7OztBQU8vRSxNQUFNLE9BQU8sYUFBYTtJQUN4QiwwQkFBMEI7SUFDakIsS0FBSyxHQUFVLEVBQUUsQ0FBQztJQUNsQixLQUFLLEdBQVcsRUFBRSxDQUFDO0lBQ25CLGFBQWEsR0FBWSxLQUFLLENBQUM7SUFDL0IsTUFBTSxHQUE4QixVQUFVLENBQUM7SUFDL0MsT0FBTyxHQUEwQyxNQUFNLENBQUM7SUFDeEQsVUFBVSxHQUFvQixHQUFHLENBQUM7SUFDbEMsWUFBWSxHQUFZLElBQUksQ0FBQztJQUM3QixPQUFPLEdBQVksS0FBSyxDQUFDO0lBQ3pCLFVBQVUsR0FBWSxJQUFJLENBQUM7SUFDM0IsU0FBUyxHQUFZLEtBQUssQ0FBQztJQUVwQyxvQ0FBb0M7SUFDM0IsT0FBTyxHQUE4QixRQUFRLENBQUM7SUFDOUMsVUFBVSxHQUFZLEtBQUssQ0FBQztJQUVyQyxVQUFVO0lBQ0EsU0FBUyxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7SUFDcEMsV0FBVyxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7SUFDdEMsY0FBYyxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7SUFDekMsY0FBYyxHQUFHLElBQUksWUFBWSxFQUFTLENBQUM7SUFFckQsbUJBQW1CO0lBQ25CLGNBQWMsR0FBeUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNqRCxhQUFh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QVMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDL0MsQ0FBQztZQUVELCtCQUErQjtZQUMvQixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDNUMsQ0FBQztJQUNILENBQUM7SUFFRCxTQUFTLENBQUMsS0FBZ0I7UUFDeEIsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLE1BQXFCLENBQUM7UUFDNUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFckMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDMUIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDM0IsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQztJQUNqQyxDQUFDO3dHQTlMVSxhQUFhOzRGQUFiLGFBQWEsbWRDUDFCLG81U0F5TU07OzRGRGxNTyxhQUFhO2tCQUx6QixTQUFTOytCQUNFLFVBQVU7d0RBTVgsS0FBSztzQkFBYixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBR0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBR0ksU0FBUztzQkFBbEIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNO2dCQUNHLGNBQWM7c0JBQXZCLE1BQU07Z0JBQ0csY0FBYztzQkFBdkIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnY2ZjLWxpc3QnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9saXN0LmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9saXN0LmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIExpc3RDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG4gIC8vIFByb3ByaWVkYWRlcyBleGlzdGVudGVzXHJcbiAgQElucHV0KCkgaXRlbXM6IGFueVtdID0gW107XHJcbiAgQElucHV0KCkgdGl0bGU6IHN0cmluZyA9ICcnO1xyXG4gIEBJbnB1dCgpIGhlYWRlckFjdGlvbnM6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBsYXlvdXQ6ICd2ZXJ0aWNhbCcgfCAnaG9yaXpvbnRhbCcgPSAndmVydGljYWwnO1xyXG4gIEBJbnB1dCgpIHNwYWNpbmc6ICdub25lJyB8ICdzbWFsbCcgfCAnbWVkaXVtJyB8ICdsYXJnZScgPSAnbm9uZSc7XHJcbiAgQElucHV0KCkgbGluZUhlaWdodDogJzEnIHwgJzInIHwgJzMnID0gJzEnO1xyXG4gIEBJbnB1dCgpIHNob3dEaXZpZGVyczogYm9vbGVhbiA9IHRydWU7XHJcbiAgQElucHV0KCkgZ3JvdXBlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGV4cGFuZGFibGU6IGJvb2xlYW4gPSB0cnVlO1xyXG4gIEBJbnB1dCgpIGRyYWdnYWJsZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIFxyXG4gIC8vIE5vdmFzIHByb3ByaWVkYWRlcyBwYXJhIGRlbnNpZGFkZVxyXG4gIEBJbnB1dCgpIGRlbnNpdHk6ICdoaWdoJyB8ICdtZWRpdW0nIHwgJ2xvdycgPSAnbWVkaXVtJztcclxuICBASW5wdXQoKSBmbGV4SGVpZ2h0OiBib29sZWFuID0gZmFsc2U7XHJcbiAgXHJcbiAgLy8gRXZlbnRvc1xyXG4gIEBPdXRwdXQoKSBpdGVtQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICBAT3V0cHV0KCkgYWN0aW9uQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICBAT3V0cHV0KCkgY2hlY2tib3hDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICBAT3V0cHV0KCkgaXRlbXNSZW9yZGVyZWQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueVtdPigpO1xyXG4gIFxyXG4gIC8vIEVzdGFkb3MgaW50ZXJub3NcclxuICBleHBhbmRlZEdyb3VwczogU2V0PHN0cmluZyB8IG51bWJlcj4gPSBuZXcgU2V0KCk7XHJcbiAgZHJhZ0l0ZW1JbmRleDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XHJcbiAgZHJhZ0dyb3VwSW5kZXg6IG51bWJlciB8IG51bGwgPSBudWxsO1xyXG4gIGRyYWdHcm91cEl0ZW1JbmRleDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIGNvbnN0cnVjdG9yKCkgeyB9XHJcblxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgLy8gU2UgZXhwYW5kYWJsZSBmb3IgZmFsc28sIHRvZG9zIG9zIGdydXBvcyBjb21lw6dhbSBleHBhbmRpZG9zXHJcbiAgICBpZiAoIXRoaXMuZXhwYW5kYWJsZSAmJiB0aGlzLmdyb3VwZWQpIHtcclxuICAgICAgdGhpcy5pdGVtcy5mb3JFYWNoKGd