@praxisui/list 1.0.0-beta.40 → 1.0.0-beta.42

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.
@@ -436,10 +436,10 @@ class ListDataService {
436
436
  data,
437
437
  };
438
438
  }
439
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ListDataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
440
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ListDataService });
439
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ListDataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
440
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ListDataService });
441
441
  }
442
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ListDataService, decorators: [{
442
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ListDataService, decorators: [{
443
443
  type: Injectable
444
444
  }] });
445
445
  function stableSerialize(value) {
@@ -519,10 +519,10 @@ class ListSkinService {
519
519
  return `${base}\n${extra}`;
520
520
  return base || extra;
521
521
  }
522
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ListSkinService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
523
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ListSkinService, providedIn: 'root' });
522
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ListSkinService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
523
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ListSkinService, providedIn: 'root' });
524
524
  }
525
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ListSkinService, decorators: [{
525
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ListSkinService, decorators: [{
526
526
  type: Injectable,
527
527
  args: [{ providedIn: 'root' }]
528
528
  }] });
@@ -956,10 +956,10 @@ class PraxisListSkinPreviewComponent {
956
956
  }
957
957
  // trackBy for preview lists
958
958
  trackByIndex = (i) => i;
959
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisListSkinPreviewComponent, deps: [{ token: ListSkinService }], target: i0.ɵɵFactoryTarget.Component });
960
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: PraxisListSkinPreviewComponent, isStandalone: true, selector: "praxis-list-skin-preview", inputs: { config: "config", items: "items", theme: "theme" }, ngImport: i0, template: "<div class=\"preview-root\" [ngClass]=\"skinClasses\" [attr.data-skin-scope]=\"skinScopeId\">\n @if (inlineCss) { <style [attr.nonce]=\"cspNonce || null\" [textContent]=\"inlineCss\"></style> }\n\n @if (isList()) {\n <mat-list>\n @for (item of items; track trackByIndex($index)) {\n <mat-list-item>\n <div class=\"list-item-content\">\n @if (leading(item); as lead) {\n @switch (lead.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\" [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon> }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n @if (lead.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(lead.badge?.color) ? lead.badge?.color : undefined\"\n [ngClass]=\"(((lead.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(lead.badge?.color, lead.badge?.variant)\">{{ lead.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('text') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, lead.value)\" [color]=\"ratingThemeColor(lead)\" [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> } }\n @case ('html') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\" [innerHTML]=\"lead.value\"></span> }\n @default { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n }\n }\n <div>\n <div class=\"primary\" [ngClass]=\"primary(item)?.class\" [style.cssText]=\"primary(item)?.style\">{{ primary(item)?.value }}</div>\n @if ((config.layout?.lines || 1) > 1) { <div class=\"secondary\" [ngClass]=\"secondary(item)?.class\" [style.cssText]=\"secondary(item)?.style\">{{ secondary(item)?.value }}</div> }\n @if (featuresVisible()) {\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{ featureLabel(item, f.expr) }}</span> }\n </span>\n }\n }\n </div>\n @if (meta(item); as m) {\n <div class=\"meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (metaPrefixIcon(); as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\" [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, m.value)\" [color]=\"ratingThemeColor(m)\" [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>{{ m.value }}</span> }\n }\n </div>\n }\n @if (trailing(item); as tr) {\n <div class=\"trailing\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n @switch (tr.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip> }\n @case ('icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"tr.value\" [alt]=\"tr.imageAlt || ''\" /></span> }\n @case ('rating') { @for (_ of ratingRange(tr); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, tr.value)\" [color]=\"ratingThemeColor(tr)\" [style.cssText]=\"ratingIconStyle(tr)\"></mat-icon> } }\n @case ('html') { <span [innerHTML]=\"tr.value\"></span> }\n @default { <span>{{ tr.value }}</span> }\n }\n </div>\n }\n </div>\n </mat-list-item>\n }\n </mat-list>\n } @else if (isTiles()) {\n <div class=\"tiles-grid\">\n @for (it of items; track trackByIndex($index)) {\n <div class=\"item-tile\">\n <div class=\"tile-media\">\n @if (leading(it); as lead) {\n @switch (lead.type) {\n @case ('image') {\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n }\n @case ('icon') { <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\" [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon> }\n @case ('text') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, lead.value)\" [color]=\"ratingThemeColor(lead)\" [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> } }\n @case ('html') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\" [innerHTML]=\"lead.value\"></span> }\n @default { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n }\n }\n </div>\n @if (trailing(it); as tr) {\n @if (statusPosition() === 'top-right' && (tr?.type === 'chip' || tr?.type === 'icon')) {\n <div class=\"tile-status\">\n @if (tr?.type === 'chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip> }\n @if (tr?.type === 'icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n </div>\n }\n }\n <div class=\"tile-body\">\n <div class=\"primary\" [ngClass]=\"primary(it)?.class\" [style.cssText]=\"primary(it)?.style\">{{ primary(it)?.value }}</div>\n @if ((config.layout?.lines || 1) > 1) { <div class=\"secondary\" [ngClass]=\"secondary(it)?.class\" [style.cssText]=\"secondary(it)?.style\">{{ secondary(it)?.value }}</div> }\n @if (meta(it); as m) {\n <div class=\"meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (metaPrefixIcon(); as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\" [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, m.value)\" [color]=\"ratingThemeColor(m)\" [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>{{ m.value }}</span> }\n }\n </div>\n }\n @if (featuresVisible()) {\n <div class=\"features\">\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{ featureLabel(it, f.expr) }}</span> }\n </span>\n }\n </div>\n }\n @if (trailing(it); as tr2) {\n @if (!(statusPosition() === 'top-right' && (tr2?.type === 'chip' || tr2?.type === 'icon'))) {\n <div class=\"meta\" [ngClass]=\"tr2.class\" [style.cssText]=\"tr2.style\">\n @switch (tr2.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr2.color) ? tr2.color : undefined\" [ngClass]=\"((tr2.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr2.color, tr2.variant)\">{{ tr2.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(tr2); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, tr2.value)\" [color]=\"ratingThemeColor(tr2)\" [style.cssText]=\"ratingIconStyle(tr2)\"></mat-icon> } }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"tr2.value\" [alt]=\"tr2.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"tr2.value\"></span> }\n @default { <span>{{ tr2.value }}</span> }\n }\n </div>\n }\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"cards-grid\">\n @for (it of items; track trackByIndex($index)) {\n <div class=\"item-card\">\n <div class=\"list-item-content\">\n @if (leading(it); as lead) {\n @switch (lead.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\" [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon> }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n @if (lead.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(lead.badge?.color) ? lead.badge?.color : undefined\"\n [ngClass]=\"(((lead.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(lead.badge?.color, lead.badge?.variant)\">{{ lead.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('text') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, lead.value)\" [color]=\"ratingThemeColor(lead)\" [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> } }\n @case ('html') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\" [innerHTML]=\"lead.value\"></span> }\n @default { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n }\n }\n <div>\n <div class=\"primary\" [ngClass]=\"primary(it)?.class\" [style.cssText]=\"primary(it)?.style\">{{ primary(it)?.value }}</div>\n @if ((config.layout?.lines || 1) > 1) { <div class=\"secondary\" [ngClass]=\"secondary(it)?.class\" [style.cssText]=\"secondary(it)?.style\">{{ secondary(it)?.value }}</div> }\n @if (featuresVisible()) {\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{ featureLabel(it, f.expr) }}</span> }\n </span>\n }\n }\n </div>\n @if (meta(it); as m) {\n <div class=\"meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (metaPrefixIcon(); as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\" [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, m.value)\" [color]=\"ratingThemeColor(m)\" [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>{{ m.value }}</span> }\n }\n </div>\n }\n @if (trailing(it); as tr) {\n <div class=\"trailing\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n @switch (tr.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip> }\n @case ('icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"tr.value\" [alt]=\"tr.imageAlt || ''\" /></span> }\n @case ('rating') { @for (_ of ratingRange(tr); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, tr.value)\" [color]=\"ratingThemeColor(tr)\" [style.cssText]=\"ratingIconStyle(tr)\"></mat-icon> } }\n @case ('html') { <span [innerHTML]=\"tr.value\"></span> }\n @default { <span>{{ tr.value }}</span> }\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".preview-root{--p-list-radius: var(--md-sys-shape-corner-medium, 16px);--p-list-shadow: var(--md-sys-elevation-level2);--p-list-border: 1px solid var(--md-sys-color-outline-variant);--p-list-blur: 10px;--p-list-foreground: var(--md-sys-color-on-surface);--p-list-foreground-muted: var(--md-sys-color-on-surface-variant);--p-list-grad-foreground: var(--md-sys-color-on-primary);--p-list-grad-foreground-muted: var(--md-sys-color-on-primary);--p-list-surface: var(--md-sys-color-surface-container);--p-list-accent: var(--md-sys-color-primary);--p-list-item-border: 1px solid var(--md-sys-color-outline-variant);--p-list-grad-from: var(--md-sys-color-primary-container);--p-list-grad-to: var(--md-sys-color-tertiary-container);--p-list-grad-angle: 135deg;--p-list-tile-minW: 240px;--p-list-tile-gap: 16px;--p-list-tile-padding: 16px;--p-list-tile-radius: 16px;--p-list-tile-media-radius: 12px;--p-list-tile-media-ratio: 1 / 1;padding:12px}.preview-light{background:var(--md-sys-color-surface-container-low, var(--md-sys-color-surface))}.preview-dark{background:var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface))}.preview-grid{background-color:var(--md-sys-color-surface-variant, var(--md-sys-color-surface));background-image:linear-gradient(var(--md-sys-color-outline-variant, var(--md-sys-color-outline)) 1px,transparent 1px),linear-gradient(90deg,var(--md-sys-color-outline-variant, var(--md-sys-color-outline)) 1px,transparent 1px);background-size:16px 16px}.skin-elevated,.skin-outline,.skin-flat,.skin-neumorphism{--p-list-item-surface: var(--mdc-elevated-card-container-color, var(--p-list-surface));--p-list-item-border: var(--p-list-border)}.skin-elevated .item-card,.skin-outline .item-card,.skin-flat .item-card,.skin-neumorphism .item-card{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:var(--p-list-radius);box-shadow:var(--p-list-shadow);border:var(--p-list-border)}.skin-elevated .item-tile,.skin-outline .item-tile,.skin-flat .item-tile,.skin-neumorphism .item-tile{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));box-shadow:var(--p-list-shadow);border:var(--p-list-border)}.skin-elevated .mat-mdc-list-item .list-item-content,.skin-outline .mat-mdc-list-item .list-item-content,.skin-flat .mat-mdc-list-item .list-item-content,.skin-neumorphism .mat-mdc-list-item .list-item-content{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:calc(var(--p-list-radius) * .75);box-shadow:var(--p-list-shadow);border:var(--p-list-item-border);color:var(--p-list-foreground)}.skin-outline{--p-list-shadow: none;--p-list-border: 1px solid var(--md-sys-color-outline)}.skin-flat{--p-list-shadow: none;--p-list-border: 1px solid var(--md-sys-color-outline-variant)}.skin-neumorphism{--p-list-shadow: var(--md-sys-elevation-level2);--p-list-border: 1px solid var(--md-sys-color-outline-variant);--p-list-radius: 1.25rem}.skin-pill-soft .item-card,.skin-pill-soft .item-tile{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:calc(var(--p-list-radius) * 1.3);box-shadow:var(--md-sys-elevation-level1);border:var(--p-list-border)}.skin-pill-soft .mat-mdc-list-item .list-item-content{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:calc(var(--p-list-radius) * 1.3);box-shadow:var(--md-sys-elevation-level1);border:var(--p-list-border);color:var(--p-list-foreground)}.lead-image{position:relative;width:96px;height:72px;border-radius:12px;overflow:hidden}.lead-image img{width:100%;height:100%;object-fit:cover;display:block}.lead-image .lead-badge{position:absolute;left:8px;bottom:8px}.features{display:flex;flex-wrap:wrap;gap:12px;margin-top:6px;color:var(--p-list-foreground-muted)}.feature{display:inline-flex;align-items:center;gap:6px}.model-media .lead-image{width:136px;height:96px;border-radius:16px}.model-hotel .lead-image{width:160px;height:110px;border-radius:18px}.skin-gradient-tile{--p-list-foreground: var(--p-list-grad-foreground);--p-list-foreground-muted: var(--p-list-grad-foreground-muted)}.skin-gradient-tile .item-card,.skin-gradient-tile .item-tile,.skin-gradient-tile .mat-mdc-list-item .list-item-content{background:linear-gradient(var(--p-list-grad-angle),var(--p-list-grad-from),var(--p-list-grad-to));border-radius:var(--p-list-radius);color:var(--p-list-foreground)}.skin-glass .item-card,.skin-glass .item-tile{background:var(--md-sys-color-surface-container-low);border-radius:var(--p-list-radius);border:1px solid var(--md-sys-color-outline-variant);backdrop-filter:blur(var(--p-list-blur));-webkit-backdrop-filter:blur(var(--p-list-blur))}.skin-glass .mat-mdc-list-item .list-item-content{background:var(--md-sys-color-surface-container-low);border-radius:var(--p-list-radius);border:1px solid var(--md-sys-color-outline-variant);backdrop-filter:blur(var(--p-list-blur));-webkit-backdrop-filter:blur(var(--p-list-blur));color:var(--p-list-foreground)}.list-item-content{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;align-items:center;gap:12px;padding:12px 16px}.primary{font-weight:500;color:var(--p-list-foreground)}.secondary,.meta{color:var(--p-list-foreground-muted)}.trailing{color:var(--p-list-foreground-muted);text-align:end}.cards-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--p-list-tile-minW),1fr));gap:var(--p-list-tile-gap)}.item-card{padding:12px}.tiles-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--p-list-tile-minW),1fr));gap:var(--p-list-tile-gap)}.item-tile{padding:var(--p-list-tile-padding);border-radius:var(--p-list-tile-radius);border:var(--p-list-border);background:var(--p-list-surface);display:grid;gap:8px}.tile-media{width:100%;aspect-ratio:var(--p-list-tile-media-ratio);border-radius:var(--p-list-tile-media-radius);background:var(--md-sys-color-surface-container-low, var(--p-list-surface));display:grid;place-items:center;overflow:hidden}.tile-media img{width:100%;height:100%;object-fit:cover}.tile-body{display:grid;gap:4px}.chip-outlined.mat-mdc-chip{background:transparent!important;border:1px solid currentColor}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i3.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i3.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i5.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
959
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisListSkinPreviewComponent, deps: [{ token: ListSkinService }], target: i0.ɵɵFactoryTarget.Component });
960
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: PraxisListSkinPreviewComponent, isStandalone: true, selector: "praxis-list-skin-preview", inputs: { config: "config", items: "items", theme: "theme" }, ngImport: i0, template: "<div class=\"preview-root\" [ngClass]=\"skinClasses\" [attr.data-skin-scope]=\"skinScopeId\">\n @if (inlineCss) { <style [attr.nonce]=\"cspNonce || null\" [textContent]=\"inlineCss\"></style> }\n\n @if (isList()) {\n <mat-list>\n @for (item of items; track trackByIndex($index)) {\n <mat-list-item>\n <div class=\"list-item-content\">\n @if (leading(item); as lead) {\n @switch (lead.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\" [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon> }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n @if (lead.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(lead.badge?.color) ? lead.badge?.color : undefined\"\n [ngClass]=\"(((lead.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(lead.badge?.color, lead.badge?.variant)\">{{ lead.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('text') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, lead.value)\" [color]=\"ratingThemeColor(lead)\" [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> } }\n @case ('html') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\" [innerHTML]=\"lead.value\"></span> }\n @default { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n }\n }\n <div>\n <div class=\"primary\" [ngClass]=\"primary(item)?.class\" [style.cssText]=\"primary(item)?.style\">{{ primary(item)?.value }}</div>\n @if ((config.layout?.lines || 1) > 1) { <div class=\"secondary\" [ngClass]=\"secondary(item)?.class\" [style.cssText]=\"secondary(item)?.style\">{{ secondary(item)?.value }}</div> }\n @if (featuresVisible()) {\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{ featureLabel(item, f.expr) }}</span> }\n </span>\n }\n }\n </div>\n @if (meta(item); as m) {\n <div class=\"meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (metaPrefixIcon(); as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\" [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, m.value)\" [color]=\"ratingThemeColor(m)\" [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>{{ m.value }}</span> }\n }\n </div>\n }\n @if (trailing(item); as tr) {\n <div class=\"trailing\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n @switch (tr.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip> }\n @case ('icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"tr.value\" [alt]=\"tr.imageAlt || ''\" /></span> }\n @case ('rating') { @for (_ of ratingRange(tr); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, tr.value)\" [color]=\"ratingThemeColor(tr)\" [style.cssText]=\"ratingIconStyle(tr)\"></mat-icon> } }\n @case ('html') { <span [innerHTML]=\"tr.value\"></span> }\n @default { <span>{{ tr.value }}</span> }\n }\n </div>\n }\n </div>\n </mat-list-item>\n }\n </mat-list>\n } @else if (isTiles()) {\n <div class=\"tiles-grid\">\n @for (it of items; track trackByIndex($index)) {\n <div class=\"item-tile\">\n <div class=\"tile-media\">\n @if (leading(it); as lead) {\n @switch (lead.type) {\n @case ('image') {\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n }\n @case ('icon') { <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\" [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon> }\n @case ('text') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, lead.value)\" [color]=\"ratingThemeColor(lead)\" [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> } }\n @case ('html') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\" [innerHTML]=\"lead.value\"></span> }\n @default { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n }\n }\n </div>\n @if (trailing(it); as tr) {\n @if (statusPosition() === 'top-right' && (tr?.type === 'chip' || tr?.type === 'icon')) {\n <div class=\"tile-status\">\n @if (tr?.type === 'chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip> }\n @if (tr?.type === 'icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n </div>\n }\n }\n <div class=\"tile-body\">\n <div class=\"primary\" [ngClass]=\"primary(it)?.class\" [style.cssText]=\"primary(it)?.style\">{{ primary(it)?.value }}</div>\n @if ((config.layout?.lines || 1) > 1) { <div class=\"secondary\" [ngClass]=\"secondary(it)?.class\" [style.cssText]=\"secondary(it)?.style\">{{ secondary(it)?.value }}</div> }\n @if (meta(it); as m) {\n <div class=\"meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (metaPrefixIcon(); as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\" [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, m.value)\" [color]=\"ratingThemeColor(m)\" [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>{{ m.value }}</span> }\n }\n </div>\n }\n @if (featuresVisible()) {\n <div class=\"features\">\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{ featureLabel(it, f.expr) }}</span> }\n </span>\n }\n </div>\n }\n @if (trailing(it); as tr2) {\n @if (!(statusPosition() === 'top-right' && (tr2?.type === 'chip' || tr2?.type === 'icon'))) {\n <div class=\"meta\" [ngClass]=\"tr2.class\" [style.cssText]=\"tr2.style\">\n @switch (tr2.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr2.color) ? tr2.color : undefined\" [ngClass]=\"((tr2.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr2.color, tr2.variant)\">{{ tr2.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(tr2); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, tr2.value)\" [color]=\"ratingThemeColor(tr2)\" [style.cssText]=\"ratingIconStyle(tr2)\"></mat-icon> } }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"tr2.value\" [alt]=\"tr2.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"tr2.value\"></span> }\n @default { <span>{{ tr2.value }}</span> }\n }\n </div>\n }\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"cards-grid\">\n @for (it of items; track trackByIndex($index)) {\n <div class=\"item-card\">\n <div class=\"list-item-content\">\n @if (leading(it); as lead) {\n @switch (lead.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\" [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon> }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n @if (lead.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(lead.badge?.color) ? lead.badge?.color : undefined\"\n [ngClass]=\"(((lead.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(lead.badge?.color, lead.badge?.variant)\">{{ lead.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('text') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, lead.value)\" [color]=\"ratingThemeColor(lead)\" [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> } }\n @case ('html') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\" [innerHTML]=\"lead.value\"></span> }\n @default { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n }\n }\n <div>\n <div class=\"primary\" [ngClass]=\"primary(it)?.class\" [style.cssText]=\"primary(it)?.style\">{{ primary(it)?.value }}</div>\n @if ((config.layout?.lines || 1) > 1) { <div class=\"secondary\" [ngClass]=\"secondary(it)?.class\" [style.cssText]=\"secondary(it)?.style\">{{ secondary(it)?.value }}</div> }\n @if (featuresVisible()) {\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{ featureLabel(it, f.expr) }}</span> }\n </span>\n }\n }\n </div>\n @if (meta(it); as m) {\n <div class=\"meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (metaPrefixIcon(); as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\" [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, m.value)\" [color]=\"ratingThemeColor(m)\" [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>{{ m.value }}</span> }\n }\n </div>\n }\n @if (trailing(it); as tr) {\n <div class=\"trailing\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n @switch (tr.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip> }\n @case ('icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"tr.value\" [alt]=\"tr.imageAlt || ''\" /></span> }\n @case ('rating') { @for (_ of ratingRange(tr); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, tr.value)\" [color]=\"ratingThemeColor(tr)\" [style.cssText]=\"ratingIconStyle(tr)\"></mat-icon> } }\n @case ('html') { <span [innerHTML]=\"tr.value\"></span> }\n @default { <span>{{ tr.value }}</span> }\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".preview-root{--p-list-radius: var(--md-sys-shape-corner-medium, 16px);--p-list-shadow: var(--md-sys-elevation-level2);--p-list-border: 1px solid var(--md-sys-color-outline-variant);--p-list-blur: 10px;--p-list-foreground: var(--md-sys-color-on-surface);--p-list-foreground-muted: var(--md-sys-color-on-surface-variant);--p-list-grad-foreground: var(--md-sys-color-on-primary);--p-list-grad-foreground-muted: var(--md-sys-color-on-primary);--p-list-surface: var(--md-sys-color-surface-container);--p-list-accent: var(--md-sys-color-primary);--p-list-item-border: 1px solid var(--md-sys-color-outline-variant);--p-list-grad-from: var(--md-sys-color-primary-container);--p-list-grad-to: var(--md-sys-color-tertiary-container);--p-list-grad-angle: 135deg;--p-list-tile-minW: 240px;--p-list-tile-gap: 16px;--p-list-tile-padding: 16px;--p-list-tile-radius: 16px;--p-list-tile-media-radius: 12px;--p-list-tile-media-ratio: 1 / 1;padding:12px}.preview-light{background:var(--md-sys-color-surface-container-low, var(--md-sys-color-surface))}.preview-dark{background:var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface))}.preview-grid{background-color:var(--md-sys-color-surface-variant, var(--md-sys-color-surface));background-image:linear-gradient(var(--md-sys-color-outline-variant, var(--md-sys-color-outline)) 1px,transparent 1px),linear-gradient(90deg,var(--md-sys-color-outline-variant, var(--md-sys-color-outline)) 1px,transparent 1px);background-size:16px 16px}.skin-elevated,.skin-outline,.skin-flat,.skin-neumorphism{--p-list-item-surface: var(--mdc-elevated-card-container-color, var(--p-list-surface));--p-list-item-border: var(--p-list-border)}.skin-elevated .item-card,.skin-outline .item-card,.skin-flat .item-card,.skin-neumorphism .item-card{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:var(--p-list-radius);box-shadow:var(--p-list-shadow);border:var(--p-list-border)}.skin-elevated .item-tile,.skin-outline .item-tile,.skin-flat .item-tile,.skin-neumorphism .item-tile{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));box-shadow:var(--p-list-shadow);border:var(--p-list-border)}.skin-elevated .mat-mdc-list-item .list-item-content,.skin-outline .mat-mdc-list-item .list-item-content,.skin-flat .mat-mdc-list-item .list-item-content,.skin-neumorphism .mat-mdc-list-item .list-item-content{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:calc(var(--p-list-radius) * .75);box-shadow:var(--p-list-shadow);border:var(--p-list-item-border);color:var(--p-list-foreground)}.skin-outline{--p-list-shadow: none;--p-list-border: 1px solid var(--md-sys-color-outline)}.skin-flat{--p-list-shadow: none;--p-list-border: 1px solid var(--md-sys-color-outline-variant)}.skin-neumorphism{--p-list-shadow: var(--md-sys-elevation-level2);--p-list-border: 1px solid var(--md-sys-color-outline-variant);--p-list-radius: 1.25rem}.skin-pill-soft .item-card,.skin-pill-soft .item-tile{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:calc(var(--p-list-radius) * 1.3);box-shadow:var(--md-sys-elevation-level1);border:var(--p-list-border)}.skin-pill-soft .mat-mdc-list-item .list-item-content{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:calc(var(--p-list-radius) * 1.3);box-shadow:var(--md-sys-elevation-level1);border:var(--p-list-border);color:var(--p-list-foreground)}.lead-image{position:relative;width:96px;height:72px;border-radius:12px;overflow:hidden}.lead-image img{width:100%;height:100%;object-fit:cover;display:block}.lead-image .lead-badge{position:absolute;left:8px;bottom:8px}.features{display:flex;flex-wrap:wrap;gap:12px;margin-top:6px;color:var(--p-list-foreground-muted)}.feature{display:inline-flex;align-items:center;gap:6px}.model-media .lead-image{width:136px;height:96px;border-radius:16px}.model-hotel .lead-image{width:160px;height:110px;border-radius:18px}.skin-gradient-tile{--p-list-foreground: var(--p-list-grad-foreground);--p-list-foreground-muted: var(--p-list-grad-foreground-muted)}.skin-gradient-tile .item-card,.skin-gradient-tile .item-tile,.skin-gradient-tile .mat-mdc-list-item .list-item-content{background:linear-gradient(var(--p-list-grad-angle),var(--p-list-grad-from),var(--p-list-grad-to));border-radius:var(--p-list-radius);color:var(--p-list-foreground)}.skin-glass .item-card,.skin-glass .item-tile{background:var(--md-sys-color-surface-container-low);border-radius:var(--p-list-radius);border:1px solid var(--md-sys-color-outline-variant);backdrop-filter:blur(var(--p-list-blur));-webkit-backdrop-filter:blur(var(--p-list-blur))}.skin-glass .mat-mdc-list-item .list-item-content{background:var(--md-sys-color-surface-container-low);border-radius:var(--p-list-radius);border:1px solid var(--md-sys-color-outline-variant);backdrop-filter:blur(var(--p-list-blur));-webkit-backdrop-filter:blur(var(--p-list-blur));color:var(--p-list-foreground)}.list-item-content{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;align-items:center;gap:12px;padding:12px 16px}.primary{font-weight:500;color:var(--p-list-foreground)}.secondary,.meta{color:var(--p-list-foreground-muted)}.trailing{color:var(--p-list-foreground-muted);text-align:end}.cards-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--p-list-tile-minW),1fr));gap:var(--p-list-tile-gap)}.item-card{padding:12px}.tiles-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--p-list-tile-minW),1fr));gap:var(--p-list-tile-gap)}.item-tile{padding:var(--p-list-tile-padding);border-radius:var(--p-list-tile-radius);border:var(--p-list-border);background:var(--p-list-surface);display:grid;gap:8px}.tile-media{width:100%;aspect-ratio:var(--p-list-tile-media-ratio);border-radius:var(--p-list-tile-media-radius);background:var(--md-sys-color-surface-container-low, var(--p-list-surface));display:grid;place-items:center;overflow:hidden}.tile-media img{width:100%;height:100%;object-fit:cover}.tile-body{display:grid;gap:4px}.chip-outlined.mat-mdc-chip{background:transparent!important;border:1px solid currentColor}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i3.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i3.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i5.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
961
961
  }
962
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisListSkinPreviewComponent, decorators: [{
962
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisListSkinPreviewComponent, decorators: [{
963
963
  type: Component,
964
964
  args: [{ selector: 'praxis-list-skin-preview', standalone: true, imports: [CommonModule, MatListModule, MatIconModule, MatChipsModule, PraxisIconDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"preview-root\" [ngClass]=\"skinClasses\" [attr.data-skin-scope]=\"skinScopeId\">\n @if (inlineCss) { <style [attr.nonce]=\"cspNonce || null\" [textContent]=\"inlineCss\"></style> }\n\n @if (isList()) {\n <mat-list>\n @for (item of items; track trackByIndex($index)) {\n <mat-list-item>\n <div class=\"list-item-content\">\n @if (leading(item); as lead) {\n @switch (lead.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\" [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon> }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n @if (lead.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(lead.badge?.color) ? lead.badge?.color : undefined\"\n [ngClass]=\"(((lead.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(lead.badge?.color, lead.badge?.variant)\">{{ lead.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('text') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, lead.value)\" [color]=\"ratingThemeColor(lead)\" [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> } }\n @case ('html') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\" [innerHTML]=\"lead.value\"></span> }\n @default { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n }\n }\n <div>\n <div class=\"primary\" [ngClass]=\"primary(item)?.class\" [style.cssText]=\"primary(item)?.style\">{{ primary(item)?.value }}</div>\n @if ((config.layout?.lines || 1) > 1) { <div class=\"secondary\" [ngClass]=\"secondary(item)?.class\" [style.cssText]=\"secondary(item)?.style\">{{ secondary(item)?.value }}</div> }\n @if (featuresVisible()) {\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{ featureLabel(item, f.expr) }}</span> }\n </span>\n }\n }\n </div>\n @if (meta(item); as m) {\n <div class=\"meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (metaPrefixIcon(); as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\" [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, m.value)\" [color]=\"ratingThemeColor(m)\" [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>{{ m.value }}</span> }\n }\n </div>\n }\n @if (trailing(item); as tr) {\n <div class=\"trailing\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n @switch (tr.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip> }\n @case ('icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"tr.value\" [alt]=\"tr.imageAlt || ''\" /></span> }\n @case ('rating') { @for (_ of ratingRange(tr); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, tr.value)\" [color]=\"ratingThemeColor(tr)\" [style.cssText]=\"ratingIconStyle(tr)\"></mat-icon> } }\n @case ('html') { <span [innerHTML]=\"tr.value\"></span> }\n @default { <span>{{ tr.value }}</span> }\n }\n </div>\n }\n </div>\n </mat-list-item>\n }\n </mat-list>\n } @else if (isTiles()) {\n <div class=\"tiles-grid\">\n @for (it of items; track trackByIndex($index)) {\n <div class=\"item-tile\">\n <div class=\"tile-media\">\n @if (leading(it); as lead) {\n @switch (lead.type) {\n @case ('image') {\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n }\n @case ('icon') { <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\" [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon> }\n @case ('text') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, lead.value)\" [color]=\"ratingThemeColor(lead)\" [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> } }\n @case ('html') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\" [innerHTML]=\"lead.value\"></span> }\n @default { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n }\n }\n </div>\n @if (trailing(it); as tr) {\n @if (statusPosition() === 'top-right' && (tr?.type === 'chip' || tr?.type === 'icon')) {\n <div class=\"tile-status\">\n @if (tr?.type === 'chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip> }\n @if (tr?.type === 'icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n </div>\n }\n }\n <div class=\"tile-body\">\n <div class=\"primary\" [ngClass]=\"primary(it)?.class\" [style.cssText]=\"primary(it)?.style\">{{ primary(it)?.value }}</div>\n @if ((config.layout?.lines || 1) > 1) { <div class=\"secondary\" [ngClass]=\"secondary(it)?.class\" [style.cssText]=\"secondary(it)?.style\">{{ secondary(it)?.value }}</div> }\n @if (meta(it); as m) {\n <div class=\"meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (metaPrefixIcon(); as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\" [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, m.value)\" [color]=\"ratingThemeColor(m)\" [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>{{ m.value }}</span> }\n }\n </div>\n }\n @if (featuresVisible()) {\n <div class=\"features\">\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{ featureLabel(it, f.expr) }}</span> }\n </span>\n }\n </div>\n }\n @if (trailing(it); as tr2) {\n @if (!(statusPosition() === 'top-right' && (tr2?.type === 'chip' || tr2?.type === 'icon'))) {\n <div class=\"meta\" [ngClass]=\"tr2.class\" [style.cssText]=\"tr2.style\">\n @switch (tr2.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr2.color) ? tr2.color : undefined\" [ngClass]=\"((tr2.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr2.color, tr2.variant)\">{{ tr2.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(tr2); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, tr2.value)\" [color]=\"ratingThemeColor(tr2)\" [style.cssText]=\"ratingIconStyle(tr2)\"></mat-icon> } }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"tr2.value\" [alt]=\"tr2.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"tr2.value\"></span> }\n @default { <span>{{ tr2.value }}</span> }\n }\n </div>\n }\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"cards-grid\">\n @for (it of items; track trackByIndex($index)) {\n <div class=\"item-card\">\n <div class=\"list-item-content\">\n @if (leading(it); as lead) {\n @switch (lead.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\" [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon> }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n @if (lead.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(lead.badge?.color) ? lead.badge?.color : undefined\"\n [ngClass]=\"(((lead.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(lead.badge?.color, lead.badge?.variant)\">{{ lead.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('text') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, lead.value)\" [color]=\"ratingThemeColor(lead)\" [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> } }\n @case ('html') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\" [innerHTML]=\"lead.value\"></span> }\n @default { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n }\n }\n <div>\n <div class=\"primary\" [ngClass]=\"primary(it)?.class\" [style.cssText]=\"primary(it)?.style\">{{ primary(it)?.value }}</div>\n @if ((config.layout?.lines || 1) > 1) { <div class=\"secondary\" [ngClass]=\"secondary(it)?.class\" [style.cssText]=\"secondary(it)?.style\">{{ secondary(it)?.value }}</div> }\n @if (featuresVisible()) {\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{ featureLabel(it, f.expr) }}</span> }\n </span>\n }\n }\n </div>\n @if (meta(it); as m) {\n <div class=\"meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (metaPrefixIcon(); as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\" [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, m.value)\" [color]=\"ratingThemeColor(m)\" [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>{{ m.value }}</span> }\n }\n </div>\n }\n @if (trailing(it); as tr) {\n <div class=\"trailing\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n @switch (tr.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip> }\n @case ('icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"tr.value\" [alt]=\"tr.imageAlt || ''\" /></span> }\n @case ('rating') { @for (_ of ratingRange(tr); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, tr.value)\" [color]=\"ratingThemeColor(tr)\" [style.cssText]=\"ratingIconStyle(tr)\"></mat-icon> } }\n @case ('html') { <span [innerHTML]=\"tr.value\"></span> }\n @default { <span>{{ tr.value }}</span> }\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".preview-root{--p-list-radius: var(--md-sys-shape-corner-medium, 16px);--p-list-shadow: var(--md-sys-elevation-level2);--p-list-border: 1px solid var(--md-sys-color-outline-variant);--p-list-blur: 10px;--p-list-foreground: var(--md-sys-color-on-surface);--p-list-foreground-muted: var(--md-sys-color-on-surface-variant);--p-list-grad-foreground: var(--md-sys-color-on-primary);--p-list-grad-foreground-muted: var(--md-sys-color-on-primary);--p-list-surface: var(--md-sys-color-surface-container);--p-list-accent: var(--md-sys-color-primary);--p-list-item-border: 1px solid var(--md-sys-color-outline-variant);--p-list-grad-from: var(--md-sys-color-primary-container);--p-list-grad-to: var(--md-sys-color-tertiary-container);--p-list-grad-angle: 135deg;--p-list-tile-minW: 240px;--p-list-tile-gap: 16px;--p-list-tile-padding: 16px;--p-list-tile-radius: 16px;--p-list-tile-media-radius: 12px;--p-list-tile-media-ratio: 1 / 1;padding:12px}.preview-light{background:var(--md-sys-color-surface-container-low, var(--md-sys-color-surface))}.preview-dark{background:var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface))}.preview-grid{background-color:var(--md-sys-color-surface-variant, var(--md-sys-color-surface));background-image:linear-gradient(var(--md-sys-color-outline-variant, var(--md-sys-color-outline)) 1px,transparent 1px),linear-gradient(90deg,var(--md-sys-color-outline-variant, var(--md-sys-color-outline)) 1px,transparent 1px);background-size:16px 16px}.skin-elevated,.skin-outline,.skin-flat,.skin-neumorphism{--p-list-item-surface: var(--mdc-elevated-card-container-color, var(--p-list-surface));--p-list-item-border: var(--p-list-border)}.skin-elevated .item-card,.skin-outline .item-card,.skin-flat .item-card,.skin-neumorphism .item-card{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:var(--p-list-radius);box-shadow:var(--p-list-shadow);border:var(--p-list-border)}.skin-elevated .item-tile,.skin-outline .item-tile,.skin-flat .item-tile,.skin-neumorphism .item-tile{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));box-shadow:var(--p-list-shadow);border:var(--p-list-border)}.skin-elevated .mat-mdc-list-item .list-item-content,.skin-outline .mat-mdc-list-item .list-item-content,.skin-flat .mat-mdc-list-item .list-item-content,.skin-neumorphism .mat-mdc-list-item .list-item-content{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:calc(var(--p-list-radius) * .75);box-shadow:var(--p-list-shadow);border:var(--p-list-item-border);color:var(--p-list-foreground)}.skin-outline{--p-list-shadow: none;--p-list-border: 1px solid var(--md-sys-color-outline)}.skin-flat{--p-list-shadow: none;--p-list-border: 1px solid var(--md-sys-color-outline-variant)}.skin-neumorphism{--p-list-shadow: var(--md-sys-elevation-level2);--p-list-border: 1px solid var(--md-sys-color-outline-variant);--p-list-radius: 1.25rem}.skin-pill-soft .item-card,.skin-pill-soft .item-tile{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:calc(var(--p-list-radius) * 1.3);box-shadow:var(--md-sys-elevation-level1);border:var(--p-list-border)}.skin-pill-soft .mat-mdc-list-item .list-item-content{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:calc(var(--p-list-radius) * 1.3);box-shadow:var(--md-sys-elevation-level1);border:var(--p-list-border);color:var(--p-list-foreground)}.lead-image{position:relative;width:96px;height:72px;border-radius:12px;overflow:hidden}.lead-image img{width:100%;height:100%;object-fit:cover;display:block}.lead-image .lead-badge{position:absolute;left:8px;bottom:8px}.features{display:flex;flex-wrap:wrap;gap:12px;margin-top:6px;color:var(--p-list-foreground-muted)}.feature{display:inline-flex;align-items:center;gap:6px}.model-media .lead-image{width:136px;height:96px;border-radius:16px}.model-hotel .lead-image{width:160px;height:110px;border-radius:18px}.skin-gradient-tile{--p-list-foreground: var(--p-list-grad-foreground);--p-list-foreground-muted: var(--p-list-grad-foreground-muted)}.skin-gradient-tile .item-card,.skin-gradient-tile .item-tile,.skin-gradient-tile .mat-mdc-list-item .list-item-content{background:linear-gradient(var(--p-list-grad-angle),var(--p-list-grad-from),var(--p-list-grad-to));border-radius:var(--p-list-radius);color:var(--p-list-foreground)}.skin-glass .item-card,.skin-glass .item-tile{background:var(--md-sys-color-surface-container-low);border-radius:var(--p-list-radius);border:1px solid var(--md-sys-color-outline-variant);backdrop-filter:blur(var(--p-list-blur));-webkit-backdrop-filter:blur(var(--p-list-blur))}.skin-glass .mat-mdc-list-item .list-item-content{background:var(--md-sys-color-surface-container-low);border-radius:var(--p-list-radius);border:1px solid var(--md-sys-color-outline-variant);backdrop-filter:blur(var(--p-list-blur));-webkit-backdrop-filter:blur(var(--p-list-blur));color:var(--p-list-foreground)}.list-item-content{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;align-items:center;gap:12px;padding:12px 16px}.primary{font-weight:500;color:var(--p-list-foreground)}.secondary,.meta{color:var(--p-list-foreground-muted)}.trailing{color:var(--p-list-foreground-muted);text-align:end}.cards-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--p-list-tile-minW),1fr));gap:var(--p-list-tile-gap)}.item-card{padding:12px}.tiles-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--p-list-tile-minW),1fr));gap:var(--p-list-tile-gap)}.item-tile{padding:var(--p-list-tile-padding);border-radius:var(--p-list-tile-radius);border:var(--p-list-border);background:var(--p-list-surface);display:grid;gap:8px}.tile-media{width:100%;aspect-ratio:var(--p-list-tile-media-ratio);border-radius:var(--p-list-tile-media-radius);background:var(--md-sys-color-surface-container-low, var(--p-list-surface));display:grid;place-items:center;overflow:hidden}.tile-media img{width:100%;height:100%;object-fit:cover}.tile-body{display:grid;gap:4px}.chip-outlined.mat-mdc-chip{background:transparent!important;border:1px solid currentColor}\n"] }]
965
965
  }], ctorParameters: () => [{ type: ListSkinService }], propDecorators: { config: [{
@@ -980,10 +980,10 @@ class PraxisMetaEditorTextComponent {
980
980
  this.setPipe?.(this.model, pipe);
981
981
  this.change.emit();
982
982
  }
983
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisMetaEditorTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
984
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: PraxisMetaEditorTextComponent, isStandalone: true, selector: "praxis-meta-editor-text", inputs: { model: "model", setPipe: "setPipe" }, outputs: { change: "change" }, ngImport: i0, template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Pipes / Formato</mat-label>\n <input matInput [(ngModel)]=\"model.extraPipe\" (ngModelChange)=\"change.emit()\" />\n <button mat-icon-button matSuffix [matMenuTriggerFor]=\"pipeMenu\"><mat-icon>build</mat-icon></button>\n </mat-form-field>\n <mat-menu #pipeMenu=\"matMenu\">\n <button mat-menu-item (click)=\"onPipe('map:KEY=VALUE')\"><mat-icon>tune</mat-icon>Map</button>\n </mat-menu>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i5$1.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: i5$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i5$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }] });
983
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisMetaEditorTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
984
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisMetaEditorTextComponent, isStandalone: true, selector: "praxis-meta-editor-text", inputs: { model: "model", setPipe: "setPipe" }, outputs: { change: "change" }, ngImport: i0, template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Pipes / Formato</mat-label>\n <input matInput [(ngModel)]=\"model.extraPipe\" (ngModelChange)=\"change.emit()\" />\n <button mat-icon-button matSuffix [matMenuTriggerFor]=\"pipeMenu\"><mat-icon>build</mat-icon></button>\n </mat-form-field>\n <mat-menu #pipeMenu=\"matMenu\">\n <button mat-menu-item (click)=\"onPipe('map:KEY=VALUE')\"><mat-icon>tune</mat-icon>Map</button>\n </mat-menu>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i5$1.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: i5$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i5$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }] });
985
985
  }
986
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisMetaEditorTextComponent, decorators: [{
986
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisMetaEditorTextComponent, decorators: [{
987
987
  type: Component,
988
988
  args: [{ selector: 'praxis-meta-editor-text', standalone: true, imports: [CommonModule, FormsModule, MatFormFieldModule, MatInputModule, MatIconModule, MatMenuModule], template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Pipes / Formato</mat-label>\n <input matInput [(ngModel)]=\"model.extraPipe\" (ngModelChange)=\"change.emit()\" />\n <button mat-icon-button matSuffix [matMenuTriggerFor]=\"pipeMenu\"><mat-icon>build</mat-icon></button>\n </mat-form-field>\n <mat-menu #pipeMenu=\"matMenu\">\n <button mat-menu-item (click)=\"onPipe('map:KEY=VALUE')\"><mat-icon>tune</mat-icon>Map</button>\n </mat-menu>\n</div>\n" }]
989
989
  }], propDecorators: { model: [{
@@ -1001,10 +1001,10 @@ class PraxisMetaEditorChipComponent {
1001
1001
  isCustomColor;
1002
1002
  enableCustomColor;
1003
1003
  change = new EventEmitter();
1004
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisMetaEditorChipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1005
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: PraxisMetaEditorChipComponent, isStandalone: true, selector: "praxis-meta-editor-chip", inputs: { model: "model", paletteOptions: "paletteOptions", colorDotBackground: "colorDotBackground", isCustomColor: "isCustomColor", enableCustomColor: "enableCustomColor" }, outputs: { change: "change" }, ngImport: i0, template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor</mat-label>\n <mat-select [(ngModel)]=\"model.chipColor\" (ngModelChange)=\"change.emit()\">\n <mat-option *ngFor=\"let c of paletteOptions\" [value]=\"c.value\">\n <span class=\"color-dot\" [style.background]=\"colorDotBackground?.(c.value)\"></span>{{ c.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Variante</mat-label>\n <mat-select [(ngModel)]=\"model.chipVariant\" (ngModelChange)=\"change.emit()\">\n <mat-option value=\"filled\">Filled</mat-option>\n <mat-option value=\"outlined\">Outlined</mat-option>\n </mat-select>\n </mat-form-field>\n</div>\n<div class=\"g gap-8\">\n <div *ngIf=\"isCustomColor?.(model.chipColor); else chipCustomBtn\">\n <pdx-color-picker label=\"Cor personalizada\" [format]=\"'hex'\" [(ngModel)]=\"model.chipColor\"\n (ngModelChange)=\"change.emit()\"></pdx-color-picker>\n </div>\n <ng-template #chipCustomBtn>\n <button mat-stroked-button type=\"button\" (click)=\"enableCustomColor?.(model, 'chipColor'); change.emit()\">\n Usar cor personalizada\n </button>\n </ng-template>\n</div>\n<div class=\"g row-flow gap-8 mt-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"model.chipVariant='filled'; model.chipColor='primary'; change.emit()\">Status</button>\n <button mat-stroked-button type=\"button\" (click)=\"model.chipVariant='outlined'; model.chipColor='primary'; change.emit()\">Outlined</button>\n <button mat-stroked-button type=\"button\" (click)=\"model.chipVariant='filled'; model.chipColor='warn'; change.emit()\">Cr\u00EDtico</button>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.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: PdxColorPickerComponent, selector: "pdx-color-picker", inputs: ["actionsLayout", "activeView", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "clearButton", "disabledMode", "readonlyMode", "visible", "presentationMode", "fillMode", "format", "gradientSettings", "icon", "iconClass", "svgIcon", "paletteSettings", "popupSettings", "preview", "rounded", "size", "tabindex", "views", "maxRecent", "showRecent"], outputs: ["valueChange", "open", "close", "cancel", "activeViewChange", "activeColorClick", "focusEvent", "blurEvent"] }] });
1004
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisMetaEditorChipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1005
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisMetaEditorChipComponent, isStandalone: true, selector: "praxis-meta-editor-chip", inputs: { model: "model", paletteOptions: "paletteOptions", colorDotBackground: "colorDotBackground", isCustomColor: "isCustomColor", enableCustomColor: "enableCustomColor" }, outputs: { change: "change" }, ngImport: i0, template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor</mat-label>\n <mat-select [(ngModel)]=\"model.chipColor\" (ngModelChange)=\"change.emit()\">\n <mat-option *ngFor=\"let c of paletteOptions\" [value]=\"c.value\">\n <span class=\"color-dot\" [style.background]=\"colorDotBackground?.(c.value)\"></span>{{ c.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Variante</mat-label>\n <mat-select [(ngModel)]=\"model.chipVariant\" (ngModelChange)=\"change.emit()\">\n <mat-option value=\"filled\">Filled</mat-option>\n <mat-option value=\"outlined\">Outlined</mat-option>\n </mat-select>\n </mat-form-field>\n</div>\n<div class=\"g gap-8\">\n <div *ngIf=\"isCustomColor?.(model.chipColor); else chipCustomBtn\">\n <pdx-color-picker label=\"Cor personalizada\" [format]=\"'hex'\" [(ngModel)]=\"model.chipColor\"\n (ngModelChange)=\"change.emit()\"></pdx-color-picker>\n </div>\n <ng-template #chipCustomBtn>\n <button mat-stroked-button type=\"button\" (click)=\"enableCustomColor?.(model, 'chipColor'); change.emit()\">\n Usar cor personalizada\n </button>\n </ng-template>\n</div>\n<div class=\"g row-flow gap-8 mt-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"model.chipVariant='filled'; model.chipColor='primary'; change.emit()\">Status</button>\n <button mat-stroked-button type=\"button\" (click)=\"model.chipVariant='outlined'; model.chipColor='primary'; change.emit()\">Outlined</button>\n <button mat-stroked-button type=\"button\" (click)=\"model.chipVariant='filled'; model.chipColor='warn'; change.emit()\">Cr\u00EDtico</button>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.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: PdxColorPickerComponent, selector: "pdx-color-picker", inputs: ["actionsLayout", "activeView", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "clearButton", "disabledMode", "readonlyMode", "visible", "presentationMode", "fillMode", "format", "gradientSettings", "icon", "iconClass", "svgIcon", "paletteSettings", "popupSettings", "preview", "rounded", "size", "tabindex", "views", "maxRecent", "showRecent"], outputs: ["valueChange", "open", "close", "cancel", "activeViewChange", "activeColorClick", "focusEvent", "blurEvent"] }] });
1006
1006
  }
1007
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisMetaEditorChipComponent, decorators: [{
1007
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisMetaEditorChipComponent, decorators: [{
1008
1008
  type: Component,
1009
1009
  args: [{ selector: 'praxis-meta-editor-chip', standalone: true, imports: [CommonModule, FormsModule, MatFormFieldModule, MatSelectModule, MatButtonModule, PdxColorPickerComponent], template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor</mat-label>\n <mat-select [(ngModel)]=\"model.chipColor\" (ngModelChange)=\"change.emit()\">\n <mat-option *ngFor=\"let c of paletteOptions\" [value]=\"c.value\">\n <span class=\"color-dot\" [style.background]=\"colorDotBackground?.(c.value)\"></span>{{ c.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Variante</mat-label>\n <mat-select [(ngModel)]=\"model.chipVariant\" (ngModelChange)=\"change.emit()\">\n <mat-option value=\"filled\">Filled</mat-option>\n <mat-option value=\"outlined\">Outlined</mat-option>\n </mat-select>\n </mat-form-field>\n</div>\n<div class=\"g gap-8\">\n <div *ngIf=\"isCustomColor?.(model.chipColor); else chipCustomBtn\">\n <pdx-color-picker label=\"Cor personalizada\" [format]=\"'hex'\" [(ngModel)]=\"model.chipColor\"\n (ngModelChange)=\"change.emit()\"></pdx-color-picker>\n </div>\n <ng-template #chipCustomBtn>\n <button mat-stroked-button type=\"button\" (click)=\"enableCustomColor?.(model, 'chipColor'); change.emit()\">\n Usar cor personalizada\n </button>\n </ng-template>\n</div>\n<div class=\"g row-flow gap-8 mt-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"model.chipVariant='filled'; model.chipColor='primary'; change.emit()\">Status</button>\n <button mat-stroked-button type=\"button\" (click)=\"model.chipVariant='outlined'; model.chipColor='primary'; change.emit()\">Outlined</button>\n <button mat-stroked-button type=\"button\" (click)=\"model.chipVariant='filled'; model.chipColor='warn'; change.emit()\">Cr\u00EDtico</button>\n</div>\n" }]
1010
1010
  }], propDecorators: { model: [{
@@ -1028,10 +1028,10 @@ class PraxisMetaEditorRatingComponent {
1028
1028
  isCustomColor;
1029
1029
  enableCustomColor;
1030
1030
  change = new EventEmitter();
1031
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisMetaEditorRatingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1032
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: PraxisMetaEditorRatingComponent, isStandalone: true, selector: "praxis-meta-editor-rating", inputs: { model: "model", paletteOptions: "paletteOptions", colorDotBackground: "colorDotBackground", isCustomColor: "isCustomColor", enableCustomColor: "enableCustomColor" }, outputs: { change: "change" }, ngImport: i0, template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor</mat-label>\n <mat-select [(ngModel)]=\"model.ratingColor\" (ngModelChange)=\"change.emit()\">\n <mat-option *ngFor=\"let c of paletteOptions\" [value]=\"c.value\">\n <span class=\"color-dot\" [style.background]=\"colorDotBackground?.(c.value)\"></span>{{ c.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tamanho (px)</mat-label>\n <input matInput type=\"number\" min=\"10\" max=\"32\" [(ngModel)]=\"model.ratingSize\" (ngModelChange)=\"change.emit()\" />\n <mat-error *ngIf=\"model.ratingSize!=null && (model.ratingSize < 10 || model.ratingSize > 32)\">Tamanho 10\u201332</mat-error>\n </mat-form-field>\n</div>\n<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>M\u00E1ximo</mat-label>\n <input matInput type=\"number\" min=\"1\" max=\"10\" [(ngModel)]=\"model.ratingMax\" (ngModelChange)=\"change.emit()\" />\n <mat-error *ngIf=\"model.ratingMax!=null && (model.ratingMax < 1 || model.ratingMax > 10)\">M\u00E1ximo 1\u201310</mat-error>\n </mat-form-field>\n <div class=\"muted text-caption\">Padr\u00E3o: 5</div>\n</div>\n<div class=\"g gap-8\">\n <div *ngIf=\"isCustomColor?.(model.ratingColor); else ratingCustomBtn\">\n <pdx-color-picker label=\"Cor personalizada\" [format]=\"'hex'\" [(ngModel)]=\"model.ratingColor\"\n (ngModelChange)=\"change.emit()\"></pdx-color-picker>\n </div>\n <ng-template #ratingCustomBtn>\n <button mat-stroked-button type=\"button\" (click)=\"enableCustomColor?.(model, 'ratingColor'); change.emit()\">\n Usar cor personalizada\n </button>\n </ng-template>\n</div>\n<div class=\"g row-flow gap-8 mt-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"model.ratingSize=12; model.ratingMax=5; model.ratingColor='primary'; change.emit()\">Compacto</button>\n <button mat-stroked-button type=\"button\" (click)=\"model.ratingSize=16; model.ratingMax=5; model.ratingColor='primary'; change.emit()\">Padr\u00E3o</button>\n <button mat-stroked-button type=\"button\" (click)=\"model.ratingSize=20; model.ratingMax=5; model.ratingColor='accent'; change.emit()\">Destaque</button>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i2.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.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: PdxColorPickerComponent, selector: "pdx-color-picker", inputs: ["actionsLayout", "activeView", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "clearButton", "disabledMode", "readonlyMode", "visible", "presentationMode", "fillMode", "format", "gradientSettings", "icon", "iconClass", "svgIcon", "paletteSettings", "popupSettings", "preview", "rounded", "size", "tabindex", "views", "maxRecent", "showRecent"], outputs: ["valueChange", "open", "close", "cancel", "activeViewChange", "activeColorClick", "focusEvent", "blurEvent"] }] });
1031
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisMetaEditorRatingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1032
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisMetaEditorRatingComponent, isStandalone: true, selector: "praxis-meta-editor-rating", inputs: { model: "model", paletteOptions: "paletteOptions", colorDotBackground: "colorDotBackground", isCustomColor: "isCustomColor", enableCustomColor: "enableCustomColor" }, outputs: { change: "change" }, ngImport: i0, template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor</mat-label>\n <mat-select [(ngModel)]=\"model.ratingColor\" (ngModelChange)=\"change.emit()\">\n <mat-option *ngFor=\"let c of paletteOptions\" [value]=\"c.value\">\n <span class=\"color-dot\" [style.background]=\"colorDotBackground?.(c.value)\"></span>{{ c.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tamanho (px)</mat-label>\n <input matInput type=\"number\" min=\"10\" max=\"32\" [(ngModel)]=\"model.ratingSize\" (ngModelChange)=\"change.emit()\" />\n <mat-error *ngIf=\"model.ratingSize!=null && (model.ratingSize < 10 || model.ratingSize > 32)\">Tamanho 10\u201332</mat-error>\n </mat-form-field>\n</div>\n<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>M\u00E1ximo</mat-label>\n <input matInput type=\"number\" min=\"1\" max=\"10\" [(ngModel)]=\"model.ratingMax\" (ngModelChange)=\"change.emit()\" />\n <mat-error *ngIf=\"model.ratingMax!=null && (model.ratingMax < 1 || model.ratingMax > 10)\">M\u00E1ximo 1\u201310</mat-error>\n </mat-form-field>\n <div class=\"muted text-caption\">Padr\u00E3o: 5</div>\n</div>\n<div class=\"g gap-8\">\n <div *ngIf=\"isCustomColor?.(model.ratingColor); else ratingCustomBtn\">\n <pdx-color-picker label=\"Cor personalizada\" [format]=\"'hex'\" [(ngModel)]=\"model.ratingColor\"\n (ngModelChange)=\"change.emit()\"></pdx-color-picker>\n </div>\n <ng-template #ratingCustomBtn>\n <button mat-stroked-button type=\"button\" (click)=\"enableCustomColor?.(model, 'ratingColor'); change.emit()\">\n Usar cor personalizada\n </button>\n </ng-template>\n</div>\n<div class=\"g row-flow gap-8 mt-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"model.ratingSize=12; model.ratingMax=5; model.ratingColor='primary'; change.emit()\">Compacto</button>\n <button mat-stroked-button type=\"button\" (click)=\"model.ratingSize=16; model.ratingMax=5; model.ratingColor='primary'; change.emit()\">Padr\u00E3o</button>\n <button mat-stroked-button type=\"button\" (click)=\"model.ratingSize=20; model.ratingMax=5; model.ratingColor='accent'; change.emit()\">Destaque</button>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i2.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.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: PdxColorPickerComponent, selector: "pdx-color-picker", inputs: ["actionsLayout", "activeView", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "clearButton", "disabledMode", "readonlyMode", "visible", "presentationMode", "fillMode", "format", "gradientSettings", "icon", "iconClass", "svgIcon", "paletteSettings", "popupSettings", "preview", "rounded", "size", "tabindex", "views", "maxRecent", "showRecent"], outputs: ["valueChange", "open", "close", "cancel", "activeViewChange", "activeColorClick", "focusEvent", "blurEvent"] }] });
1033
1033
  }
1034
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisMetaEditorRatingComponent, decorators: [{
1034
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisMetaEditorRatingComponent, decorators: [{
1035
1035
  type: Component,
1036
1036
  args: [{ selector: 'praxis-meta-editor-rating', standalone: true, imports: [CommonModule, FormsModule, MatFormFieldModule, MatInputModule, MatSelectModule, MatButtonModule, PdxColorPickerComponent], template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor</mat-label>\n <mat-select [(ngModel)]=\"model.ratingColor\" (ngModelChange)=\"change.emit()\">\n <mat-option *ngFor=\"let c of paletteOptions\" [value]=\"c.value\">\n <span class=\"color-dot\" [style.background]=\"colorDotBackground?.(c.value)\"></span>{{ c.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tamanho (px)</mat-label>\n <input matInput type=\"number\" min=\"10\" max=\"32\" [(ngModel)]=\"model.ratingSize\" (ngModelChange)=\"change.emit()\" />\n <mat-error *ngIf=\"model.ratingSize!=null && (model.ratingSize < 10 || model.ratingSize > 32)\">Tamanho 10\u201332</mat-error>\n </mat-form-field>\n</div>\n<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>M\u00E1ximo</mat-label>\n <input matInput type=\"number\" min=\"1\" max=\"10\" [(ngModel)]=\"model.ratingMax\" (ngModelChange)=\"change.emit()\" />\n <mat-error *ngIf=\"model.ratingMax!=null && (model.ratingMax < 1 || model.ratingMax > 10)\">M\u00E1ximo 1\u201310</mat-error>\n </mat-form-field>\n <div class=\"muted text-caption\">Padr\u00E3o: 5</div>\n</div>\n<div class=\"g gap-8\">\n <div *ngIf=\"isCustomColor?.(model.ratingColor); else ratingCustomBtn\">\n <pdx-color-picker label=\"Cor personalizada\" [format]=\"'hex'\" [(ngModel)]=\"model.ratingColor\"\n (ngModelChange)=\"change.emit()\"></pdx-color-picker>\n </div>\n <ng-template #ratingCustomBtn>\n <button mat-stroked-button type=\"button\" (click)=\"enableCustomColor?.(model, 'ratingColor'); change.emit()\">\n Usar cor personalizada\n </button>\n </ng-template>\n</div>\n<div class=\"g row-flow gap-8 mt-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"model.ratingSize=12; model.ratingMax=5; model.ratingColor='primary'; change.emit()\">Compacto</button>\n <button mat-stroked-button type=\"button\" (click)=\"model.ratingSize=16; model.ratingMax=5; model.ratingColor='primary'; change.emit()\">Padr\u00E3o</button>\n <button mat-stroked-button type=\"button\" (click)=\"model.ratingSize=20; model.ratingMax=5; model.ratingColor='accent'; change.emit()\">Destaque</button>\n</div>\n" }]
1037
1037
  }], propDecorators: { model: [{
@@ -1051,10 +1051,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
1051
1051
  class PraxisMetaEditorCurrencyComponent {
1052
1052
  model;
1053
1053
  change = new EventEmitter();
1054
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisMetaEditorCurrencyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1055
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: PraxisMetaEditorCurrencyComponent, isStandalone: true, selector: "praxis-meta-editor-currency", inputs: { model: "model" }, outputs: { change: "change" }, ngImport: i0, template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Moeda</mat-label>\n <input matInput [(ngModel)]=\"model.currencyCode\" (ngModelChange)=\"change.emit()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Locale</mat-label>\n <input matInput [(ngModel)]=\"model.locale\" (ngModelChange)=\"change.emit()\" />\n </mat-form-field>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }] });
1054
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisMetaEditorCurrencyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1055
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisMetaEditorCurrencyComponent, isStandalone: true, selector: "praxis-meta-editor-currency", inputs: { model: "model" }, outputs: { change: "change" }, ngImport: i0, template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Moeda</mat-label>\n <input matInput [(ngModel)]=\"model.currencyCode\" (ngModelChange)=\"change.emit()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Locale</mat-label>\n <input matInput [(ngModel)]=\"model.locale\" (ngModelChange)=\"change.emit()\" />\n </mat-form-field>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }] });
1056
1056
  }
1057
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisMetaEditorCurrencyComponent, decorators: [{
1057
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisMetaEditorCurrencyComponent, decorators: [{
1058
1058
  type: Component,
1059
1059
  args: [{ selector: 'praxis-meta-editor-currency', standalone: true, imports: [CommonModule, FormsModule, MatFormFieldModule, MatInputModule], template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Moeda</mat-label>\n <input matInput [(ngModel)]=\"model.currencyCode\" (ngModelChange)=\"change.emit()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Locale</mat-label>\n <input matInput [(ngModel)]=\"model.locale\" (ngModelChange)=\"change.emit()\" />\n </mat-form-field>\n</div>\n" }]
1060
1060
  }], propDecorators: { model: [{
@@ -1066,10 +1066,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
1066
1066
  class PraxisMetaEditorDateComponent {
1067
1067
  model;
1068
1068
  change = new EventEmitter();
1069
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisMetaEditorDateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1070
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: PraxisMetaEditorDateComponent, isStandalone: true, selector: "praxis-meta-editor-date", inputs: { model: "model" }, outputs: { change: "change" }, ngImport: i0, template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Formato</mat-label>\n <mat-select [(ngModel)]=\"model.dateStyle\" (ngModelChange)=\"change.emit()\">\n <mat-option value=\"short\">Curto</mat-option>\n <mat-option value=\"medium\">M\u00E9dio</mat-option>\n <mat-option value=\"long\">Longo</mat-option>\n <mat-option value=\"full\">Completo</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Locale</mat-label>\n <input matInput [(ngModel)]=\"model.locale\" (ngModelChange)=\"change.emit()\" />\n </mat-form-field>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }] });
1069
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisMetaEditorDateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1070
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisMetaEditorDateComponent, isStandalone: true, selector: "praxis-meta-editor-date", inputs: { model: "model" }, outputs: { change: "change" }, ngImport: i0, template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Formato</mat-label>\n <mat-select [(ngModel)]=\"model.dateStyle\" (ngModelChange)=\"change.emit()\">\n <mat-option value=\"short\">Curto</mat-option>\n <mat-option value=\"medium\">M\u00E9dio</mat-option>\n <mat-option value=\"long\">Longo</mat-option>\n <mat-option value=\"full\">Completo</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Locale</mat-label>\n <input matInput [(ngModel)]=\"model.locale\" (ngModelChange)=\"change.emit()\" />\n </mat-form-field>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }] });
1071
1071
  }
1072
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisMetaEditorDateComponent, decorators: [{
1072
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisMetaEditorDateComponent, decorators: [{
1073
1073
  type: Component,
1074
1074
  args: [{ selector: 'praxis-meta-editor-date', standalone: true, imports: [CommonModule, FormsModule, MatFormFieldModule, MatInputModule, MatSelectModule], template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Formato</mat-label>\n <mat-select [(ngModel)]=\"model.dateStyle\" (ngModelChange)=\"change.emit()\">\n <mat-option value=\"short\">Curto</mat-option>\n <mat-option value=\"medium\">M\u00E9dio</mat-option>\n <mat-option value=\"long\">Longo</mat-option>\n <mat-option value=\"full\">Completo</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Locale</mat-label>\n <input matInput [(ngModel)]=\"model.locale\" (ngModelChange)=\"change.emit()\" />\n </mat-form-field>\n</div>\n" }]
1075
1075
  }], propDecorators: { model: [{
@@ -1085,10 +1085,10 @@ class PraxisMetaEditorIconComponent {
1085
1085
  isCustomColor;
1086
1086
  enableCustomColor;
1087
1087
  change = new EventEmitter();
1088
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisMetaEditorIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1089
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: PraxisMetaEditorIconComponent, isStandalone: true, selector: "praxis-meta-editor-icon", inputs: { model: "model", paletteOptions: "paletteOptions", colorDotBackground: "colorDotBackground", isCustomColor: "isCustomColor", enableCustomColor: "enableCustomColor" }, outputs: { change: "change" }, ngImport: i0, template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor</mat-label>\n <mat-select [(ngModel)]=\"model.iconColor\" (ngModelChange)=\"change.emit()\">\n <mat-option *ngFor=\"let c of paletteOptions\" [value]=\"c.value\">\n <span class=\"color-dot\" [style.background]=\"colorDotBackground?.(c.value)\"></span>{{ c.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n</div>\n<div class=\"g gap-8\">\n <div *ngIf=\"isCustomColor?.(model.iconColor); else iconCustomBtn\">\n <pdx-color-picker label=\"Cor personalizada\" [format]=\"'hex'\" [(ngModel)]=\"model.iconColor\"\n (ngModelChange)=\"change.emit()\"></pdx-color-picker>\n </div>\n <ng-template #iconCustomBtn>\n <button mat-stroked-button type=\"button\" (click)=\"enableCustomColor?.(model, 'iconColor'); change.emit()\">\n Usar cor personalizada\n </button>\n </ng-template>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.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: PdxColorPickerComponent, selector: "pdx-color-picker", inputs: ["actionsLayout", "activeView", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "clearButton", "disabledMode", "readonlyMode", "visible", "presentationMode", "fillMode", "format", "gradientSettings", "icon", "iconClass", "svgIcon", "paletteSettings", "popupSettings", "preview", "rounded", "size", "tabindex", "views", "maxRecent", "showRecent"], outputs: ["valueChange", "open", "close", "cancel", "activeViewChange", "activeColorClick", "focusEvent", "blurEvent"] }] });
1088
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisMetaEditorIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1089
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisMetaEditorIconComponent, isStandalone: true, selector: "praxis-meta-editor-icon", inputs: { model: "model", paletteOptions: "paletteOptions", colorDotBackground: "colorDotBackground", isCustomColor: "isCustomColor", enableCustomColor: "enableCustomColor" }, outputs: { change: "change" }, ngImport: i0, template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor</mat-label>\n <mat-select [(ngModel)]=\"model.iconColor\" (ngModelChange)=\"change.emit()\">\n <mat-option *ngFor=\"let c of paletteOptions\" [value]=\"c.value\">\n <span class=\"color-dot\" [style.background]=\"colorDotBackground?.(c.value)\"></span>{{ c.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n</div>\n<div class=\"g gap-8\">\n <div *ngIf=\"isCustomColor?.(model.iconColor); else iconCustomBtn\">\n <pdx-color-picker label=\"Cor personalizada\" [format]=\"'hex'\" [(ngModel)]=\"model.iconColor\"\n (ngModelChange)=\"change.emit()\"></pdx-color-picker>\n </div>\n <ng-template #iconCustomBtn>\n <button mat-stroked-button type=\"button\" (click)=\"enableCustomColor?.(model, 'iconColor'); change.emit()\">\n Usar cor personalizada\n </button>\n </ng-template>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.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: PdxColorPickerComponent, selector: "pdx-color-picker", inputs: ["actionsLayout", "activeView", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "clearButton", "disabledMode", "readonlyMode", "visible", "presentationMode", "fillMode", "format", "gradientSettings", "icon", "iconClass", "svgIcon", "paletteSettings", "popupSettings", "preview", "rounded", "size", "tabindex", "views", "maxRecent", "showRecent"], outputs: ["valueChange", "open", "close", "cancel", "activeViewChange", "activeColorClick", "focusEvent", "blurEvent"] }] });
1090
1090
  }
1091
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisMetaEditorIconComponent, decorators: [{
1091
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisMetaEditorIconComponent, decorators: [{
1092
1092
  type: Component,
1093
1093
  args: [{ selector: 'praxis-meta-editor-icon', standalone: true, imports: [CommonModule, FormsModule, MatFormFieldModule, MatSelectModule, MatButtonModule, PdxColorPickerComponent], template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor</mat-label>\n <mat-select [(ngModel)]=\"model.iconColor\" (ngModelChange)=\"change.emit()\">\n <mat-option *ngFor=\"let c of paletteOptions\" [value]=\"c.value\">\n <span class=\"color-dot\" [style.background]=\"colorDotBackground?.(c.value)\"></span>{{ c.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n</div>\n<div class=\"g gap-8\">\n <div *ngIf=\"isCustomColor?.(model.iconColor); else iconCustomBtn\">\n <pdx-color-picker label=\"Cor personalizada\" [format]=\"'hex'\" [(ngModel)]=\"model.iconColor\"\n (ngModelChange)=\"change.emit()\"></pdx-color-picker>\n </div>\n <ng-template #iconCustomBtn>\n <button mat-stroked-button type=\"button\" (click)=\"enableCustomColor?.(model, 'iconColor'); change.emit()\">\n Usar cor personalizada\n </button>\n </ng-template>\n</div>\n" }]
1094
1094
  }], propDecorators: { model: [{
@@ -1108,10 +1108,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
1108
1108
  class PraxisMetaEditorImageComponent {
1109
1109
  model;
1110
1110
  change = new EventEmitter();
1111
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisMetaEditorImageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1112
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: PraxisMetaEditorImageComponent, isStandalone: true, selector: "praxis-meta-editor-image", inputs: { model: "model" }, outputs: { change: "change" }, ngImport: i0, template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\" class=\"col-span-2\">\n <mat-label>Alt da imagem</mat-label>\n <input matInput [(ngModel)]=\"model.imageAlt\" (ngModelChange)=\"change.emit()\" />\n </mat-form-field>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }] });
1111
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisMetaEditorImageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1112
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisMetaEditorImageComponent, isStandalone: true, selector: "praxis-meta-editor-image", inputs: { model: "model" }, outputs: { change: "change" }, ngImport: i0, template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\" class=\"col-span-2\">\n <mat-label>Alt da imagem</mat-label>\n <input matInput [(ngModel)]=\"model.imageAlt\" (ngModelChange)=\"change.emit()\" />\n </mat-form-field>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }] });
1113
1113
  }
1114
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisMetaEditorImageComponent, decorators: [{
1114
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisMetaEditorImageComponent, decorators: [{
1115
1115
  type: Component,
1116
1116
  args: [{ selector: 'praxis-meta-editor-image', standalone: true, imports: [CommonModule, FormsModule, MatFormFieldModule, MatInputModule], template: "<div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\" class=\"col-span-2\">\n <mat-label>Alt da imagem</mat-label>\n <input matInput [(ngModel)]=\"model.imageAlt\" (ngModelChange)=\"change.emit()\" />\n </mat-form-field>\n</div>\n" }]
1117
1117
  }], propDecorators: { model: [{
@@ -2825,10 +2825,10 @@ class PraxisListConfigEditor {
2825
2825
  default: return 'horizontal_rule';
2826
2826
  }
2827
2827
  }
2828
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisListConfigEditor, deps: [{ token: SETTINGS_PANEL_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
2829
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: PraxisListConfigEditor, isStandalone: true, selector: "praxis-list-config-editor", inputs: { config: "config", listId: "listId" }, ngImport: i0, template: "<mat-tab-group class=\"list-editor-tabs\">\n <mat-tab label=\"Dados\">\n <div class=\"editor-content\">\n <div class=\"g g-1-auto gap-8 ai-center\">\n <div class=\"muted\">Observa\u00E7\u00E3o: ajustes aplicados pelo assistente substituem o objeto de configura\u00E7\u00E3o inteiro.\n </div>\n <button mat-icon-button type=\"button\" class=\"help-icon-button\"\n matTooltip=\"O applyConfigFromAdapter n\u00E3o faz merge profundo. Garanta que o adapter envie a config completa.\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </div>\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Recurso (API)</mat-label>\n <input matInput [(ngModel)]=\"working.dataSource.resourcePath\" (ngModelChange)=\"onResourcePathChange($event)\"\n placeholder=\"ex.: users\" />\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\"\n matTooltip=\"Endpoint do recurso (resourcePath).\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Query (JSON)</mat-label>\n <textarea matInput rows=\"3\" [(ngModel)]=\"queryJson\" (ngModelChange)=\"onQueryChanged($event)\"\n placeholder='ex.: &#123;\"status\":\"active\",\"department\":\"sales\"&#125;'></textarea>\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\"\n matTooltip=\"Opcional. Use JSON v\u00E1lido para filtros iniciais.\" *ngIf=\"!queryError\">\n <mat-icon>help_outline</mat-icon>\n </button>\n <mat-error *ngIf=\"queryError\">{{ queryError }}</mat-error>\n </mat-form-field>\n <div class=\"g g-auto-220 gap-12 ai-end mt-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Ordenar por</mat-label>\n <mat-select [(ngModel)]=\"sortField\" (ngModelChange)=\"updateSortConfig()\">\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\" matTooltip=\"Campo base do recurso.\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Dire\u00E7\u00E3o</mat-label>\n <mat-select [(ngModel)]=\"sortDir\" (ngModelChange)=\"updateSortConfig()\">\n <mat-option value=\"asc\">Ascendente</mat-option>\n <mat-option value=\"desc\">Descendente</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"A\u00E7\u00F5es\">\n <div class=\"editor-content g gap-12\">\n <div class=\"g g-1-auto gap-8 ai-center\">\n <div class=\"muted\">Configure bot\u00F5es de a\u00E7\u00E3o por item (\u00EDcone, r\u00F3tulo, cor, visibilidade)</div>\n <button mat-flat-button color=\"primary\" (click)=\"addAction()\">Adicionar a\u00E7\u00E3o</button>\n </div>\n <div class=\"g g-1-auto gap-8 ai-center\">\n <mat-form-field appearance=\"outline\">\n <mat-label>A\u00E7\u00E3o global (Praxis)</mat-label>\n <mat-select [(ngModel)]=\"selectedGlobalActionId\" (ngModelChange)=\"onGlobalActionSelected($event)\">\n <mat-option [value]=\"undefined\">-- Selecionar --</mat-option>\n <mat-option *ngFor=\"let ga of globalActionCatalog\" [value]=\"ga.id\">\n <mat-icon class=\"option-icon\">{{ ga.icon || 'bolt' }}</mat-icon>\n {{ ga.label }}\n </mat-option>\n </mat-select>\n <mat-hint *ngIf=\"!globalActionCatalog.length\" class=\"text-caption muted\">Nenhuma a\u00E7\u00E3o global registrada.</mat-hint>\n </mat-form-field>\n <div class=\"muted text-caption\">Selecione para adicionar com `command` global.</div>\n </div>\n <div *ngFor=\"let a of (working.actions || []); let i = index\" class=\"g g-auto-200 gap-12 ai-end\">\n <mat-form-field appearance=\"outline\">\n <mat-label>ID</mat-label>\n <input matInput [(ngModel)]=\"a.id\" (ngModelChange)=\"onActionsChanged()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo de a\u00E7\u00E3o</mat-label>\n <mat-select [(ngModel)]=\"a.kind\" (ngModelChange)=\"onActionsChanged()\">\n <mat-option value=\"icon\">\u00CDcone</mat-option>\n <mat-option value=\"button\">Bot\u00E3o</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>\u00CDcone</mat-label>\n <input matInput [(ngModel)]=\"a.icon\" (ngModelChange)=\"onActionsChanged()\" placeholder=\"ex.: edit, delete\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Command (global)</mat-label>\n <input matInput [(ngModel)]=\"a.command\" (ngModelChange)=\"onActionsChanged()\" placeholder=\"global:toast.success\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>R\u00F3tulo</mat-label>\n <input matInput [(ngModel)]=\"a.label\" (ngModelChange)=\"onActionsChanged()\" />\n </mat-form-field>\n <ng-container *ngIf=\"a.kind === 'button'\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Variante</mat-label>\n <mat-select [(ngModel)]=\"a.buttonVariant\" (ngModelChange)=\"onActionsChanged()\">\n <mat-option value=\"stroked\">Contorno</mat-option>\n <mat-option value=\"raised\">Elevado</mat-option>\n <mat-option value=\"flat\">Preenchido</mat-option>\n </mat-select>\n </mat-form-field>\n </ng-container>\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor da a\u00E7\u00E3o</mat-label>\n <mat-select [(ngModel)]=\"a.color\" (ngModelChange)=\"onActionsChanged()\">\n <mat-option *ngFor=\"let c of paletteOptions\" [value]=\"c.value\">\n <span class=\"color-dot\" [style.background]=\"colorDotBackground(c.value)\"></span>{{ c.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <div class=\"g gap-8\" *ngIf=\"isCustomColor(a.color); else actionCustomBtn\">\n <pdx-color-picker label=\"Cor personalizada\" [format]=\"'hex'\" [(ngModel)]=\"a.color\"\n (ngModelChange)=\"onActionsChanged()\"></pdx-color-picker>\n </div>\n <ng-template #actionCustomBtn>\n <button mat-stroked-button type=\"button\" (click)=\"enableCustomActionColor(a)\">Usar cor personalizada</button>\n </ng-template>\n <mat-form-field appearance=\"outline\">\n <mat-label>Payload da a\u00E7\u00E3o</mat-label>\n <mat-select [(ngModel)]=\"a.emitPayload\" (ngModelChange)=\"onActionsChanged()\">\n <mat-option [value]=\"undefined\">Padr\u00E3o</mat-option>\n <mat-option value=\"item\">item</mat-option>\n <mat-option value=\"id\">id</mat-option>\n <mat-option value=\"value\">value</mat-option>\n </mat-select>\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\" matTooltip=\"emitPayload\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"col-span-2\">\n <mat-label>Exibir quando (ex.: &#36;&#123;item.status&#125; == 'done')</mat-label>\n <input matInput [(ngModel)]=\"a.showIf\" (ngModelChange)=\"onActionsChanged()\" />\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\"\n matTooltip=\"Sintaxe suportada: &#34;&#36;{item.campo} == &#39;valor&#39;&#34;. Express\u00F5es avan\u00E7adas n\u00E3o s\u00E3o avaliadas.\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <div class=\"g row-flow gap-8 ai-center\">\n <button *ngIf=\"(a.kind || 'icon') === 'icon'\" mat-icon-button\n [color]=\"isThemeColor(a.color) ? a.color : undefined\"><mat-icon\n [praxisIcon]=\"a.icon || 'bolt'\" [style.cssText]=\"iconStyle(a.color)\"></mat-icon></button>\n <ng-container *ngIf=\"a.kind === 'button'\">\n <button *ngIf=\"a.buttonVariant === 'stroked'\" mat-stroked-button\n [color]=\"isThemeColor(a.color) ? a.color : undefined\" [style.cssText]=\"buttonStyle(a.color, 'stroked')\">{{ a.label\n || a.id || 'A\u00E7\u00E3o' }}</button>\n <button *ngIf=\"a.buttonVariant === 'raised'\" mat-raised-button\n [color]=\"isThemeColor(a.color) ? a.color : undefined\" [style.cssText]=\"buttonStyle(a.color, 'raised')\">{{ a.label ||\n a.id || 'A\u00E7\u00E3o' }}</button>\n <button *ngIf=\"!a.buttonVariant || a.buttonVariant === 'flat'\" mat-flat-button\n [color]=\"isThemeColor(a.color) ? a.color : undefined\" [style.cssText]=\"buttonStyle(a.color, 'flat')\">{{ a.label || a.id || 'A\u00E7\u00E3o' }}</button>\n </ng-container>\n <span class=\"muted\">Pr\u00E9-visualiza\u00E7\u00E3o</span>\n </div>\n <div class=\"flex-end\">\n <button mat-button color=\"warn\" (click)=\"removeAction(i)\">Remover</button>\n </div>\n <div class=\"g gap-8 col-span-2\" *ngIf=\"a.command\">\n <mat-slide-toggle [(ngModel)]=\"a.showLoading\" (ngModelChange)=\"onActionsChanged()\">Mostrar loading</mat-slide-toggle>\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header><mat-panel-title>Confirma\u00E7\u00E3o</mat-panel-title></mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <div class=\"g row-flow gap-8 ai-center\">\n <span class=\"text-caption muted\">Tipo</span>\n <mat-button-toggle-group [value]=\"a.confirmation?.type || ''\" (change)=\"applyConfirmationPreset(a, $event.value)\">\n <mat-button-toggle value=\"\">Padr\u00E3o</mat-button-toggle>\n <mat-button-toggle value=\"danger\">Danger</mat-button-toggle>\n <mat-button-toggle value=\"warning\">Warning</mat-button-toggle>\n <mat-button-toggle value=\"info\">Info</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <mat-form-field appearance=\"outline\">\n <mat-label>T\u00EDtulo</mat-label>\n <input matInput [ngModel]=\"a.confirmation?.title\" (ngModelChange)=\"setConfirmationField(a, 'title', $event)\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Mensagem</mat-label>\n <input matInput [ngModel]=\"a.confirmation?.message\" (ngModelChange)=\"setConfirmationField(a, 'message', $event)\" />\n </mat-form-field>\n <div class=\"g gap-6\">\n <div class=\"text-caption muted\">Pr\u00E9via</div>\n <div class=\"text-caption\">\n <strong>{{ a.confirmation?.title || 'Confirmar a\u00E7\u00E3o' }}</strong>\n </div>\n <div class=\"text-caption muted\">{{ a.confirmation?.message || 'Tem certeza que deseja continuar?' }}</div>\n <div class=\"text-caption\">\n <span class=\"confirm-type\" [ngClass]=\"(a.confirmation?.type || 'default')\">Tipo: {{ a.confirmation?.type || 'padr\u00E3o' }}</span>\n </div>\n <div class=\"text-caption muted\" *ngIf=\"!a.confirmation?.title && !a.confirmation?.message\">\n Defina um t\u00EDtulo ou mensagem para a confirma\u00E7\u00E3o.\n </div>\n </div>\n </div>\n </mat-expansion-panel>\n <mat-form-field appearance=\"outline\" class=\"col-span-2\">\n <mat-label>Payload (JSON/Template)</mat-label>\n <textarea matInput rows=\"4\" [(ngModel)]=\"a.globalPayload\" (ngModelChange)=\"onActionsChanged()\"\n placeholder='{\"message\":\"${item.name} favoritado\"}'></textarea>\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\"\n [matTooltip]=\"globalPayloadSchemaTooltip(a)\">\n <mat-icon>help_outline</mat-icon>\n </button>\n <mat-error *ngIf=\"isGlobalPayloadInvalid(a.globalPayload)\">JSON inv\u00E1lido</mat-error>\n </mat-form-field>\n <div class=\"g row-flow gap-8 ai-center\">\n <button mat-stroked-button type=\"button\" (click)=\"applyGlobalPayloadExample(a)\">Inserir exemplo</button>\n <span class=\"muted text-caption\">{{ globalPayloadExampleHint(a) }}</span>\n </div>\n <mat-slide-toggle [(ngModel)]=\"a.emitLocal\" (ngModelChange)=\"onActionsChanged()\">Emitir evento local tamb\u00E9m</mat-slide-toggle>\n </div>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Layout\">\n <div class=\"editor-content grid gap-3\">\n <div class=\"preset-row g row-flow gap-8\">\n <button mat-stroked-button (click)=\"applyLayoutPreset('tiles-modern')\">Preset Tiles Moderno</button>\n </div>\n <mat-form-field appearance=\"outline\">\n <mat-label>Variante</mat-label>\n <mat-select [(ngModel)]=\"working.layout.variant\" (ngModelChange)=\"onLayoutChanged()\">\n <mat-option value=\"list\">Lista</mat-option>\n <mat-option value=\"cards\">Cards</mat-option>\n <mat-option value=\"tiles\">Tiles</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Modelo</mat-label>\n <mat-select [(ngModel)]=\"working.layout.model\" (ngModelChange)=\"onLayoutChanged()\">\n <ng-container *ngIf=\"working.layout.variant === 'list'; else cardModels\">\n <mat-option value=\"standard\">Padr\u00E3o</mat-option>\n <mat-option value=\"media\">M\u00EDdia \u00E0 esquerda</mat-option>\n <mat-option value=\"hotel\">Hotel (m\u00EDdia grande)</mat-option>\n </ng-container>\n <ng-template #cardModels>\n <ng-container *ngIf=\"working.layout.variant === 'tiles'; else cardsOnly\">\n <mat-option value=\"standard\">Tile padr\u00E3o</mat-option>\n <mat-option value=\"media\">Tile com m\u00EDdia</mat-option>\n <mat-option value=\"hotel\">Tile hotel</mat-option>\n </ng-container>\n <ng-template #cardsOnly>\n <mat-option value=\"standard\">Padr\u00E3o</mat-option>\n <mat-option value=\"media\">Card com m\u00EDdia</mat-option>\n <mat-option value=\"hotel\">Hotel</mat-option>\n </ng-template>\n </ng-template>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Linhas</mat-label>\n <mat-select [(ngModel)]=\"working.layout.lines\" (ngModelChange)=\"onLayoutChanged()\">\n <mat-option [value]=\"1\">1</mat-option>\n <mat-option [value]=\"2\">2</mat-option>\n <mat-option [value]=\"3\">3</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Itens por p\u00E1gina</mat-label>\n <input matInput type=\"number\" min=\"1\" [(ngModel)]=\"working.layout.pageSize\"\n (ngModelChange)=\"onPageSizeChange($event)\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Densidade</mat-label>\n <mat-select [(ngModel)]=\"working.layout.density\" (ngModelChange)=\"onLayoutChanged()\">\n <mat-option value=\"default\">Padr\u00E3o</mat-option>\n <mat-option value=\"comfortable\">Confort\u00E1vel</mat-option>\n <mat-option value=\"compact\">Compacta</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" *ngIf=\"working.layout.variant !== 'tiles'\">\n <mat-label>Divisores</mat-label>\n <mat-select [(ngModel)]=\"working.layout.dividers\" (ngModelChange)=\"onLayoutChanged()\">\n <mat-option value=\"none\">Sem</mat-option>\n <mat-option value=\"between\">Entre grupos</mat-option>\n <mat-option value=\"all\">Todos</mat-option>\n </mat-select>\n </mat-form-field>\n <ng-container *ngIf=\"fields.length > 0; else groupByText\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Agrupar por</mat-label>\n <mat-select [(ngModel)]=\"working.layout.groupBy\" (ngModelChange)=\"onLayoutChanged()\">\n <mat-option [value]=\"\">Nenhum</mat-option>\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n </ng-container>\n <ng-template #groupByText>\n <mat-form-field appearance=\"outline\">\n <mat-label>Agrupar por</mat-label>\n <input matInput [(ngModel)]=\"working.layout.groupBy\" (ngModelChange)=\"onLayoutChanged()\"\n placeholder=\"ex.: departamento\" />\n </mat-form-field>\n </ng-template>\n <mat-slide-toggle [(ngModel)]=\"working.layout.stickySectionHeader\" (ngModelChange)=\"onLayoutChanged()\">\n Header de se\u00E7\u00E3o fixo\n </mat-slide-toggle>\n <mat-slide-toggle [(ngModel)]=\"working.layout.virtualScroll\" (ngModelChange)=\"onLayoutChanged()\">\n Scroll virtual\n </mat-slide-toggle>\n <mat-divider class=\"my-8\"></mat-divider>\n <div class=\"subtitle\">Ferramentas da lista</div>\n <div class=\"g g-auto-220 gap-12 ai-end\">\n <mat-slide-toggle [(ngModel)]=\"working.ui.showSearch\" (ngModelChange)=\"onUiChanged()\">Mostrar\n busca</mat-slide-toggle>\n <mat-slide-toggle [(ngModel)]=\"working.ui.showSort\" (ngModelChange)=\"onUiChanged()\">Mostrar\n ordenar</mat-slide-toggle>\n <mat-slide-toggle [(ngModel)]=\"working.ui.showRange\" (ngModelChange)=\"onUiChanged()\">Mostrar faixa X\u2013Y de\n Total</mat-slide-toggle>\n </div>\n <div class=\"g g-auto-220 gap-12 ai-end mt-12\" *ngIf=\"working.ui?.showSearch\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Campo para buscar</mat-label>\n <mat-select [(ngModel)]=\"working.ui.searchField\" (ngModelChange)=\"onUiChanged()\">\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Placeholder da busca</mat-label>\n <input matInput [(ngModel)]=\"working.ui.searchPlaceholder\" (ngModelChange)=\"onUiChanged()\"\n placeholder=\"ex.: Buscar por t\u00EDtulo\" />\n </mat-form-field>\n </div>\n <div class=\"mt-12\" *ngIf=\"working.ui?.showSort\">\n <div class=\"g g-1-auto ai-center gap-8\">\n <div class=\"muted\">Op\u00E7\u00F5es de ordena\u00E7\u00E3o (r\u00F3tulo \u2192 campo+dire\u00E7\u00E3o)</div>\n <button mat-flat-button color=\"primary\" (click)=\"addUiSortRow()\">Adicionar op\u00E7\u00E3o</button>\n </div>\n <div class=\"g g-auto-220 gap-12 ai-end mt-12\" *ngFor=\"let r of uiSortRows; let i = index\">\n <mat-form-field appearance=\"outline\">\n <mat-label>R\u00F3tulo</mat-label>\n <input matInput [(ngModel)]=\"r.label\" (ngModelChange)=\"onUiSortRowsChanged()\"\n placeholder=\"ex.: Mais recentes\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Campo</mat-label>\n <mat-select [(ngModel)]=\"r.field\" (ngModelChange)=\"onUiSortRowsChanged()\">\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Dire\u00E7\u00E3o</mat-label>\n <mat-select [(ngModel)]=\"r.dir\" (ngModelChange)=\"onUiSortRowsChanged()\">\n <mat-option value=\"desc\">Descendente</mat-option>\n <mat-option value=\"asc\">Ascendente</mat-option>\n </mat-select>\n </mat-form-field>\n <div class=\"error\" *ngIf=\"isUiSortRowDuplicate(i)\">Op\u00E7\u00E3o duplicada (campo+dire\u00E7\u00E3o)</div>\n <div class=\"flex-end\"><button mat-button color=\"warn\" (click)=\"removeUiSortRow(i)\">Remover</button></div>\n </div>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Conte\u00FAdo\">\n <div class=\"editor-content\">\n <div class=\"editor-main\">\n <mat-accordion multi>\n <!-- Primary -->\n <mat-expansion-panel [expanded]=\"true\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>{{ getTypeIcon(mappingPrimary.type) }}</mat-icon>\n <span>Primary (T\u00EDtulo)</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>{{ mappingPrimary.field || 'N\u00E3o mapeado' }}</mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"g gap-12\">\n <div class=\"g row-flow gap-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"mappingPrimary.type='text'; mappingPrimary.field='name'; onMappingChanged()\">Nome</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingPrimary.type='text'; mappingPrimary.field='title'; onMappingChanged()\">T\u00EDtulo</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingPrimary.type='text'; mappingPrimary.field='name'; mappingSecondary.type='text'; mappingSecondary.field='role'; onMappingChanged()\">Nome + Papel</button>\n </div>\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Campo</mat-label>\n <mat-select [(ngModel)]=\"mappingPrimary.field\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [(ngModel)]=\"mappingPrimary.type\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let mt of primaryTypeConfigs\" [value]=\"mt.type\">\n <mat-icon class=\"option-icon\">{{ mt.icon }}</mat-icon>\n {{ mt.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n @switch (mappingPrimary.type) {\n @case ('text') { <praxis-meta-editor-text [model]=\"mappingPrimary\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('html') { <praxis-meta-editor-text [model]=\"mappingPrimary\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('currency') { <praxis-meta-editor-currency [model]=\"mappingPrimary\" (change)=\"onMappingChanged()\"></praxis-meta-editor-currency> }\n @case ('date') { <praxis-meta-editor-date [model]=\"mappingPrimary\" (change)=\"onMappingChanged()\"></praxis-meta-editor-date> }\n }\n\n <!-- Advanced -->\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header>\n <mat-panel-title>Formata\u00E7\u00E3o e Estilo</mat-panel-title>\n </mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <mat-form-field appearance=\"outline\" *ngIf=\"mappingPrimary.type==='text' || mappingPrimary.type==='html'\">\n <mat-label>Classe CSS</mat-label>\n <input matInput [(ngModel)]=\"mappingPrimary.class\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" *ngIf=\"mappingPrimary.type==='text' || mappingPrimary.type==='html'\">\n <mat-label>Estilo Inline</mat-label>\n <input matInput [(ngModel)]=\"mappingPrimary.style\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Classe CSS</mat-label>\n <input matInput [(ngModel)]=\"mappingPrimary.class\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Estilo Inline</mat-label>\n <input matInput [(ngModel)]=\"mappingPrimary.style\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n </div>\n </div>\n </mat-expansion-panel>\n </div>\n </mat-expansion-panel>\n\n <!-- Secondary -->\n <mat-expansion-panel [expanded]=\"!!mappingSecondary.field\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>{{ getTypeIcon(mappingSecondary.type) }}</mat-icon>\n <span>Secondary (Resumo)</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>{{ mappingSecondary.field || 'N\u00E3o mapeado' }}</mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"g gap-12\">\n <div class=\"g row-flow gap-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"mappingSecondary.type='text'; mappingSecondary.field='subtitle'; onMappingChanged()\">Subt\u00EDtulo</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingSecondary.type='date'; mappingSecondary.field='hireDate'; mappingSecondary.dateStyle='short'; onMappingChanged()\">Data curta</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingSecondary.type='currency'; mappingSecondary.field='salary'; mappingSecondary.currencyCode='BRL'; mappingSecondary.locale='pt-BR'; onMappingChanged()\">Sal\u00E1rio</button>\n </div>\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Campo</mat-label>\n <mat-select [(ngModel)]=\"mappingSecondary.field\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [(ngModel)]=\"mappingSecondary.type\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let mt of secondaryTypeConfigs\" [value]=\"mt.type\">\n <mat-icon class=\"option-icon\">{{ mt.icon }}</mat-icon>\n {{ mt.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n @switch (mappingSecondary.type) {\n @case ('text') { <praxis-meta-editor-text [model]=\"mappingSecondary\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('html') { <praxis-meta-editor-text [model]=\"mappingSecondary\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('currency') { <praxis-meta-editor-currency [model]=\"mappingSecondary\" (change)=\"onMappingChanged()\"></praxis-meta-editor-currency> }\n @case ('date') { <praxis-meta-editor-date [model]=\"mappingSecondary\" (change)=\"onMappingChanged()\"></praxis-meta-editor-date> }\n }\n\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header>\n <mat-panel-title>Formata\u00E7\u00E3o e Estilo</mat-panel-title>\n </mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\"><mat-label>Classe CSS</mat-label><input matInput\n [(ngModel)]=\"mappingSecondary.class\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Estilo Inline</mat-label><input matInput\n [(ngModel)]=\"mappingSecondary.style\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n </div>\n </div>\n </mat-expansion-panel>\n </div>\n </mat-expansion-panel>\n\n <mat-expansion-panel [expanded]=\"!!mappingMeta.field || mappingMetaFields.length > 0\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>{{ getTypeIcon(mappingMeta.type || 'text') }}</mat-icon>\n <span>Meta (Detalhe/Lateral)</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>\n {{ mappingMetaFields.length ? 'Campo composto (' + mappingMetaFields.length + ')' :\n (mappingMeta.field || 'N\u00E3o mapeado') }}\n </mat-panel-description>\n </mat-expansion-panel-header>\n\n <div class=\"g gap-12\">\n <!-- Composition Mode Toggle -->\n <div class=\"g g-1-1 gap-12 p-12 bg-subtle rounded\">\n <div class=\"text-caption muted\">Modo de composi\u00E7\u00E3o</div>\n <mat-form-field appearance=\"outline\">\n <mat-label>Campos para compor (Multi-select)</mat-label>\n <mat-select [(ngModel)]=\"mappingMetaFields\" multiple (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n <div class=\"g g-1-1 ai-center gap-12\" *ngIf=\"mappingMetaFields.length\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Separador</mat-label>\n <input matInput [(ngModel)]=\"mappingMetaSeparator\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n <mat-slide-toggle [(ngModel)]=\"mappingMetaWrapSecondInParens\" (ngModelChange)=\"onMappingChanged()\">\n (Seg) entre par\u00EAnteses\n </mat-slide-toggle>\n </div>\n </div>\n\n <!-- Single Field Mode (if no composition) -->\n <div class=\"g g-1-1 gap-12\" *ngIf=\"!mappingMetaFields.length\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Campo \u00DAnico</mat-label>\n <mat-select [(ngModel)]=\"mappingMeta.field\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option [value]=\"undefined\">-- Nenhum --</mat-option>\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [(ngModel)]=\"mappingMeta.type\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let mt of metaTypeConfigs\" [value]=\"mt.type\">\n <mat-icon class=\"option-icon\">{{ mt.icon }}</mat-icon>\n {{ mt.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- Type configuration (pluggable editors) -->\n @switch (mappingMeta.type) {\n @case ('text') { <praxis-meta-editor-text [model]=\"mappingMeta\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('html') { <praxis-meta-editor-text [model]=\"mappingMeta\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('currency') { <praxis-meta-editor-currency [model]=\"mappingMeta\" (change)=\"onMappingChanged()\"></praxis-meta-editor-currency> }\n @case ('date') { <praxis-meta-editor-date [model]=\"mappingMeta\" (change)=\"onMappingChanged()\"></praxis-meta-editor-date> }\n @case ('chip') {\n <praxis-meta-editor-chip\n [model]=\"mappingMeta\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-chip>\n }\n @case ('rating') {\n <praxis-meta-editor-rating\n [model]=\"mappingMeta\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-rating>\n }\n @case ('icon') {\n <praxis-meta-editor-icon\n [model]=\"mappingMeta\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-icon>\n }\n @case ('image') { <praxis-meta-editor-image [model]=\"mappingMeta\" (change)=\"onMappingChanged()\"></praxis-meta-editor-image> }\n }\n\n <!-- Advanced -->\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header><mat-panel-title>Op\u00E7\u00F5es\n avan\u00E7adas</mat-panel-title></mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Posi\u00E7\u00E3o</mat-label>\n <mat-select [(ngModel)]=\"mappingMeta.placement\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option value=\"side\">Lateral (Direita)</mat-option>\n <mat-option value=\"line\">Na linha (Abaixo)</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Classe CSS</mat-label>\n <input matInput [(ngModel)]=\"mappingMeta.class\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Estilo</mat-label>\n <input matInput [(ngModel)]=\"mappingMeta.style\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n </div>\n </mat-expansion-panel>\n </div>\n </mat-expansion-panel>\n <!-- Trailing -->\n <mat-expansion-panel [expanded]=\"!!mappingTrailing.field\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>{{ getTypeIcon(mappingTrailing.type || 'text') }}</mat-icon>\n <span>Trailing (Direita)</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>{{ mappingTrailing.field || 'N\u00E3o mapeado'\n }}</mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"g gap-12\">\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Campo</mat-label>\n <mat-select [(ngModel)]=\"mappingTrailing.field\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option [value]=\"undefined\">-- Nenhum --</mat-option>\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [(ngModel)]=\"mappingTrailing.type\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let mt of trailingTypeConfigs\" [value]=\"mt.type\">\n <mat-icon class=\"option-icon\">{{ mt.icon }}</mat-icon>\n {{ mt.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"g row-flow gap-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"mappingTrailing.type='chip'; mappingTrailing.chipColor='primary'; mappingTrailing.chipVariant='filled'; mappingTrailing.field='status'; onMappingChanged()\">Status Chip</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingTrailing.type='icon'; mappingTrailing.field='status'; mappingTrailing.iconColor='primary'; onMappingChanged()\">Status \u00CDcone</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingTrailing.type='currency'; mappingTrailing.field='price'; mappingTrailing.currencyCode='BRL'; mappingTrailing.locale='pt-BR'; onMappingChanged()\">Pre\u00E7o</button>\n </div>\n\n @switch (mappingTrailing.type) {\n @case ('text') { <praxis-meta-editor-text [model]=\"mappingTrailing\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('html') { <praxis-meta-editor-text [model]=\"mappingTrailing\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('currency') { <praxis-meta-editor-currency [model]=\"mappingTrailing\" (change)=\"onMappingChanged()\"></praxis-meta-editor-currency> }\n @case ('date') { <praxis-meta-editor-date [model]=\"mappingTrailing\" (change)=\"onMappingChanged()\"></praxis-meta-editor-date> }\n @case ('chip') {\n <praxis-meta-editor-chip\n [model]=\"mappingTrailing\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-chip>\n }\n @case ('rating') {\n <praxis-meta-editor-rating\n [model]=\"mappingTrailing\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-rating>\n }\n @case ('icon') {\n <praxis-meta-editor-icon\n [model]=\"mappingTrailing\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-icon>\n }\n @case ('image') {\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>URL / Expr</mat-label>\n <input matInput [(ngModel)]=\"mappingTrailing.imageUrl\" (ngModelChange)=\"onMappingChanged()\"\n placeholder=\"https://... ou ${item.imageUrl}\" />\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\"\n matTooltip=\"Use URL absoluta/relativa ou express\u00E3o ${item.campo}.\">\n <mat-icon>help_outline</mat-icon>\n </button>\n <mat-error *ngIf=\"isImageUrlRequiredInvalid(mappingTrailing.imageUrl)\">URL/expr obrigat\u00F3ria</mat-error>\n </mat-form-field>\n </div>\n <praxis-meta-editor-image [model]=\"mappingTrailing\" (change)=\"onMappingChanged()\"></praxis-meta-editor-image>\n <div class=\"text-caption muted\" *ngIf=\"!mappingTrailing.imageUrl\">Defina a URL/expr para renderizar a imagem.</div>\n }\n }\n\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header><mat-panel-title>Estilo</mat-panel-title></mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\"><mat-label>Classe</mat-label><input matInput\n [(ngModel)]=\"mappingTrailing.class\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Style</mat-label><input matInput\n [(ngModel)]=\"mappingTrailing.style\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n </div>\n </div>\n </mat-expansion-panel>\n </div>\n </mat-expansion-panel>\n\n <!-- Leading -->\n <mat-expansion-panel\n [expanded]=\"!!mappingLeading.field || (mappingLeading.type === 'icon' && !!mappingLeading.icon) || (mappingLeading.type === 'image' && !!mappingLeading.imageUrl)\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>{{ getTypeIcon(mappingLeading.type) }}</mat-icon>\n <span>Leading (Esquerda)</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>\n {{ mappingLeading.type === 'icon' ? (mappingLeading.icon || '\u00CDcone est\u00E1tico') :\n (mappingLeading.field || (mappingLeading.imageUrl ? 'Imagem est\u00E1tica' : 'N\u00E3o mapeado'))\n }}\n </mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"g gap-12\">\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [(ngModel)]=\"mappingLeading.type\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let mt of leadingTypeConfigs\" [value]=\"mt.type\">\n <mat-icon class=\"option-icon\">{{ mt.icon }}</mat-icon>\n {{ mt.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <!-- Field (only if not static icon/image, though user might want dynamic) -->\n <mat-form-field appearance=\"outline\"\n *ngIf=\"mappingLeading.type !== 'icon' && mappingLeading.type !== 'image'\">\n <mat-label>Campo</mat-label>\n <mat-select [(ngModel)]=\"mappingLeading.field\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"g row-flow gap-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"mappingLeading.type='icon'; mappingLeading.icon='person'; mappingLeading.iconColor='primary'; onMappingChanged()\">Avatar \u00CDcone</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingLeading.type='image'; mappingLeading.imageUrl='https://placehold.co/64x64'; mappingLeading.imageAlt='Avatar'; mappingLeading.badgeText='${item.status}'; onMappingChanged()\">Avatar Imagem + Badge</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingLeading.type='chip'; mappingLeading.field='tag'; mappingLeading.chipColor='accent'; mappingLeading.chipVariant='filled'; onMappingChanged()\">Chip Tag</button>\n </div>\n\n <!-- Icon Specific -->\n <div class=\"g g-1-auto gap-12 ai-center\" *ngIf=\"mappingLeading.type === 'icon'\">\n <mat-form-field appearance=\"outline\">\n <mat-label>\u00CDcone</mat-label>\n <input matInput [(ngModel)]=\"mappingLeading.icon\" (ngModelChange)=\"onMappingChanged()\" />\n <button mat-icon-button matSuffix (click)=\"pickLeadingIcon()\"><mat-icon>search</mat-icon></button>\n </mat-form-field>\n <div class=\"text-caption muted\">Use pipe <code>|iconMap</code> no extra pipe para\n din\u00E2mico</div>\n </div>\n <div *ngIf=\"mappingLeading.type === 'icon'\">\n <praxis-meta-editor-icon\n [model]=\"mappingLeading\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-icon>\n </div>\n\n <!-- Image Specific -->\n <div class=\"g g-1-1 gap-12\" *ngIf=\"mappingLeading.type === 'image'\">\n <mat-form-field appearance=\"outline\">\n <mat-label>URL da Imagem</mat-label>\n <input matInput [(ngModel)]=\"mappingLeading.imageUrl\" (ngModelChange)=\"onMappingChanged()\"\n placeholder=\"https://... ou ${item.imageUrl}\" />\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\"\n matTooltip=\"Use URL absoluta/relativa ou express\u00E3o ${item.campo}.\">\n <mat-icon>help_outline</mat-icon>\n </button>\n <mat-error *ngIf=\"isImageUrlRequiredInvalid(mappingLeading.imageUrl)\">URL/expr obrigat\u00F3ria</mat-error>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Alt Text</mat-label>\n <input matInput [(ngModel)]=\"mappingLeading.imageAlt\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Badge Texto</mat-label>\n <input matInput [(ngModel)]=\"mappingLeading.badgeText\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n </div>\n\n @switch (mappingLeading.type) {\n @case ('text') { <praxis-meta-editor-text [model]=\"mappingLeading\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('html') { <praxis-meta-editor-text [model]=\"mappingLeading\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('chip') {\n <praxis-meta-editor-chip\n [model]=\"mappingLeading\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-chip>\n }\n @case ('rating') {\n <praxis-meta-editor-rating\n [model]=\"mappingLeading\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-rating>\n }\n }\n\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header><mat-panel-title>Estilo</mat-panel-title></mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <mat-form-field appearance=\"outline\"><mat-label>Classe</mat-label><input matInput\n [(ngModel)]=\"mappingLeading.class\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Style</mat-label><input matInput\n [(ngModel)]=\"mappingLeading.style\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n </div>\n </mat-expansion-panel>\n </div>\n </mat-expansion-panel>\n\n <!-- Features -->\n <mat-expansion-panel [expanded]=\"featuresVisible && features.length > 0\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>view_list</mat-icon>\n <span>Recursos (Features)</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>{{ features.length }} item(s)</mat-panel-description>\n </mat-expansion-panel-header>\n\n <div class=\"g gap-12\">\n <div class=\"g row-flow gap-12 ai-center\">\n <mat-slide-toggle [(ngModel)]=\"featuresVisible\" (ngModelChange)=\"onFeaturesChanged()\">Ativar\n recursos</mat-slide-toggle>\n <mat-slide-toggle [(ngModel)]=\"featuresSyncWithMeta\" (ngModelChange)=\"onMappingChanged()\">Sincronizar\n com Meta</mat-slide-toggle>\n <span class=\"flex-1\"></span>\n <mat-button-toggle-group [(ngModel)]=\"featuresMode\" (change)=\"onFeaturesChanged()\" appearance=\"legacy\">\n <mat-button-toggle value=\"icons+labels\"><mat-icon>view_list</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"icons-only\"><mat-icon>more_horiz</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div *ngFor=\"let f of features; let i = index\" class=\"g g-auto-1 gap-8 ai-center p-8 border rounded mb-2\">\n <button mat-icon-button (click)=\"pickFeatureIcon(i)\"><mat-icon>{{ f.icon || 'search'\n }}</mat-icon></button>\n <mat-form-field appearance=\"outline\" class=\"dense-form-field no-sub\">\n <input matInput [(ngModel)]=\"f.expr\" (ngModelChange)=\"onFeaturesChanged()\" placeholder=\"Expr/Texto\" />\n </mat-form-field>\n <button mat-icon-button color=\"warn\" (click)=\"removeFeature(i)\"><mat-icon>delete</mat-icon></button>\n </div>\n <button mat-button color=\"primary\" (click)=\"addFeature()\"><mat-icon>add</mat-icon>\n Adicionar recurso</button>\n </div>\n </mat-expansion-panel>\n <!-- Section Header -->\n <mat-expansion-panel [expanded]=\"!!mappingSectionHeader.expr\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>{{ getTypeIcon(mappingSectionHeader.type) }}</mat-icon>\n <span>Cabe\u00E7alho de Se\u00E7\u00E3o</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>{{ mappingSectionHeader.expr || 'N\u00E3o configurado'\n }}</mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"g gap-12\">\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [(ngModel)]=\"mappingSectionHeader.type\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let mt of sectionHeaderTypeConfigs\" [value]=\"mt.type\">\n <mat-icon class=\"option-icon\">{{ mt.icon }}</mat-icon>\n {{ mt.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Express\u00E3o (item.key)</mat-label>\n <input matInput [(ngModel)]=\"mappingSectionHeader.expr\" (ngModelChange)=\"onMappingChanged()\"\n placeholder=\"item.key\" />\n </mat-form-field>\n </div>\n <div class=\"g row-flow gap-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"mappingSectionHeader.type='text'; mappingSectionHeader.expr='${item.key}'; onMappingChanged()\">Texto padr\u00E3o</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingSectionHeader.type='chip'; mappingSectionHeader.chipColor='primary'; mappingSectionHeader.chipVariant='filled'; mappingSectionHeader.expr='${item.key}'; onMappingChanged()\">Chip padr\u00E3o</button>\n </div>\n\n @switch (mappingSectionHeader.type) {\n @case ('text') { <praxis-meta-editor-text [model]=\"mappingSectionHeader\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('html') { <praxis-meta-editor-text [model]=\"mappingSectionHeader\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('chip') {\n <praxis-meta-editor-chip\n [model]=\"mappingSectionHeader\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-chip>\n }\n @case ('rating') {\n <praxis-meta-editor-rating\n [model]=\"mappingSectionHeader\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-rating>\n }\n @case ('icon') {\n <praxis-meta-editor-icon\n [model]=\"mappingSectionHeader\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-icon>\n }\n @case ('image') {\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>URL Imagem</mat-label>\n <input matInput [(ngModel)]=\"mappingSectionHeader.imageUrl\" (ngModelChange)=\"onMappingChanged()\" />\n <mat-error *ngIf=\"isImageUrlRequiredInvalid(mappingSectionHeader.imageUrl)\">URL/expr obrigat\u00F3ria</mat-error>\n </mat-form-field>\n </div>\n <div class=\"text-caption muted\" *ngIf=\"!mappingSectionHeader.imageUrl\">Defina a URL/expr para renderizar a imagem.</div>\n <praxis-meta-editor-image [model]=\"mappingSectionHeader\" (change)=\"onMappingChanged()\"></praxis-meta-editor-image>\n }\n }\n\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header><mat-panel-title>Estilo</mat-panel-title></mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <mat-form-field appearance=\"outline\"><mat-label>Classe</mat-label><input matInput\n [(ngModel)]=\"mappingSectionHeader.class\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Style</mat-label><input matInput\n [(ngModel)]=\"mappingSectionHeader.style\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n </div>\n </mat-expansion-panel>\n </div>\n </mat-expansion-panel>\n\n <!-- Empty State -->\n <mat-expansion-panel [expanded]=\"!!mappingEmptyState.expr\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>inbox</mat-icon>\n <span>Estado Vazio</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>{{ mappingEmptyState.expr || 'Padr\u00E3o' }}</mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"g gap-12\">\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [(ngModel)]=\"mappingEmptyState.type\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let mt of emptyStateTypeConfigs\" [value]=\"mt.type\">\n <mat-icon class=\"option-icon\">{{ mt.icon }}</mat-icon>\n {{ mt.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Mensagem / Expr</mat-label>\n <input matInput [(ngModel)]=\"mappingEmptyState.expr\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n </div>\n <div class=\"g row-flow gap-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"mappingEmptyState.type='text'; mappingEmptyState.expr='Nenhum item dispon\u00EDvel'; onMappingChanged()\">Mensagem padr\u00E3o</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingEmptyState.type='image'; mappingEmptyState.imageUrl='/list-empty-state.svg'; mappingEmptyState.imageAlt='Sem resultados'; onMappingChanged()\">Imagem padr\u00E3o</button>\n </div>\n\n @switch (mappingEmptyState.type) {\n @case ('text') { <praxis-meta-editor-text [model]=\"mappingEmptyState\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('html') { <praxis-meta-editor-text [model]=\"mappingEmptyState\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('chip') {\n <praxis-meta-editor-chip\n [model]=\"mappingEmptyState\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-chip>\n }\n @case ('rating') {\n <praxis-meta-editor-rating\n [model]=\"mappingEmptyState\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-rating>\n }\n @case ('icon') {\n <praxis-meta-editor-icon\n [model]=\"mappingEmptyState\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-icon>\n }\n @case ('image') {\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\"><mat-label>URL Imagem</mat-label><input matInput\n [(ngModel)]=\"mappingEmptyState.imageUrl\" (ngModelChange)=\"onMappingChanged()\" />\n <mat-error *ngIf=\"isImageUrlRequiredInvalid(mappingEmptyState.imageUrl)\">URL/expr obrigat\u00F3ria</mat-error>\n </mat-form-field>\n </div>\n <div class=\"text-caption muted\" *ngIf=\"!mappingEmptyState.imageUrl\">Defina a URL/expr para renderizar a imagem.</div>\n <praxis-meta-editor-image [model]=\"mappingEmptyState\" (change)=\"onMappingChanged()\"></praxis-meta-editor-image>\n }\n }\n\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header><mat-panel-title>Estilo</mat-panel-title></mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <mat-form-field appearance=\"outline\"><mat-label>Classe</mat-label><input matInput\n [(ngModel)]=\"mappingEmptyState.class\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Style</mat-label><input matInput\n [(ngModel)]=\"mappingEmptyState.style\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n </div>\n </mat-expansion-panel>\n </div>\n </mat-expansion-panel>\n </mat-accordion>\n\n <button mat-flat-button color=\"primary\" (click)=\"applyTemplate()\">Aplicar mapeamento</button>\n <button mat-button (click)=\"inferFromFields()\" [disabled]=\"!fields.length\">Inferir do schema</button>\n <div class=\"g g-auto-220 gap-12 ai-end mt-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Skeleton (quantidade)</mat-label>\n <input matInput type=\"number\" min=\"0\" [(ngModel)]=\"skeletonCountInput\"\n (ngModelChange)=\"onSkeletonChanged($event)\" />\n </mat-form-field>\n </div>\n\n <div class=\"g gap-12 mt-12\">\n <div class=\"g row-flow gap-8 ai-center\">\n <span class=\"section-title mat-subtitle-1\">Pr\u00E9via de tema</span>\n <mat-button-toggle-group [(ngModel)]=\"skinPreviewTheme\" (change)=\"onSkinChanged()\" appearance=\"legacy\">\n <mat-button-toggle [value]=\"'light'\">Claro</mat-button-toggle>\n <mat-button-toggle [value]=\"'dark'\">Escuro</mat-button-toggle>\n <mat-button-toggle [value]=\"'grid'\">Grade</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"skin-preview-wrap\">\n <praxis-list-skin-preview [config]=\"working\" [items]=\"previewData\"\n [theme]=\"skinPreviewTheme\"></praxis-list-skin-preview>\n </div>\n </div>\n </div>\n </div>\n\n </mat-tab>\n <mat-tab label=\"i18n/A11y\">\n <div class=\"editor-content grid gap-3\" *ngIf=\"working?.a11y && working?.events\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Locale padr\u00E3o</mat-label>\n <input matInput [(ngModel)]=\"working.i18n.locale\" (ngModelChange)=\"markDirty()\" placeholder=\"ex.: pt-BR\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Moeda padr\u00E3o</mat-label>\n <input matInput [(ngModel)]=\"working.i18n.currency\" (ngModelChange)=\"markDirty()\" placeholder=\"ex.: BRL\" />\n </mat-form-field>\n <mat-divider class=\"my-8\"></mat-divider>\n <div class=\"subtitle\">Acessibilidade</div>\n <div class=\"g g-auto-220 gap-12 ai-end\">\n <mat-form-field appearance=\"outline\">\n <mat-label>aria-label</mat-label>\n <input matInput [(ngModel)]=\"working!.a11y!.ariaLabel\" (ngModelChange)=\"markDirty()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>aria-labelledby</mat-label>\n <input matInput [(ngModel)]=\"working!.a11y!.ariaLabelledBy\" (ngModelChange)=\"markDirty()\" />\n </mat-form-field>\n </div>\n <div class=\"g g-auto-220 gap-12 ai-end\">\n <mat-slide-toggle [(ngModel)]=\"working!.a11y!.highContrast\" (ngModelChange)=\"markDirty()\">Alto\n contraste</mat-slide-toggle>\n <mat-slide-toggle [(ngModel)]=\"working!.a11y!.reduceMotion\" (ngModelChange)=\"markDirty()\">Reduzir\n movimento</mat-slide-toggle>\n </div>\n <mat-divider class=\"my-8\"></mat-divider>\n <div class=\"subtitle\">Eventos</div>\n <div class=\"g g-auto-220 gap-12 ai-end\">\n <mat-form-field appearance=\"outline\">\n <mat-label>itemClick</mat-label>\n <input matInput [(ngModel)]=\"working!.events!.itemClick\" (ngModelChange)=\"markDirty()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>actionClick</mat-label>\n <input matInput [(ngModel)]=\"working!.events!.actionClick\" (ngModelChange)=\"markDirty()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>selectionChange</mat-label>\n <input matInput [(ngModel)]=\"working!.events!.selectionChange\" (ngModelChange)=\"markDirty()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>loaded</mat-label>\n <input matInput [(ngModel)]=\"working!.events!.loaded\" (ngModelChange)=\"markDirty()\" />\n </mat-form-field>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Sele\u00E7\u00E3o\">\n <div class=\"editor-content grid gap-3\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Modo</mat-label>\n <mat-select [(ngModel)]=\"working.selection.mode\" (ngModelChange)=\"onSelectionChanged()\">\n <mat-option value=\"none\">Sem sele\u00E7\u00E3o</mat-option>\n <mat-option value=\"single\">\u00DAnica</mat-option>\n <mat-option value=\"multiple\">M\u00FAltipla</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Nome no formul\u00E1rio</mat-label>\n <input matInput [(ngModel)]=\"working.selection.formControlName\" (ngModelChange)=\"onSelectionChanged()\" />\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\" matTooltip=\"formControlName\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Caminho no formul\u00E1rio</mat-label>\n <input matInput [(ngModel)]=\"working.selection.formControlPath\" (ngModelChange)=\"onSelectionChanged()\" />\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\" matTooltip=\"formControlPath\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Comparar por (campo)</mat-label>\n <input matInput [(ngModel)]=\"working.selection.compareBy\" (ngModelChange)=\"onSelectionChanged()\" />\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\" matTooltip=\"Chave unica do item.\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Retorno</mat-label>\n <mat-select [(ngModel)]=\"working.selection.return\" (ngModelChange)=\"onSelectionChanged()\">\n <mat-option value=\"value\">value</mat-option>\n <mat-option value=\"item\">item</mat-option>\n <mat-option value=\"id\">id</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </mat-tab>\n <mat-tab label=\"Apar\u00EAncia\">\n <div class=\"editor-content grid gap-3\">\n <div class=\"preset-row g row-flow gap-8\">\n <button mat-button (click)=\"applySkinPreset('pill-soft')\">Pill Soft</button>\n <button mat-button (click)=\"applySkinPreset('gradient-tile')\">Gradient Tile</button>\n <button mat-button (click)=\"applySkinPreset('glass')\">Glass</button>\n <button mat-button (click)=\"applySkinPreset('elevated')\">Elevated</button>\n <button mat-button (click)=\"applySkinPreset('outline')\">Outline</button>\n <button mat-button (click)=\"applySkinPreset('flat')\">Flat</button>\n <button mat-button (click)=\"applySkinPreset('neumorphism')\">Neumorphism</button>\n </div>\n <mat-form-field appearance=\"outline\">\n <mat-label>Estilo</mat-label>\n <mat-select [(ngModel)]=\"working.skin.type\" (ngModelChange)=\"onSkinTypeChanged($event)\">\n <mat-option value=\"pill-soft\">Pill Soft</mat-option>\n <mat-option value=\"gradient-tile\">Gradient Tile</mat-option>\n <mat-option value=\"glass\">Glass</mat-option>\n <mat-option value=\"elevated\">Elevated</mat-option>\n <mat-option value=\"outline\">Outline</mat-option>\n <mat-option value=\"flat\">Flat</mat-option>\n <mat-option value=\"neumorphism\">Neumorphism</mat-option>\n <mat-option value=\"custom\">Custom</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Raio</mat-label>\n <input matInput [(ngModel)]=\"working.skin.radius\" (ngModelChange)=\"onSkinChanged()\"\n placeholder=\"ex.: 1.25rem\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Sombra</mat-label>\n <input matInput [(ngModel)]=\"working.skin.shadow\" (ngModelChange)=\"onSkinChanged()\"\n placeholder=\"ex.: var(--md-sys-elevation-level2)\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Borda</mat-label>\n <input matInput [(ngModel)]=\"working.skin.border\" (ngModelChange)=\"onSkinChanged()\" />\n </mat-form-field>\n <mat-form-field *ngIf=\"working.skin.type==='glass'\" appearance=\"outline\">\n <mat-label>Desfoque</mat-label>\n <input matInput [(ngModel)]=\"working.skin.backdropBlur\" (ngModelChange)=\"onSkinChanged()\"\n placeholder=\"ex.: 8px\" />\n </mat-form-field>\n <div *ngIf=\"working.skin.type==='gradient-tile'\" class=\"g gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Degrad\u00EA de</mat-label>\n <input matInput [ngModel]=\"working.skin.gradient.from || ''\"\n (ngModelChange)=\"onSkinGradientChanged('from', $event)\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Degrad\u00EA at\u00E9</mat-label>\n <input matInput [ngModel]=\"working.skin.gradient.to || ''\"\n (ngModelChange)=\"onSkinGradientChanged('to', $event)\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>\u00C2ngulo</mat-label>\n <input matInput type=\"number\" [ngModel]=\"working.skin.gradient.angle ?? 135\"\n (ngModelChange)=\"onSkinGradientChanged('angle', $event)\" />\n </mat-form-field>\n </div>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Classe CSS extra (skin.class)</mat-label>\n <input matInput [(ngModel)]=\"working.skin.class\" (ngModelChange)=\"onSkinChanged()\"\n placeholder=\"ex.: my-list-skin\" />\n </mat-form-field>\n\n <div *ngIf=\"working.skin.type==='custom'\" class=\"g g-auto-220 gap-12 ai-end\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Estilo inline (skin.inlineStyle)</mat-label>\n <textarea matInput rows=\"4\" [(ngModel)]=\"working.skin.inlineStyle\" (ngModelChange)=\"onSkinChanged()\"\n [attr.placeholder]=\"':host{--p-list-radius: 1rem}'\"></textarea>\n </mat-form-field>\n <div class=\"text-caption\">\n Exemplo de CSS por classe (adicione no seu styles global):\n <pre class=\"code-block\">.my-list-skin .item-card &#123;\n border-radius: 14px;\n border: 1px solid var(--md-sys-color-outline-variant);\n box-shadow: var(--md-sys-elevation-level2);\n&#125;\n.my-list-skin .mat-mdc-list-item .list-item-content &#123;\n backdrop-filter: blur(6px);\n&#125;</pre>\n </div>\n </div>\n\n\n </div>\n </mat-tab>\n</mat-tab-group>\n", styles: [".confirm-type{display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;font-size:11px;line-height:16px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface-variant)}.confirm-type.danger{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container)}.confirm-type.warning{background:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container)}.confirm-type.info{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}:host{display:block;color:var(--md-sys-color-on-surface)}.list-editor-tabs{--editor-surface: var(--md-sys-color-surface-container-lowest);--editor-border: 1px solid var(--md-sys-color-outline-variant);--editor-radius: var(--md-sys-shape-corner-large, 16px);--editor-muted: var(--md-sys-color-on-surface-variant);--editor-accent: var(--md-sys-color-primary)}.editor-content{padding:16px;background:var(--editor-surface);border:var(--editor-border);border-radius:var(--editor-radius);display:grid;gap:12px}.editor-content .mat-mdc-form-field{width:100%;max-width:none;--mdc-outlined-text-field-container-height: 48px;--mdc-outlined-text-field-outline-color: var(--md-sys-color-outline-variant);--mdc-outlined-text-field-hover-outline-color: var(--md-sys-color-outline);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-error-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-focus-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-hover-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-label-text-color: var(--md-sys-color-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--md-sys-color-on-surface);--mdc-outlined-text-field-supporting-text-color: var(--md-sys-color-on-surface-variant)}.editor-content .mat-mdc-form-field.w-full{max-width:none}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.editor-split{grid-template-columns:minmax(0,1fr);align-items:start}.editor-main,.editor-aside{display:grid;gap:12px}.skin-preview-wrap{border-radius:calc(var(--editor-radius) - 4px);border:var(--editor-border);background:var(--md-sys-color-surface-container);padding:12px}.g{display:grid}.g-auto-220{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.g-auto-200{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}.g-1-auto{grid-template-columns:1fr auto}.row-flow{grid-auto-flow:column}.gap-6{gap:6px}.gap-8{gap:8px}.gap-12{gap:12px}.ai-center{align-items:center}.ai-end{align-items:end}.mt-12{margin-top:12px}.mb-8{margin-bottom:8px}.mb-6{margin-bottom:6px}.my-8{margin:8px 0}.subtitle{margin:8px 0 4px;color:var(--editor-muted);font-weight:500}.section-title{color:var(--editor-muted);font-weight:600}.chips-row{display:flex;flex-wrap:wrap;gap:6px;align-items:center}.error{color:var(--md-sys-color-error);font-size:.85rem}.muted{color:var(--editor-muted)}.text-caption{color:var(--editor-muted);font-size:.8rem}:host ::ng-deep .mat-mdc-select-panel .option-icon{font-size:18px;margin-right:6px;vertical-align:middle}:host ::ng-deep .mat-mdc-select-panel .color-dot{width:10px;height:10px;border-radius:999px;display:inline-block;margin-right:6px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-outline)}:host ::ng-deep .mat-mdc-select-panel .color-primary{background:var(--md-sys-color-primary)}:host ::ng-deep .mat-mdc-select-panel .color-accent{background:var(--md-sys-color-tertiary)}:host ::ng-deep .mat-mdc-select-panel .color-warn{background:var(--md-sys-color-error)}:host ::ng-deep .mat-mdc-select-panel .color-default{background:var(--md-sys-color-outline)}@media(max-width:1024px){.editor-split{grid-template-columns:minmax(0,1fr)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i3$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i3$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.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: i6.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i8.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i10.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i10.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i10.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i10.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i10.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i11.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i11.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i12.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisListSkinPreviewComponent, selector: "praxis-list-skin-preview", inputs: ["config", "items", "theme"] }, { kind: "component", type: PraxisMetaEditorTextComponent, selector: "praxis-meta-editor-text", inputs: ["model", "setPipe"], outputs: ["change"] }, { kind: "component", type: PraxisMetaEditorChipComponent, selector: "praxis-meta-editor-chip", inputs: ["model", "paletteOptions", "colorDotBackground", "isCustomColor", "enableCustomColor"], outputs: ["change"] }, { kind: "component", type: PraxisMetaEditorRatingComponent, selector: "praxis-meta-editor-rating", inputs: ["model", "paletteOptions", "colorDotBackground", "isCustomColor", "enableCustomColor"], outputs: ["change"] }, { kind: "component", type: PraxisMetaEditorCurrencyComponent, selector: "praxis-meta-editor-currency", inputs: ["model"], outputs: ["change"] }, { kind: "component", type: PraxisMetaEditorDateComponent, selector: "praxis-meta-editor-date", inputs: ["model"], outputs: ["change"] }, { kind: "component", type: PraxisMetaEditorIconComponent, selector: "praxis-meta-editor-icon", inputs: ["model", "paletteOptions", "colorDotBackground", "isCustomColor", "enableCustomColor"], outputs: ["change"] }, { kind: "component", type: PraxisMetaEditorImageComponent, selector: "praxis-meta-editor-image", inputs: ["model"], outputs: ["change"] }, { kind: "component", type: PdxColorPickerComponent, selector: "pdx-color-picker", inputs: ["actionsLayout", "activeView", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "clearButton", "disabledMode", "readonlyMode", "visible", "presentationMode", "fillMode", "format", "gradientSettings", "icon", "iconClass", "svgIcon", "paletteSettings", "popupSettings", "preview", "rounded", "size", "tabindex", "views", "maxRecent", "showRecent"], outputs: ["valueChange", "open", "close", "cancel", "activeViewChange", "activeColorClick", "focusEvent", "blurEvent"] }] });
2828
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisListConfigEditor, deps: [{ token: SETTINGS_PANEL_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
2829
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: PraxisListConfigEditor, isStandalone: true, selector: "praxis-list-config-editor", inputs: { config: "config", listId: "listId" }, ngImport: i0, template: "<mat-tab-group class=\"list-editor-tabs\">\n <mat-tab label=\"Dados\">\n <div class=\"editor-content\">\n <div class=\"g g-1-auto gap-8 ai-center\">\n <div class=\"muted\">Observa\u00E7\u00E3o: ajustes aplicados pelo assistente substituem o objeto de configura\u00E7\u00E3o inteiro.\n </div>\n <button mat-icon-button type=\"button\" class=\"help-icon-button\"\n matTooltip=\"O applyConfigFromAdapter n\u00E3o faz merge profundo. Garanta que o adapter envie a config completa.\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </div>\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Recurso (API)</mat-label>\n <input matInput [(ngModel)]=\"working.dataSource.resourcePath\" (ngModelChange)=\"onResourcePathChange($event)\"\n placeholder=\"ex.: users\" />\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\"\n matTooltip=\"Endpoint do recurso (resourcePath).\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Query (JSON)</mat-label>\n <textarea matInput rows=\"3\" [(ngModel)]=\"queryJson\" (ngModelChange)=\"onQueryChanged($event)\"\n placeholder='ex.: &#123;\"status\":\"active\",\"department\":\"sales\"&#125;'></textarea>\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\"\n matTooltip=\"Opcional. Use JSON v\u00E1lido para filtros iniciais.\" *ngIf=\"!queryError\">\n <mat-icon>help_outline</mat-icon>\n </button>\n <mat-error *ngIf=\"queryError\">{{ queryError }}</mat-error>\n </mat-form-field>\n <div class=\"g g-auto-220 gap-12 ai-end mt-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Ordenar por</mat-label>\n <mat-select [(ngModel)]=\"sortField\" (ngModelChange)=\"updateSortConfig()\">\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\" matTooltip=\"Campo base do recurso.\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Dire\u00E7\u00E3o</mat-label>\n <mat-select [(ngModel)]=\"sortDir\" (ngModelChange)=\"updateSortConfig()\">\n <mat-option value=\"asc\">Ascendente</mat-option>\n <mat-option value=\"desc\">Descendente</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"A\u00E7\u00F5es\">\n <div class=\"editor-content g gap-12\">\n <div class=\"g g-1-auto gap-8 ai-center\">\n <div class=\"muted\">Configure bot\u00F5es de a\u00E7\u00E3o por item (\u00EDcone, r\u00F3tulo, cor, visibilidade)</div>\n <button mat-flat-button color=\"primary\" (click)=\"addAction()\">Adicionar a\u00E7\u00E3o</button>\n </div>\n <div class=\"g g-1-auto gap-8 ai-center\">\n <mat-form-field appearance=\"outline\">\n <mat-label>A\u00E7\u00E3o global (Praxis)</mat-label>\n <mat-select [(ngModel)]=\"selectedGlobalActionId\" (ngModelChange)=\"onGlobalActionSelected($event)\">\n <mat-option [value]=\"undefined\">-- Selecionar --</mat-option>\n <mat-option *ngFor=\"let ga of globalActionCatalog\" [value]=\"ga.id\">\n <mat-icon class=\"option-icon\">{{ ga.icon || 'bolt' }}</mat-icon>\n {{ ga.label }}\n </mat-option>\n </mat-select>\n <mat-hint *ngIf=\"!globalActionCatalog.length\" class=\"text-caption muted\">Nenhuma a\u00E7\u00E3o global registrada.</mat-hint>\n </mat-form-field>\n <div class=\"muted text-caption\">Selecione para adicionar com `command` global.</div>\n </div>\n <div *ngFor=\"let a of (working.actions || []); let i = index\" class=\"g g-auto-200 gap-12 ai-end\">\n <mat-form-field appearance=\"outline\">\n <mat-label>ID</mat-label>\n <input matInput [(ngModel)]=\"a.id\" (ngModelChange)=\"onActionsChanged()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo de a\u00E7\u00E3o</mat-label>\n <mat-select [(ngModel)]=\"a.kind\" (ngModelChange)=\"onActionsChanged()\">\n <mat-option value=\"icon\">\u00CDcone</mat-option>\n <mat-option value=\"button\">Bot\u00E3o</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>\u00CDcone</mat-label>\n <input matInput [(ngModel)]=\"a.icon\" (ngModelChange)=\"onActionsChanged()\" placeholder=\"ex.: edit, delete\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Command (global)</mat-label>\n <input matInput [(ngModel)]=\"a.command\" (ngModelChange)=\"onActionsChanged()\" placeholder=\"global:toast.success\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>R\u00F3tulo</mat-label>\n <input matInput [(ngModel)]=\"a.label\" (ngModelChange)=\"onActionsChanged()\" />\n </mat-form-field>\n <ng-container *ngIf=\"a.kind === 'button'\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Variante</mat-label>\n <mat-select [(ngModel)]=\"a.buttonVariant\" (ngModelChange)=\"onActionsChanged()\">\n <mat-option value=\"stroked\">Contorno</mat-option>\n <mat-option value=\"raised\">Elevado</mat-option>\n <mat-option value=\"flat\">Preenchido</mat-option>\n </mat-select>\n </mat-form-field>\n </ng-container>\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor da a\u00E7\u00E3o</mat-label>\n <mat-select [(ngModel)]=\"a.color\" (ngModelChange)=\"onActionsChanged()\">\n <mat-option *ngFor=\"let c of paletteOptions\" [value]=\"c.value\">\n <span class=\"color-dot\" [style.background]=\"colorDotBackground(c.value)\"></span>{{ c.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <div class=\"g gap-8\" *ngIf=\"isCustomColor(a.color); else actionCustomBtn\">\n <pdx-color-picker label=\"Cor personalizada\" [format]=\"'hex'\" [(ngModel)]=\"a.color\"\n (ngModelChange)=\"onActionsChanged()\"></pdx-color-picker>\n </div>\n <ng-template #actionCustomBtn>\n <button mat-stroked-button type=\"button\" (click)=\"enableCustomActionColor(a)\">Usar cor personalizada</button>\n </ng-template>\n <mat-form-field appearance=\"outline\">\n <mat-label>Payload da a\u00E7\u00E3o</mat-label>\n <mat-select [(ngModel)]=\"a.emitPayload\" (ngModelChange)=\"onActionsChanged()\">\n <mat-option [value]=\"undefined\">Padr\u00E3o</mat-option>\n <mat-option value=\"item\">item</mat-option>\n <mat-option value=\"id\">id</mat-option>\n <mat-option value=\"value\">value</mat-option>\n </mat-select>\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\" matTooltip=\"emitPayload\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"col-span-2\">\n <mat-label>Exibir quando (ex.: &#36;&#123;item.status&#125; == 'done')</mat-label>\n <input matInput [(ngModel)]=\"a.showIf\" (ngModelChange)=\"onActionsChanged()\" />\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\"\n matTooltip=\"Sintaxe suportada: &#34;&#36;{item.campo} == &#39;valor&#39;&#34;. Express\u00F5es avan\u00E7adas n\u00E3o s\u00E3o avaliadas.\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <div class=\"g row-flow gap-8 ai-center\">\n <button *ngIf=\"(a.kind || 'icon') === 'icon'\" mat-icon-button\n [color]=\"isThemeColor(a.color) ? a.color : undefined\"><mat-icon\n [praxisIcon]=\"a.icon || 'bolt'\" [style.cssText]=\"iconStyle(a.color)\"></mat-icon></button>\n <ng-container *ngIf=\"a.kind === 'button'\">\n <button *ngIf=\"a.buttonVariant === 'stroked'\" mat-stroked-button\n [color]=\"isThemeColor(a.color) ? a.color : undefined\" [style.cssText]=\"buttonStyle(a.color, 'stroked')\">{{ a.label\n || a.id || 'A\u00E7\u00E3o' }}</button>\n <button *ngIf=\"a.buttonVariant === 'raised'\" mat-raised-button\n [color]=\"isThemeColor(a.color) ? a.color : undefined\" [style.cssText]=\"buttonStyle(a.color, 'raised')\">{{ a.label ||\n a.id || 'A\u00E7\u00E3o' }}</button>\n <button *ngIf=\"!a.buttonVariant || a.buttonVariant === 'flat'\" mat-flat-button\n [color]=\"isThemeColor(a.color) ? a.color : undefined\" [style.cssText]=\"buttonStyle(a.color, 'flat')\">{{ a.label || a.id || 'A\u00E7\u00E3o' }}</button>\n </ng-container>\n <span class=\"muted\">Pr\u00E9-visualiza\u00E7\u00E3o</span>\n </div>\n <div class=\"flex-end\">\n <button mat-button color=\"warn\" (click)=\"removeAction(i)\">Remover</button>\n </div>\n <div class=\"g gap-8 col-span-2\" *ngIf=\"a.command\">\n <mat-slide-toggle [(ngModel)]=\"a.showLoading\" (ngModelChange)=\"onActionsChanged()\">Mostrar loading</mat-slide-toggle>\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header><mat-panel-title>Confirma\u00E7\u00E3o</mat-panel-title></mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <div class=\"g row-flow gap-8 ai-center\">\n <span class=\"text-caption muted\">Tipo</span>\n <mat-button-toggle-group [value]=\"a.confirmation?.type || ''\" (change)=\"applyConfirmationPreset(a, $event.value)\">\n <mat-button-toggle value=\"\">Padr\u00E3o</mat-button-toggle>\n <mat-button-toggle value=\"danger\">Danger</mat-button-toggle>\n <mat-button-toggle value=\"warning\">Warning</mat-button-toggle>\n <mat-button-toggle value=\"info\">Info</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <mat-form-field appearance=\"outline\">\n <mat-label>T\u00EDtulo</mat-label>\n <input matInput [ngModel]=\"a.confirmation?.title\" (ngModelChange)=\"setConfirmationField(a, 'title', $event)\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Mensagem</mat-label>\n <input matInput [ngModel]=\"a.confirmation?.message\" (ngModelChange)=\"setConfirmationField(a, 'message', $event)\" />\n </mat-form-field>\n <div class=\"g gap-6\">\n <div class=\"text-caption muted\">Pr\u00E9via</div>\n <div class=\"text-caption\">\n <strong>{{ a.confirmation?.title || 'Confirmar a\u00E7\u00E3o' }}</strong>\n </div>\n <div class=\"text-caption muted\">{{ a.confirmation?.message || 'Tem certeza que deseja continuar?' }}</div>\n <div class=\"text-caption\">\n <span class=\"confirm-type\" [ngClass]=\"(a.confirmation?.type || 'default')\">Tipo: {{ a.confirmation?.type || 'padr\u00E3o' }}</span>\n </div>\n <div class=\"text-caption muted\" *ngIf=\"!a.confirmation?.title && !a.confirmation?.message\">\n Defina um t\u00EDtulo ou mensagem para a confirma\u00E7\u00E3o.\n </div>\n </div>\n </div>\n </mat-expansion-panel>\n <mat-form-field appearance=\"outline\" class=\"col-span-2\">\n <mat-label>Payload (JSON/Template)</mat-label>\n <textarea matInput rows=\"4\" [(ngModel)]=\"a.globalPayload\" (ngModelChange)=\"onActionsChanged()\"\n placeholder='{\"message\":\"${item.name} favoritado\"}'></textarea>\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\"\n [matTooltip]=\"globalPayloadSchemaTooltip(a)\">\n <mat-icon>help_outline</mat-icon>\n </button>\n <mat-error *ngIf=\"isGlobalPayloadInvalid(a.globalPayload)\">JSON inv\u00E1lido</mat-error>\n </mat-form-field>\n <div class=\"g row-flow gap-8 ai-center\">\n <button mat-stroked-button type=\"button\" (click)=\"applyGlobalPayloadExample(a)\">Inserir exemplo</button>\n <span class=\"muted text-caption\">{{ globalPayloadExampleHint(a) }}</span>\n </div>\n <mat-slide-toggle [(ngModel)]=\"a.emitLocal\" (ngModelChange)=\"onActionsChanged()\">Emitir evento local tamb\u00E9m</mat-slide-toggle>\n </div>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Layout\">\n <div class=\"editor-content grid gap-3\">\n <div class=\"preset-row g row-flow gap-8\">\n <button mat-stroked-button (click)=\"applyLayoutPreset('tiles-modern')\">Preset Tiles Moderno</button>\n </div>\n <mat-form-field appearance=\"outline\">\n <mat-label>Variante</mat-label>\n <mat-select [(ngModel)]=\"working.layout.variant\" (ngModelChange)=\"onLayoutChanged()\">\n <mat-option value=\"list\">Lista</mat-option>\n <mat-option value=\"cards\">Cards</mat-option>\n <mat-option value=\"tiles\">Tiles</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Modelo</mat-label>\n <mat-select [(ngModel)]=\"working.layout.model\" (ngModelChange)=\"onLayoutChanged()\">\n <ng-container *ngIf=\"working.layout.variant === 'list'; else cardModels\">\n <mat-option value=\"standard\">Padr\u00E3o</mat-option>\n <mat-option value=\"media\">M\u00EDdia \u00E0 esquerda</mat-option>\n <mat-option value=\"hotel\">Hotel (m\u00EDdia grande)</mat-option>\n </ng-container>\n <ng-template #cardModels>\n <ng-container *ngIf=\"working.layout.variant === 'tiles'; else cardsOnly\">\n <mat-option value=\"standard\">Tile padr\u00E3o</mat-option>\n <mat-option value=\"media\">Tile com m\u00EDdia</mat-option>\n <mat-option value=\"hotel\">Tile hotel</mat-option>\n </ng-container>\n <ng-template #cardsOnly>\n <mat-option value=\"standard\">Padr\u00E3o</mat-option>\n <mat-option value=\"media\">Card com m\u00EDdia</mat-option>\n <mat-option value=\"hotel\">Hotel</mat-option>\n </ng-template>\n </ng-template>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Linhas</mat-label>\n <mat-select [(ngModel)]=\"working.layout.lines\" (ngModelChange)=\"onLayoutChanged()\">\n <mat-option [value]=\"1\">1</mat-option>\n <mat-option [value]=\"2\">2</mat-option>\n <mat-option [value]=\"3\">3</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Itens por p\u00E1gina</mat-label>\n <input matInput type=\"number\" min=\"1\" [(ngModel)]=\"working.layout.pageSize\"\n (ngModelChange)=\"onPageSizeChange($event)\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Densidade</mat-label>\n <mat-select [(ngModel)]=\"working.layout.density\" (ngModelChange)=\"onLayoutChanged()\">\n <mat-option value=\"default\">Padr\u00E3o</mat-option>\n <mat-option value=\"comfortable\">Confort\u00E1vel</mat-option>\n <mat-option value=\"compact\">Compacta</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" *ngIf=\"working.layout.variant !== 'tiles'\">\n <mat-label>Divisores</mat-label>\n <mat-select [(ngModel)]=\"working.layout.dividers\" (ngModelChange)=\"onLayoutChanged()\">\n <mat-option value=\"none\">Sem</mat-option>\n <mat-option value=\"between\">Entre grupos</mat-option>\n <mat-option value=\"all\">Todos</mat-option>\n </mat-select>\n </mat-form-field>\n <ng-container *ngIf=\"fields.length > 0; else groupByText\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Agrupar por</mat-label>\n <mat-select [(ngModel)]=\"working.layout.groupBy\" (ngModelChange)=\"onLayoutChanged()\">\n <mat-option [value]=\"\">Nenhum</mat-option>\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n </ng-container>\n <ng-template #groupByText>\n <mat-form-field appearance=\"outline\">\n <mat-label>Agrupar por</mat-label>\n <input matInput [(ngModel)]=\"working.layout.groupBy\" (ngModelChange)=\"onLayoutChanged()\"\n placeholder=\"ex.: departamento\" />\n </mat-form-field>\n </ng-template>\n <mat-slide-toggle [(ngModel)]=\"working.layout.stickySectionHeader\" (ngModelChange)=\"onLayoutChanged()\">\n Header de se\u00E7\u00E3o fixo\n </mat-slide-toggle>\n <mat-slide-toggle [(ngModel)]=\"working.layout.virtualScroll\" (ngModelChange)=\"onLayoutChanged()\">\n Scroll virtual\n </mat-slide-toggle>\n <mat-divider class=\"my-8\"></mat-divider>\n <div class=\"subtitle\">Ferramentas da lista</div>\n <div class=\"g g-auto-220 gap-12 ai-end\">\n <mat-slide-toggle [(ngModel)]=\"working.ui.showSearch\" (ngModelChange)=\"onUiChanged()\">Mostrar\n busca</mat-slide-toggle>\n <mat-slide-toggle [(ngModel)]=\"working.ui.showSort\" (ngModelChange)=\"onUiChanged()\">Mostrar\n ordenar</mat-slide-toggle>\n <mat-slide-toggle [(ngModel)]=\"working.ui.showRange\" (ngModelChange)=\"onUiChanged()\">Mostrar faixa X\u2013Y de\n Total</mat-slide-toggle>\n </div>\n <div class=\"g g-auto-220 gap-12 ai-end mt-12\" *ngIf=\"working.ui?.showSearch\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Campo para buscar</mat-label>\n <mat-select [(ngModel)]=\"working.ui.searchField\" (ngModelChange)=\"onUiChanged()\">\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Placeholder da busca</mat-label>\n <input matInput [(ngModel)]=\"working.ui.searchPlaceholder\" (ngModelChange)=\"onUiChanged()\"\n placeholder=\"ex.: Buscar por t\u00EDtulo\" />\n </mat-form-field>\n </div>\n <div class=\"mt-12\" *ngIf=\"working.ui?.showSort\">\n <div class=\"g g-1-auto ai-center gap-8\">\n <div class=\"muted\">Op\u00E7\u00F5es de ordena\u00E7\u00E3o (r\u00F3tulo \u2192 campo+dire\u00E7\u00E3o)</div>\n <button mat-flat-button color=\"primary\" (click)=\"addUiSortRow()\">Adicionar op\u00E7\u00E3o</button>\n </div>\n <div class=\"g g-auto-220 gap-12 ai-end mt-12\" *ngFor=\"let r of uiSortRows; let i = index\">\n <mat-form-field appearance=\"outline\">\n <mat-label>R\u00F3tulo</mat-label>\n <input matInput [(ngModel)]=\"r.label\" (ngModelChange)=\"onUiSortRowsChanged()\"\n placeholder=\"ex.: Mais recentes\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Campo</mat-label>\n <mat-select [(ngModel)]=\"r.field\" (ngModelChange)=\"onUiSortRowsChanged()\">\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Dire\u00E7\u00E3o</mat-label>\n <mat-select [(ngModel)]=\"r.dir\" (ngModelChange)=\"onUiSortRowsChanged()\">\n <mat-option value=\"desc\">Descendente</mat-option>\n <mat-option value=\"asc\">Ascendente</mat-option>\n </mat-select>\n </mat-form-field>\n <div class=\"error\" *ngIf=\"isUiSortRowDuplicate(i)\">Op\u00E7\u00E3o duplicada (campo+dire\u00E7\u00E3o)</div>\n <div class=\"flex-end\"><button mat-button color=\"warn\" (click)=\"removeUiSortRow(i)\">Remover</button></div>\n </div>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Conte\u00FAdo\">\n <div class=\"editor-content\">\n <div class=\"editor-main\">\n <mat-accordion multi>\n <!-- Primary -->\n <mat-expansion-panel [expanded]=\"true\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>{{ getTypeIcon(mappingPrimary.type) }}</mat-icon>\n <span>Primary (T\u00EDtulo)</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>{{ mappingPrimary.field || 'N\u00E3o mapeado' }}</mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"g gap-12\">\n <div class=\"g row-flow gap-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"mappingPrimary.type='text'; mappingPrimary.field='name'; onMappingChanged()\">Nome</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingPrimary.type='text'; mappingPrimary.field='title'; onMappingChanged()\">T\u00EDtulo</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingPrimary.type='text'; mappingPrimary.field='name'; mappingSecondary.type='text'; mappingSecondary.field='role'; onMappingChanged()\">Nome + Papel</button>\n </div>\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Campo</mat-label>\n <mat-select [(ngModel)]=\"mappingPrimary.field\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [(ngModel)]=\"mappingPrimary.type\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let mt of primaryTypeConfigs\" [value]=\"mt.type\">\n <mat-icon class=\"option-icon\">{{ mt.icon }}</mat-icon>\n {{ mt.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n @switch (mappingPrimary.type) {\n @case ('text') { <praxis-meta-editor-text [model]=\"mappingPrimary\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('html') { <praxis-meta-editor-text [model]=\"mappingPrimary\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('currency') { <praxis-meta-editor-currency [model]=\"mappingPrimary\" (change)=\"onMappingChanged()\"></praxis-meta-editor-currency> }\n @case ('date') { <praxis-meta-editor-date [model]=\"mappingPrimary\" (change)=\"onMappingChanged()\"></praxis-meta-editor-date> }\n }\n\n <!-- Advanced -->\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header>\n <mat-panel-title>Formata\u00E7\u00E3o e Estilo</mat-panel-title>\n </mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <mat-form-field appearance=\"outline\" *ngIf=\"mappingPrimary.type==='text' || mappingPrimary.type==='html'\">\n <mat-label>Classe CSS</mat-label>\n <input matInput [(ngModel)]=\"mappingPrimary.class\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" *ngIf=\"mappingPrimary.type==='text' || mappingPrimary.type==='html'\">\n <mat-label>Estilo Inline</mat-label>\n <input matInput [(ngModel)]=\"mappingPrimary.style\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Classe CSS</mat-label>\n <input matInput [(ngModel)]=\"mappingPrimary.class\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Estilo Inline</mat-label>\n <input matInput [(ngModel)]=\"mappingPrimary.style\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n </div>\n </div>\n </mat-expansion-panel>\n </div>\n </mat-expansion-panel>\n\n <!-- Secondary -->\n <mat-expansion-panel [expanded]=\"!!mappingSecondary.field\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>{{ getTypeIcon(mappingSecondary.type) }}</mat-icon>\n <span>Secondary (Resumo)</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>{{ mappingSecondary.field || 'N\u00E3o mapeado' }}</mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"g gap-12\">\n <div class=\"g row-flow gap-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"mappingSecondary.type='text'; mappingSecondary.field='subtitle'; onMappingChanged()\">Subt\u00EDtulo</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingSecondary.type='date'; mappingSecondary.field='hireDate'; mappingSecondary.dateStyle='short'; onMappingChanged()\">Data curta</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingSecondary.type='currency'; mappingSecondary.field='salary'; mappingSecondary.currencyCode='BRL'; mappingSecondary.locale='pt-BR'; onMappingChanged()\">Sal\u00E1rio</button>\n </div>\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Campo</mat-label>\n <mat-select [(ngModel)]=\"mappingSecondary.field\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [(ngModel)]=\"mappingSecondary.type\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let mt of secondaryTypeConfigs\" [value]=\"mt.type\">\n <mat-icon class=\"option-icon\">{{ mt.icon }}</mat-icon>\n {{ mt.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n @switch (mappingSecondary.type) {\n @case ('text') { <praxis-meta-editor-text [model]=\"mappingSecondary\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('html') { <praxis-meta-editor-text [model]=\"mappingSecondary\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('currency') { <praxis-meta-editor-currency [model]=\"mappingSecondary\" (change)=\"onMappingChanged()\"></praxis-meta-editor-currency> }\n @case ('date') { <praxis-meta-editor-date [model]=\"mappingSecondary\" (change)=\"onMappingChanged()\"></praxis-meta-editor-date> }\n }\n\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header>\n <mat-panel-title>Formata\u00E7\u00E3o e Estilo</mat-panel-title>\n </mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\"><mat-label>Classe CSS</mat-label><input matInput\n [(ngModel)]=\"mappingSecondary.class\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Estilo Inline</mat-label><input matInput\n [(ngModel)]=\"mappingSecondary.style\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n </div>\n </div>\n </mat-expansion-panel>\n </div>\n </mat-expansion-panel>\n\n <mat-expansion-panel [expanded]=\"!!mappingMeta.field || mappingMetaFields.length > 0\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>{{ getTypeIcon(mappingMeta.type || 'text') }}</mat-icon>\n <span>Meta (Detalhe/Lateral)</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>\n {{ mappingMetaFields.length ? 'Campo composto (' + mappingMetaFields.length + ')' :\n (mappingMeta.field || 'N\u00E3o mapeado') }}\n </mat-panel-description>\n </mat-expansion-panel-header>\n\n <div class=\"g gap-12\">\n <!-- Composition Mode Toggle -->\n <div class=\"g g-1-1 gap-12 p-12 bg-subtle rounded\">\n <div class=\"text-caption muted\">Modo de composi\u00E7\u00E3o</div>\n <mat-form-field appearance=\"outline\">\n <mat-label>Campos para compor (Multi-select)</mat-label>\n <mat-select [(ngModel)]=\"mappingMetaFields\" multiple (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n <div class=\"g g-1-1 ai-center gap-12\" *ngIf=\"mappingMetaFields.length\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Separador</mat-label>\n <input matInput [(ngModel)]=\"mappingMetaSeparator\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n <mat-slide-toggle [(ngModel)]=\"mappingMetaWrapSecondInParens\" (ngModelChange)=\"onMappingChanged()\">\n (Seg) entre par\u00EAnteses\n </mat-slide-toggle>\n </div>\n </div>\n\n <!-- Single Field Mode (if no composition) -->\n <div class=\"g g-1-1 gap-12\" *ngIf=\"!mappingMetaFields.length\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Campo \u00DAnico</mat-label>\n <mat-select [(ngModel)]=\"mappingMeta.field\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option [value]=\"undefined\">-- Nenhum --</mat-option>\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [(ngModel)]=\"mappingMeta.type\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let mt of metaTypeConfigs\" [value]=\"mt.type\">\n <mat-icon class=\"option-icon\">{{ mt.icon }}</mat-icon>\n {{ mt.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- Type configuration (pluggable editors) -->\n @switch (mappingMeta.type) {\n @case ('text') { <praxis-meta-editor-text [model]=\"mappingMeta\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('html') { <praxis-meta-editor-text [model]=\"mappingMeta\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('currency') { <praxis-meta-editor-currency [model]=\"mappingMeta\" (change)=\"onMappingChanged()\"></praxis-meta-editor-currency> }\n @case ('date') { <praxis-meta-editor-date [model]=\"mappingMeta\" (change)=\"onMappingChanged()\"></praxis-meta-editor-date> }\n @case ('chip') {\n <praxis-meta-editor-chip\n [model]=\"mappingMeta\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-chip>\n }\n @case ('rating') {\n <praxis-meta-editor-rating\n [model]=\"mappingMeta\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-rating>\n }\n @case ('icon') {\n <praxis-meta-editor-icon\n [model]=\"mappingMeta\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-icon>\n }\n @case ('image') { <praxis-meta-editor-image [model]=\"mappingMeta\" (change)=\"onMappingChanged()\"></praxis-meta-editor-image> }\n }\n\n <!-- Advanced -->\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header><mat-panel-title>Op\u00E7\u00F5es\n avan\u00E7adas</mat-panel-title></mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Posi\u00E7\u00E3o</mat-label>\n <mat-select [(ngModel)]=\"mappingMeta.placement\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option value=\"side\">Lateral (Direita)</mat-option>\n <mat-option value=\"line\">Na linha (Abaixo)</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Classe CSS</mat-label>\n <input matInput [(ngModel)]=\"mappingMeta.class\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Estilo</mat-label>\n <input matInput [(ngModel)]=\"mappingMeta.style\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n </div>\n </mat-expansion-panel>\n </div>\n </mat-expansion-panel>\n <!-- Trailing -->\n <mat-expansion-panel [expanded]=\"!!mappingTrailing.field\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>{{ getTypeIcon(mappingTrailing.type || 'text') }}</mat-icon>\n <span>Trailing (Direita)</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>{{ mappingTrailing.field || 'N\u00E3o mapeado'\n }}</mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"g gap-12\">\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Campo</mat-label>\n <mat-select [(ngModel)]=\"mappingTrailing.field\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option [value]=\"undefined\">-- Nenhum --</mat-option>\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [(ngModel)]=\"mappingTrailing.type\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let mt of trailingTypeConfigs\" [value]=\"mt.type\">\n <mat-icon class=\"option-icon\">{{ mt.icon }}</mat-icon>\n {{ mt.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"g row-flow gap-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"mappingTrailing.type='chip'; mappingTrailing.chipColor='primary'; mappingTrailing.chipVariant='filled'; mappingTrailing.field='status'; onMappingChanged()\">Status Chip</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingTrailing.type='icon'; mappingTrailing.field='status'; mappingTrailing.iconColor='primary'; onMappingChanged()\">Status \u00CDcone</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingTrailing.type='currency'; mappingTrailing.field='price'; mappingTrailing.currencyCode='BRL'; mappingTrailing.locale='pt-BR'; onMappingChanged()\">Pre\u00E7o</button>\n </div>\n\n @switch (mappingTrailing.type) {\n @case ('text') { <praxis-meta-editor-text [model]=\"mappingTrailing\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('html') { <praxis-meta-editor-text [model]=\"mappingTrailing\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('currency') { <praxis-meta-editor-currency [model]=\"mappingTrailing\" (change)=\"onMappingChanged()\"></praxis-meta-editor-currency> }\n @case ('date') { <praxis-meta-editor-date [model]=\"mappingTrailing\" (change)=\"onMappingChanged()\"></praxis-meta-editor-date> }\n @case ('chip') {\n <praxis-meta-editor-chip\n [model]=\"mappingTrailing\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-chip>\n }\n @case ('rating') {\n <praxis-meta-editor-rating\n [model]=\"mappingTrailing\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-rating>\n }\n @case ('icon') {\n <praxis-meta-editor-icon\n [model]=\"mappingTrailing\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-icon>\n }\n @case ('image') {\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>URL / Expr</mat-label>\n <input matInput [(ngModel)]=\"mappingTrailing.imageUrl\" (ngModelChange)=\"onMappingChanged()\"\n placeholder=\"https://... ou ${item.imageUrl}\" />\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\"\n matTooltip=\"Use URL absoluta/relativa ou express\u00E3o ${item.campo}.\">\n <mat-icon>help_outline</mat-icon>\n </button>\n <mat-error *ngIf=\"isImageUrlRequiredInvalid(mappingTrailing.imageUrl)\">URL/expr obrigat\u00F3ria</mat-error>\n </mat-form-field>\n </div>\n <praxis-meta-editor-image [model]=\"mappingTrailing\" (change)=\"onMappingChanged()\"></praxis-meta-editor-image>\n <div class=\"text-caption muted\" *ngIf=\"!mappingTrailing.imageUrl\">Defina a URL/expr para renderizar a imagem.</div>\n }\n }\n\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header><mat-panel-title>Estilo</mat-panel-title></mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\"><mat-label>Classe</mat-label><input matInput\n [(ngModel)]=\"mappingTrailing.class\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Style</mat-label><input matInput\n [(ngModel)]=\"mappingTrailing.style\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n </div>\n </div>\n </mat-expansion-panel>\n </div>\n </mat-expansion-panel>\n\n <!-- Leading -->\n <mat-expansion-panel\n [expanded]=\"!!mappingLeading.field || (mappingLeading.type === 'icon' && !!mappingLeading.icon) || (mappingLeading.type === 'image' && !!mappingLeading.imageUrl)\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>{{ getTypeIcon(mappingLeading.type) }}</mat-icon>\n <span>Leading (Esquerda)</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>\n {{ mappingLeading.type === 'icon' ? (mappingLeading.icon || '\u00CDcone est\u00E1tico') :\n (mappingLeading.field || (mappingLeading.imageUrl ? 'Imagem est\u00E1tica' : 'N\u00E3o mapeado'))\n }}\n </mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"g gap-12\">\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [(ngModel)]=\"mappingLeading.type\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let mt of leadingTypeConfigs\" [value]=\"mt.type\">\n <mat-icon class=\"option-icon\">{{ mt.icon }}</mat-icon>\n {{ mt.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <!-- Field (only if not static icon/image, though user might want dynamic) -->\n <mat-form-field appearance=\"outline\"\n *ngIf=\"mappingLeading.type !== 'icon' && mappingLeading.type !== 'image'\">\n <mat-label>Campo</mat-label>\n <mat-select [(ngModel)]=\"mappingLeading.field\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let f of fields\" [value]=\"f\">{{ f }}</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"g row-flow gap-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"mappingLeading.type='icon'; mappingLeading.icon='person'; mappingLeading.iconColor='primary'; onMappingChanged()\">Avatar \u00CDcone</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingLeading.type='image'; mappingLeading.imageUrl='https://placehold.co/64x64'; mappingLeading.imageAlt='Avatar'; mappingLeading.badgeText='${item.status}'; onMappingChanged()\">Avatar Imagem + Badge</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingLeading.type='chip'; mappingLeading.field='tag'; mappingLeading.chipColor='accent'; mappingLeading.chipVariant='filled'; onMappingChanged()\">Chip Tag</button>\n </div>\n\n <!-- Icon Specific -->\n <div class=\"g g-1-auto gap-12 ai-center\" *ngIf=\"mappingLeading.type === 'icon'\">\n <mat-form-field appearance=\"outline\">\n <mat-label>\u00CDcone</mat-label>\n <input matInput [(ngModel)]=\"mappingLeading.icon\" (ngModelChange)=\"onMappingChanged()\" />\n <button mat-icon-button matSuffix (click)=\"pickLeadingIcon()\"><mat-icon>search</mat-icon></button>\n </mat-form-field>\n <div class=\"text-caption muted\">Use pipe <code>|iconMap</code> no extra pipe para\n din\u00E2mico</div>\n </div>\n <div *ngIf=\"mappingLeading.type === 'icon'\">\n <praxis-meta-editor-icon\n [model]=\"mappingLeading\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-icon>\n </div>\n\n <!-- Image Specific -->\n <div class=\"g g-1-1 gap-12\" *ngIf=\"mappingLeading.type === 'image'\">\n <mat-form-field appearance=\"outline\">\n <mat-label>URL da Imagem</mat-label>\n <input matInput [(ngModel)]=\"mappingLeading.imageUrl\" (ngModelChange)=\"onMappingChanged()\"\n placeholder=\"https://... ou ${item.imageUrl}\" />\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\"\n matTooltip=\"Use URL absoluta/relativa ou express\u00E3o ${item.campo}.\">\n <mat-icon>help_outline</mat-icon>\n </button>\n <mat-error *ngIf=\"isImageUrlRequiredInvalid(mappingLeading.imageUrl)\">URL/expr obrigat\u00F3ria</mat-error>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Alt Text</mat-label>\n <input matInput [(ngModel)]=\"mappingLeading.imageAlt\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Badge Texto</mat-label>\n <input matInput [(ngModel)]=\"mappingLeading.badgeText\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n </div>\n\n @switch (mappingLeading.type) {\n @case ('text') { <praxis-meta-editor-text [model]=\"mappingLeading\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('html') { <praxis-meta-editor-text [model]=\"mappingLeading\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('chip') {\n <praxis-meta-editor-chip\n [model]=\"mappingLeading\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-chip>\n }\n @case ('rating') {\n <praxis-meta-editor-rating\n [model]=\"mappingLeading\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-rating>\n }\n }\n\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header><mat-panel-title>Estilo</mat-panel-title></mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <mat-form-field appearance=\"outline\"><mat-label>Classe</mat-label><input matInput\n [(ngModel)]=\"mappingLeading.class\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Style</mat-label><input matInput\n [(ngModel)]=\"mappingLeading.style\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n </div>\n </mat-expansion-panel>\n </div>\n </mat-expansion-panel>\n\n <!-- Features -->\n <mat-expansion-panel [expanded]=\"featuresVisible && features.length > 0\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>view_list</mat-icon>\n <span>Recursos (Features)</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>{{ features.length }} item(s)</mat-panel-description>\n </mat-expansion-panel-header>\n\n <div class=\"g gap-12\">\n <div class=\"g row-flow gap-12 ai-center\">\n <mat-slide-toggle [(ngModel)]=\"featuresVisible\" (ngModelChange)=\"onFeaturesChanged()\">Ativar\n recursos</mat-slide-toggle>\n <mat-slide-toggle [(ngModel)]=\"featuresSyncWithMeta\" (ngModelChange)=\"onMappingChanged()\">Sincronizar\n com Meta</mat-slide-toggle>\n <span class=\"flex-1\"></span>\n <mat-button-toggle-group [(ngModel)]=\"featuresMode\" (change)=\"onFeaturesChanged()\" appearance=\"legacy\">\n <mat-button-toggle value=\"icons+labels\"><mat-icon>view_list</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"icons-only\"><mat-icon>more_horiz</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div *ngFor=\"let f of features; let i = index\" class=\"g g-auto-1 gap-8 ai-center p-8 border rounded mb-2\">\n <button mat-icon-button (click)=\"pickFeatureIcon(i)\"><mat-icon>{{ f.icon || 'search'\n }}</mat-icon></button>\n <mat-form-field appearance=\"outline\" class=\"dense-form-field no-sub\">\n <input matInput [(ngModel)]=\"f.expr\" (ngModelChange)=\"onFeaturesChanged()\" placeholder=\"Expr/Texto\" />\n </mat-form-field>\n <button mat-icon-button color=\"warn\" (click)=\"removeFeature(i)\"><mat-icon>delete</mat-icon></button>\n </div>\n <button mat-button color=\"primary\" (click)=\"addFeature()\"><mat-icon>add</mat-icon>\n Adicionar recurso</button>\n </div>\n </mat-expansion-panel>\n <!-- Section Header -->\n <mat-expansion-panel [expanded]=\"!!mappingSectionHeader.expr\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>{{ getTypeIcon(mappingSectionHeader.type) }}</mat-icon>\n <span>Cabe\u00E7alho de Se\u00E7\u00E3o</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>{{ mappingSectionHeader.expr || 'N\u00E3o configurado'\n }}</mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"g gap-12\">\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [(ngModel)]=\"mappingSectionHeader.type\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let mt of sectionHeaderTypeConfigs\" [value]=\"mt.type\">\n <mat-icon class=\"option-icon\">{{ mt.icon }}</mat-icon>\n {{ mt.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Express\u00E3o (item.key)</mat-label>\n <input matInput [(ngModel)]=\"mappingSectionHeader.expr\" (ngModelChange)=\"onMappingChanged()\"\n placeholder=\"item.key\" />\n </mat-form-field>\n </div>\n <div class=\"g row-flow gap-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"mappingSectionHeader.type='text'; mappingSectionHeader.expr='${item.key}'; onMappingChanged()\">Texto padr\u00E3o</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingSectionHeader.type='chip'; mappingSectionHeader.chipColor='primary'; mappingSectionHeader.chipVariant='filled'; mappingSectionHeader.expr='${item.key}'; onMappingChanged()\">Chip padr\u00E3o</button>\n </div>\n\n @switch (mappingSectionHeader.type) {\n @case ('text') { <praxis-meta-editor-text [model]=\"mappingSectionHeader\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('html') { <praxis-meta-editor-text [model]=\"mappingSectionHeader\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('chip') {\n <praxis-meta-editor-chip\n [model]=\"mappingSectionHeader\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-chip>\n }\n @case ('rating') {\n <praxis-meta-editor-rating\n [model]=\"mappingSectionHeader\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-rating>\n }\n @case ('icon') {\n <praxis-meta-editor-icon\n [model]=\"mappingSectionHeader\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-icon>\n }\n @case ('image') {\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>URL Imagem</mat-label>\n <input matInput [(ngModel)]=\"mappingSectionHeader.imageUrl\" (ngModelChange)=\"onMappingChanged()\" />\n <mat-error *ngIf=\"isImageUrlRequiredInvalid(mappingSectionHeader.imageUrl)\">URL/expr obrigat\u00F3ria</mat-error>\n </mat-form-field>\n </div>\n <div class=\"text-caption muted\" *ngIf=\"!mappingSectionHeader.imageUrl\">Defina a URL/expr para renderizar a imagem.</div>\n <praxis-meta-editor-image [model]=\"mappingSectionHeader\" (change)=\"onMappingChanged()\"></praxis-meta-editor-image>\n }\n }\n\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header><mat-panel-title>Estilo</mat-panel-title></mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <mat-form-field appearance=\"outline\"><mat-label>Classe</mat-label><input matInput\n [(ngModel)]=\"mappingSectionHeader.class\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Style</mat-label><input matInput\n [(ngModel)]=\"mappingSectionHeader.style\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n </div>\n </mat-expansion-panel>\n </div>\n </mat-expansion-panel>\n\n <!-- Empty State -->\n <mat-expansion-panel [expanded]=\"!!mappingEmptyState.expr\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"g row-flow gap-8 ai-center\">\n <mat-icon>inbox</mat-icon>\n <span>Estado Vazio</span>\n </div>\n </mat-panel-title>\n <mat-panel-description>{{ mappingEmptyState.expr || 'Padr\u00E3o' }}</mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"g gap-12\">\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [(ngModel)]=\"mappingEmptyState.type\" (ngModelChange)=\"onMappingChanged()\">\n <mat-option *ngFor=\"let mt of emptyStateTypeConfigs\" [value]=\"mt.type\">\n <mat-icon class=\"option-icon\">{{ mt.icon }}</mat-icon>\n {{ mt.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Mensagem / Expr</mat-label>\n <input matInput [(ngModel)]=\"mappingEmptyState.expr\" (ngModelChange)=\"onMappingChanged()\" />\n </mat-form-field>\n </div>\n <div class=\"g row-flow gap-8\">\n <span class=\"text-caption muted\">Presets</span>\n <button mat-stroked-button type=\"button\" (click)=\"mappingEmptyState.type='text'; mappingEmptyState.expr='Nenhum item dispon\u00EDvel'; onMappingChanged()\">Mensagem padr\u00E3o</button>\n <button mat-stroked-button type=\"button\" (click)=\"mappingEmptyState.type='image'; mappingEmptyState.imageUrl='/list-empty-state.svg'; mappingEmptyState.imageAlt='Sem resultados'; onMappingChanged()\">Imagem padr\u00E3o</button>\n </div>\n\n @switch (mappingEmptyState.type) {\n @case ('text') { <praxis-meta-editor-text [model]=\"mappingEmptyState\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('html') { <praxis-meta-editor-text [model]=\"mappingEmptyState\" [setPipe]=\"setPipe.bind(this)\" (change)=\"onMappingChanged()\"></praxis-meta-editor-text> }\n @case ('chip') {\n <praxis-meta-editor-chip\n [model]=\"mappingEmptyState\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-chip>\n }\n @case ('rating') {\n <praxis-meta-editor-rating\n [model]=\"mappingEmptyState\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-rating>\n }\n @case ('icon') {\n <praxis-meta-editor-icon\n [model]=\"mappingEmptyState\"\n [paletteOptions]=\"paletteOptions\"\n [colorDotBackground]=\"colorDotBackground\"\n [isCustomColor]=\"isCustomColor\"\n [enableCustomColor]=\"enableCustomColor.bind(this)\"\n (change)=\"onMappingChanged()\"></praxis-meta-editor-icon>\n }\n @case ('image') {\n <div class=\"g g-1-1 gap-12\">\n <mat-form-field appearance=\"outline\"><mat-label>URL Imagem</mat-label><input matInput\n [(ngModel)]=\"mappingEmptyState.imageUrl\" (ngModelChange)=\"onMappingChanged()\" />\n <mat-error *ngIf=\"isImageUrlRequiredInvalid(mappingEmptyState.imageUrl)\">URL/expr obrigat\u00F3ria</mat-error>\n </mat-form-field>\n </div>\n <div class=\"text-caption muted\" *ngIf=\"!mappingEmptyState.imageUrl\">Defina a URL/expr para renderizar a imagem.</div>\n <praxis-meta-editor-image [model]=\"mappingEmptyState\" (change)=\"onMappingChanged()\"></praxis-meta-editor-image>\n }\n }\n\n <mat-expansion-panel class=\"mat-elevation-z0 advanced-panel\">\n <mat-expansion-panel-header><mat-panel-title>Estilo</mat-panel-title></mat-expansion-panel-header>\n <div class=\"g gap-12 pt-12\">\n <mat-form-field appearance=\"outline\"><mat-label>Classe</mat-label><input matInput\n [(ngModel)]=\"mappingEmptyState.class\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Style</mat-label><input matInput\n [(ngModel)]=\"mappingEmptyState.style\" (ngModelChange)=\"onMappingChanged()\" /></mat-form-field>\n </div>\n </mat-expansion-panel>\n </div>\n </mat-expansion-panel>\n </mat-accordion>\n\n <button mat-flat-button color=\"primary\" (click)=\"applyTemplate()\">Aplicar mapeamento</button>\n <button mat-button (click)=\"inferFromFields()\" [disabled]=\"!fields.length\">Inferir do schema</button>\n <div class=\"g g-auto-220 gap-12 ai-end mt-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Skeleton (quantidade)</mat-label>\n <input matInput type=\"number\" min=\"0\" [(ngModel)]=\"skeletonCountInput\"\n (ngModelChange)=\"onSkeletonChanged($event)\" />\n </mat-form-field>\n </div>\n\n <div class=\"g gap-12 mt-12\">\n <div class=\"g row-flow gap-8 ai-center\">\n <span class=\"section-title mat-subtitle-1\">Pr\u00E9via de tema</span>\n <mat-button-toggle-group [(ngModel)]=\"skinPreviewTheme\" (change)=\"onSkinChanged()\" appearance=\"legacy\">\n <mat-button-toggle [value]=\"'light'\">Claro</mat-button-toggle>\n <mat-button-toggle [value]=\"'dark'\">Escuro</mat-button-toggle>\n <mat-button-toggle [value]=\"'grid'\">Grade</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"skin-preview-wrap\">\n <praxis-list-skin-preview [config]=\"working\" [items]=\"previewData\"\n [theme]=\"skinPreviewTheme\"></praxis-list-skin-preview>\n </div>\n </div>\n </div>\n </div>\n\n </mat-tab>\n <mat-tab label=\"i18n/A11y\">\n <div class=\"editor-content grid gap-3\" *ngIf=\"working?.a11y && working?.events\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Locale padr\u00E3o</mat-label>\n <input matInput [(ngModel)]=\"working.i18n.locale\" (ngModelChange)=\"markDirty()\" placeholder=\"ex.: pt-BR\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Moeda padr\u00E3o</mat-label>\n <input matInput [(ngModel)]=\"working.i18n.currency\" (ngModelChange)=\"markDirty()\" placeholder=\"ex.: BRL\" />\n </mat-form-field>\n <mat-divider class=\"my-8\"></mat-divider>\n <div class=\"subtitle\">Acessibilidade</div>\n <div class=\"g g-auto-220 gap-12 ai-end\">\n <mat-form-field appearance=\"outline\">\n <mat-label>aria-label</mat-label>\n <input matInput [(ngModel)]=\"working!.a11y!.ariaLabel\" (ngModelChange)=\"markDirty()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>aria-labelledby</mat-label>\n <input matInput [(ngModel)]=\"working!.a11y!.ariaLabelledBy\" (ngModelChange)=\"markDirty()\" />\n </mat-form-field>\n </div>\n <div class=\"g g-auto-220 gap-12 ai-end\">\n <mat-slide-toggle [(ngModel)]=\"working!.a11y!.highContrast\" (ngModelChange)=\"markDirty()\">Alto\n contraste</mat-slide-toggle>\n <mat-slide-toggle [(ngModel)]=\"working!.a11y!.reduceMotion\" (ngModelChange)=\"markDirty()\">Reduzir\n movimento</mat-slide-toggle>\n </div>\n <mat-divider class=\"my-8\"></mat-divider>\n <div class=\"subtitle\">Eventos</div>\n <div class=\"g g-auto-220 gap-12 ai-end\">\n <mat-form-field appearance=\"outline\">\n <mat-label>itemClick</mat-label>\n <input matInput [(ngModel)]=\"working!.events!.itemClick\" (ngModelChange)=\"markDirty()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>actionClick</mat-label>\n <input matInput [(ngModel)]=\"working!.events!.actionClick\" (ngModelChange)=\"markDirty()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>selectionChange</mat-label>\n <input matInput [(ngModel)]=\"working!.events!.selectionChange\" (ngModelChange)=\"markDirty()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>loaded</mat-label>\n <input matInput [(ngModel)]=\"working!.events!.loaded\" (ngModelChange)=\"markDirty()\" />\n </mat-form-field>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Sele\u00E7\u00E3o\">\n <div class=\"editor-content grid gap-3\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Modo</mat-label>\n <mat-select [(ngModel)]=\"working.selection.mode\" (ngModelChange)=\"onSelectionChanged()\">\n <mat-option value=\"none\">Sem sele\u00E7\u00E3o</mat-option>\n <mat-option value=\"single\">\u00DAnica</mat-option>\n <mat-option value=\"multiple\">M\u00FAltipla</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Nome no formul\u00E1rio</mat-label>\n <input matInput [(ngModel)]=\"working.selection.formControlName\" (ngModelChange)=\"onSelectionChanged()\" />\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\" matTooltip=\"formControlName\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Caminho no formul\u00E1rio</mat-label>\n <input matInput [(ngModel)]=\"working.selection.formControlPath\" (ngModelChange)=\"onSelectionChanged()\" />\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\" matTooltip=\"formControlPath\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Comparar por (campo)</mat-label>\n <input matInput [(ngModel)]=\"working.selection.compareBy\" (ngModelChange)=\"onSelectionChanged()\" />\n <button mat-icon-button matSuffix type=\"button\" class=\"help-icon-button\" matTooltip=\"Chave unica do item.\">\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Retorno</mat-label>\n <mat-select [(ngModel)]=\"working.selection.return\" (ngModelChange)=\"onSelectionChanged()\">\n <mat-option value=\"value\">value</mat-option>\n <mat-option value=\"item\">item</mat-option>\n <mat-option value=\"id\">id</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </mat-tab>\n <mat-tab label=\"Apar\u00EAncia\">\n <div class=\"editor-content grid gap-3\">\n <div class=\"preset-row g row-flow gap-8\">\n <button mat-button (click)=\"applySkinPreset('pill-soft')\">Pill Soft</button>\n <button mat-button (click)=\"applySkinPreset('gradient-tile')\">Gradient Tile</button>\n <button mat-button (click)=\"applySkinPreset('glass')\">Glass</button>\n <button mat-button (click)=\"applySkinPreset('elevated')\">Elevated</button>\n <button mat-button (click)=\"applySkinPreset('outline')\">Outline</button>\n <button mat-button (click)=\"applySkinPreset('flat')\">Flat</button>\n <button mat-button (click)=\"applySkinPreset('neumorphism')\">Neumorphism</button>\n </div>\n <mat-form-field appearance=\"outline\">\n <mat-label>Estilo</mat-label>\n <mat-select [(ngModel)]=\"working.skin.type\" (ngModelChange)=\"onSkinTypeChanged($event)\">\n <mat-option value=\"pill-soft\">Pill Soft</mat-option>\n <mat-option value=\"gradient-tile\">Gradient Tile</mat-option>\n <mat-option value=\"glass\">Glass</mat-option>\n <mat-option value=\"elevated\">Elevated</mat-option>\n <mat-option value=\"outline\">Outline</mat-option>\n <mat-option value=\"flat\">Flat</mat-option>\n <mat-option value=\"neumorphism\">Neumorphism</mat-option>\n <mat-option value=\"custom\">Custom</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Raio</mat-label>\n <input matInput [(ngModel)]=\"working.skin.radius\" (ngModelChange)=\"onSkinChanged()\"\n placeholder=\"ex.: 1.25rem\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Sombra</mat-label>\n <input matInput [(ngModel)]=\"working.skin.shadow\" (ngModelChange)=\"onSkinChanged()\"\n placeholder=\"ex.: var(--md-sys-elevation-level2)\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Borda</mat-label>\n <input matInput [(ngModel)]=\"working.skin.border\" (ngModelChange)=\"onSkinChanged()\" />\n </mat-form-field>\n <mat-form-field *ngIf=\"working.skin.type==='glass'\" appearance=\"outline\">\n <mat-label>Desfoque</mat-label>\n <input matInput [(ngModel)]=\"working.skin.backdropBlur\" (ngModelChange)=\"onSkinChanged()\"\n placeholder=\"ex.: 8px\" />\n </mat-form-field>\n <div *ngIf=\"working.skin.type==='gradient-tile'\" class=\"g gap-12\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Degrad\u00EA de</mat-label>\n <input matInput [ngModel]=\"working.skin.gradient.from || ''\"\n (ngModelChange)=\"onSkinGradientChanged('from', $event)\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Degrad\u00EA at\u00E9</mat-label>\n <input matInput [ngModel]=\"working.skin.gradient.to || ''\"\n (ngModelChange)=\"onSkinGradientChanged('to', $event)\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>\u00C2ngulo</mat-label>\n <input matInput type=\"number\" [ngModel]=\"working.skin.gradient.angle ?? 135\"\n (ngModelChange)=\"onSkinGradientChanged('angle', $event)\" />\n </mat-form-field>\n </div>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Classe CSS extra (skin.class)</mat-label>\n <input matInput [(ngModel)]=\"working.skin.class\" (ngModelChange)=\"onSkinChanged()\"\n placeholder=\"ex.: my-list-skin\" />\n </mat-form-field>\n\n <div *ngIf=\"working.skin.type==='custom'\" class=\"g g-auto-220 gap-12 ai-end\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Estilo inline (skin.inlineStyle)</mat-label>\n <textarea matInput rows=\"4\" [(ngModel)]=\"working.skin.inlineStyle\" (ngModelChange)=\"onSkinChanged()\"\n [attr.placeholder]=\"':host{--p-list-radius: 1rem}'\"></textarea>\n </mat-form-field>\n <div class=\"text-caption\">\n Exemplo de CSS por classe (adicione no seu styles global):\n <pre class=\"code-block\">.my-list-skin .item-card &#123;\n border-radius: 14px;\n border: 1px solid var(--md-sys-color-outline-variant);\n box-shadow: var(--md-sys-elevation-level2);\n&#125;\n.my-list-skin .mat-mdc-list-item .list-item-content &#123;\n backdrop-filter: blur(6px);\n&#125;</pre>\n </div>\n </div>\n\n\n </div>\n </mat-tab>\n</mat-tab-group>\n", styles: [".confirm-type{display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;font-size:11px;line-height:16px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface-variant)}.confirm-type.danger{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container)}.confirm-type.warning{background:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container)}.confirm-type.info{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}:host{display:block;color:var(--md-sys-color-on-surface)}.list-editor-tabs{--editor-surface: var(--md-sys-color-surface-container-lowest);--editor-border: 1px solid var(--md-sys-color-outline-variant);--editor-radius: var(--md-sys-shape-corner-large, 16px);--editor-muted: var(--md-sys-color-on-surface-variant);--editor-accent: var(--md-sys-color-primary)}.editor-content{padding:16px;background:var(--editor-surface);border:var(--editor-border);border-radius:var(--editor-radius);display:grid;gap:12px}.editor-content .mat-mdc-form-field{width:100%;max-width:none;--mdc-outlined-text-field-container-height: 48px;--mdc-outlined-text-field-outline-color: var(--md-sys-color-outline-variant);--mdc-outlined-text-field-hover-outline-color: var(--md-sys-color-outline);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-error-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-focus-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-hover-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-label-text-color: var(--md-sys-color-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--md-sys-color-on-surface);--mdc-outlined-text-field-supporting-text-color: var(--md-sys-color-on-surface-variant)}.editor-content .mat-mdc-form-field.w-full{max-width:none}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.editor-split{grid-template-columns:minmax(0,1fr);align-items:start}.editor-main,.editor-aside{display:grid;gap:12px}.skin-preview-wrap{border-radius:calc(var(--editor-radius) - 4px);border:var(--editor-border);background:var(--md-sys-color-surface-container);padding:12px}.g{display:grid}.g-auto-220{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.g-auto-200{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}.g-1-auto{grid-template-columns:1fr auto}.row-flow{grid-auto-flow:column}.gap-6{gap:6px}.gap-8{gap:8px}.gap-12{gap:12px}.ai-center{align-items:center}.ai-end{align-items:end}.mt-12{margin-top:12px}.mb-8{margin-bottom:8px}.mb-6{margin-bottom:6px}.my-8{margin:8px 0}.subtitle{margin:8px 0 4px;color:var(--editor-muted);font-weight:500}.section-title{color:var(--editor-muted);font-weight:600}.chips-row{display:flex;flex-wrap:wrap;gap:6px;align-items:center}.error{color:var(--md-sys-color-error);font-size:.85rem}.muted{color:var(--editor-muted)}.text-caption{color:var(--editor-muted);font-size:.8rem}:host ::ng-deep .mat-mdc-select-panel .option-icon{font-size:18px;margin-right:6px;vertical-align:middle}:host ::ng-deep .mat-mdc-select-panel .color-dot{width:10px;height:10px;border-radius:999px;display:inline-block;margin-right:6px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-outline)}:host ::ng-deep .mat-mdc-select-panel .color-primary{background:var(--md-sys-color-primary)}:host ::ng-deep .mat-mdc-select-panel .color-accent{background:var(--md-sys-color-tertiary)}:host ::ng-deep .mat-mdc-select-panel .color-warn{background:var(--md-sys-color-error)}:host ::ng-deep .mat-mdc-select-panel .color-default{background:var(--md-sys-color-outline)}@media(max-width:1024px){.editor-split{grid-template-columns:minmax(0,1fr)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i3$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i3$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.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: i6.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i8.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i10.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i10.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i10.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i10.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i10.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i11.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i11.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i12.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisListSkinPreviewComponent, selector: "praxis-list-skin-preview", inputs: ["config", "items", "theme"] }, { kind: "component", type: PraxisMetaEditorTextComponent, selector: "praxis-meta-editor-text", inputs: ["model", "setPipe"], outputs: ["change"] }, { kind: "component", type: PraxisMetaEditorChipComponent, selector: "praxis-meta-editor-chip", inputs: ["model", "paletteOptions", "colorDotBackground", "isCustomColor", "enableCustomColor"], outputs: ["change"] }, { kind: "component", type: PraxisMetaEditorRatingComponent, selector: "praxis-meta-editor-rating", inputs: ["model", "paletteOptions", "colorDotBackground", "isCustomColor", "enableCustomColor"], outputs: ["change"] }, { kind: "component", type: PraxisMetaEditorCurrencyComponent, selector: "praxis-meta-editor-currency", inputs: ["model"], outputs: ["change"] }, { kind: "component", type: PraxisMetaEditorDateComponent, selector: "praxis-meta-editor-date", inputs: ["model"], outputs: ["change"] }, { kind: "component", type: PraxisMetaEditorIconComponent, selector: "praxis-meta-editor-icon", inputs: ["model", "paletteOptions", "colorDotBackground", "isCustomColor", "enableCustomColor"], outputs: ["change"] }, { kind: "component", type: PraxisMetaEditorImageComponent, selector: "praxis-meta-editor-image", inputs: ["model"], outputs: ["change"] }, { kind: "component", type: PdxColorPickerComponent, selector: "pdx-color-picker", inputs: ["actionsLayout", "activeView", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "clearButton", "disabledMode", "readonlyMode", "visible", "presentationMode", "fillMode", "format", "gradientSettings", "icon", "iconClass", "svgIcon", "paletteSettings", "popupSettings", "preview", "rounded", "size", "tabindex", "views", "maxRecent", "showRecent"], outputs: ["valueChange", "open", "close", "cancel", "activeViewChange", "activeColorClick", "focusEvent", "blurEvent"] }] });
2830
2830
  }
2831
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisListConfigEditor, decorators: [{
2831
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisListConfigEditor, decorators: [{
2832
2832
  type: Component,
2833
2833
  args: [{ selector: 'praxis-list-config-editor', standalone: true, imports: [
2834
2834
  CommonModule,
@@ -4058,10 +4058,10 @@ class PraxisList {
4058
4058
  data,
4059
4059
  };
4060
4060
  }
4061
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisList, deps: [], target: i0.ɵɵFactoryTarget.Component });
4062
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: PraxisList, isStandalone: true, selector: "praxis-list", inputs: { config: "config", listId: "listId", componentInstanceId: "componentInstanceId", form: "form", enableCustomization: "enableCustomization" }, outputs: { itemClick: "itemClick", actionClick: "actionClick", selectionChange: "selectionChange" }, providers: [GenericCrudService, ListDataService], usesOnChanges: true, ngImport: i0, template: "<div class=\"praxis-list-root\" [ngClass]=\"skinClasses\" [attr.data-skin-scope]=\"skinScopeId\"\n [attr.aria-label]=\"config.a11y?.ariaLabel || null\"\n [attr.aria-labelledby]=\"config.a11y?.ariaLabelledBy || null\">\n @if (inlineCss) {\n <style [attr.nonce]=\"cspNonce || null\" [textContent]=\"inlineCss\"></style>\n }\n\n @if (enableCustomization) {\n <div class=\"list-assistant\">\n <button mat-mini-fab color=\"primary\" (click)=\"openConfigEditor()\" matTooltip=\"Editar Configura\u00E7\u00F5es\"\n aria-label=\"Editar Configura\u00E7\u00F5es\">\n <mat-icon [praxisIcon]=\"'edit'\"></mat-icon>\n </button>\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n </div>\n }\n\n <!-- Skeleton while loading -->\n @if ((loading$ | async) && hasSkeleton()) {\n @if (isListVariant()) {\n <mat-list>\n @for (_ of skeletonItems(); track $index; let i = $index) {\n <mat-list-item>\n <div class=\"list-item-content\">\n <div class=\"list-item-leading\">\n <div class=\"skeleton skeleton-avatar\"></div>\n </div>\n <div class=\"list-item-text\">\n <div class=\"skeleton skeleton-line w-60\"></div>\n @if (layoutLines > 1) { <div class=\"skeleton skeleton-line w-40\"></div> }\n </div>\n <div class=\"list-item-trailing\">\n <div class=\"skeleton skeleton-chip\"></div>\n </div>\n </div>\n </mat-list-item>\n }\n </mat-list>\n } @else {\n <div class=\"cards-grid\">\n @for (_ of skeletonItems(); track $index; let i = $index) {\n <div class=\"item-card\">\n <div class=\"list-item-content\">\n <div class=\"list-item-leading\">\n <div class=\"skeleton skeleton-avatar\"></div>\n </div>\n <div class=\"list-item-text\">\n <div class=\"skeleton skeleton-line w-60\"></div>\n @if (layoutLines > 1) { <div class=\"skeleton skeleton-line w-40\"></div> }\n </div>\n <div class=\"list-item-trailing\">\n <div class=\"skeleton skeleton-chip\"></div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n } @else {\n <ng-container *ngTemplateOutlet=\"notLoading\"></ng-container>\n }\n\n <ng-template #notLoading>\n <!-- Empty state -->\n @if (items$ | async; as all) {\n @if (all.length === 0) {\n <div class=\"section-header\">\n @if (emptyStateTemplate(); as empty) {\n @switch (empty.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"empty.value\" [ngClass]=\"empty.class\"\n [color]=\"isThemeColor(empty.color) ? empty.color : undefined\"\n [style.cssText]=\"(empty.style ? empty.style + ';' : '') + iconStyle(empty.color)\"></mat-icon> }\n @case ('image') {\n <span class=\"inline-image\" [ngClass]=\"empty.class\" [style.cssText]=\"empty.style\">\n <img [src]=\"empty.value\" [alt]=\"config.templating?.emptyState?.imageAlt || ''\" />\n @if (empty.badge?.value) { <mat-chip class=\"inline-badge\"\n [color]=\"isThemeColor(empty.badge?.color) ? empty.badge?.color : undefined\"\n [ngClass]=\"(((empty.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(empty.badge?.color, empty.badge?.variant)\">{{ empty.badge?.value }}</mat-chip> }\n </span>\n }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(empty.color) ? empty.color : undefined\"\n [ngClass]=\"[empty.class || '', ((empty.variant || 'filled') === 'outlined') ? 'chip-outlined' : '']\"\n [style.cssText]=\"chipStyle(empty.color, empty.variant) + (empty.style ? ';' + empty.style : '')\">{{ empty.value }}</mat-chip> }\n @case ('rating') {\n <span [ngClass]=\"empty.class\" [style.cssText]=\"empty.style\">\n @for (_ of ratingRange(empty); track $index; let idx = $index) { <mat-icon\n [praxisIcon]=\"starIcon(idx, empty.value)\"\n [color]=\"ratingThemeColor(empty)\"\n [style.cssText]=\"ratingIconStyle(empty)\"></mat-icon> }\n </span>\n }\n @case ('html') { <span [ngClass]=\"empty.class\" [style.cssText]=\"empty.style\" [innerHTML]=\"empty.value\"></span> }\n @default { <span [ngClass]=\"empty.class\" [style.cssText]=\"empty.style\">{{ empty.value }}</span> }\n }\n }\n </div>\n }\n }\n\n <!-- List variant -->\n @if (isListVariant()) {\n <!-- Selection list -->\n @if (isSelectionEnabled()) {\n <mat-selection-list [multiple]=\"config.selection?.mode === 'multiple'\" [formControl]=\"boundControl\"\n (selectionChange)=\"onSelectionChange($event)\">\n @for (section of sections$ | async; track trackBySection($index, section)) {\n @if (section.key) {\n <div class=\"section-header mat-subheader\">\n @if (sectionHeaderTemplate(section.key); as sh) {\n @switch (sh.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"sh.value\" [ngClass]=\"sh.class\"\n [color]=\"isThemeColor(sh.color) ? sh.color : undefined\"\n [style.cssText]=\"(sh.style ? sh.style + ';' : '') + iconStyle(sh.color)\"></mat-icon> }\n @case ('image') {\n <span class=\"inline-image\" [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\">\n <img [src]=\"sh.value\" [alt]=\"config.templating?.sectionHeader?.imageAlt || ''\" />\n @if (sh.badge?.value) { <mat-chip class=\"inline-badge\"\n [color]=\"isThemeColor(sh.badge?.color) ? sh.badge?.color : undefined\"\n [ngClass]=\"(((sh.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(sh.badge?.color, sh.badge?.variant)\">{{ sh.badge?.value }}</mat-chip> }\n </span>\n }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(sh.color) ? sh.color : undefined\"\n [ngClass]=\"[sh.class || '', ((sh.variant || 'filled') === 'outlined') ? 'chip-outlined' : '']\"\n [style.cssText]=\"chipStyle(sh.color, sh.variant) + (sh.style ? ';' + sh.style : '')\">{{ sh.value }}</mat-chip> }\n @case ('rating') {\n <span [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\">\n @for (_ of ratingRange(sh); track $index; let idx = $index) { <mat-icon\n [praxisIcon]=\"starIcon(idx, sh.value)\"\n [color]=\"ratingThemeColor(sh)\"\n [style.cssText]=\"ratingIconStyle(sh)\"></mat-icon> }\n </span>\n }\n @case ('html') { <span [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\" [innerHTML]=\"sh.value\"></span> }\n @default { <span [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\">{{ sh.value }}</span> }\n }\n }\n </div>\n }\n @for (item of section.items; track trackByItem($index, item); let i = $index) {\n <mat-list-option\n [value]=\"item\"\n [attr.aria-label]=\"primary(item)?.value || null\"\n (click)=\"onItemClick(item, i, section.key || undefined)\"\n >\n <div class=\"list-item-content\">\n <div class=\"list-item-leading\">\n @if (leading(item); as lead) {\n @switch (lead.type) {\n @case ('icon') {\n <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\"\n [color]=\"isThemeColor(lead.color) ? lead.color : undefined\"\n [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon>\n }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n @if (lead.badge?.value) {\n <mat-chip class=\"lead-badge\" [color]=\"isThemeColor(lead.badge?.color) ? lead.badge?.color : undefined\"\n [ngClass]=\"(((lead.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(lead.badge?.color, lead.badge?.variant)\">{{ lead.badge?.value }}</mat-chip>\n }\n </div>\n }\n @case ('text') {\n <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span>\n }\n @case ('chip') {\n <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\"\n [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip>\n }\n @case ('rating') {\n <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon\n [praxisIcon]=\"starIcon(idx, lead.value)\"\n [color]=\"ratingThemeColor(lead)\"\n [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> }\n </span>\n }\n @case ('html') {\n <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\" [innerHTML]=\"lead.value\"></span>\n }\n @default {\n <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span>\n }\n }\n } @else {\n <span class=\"leading-placeholder\"></span>\n }\n </div>\n <div class=\"list-item-text\">\n <div class=\"primary\" [ngClass]=\"primary(item)?.class\" [style.cssText]=\"primary(item)?.style\">{{\n primary(item)?.value }}</div>\n @if (layoutLines > 1) { <div class=\"secondary\" [ngClass]=\"secondary(item)?.class\"\n [style.cssText]=\"secondary(item)?.style\">{{ secondary(item)?.value }}</div> }\n @if (meta(item); as m) {\n @if ((config.templating?.metaPlacement === 'line' && (m?.type === 'text' || m?.type === 'date' || m?.type\n === 'currency')) || (layoutLines > 2 && (m?.type === 'text' || m?.type === 'date' || m?.type ===\n 'currency'))) {\n <div class=\"tertiary\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (config.templating?.metaPrefixIcon; as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n {{ m.value }}\n </div>\n }\n }\n @if (featuresVisible()) {\n <div class=\"features\">\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{\n featureLabel(item, f.expr) }}</span> }\n </span>\n }\n </div>\n }\n </div>\n <div class=\"list-item-trailing\">\n @if (meta(item); as m) {\n @if (!(((config.templating?.metaPlacement === 'line') || (layoutLines > 2)) && (m?.type === 'text' ||\n m?.type === 'date' || m?.type === 'currency'))) {\n <div class=\"meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\"\n [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon\n [praxisIcon]=\"starIcon(idx, m.value)\"\n [color]=\"ratingThemeColor(m)\"\n [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>@if (config.templating?.metaPrefixIcon; as mpi2) { <mat-icon [praxisIcon]=\"mpi2\"></mat-icon> }{{\n m.value }}</span> }\n }\n </div>\n }\n }\n @if (trailing(item); as tr) {\n <div class=\"trailing\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n @switch (tr.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\"\n [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip> }\n @case ('icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n <img [src]=\"tr.value\" [alt]=\"config.templating?.trailing?.imageAlt || ''\" />\n @if (tr.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(tr.badge?.color) ? tr.badge?.color : undefined\"\n [ngClass]=\"(((tr.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(tr.badge?.color, tr.badge?.variant)\">{{ tr.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('rating') { @for (_ of ratingRange(tr); track $index; let idx = $index) { <mat-icon\n [praxisIcon]=\"starIcon(idx, tr.value)\"\n [color]=\"ratingThemeColor(tr)\"\n [style.cssText]=\"ratingIconStyle(tr)\"></mat-icon> } }\n @case ('html') { <span [innerHTML]=\"tr.value\"></span> }\n @default { <span>{{ tr.value }}</span> }\n }\n </div>\n }\n @if ((visibleActions(item) || []).length) {\n <div\n class=\"list-item-actions\"\n (click)=\"$event.stopPropagation()\"\n (keydown.enter)=\"onActionKeydown($event)\"\n (keydown.space)=\"onActionKeydown($event)\">\n @for (action of visibleActions(item); let aidx = $index; track action?.id ?? $index) {\n @if ((action.kind || 'icon') === 'icon') {\n <button mat-icon-button [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n (click)=\"onActionClick($event, action.id, item, i)\" [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n <mat-icon [praxisIcon]=\"action.icon\" [style.cssText]=\"iconStyle(action.color)\"></mat-icon>\n }\n </button>\n } @else {\n @if (action.buttonVariant === 'stroked') { <button mat-stroked-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'stroked')\"\n (click)=\"onActionClick($event, action.id, item, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (action.buttonVariant === 'raised') { <button mat-raised-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'raised')\"\n (click)=\"onActionClick($event, action.id, item, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (!action.buttonVariant || action.buttonVariant === 'flat') { <button mat-flat-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'flat')\"\n (click)=\"onActionClick($event, action.id, item, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n }\n }\n </div>\n }\n </div>\n </div>\n </mat-list-option>\n @if ((config.layout?.dividers === 'all' || config.layout?.dividers === 'between') && i < section.items.length - 1) { <mat-divider></mat-divider> }\n }\n }\n </mat-selection-list>\n } @else {\n <ng-container *ngTemplateOutlet=\"readList\"></ng-container>\n }\n\n <!-- Read-only list -->\n <ng-template #readList>\n <mat-list>\n @for (section of sections$ | async; track trackBySection($index, section); let sidx = $index) {\n @if (section.key) {\n <div class=\"section-header mat-subheader\">\n @if (sectionHeaderTemplate(section.key); as sh) {\n @switch (sh.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"sh.value\" [ngClass]=\"sh.class\"\n [color]=\"isThemeColor(sh.color) ? sh.color : undefined\"\n [style.cssText]=\"(sh.style ? sh.style + ';' : '') + iconStyle(sh.color)\"></mat-icon>\n }\n @case ('image') {\n <span class=\"inline-image\" [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\">\n <img [src]=\"sh.value\" [alt]=\"config.templating?.sectionHeader?.imageAlt || ''\" />\n @if (sh.badge?.value) { <mat-chip class=\"inline-badge\"\n [color]=\"isThemeColor(sh.badge?.color) ? sh.badge?.color : undefined\"\n [ngClass]=\"(((sh.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(sh.badge?.color, sh.badge?.variant)\">{{ sh.badge?.value }}</mat-chip> }\n </span>\n }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(sh.color) ? sh.color : undefined\"\n [ngClass]=\"[sh.class || '', ((sh.variant || 'filled') === 'outlined') ? 'chip-outlined' : '']\"\n [style.cssText]=\"chipStyle(sh.color, sh.variant) + (sh.style ? ';' + sh.style : '')\">{{ sh.value }}</mat-chip> }\n @case ('rating') {\n <span [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\">\n @for (_ of ratingRange(sh); track $index; let idx = $index) { <mat-icon\n [praxisIcon]=\"starIcon(idx, sh.value)\"\n [color]=\"ratingThemeColor(sh)\"\n [style.cssText]=\"ratingIconStyle(sh)\"></mat-icon> }\n </span>\n }\n @case ('html') { <span [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\" [innerHTML]=\"sh.value\"></span> }\n @default { <span [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\">{{ sh.value }}</span> }\n }\n }\n </div>\n }\n @for (item of section.items; track trackByItem($index, item); let i = $index) {\n <mat-list-item\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"primary(item)?.value || null\"\n (click)=\"onItemClick(item, i, section.key || undefined)\"\n (keydown.enter)=\"onItemClick(item, i, section.key || undefined)\"\n (keydown.space)=\"$event.preventDefault(); onItemClick(item, i, section.key || undefined)\"\n >\n <div class=\"list-item-content\">\n <div class=\"list-item-leading\">\n @if (leading(item); as lead) {\n @switch (lead.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\"\n [color]=\"isThemeColor(lead.color) ? lead.color : undefined\"\n [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon>\n }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n @if (lead.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(lead.badge?.color) ? lead.badge?.color : undefined\"\n [ngClass]=\"(((lead.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(lead.badge?.color, lead.badge?.variant)\">{{ lead.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('text') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\"\n [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx,\n lead.value)\" [color]=\"ratingThemeColor(lead)\" [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> } }\n @case ('html') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\"\n [innerHTML]=\"lead.value\"></span> }\n @default { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n }\n } @else {\n <span class=\"leading-placeholder\"></span>\n }\n </div>\n <div class=\"list-item-text\">\n <div class=\"primary\" [ngClass]=\"primary(item)?.class\" [style.cssText]=\"primary(item)?.style\">{{\n primary(item)?.value }}</div>\n @if (layoutLines > 1) { <div class=\"secondary\" [ngClass]=\"secondary(item)?.class\"\n [style.cssText]=\"secondary(item)?.style\">{{ secondary(item)?.value }}</div> }\n @if (meta(item); as m) {\n @if ((config.templating?.metaPlacement === 'line' && (m?.type === 'text' || m?.type === 'date' || m?.type\n === 'currency')) || (layoutLines > 2 && (m?.type === 'text' || m?.type === 'date' || m?.type ===\n 'currency'))) {\n <div class=\"tertiary\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (config.templating?.metaPrefixIcon; as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n {{ m.value }}\n </div>\n }\n }\n @if (featuresVisible()) {\n <div class=\"features\">\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{ featureLabel(item, f.expr) }}</span> }\n </span>\n }\n </div>\n }\n </div>\n <div class=\"list-item-trailing\">\n @if (meta(item); as m) {\n @if (!(((config.templating?.metaPlacement === 'line') || (layoutLines > 2)) && (m?.type === 'text' ||\n m?.type === 'date' || m?.type === 'currency'))) {\n <div class=\"meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\" [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx,\n m.value)\" [color]=\"ratingThemeColor(m)\" [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>@if (config.templating?.metaPrefixIcon; as mpi2) { <mat-icon [praxisIcon]=\"mpi2\"></mat-icon> }{{ m.value }}</span> }\n }\n </div>\n }\n }\n @if (trailing(item); as tr) {\n <div class=\"trailing\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n @switch (tr.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip> }\n @case ('icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n <img [src]=\"tr.value\" [alt]=\"config.templating?.trailing?.imageAlt || ''\" />\n @if (tr.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(tr.badge?.color) ? tr.badge?.color : undefined\"\n [ngClass]=\"(((tr.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(tr.badge?.color, tr.badge?.variant)\">{{ tr.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('rating') { @for (_ of ratingRange(tr); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx,\n tr.value)\" [color]=\"ratingThemeColor(tr)\" [style.cssText]=\"ratingIconStyle(tr)\"></mat-icon> } }\n @case ('html') { <span [innerHTML]=\"tr.value\"></span> }\n @default { <span>{{ tr.value }}</span> }\n }\n </div>\n }\n @if ((visibleActions(item) || []).length) {\n <div\n class=\"list-item-actions\"\n (click)=\"$event.stopPropagation()\"\n (keydown.enter)=\"onActionKeydown($event)\"\n (keydown.space)=\"onActionKeydown($event)\">\n @for (action of visibleActions(item); let aidx = $index; track action?.id ?? $index) {\n @if ((action.kind || 'icon') === 'icon') {\n <button mat-icon-button [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n (click)=\"onActionClick($event, action.id, item, i)\" [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n <mat-icon [praxisIcon]=\"action.icon\" [style.cssText]=\"iconStyle(action.color)\"></mat-icon>\n }\n </button>\n } @else {\n @if (action.buttonVariant === 'stroked') { <button mat-stroked-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'stroked')\"\n (click)=\"onActionClick($event, action.id, item, i)\" [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (action.buttonVariant === 'raised') { <button mat-raised-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'raised')\"\n (click)=\"onActionClick($event, action.id, item, i)\" [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (!action.buttonVariant || action.buttonVariant === 'flat') { <button mat-flat-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'flat')\"\n (click)=\"onActionClick($event, action.id, item, i)\" [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n }\n }\n </div>\n }\n </div>\n </div>\n </mat-list-item>\n @if ((config.layout?.dividers === 'all' || config.layout?.dividers === 'between') && i < section.items.length - 1) { <mat-divider></mat-divider> }\n }\n }\n </mat-list>\n </ng-template>\n } @else if (isTilesVariant()) {\n <ng-container *ngTemplateOutlet=\"tilesVariant\"></ng-container>\n } @else {\n <ng-container *ngTemplateOutlet=\"cardsVariant\"></ng-container>\n }\n\n <!-- Cards variant -->\n <ng-template #cardsVariant>\n <div class=\"cards-grid\">\n @for (it of (items$ | async) ?? []; track $index; let i = $index) {\n <div\n class=\"item-card\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"primary(it)?.value || null\"\n (click)=\"onItemClick(it, i)\"\n (keydown.enter)=\"onItemClick(it, i)\"\n (keydown.space)=\"$event.preventDefault(); onItemClick(it, i)\"\n >\n <div class=\"list-item-content\">\n <div class=\"list-item-leading\">\n @if (leading(it); as lead) {\n @switch (lead.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\"\n [color]=\"isThemeColor(lead.color) ? lead.color : undefined\"\n [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon>\n }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n @if (lead.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(lead.badge?.color) ? lead.badge?.color : undefined\"\n [ngClass]=\"(((lead.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(lead.badge?.color, lead.badge?.variant)\">{{ lead.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('text') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\"\n [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx,\n lead.value)\" [color]=\"ratingThemeColor(lead)\" [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> } }\n @case ('html') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\"\n [innerHTML]=\"lead.value\"></span> }\n @default { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n }\n } @else {\n <span class=\"leading-placeholder\"></span>\n }\n </div>\n <div class=\"list-item-text\">\n <div class=\"primary\" [ngClass]=\"primary(it)?.class\" [style.cssText]=\"primary(it)?.style\">{{\n primary(it)?.value }}</div>\n @if (layoutLines > 1) { <div class=\"secondary\" [ngClass]=\"secondary(it)?.class\"\n [style.cssText]=\"secondary(it)?.style\">{{ secondary(it)?.value }}</div> }\n @if (meta(it); as m) {\n @if ((config.templating?.metaPlacement === 'line' && (m?.type === 'text' || m?.type === 'date' || m?.type\n === 'currency')) || (layoutLines > 2 && (m?.type === 'text' || m?.type === 'date' || m?.type ===\n 'currency'))) {\n <div class=\"tertiary\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (config.templating?.metaPrefixIcon; as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n {{ m.value }}\n </div>\n }\n }\n @if (featuresVisible()) {\n <div class=\"features\">\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{\n featureLabel(it, f.expr) }}</span> }\n </span>\n }\n </div>\n }\n </div>\n <div class=\"list-item-trailing\">\n @if (meta(it); as m) {\n @if (!(((config.templating?.metaPlacement === 'line') || (layoutLines > 2)) && (m?.type === 'text' ||\n m?.type === 'date' || m?.type === 'currency'))) {\n <div class=\"meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\"\n [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx,\n m.value)\" [color]=\"ratingThemeColor(m)\" [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>@if (config.templating?.metaPrefixIcon; as mpi2) { <mat-icon [praxisIcon]=\"mpi2\"></mat-icon> }{{ m.value }}</span> }\n }\n </div>\n }\n }\n @if (trailing(it); as tr) {\n @if ((config.templating?.statusPosition || 'inline') === 'top-right' && (tr?.type === 'chip' || tr?.type\n === 'icon')) {\n <div class=\"status-overlay\">\n @if (tr?.type === 'chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\"\n [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip>\n }\n @if (tr?.type === 'icon') { <mat-icon [praxisIcon]=\"tr.value\"\n [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n </div>\n } @else {\n <div class=\"trailing\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n @switch (tr.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\"\n [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip>\n }\n @case ('icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n <img [src]=\"tr.value\" [alt]=\"config.templating?.trailing?.imageAlt || ''\" />\n @if (tr.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(tr.badge?.color) ? tr.badge?.color : undefined\"\n [ngClass]=\"(((tr.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(tr.badge?.color, tr.badge?.variant)\">{{ tr.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('rating') { @for (_ of ratingRange(tr); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx,\n tr.value)\" [color]=\"ratingThemeColor(tr)\" [style.cssText]=\"ratingIconStyle(tr)\"></mat-icon> } }\n @case ('html') { <span [innerHTML]=\"tr.value\"></span> }\n @default { <span>{{ tr.value }}</span> }\n }\n </div>\n }\n }\n </div>\n </div>\n <div\n class=\"card-actions\"\n (click)=\"$event.stopPropagation()\"\n (keydown.enter)=\"onActionKeydown($event)\"\n (keydown.space)=\"onActionKeydown($event)\">\n @for (action of visibleActions(it); let aidx = $index; track action?.id ?? $index) {\n @if ((action.kind || 'icon') === 'icon') {\n <button mat-icon-button [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n (click)=\"onActionClick($event, action.id, it, i)\" [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, it, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n <mat-icon [praxisIcon]=\"action.icon\" [style.cssText]=\"iconStyle(action.color)\"></mat-icon>\n }\n </button>\n } @else {\n @if (action.buttonVariant === 'stroked') { <button mat-stroked-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'stroked')\"\n (click)=\"onActionClick($event, action.id, it, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, it, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (action.buttonVariant === 'raised') { <button mat-raised-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'raised')\"\n (click)=\"onActionClick($event, action.id, it, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, it, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (!action.buttonVariant || action.buttonVariant === 'flat') { <button mat-flat-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'flat')\"\n (click)=\"onActionClick($event, action.id, it, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, it, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n }\n }\n </div>\n </div>\n }\n </div>\n </ng-template>\n\n <!-- Tiles variant -->\n <ng-template #tilesVariant>\n <div class=\"tiles-grid\">\n @for (it of (items$ | async) ?? []; track $index; let i = $index) {\n <div\n class=\"item-tile\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"primary(it)?.value || null\"\n (click)=\"onItemClick(it, i)\"\n (keydown.enter)=\"onItemClick(it, i)\"\n (keydown.space)=\"$event.preventDefault(); onItemClick(it, i)\"\n >\n <div class=\"tile-media\">\n @if (leading(it); as lead) {\n @switch (lead.type) {\n @case ('image') {\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n }\n @case ('icon') { <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\"\n [color]=\"isThemeColor(lead.color) ? lead.color : undefined\"\n [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon> }\n @case ('text') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip> }\n @case ('rating') {\n <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, lead.value)\" [color]=\"ratingThemeColor(lead)\" [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> }\n </span>\n }\n @case ('html') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\" [innerHTML]=\"lead.value\"></span> }\n @default { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n }\n }\n </div>\n\n @if (trailing(it); as tr) {\n @if ((config.templating?.statusPosition || 'inline') === 'top-right' && (tr?.type === 'chip' || tr?.type === 'icon')) {\n <div class=\"tile-status\">\n @if (tr?.type === 'chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip> }\n @if (tr?.type === 'icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n </div>\n }\n }\n\n <div class=\"tile-body\">\n <div class=\"primary\" [ngClass]=\"primary(it)?.class\" [style.cssText]=\"primary(it)?.style\">{{ primary(it)?.value }}</div>\n @if (layoutLines > 1) { <div class=\"secondary\" [ngClass]=\"secondary(it)?.class\" [style.cssText]=\"secondary(it)?.style\">{{ secondary(it)?.value }}</div> }\n\n @if (meta(it); as m) {\n <div class=\"tile-meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (config.templating?.metaPrefixIcon; as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\" [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, m.value)\" [color]=\"ratingThemeColor(m)\" [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>{{ m.value }}</span> }\n }\n </div>\n }\n\n @if (featuresVisible()) {\n <div class=\"tiles-features\">\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{ featureLabel(it, f.expr) }}</span> }\n </span>\n }\n </div>\n }\n\n @if (trailing(it); as tr2) {\n @if (!((config.templating?.statusPosition || 'inline') === 'top-right' && (tr2?.type === 'chip' || tr2?.type === 'icon'))) {\n <div class=\"tile-trailing\" [ngClass]=\"tr2.class\" [style.cssText]=\"tr2.style\">\n @switch (tr2.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr2.color) ? tr2.color : undefined\" [ngClass]=\"((tr2.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr2.color, tr2.variant)\">{{ tr2.value }}</mat-chip> }\n @case ('icon') { <mat-icon [praxisIcon]=\"tr2.value\" [color]=\"isThemeColor(tr2.color) ? tr2.color : undefined\" [style.cssText]=\"iconStyle(tr2.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"tr2.value\" [alt]=\"tr2.imageAlt || ''\" /></span> }\n @case ('rating') { @for (_ of ratingRange(tr2); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, tr2.value)\" [color]=\"ratingThemeColor(tr2)\" [style.cssText]=\"ratingIconStyle(tr2)\"></mat-icon> } }\n @case ('html') { <span [innerHTML]=\"tr2.value\"></span> }\n @default { <span>{{ tr2.value }}</span> }\n }\n </div>\n }\n }\n </div>\n\n @if ((visibleActions(it) || []).length) {\n <div\n class=\"tile-actions\"\n (click)=\"$event.stopPropagation()\"\n (keydown.enter)=\"onActionKeydown($event)\"\n (keydown.space)=\"onActionKeydown($event)\">\n @for (action of visibleActions(it); let aidx = $index; track action?.id ?? $index) {\n @if ((action.kind || 'icon') === 'icon') {\n <button mat-icon-button [color]=\"isThemeColor(action.color) ? action.color : undefined\" (click)=\"onActionClick($event, action.id, it, i)\" [attr.aria-label]=\"action.label || action.id\" [disabled]=\"isActionLoading(action.id, it, i)\" [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n <mat-icon [praxisIcon]=\"action.icon\" [style.cssText]=\"iconStyle(action.color)\"></mat-icon>\n }\n </button>\n } @else {\n @if (action.buttonVariant === 'stroked') { <button mat-stroked-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'stroked')\"\n (click)=\"onActionClick($event, action.id, it, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, it, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (action.buttonVariant === 'raised') { <button mat-raised-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'raised')\"\n (click)=\"onActionClick($event, action.id, it, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, it, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (!action.buttonVariant || action.buttonVariant === 'flat') { <button mat-flat-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'flat')\"\n (click)=\"onActionClick($event, action.id, it, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, it, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n }\n }\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n\n <!-- Simple pagination controls for remote data -->\n @if (config.dataSource?.resourcePath) {\n <div class=\"paginator\">\n <div class=\"paginator-controls\">\n <button mat-stroked-button color=\"primary\" (click)=\"prevPage()\">Anterior</button>\n <button mat-stroked-button color=\"primary\" (click)=\"nextPage()\">Pr\u00F3ximo</button>\n <mat-form-field class=\"paginator-page-size\" appearance=\"outline\">\n <mat-label>Tam. p\u00E1gina</mat-label>\n <mat-select (selectionChange)=\"setPageSize($event.value)\" [value]=\"config.layout?.pageSize || 10\">\n <mat-option [value]=\"6\">6</mat-option>\n <mat-option [value]=\"8\">8</mat-option>\n <mat-option [value]=\"12\">12</mat-option>\n <mat-option [value]=\"24\">24</mat-option>\n </mat-select>\n </mat-form-field>\n @if (config.ui?.showSort) {\n <mat-form-field class=\"paginator-sort\" appearance=\"outline\">\n <mat-label>Ordenar</mat-label>\n <mat-select (selectionChange)=\"onSortChange($event.value)\">\n @for (op of (config.ui?.sortOptions || []); track $index) {\n <mat-option [value]=\"sortOptionValue(op)\">{{ sortOptionLabel(op) }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n @if (config.ui?.showSearch && config.ui?.searchField) {\n <mat-form-field class=\"paginator-search\" appearance=\"outline\">\n <mat-label>{{ config.ui?.searchPlaceholder || 'Buscar' }}</mat-label>\n <input matInput type=\"search\" (input)=\"onSearchInput($any($event.target).value)\" />\n </mat-form-field>\n }\n </div>\n <div class=\"paginator-meta\">\n @if ((config.ui?.showRange ?? true)) {\n @if (page$ | async; as ps) {\n @if (total$ | async; as total) {\n @if (items$ | async; as curr) {\n <span class=\"muted\">{{ (total || 0) > 0 ? rangeStart(ps) : 0 }}\u2013{{ rangeEnd(curr?.length || 0, ps, total || 0) }} de {{ total || 0\n }}</span>\n }\n }\n }\n } @else {\n @if (total$ | async; as total2) { <span class=\"muted\">Total: {{ total2 }}</span> }\n }\n </div>\n </div>\n }\n </ng-template>\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block}.praxis-list-root{--p-list-radius: var(--md-sys-shape-corner-medium, 16px);--p-list-shadow: var(--md-sys-elevation-level2);--p-list-border: 1px solid var(--md-sys-color-outline-variant);--p-list-blur: 10px;--p-list-surface: var(--md-sys-color-surface-container);--p-list-surface-low: var(--md-sys-color-surface);--p-list-surface-high: var(--md-sys-color-surface-container-high, var(--md-sys-color-surface-container));--p-list-foreground: var(--md-sys-color-on-surface);--p-list-foreground-muted: var(--md-sys-color-on-surface-variant);--p-list-accent: var(--md-sys-color-primary);--p-list-accent-weak: var(--md-sys-color-primary-container);--p-list-item-surface: var(--md-sys-color-surface-container-low, var(--md-sys-color-surface));--p-list-item-border: 1px solid var(--md-sys-color-outline-variant);--p-list-item-hover-surface: var(--md-sys-color-surface-container-low);--p-list-item-active-surface: var(--md-sys-color-surface-container);--p-list-item-selected-surface: var(--md-sys-color-surface-container);--p-list-grad-from: var(--md-sys-color-primary-container);--p-list-grad-to: var(--md-sys-color-tertiary-container);--p-list-grad-angle: 135deg;--p-list-grad-foreground: var(--md-sys-color-on-primary);--p-list-grad-foreground-muted: var(--md-sys-color-on-primary);--p-list-leading-width: 40px;--p-list-trailing-min-width: 140px;--p-list-item-gap: 12px;--p-list-item-padding-x: 16px;--p-list-item-padding-y: 12px;--p-list-meta-size: .95rem;--p-list-meta-weight: 500;--p-list-chip-height: 22px;--p-list-chip-font-size: 12px;--p-list-trailing-padding-right: 12px;--p-list-tile-minW: 240px;--p-list-tile-gap: 16px;--p-list-tile-padding: 16px;--p-list-tile-radius: 16px;--p-list-tile-media-radius: 12px;--p-list-tile-media-ratio: 1 / 1;--p-list-tile-hover-overlay: .04;--p-list-tile-press-overlay: .08;--p-list-tile-press-scale: .99}.list-assistant{display:flex;justify-content:flex-end;gap:8px;padding:4px 4px 8px}.action-loading{opacity:.65}.action-spinner{width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center}.action-loading .mat-mdc-button-touch-target,.action-loading .mdc-button__label{opacity:.7}.skin-elevated,.skin-outline,.skin-flat,.skin-neumorphism{--p-list-item-surface: var(--mdc-elevated-card-container-color, var(--p-list-surface));--p-list-item-border: var(--p-list-border)}.skin-elevated .item-card,.skin-outline .item-card,.skin-flat .item-card,.skin-neumorphism .item-card{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:var(--p-list-radius);box-shadow:var(--p-list-shadow);border:var(--p-list-border)}.skin-elevated .item-tile,.skin-outline .item-tile,.skin-flat .item-tile,.skin-neumorphism .item-tile{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));box-shadow:var(--p-list-shadow);border:var(--p-list-border)}.skin-elevated .mat-mdc-list-item .list-item-content,.skin-outline .mat-mdc-list-item .list-item-content,.skin-flat .mat-mdc-list-item .list-item-content,.skin-neumorphism .mat-mdc-list-item .list-item-content{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:calc(var(--p-list-radius) * .75);box-shadow:var(--p-list-shadow);border:var(--p-list-item-border);color:var(--p-list-foreground)}.skin-outline{--p-list-shadow: none;--p-list-border: 1px solid var(--md-sys-color-outline)}.skin-flat{--p-list-shadow: none;--p-list-border: 1px solid var(--md-sys-color-outline-variant)}.skin-neumorphism{--p-list-shadow: var(--md-sys-elevation-level2);--p-list-border: 1px solid var(--md-sys-color-outline-variant);--p-list-radius: 1.25rem}.skin-pill-soft .item-card,.skin-pill-soft .item-tile{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:calc(var(--p-list-radius) * 1.3);box-shadow:var(--md-sys-elevation-level1);border:var(--p-list-border)}.skin-pill-soft .mat-mdc-list-item .list-item-content{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:calc(var(--p-list-radius) * 1.3);box-shadow:var(--md-sys-elevation-level1);border:var(--p-list-border);color:var(--p-list-foreground)}.skin-gradient-tile{--p-list-foreground: var(--p-list-grad-foreground);--p-list-foreground-muted: var(--p-list-grad-foreground-muted);--p-list-item-hover-surface: linear-gradient( var(--p-list-grad-angle), var(--p-list-grad-from), var(--p-list-grad-to) );--p-list-item-active-surface: linear-gradient( var(--p-list-grad-angle), var(--p-list-grad-from), var(--p-list-grad-to) );--p-list-item-selected-surface: linear-gradient( var(--p-list-grad-angle), var(--p-list-grad-from), var(--p-list-grad-to) )}.skin-gradient-tile .item-card,.skin-gradient-tile .item-tile,.skin-gradient-tile .mat-mdc-list-item .list-item-content{background:linear-gradient(var(--p-list-grad-angle),var(--p-list-grad-from),var(--p-list-grad-to));border-radius:var(--p-list-radius);color:var(--p-list-foreground)}.skin-glass .item-card,.skin-glass .item-tile{background:var(--md-sys-color-surface-container-low);border-radius:var(--p-list-radius);border:1px solid var(--md-sys-color-outline-variant);backdrop-filter:blur(var(--p-list-blur));-webkit-backdrop-filter:blur(var(--p-list-blur))}.skin-glass .mat-mdc-list-item .list-item-content{background:var(--md-sys-color-surface-container-low);border-radius:var(--p-list-radius);border:1px solid var(--md-sys-color-outline-variant);backdrop-filter:blur(var(--p-list-blur));-webkit-backdrop-filter:blur(var(--p-list-blur));color:var(--p-list-foreground)}.density-compact .mat-mdc-list-item,.density-compact .item-card{--p-list-item-padding-y: 8px;--p-list-item-padding-x: 12px;--p-list-item-gap: 10px}.density-comfortable .mat-mdc-list-item,.density-comfortable .item-card{--p-list-item-padding-y: 10px;--p-list-item-padding-x: 14px;--p-list-item-gap: 12px}.praxis-list-root.lines-3 .mat-mdc-list-item,.praxis-list-root.lines-3 .mat-mdc-list-option{min-height:76px}.density-compact{--p-list-tile-gap: 12px;--p-list-tile-padding: 12px;--p-list-tile-minW: 200px}.density-comfortable{--p-list-tile-gap: 16px;--p-list-tile-padding: 16px}.list-item-content{display:grid;grid-template-columns:var(--p-list-leading-width) minmax(0,1fr) minmax(var(--p-list-trailing-min-width),max-content);align-items:center;gap:var(--p-list-item-gap);padding:var(--p-list-item-padding-y) var(--p-list-item-padding-x);width:100%;min-width:0;border-radius:calc(var(--p-list-radius) * .75);overflow:visible}.list-item-leading{display:flex;align-items:center;justify-content:center;min-height:100%}.leading-placeholder{width:24px;height:24px;display:inline-block}.list-item-text{min-width:0;display:grid;align-content:center;gap:4px}.list-item-trailing{min-width:0;display:flex;flex-direction:column;align-items:flex-end;justify-content:center;gap:6px;text-align:end;padding-right:var(--p-list-trailing-padding-right)}.list-item-actions{display:flex;align-items:center;justify-content:flex-end;gap:4px;flex-wrap:wrap}.mat-mdc-list-item .list-item-content{background:var(--p-list-item-surface);border:var(--p-list-item-border);transition:background .15s ease,box-shadow .15s ease,transform .15s ease}.mat-mdc-list-item,.mat-mdc-list-option{height:auto;align-items:stretch;overflow:visible}.mdc-list-item{overflow:visible}.density-compact .mat-mdc-list-item,.density-compact .mat-mdc-list-option{min-height:44px}.density-comfortable .mat-mdc-list-item,.density-comfortable .mat-mdc-list-option{min-height:52px}.praxis-list-root:not(.density-compact):not(.density-comfortable) .mat-mdc-list-item,.praxis-list-root:not(.density-compact):not(.density-comfortable) .mat-mdc-list-option{min-height:56px}.mat-mdc-list-item .mdc-list-item__content,.mat-mdc-list-option .mdc-list-item__content,.mat-mdc-list-item .mdc-list-item__primary-text,.mat-mdc-list-option .mdc-list-item__primary-text{display:block!important;width:100%!important;height:auto!important;padding:0!important;margin:0!important;overflow:visible!important;box-sizing:border-box}.mat-mdc-list-item,.mat-mdc-list-option{padding:0!important;box-sizing:border-box}.mat-mdc-list-item:hover .list-item-content,.mat-mdc-list-option:hover .list-item-content{background:var(--p-list-item-hover-surface)}.mat-mdc-list-item:active .list-item-content,.mat-mdc-list-option:active .list-item-content{background:var(--p-list-item-active-surface)}.mat-mdc-list-option.mdc-list-item--selected .list-item-content{background:var(--p-list-item-selected-surface);border-color:var(--md-sys-color-outline-variant)}.mat-mdc-list-option.cdk-keyboard-focused .list-item-content,.mat-mdc-list-option.cdk-focused .list-item-content{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.mat-mdc-list-item:focus-visible .list-item-content{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.lead-image{position:relative;width:96px;height:72px;border-radius:12px;overflow:hidden}.lead-image img{width:100%;height:100%;object-fit:cover;display:block}.lead-image .lead-badge{position:absolute;left:8px;bottom:8px}.inline-image{position:relative;width:20px;height:20px;border-radius:4px;overflow:hidden;display:inline-block;vertical-align:middle}.inline-image img{width:100%;height:100%;object-fit:cover;display:block}.inline-image .inline-badge{position:absolute;left:2px;bottom:2px}.model-media .lead-image{width:136px;height:96px;border-radius:16px}.model-media .list-item-content{gap:16px}.model-media .item-card{--p-list-leading-width: 136px}.model-hotel .lead-image{width:160px;height:110px;border-radius:18px}.model-hotel .item-card{--p-list-leading-width: 160px}.primary,.secondary{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.primary{-webkit-line-clamp:1;font-weight:600;color:var(--p-list-foreground)}.secondary{-webkit-line-clamp:1;color:var(--p-list-foreground-muted)}.lines-3 .tertiary{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.item-tile .primary{-webkit-line-clamp:2;font-size:.95rem;line-height:1.25rem}.item-tile .secondary{-webkit-line-clamp:2;font-size:.8rem;line-height:1.1rem}.tertiary{color:var(--p-list-foreground-muted)}.features{display:flex;flex-wrap:wrap;gap:12px;margin-top:6px;color:inherit}.feature{display:inline-flex;align-items:center;gap:6px}.meta{color:var(--p-list-foreground);font-size:var(--p-list-meta-size);font-weight:var(--p-list-meta-weight);font-variant-numeric:tabular-nums;white-space:nowrap}.trailing{color:var(--p-list-foreground-muted);margin-left:0;white-space:nowrap}.section-header{font-size:.85rem;color:var(--p-list-foreground-muted);padding:8px 12px}.praxis-list-root .mat-divider{margin-left:var(--p-list-item-padding-x);margin-right:var(--p-list-item-padding-x)}.cards-grid,.tiles-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--p-list-tile-minW),1fr));gap:var(--p-list-tile-gap)}.item-tile{position:relative;display:flex;flex-direction:column;gap:10px;padding:var(--p-list-tile-padding);border-radius:var(--p-list-tile-radius);background:var(--p-list-surface);border:var(--p-list-border);color:var(--p-list-foreground);cursor:pointer;min-height:160px;transition:box-shadow .16s ease-out,border-color .16s ease-out,transform .12s ease-out,background .16s ease-out}.item-tile:hover{box-shadow:var(--md-sys-elevation-level2);border-color:var(--md-sys-color-outline-variant);background:var(--p-list-item-hover-surface)}.item-tile:active{transform:scale(var(--p-list-tile-press-scale));background:var(--p-list-item-active-surface)}.item-tile:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.tile-media{width:100%;aspect-ratio:var(--p-list-tile-media-ratio);border-radius:var(--p-list-tile-media-radius);background:var(--p-list-item-surface);border:1px solid var(--md-sys-color-outline-variant);display:grid;place-items:center;overflow:hidden}.tile-media img{width:100%;height:100%;object-fit:cover;display:block}.tile-media mat-icon{font-size:28px;height:28px;width:28px;color:var(--p-list-foreground-muted)}.tile-body{display:grid;gap:6px;min-width:0}.tile-meta{display:inline-flex;align-items:center;gap:6px;font-size:.75rem;color:var(--p-list-foreground-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tile-trailing{font-size:.75rem;color:var(--p-list-foreground-muted);white-space:nowrap}.tiles-features{display:flex;flex-wrap:wrap;gap:8px;color:inherit}.tile-status{position:absolute;top:10px;right:10px}.tile-actions{position:absolute;top:8px;left:8px;display:flex;gap:4px;opacity:0;pointer-events:none;transform:translateY(-2px);transition:opacity .16s ease-out,transform .16s ease-out}.item-tile:hover .tile-actions,.item-tile:focus-visible .tile-actions,.item-tile:focus-within .tile-actions{opacity:1;pointer-events:auto;transform:translateY(0)}@media(hover:none){.tile-actions{opacity:1;pointer-events:auto;transform:none}}@media(max-width:600px){.tiles-grid{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}}@media(prefers-reduced-motion:reduce){.item-tile,.tile-actions{transition:none}.item-tile:active{transform:none}.item-card{transition:none}.item-card:active{transform:none}}.item-card{padding:var(--p-list-tile-padding);display:flex;flex-direction:column;min-height:160px;position:relative;cursor:pointer;background:var(--p-list-surface);border:var(--p-list-border);border-radius:var(--p-list-tile-radius);box-shadow:var(--p-list-shadow);transition:box-shadow .16s ease-out,border-color .16s ease-out,transform .12s ease-out,background .16s ease-out;--p-list-leading-width: 96px;--p-list-trailing-min-width: 0px}.item-card .list-item-trailing{min-width:var(--p-list-trailing-min-width)}.item-card:hover{box-shadow:var(--md-sys-elevation-level3);border-color:var(--md-sys-color-outline-variant);background:var(--p-list-item-hover-surface)}.item-card:active{transform:scale(var(--p-list-tile-press-scale));background:var(--p-list-item-active-surface)}.item-card:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.card-actions{display:flex;align-items:center;justify-content:flex-end;gap:4px;padding:6px 8px 4px;border-top:1px solid var(--md-sys-color-outline-variant);margin-top:auto}.status-overlay{position:absolute;top:10px;right:10px;pointer-events:none}.status-overlay .mat-mdc-chip{pointer-events:auto}.leading-icon.mat-icon{width:36px;height:36px;line-height:36px;font-size:20px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.mat-mdc-chip{--mdc-chip-container-height: var(--p-list-chip-height);font-size:var(--p-list-chip-font-size)}.meta .mat-icon{font-size:18px;height:18px;width:18px}.features{overflow:hidden}@keyframes shimmer{0%{background-position:-468px 0}to{background-position:468px 0}}.skeleton{animation-duration:1.2s;animation-fill-mode:forwards;animation-iteration-count:infinite;animation-name:shimmer;animation-timing-function:linear;background:linear-gradient(to right,var(--md-sys-color-surface-container-low) 8%,var(--md-sys-color-surface-container) 18%,var(--md-sys-color-surface-container-low) 33%);background-size:800px 104px;position:relative}.skeleton-avatar{width:32px;height:32px;border-radius:50%}.skeleton-line{height:10px;margin:6px 0;border-radius:6px}.skeleton-chip{width:48px;height:18px;border-radius:999px}.chip-outlined.mat-mdc-chip{background:transparent!important;border:1px solid currentColor}.w-60{width:60%}.w-40{width:40%}.paginator{display:flex;align-items:center;flex-wrap:wrap;gap:8px;padding:8px 4px;border-top:1px solid var(--md-sys-color-outline-variant)}.paginator-controls{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.paginator-meta{display:flex;align-items:center;gap:8px;margin-left:auto}.paginator-page-size{width:120px}.paginator-sort{width:180px}.paginator-search{min-width:220px}.muted{color:var(--p-list-foreground-muted)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i3.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i3.MatSelectionList, selector: "mat-selection-list", inputs: ["color", "compareWith", "multiple", "hideSingleSelectionIndicator", "disabled"], outputs: ["selectionChange"], exportAs: ["matSelectionList"] }, { kind: "component", type: i3.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "component", type: i3.MatListOption, selector: "mat-list-option", inputs: ["togglePosition", "checkboxPosition", "color", "value", "selected"], outputs: ["selectedChange"], exportAs: ["matListOption"] }, { kind: "component", type: i3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i5.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.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: i6.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i12.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: PraxisAiAssistantComponent, selector: "praxis-ai-assistant", inputs: ["adapter", "riskPolicy", "allowManualPatchEdit"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4061
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisList, deps: [], target: i0.ɵɵFactoryTarget.Component });
4062
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: PraxisList, isStandalone: true, selector: "praxis-list", inputs: { config: "config", listId: "listId", componentInstanceId: "componentInstanceId", form: "form", enableCustomization: "enableCustomization" }, outputs: { itemClick: "itemClick", actionClick: "actionClick", selectionChange: "selectionChange" }, providers: [GenericCrudService, ListDataService], usesOnChanges: true, ngImport: i0, template: "<div class=\"praxis-list-root\" [ngClass]=\"skinClasses\" [attr.data-skin-scope]=\"skinScopeId\"\n [attr.aria-label]=\"config.a11y?.ariaLabel || null\"\n [attr.aria-labelledby]=\"config.a11y?.ariaLabelledBy || null\">\n @if (inlineCss) {\n <style [attr.nonce]=\"cspNonce || null\" [textContent]=\"inlineCss\"></style>\n }\n\n @if (enableCustomization) {\n <div class=\"list-assistant\">\n <button mat-mini-fab color=\"primary\" (click)=\"openConfigEditor()\" matTooltip=\"Editar Configura\u00E7\u00F5es\"\n aria-label=\"Editar Configura\u00E7\u00F5es\">\n <mat-icon [praxisIcon]=\"'edit'\"></mat-icon>\n </button>\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n </div>\n }\n\n <!-- Skeleton while loading -->\n @if ((loading$ | async) && hasSkeleton()) {\n @if (isListVariant()) {\n <mat-list>\n @for (_ of skeletonItems(); track $index; let i = $index) {\n <mat-list-item>\n <div class=\"list-item-content\">\n <div class=\"list-item-leading\">\n <div class=\"skeleton skeleton-avatar\"></div>\n </div>\n <div class=\"list-item-text\">\n <div class=\"skeleton skeleton-line w-60\"></div>\n @if (layoutLines > 1) { <div class=\"skeleton skeleton-line w-40\"></div> }\n </div>\n <div class=\"list-item-trailing\">\n <div class=\"skeleton skeleton-chip\"></div>\n </div>\n </div>\n </mat-list-item>\n }\n </mat-list>\n } @else {\n <div class=\"cards-grid\">\n @for (_ of skeletonItems(); track $index; let i = $index) {\n <div class=\"item-card\">\n <div class=\"list-item-content\">\n <div class=\"list-item-leading\">\n <div class=\"skeleton skeleton-avatar\"></div>\n </div>\n <div class=\"list-item-text\">\n <div class=\"skeleton skeleton-line w-60\"></div>\n @if (layoutLines > 1) { <div class=\"skeleton skeleton-line w-40\"></div> }\n </div>\n <div class=\"list-item-trailing\">\n <div class=\"skeleton skeleton-chip\"></div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n } @else {\n <ng-container *ngTemplateOutlet=\"notLoading\"></ng-container>\n }\n\n <ng-template #notLoading>\n <!-- Empty state -->\n @if (items$ | async; as all) {\n @if (all.length === 0) {\n <div class=\"section-header\">\n @if (emptyStateTemplate(); as empty) {\n @switch (empty.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"empty.value\" [ngClass]=\"empty.class\"\n [color]=\"isThemeColor(empty.color) ? empty.color : undefined\"\n [style.cssText]=\"(empty.style ? empty.style + ';' : '') + iconStyle(empty.color)\"></mat-icon> }\n @case ('image') {\n <span class=\"inline-image\" [ngClass]=\"empty.class\" [style.cssText]=\"empty.style\">\n <img [src]=\"empty.value\" [alt]=\"config.templating?.emptyState?.imageAlt || ''\" />\n @if (empty.badge?.value) { <mat-chip class=\"inline-badge\"\n [color]=\"isThemeColor(empty.badge?.color) ? empty.badge?.color : undefined\"\n [ngClass]=\"(((empty.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(empty.badge?.color, empty.badge?.variant)\">{{ empty.badge?.value }}</mat-chip> }\n </span>\n }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(empty.color) ? empty.color : undefined\"\n [ngClass]=\"[empty.class || '', ((empty.variant || 'filled') === 'outlined') ? 'chip-outlined' : '']\"\n [style.cssText]=\"chipStyle(empty.color, empty.variant) + (empty.style ? ';' + empty.style : '')\">{{ empty.value }}</mat-chip> }\n @case ('rating') {\n <span [ngClass]=\"empty.class\" [style.cssText]=\"empty.style\">\n @for (_ of ratingRange(empty); track $index; let idx = $index) { <mat-icon\n [praxisIcon]=\"starIcon(idx, empty.value)\"\n [color]=\"ratingThemeColor(empty)\"\n [style.cssText]=\"ratingIconStyle(empty)\"></mat-icon> }\n </span>\n }\n @case ('html') { <span [ngClass]=\"empty.class\" [style.cssText]=\"empty.style\" [innerHTML]=\"empty.value\"></span> }\n @default { <span [ngClass]=\"empty.class\" [style.cssText]=\"empty.style\">{{ empty.value }}</span> }\n }\n }\n </div>\n }\n }\n\n <!-- List variant -->\n @if (isListVariant()) {\n <!-- Selection list -->\n @if (isSelectionEnabled()) {\n <mat-selection-list [multiple]=\"config.selection?.mode === 'multiple'\" [formControl]=\"boundControl\"\n (selectionChange)=\"onSelectionChange($event)\">\n @for (section of sections$ | async; track trackBySection($index, section)) {\n @if (section.key) {\n <div class=\"section-header mat-subheader\">\n @if (sectionHeaderTemplate(section.key); as sh) {\n @switch (sh.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"sh.value\" [ngClass]=\"sh.class\"\n [color]=\"isThemeColor(sh.color) ? sh.color : undefined\"\n [style.cssText]=\"(sh.style ? sh.style + ';' : '') + iconStyle(sh.color)\"></mat-icon> }\n @case ('image') {\n <span class=\"inline-image\" [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\">\n <img [src]=\"sh.value\" [alt]=\"config.templating?.sectionHeader?.imageAlt || ''\" />\n @if (sh.badge?.value) { <mat-chip class=\"inline-badge\"\n [color]=\"isThemeColor(sh.badge?.color) ? sh.badge?.color : undefined\"\n [ngClass]=\"(((sh.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(sh.badge?.color, sh.badge?.variant)\">{{ sh.badge?.value }}</mat-chip> }\n </span>\n }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(sh.color) ? sh.color : undefined\"\n [ngClass]=\"[sh.class || '', ((sh.variant || 'filled') === 'outlined') ? 'chip-outlined' : '']\"\n [style.cssText]=\"chipStyle(sh.color, sh.variant) + (sh.style ? ';' + sh.style : '')\">{{ sh.value }}</mat-chip> }\n @case ('rating') {\n <span [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\">\n @for (_ of ratingRange(sh); track $index; let idx = $index) { <mat-icon\n [praxisIcon]=\"starIcon(idx, sh.value)\"\n [color]=\"ratingThemeColor(sh)\"\n [style.cssText]=\"ratingIconStyle(sh)\"></mat-icon> }\n </span>\n }\n @case ('html') { <span [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\" [innerHTML]=\"sh.value\"></span> }\n @default { <span [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\">{{ sh.value }}</span> }\n }\n }\n </div>\n }\n @for (item of section.items; track trackByItem($index, item); let i = $index) {\n <mat-list-option\n [value]=\"item\"\n [attr.aria-label]=\"primary(item)?.value || null\"\n (click)=\"onItemClick(item, i, section.key || undefined)\"\n >\n <div class=\"list-item-content\">\n <div class=\"list-item-leading\">\n @if (leading(item); as lead) {\n @switch (lead.type) {\n @case ('icon') {\n <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\"\n [color]=\"isThemeColor(lead.color) ? lead.color : undefined\"\n [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon>\n }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n @if (lead.badge?.value) {\n <mat-chip class=\"lead-badge\" [color]=\"isThemeColor(lead.badge?.color) ? lead.badge?.color : undefined\"\n [ngClass]=\"(((lead.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(lead.badge?.color, lead.badge?.variant)\">{{ lead.badge?.value }}</mat-chip>\n }\n </div>\n }\n @case ('text') {\n <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span>\n }\n @case ('chip') {\n <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\"\n [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip>\n }\n @case ('rating') {\n <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon\n [praxisIcon]=\"starIcon(idx, lead.value)\"\n [color]=\"ratingThemeColor(lead)\"\n [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> }\n </span>\n }\n @case ('html') {\n <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\" [innerHTML]=\"lead.value\"></span>\n }\n @default {\n <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span>\n }\n }\n } @else {\n <span class=\"leading-placeholder\"></span>\n }\n </div>\n <div class=\"list-item-text\">\n <div class=\"primary\" [ngClass]=\"primary(item)?.class\" [style.cssText]=\"primary(item)?.style\">{{\n primary(item)?.value }}</div>\n @if (layoutLines > 1) { <div class=\"secondary\" [ngClass]=\"secondary(item)?.class\"\n [style.cssText]=\"secondary(item)?.style\">{{ secondary(item)?.value }}</div> }\n @if (meta(item); as m) {\n @if ((config.templating?.metaPlacement === 'line' && (m?.type === 'text' || m?.type === 'date' || m?.type\n === 'currency')) || (layoutLines > 2 && (m?.type === 'text' || m?.type === 'date' || m?.type ===\n 'currency'))) {\n <div class=\"tertiary\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (config.templating?.metaPrefixIcon; as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n {{ m.value }}\n </div>\n }\n }\n @if (featuresVisible()) {\n <div class=\"features\">\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{\n featureLabel(item, f.expr) }}</span> }\n </span>\n }\n </div>\n }\n </div>\n <div class=\"list-item-trailing\">\n @if (meta(item); as m) {\n @if (!(((config.templating?.metaPlacement === 'line') || (layoutLines > 2)) && (m?.type === 'text' ||\n m?.type === 'date' || m?.type === 'currency'))) {\n <div class=\"meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\"\n [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon\n [praxisIcon]=\"starIcon(idx, m.value)\"\n [color]=\"ratingThemeColor(m)\"\n [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>@if (config.templating?.metaPrefixIcon; as mpi2) { <mat-icon [praxisIcon]=\"mpi2\"></mat-icon> }{{\n m.value }}</span> }\n }\n </div>\n }\n }\n @if (trailing(item); as tr) {\n <div class=\"trailing\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n @switch (tr.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\"\n [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip> }\n @case ('icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n <img [src]=\"tr.value\" [alt]=\"config.templating?.trailing?.imageAlt || ''\" />\n @if (tr.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(tr.badge?.color) ? tr.badge?.color : undefined\"\n [ngClass]=\"(((tr.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(tr.badge?.color, tr.badge?.variant)\">{{ tr.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('rating') { @for (_ of ratingRange(tr); track $index; let idx = $index) { <mat-icon\n [praxisIcon]=\"starIcon(idx, tr.value)\"\n [color]=\"ratingThemeColor(tr)\"\n [style.cssText]=\"ratingIconStyle(tr)\"></mat-icon> } }\n @case ('html') { <span [innerHTML]=\"tr.value\"></span> }\n @default { <span>{{ tr.value }}</span> }\n }\n </div>\n }\n @if ((visibleActions(item) || []).length) {\n <div\n class=\"list-item-actions\"\n (click)=\"$event.stopPropagation()\"\n (keydown.enter)=\"onActionKeydown($event)\"\n (keydown.space)=\"onActionKeydown($event)\">\n @for (action of visibleActions(item); let aidx = $index; track action?.id ?? $index) {\n @if ((action.kind || 'icon') === 'icon') {\n <button mat-icon-button [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n (click)=\"onActionClick($event, action.id, item, i)\" [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n <mat-icon [praxisIcon]=\"action.icon\" [style.cssText]=\"iconStyle(action.color)\"></mat-icon>\n }\n </button>\n } @else {\n @if (action.buttonVariant === 'stroked') { <button mat-stroked-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'stroked')\"\n (click)=\"onActionClick($event, action.id, item, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (action.buttonVariant === 'raised') { <button mat-raised-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'raised')\"\n (click)=\"onActionClick($event, action.id, item, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (!action.buttonVariant || action.buttonVariant === 'flat') { <button mat-flat-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'flat')\"\n (click)=\"onActionClick($event, action.id, item, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n }\n }\n </div>\n }\n </div>\n </div>\n </mat-list-option>\n @if ((config.layout?.dividers === 'all' || config.layout?.dividers === 'between') && i < section.items.length - 1) { <mat-divider></mat-divider> }\n }\n }\n </mat-selection-list>\n } @else {\n <ng-container *ngTemplateOutlet=\"readList\"></ng-container>\n }\n\n <!-- Read-only list -->\n <ng-template #readList>\n <mat-list>\n @for (section of sections$ | async; track trackBySection($index, section); let sidx = $index) {\n @if (section.key) {\n <div class=\"section-header mat-subheader\">\n @if (sectionHeaderTemplate(section.key); as sh) {\n @switch (sh.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"sh.value\" [ngClass]=\"sh.class\"\n [color]=\"isThemeColor(sh.color) ? sh.color : undefined\"\n [style.cssText]=\"(sh.style ? sh.style + ';' : '') + iconStyle(sh.color)\"></mat-icon>\n }\n @case ('image') {\n <span class=\"inline-image\" [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\">\n <img [src]=\"sh.value\" [alt]=\"config.templating?.sectionHeader?.imageAlt || ''\" />\n @if (sh.badge?.value) { <mat-chip class=\"inline-badge\"\n [color]=\"isThemeColor(sh.badge?.color) ? sh.badge?.color : undefined\"\n [ngClass]=\"(((sh.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(sh.badge?.color, sh.badge?.variant)\">{{ sh.badge?.value }}</mat-chip> }\n </span>\n }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(sh.color) ? sh.color : undefined\"\n [ngClass]=\"[sh.class || '', ((sh.variant || 'filled') === 'outlined') ? 'chip-outlined' : '']\"\n [style.cssText]=\"chipStyle(sh.color, sh.variant) + (sh.style ? ';' + sh.style : '')\">{{ sh.value }}</mat-chip> }\n @case ('rating') {\n <span [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\">\n @for (_ of ratingRange(sh); track $index; let idx = $index) { <mat-icon\n [praxisIcon]=\"starIcon(idx, sh.value)\"\n [color]=\"ratingThemeColor(sh)\"\n [style.cssText]=\"ratingIconStyle(sh)\"></mat-icon> }\n </span>\n }\n @case ('html') { <span [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\" [innerHTML]=\"sh.value\"></span> }\n @default { <span [ngClass]=\"sh.class\" [style.cssText]=\"sh.style\">{{ sh.value }}</span> }\n }\n }\n </div>\n }\n @for (item of section.items; track trackByItem($index, item); let i = $index) {\n <mat-list-item\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"primary(item)?.value || null\"\n (click)=\"onItemClick(item, i, section.key || undefined)\"\n (keydown.enter)=\"onItemClick(item, i, section.key || undefined)\"\n (keydown.space)=\"$event.preventDefault(); onItemClick(item, i, section.key || undefined)\"\n >\n <div class=\"list-item-content\">\n <div class=\"list-item-leading\">\n @if (leading(item); as lead) {\n @switch (lead.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\"\n [color]=\"isThemeColor(lead.color) ? lead.color : undefined\"\n [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon>\n }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n @if (lead.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(lead.badge?.color) ? lead.badge?.color : undefined\"\n [ngClass]=\"(((lead.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(lead.badge?.color, lead.badge?.variant)\">{{ lead.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('text') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\"\n [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx,\n lead.value)\" [color]=\"ratingThemeColor(lead)\" [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> } }\n @case ('html') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\"\n [innerHTML]=\"lead.value\"></span> }\n @default { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n }\n } @else {\n <span class=\"leading-placeholder\"></span>\n }\n </div>\n <div class=\"list-item-text\">\n <div class=\"primary\" [ngClass]=\"primary(item)?.class\" [style.cssText]=\"primary(item)?.style\">{{\n primary(item)?.value }}</div>\n @if (layoutLines > 1) { <div class=\"secondary\" [ngClass]=\"secondary(item)?.class\"\n [style.cssText]=\"secondary(item)?.style\">{{ secondary(item)?.value }}</div> }\n @if (meta(item); as m) {\n @if ((config.templating?.metaPlacement === 'line' && (m?.type === 'text' || m?.type === 'date' || m?.type\n === 'currency')) || (layoutLines > 2 && (m?.type === 'text' || m?.type === 'date' || m?.type ===\n 'currency'))) {\n <div class=\"tertiary\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (config.templating?.metaPrefixIcon; as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n {{ m.value }}\n </div>\n }\n }\n @if (featuresVisible()) {\n <div class=\"features\">\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{ featureLabel(item, f.expr) }}</span> }\n </span>\n }\n </div>\n }\n </div>\n <div class=\"list-item-trailing\">\n @if (meta(item); as m) {\n @if (!(((config.templating?.metaPlacement === 'line') || (layoutLines > 2)) && (m?.type === 'text' ||\n m?.type === 'date' || m?.type === 'currency'))) {\n <div class=\"meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\" [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx,\n m.value)\" [color]=\"ratingThemeColor(m)\" [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>@if (config.templating?.metaPrefixIcon; as mpi2) { <mat-icon [praxisIcon]=\"mpi2\"></mat-icon> }{{ m.value }}</span> }\n }\n </div>\n }\n }\n @if (trailing(item); as tr) {\n <div class=\"trailing\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n @switch (tr.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip> }\n @case ('icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n <img [src]=\"tr.value\" [alt]=\"config.templating?.trailing?.imageAlt || ''\" />\n @if (tr.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(tr.badge?.color) ? tr.badge?.color : undefined\"\n [ngClass]=\"(((tr.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(tr.badge?.color, tr.badge?.variant)\">{{ tr.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('rating') { @for (_ of ratingRange(tr); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx,\n tr.value)\" [color]=\"ratingThemeColor(tr)\" [style.cssText]=\"ratingIconStyle(tr)\"></mat-icon> } }\n @case ('html') { <span [innerHTML]=\"tr.value\"></span> }\n @default { <span>{{ tr.value }}</span> }\n }\n </div>\n }\n @if ((visibleActions(item) || []).length) {\n <div\n class=\"list-item-actions\"\n (click)=\"$event.stopPropagation()\"\n (keydown.enter)=\"onActionKeydown($event)\"\n (keydown.space)=\"onActionKeydown($event)\">\n @for (action of visibleActions(item); let aidx = $index; track action?.id ?? $index) {\n @if ((action.kind || 'icon') === 'icon') {\n <button mat-icon-button [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n (click)=\"onActionClick($event, action.id, item, i)\" [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n <mat-icon [praxisIcon]=\"action.icon\" [style.cssText]=\"iconStyle(action.color)\"></mat-icon>\n }\n </button>\n } @else {\n @if (action.buttonVariant === 'stroked') { <button mat-stroked-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'stroked')\"\n (click)=\"onActionClick($event, action.id, item, i)\" [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (action.buttonVariant === 'raised') { <button mat-raised-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'raised')\"\n (click)=\"onActionClick($event, action.id, item, i)\" [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (!action.buttonVariant || action.buttonVariant === 'flat') { <button mat-flat-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'flat')\"\n (click)=\"onActionClick($event, action.id, item, i)\" [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, item, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, item, i)}\">\n @if (isActionLoading(action.id, item, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n }\n }\n </div>\n }\n </div>\n </div>\n </mat-list-item>\n @if ((config.layout?.dividers === 'all' || config.layout?.dividers === 'between') && i < section.items.length - 1) { <mat-divider></mat-divider> }\n }\n }\n </mat-list>\n </ng-template>\n } @else if (isTilesVariant()) {\n <ng-container *ngTemplateOutlet=\"tilesVariant\"></ng-container>\n } @else {\n <ng-container *ngTemplateOutlet=\"cardsVariant\"></ng-container>\n }\n\n <!-- Cards variant -->\n <ng-template #cardsVariant>\n <div class=\"cards-grid\">\n @for (it of (items$ | async) ?? []; track $index; let i = $index) {\n <div\n class=\"item-card\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"primary(it)?.value || null\"\n (click)=\"onItemClick(it, i)\"\n (keydown.enter)=\"onItemClick(it, i)\"\n (keydown.space)=\"$event.preventDefault(); onItemClick(it, i)\"\n >\n <div class=\"list-item-content\">\n <div class=\"list-item-leading\">\n @if (leading(it); as lead) {\n @switch (lead.type) {\n @case ('icon') { <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\"\n [color]=\"isThemeColor(lead.color) ? lead.color : undefined\"\n [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon>\n }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n @if (lead.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(lead.badge?.color) ? lead.badge?.color : undefined\"\n [ngClass]=\"(((lead.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(lead.badge?.color, lead.badge?.variant)\">{{ lead.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('text') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\"\n [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx,\n lead.value)\" [color]=\"ratingThemeColor(lead)\" [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> } }\n @case ('html') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\"\n [innerHTML]=\"lead.value\"></span> }\n @default { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n }\n } @else {\n <span class=\"leading-placeholder\"></span>\n }\n </div>\n <div class=\"list-item-text\">\n <div class=\"primary\" [ngClass]=\"primary(it)?.class\" [style.cssText]=\"primary(it)?.style\">{{\n primary(it)?.value }}</div>\n @if (layoutLines > 1) { <div class=\"secondary\" [ngClass]=\"secondary(it)?.class\"\n [style.cssText]=\"secondary(it)?.style\">{{ secondary(it)?.value }}</div> }\n @if (meta(it); as m) {\n @if ((config.templating?.metaPlacement === 'line' && (m?.type === 'text' || m?.type === 'date' || m?.type\n === 'currency')) || (layoutLines > 2 && (m?.type === 'text' || m?.type === 'date' || m?.type ===\n 'currency'))) {\n <div class=\"tertiary\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (config.templating?.metaPrefixIcon; as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n {{ m.value }}\n </div>\n }\n }\n @if (featuresVisible()) {\n <div class=\"features\">\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{\n featureLabel(it, f.expr) }}</span> }\n </span>\n }\n </div>\n }\n </div>\n <div class=\"list-item-trailing\">\n @if (meta(it); as m) {\n @if (!(((config.templating?.metaPlacement === 'line') || (layoutLines > 2)) && (m?.type === 'text' ||\n m?.type === 'date' || m?.type === 'currency'))) {\n <div class=\"meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\"\n [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx,\n m.value)\" [color]=\"ratingThemeColor(m)\" [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>@if (config.templating?.metaPrefixIcon; as mpi2) { <mat-icon [praxisIcon]=\"mpi2\"></mat-icon> }{{ m.value }}</span> }\n }\n </div>\n }\n }\n @if (trailing(it); as tr) {\n @if ((config.templating?.statusPosition || 'inline') === 'top-right' && (tr?.type === 'chip' || tr?.type\n === 'icon')) {\n <div class=\"status-overlay\">\n @if (tr?.type === 'chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\"\n [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip>\n }\n @if (tr?.type === 'icon') { <mat-icon [praxisIcon]=\"tr.value\"\n [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n </div>\n } @else {\n <div class=\"trailing\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n @switch (tr.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\"\n [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\"\n [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip>\n }\n @case ('icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n @case ('image') {\n <div class=\"lead-image\" [ngClass]=\"tr.class\" [style.cssText]=\"tr.style\">\n <img [src]=\"tr.value\" [alt]=\"config.templating?.trailing?.imageAlt || ''\" />\n @if (tr.badge?.value) { <mat-chip class=\"lead-badge\"\n [color]=\"isThemeColor(tr.badge?.color) ? tr.badge?.color : undefined\"\n [ngClass]=\"(((tr.badge?.variant || 'filled') === 'outlined') ? 'chip-outlined' : '')\"\n [style.cssText]=\"chipStyle(tr.badge?.color, tr.badge?.variant)\">{{ tr.badge?.value }}</mat-chip> }\n </div>\n }\n @case ('rating') { @for (_ of ratingRange(tr); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx,\n tr.value)\" [color]=\"ratingThemeColor(tr)\" [style.cssText]=\"ratingIconStyle(tr)\"></mat-icon> } }\n @case ('html') { <span [innerHTML]=\"tr.value\"></span> }\n @default { <span>{{ tr.value }}</span> }\n }\n </div>\n }\n }\n </div>\n </div>\n <div\n class=\"card-actions\"\n (click)=\"$event.stopPropagation()\"\n (keydown.enter)=\"onActionKeydown($event)\"\n (keydown.space)=\"onActionKeydown($event)\">\n @for (action of visibleActions(it); let aidx = $index; track action?.id ?? $index) {\n @if ((action.kind || 'icon') === 'icon') {\n <button mat-icon-button [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n (click)=\"onActionClick($event, action.id, it, i)\" [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, it, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n <mat-icon [praxisIcon]=\"action.icon\" [style.cssText]=\"iconStyle(action.color)\"></mat-icon>\n }\n </button>\n } @else {\n @if (action.buttonVariant === 'stroked') { <button mat-stroked-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'stroked')\"\n (click)=\"onActionClick($event, action.id, it, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, it, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (action.buttonVariant === 'raised') { <button mat-raised-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'raised')\"\n (click)=\"onActionClick($event, action.id, it, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, it, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (!action.buttonVariant || action.buttonVariant === 'flat') { <button mat-flat-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'flat')\"\n (click)=\"onActionClick($event, action.id, it, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, it, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n }\n }\n </div>\n </div>\n }\n </div>\n </ng-template>\n\n <!-- Tiles variant -->\n <ng-template #tilesVariant>\n <div class=\"tiles-grid\">\n @for (it of (items$ | async) ?? []; track $index; let i = $index) {\n <div\n class=\"item-tile\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"primary(it)?.value || null\"\n (click)=\"onItemClick(it, i)\"\n (keydown.enter)=\"onItemClick(it, i)\"\n (keydown.space)=\"$event.preventDefault(); onItemClick(it, i)\"\n >\n <div class=\"tile-media\">\n @if (leading(it); as lead) {\n @switch (lead.type) {\n @case ('image') {\n <img [src]=\"lead.value\" [alt]=\"config.templating?.leading?.imageAlt || ''\" />\n }\n @case ('icon') { <mat-icon [praxisIcon]=\"lead.value\" [ngClass]=\"lead.class\"\n [color]=\"isThemeColor(lead.color) ? lead.color : undefined\"\n [style.cssText]=\"(lead.style ? lead.style + ';' : '') + iconStyle(lead.color)\"></mat-icon> }\n @case ('text') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n @case ('chip') { <mat-chip [color]=\"isThemeColor(lead.color) ? lead.color : undefined\" [ngClass]=\"((lead.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(lead.color, lead.variant)\">{{ lead.value }}</mat-chip> }\n @case ('rating') {\n <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">\n @for (_ of ratingRange(lead); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, lead.value)\" [color]=\"ratingThemeColor(lead)\" [style.cssText]=\"ratingIconStyle(lead)\"></mat-icon> }\n </span>\n }\n @case ('html') { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\" [innerHTML]=\"lead.value\"></span> }\n @default { <span [ngClass]=\"lead.class\" [style.cssText]=\"lead.style\">{{ lead.value }}</span> }\n }\n }\n </div>\n\n @if (trailing(it); as tr) {\n @if ((config.templating?.statusPosition || 'inline') === 'top-right' && (tr?.type === 'chip' || tr?.type === 'icon')) {\n <div class=\"tile-status\">\n @if (tr?.type === 'chip') { <mat-chip [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [ngClass]=\"((tr.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr.color, tr.variant)\">{{ tr.value }}</mat-chip> }\n @if (tr?.type === 'icon') { <mat-icon [praxisIcon]=\"tr.value\" [color]=\"isThemeColor(tr.color) ? tr.color : undefined\" [style.cssText]=\"iconStyle(tr.color)\"></mat-icon> }\n </div>\n }\n }\n\n <div class=\"tile-body\">\n <div class=\"primary\" [ngClass]=\"primary(it)?.class\" [style.cssText]=\"primary(it)?.style\">{{ primary(it)?.value }}</div>\n @if (layoutLines > 1) { <div class=\"secondary\" [ngClass]=\"secondary(it)?.class\" [style.cssText]=\"secondary(it)?.style\">{{ secondary(it)?.value }}</div> }\n\n @if (meta(it); as m) {\n <div class=\"tile-meta\" [ngClass]=\"m.class\" [style.cssText]=\"m.style\">\n @if (config.templating?.metaPrefixIcon; as mpi) { <mat-icon [praxisIcon]=\"mpi\"></mat-icon> }\n @switch (m.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(m.color) ? m.color : undefined\" [ngClass]=\"((m.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(m.color, m.variant)\">{{ m.value }}</mat-chip> }\n @case ('rating') { @for (_ of ratingRange(m); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, m.value)\" [color]=\"ratingThemeColor(m)\" [style.cssText]=\"ratingIconStyle(m)\"></mat-icon> } }\n @case ('icon') { <mat-icon [praxisIcon]=\"m.value\" [color]=\"isThemeColor(m.color) ? m.color : undefined\" [style.cssText]=\"iconStyle(m.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"m.value\" [alt]=\"m.imageAlt || ''\" /></span> }\n @case ('html') { <span [innerHTML]=\"m.value\"></span> }\n @default { <span>{{ m.value }}</span> }\n }\n </div>\n }\n\n @if (featuresVisible()) {\n <div class=\"tiles-features\">\n @for (f of (config.templating?.features || []); track $index; let fi = $index) {\n <span class=\"feature\">\n @if (f.icon && featuresMode() !== 'labels-only') { <mat-icon [praxisIcon]=\"f.icon\"></mat-icon> }\n @if (featuresMode() !== 'icons-only') { <span [ngClass]=\"f.class\" [style.cssText]=\"f.style\">{{ featureLabel(it, f.expr) }}</span> }\n </span>\n }\n </div>\n }\n\n @if (trailing(it); as tr2) {\n @if (!((config.templating?.statusPosition || 'inline') === 'top-right' && (tr2?.type === 'chip' || tr2?.type === 'icon'))) {\n <div class=\"tile-trailing\" [ngClass]=\"tr2.class\" [style.cssText]=\"tr2.style\">\n @switch (tr2.type) {\n @case ('chip') { <mat-chip [color]=\"isThemeColor(tr2.color) ? tr2.color : undefined\" [ngClass]=\"((tr2.variant || 'filled') === 'outlined') ? 'chip-outlined' : ''\" [style.cssText]=\"chipStyle(tr2.color, tr2.variant)\">{{ tr2.value }}</mat-chip> }\n @case ('icon') { <mat-icon [praxisIcon]=\"tr2.value\" [color]=\"isThemeColor(tr2.color) ? tr2.color : undefined\" [style.cssText]=\"iconStyle(tr2.color)\"></mat-icon> }\n @case ('image') { <span class=\"inline-image\"><img [src]=\"tr2.value\" [alt]=\"tr2.imageAlt || ''\" /></span> }\n @case ('rating') { @for (_ of ratingRange(tr2); track $index; let idx = $index) { <mat-icon [praxisIcon]=\"starIcon(idx, tr2.value)\" [color]=\"ratingThemeColor(tr2)\" [style.cssText]=\"ratingIconStyle(tr2)\"></mat-icon> } }\n @case ('html') { <span [innerHTML]=\"tr2.value\"></span> }\n @default { <span>{{ tr2.value }}</span> }\n }\n </div>\n }\n }\n </div>\n\n @if ((visibleActions(it) || []).length) {\n <div\n class=\"tile-actions\"\n (click)=\"$event.stopPropagation()\"\n (keydown.enter)=\"onActionKeydown($event)\"\n (keydown.space)=\"onActionKeydown($event)\">\n @for (action of visibleActions(it); let aidx = $index; track action?.id ?? $index) {\n @if ((action.kind || 'icon') === 'icon') {\n <button mat-icon-button [color]=\"isThemeColor(action.color) ? action.color : undefined\" (click)=\"onActionClick($event, action.id, it, i)\" [attr.aria-label]=\"action.label || action.id\" [disabled]=\"isActionLoading(action.id, it, i)\" [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n <mat-icon [praxisIcon]=\"action.icon\" [style.cssText]=\"iconStyle(action.color)\"></mat-icon>\n }\n </button>\n } @else {\n @if (action.buttonVariant === 'stroked') { <button mat-stroked-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'stroked')\"\n (click)=\"onActionClick($event, action.id, it, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, it, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (action.buttonVariant === 'raised') { <button mat-raised-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'raised')\"\n (click)=\"onActionClick($event, action.id, it, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, it, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n @if (!action.buttonVariant || action.buttonVariant === 'flat') { <button mat-flat-button\n [color]=\"isThemeColor(action.color) ? action.color : undefined\"\n [style.cssText]=\"buttonStyle(action.color, 'flat')\"\n (click)=\"onActionClick($event, action.id, it, i)\"\n [attr.aria-label]=\"action.label || action.id\"\n [disabled]=\"isActionLoading(action.id, it, i)\"\n [ngClass]=\"{'action-loading': isActionLoading(action.id, it, i)}\">\n @if (isActionLoading(action.id, it, i)) {\n <mat-progress-spinner class=\"action-spinner\" mode=\"indeterminate\" diameter=\"16\" strokeWidth=\"3\"></mat-progress-spinner>\n } @else {\n {{ action.label || action.id }}\n }\n </button> }\n }\n }\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n\n <!-- Simple pagination controls for remote data -->\n @if (config.dataSource?.resourcePath) {\n <div class=\"paginator\">\n <div class=\"paginator-controls\">\n <button mat-stroked-button color=\"primary\" (click)=\"prevPage()\">Anterior</button>\n <button mat-stroked-button color=\"primary\" (click)=\"nextPage()\">Pr\u00F3ximo</button>\n <mat-form-field class=\"paginator-page-size\" appearance=\"outline\">\n <mat-label>Tam. p\u00E1gina</mat-label>\n <mat-select (selectionChange)=\"setPageSize($event.value)\" [value]=\"config.layout?.pageSize || 10\">\n <mat-option [value]=\"6\">6</mat-option>\n <mat-option [value]=\"8\">8</mat-option>\n <mat-option [value]=\"12\">12</mat-option>\n <mat-option [value]=\"24\">24</mat-option>\n </mat-select>\n </mat-form-field>\n @if (config.ui?.showSort) {\n <mat-form-field class=\"paginator-sort\" appearance=\"outline\">\n <mat-label>Ordenar</mat-label>\n <mat-select (selectionChange)=\"onSortChange($event.value)\">\n @for (op of (config.ui?.sortOptions || []); track $index) {\n <mat-option [value]=\"sortOptionValue(op)\">{{ sortOptionLabel(op) }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n @if (config.ui?.showSearch && config.ui?.searchField) {\n <mat-form-field class=\"paginator-search\" appearance=\"outline\">\n <mat-label>{{ config.ui?.searchPlaceholder || 'Buscar' }}</mat-label>\n <input matInput type=\"search\" (input)=\"onSearchInput($any($event.target).value)\" />\n </mat-form-field>\n }\n </div>\n <div class=\"paginator-meta\">\n @if ((config.ui?.showRange ?? true)) {\n @if (page$ | async; as ps) {\n @if (total$ | async; as total) {\n @if (items$ | async; as curr) {\n <span class=\"muted\">{{ (total || 0) > 0 ? rangeStart(ps) : 0 }}\u2013{{ rangeEnd(curr?.length || 0, ps, total || 0) }} de {{ total || 0\n }}</span>\n }\n }\n }\n } @else {\n @if (total$ | async; as total2) { <span class=\"muted\">Total: {{ total2 }}</span> }\n }\n </div>\n </div>\n }\n </ng-template>\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block}.praxis-list-root{--p-list-radius: var(--md-sys-shape-corner-medium, 16px);--p-list-shadow: var(--md-sys-elevation-level2);--p-list-border: 1px solid var(--md-sys-color-outline-variant);--p-list-blur: 10px;--p-list-surface: var(--md-sys-color-surface-container);--p-list-surface-low: var(--md-sys-color-surface);--p-list-surface-high: var(--md-sys-color-surface-container-high, var(--md-sys-color-surface-container));--p-list-foreground: var(--md-sys-color-on-surface);--p-list-foreground-muted: var(--md-sys-color-on-surface-variant);--p-list-accent: var(--md-sys-color-primary);--p-list-accent-weak: var(--md-sys-color-primary-container);--p-list-item-surface: var(--md-sys-color-surface-container-low, var(--md-sys-color-surface));--p-list-item-border: 1px solid var(--md-sys-color-outline-variant);--p-list-item-hover-surface: var(--md-sys-color-surface-container-low);--p-list-item-active-surface: var(--md-sys-color-surface-container);--p-list-item-selected-surface: var(--md-sys-color-surface-container);--p-list-grad-from: var(--md-sys-color-primary-container);--p-list-grad-to: var(--md-sys-color-tertiary-container);--p-list-grad-angle: 135deg;--p-list-grad-foreground: var(--md-sys-color-on-primary);--p-list-grad-foreground-muted: var(--md-sys-color-on-primary);--p-list-leading-width: 40px;--p-list-trailing-min-width: 140px;--p-list-item-gap: 12px;--p-list-item-padding-x: 16px;--p-list-item-padding-y: 12px;--p-list-meta-size: .95rem;--p-list-meta-weight: 500;--p-list-chip-height: 22px;--p-list-chip-font-size: 12px;--p-list-trailing-padding-right: 12px;--p-list-tile-minW: 240px;--p-list-tile-gap: 16px;--p-list-tile-padding: 16px;--p-list-tile-radius: 16px;--p-list-tile-media-radius: 12px;--p-list-tile-media-ratio: 1 / 1;--p-list-tile-hover-overlay: .04;--p-list-tile-press-overlay: .08;--p-list-tile-press-scale: .99}.list-assistant{display:flex;justify-content:flex-end;gap:8px;padding:4px 4px 8px}.action-loading{opacity:.65}.action-spinner{width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center}.action-loading .mat-mdc-button-touch-target,.action-loading .mdc-button__label{opacity:.7}.skin-elevated,.skin-outline,.skin-flat,.skin-neumorphism{--p-list-item-surface: var(--mdc-elevated-card-container-color, var(--p-list-surface));--p-list-item-border: var(--p-list-border)}.skin-elevated .item-card,.skin-outline .item-card,.skin-flat .item-card,.skin-neumorphism .item-card{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:var(--p-list-radius);box-shadow:var(--p-list-shadow);border:var(--p-list-border)}.skin-elevated .item-tile,.skin-outline .item-tile,.skin-flat .item-tile,.skin-neumorphism .item-tile{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));box-shadow:var(--p-list-shadow);border:var(--p-list-border)}.skin-elevated .mat-mdc-list-item .list-item-content,.skin-outline .mat-mdc-list-item .list-item-content,.skin-flat .mat-mdc-list-item .list-item-content,.skin-neumorphism .mat-mdc-list-item .list-item-content{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:calc(var(--p-list-radius) * .75);box-shadow:var(--p-list-shadow);border:var(--p-list-item-border);color:var(--p-list-foreground)}.skin-outline{--p-list-shadow: none;--p-list-border: 1px solid var(--md-sys-color-outline)}.skin-flat{--p-list-shadow: none;--p-list-border: 1px solid var(--md-sys-color-outline-variant)}.skin-neumorphism{--p-list-shadow: var(--md-sys-elevation-level2);--p-list-border: 1px solid var(--md-sys-color-outline-variant);--p-list-radius: 1.25rem}.skin-pill-soft .item-card,.skin-pill-soft .item-tile{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:calc(var(--p-list-radius) * 1.3);box-shadow:var(--md-sys-elevation-level1);border:var(--p-list-border)}.skin-pill-soft .mat-mdc-list-item .list-item-content{background:var(--mdc-elevated-card-container-color, var(--p-list-surface));border-radius:calc(var(--p-list-radius) * 1.3);box-shadow:var(--md-sys-elevation-level1);border:var(--p-list-border);color:var(--p-list-foreground)}.skin-gradient-tile{--p-list-foreground: var(--p-list-grad-foreground);--p-list-foreground-muted: var(--p-list-grad-foreground-muted);--p-list-item-hover-surface: linear-gradient( var(--p-list-grad-angle), var(--p-list-grad-from), var(--p-list-grad-to) );--p-list-item-active-surface: linear-gradient( var(--p-list-grad-angle), var(--p-list-grad-from), var(--p-list-grad-to) );--p-list-item-selected-surface: linear-gradient( var(--p-list-grad-angle), var(--p-list-grad-from), var(--p-list-grad-to) )}.skin-gradient-tile .item-card,.skin-gradient-tile .item-tile,.skin-gradient-tile .mat-mdc-list-item .list-item-content{background:linear-gradient(var(--p-list-grad-angle),var(--p-list-grad-from),var(--p-list-grad-to));border-radius:var(--p-list-radius);color:var(--p-list-foreground)}.skin-glass .item-card,.skin-glass .item-tile{background:var(--md-sys-color-surface-container-low);border-radius:var(--p-list-radius);border:1px solid var(--md-sys-color-outline-variant);backdrop-filter:blur(var(--p-list-blur));-webkit-backdrop-filter:blur(var(--p-list-blur))}.skin-glass .mat-mdc-list-item .list-item-content{background:var(--md-sys-color-surface-container-low);border-radius:var(--p-list-radius);border:1px solid var(--md-sys-color-outline-variant);backdrop-filter:blur(var(--p-list-blur));-webkit-backdrop-filter:blur(var(--p-list-blur));color:var(--p-list-foreground)}.density-compact .mat-mdc-list-item,.density-compact .item-card{--p-list-item-padding-y: 8px;--p-list-item-padding-x: 12px;--p-list-item-gap: 10px}.density-comfortable .mat-mdc-list-item,.density-comfortable .item-card{--p-list-item-padding-y: 10px;--p-list-item-padding-x: 14px;--p-list-item-gap: 12px}.praxis-list-root.lines-3 .mat-mdc-list-item,.praxis-list-root.lines-3 .mat-mdc-list-option{min-height:76px}.density-compact{--p-list-tile-gap: 12px;--p-list-tile-padding: 12px;--p-list-tile-minW: 200px}.density-comfortable{--p-list-tile-gap: 16px;--p-list-tile-padding: 16px}.list-item-content{display:grid;grid-template-columns:var(--p-list-leading-width) minmax(0,1fr) minmax(var(--p-list-trailing-min-width),max-content);align-items:center;gap:var(--p-list-item-gap);padding:var(--p-list-item-padding-y) var(--p-list-item-padding-x);width:100%;min-width:0;border-radius:calc(var(--p-list-radius) * .75);overflow:visible}.list-item-leading{display:flex;align-items:center;justify-content:center;min-height:100%}.leading-placeholder{width:24px;height:24px;display:inline-block}.list-item-text{min-width:0;display:grid;align-content:center;gap:4px}.list-item-trailing{min-width:0;display:flex;flex-direction:column;align-items:flex-end;justify-content:center;gap:6px;text-align:end;padding-right:var(--p-list-trailing-padding-right)}.list-item-actions{display:flex;align-items:center;justify-content:flex-end;gap:4px;flex-wrap:wrap}.mat-mdc-list-item .list-item-content{background:var(--p-list-item-surface);border:var(--p-list-item-border);transition:background .15s ease,box-shadow .15s ease,transform .15s ease}.mat-mdc-list-item,.mat-mdc-list-option{height:auto;align-items:stretch;overflow:visible}.mdc-list-item{overflow:visible}.density-compact .mat-mdc-list-item,.density-compact .mat-mdc-list-option{min-height:44px}.density-comfortable .mat-mdc-list-item,.density-comfortable .mat-mdc-list-option{min-height:52px}.praxis-list-root:not(.density-compact):not(.density-comfortable) .mat-mdc-list-item,.praxis-list-root:not(.density-compact):not(.density-comfortable) .mat-mdc-list-option{min-height:56px}.mat-mdc-list-item .mdc-list-item__content,.mat-mdc-list-option .mdc-list-item__content,.mat-mdc-list-item .mdc-list-item__primary-text,.mat-mdc-list-option .mdc-list-item__primary-text{display:block!important;width:100%!important;height:auto!important;padding:0!important;margin:0!important;overflow:visible!important;box-sizing:border-box}.mat-mdc-list-item,.mat-mdc-list-option{padding:0!important;box-sizing:border-box}.mat-mdc-list-item:hover .list-item-content,.mat-mdc-list-option:hover .list-item-content{background:var(--p-list-item-hover-surface)}.mat-mdc-list-item:active .list-item-content,.mat-mdc-list-option:active .list-item-content{background:var(--p-list-item-active-surface)}.mat-mdc-list-option.mdc-list-item--selected .list-item-content{background:var(--p-list-item-selected-surface);border-color:var(--md-sys-color-outline-variant)}.mat-mdc-list-option.cdk-keyboard-focused .list-item-content,.mat-mdc-list-option.cdk-focused .list-item-content{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.mat-mdc-list-item:focus-visible .list-item-content{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.lead-image{position:relative;width:96px;height:72px;border-radius:12px;overflow:hidden}.lead-image img{width:100%;height:100%;object-fit:cover;display:block}.lead-image .lead-badge{position:absolute;left:8px;bottom:8px}.inline-image{position:relative;width:20px;height:20px;border-radius:4px;overflow:hidden;display:inline-block;vertical-align:middle}.inline-image img{width:100%;height:100%;object-fit:cover;display:block}.inline-image .inline-badge{position:absolute;left:2px;bottom:2px}.model-media .lead-image{width:136px;height:96px;border-radius:16px}.model-media .list-item-content{gap:16px}.model-media .item-card{--p-list-leading-width: 136px}.model-hotel .lead-image{width:160px;height:110px;border-radius:18px}.model-hotel .item-card{--p-list-leading-width: 160px}.primary,.secondary{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.primary{-webkit-line-clamp:1;font-weight:600;color:var(--p-list-foreground)}.secondary{-webkit-line-clamp:1;color:var(--p-list-foreground-muted)}.lines-3 .tertiary{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.item-tile .primary{-webkit-line-clamp:2;font-size:.95rem;line-height:1.25rem}.item-tile .secondary{-webkit-line-clamp:2;font-size:.8rem;line-height:1.1rem}.tertiary{color:var(--p-list-foreground-muted)}.features{display:flex;flex-wrap:wrap;gap:12px;margin-top:6px;color:inherit}.feature{display:inline-flex;align-items:center;gap:6px}.meta{color:var(--p-list-foreground);font-size:var(--p-list-meta-size);font-weight:var(--p-list-meta-weight);font-variant-numeric:tabular-nums;white-space:nowrap}.trailing{color:var(--p-list-foreground-muted);margin-left:0;white-space:nowrap}.section-header{font-size:.85rem;color:var(--p-list-foreground-muted);padding:8px 12px}.praxis-list-root .mat-divider{margin-left:var(--p-list-item-padding-x);margin-right:var(--p-list-item-padding-x)}.cards-grid,.tiles-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--p-list-tile-minW),1fr));gap:var(--p-list-tile-gap)}.item-tile{position:relative;display:flex;flex-direction:column;gap:10px;padding:var(--p-list-tile-padding);border-radius:var(--p-list-tile-radius);background:var(--p-list-surface);border:var(--p-list-border);color:var(--p-list-foreground);cursor:pointer;min-height:160px;transition:box-shadow .16s ease-out,border-color .16s ease-out,transform .12s ease-out,background .16s ease-out}.item-tile:hover{box-shadow:var(--md-sys-elevation-level2);border-color:var(--md-sys-color-outline-variant);background:var(--p-list-item-hover-surface)}.item-tile:active{transform:scale(var(--p-list-tile-press-scale));background:var(--p-list-item-active-surface)}.item-tile:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.tile-media{width:100%;aspect-ratio:var(--p-list-tile-media-ratio);border-radius:var(--p-list-tile-media-radius);background:var(--p-list-item-surface);border:1px solid var(--md-sys-color-outline-variant);display:grid;place-items:center;overflow:hidden}.tile-media img{width:100%;height:100%;object-fit:cover;display:block}.tile-media mat-icon{font-size:28px;height:28px;width:28px;color:var(--p-list-foreground-muted)}.tile-body{display:grid;gap:6px;min-width:0}.tile-meta{display:inline-flex;align-items:center;gap:6px;font-size:.75rem;color:var(--p-list-foreground-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tile-trailing{font-size:.75rem;color:var(--p-list-foreground-muted);white-space:nowrap}.tiles-features{display:flex;flex-wrap:wrap;gap:8px;color:inherit}.tile-status{position:absolute;top:10px;right:10px}.tile-actions{position:absolute;top:8px;left:8px;display:flex;gap:4px;opacity:0;pointer-events:none;transform:translateY(-2px);transition:opacity .16s ease-out,transform .16s ease-out}.item-tile:hover .tile-actions,.item-tile:focus-visible .tile-actions,.item-tile:focus-within .tile-actions{opacity:1;pointer-events:auto;transform:translateY(0)}@media(hover:none){.tile-actions{opacity:1;pointer-events:auto;transform:none}}@media(max-width:600px){.tiles-grid{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}}@media(prefers-reduced-motion:reduce){.item-tile,.tile-actions{transition:none}.item-tile:active{transform:none}.item-card{transition:none}.item-card:active{transform:none}}.item-card{padding:var(--p-list-tile-padding);display:flex;flex-direction:column;min-height:160px;position:relative;cursor:pointer;background:var(--p-list-surface);border:var(--p-list-border);border-radius:var(--p-list-tile-radius);box-shadow:var(--p-list-shadow);transition:box-shadow .16s ease-out,border-color .16s ease-out,transform .12s ease-out,background .16s ease-out;--p-list-leading-width: 96px;--p-list-trailing-min-width: 0px}.item-card .list-item-trailing{min-width:var(--p-list-trailing-min-width)}.item-card:hover{box-shadow:var(--md-sys-elevation-level3);border-color:var(--md-sys-color-outline-variant);background:var(--p-list-item-hover-surface)}.item-card:active{transform:scale(var(--p-list-tile-press-scale));background:var(--p-list-item-active-surface)}.item-card:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.card-actions{display:flex;align-items:center;justify-content:flex-end;gap:4px;padding:6px 8px 4px;border-top:1px solid var(--md-sys-color-outline-variant);margin-top:auto}.status-overlay{position:absolute;top:10px;right:10px;pointer-events:none}.status-overlay .mat-mdc-chip{pointer-events:auto}.leading-icon.mat-icon{width:36px;height:36px;line-height:36px;font-size:20px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.mat-mdc-chip{--mdc-chip-container-height: var(--p-list-chip-height);font-size:var(--p-list-chip-font-size)}.meta .mat-icon{font-size:18px;height:18px;width:18px}.features{overflow:hidden}@keyframes shimmer{0%{background-position:-468px 0}to{background-position:468px 0}}.skeleton{animation-duration:1.2s;animation-fill-mode:forwards;animation-iteration-count:infinite;animation-name:shimmer;animation-timing-function:linear;background:linear-gradient(to right,var(--md-sys-color-surface-container-low) 8%,var(--md-sys-color-surface-container) 18%,var(--md-sys-color-surface-container-low) 33%);background-size:800px 104px;position:relative}.skeleton-avatar{width:32px;height:32px;border-radius:50%}.skeleton-line{height:10px;margin:6px 0;border-radius:6px}.skeleton-chip{width:48px;height:18px;border-radius:999px}.chip-outlined.mat-mdc-chip{background:transparent!important;border:1px solid currentColor}.w-60{width:60%}.w-40{width:40%}.paginator{display:flex;align-items:center;flex-wrap:wrap;gap:8px;padding:8px 4px;border-top:1px solid var(--md-sys-color-outline-variant)}.paginator-controls{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.paginator-meta{display:flex;align-items:center;gap:8px;margin-left:auto}.paginator-page-size{width:120px}.paginator-sort{width:180px}.paginator-search{min-width:220px}.muted{color:var(--p-list-foreground-muted)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i3.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i3.MatSelectionList, selector: "mat-selection-list", inputs: ["color", "compareWith", "multiple", "hideSingleSelectionIndicator", "disabled"], outputs: ["selectionChange"], exportAs: ["matSelectionList"] }, { kind: "component", type: i3.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "component", type: i3.MatListOption, selector: "mat-list-option", inputs: ["togglePosition", "checkboxPosition", "color", "value", "selected"], outputs: ["selectedChange"], exportAs: ["matListOption"] }, { kind: "component", type: i3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i5.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.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: i6.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i12.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: PraxisAiAssistantComponent, selector: "praxis-ai-assistant", inputs: ["adapter", "riskPolicy", "allowManualPatchEdit"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4063
4063
  }
4064
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisList, decorators: [{
4064
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisList, decorators: [{
4065
4065
  type: Component,
4066
4066
  args: [{ selector: 'praxis-list', standalone: true, imports: [
4067
4067
  CommonModule,
@@ -4873,8 +4873,8 @@ export class ListDocHostComponent {}`;
4873
4873
  return [entry, ...curr].slice(0, 14);
4874
4874
  });
4875
4875
  }
4876
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisListDocPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4877
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: PraxisListDocPageComponent, isStandalone: true, selector: "praxis-list-doc-page", providers: [
4876
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisListDocPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4877
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: PraxisListDocPageComponent, isStandalone: true, selector: "praxis-list-doc-page", providers: [
4878
4878
  { provide: API_URL, useValue: { default: { baseUrl: '/api' } } },
4879
4879
  {
4880
4880
  provide: ASYNC_CONFIG_STORAGE,
@@ -4883,7 +4883,7 @@ export class ListDocHostComponent {}`;
4883
4883
  { provide: SETTINGS_PANEL_DATA, useValue: {} },
4884
4884
  ], ngImport: i0, template: "<section class=\"list-doc-page\">\n <header class=\"hero\">\n <div class=\"hero__copy\">\n <p class=\"hero__eyebrow\">Praxis UI - List</p>\n <h1>Pagina viva de documentacao do <code>praxis-list</code></h1>\n <p>\n Esta pagina entrega um laboratorio completo para validar recursos de\n layout, templating, selecao, acoes, skins e contratos de integracao do\n componente.\n </p>\n <div class=\"hero__badges\">\n <span>Live first</span>\n <span>Config orientada a JSON</span>\n <span>Cobertura corporativa</span>\n </div>\n </div>\n <div class=\"hero__panel\">\n <p class=\"hero__panel-title\">Recursos cobertos</p>\n <ul>\n @for (topic of featureCoverage; track topic.title) {\n <li>\n <strong>{{ topic.title }}</strong>\n <span>{{ topic.details }}</span>\n </li>\n }\n </ul>\n </div>\n </header>\n\n <section class=\"lab\">\n <aside class=\"controls\">\n <article class=\"panel panel--controls\">\n <h2>Playground</h2>\n <p class=\"muted\">\n Ajuste os controles e observe o comportamento da lista em tempo real.\n </p>\n\n <div class=\"control-block\">\n <p class=\"control-block__title\">Cenario</p>\n <div class=\"chip-row\">\n @for (option of scenarioOptions; track option.id) {\n <button\n type=\"button\"\n class=\"chip-button\"\n [attr.data-testid]=\"'scenario-' + option.id\"\n [class.is-active]=\"scenario() === option.id\"\n (click)=\"setScenario(option.id)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n @if (activeScenarioMeta(); as activeScenario) {\n <p class=\"control-hint\">{{ activeScenario.helper }}</p>\n }\n </div>\n\n <div class=\"control-block\">\n <p class=\"control-block__title\">Variant</p>\n <div class=\"chip-row\">\n @for (option of variantOptions; track option.id) {\n <button\n type=\"button\"\n class=\"chip-button\"\n [attr.data-testid]=\"'variant-' + option.id\"\n [class.is-active]=\"variant() === option.id\"\n (click)=\"setVariant(option.id)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n </div>\n\n <div class=\"control-grid\">\n <div class=\"control-block\">\n <p class=\"control-block__title\">Density</p>\n <div class=\"chip-row\">\n @for (option of densityOptions; track option.id) {\n <button\n type=\"button\"\n class=\"chip-button chip-button--small\"\n [attr.data-testid]=\"'density-' + option.id\"\n [class.is-active]=\"density() === option.id\"\n (click)=\"setDensity(option.id)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n </div>\n\n <div class=\"control-block\">\n <p class=\"control-block__title\">Lines</p>\n <div class=\"chip-row\">\n @for (count of [1, 2, 3]; track count) {\n <button\n type=\"button\"\n class=\"chip-button chip-button--small\"\n [attr.data-testid]=\"'lines-' + count\"\n [class.is-active]=\"lines() === count\"\n (click)=\"setLines($any(count))\"\n >\n {{ count }}\n </button>\n }\n </div>\n </div>\n </div>\n\n <div class=\"control-block\">\n <p class=\"control-block__title\">Skin</p>\n <div class=\"chip-row\">\n @for (option of skinOptions; track option.id) {\n <button\n type=\"button\"\n class=\"chip-button chip-button--small\"\n [attr.data-testid]=\"'skin-' + option.id\"\n [class.is-active]=\"skin() === option.id\"\n (click)=\"setSkin(option.id)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n </div>\n\n <div class=\"control-block\">\n <p class=\"control-block__title\">Features mode</p>\n <div class=\"chip-row\">\n @for (option of featuresModeOptions; track option.id) {\n <button\n type=\"button\"\n class=\"chip-button chip-button--small\"\n [attr.data-testid]=\"'features-' + option.id\"\n [class.is-active]=\"featuresMode() === option.id\"\n (click)=\"setFeaturesMode(option.id)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n </div>\n\n <div class=\"control-block\">\n <p class=\"control-block__title\">Selection</p>\n <div class=\"chip-row\">\n @for (option of selectionOptions; track option.id) {\n <button\n type=\"button\"\n class=\"chip-button chip-button--small\"\n [attr.data-testid]=\"'selection-' + option.id\"\n [class.is-active]=\"selectionMode() === option.id\"\n (click)=\"setSelectionMode(option.id)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n </div>\n\n <div class=\"control-block\">\n <p class=\"control-block__title\">Customization mode</p>\n <div class=\"chip-row\">\n <button\n type=\"button\"\n class=\"chip-button chip-button--small\"\n data-testid=\"customization-on\"\n [class.is-active]=\"customizationEnabled()\"\n (click)=\"setCustomizationMode(true)\"\n >\n On\n </button>\n <button\n type=\"button\"\n class=\"chip-button chip-button--small\"\n data-testid=\"customization-off\"\n [class.is-active]=\"!customizationEnabled()\"\n (click)=\"setCustomizationMode(false)\"\n >\n Off\n </button>\n </div>\n <p class=\"control-hint\">\n Ative para exibir editor interno + AI assistant do componente.\n </p>\n </div>\n </article>\n\n <article class=\"panel panel--events\">\n <div class=\"panel__head\">\n <h2>Eventos</h2>\n <button\n type=\"button\"\n class=\"ghost-btn\"\n data-testid=\"clear-log\"\n (click)=\"clearLog()\"\n >\n Limpar log\n </button>\n </div>\n @if (eventLog().length === 0) {\n <p class=\"muted\">\n Sem eventos ainda. Clique em itens, acoes ou selecao.\n </p>\n } @else {\n <ul class=\"event-log\">\n @for (entry of eventLog(); track entry.id) {\n <li>{{ entry.message }}</li>\n }\n </ul>\n }\n </article>\n </aside>\n\n <article class=\"panel panel--live\">\n <h2>Exemplo live</h2>\n <p class=\"muted\">\n Mostra list/cards/tiles com os mesmos dados e configura em tempo real.\n </p>\n <praxis-list\n listId=\"praxis-list-doc-live\"\n componentInstanceId=\"main-showcase\"\n [config]=\"liveConfig()\"\n [form]=\"form\"\n [enableCustomization]=\"customizationEnabled()\"\n (itemClick)=\"handleItemClick($event)\"\n (actionClick)=\"handleActionClick($event)\"\n (selectionChange)=\"handleSelectionChange($event)\"\n />\n </article>\n </section>\n\n <section class=\"skin-matrix\">\n <div class=\"section-head\">\n <h2>Matriz de skins</h2>\n <p>\n Preview rapido de todos os estilos visuais disponiveis no componente.\n </p>\n </div>\n <div class=\"skin-matrix__grid\">\n @for (preview of skinPreviewConfigs(); track preview.type) {\n <article class=\"panel skin-preview\">\n <h3>{{ preview.type }}</h3>\n <praxis-list-skin-preview\n [config]=\"preview.config\"\n [items]=\"skinPreviewItems\"\n />\n </article>\n }\n </div>\n </section>\n\n <section class=\"code-lab panel\">\n <div class=\"section-head\">\n <h2>Snippets de referencia</h2>\n <p>\n Use os blocos abaixo para replicar os exemplos no host ou no site de\n documentacao.\n </p>\n </div>\n\n <div class=\"code-tabs\">\n @for (tab of codeTabs; track tab.id) {\n <button\n type=\"button\"\n class=\"chip-button\"\n [attr.data-testid]=\"'tab-' + tab.id\"\n [class.is-active]=\"activeTab() === tab.id\"\n (click)=\"setCodeTab(tab.id)\"\n >\n {{ tab.label }}\n </button>\n }\n </div>\n\n <pre class=\"code-box\"><code>{{ selectedSnippet() }}</code></pre>\n </section>\n\n <section class=\"notes panel\">\n <h2>Notas de arquitetura</h2>\n <ul>\n <li>\n <strong>Persistencia:</strong> sempre definir <code>listId</code>; para\n multiplas instancias, use <code>componentInstanceId</code>.\n </li>\n <li>\n <strong>Local vs remoto:</strong> <code>dataSource.data</code> tem\n precedencia para preview local; <code>resourcePath</code> define o\n contrato remoto.\n </li>\n <li>\n <strong>Toolbar remota:</strong> controles de paginacao/sort/busca\n refletem o contrato; a semantica completa de filtro/paginacao depende do\n backend em <code>/filter</code>.\n </li>\n <li>\n <strong>Editor interno:</strong> habilite\n <code>enableCustomization</code> quando o host tiver os providers de\n Settings Panel e AI.\n </li>\n <li>\n <strong>A11y:</strong> configure <code>a11y.ariaLabel</code>/<code\n >ariaLabelledBy</code\n >\n e mantenha labels de acoes explicitas.\n </li>\n </ul>\n </section>\n</section>\n", styles: [":host{display:block}.list-doc-page{--doc-bg: linear-gradient(160deg, #eef5ff 0%, #f9fbff 48%, #e8f7ef 100%);--doc-surface: rgba(255, 255, 255, .86);--doc-surface-strong: #ffffff;--doc-border: #cfdae8;--doc-text: #10243a;--doc-muted: #4d6075;--doc-accent: #0b6dff;--doc-accent-2: #0f9d58;--doc-accent-soft: color-mix(in srgb, var(--doc-accent) 15%, #ffffff);display:grid;gap:20px;padding:18px;border-radius:22px;border:1px solid var(--doc-border);color:var(--doc-text);background:var(--doc-bg);font-family:Manrope,Segoe UI,sans-serif}.hero{display:grid;gap:16px;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr)}.hero__copy{border-radius:18px;border:1px solid var(--doc-border);padding:18px;background:radial-gradient(120% 130% at 0% 0%,rgba(11,109,255,.2),transparent 56%),var(--doc-surface-strong);box-shadow:0 14px 24px #0a254c14}.hero__eyebrow{margin:0 0 8px;font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:#385f9c;font-weight:700}.hero h1{margin:0;font-size:clamp(1.24rem,2.8vw,1.86rem);line-height:1.25}.hero h1 code{background:color-mix(in srgb,#0b6dff 12%,#ffffff);border:1px solid color-mix(in srgb,#0b6dff 28%,#cad6ec);border-radius:8px;padding:2px 6px;font-size:.9em}.hero p{margin:10px 0 0;color:var(--doc-muted)}.hero__badges{margin-top:14px;display:flex;flex-wrap:wrap;gap:8px}.hero__badges span{border-radius:999px;border:1px solid color-mix(in srgb,#0f9d58 26%,#cad9d2);background:color-mix(in srgb,#0f9d58 12%,#ffffff);color:#0f5d39;padding:5px 10px;font-size:12px;font-weight:700}.hero__panel{border-radius:18px;border:1px solid var(--doc-border);padding:16px;background:var(--doc-surface);box-shadow:0 10px 20px #182e5414}.hero__panel-title{margin:0 0 10px;font-size:13px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:#345684}.hero__panel ul{margin:0;padding:0;list-style:none;display:grid;gap:8px}.hero__panel li{display:grid;gap:2px;padding:8px 10px;border-radius:10px;border:1px solid color-mix(in srgb,#274f82 14%,#d1d8e6);background:#fff}.hero__panel strong{font-size:12px}.hero__panel span{color:var(--doc-muted);font-size:12px}.lab{display:grid;gap:14px;grid-template-columns:minmax(260px,340px) minmax(0,1fr);align-items:start}.controls{display:grid;gap:12px}.panel{border-radius:16px;border:1px solid var(--doc-border);background:var(--doc-surface);box-shadow:0 8px 18px #1b2d4f12}.panel--controls,.panel--events{padding:14px}.panel--controls h2,.panel--live h2,.panel--events h2,.skin-preview h3,.code-lab h2,.notes h2{margin:0}.panel--live{padding:14px;min-width:0}.muted{margin:6px 0 0;color:var(--doc-muted);font-size:13px}.control-block{margin-top:12px}.control-grid{display:grid;gap:10px;grid-template-columns:repeat(2,minmax(0,1fr))}.control-block__title{margin:0 0 6px;font-size:12px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:#325d96}.control-hint{margin:8px 0 0;color:var(--doc-muted);font-size:12px}.chip-row{display:flex;gap:7px;flex-wrap:wrap}.chip-button{min-height:30px;border-radius:999px;border:1px solid color-mix(in srgb,#225ea9 30%,#c8d3e3);background:#f4f8ff;color:#1f3f69;padding:0 12px;font-size:12px;font-weight:700;cursor:pointer;transition:.14s ease;transition-property:border-color,background,color,transform}.chip-button--small{min-height:28px;padding-inline:10px;font-size:11px}.chip-button:hover{transform:translateY(-1px);border-color:color-mix(in srgb,var(--doc-accent) 44%,#a6bad7)}.chip-button.is-active{border-color:color-mix(in srgb,var(--doc-accent) 62%,#6f8aa9);background:linear-gradient(140deg,#1565d8,#0f9360);color:#fff}.chip-button:focus-visible,.ghost-btn:focus-visible{outline:2px solid color-mix(in srgb,var(--doc-accent) 65%,#416688);outline-offset:1px}.panel__head{display:flex;gap:10px;justify-content:space-between;align-items:center}.ghost-btn{min-height:30px;border-radius:8px;border:1px solid color-mix(in srgb,#173d6e 32%,#cdd7e4);background:#fff;color:#1f3d66;font-size:12px;font-weight:700;padding:0 10px;cursor:pointer}.event-log{margin:10px 0 0;padding:0;list-style:none;display:grid;gap:6px}.event-log li{border-radius:9px;border:1px solid color-mix(in srgb,#34598a 16%,#ccd7e6);background:#fff;padding:7px 9px;font-family:JetBrains Mono,Consolas,monospace;font-size:12px;color:#273e5f}.skin-matrix{display:grid;gap:10px}.section-head h2{margin:0}.section-head p{margin:4px 0 0;color:var(--doc-muted)}.skin-matrix__grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.skin-preview{padding:12px}.skin-preview h3{margin-bottom:8px;text-transform:capitalize}.code-lab{padding:14px}.code-tabs{margin-top:12px;display:flex;gap:8px;flex-wrap:wrap}.code-box{margin:12px 0 0;border-radius:12px;border:1px solid color-mix(in srgb,#2d3f58 36%,#8194aa);background:#0d1420;color:#d9ecff;padding:12px;max-height:360px;overflow:auto;font-size:12px;line-height:1.55}.notes{padding:14px}.notes ul{margin:10px 0 0;padding-left:18px;display:grid;gap:8px}.notes li{color:#21354f}.notes code{background:color-mix(in srgb,#0b6dff 12%,#ffffff);border:1px solid color-mix(in srgb,#0b6dff 30%,#c8d5e7);border-radius:6px;padding:1px 5px}@media(max-width:1060px){.hero,.lab{grid-template-columns:1fr}}@media(max-width:700px){.list-doc-page{padding:12px}.control-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: PraxisList, selector: "praxis-list", inputs: ["config", "listId", "componentInstanceId", "form", "enableCustomization"], outputs: ["itemClick", "actionClick", "selectionChange"] }, { kind: "component", type: PraxisListSkinPreviewComponent, selector: "praxis-list-skin-preview", inputs: ["config", "items", "theme"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4885
4885
  }
4886
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisListDocPageComponent, decorators: [{
4886
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisListDocPageComponent, decorators: [{
4887
4887
  type: Component,
4888
4888
  args: [{ selector: 'praxis-list-doc-page', standalone: true, imports: [
4889
4889
  CommonModule,